hme.c revision 11878:ac93462db6d7
1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21/*
22 * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
23 * Use is subject to license terms.
24 */
25
26
27/*
28 * SunOS MT STREAMS FEPS(SBus)/Cheerio(PCI) 10/100Mb Ethernet Device Driver
29 */
30
31#include	<sys/types.h>
32#include	<sys/debug.h>
33#include	<sys/stream.h>
34#include	<sys/cmn_err.h>
35#include	<sys/kmem.h>
36#include	<sys/crc32.h>
37#include	<sys/modctl.h>
38#include	<sys/conf.h>
39#include	<sys/strsun.h>
40#include	<sys/kstat.h>
41#include	<sys/pattr.h>
42#include	<sys/dlpi.h>
43#include	<sys/strsubr.h>
44#include	<sys/mac_provider.h>
45#include	<sys/mac_ether.h>
46#include	<sys/mii.h>
47#include	<sys/ethernet.h>
48#include	<sys/vlan.h>
49#include	<sys/pci.h>
50#include	<sys/policy.h>
51#include	<sys/ddi.h>
52#include	<sys/sunddi.h>
53#include	<sys/byteorder.h>
54#include	"hme_phy.h"
55#include	"hme_mac.h"
56#include	"hme.h"
57
58typedef void	(*fptrv_t)();
59
60typedef enum {
61	NO_MSG		= 0,
62	AUTOCONFIG_MSG,
63	DISPLAY_MSG,
64	INIT_MSG,
65	UNINIT_MSG,
66	CONFIG_MSG,
67	MII_MSG,
68	FATAL_ERR_MSG,
69	NFATAL_ERR_MSG,
70	XCVR_MSG,
71	NOXCVR_MSG,
72	ERX_MSG,
73	DDI_MSG,
74} msg_t;
75
76msg_t	hme_debug_level =	NO_MSG;
77
78static char	*msg_string[] = {
79	"NONE       ",
80	"AUTOCONFIG ",
81	"DISPLAY	"
82	"INIT       ",
83	"UNINIT		",
84	"CONFIG	",
85	"MII	",
86	"FATAL_ERR	",
87	"NFATAL_ERR	",
88	"XCVR	",
89	"NOXCVR	",
90	"ERX	",
91	"DDI	",
92};
93
94#define	SEVERITY_NONE	0
95#define	SEVERITY_LOW	0
96#define	SEVERITY_MID	1
97#define	SEVERITY_HIGH	2
98#define	SEVERITY_UNKNOWN 99
99
100#define	FEPS_URUN_BUG
101#define	HME_CODEVIOL_BUG
102
103#define	KIOIP	KSTAT_INTR_PTR(hmep->hme_intrstats)
104
105/*
106 * The following variables are used for checking fixes in Sbus/FEPS 2.0
107 */
108static	int	hme_urun_fix = 0;	/* Bug fixed in Sbus/FEPS 2.0 */
109
110/*
111 * The following variables are used for configuring various features
112 */
113static	int	hme_64bit_enable =	1;	/* Use 64-bit sbus transfers */
114static	int	hme_reject_own =	1;	/* Reject packets with own SA */
115static	int	hme_ngu_enable =	0;	/* Never Give Up mode */
116
117char *hme_priv_prop[] = {
118	"_ipg0",
119	"_ipg1",
120	"_ipg2",
121	"_lance_mode",
122	NULL
123};
124
125static	int	hme_lance_mode =	1;	/* to enable lance mode */
126static	int	hme_ipg0 =		16;
127static	int	hme_ipg1 =		8;
128static	int	hme_ipg2 =		4;
129
130/*
131 * The following parameters may be configured by the user. If they are not
132 * configured by the user, the values will be based on the capabilities of
133 * the transceiver.
134 * The value "HME_NOTUSR" is ORed with the parameter value to indicate values
135 * which are NOT configured by the user.
136 */
137
138#define	HME_NOTUSR	0x0f000000
139#define	HME_MASK_1BIT	0x1
140#define	HME_MASK_5BIT	0x1f
141#define	HME_MASK_8BIT	0xff
142
143/*
144 * All strings used by hme messaging functions
145 */
146
147static	char *no_xcvr_msg =
148	"No transceiver found.";
149
150static	char *burst_size_msg =
151	"Could not identify the burst size";
152
153static	char *unk_rx_ringsz_msg =
154	"Unknown receive RINGSZ";
155
156static  char *add_intr_fail_msg =
157	"ddi_add_intr(9F) failed";
158
159static  char *mregs_4global_reg_fail_msg =
160	"ddi_regs_map_setup(9F) for global reg failed";
161
162static	char *mregs_4etx_reg_fail_msg =
163	"ddi_map_regs for etx reg failed";
164
165static	char *mregs_4erx_reg_fail_msg =
166	"ddi_map_regs for erx reg failed";
167
168static	char *mregs_4bmac_reg_fail_msg =
169	"ddi_map_regs for bmac reg failed";
170
171static	char *mregs_4mif_reg_fail_msg =
172	"ddi_map_regs for mif reg failed";
173
174static	char *init_fail_gen_msg =
175	"Failed to initialize hardware/driver";
176
177static	char *ddi_nregs_fail_msg =
178	"ddi_dev_nregs failed(9F), returned %d";
179
180static	char *bad_num_regs_msg =
181	"Invalid number of registers.";
182
183
184/* FATAL ERR msgs */
185/*
186 * Function prototypes.
187 */
188/* these two are global so that qfe can use them */
189int hmeattach(dev_info_t *, ddi_attach_cmd_t);
190int hmedetach(dev_info_t *, ddi_detach_cmd_t);
191int hmequiesce(dev_info_t *);
192static	boolean_t hmeinit_xfer_params(struct hme *);
193static	uint_t hmestop(struct hme *);
194static	void hmestatinit(struct hme *);
195static	int hmeallocthings(struct hme *);
196static	void hmefreethings(struct hme *);
197static	int hmeallocbuf(struct hme *, hmebuf_t *, int);
198static	int hmeallocbufs(struct hme *);
199static	void hmefreebufs(struct hme *);
200static	void hmeget_hm_rev_property(struct hme *);
201static	boolean_t hmestart(struct hme *, mblk_t *);
202static	uint_t hmeintr(caddr_t);
203static	void hmereclaim(struct hme *);
204static	int hmeinit(struct hme *);
205static	void hmeuninit(struct hme *hmep);
206static 	mblk_t *hmeread(struct hme *, hmebuf_t *, uint32_t);
207static	void hmesavecntrs(struct hme *);
208static	void hme_fatal_err(struct hme *, uint_t);
209static	void hme_nonfatal_err(struct hme *, uint_t);
210static	int hmeburstsizes(struct hme *);
211static	void send_bit(struct hme *, uint16_t);
212static	uint16_t get_bit_std(uint8_t, struct hme *);
213static	uint16_t hme_bb_mii_read(struct hme *, uint8_t, uint8_t);
214static	void hme_bb_mii_write(struct hme *, uint8_t, uint8_t, uint16_t);
215static	void hme_bb_force_idle(struct hme *);
216static	uint16_t hme_mii_read(void *, uint8_t, uint8_t);
217static	void hme_mii_write(void *, uint8_t, uint8_t, uint16_t);
218static	void hme_setup_mac_address(struct hme *, dev_info_t *);
219static	void hme_mii_notify(void *, link_state_t);
220
221static void hme_fault_msg(struct hme *, uint_t, msg_t, char *, ...);
222
223static void hme_check_acc_handle(char *, uint_t, struct hme *,
224    ddi_acc_handle_t);
225
226/*
227 * Nemo (GLDv3) Functions.
228 */
229static int	hme_m_stat(void *, uint_t, uint64_t *);
230static int	hme_m_start(void *);
231static void	hme_m_stop(void *);
232static int	hme_m_promisc(void *, boolean_t);
233static int	hme_m_multicst(void *, boolean_t, const uint8_t *);
234static int	hme_m_unicst(void *, const uint8_t *);
235static mblk_t	*hme_m_tx(void *, mblk_t *);
236static boolean_t	hme_m_getcapab(void *, mac_capab_t, void *);
237static int hme_m_getprop(void *, const char *, mac_prop_id_t, uint_t, void *);
238static void hme_m_propinfo(void *, const char *, mac_prop_id_t,
239    mac_prop_info_handle_t);
240static int hme_m_setprop(void *, const char *, mac_prop_id_t, uint_t,
241    const void *);
242
243static mii_ops_t hme_mii_ops = {
244	MII_OPS_VERSION,
245	hme_mii_read,
246	hme_mii_write,
247	hme_mii_notify,
248	NULL
249};
250
251static mac_callbacks_t hme_m_callbacks = {
252	MC_GETCAPAB | MC_SETPROP | MC_GETPROP | MC_PROPINFO,
253	hme_m_stat,
254	hme_m_start,
255	hme_m_stop,
256	hme_m_promisc,
257	hme_m_multicst,
258	hme_m_unicst,
259	hme_m_tx,
260	NULL,
261	NULL,
262	hme_m_getcapab,
263	NULL,
264	NULL,
265	hme_m_setprop,
266	hme_m_getprop,
267	hme_m_propinfo
268};
269
270DDI_DEFINE_STREAM_OPS(hme_dev_ops, nulldev, nulldev, hmeattach, hmedetach,
271    nodev, NULL, D_MP, NULL, hmequiesce);
272
273#define	HME_FAULT_MSG1(p, s, t, f) \
274    hme_fault_msg((p), (s), (t), (f));
275
276#define	HME_FAULT_MSG2(p, s, t, f, a) \
277    hme_fault_msg((p), (s), (t), (f), (a));
278
279#define	HME_FAULT_MSG3(p, s, t, f, a, b) \
280    hme_fault_msg((p), (s), (t), (f), (a), (b));
281
282#define	HME_FAULT_MSG4(p, s, t, f, a, b, c) \
283    hme_fault_msg((p), (s), (t), (f), (a), (b), (c));
284
285#define	CHECK_MIFREG() \
286	hme_check_acc_handle(__FILE__, __LINE__, hmep, hmep->hme_mifregh)
287#define	CHECK_ETXREG() \
288	hme_check_acc_handle(__FILE__, __LINE__, hmep, hmep->hme_etxregh)
289#define	CHECK_ERXREG() \
290	hme_check_acc_handle(__FILE__, __LINE__, hmep, hmep->hme_erxregh)
291#define	CHECK_MACREG() \
292	hme_check_acc_handle(__FILE__, __LINE__, hmep, hmep->hme_bmacregh)
293#define	CHECK_GLOBREG() \
294	hme_check_acc_handle(__FILE__, __LINE__, hmep, hmep->hme_globregh)
295
296/*
297 * Claim the device is ultra-capable of burst in the beginning.  Use
298 * the value returned by ddi_dma_burstsizes() to actually set the HME
299 * global configuration register later.
300 *
301 * Sbus/FEPS supports burst sizes of 16, 32 and 64 bytes. Also, it supports
302 * 32-bit and 64-bit Sbus transfers. Hence the dlim_burstsizes field contains
303 * the the burstsizes in both the lo and hi words.
304 */
305#define	HMELIMADDRLO	((uint64_t)0x00000000)
306#define	HMELIMADDRHI	((uint64_t)0xffffffff)
307
308/*
309 * Note that rx and tx data buffers can be arbitrarily aligned, but
310 * that the descriptor rings need to be aligned on 2K boundaries, per
311 * the spec.
312 */
313static ddi_dma_attr_t hme_dma_attr = {
314	DMA_ATTR_V0,		/* version number. */
315	(uint64_t)HMELIMADDRLO,	/* low address */
316	(uint64_t)HMELIMADDRHI,	/* high address */
317	(uint64_t)0x00ffffff,	/* address counter max */
318	(uint64_t)HME_HMDALIGN,	/* alignment */
319	(uint_t)0x00700070,	/* dlim_burstsizes for 32 and 64 bit xfers */
320	(uint32_t)0x1,		/* minimum transfer size */
321	(uint64_t)0x7fffffff,	/* maximum transfer size */
322	(uint64_t)0x00ffffff,	/* maximum segment size */
323	1,			/* scatter/gather list length */
324	512,			/* granularity */
325	0			/* attribute flags */
326};
327
328static ddi_device_acc_attr_t hme_buf_attr = {
329	DDI_DEVICE_ATTR_V0,
330	DDI_NEVERSWAP_ACC,
331	DDI_STRICTORDER_ACC,	/* probably could allow merging & caching */
332	DDI_DEFAULT_ACC,
333};
334
335static uchar_t pci_latency_timer = 0;
336
337/*
338 * Module linkage information for the kernel.
339 */
340static struct modldrv modldrv = {
341	&mod_driverops,	/* Type of module.  This one is a driver */
342	"Sun HME 10/100 Mb Ethernet",
343	&hme_dev_ops,	/* driver ops */
344};
345
346static struct modlinkage modlinkage = {
347	MODREV_1, &modldrv, NULL
348};
349
350/* <<<<<<<<<<<<<<<<<<<<<<  Register operations >>>>>>>>>>>>>>>>>>>>> */
351
352#define	GET_MIFREG(reg) \
353	ddi_get32(hmep->hme_mifregh, (uint32_t *)&hmep->hme_mifregp->reg)
354#define	PUT_MIFREG(reg, value) \
355	ddi_put32(hmep->hme_mifregh, (uint32_t *)&hmep->hme_mifregp->reg, value)
356
357#define	GET_ETXREG(reg) \
358	ddi_get32(hmep->hme_etxregh, (uint32_t *)&hmep->hme_etxregp->reg)
359#define	PUT_ETXREG(reg, value) \
360	ddi_put32(hmep->hme_etxregh, (uint32_t *)&hmep->hme_etxregp->reg, value)
361#define	GET_ERXREG(reg) \
362	ddi_get32(hmep->hme_erxregh, (uint32_t *)&hmep->hme_erxregp->reg)
363#define	PUT_ERXREG(reg, value) \
364	ddi_put32(hmep->hme_erxregh, (uint32_t *)&hmep->hme_erxregp->reg, value)
365#define	GET_MACREG(reg) \
366	ddi_get32(hmep->hme_bmacregh, (uint32_t *)&hmep->hme_bmacregp->reg)
367#define	PUT_MACREG(reg, value) \
368	ddi_put32(hmep->hme_bmacregh, \
369		(uint32_t *)&hmep->hme_bmacregp->reg, value)
370#define	GET_GLOBREG(reg) \
371	ddi_get32(hmep->hme_globregh, (uint32_t *)&hmep->hme_globregp->reg)
372#define	PUT_GLOBREG(reg, value) \
373	ddi_put32(hmep->hme_globregh, \
374		(uint32_t *)&hmep->hme_globregp->reg, value)
375#define	PUT_TMD(ptr, paddr, len, flags)					\
376	ddi_put32(hmep->hme_tmd_acch, &hmep->hme_tmdp[ptr].tmd_addr, paddr); \
377	ddi_put32(hmep->hme_tmd_acch, &hmep->hme_tmdp[ptr].tmd_flags,	\
378	    len | flags)
379#define	GET_TMD_FLAGS(ptr)					\
380	ddi_get32(hmep->hme_tmd_acch, &hmep->hme_tmdp[ptr].tmd_flags)
381#define	PUT_RMD(ptr, paddr) \
382	ddi_put32(hmep->hme_rmd_acch, &hmep->hme_rmdp[ptr].rmd_addr, paddr); \
383	ddi_put32(hmep->hme_rmd_acch, &hmep->hme_rmdp[ptr].rmd_flags,	\
384	    (uint32_t)(HMEBUFSIZE << HMERMD_BUFSIZE_SHIFT) | HMERMD_OWN)
385#define	GET_RMD_FLAGS(ptr)					\
386	ddi_get32(hmep->hme_rmd_acch, &hmep->hme_rmdp[ptr].rmd_flags)
387
388#define	GET_ROM8(offset) \
389	ddi_get8((hmep->hme_romh), (offset))
390
391/*
392 * Ether_copy is not endian-correct. Define an endian-correct version.
393 */
394#define	ether_bcopy(a, b) (bcopy(a, b, 6))
395
396/*
397 * Ether-type is specifically big-endian, but data region is unknown endian
398 */
399#define	get_ether_type(ptr) \
400	(((((uint8_t *)ptr)[12] << 8) | (((uint8_t *)ptr)[13])))
401
402/* <<<<<<<<<<<<<<<<<<<<<<  Configuration Parameters >>>>>>>>>>>>>>>>>>>>> */
403
404#define	BMAC_DEFAULT_JAMSIZE	(0x04)		/* jamsize equals 4 */
405#define	BMAC_LONG_JAMSIZE	(0x10)		/* jamsize equals 0x10 */
406static	int 	jamsize = BMAC_DEFAULT_JAMSIZE;
407
408
409/*
410 * Calculate the bit in the multicast address filter that selects the given
411 * address.
412 */
413
414static uint32_t
415hmeladrf_bit(const uint8_t *addr)
416{
417	uint32_t crc;
418
419	CRC32(crc, addr, ETHERADDRL, -1U, crc32_table);
420
421	/*
422	 * Just want the 6 most significant bits.
423	 */
424	return (crc >> 26);
425}
426
427/* <<<<<<<<<<<<<<<<<<<<<<<<  Bit Bang Operations >>>>>>>>>>>>>>>>>>>>>>>> */
428
429static void
430send_bit(struct hme *hmep, uint16_t x)
431{
432	PUT_MIFREG(mif_bbdata, x);
433	PUT_MIFREG(mif_bbclk, HME_BBCLK_LOW);
434	PUT_MIFREG(mif_bbclk, HME_BBCLK_HIGH);
435}
436
437
438/*
439 * To read the MII register bits according to the IEEE Standard
440 */
441static uint16_t
442get_bit_std(uint8_t phyad, struct hme *hmep)
443{
444	uint16_t	x;
445
446	PUT_MIFREG(mif_bbclk, HME_BBCLK_LOW);
447	drv_usecwait(1);	/* wait for  >330 ns for stable data */
448	if (phyad == HME_INTERNAL_PHYAD)
449		x = (GET_MIFREG(mif_cfg) & HME_MIF_CFGM0) ? 1 : 0;
450	else
451		x = (GET_MIFREG(mif_cfg) & HME_MIF_CFGM1) ? 1 : 0;
452	PUT_MIFREG(mif_bbclk, HME_BBCLK_HIGH);
453	return (x);
454}
455
456#define	SEND_BIT(x)		send_bit(hmep, x)
457#define	GET_BIT_STD(phyad, x)	x = get_bit_std(phyad, hmep)
458
459
460static void
461hme_bb_mii_write(struct hme *hmep, uint8_t phyad, uint8_t regad, uint16_t data)
462{
463	int	i;
464
465	PUT_MIFREG(mif_bbopenb, 1);	/* Enable the MII driver */
466	(void) hme_bb_force_idle(hmep);
467	SEND_BIT(0); SEND_BIT(1);	/* <ST> */
468	SEND_BIT(0); SEND_BIT(1);	/* <OP> */
469
470	for (i = 4; i >= 0; i--) {		/* <AAAAA> */
471		SEND_BIT((phyad >> i) & 1);
472	}
473
474	for (i = 4; i >= 0; i--) {		/* <RRRRR> */
475		SEND_BIT((regad >> i) & 1);
476	}
477
478	SEND_BIT(1); SEND_BIT(0);	/* <TA> */
479
480	for (i = 0xf; i >= 0; i--) {	/* <DDDDDDDDDDDDDDDD> */
481		SEND_BIT((data >> i) & 1);
482	}
483
484	PUT_MIFREG(mif_bbopenb, 0);	/* Disable the MII driver */
485	CHECK_MIFREG();
486}
487
488/* Return 0 if OK, 1 if error (Transceiver does not talk management) */
489static uint16_t
490hme_bb_mii_read(struct hme *hmep, uint8_t phyad, uint8_t regad)
491{
492	int		i;
493	uint32_t	x;
494	uint16_t	data = 0;
495
496	PUT_MIFREG(mif_bbopenb, 1);	/* Enable the MII driver */
497	(void) hme_bb_force_idle(hmep);
498	SEND_BIT(0); SEND_BIT(1);	/* <ST> */
499	SEND_BIT(1); SEND_BIT(0);	/* <OP> */
500	for (i = 4; i >= 0; i--) {		/* <AAAAA> */
501		SEND_BIT((phyad >> i) & 1);
502	}
503	for (i = 4; i >= 0; i--) {		/* <RRRRR> */
504		SEND_BIT((regad >> i) & 1);
505	}
506
507	PUT_MIFREG(mif_bbopenb, 0);	/* Disable the MII driver */
508
509	GET_BIT_STD(phyad, x);
510	GET_BIT_STD(phyad, x);		/* <TA> */
511	for (i = 0xf; i >= 0; i--) {	/* <DDDDDDDDDDDDDDDD> */
512		GET_BIT_STD(phyad, x);
513		data += (x << i);
514	}
515	/*
516	 * Kludge to get the Transceiver out of hung mode
517	 */
518	GET_BIT_STD(phyad, x);
519	GET_BIT_STD(phyad, x);
520	GET_BIT_STD(phyad, x);
521	CHECK_MIFREG();
522	return (data);
523}
524
525
526static void
527hme_bb_force_idle(struct hme *hmep)
528{
529	int	i;
530
531	for (i = 0; i < 33; i++) {
532		SEND_BIT(1);
533	}
534}
535
536/* <<<<<<<<<<<<<<<<<<<<End of Bit Bang Operations >>>>>>>>>>>>>>>>>>>>>>>> */
537
538
539/* <<<<<<<<<<<<< Frame Register used for MII operations >>>>>>>>>>>>>>>>>>>> */
540
541/* Return 0 if OK, 1 if error (Transceiver does not talk management) */
542static uint16_t
543hme_mii_read(void *arg, uint8_t phyad, uint8_t regad)
544{
545	struct hme	*hmep = arg;
546	uint32_t	frame;
547	uint32_t	tmp_mif;
548	uint32_t	tmp_xif;
549
550	tmp_mif = GET_MIFREG(mif_cfg);
551	tmp_xif = GET_MACREG(xifc);
552
553	switch (phyad) {
554	case HME_EXTERNAL_PHYAD:
555		PUT_MIFREG(mif_cfg, tmp_mif | HME_MIF_CFGPS);
556		PUT_MACREG(xifc, tmp_xif | BMAC_XIFC_MIIBUFDIS);
557		break;
558	case HME_INTERNAL_PHYAD:
559		PUT_MIFREG(mif_cfg, tmp_mif & ~(HME_MIF_CFGPS));
560		PUT_MACREG(xifc, tmp_xif & ~(BMAC_XIFC_MIIBUFDIS));
561		break;
562	default:
563		return (0xffff);
564	}
565
566	if (!hmep->hme_frame_enable) {
567		frame = (hme_bb_mii_read(hmep, phyad, regad));
568		PUT_MACREG(xifc, tmp_xif);
569		PUT_MIFREG(mif_cfg, tmp_mif);
570		return (frame & 0xffff);
571	}
572
573	PUT_MIFREG(mif_frame,
574	    HME_MIF_FRREAD | (phyad << HME_MIF_FRPHYAD_SHIFT) |
575	    (regad << HME_MIF_FRREGAD_SHIFT));
576/*
577 *	HMEDELAY((*framerp & HME_MIF_FRTA0), HMEMAXRSTDELAY);
578 */
579	HMEDELAY((GET_MIFREG(mif_frame) & HME_MIF_FRTA0), 300);
580	frame = GET_MIFREG(mif_frame);
581	CHECK_MIFREG();
582
583	PUT_MACREG(xifc, tmp_xif);
584	PUT_MIFREG(mif_cfg, tmp_mif);
585
586	if ((frame & HME_MIF_FRTA0) == 0) {
587
588
589		HME_FAULT_MSG1(hmep, SEVERITY_UNKNOWN, MII_MSG,
590		    "MIF Read failure");
591		return (0xffff);
592	}
593	return ((uint16_t)(frame & HME_MIF_FRDATA));
594}
595
596static void
597hme_mii_write(void *arg, uint8_t phyad, uint8_t regad, uint16_t data)
598{
599	struct hme *hmep = arg;
600	uint32_t frame;
601	uint32_t tmp_mif;
602	uint32_t tmp_xif;
603
604	tmp_mif = GET_MIFREG(mif_cfg);
605	tmp_xif = GET_MACREG(xifc);
606
607	switch (phyad) {
608	case HME_EXTERNAL_PHYAD:
609		PUT_MIFREG(mif_cfg, tmp_mif | HME_MIF_CFGPS);
610		PUT_MACREG(xifc, tmp_xif | BMAC_XIFC_MIIBUFDIS);
611		break;
612	case HME_INTERNAL_PHYAD:
613		PUT_MIFREG(mif_cfg, tmp_mif & ~(HME_MIF_CFGPS));
614		PUT_MACREG(xifc, tmp_xif & ~(BMAC_XIFC_MIIBUFDIS));
615		break;
616	default:
617		return;
618	}
619
620	if (!hmep->hme_frame_enable) {
621		hme_bb_mii_write(hmep, phyad, regad, data);
622		PUT_MACREG(xifc, tmp_xif);
623		PUT_MIFREG(mif_cfg, tmp_mif);
624		return;
625	}
626
627	PUT_MIFREG(mif_frame,
628	    HME_MIF_FRWRITE | (phyad << HME_MIF_FRPHYAD_SHIFT) |
629	    (regad << HME_MIF_FRREGAD_SHIFT) | data);
630/*
631 *	HMEDELAY((*framerp & HME_MIF_FRTA0), HMEMAXRSTDELAY);
632 */
633	HMEDELAY((GET_MIFREG(mif_frame) & HME_MIF_FRTA0), 300);
634	frame = GET_MIFREG(mif_frame);
635	PUT_MACREG(xifc, tmp_xif);
636	PUT_MIFREG(mif_cfg, tmp_mif);
637	CHECK_MIFREG();
638	if ((frame & HME_MIF_FRTA0) == 0) {
639		HME_FAULT_MSG1(hmep, SEVERITY_MID, MII_MSG,
640		    "MIF Write failure");
641	}
642}
643
644static void
645hme_mii_notify(void *arg, link_state_t link)
646{
647	struct hme *hmep = arg;
648
649	if (link == LINK_STATE_UP) {
650		(void) hmeinit(hmep);
651	}
652	mac_link_update(hmep->hme_mh, link);
653}
654
655/* <<<<<<<<<<<<<<<<<<<<<<<<<<<  LOADABLE ENTRIES  >>>>>>>>>>>>>>>>>>>>>>> */
656
657int
658_init(void)
659{
660	int	status;
661
662	mac_init_ops(&hme_dev_ops, "hme");
663	if ((status = mod_install(&modlinkage)) != 0) {
664		mac_fini_ops(&hme_dev_ops);
665	}
666	return (status);
667}
668
669int
670_fini(void)
671{
672	int	status;
673
674	if ((status = mod_remove(&modlinkage)) == 0) {
675		mac_fini_ops(&hme_dev_ops);
676	}
677	return (status);
678}
679
680int
681_info(struct modinfo *modinfop)
682{
683	return (mod_info(&modlinkage, modinfop));
684}
685
686/*
687 * ddi_dma_sync() a TMD or RMD descriptor.
688 */
689#define	HMESYNCRMD(num, who)				\
690	(void) ddi_dma_sync(hmep->hme_rmd_dmah,		\
691	    (num * sizeof (struct hme_rmd)),		\
692	    sizeof (struct hme_rmd),			\
693	    who)
694
695#define	HMESYNCTMD(num, who)				\
696	(void) ddi_dma_sync(hmep->hme_tmd_dmah,		\
697	    (num * sizeof (struct hme_tmd)),		\
698	    sizeof (struct hme_tmd),			\
699	    who)
700
701/*
702 * Ethernet broadcast address definition.
703 */
704static	struct ether_addr	etherbroadcastaddr = {
705	0xff, 0xff, 0xff, 0xff, 0xff, 0xff
706};
707
708/*
709 * MIB II broadcast/multicast packets
710 */
711#define	IS_BROADCAST(pkt) (bcmp(pkt, &etherbroadcastaddr, ETHERADDRL) == 0)
712#define	IS_MULTICAST(pkt) ((pkt[0] & 01) == 1)
713#define	BUMP_InNUcast(hmep, pkt) \
714	if (IS_MULTICAST(pkt)) {			       \
715		if (IS_BROADCAST(pkt)) {		       \
716			hmep->hme_brdcstrcv++;		       \
717		} else {				       \
718			hmep->hme_multircv++;		       \
719		}					       \
720	}
721#define	BUMP_OutNUcast(hmep, pkt) \
722	if (IS_MULTICAST(pkt)) {			       \
723		if (IS_BROADCAST(pkt)) {		       \
724			hmep->hme_brdcstxmt++;		       \
725		} else {				       \
726			hmep->hme_multixmt++;		       \
727		}					       \
728	}
729
730static int
731hme_create_prop_from_kw(dev_info_t *dip, char *vpdname, char *vpdstr)
732{
733	char propstr[80];
734	int i, needprop = 0;
735	struct ether_addr local_mac;
736
737	if (strcmp(vpdname, "NA") == 0) {
738		(void) strcpy(propstr, "local-mac-address");
739		needprop = 1;
740	} else if (strcmp(vpdname, "Z0") == 0) {
741		(void) strcpy(propstr, "model");
742		needprop = 1;
743	} else if (strcmp(vpdname, "Z1") == 0) {
744		(void) strcpy(propstr, "board-model");
745		needprop = 1;
746	}
747
748	if (needprop == 1) {
749
750		if (strcmp(propstr, "local-mac-address") == 0) {
751			for (i = 0; i < ETHERADDRL; i++)
752				local_mac.ether_addr_octet[i] =
753				    (uchar_t)vpdstr[i];
754			if (ddi_prop_create(DDI_DEV_T_NONE, dip,
755			    DDI_PROP_CANSLEEP, propstr,
756			    (char *)local_mac.ether_addr_octet, ETHERADDRL)
757			    != DDI_SUCCESS) {
758				return (DDI_FAILURE);
759			}
760		} else {
761			if (ddi_prop_create(DDI_DEV_T_NONE, dip,
762			    DDI_PROP_CANSLEEP, propstr, vpdstr,
763			    strlen(vpdstr)+1) != DDI_SUCCESS) {
764				return (DDI_FAILURE);
765			}
766		}
767	}
768	return (0);
769}
770
771/*
772 * Get properties from old VPD
773 * for PCI cards
774 */
775static int
776hme_get_oldvpd_props(dev_info_t *dip, int vpd_base)
777{
778	struct hme *hmep;
779	int vpd_start, vpd_len, kw_start, kw_len, kw_ptr;
780	char kw_namestr[3];
781	char kw_fieldstr[256];
782	int i;
783
784	hmep = ddi_get_driver_private(dip);
785
786	vpd_start = vpd_base;
787
788	if ((GET_ROM8(&hmep->hme_romp[vpd_start]) & 0xff) != 0x90) {
789		return (1); /* error */
790	} else {
791		vpd_len = 9;
792	}
793
794	/* Get local-mac-address */
795	kw_start = vpd_start + 3; /* Location of 1st keyword */
796	kw_ptr = kw_start;
797	while ((kw_ptr - kw_start) < vpd_len) { /* Get all keywords */
798		kw_namestr[0] = GET_ROM8(&hmep->hme_romp[kw_ptr]);
799		kw_namestr[1] = GET_ROM8(&hmep->hme_romp[kw_ptr+1]);
800		kw_namestr[2] = '\0';
801		kw_len = (int)(GET_ROM8(&hmep->hme_romp[kw_ptr+2]) & 0xff);
802		for (i = 0, kw_ptr += 3; i < kw_len; i++)
803			kw_fieldstr[i] = GET_ROM8(&hmep->hme_romp[kw_ptr+i]);
804		kw_fieldstr[i] = '\0';
805		if (hme_create_prop_from_kw(dip, kw_namestr, kw_fieldstr)) {
806			return (DDI_FAILURE);
807		}
808		kw_ptr += kw_len;
809	} /* next keyword */
810
811	if (ddi_prop_create(DDI_DEV_T_NONE, dip, DDI_PROP_CANSLEEP, "model",
812	    "SUNW,cheerio", strlen("SUNW,cheerio")+1) != DDI_SUCCESS) {
813		return (DDI_FAILURE);
814	}
815	return (0);
816}
817
818
819/*
820 * Get properties from new VPD
821 * for CompactPCI cards
822 */
823static int
824hme_get_newvpd_props(dev_info_t *dip, int vpd_base)
825{
826	struct hme *hmep;
827	int vpd_start, vpd_len, kw_start, kw_len, kw_ptr;
828	char kw_namestr[3];
829	char kw_fieldstr[256];
830	int maxvpdsize, i;
831
832	hmep = ddi_get_driver_private(dip);
833
834	maxvpdsize = 1024; /* Real size not known until after it is read */
835
836	vpd_start = (int)((GET_ROM8(&(hmep->hme_romp[vpd_base+1])) & 0xff) |
837	    ((GET_ROM8(&hmep->hme_romp[vpd_base+2]) & 0xff) << 8)) +3;
838	vpd_start = vpd_base + vpd_start;
839	while (vpd_start < (vpd_base + maxvpdsize)) { /* Get all VPDs */
840		if ((GET_ROM8(&hmep->hme_romp[vpd_start]) & 0xff) != 0x90) {
841			break; /* no VPD found */
842		} else {
843			vpd_len = (int)((GET_ROM8(&hmep->hme_romp[vpd_start
844			    + 1]) & 0xff) | (GET_ROM8(&hmep->hme_romp[vpd_start
845			    + 2]) & 0xff) << 8);
846		}
847		/* Get all keywords in this VPD */
848		kw_start = vpd_start + 3; /* Location of 1st keyword */
849		kw_ptr = kw_start;
850		while ((kw_ptr - kw_start) < vpd_len) { /* Get all keywords */
851			kw_namestr[0] = GET_ROM8(&hmep->hme_romp[kw_ptr]);
852			kw_namestr[1] = GET_ROM8(&hmep->hme_romp[kw_ptr+1]);
853			kw_namestr[2] = '\0';
854			kw_len =
855			    (int)(GET_ROM8(&hmep->hme_romp[kw_ptr+2]) & 0xff);
856			for (i = 0, kw_ptr += 3; i < kw_len; i++)
857				kw_fieldstr[i] =
858				    GET_ROM8(&hmep->hme_romp[kw_ptr+i]);
859			kw_fieldstr[i] = '\0';
860			if (hme_create_prop_from_kw(dip, kw_namestr,
861			    kw_fieldstr)) {
862				return (DDI_FAILURE);
863			}
864			kw_ptr += kw_len;
865		} /* next keyword */
866		vpd_start += (vpd_len + 3);
867	} /* next VPD */
868	return (0);
869}
870
871
872/*
873 * Get properties from VPD
874 */
875static int
876hme_get_vpd_props(dev_info_t *dip)
877{
878	struct hme *hmep;
879	int v0, v1, vpd_base;
880	int i, epromsrchlimit;
881
882
883	hmep = ddi_get_driver_private(dip);
884
885	v0 = (int)(GET_ROM8(&(hmep->hme_romp[0])));
886	v1 = (int)(GET_ROM8(&(hmep->hme_romp[1])));
887	v0 = ((v0 & 0xff) << 8 | v1);
888
889	if ((v0 & 0xffff) != 0x55aa) {
890		cmn_err(CE_NOTE, " Valid pci prom not found \n");
891		return (1);
892	}
893
894	epromsrchlimit = 4096;
895	for (i = 2; i < epromsrchlimit; i++) {
896		/* "PCIR" */
897		if (((GET_ROM8(&(hmep->hme_romp[i])) & 0xff) == 'P') &&
898		    ((GET_ROM8(&(hmep->hme_romp[i+1])) & 0xff) == 'C') &&
899		    ((GET_ROM8(&(hmep->hme_romp[i+2])) & 0xff) == 'I') &&
900		    ((GET_ROM8(&(hmep->hme_romp[i+3])) & 0xff) == 'R')) {
901			vpd_base =
902			    (int)((GET_ROM8(&(hmep->hme_romp[i+8])) & 0xff) |
903			    (GET_ROM8(&(hmep->hme_romp[i+9])) & 0xff) << 8);
904			break; /* VPD pointer found */
905		}
906	}
907
908	/* No VPD found */
909	if (vpd_base == 0) {
910		cmn_err(CE_NOTE, " Vital Product Data pointer not found \n");
911		return (1);
912	}
913
914	v0 = (int)(GET_ROM8(&(hmep->hme_romp[vpd_base])));
915	if (v0 == 0x82) {
916		if (hme_get_newvpd_props(dip, vpd_base))
917			return (1);
918		return (0);
919	} else if (v0 == 0x90) {
920		/* If we are are SUNW,qfe card, look for the Nth "NA" descr */
921		if ((GET_ROM8(&hmep->hme_romp[vpd_base + 12])  != 0x79) &&
922		    GET_ROM8(&hmep->hme_romp[vpd_base + 4 * 12]) == 0x79) {
923			vpd_base += hmep->hme_devno * 12;
924		}
925		if (hme_get_oldvpd_props(dip, vpd_base))
926			return (1);
927		return (0);
928	} else
929		return (1);	/* unknown start byte in VPD */
930}
931
932/*
933 * For x86, the BIOS doesn't map the PCI Rom register for the qfe
934 * cards, so we have to extract it from the ebus bridge that is
935 * function zero of the same device.  This is a bit of an ugly hack.
936 * (The ebus bridge leaves the entire ROM mapped at base address
937 * register 0x10.)
938 */
939
940typedef struct {
941	struct hme 		*hmep;
942	dev_info_t		*parent;
943	uint8_t			bus, dev;
944	ddi_acc_handle_t	acch;
945	caddr_t			romp;
946} ebus_rom_t;
947
948static int
949hme_mapebusrom(dev_info_t *dip, void *arg)
950{
951	int		*regs;
952	unsigned	nregs;
953	int		reg;
954	ebus_rom_t	*rom = arg;
955	struct hme	*hmep = rom->hmep;
956
957	/*
958	 * We only want to look at our peers.  Skip our parent.
959	 */
960	if (dip == rom->parent) {
961		return (DDI_WALK_PRUNESIB);
962	}
963
964	if (ddi_get_parent(dip) != rom->parent)
965		return (DDI_WALK_CONTINUE);
966
967	if ((ddi_prop_lookup_int_array(DDI_DEV_T_ANY, dip, 0,
968	    "reg", &regs, &nregs)) != DDI_PROP_SUCCESS) {
969		return (DDI_WALK_PRUNECHILD);
970	}
971
972	if (nregs < 1) {
973		ddi_prop_free(regs);
974		return (DDI_WALK_PRUNECHILD);
975	}
976	reg = regs[0];
977	ddi_prop_free(regs);
978
979	/*
980	 * Look for function 0 on our bus and device.  If the device doesn't
981	 * match, it might be an alternate peer, in which case we don't want
982	 * to examine any of its children.
983	 */
984	if ((PCI_REG_BUS_G(reg) != rom->bus) ||
985	    (PCI_REG_DEV_G(reg) != rom->dev) ||
986	    (PCI_REG_FUNC_G(reg) != 0)) {
987		return (DDI_WALK_PRUNECHILD);
988	}
989
990	(void) ddi_regs_map_setup(dip, 1, &rom->romp, 0, 0, &hmep->hme_dev_attr,
991	    &rom->acch);
992	/*
993	 * If we can't map the registers, the caller will notice that
994	 * the acch is NULL.
995	 */
996	return (DDI_WALK_TERMINATE);
997}
998
999static int
1000hmeget_promebus(dev_info_t *dip)
1001{
1002	ebus_rom_t	rom;
1003	int		*regs;
1004	unsigned	nregs;
1005	struct hme	*hmep;
1006
1007	hmep = ddi_get_driver_private(dip);
1008
1009	bzero(&rom, sizeof (rom));
1010
1011	/*
1012	 * For x86, the BIOS doesn't map the PCI Rom register for the qfe
1013	 * cards, so we have to extract it from the eBus bridge that is
1014	 * function zero.  This is a bit of an ugly hack.
1015	 */
1016	if ((ddi_prop_lookup_int_array(DDI_DEV_T_ANY, dip, 0,
1017	    "reg", &regs, &nregs)) != DDI_PROP_SUCCESS) {
1018		return (DDI_FAILURE);
1019	}
1020
1021	if (nregs < 5) {
1022		ddi_prop_free(regs);
1023		return (DDI_FAILURE);
1024	}
1025	rom.hmep = hmep;
1026	rom.bus = PCI_REG_BUS_G(regs[0]);
1027	rom.dev = PCI_REG_DEV_G(regs[0]);
1028	hmep->hme_devno = rom.dev;
1029	rom.parent = ddi_get_parent(dip);
1030
1031	/*
1032	 * The implementation of ddi_walk_devs says that we must not
1033	 * be called during autoconfiguration.  However, it turns out
1034	 * that it is safe to call this during our attach routine,
1035	 * because we are not a nexus device.
1036	 *
1037	 * Previously we rooted our search at our immediate parent,
1038	 * but this triggered an assertion panic in debug kernels.
1039	 */
1040	ddi_walk_devs(ddi_root_node(), hme_mapebusrom, &rom);
1041
1042	if (rom.acch) {
1043		hmep->hme_romh = rom.acch;
1044		hmep->hme_romp = (unsigned char *)rom.romp;
1045		return (DDI_SUCCESS);
1046	}
1047	return (DDI_FAILURE);
1048}
1049
1050static int
1051hmeget_promprops(dev_info_t *dip)
1052{
1053	struct hme *hmep;
1054	int rom_bar;
1055	ddi_acc_handle_t cfg_handle;
1056	struct {
1057		uint16_t vendorid;
1058		uint16_t devid;
1059		uint16_t command;
1060		uint16_t status;
1061		uint32_t junk1;
1062		uint8_t cache_line;
1063		uint8_t latency;
1064		uint8_t header;
1065		uint8_t bist;
1066		uint32_t base;
1067		uint32_t base14;
1068		uint32_t base18;
1069		uint32_t base1c;
1070		uint32_t base20;
1071		uint32_t base24;
1072		uint32_t base28;
1073		uint32_t base2c;
1074		uint32_t base30;
1075	} *cfg_ptr;
1076
1077	hmep = ddi_get_driver_private(dip);
1078
1079
1080	/*
1081	 * map configuration space
1082	 */
1083	if (ddi_regs_map_setup(hmep->dip, 0, (caddr_t *)&cfg_ptr,
1084	    0, 0, &hmep->hme_dev_attr, &cfg_handle)) {
1085		return (DDI_FAILURE);
1086	}
1087
1088	/*
1089	 * Enable bus-master and memory accesses
1090	 */
1091	ddi_put16(cfg_handle, &cfg_ptr->command,
1092	    PCI_COMM_SERR_ENABLE | PCI_COMM_PARITY_DETECT |
1093	    PCI_COMM_MAE | PCI_COMM_ME);
1094
1095	/*
1096	 * Enable rom accesses
1097	 */
1098	rom_bar = ddi_get32(cfg_handle, &cfg_ptr->base30);
1099	ddi_put32(cfg_handle, &cfg_ptr->base30, rom_bar | 1);
1100
1101
1102	if ((ddi_regs_map_setup(dip, 2, (caddr_t *)&(hmep->hme_romp), 0, 0,
1103	    &hmep->hme_dev_attr, &hmep->hme_romh) != DDI_SUCCESS) &&
1104	    (hmeget_promebus(dip) != DDI_SUCCESS)) {
1105
1106		if (cfg_ptr)
1107			ddi_regs_map_free(&cfg_handle);
1108		return (DDI_FAILURE);
1109	} else {
1110		if (hme_get_vpd_props(dip))
1111			return (DDI_FAILURE);
1112	}
1113	if (hmep->hme_romp)
1114		ddi_regs_map_free(&hmep->hme_romh);
1115	if (cfg_ptr)
1116		ddi_regs_map_free(&cfg_handle);
1117	return (DDI_SUCCESS);
1118
1119}
1120
1121static void
1122hmeget_hm_rev_property(struct hme *hmep)
1123{
1124	int	hm_rev;
1125
1126
1127	hm_rev = hmep->asic_rev;
1128	switch (hm_rev) {
1129	case HME_2P1_REVID:
1130	case HME_2P1_REVID_OBP:
1131		HME_FAULT_MSG2(hmep, SEVERITY_NONE, DISPLAY_MSG,
1132		    "SBus 2.1 Found (Rev Id = %x)", hm_rev);
1133		hmep->hme_frame_enable = 1;
1134		break;
1135
1136	case HME_2P0_REVID:
1137		HME_FAULT_MSG2(hmep, SEVERITY_NONE, DISPLAY_MSG,
1138		    "SBus 2.0 Found (Rev Id = %x)", hm_rev);
1139		break;
1140
1141	case HME_1C0_REVID:
1142		HME_FAULT_MSG2(hmep, SEVERITY_NONE, DISPLAY_MSG,
1143		    "PCI IO 1.0 Found (Rev Id = %x)", hm_rev);
1144		break;
1145
1146	default:
1147		HME_FAULT_MSG3(hmep, SEVERITY_NONE, DISPLAY_MSG,
1148		    "%s (Rev Id = %x) Found",
1149		    (hm_rev == HME_2C0_REVID) ? "PCI IO 2.0" : "Sbus", hm_rev);
1150		hmep->hme_frame_enable = 1;
1151		hmep->hme_lance_mode_enable = 1;
1152		hmep->hme_rxcv_enable = 1;
1153		break;
1154	}
1155}
1156
1157/*
1158 * Interface exists: make available by filling in network interface
1159 * record.  System will initialize the interface when it is ready
1160 * to accept packets.
1161 */
1162int
1163hmeattach(dev_info_t *dip, ddi_attach_cmd_t cmd)
1164{
1165	struct hme *hmep;
1166	mac_register_t *macp = NULL;
1167	int 	regno;
1168	int hm_rev = 0;
1169	int prop_len = sizeof (int);
1170	ddi_acc_handle_t cfg_handle;
1171	struct {
1172		uint16_t vendorid;
1173		uint16_t devid;
1174		uint16_t command;
1175		uint16_t status;
1176		uint8_t revid;
1177		uint8_t j1;
1178		uint16_t j2;
1179	} *cfg_ptr;
1180
1181	switch (cmd) {
1182	case DDI_ATTACH:
1183		break;
1184
1185	case DDI_RESUME:
1186		if ((hmep = ddi_get_driver_private(dip)) == NULL)
1187			return (DDI_FAILURE);
1188
1189		hmep->hme_flags &= ~HMESUSPENDED;
1190
1191		mii_resume(hmep->hme_mii);
1192
1193		if (hmep->hme_started)
1194			(void) hmeinit(hmep);
1195		return (DDI_SUCCESS);
1196
1197	default:
1198		return (DDI_FAILURE);
1199	}
1200
1201	/*
1202	 * Allocate soft device data structure
1203	 */
1204	hmep = kmem_zalloc(sizeof (*hmep), KM_SLEEP);
1205
1206	/*
1207	 * Might as well set up elements of data structure
1208	 */
1209	hmep->dip =		dip;
1210	hmep->instance = 	ddi_get_instance(dip);
1211	hmep->pagesize =	ddi_ptob(dip, (ulong_t)1); /* IOMMU PSize */
1212
1213	/*
1214	 *  Might as well setup the driver private
1215	 * structure as part of the dip.
1216	 */
1217	ddi_set_driver_private(dip, hmep);
1218
1219	/*
1220	 * Reject this device if it's in a slave-only slot.
1221	 */
1222	if (ddi_slaveonly(dip) == DDI_SUCCESS) {
1223		HME_FAULT_MSG1(hmep, SEVERITY_UNKNOWN, CONFIG_MSG,
1224		    "Dev not used - dev in slave only slot");
1225		goto error_state;
1226	}
1227
1228	/*
1229	 * Map in the device registers.
1230	 *
1231	 * Reg # 0 is the Global register set
1232	 * Reg # 1 is the ETX register set
1233	 * Reg # 2 is the ERX register set
1234	 * Reg # 3 is the BigMAC register set.
1235	 * Reg # 4 is the MIF register set
1236	 */
1237	if (ddi_dev_nregs(dip, &regno) != (DDI_SUCCESS)) {
1238		HME_FAULT_MSG2(hmep, SEVERITY_HIGH, INIT_MSG,
1239		    ddi_nregs_fail_msg, regno);
1240		goto error_state;
1241	}
1242
1243	switch (regno) {
1244	case 5:
1245		hmep->hme_cheerio_mode = 0;
1246		break;
1247	case 2:
1248	case 3: /* for hot swap/plug, there will be 3 entries in "reg" prop */
1249		hmep->hme_cheerio_mode = 1;
1250		break;
1251	default:
1252		HME_FAULT_MSG1(hmep, SEVERITY_HIGH, INIT_MSG,
1253		    bad_num_regs_msg);
1254		goto error_state;
1255	}
1256
1257	/* Initialize device attributes structure */
1258	hmep->hme_dev_attr.devacc_attr_version = DDI_DEVICE_ATTR_V0;
1259
1260	if (hmep->hme_cheerio_mode)
1261		hmep->hme_dev_attr.devacc_attr_endian_flags =
1262		    DDI_STRUCTURE_LE_ACC;
1263	else
1264		hmep->hme_dev_attr.devacc_attr_endian_flags =
1265		    DDI_STRUCTURE_BE_ACC;
1266
1267	hmep->hme_dev_attr.devacc_attr_dataorder = DDI_STRICTORDER_ACC;
1268
1269	if (hmep->hme_cheerio_mode) {
1270		uint8_t		oldLT;
1271		uint8_t		newLT = 0;
1272		dev_info_t	*pdip;
1273		const char	*pdrvname;
1274
1275		/*
1276		 * Map the PCI config space
1277		 */
1278		if (pci_config_setup(dip, &hmep->pci_config_handle) !=
1279		    DDI_SUCCESS) {
1280			HME_FAULT_MSG1(hmep, SEVERITY_UNKNOWN, CONFIG_MSG,
1281			    "pci_config_setup() failed..");
1282			goto error_state;
1283		}
1284
1285		if (ddi_regs_map_setup(dip, 1,
1286		    (caddr_t *)&(hmep->hme_globregp), 0, 0,
1287		    &hmep->hme_dev_attr, &hmep->hme_globregh)) {
1288			HME_FAULT_MSG1(hmep, SEVERITY_UNKNOWN, CONFIG_MSG,
1289			    mregs_4global_reg_fail_msg);
1290			goto error_unmap;
1291		}
1292		hmep->hme_etxregh = hmep->hme_erxregh = hmep->hme_bmacregh =
1293		    hmep->hme_mifregh = hmep->hme_globregh;
1294
1295		hmep->hme_etxregp =
1296		    (void *)(((caddr_t)hmep->hme_globregp) + 0x2000);
1297		hmep->hme_erxregp =
1298		    (void *)(((caddr_t)hmep->hme_globregp) + 0x4000);
1299		hmep->hme_bmacregp =
1300		    (void *)(((caddr_t)hmep->hme_globregp) + 0x6000);
1301		hmep->hme_mifregp =
1302		    (void *)(((caddr_t)hmep->hme_globregp) + 0x7000);
1303
1304		/*
1305		 * Get parent pci bridge info.
1306		 */
1307		pdip = ddi_get_parent(dip);
1308		pdrvname = ddi_driver_name(pdip);
1309
1310		oldLT = pci_config_get8(hmep->pci_config_handle,
1311		    PCI_CONF_LATENCY_TIMER);
1312		/*
1313		 * Honor value set in /etc/system
1314		 * "set hme:pci_latency_timer=0xYY"
1315		 */
1316		if (pci_latency_timer)
1317			newLT = pci_latency_timer;
1318		/*
1319		 * Modify LT for simba
1320		 */
1321		else if (strcmp("simba", pdrvname) == 0)
1322			newLT = 0xf0;
1323		/*
1324		 * Ensure minimum cheerio latency timer of 0x50
1325		 * Usually OBP or pci bridge should set this value
1326		 * based on cheerio
1327		 * min_grant * 8(33MHz) = 0x50 = 0xa * 0x8
1328		 * Some system set cheerio LT at 0x40
1329		 */
1330		else if (oldLT < 0x40)
1331			newLT = 0x50;
1332
1333		/*
1334		 * Now program cheerio's pci latency timer with newLT
1335		 */
1336		if (newLT)
1337			pci_config_put8(hmep->pci_config_handle,
1338			    PCI_CONF_LATENCY_TIMER, (uchar_t)newLT);
1339	} else { /* Map register sets */
1340		if (ddi_regs_map_setup(dip, 0,
1341		    (caddr_t *)&(hmep->hme_globregp), 0, 0,
1342		    &hmep->hme_dev_attr, &hmep->hme_globregh)) {
1343			HME_FAULT_MSG1(hmep, SEVERITY_UNKNOWN, CONFIG_MSG,
1344			    mregs_4global_reg_fail_msg);
1345			goto error_state;
1346		}
1347		if (ddi_regs_map_setup(dip, 1,
1348		    (caddr_t *)&(hmep->hme_etxregp), 0, 0,
1349		    &hmep->hme_dev_attr, &hmep->hme_etxregh)) {
1350			HME_FAULT_MSG1(hmep, SEVERITY_UNKNOWN, CONFIG_MSG,
1351			    mregs_4etx_reg_fail_msg);
1352			goto error_unmap;
1353		}
1354		if (ddi_regs_map_setup(dip, 2,
1355		    (caddr_t *)&(hmep->hme_erxregp), 0, 0,
1356		    &hmep->hme_dev_attr, &hmep->hme_erxregh)) {
1357			HME_FAULT_MSG1(hmep, SEVERITY_UNKNOWN, CONFIG_MSG,
1358			    mregs_4erx_reg_fail_msg);
1359			goto error_unmap;
1360		}
1361		if (ddi_regs_map_setup(dip, 3,
1362		    (caddr_t *)&(hmep->hme_bmacregp), 0, 0,
1363		    &hmep->hme_dev_attr, &hmep->hme_bmacregh)) {
1364			HME_FAULT_MSG1(hmep, SEVERITY_UNKNOWN, CONFIG_MSG,
1365			    mregs_4bmac_reg_fail_msg);
1366			goto error_unmap;
1367		}
1368
1369		if (ddi_regs_map_setup(dip, 4,
1370		    (caddr_t *)&(hmep->hme_mifregp), 0, 0,
1371		    &hmep->hme_dev_attr, &hmep->hme_mifregh)) {
1372			HME_FAULT_MSG1(hmep, SEVERITY_UNKNOWN, CONFIG_MSG,
1373			    mregs_4mif_reg_fail_msg);
1374			goto error_unmap;
1375		}
1376	} /* Endif cheerio_mode */
1377
1378	/*
1379	 * Based on the hm-rev, set some capabilities
1380	 * Set up default capabilities for HM 2.0
1381	 */
1382	hmep->hme_frame_enable = 0;
1383	hmep->hme_lance_mode_enable = 0;
1384	hmep->hme_rxcv_enable = 0;
1385
1386	/* NEW routine to get the properties */
1387
1388	if (ddi_getlongprop_buf(DDI_DEV_T_ANY, hmep->dip, 0, "hm-rev",
1389	    (caddr_t)&hm_rev, &prop_len) == DDI_PROP_SUCCESS) {
1390
1391		hmep->asic_rev = hm_rev;
1392		hmeget_hm_rev_property(hmep);
1393	} else {
1394		/*
1395		 * hm_rev property not found so, this is
1396		 * case of hot insertion of card without interpreting fcode.
1397		 * Get it from revid in config space after mapping it.
1398		 */
1399		if (ddi_regs_map_setup(hmep->dip, 0, (caddr_t *)&cfg_ptr,
1400		    0, 0, &hmep->hme_dev_attr, &cfg_handle)) {
1401			return (DDI_FAILURE);
1402		}
1403		/*
1404		 * Since this is cheerio-based PCI card, we write 0xC in the
1405		 * top 4 bits(4-7) of hm-rev and retain the bottom(0-3) bits
1406		 * for Cheerio version(1.0 or 2.0 = 0xC0 or 0xC1)
1407		 */
1408		hm_rev = ddi_get8(cfg_handle, &cfg_ptr->revid);
1409		hm_rev = HME_1C0_REVID | (hm_rev & HME_REV_VERS_MASK);
1410		hmep->asic_rev = hm_rev;
1411		if (ddi_prop_create(DDI_DEV_T_NONE, dip, DDI_PROP_CANSLEEP,
1412		    "hm-rev", (caddr_t)&hm_rev, sizeof (hm_rev)) !=
1413		    DDI_SUCCESS) {
1414			HME_FAULT_MSG1(hmep, SEVERITY_UNKNOWN, AUTOCONFIG_MSG,
1415			    "ddi_prop_create error for hm_rev");
1416		}
1417		ddi_regs_map_free(&cfg_handle);
1418
1419		hmeget_hm_rev_property(hmep);
1420
1421		/* get info via VPD */
1422		if (hmeget_promprops(dip) != DDI_SUCCESS) {
1423			HME_FAULT_MSG1(hmep, SEVERITY_UNKNOWN, AUTOCONFIG_MSG,
1424			    "no promprops");
1425		}
1426	}
1427
1428	if (ddi_intr_hilevel(dip, 0)) {
1429		HME_FAULT_MSG1(hmep, SEVERITY_HIGH, NFATAL_ERR_MSG,
1430		    " high-level interrupts are not supported");
1431		goto error_unmap;
1432	}
1433
1434	/*
1435	 * Get intr. block cookie so that mutex locks can be initialized.
1436	 */
1437	if (ddi_get_iblock_cookie(dip, 0, &hmep->hme_cookie) != DDI_SUCCESS)
1438		goto error_unmap;
1439
1440	/*
1441	 * Initialize mutex's for this device.
1442	 */
1443	mutex_init(&hmep->hme_xmitlock, NULL, MUTEX_DRIVER, hmep->hme_cookie);
1444	mutex_init(&hmep->hme_intrlock, NULL, MUTEX_DRIVER, hmep->hme_cookie);
1445
1446	/*
1447	 * Quiesce the hardware.
1448	 */
1449	(void) hmestop(hmep);
1450
1451	/*
1452	 * Add interrupt to system
1453	 */
1454	if (ddi_add_intr(dip, 0, (ddi_iblock_cookie_t *)NULL,
1455	    (ddi_idevice_cookie_t *)NULL, hmeintr, (caddr_t)hmep)) {
1456		HME_FAULT_MSG1(hmep, SEVERITY_UNKNOWN, CONFIG_MSG,
1457		    add_intr_fail_msg);
1458		goto error_mutex;
1459	}
1460
1461	/*
1462	 * Set up the ethernet mac address.
1463	 */
1464	hme_setup_mac_address(hmep, dip);
1465
1466	if (!hmeinit_xfer_params(hmep))
1467		goto error_intr;
1468
1469	if (hmeburstsizes(hmep) == DDI_FAILURE) {
1470		HME_FAULT_MSG1(hmep, SEVERITY_HIGH, INIT_MSG, burst_size_msg);
1471		goto error_intr;
1472	}
1473
1474	if (hmeallocthings(hmep) != DDI_SUCCESS) {
1475		HME_FAULT_MSG1(hmep, SEVERITY_HIGH, CONFIG_MSG,
1476		    "resource allocation failed");
1477		goto error_intr;
1478	}
1479
1480	if (hmeallocbufs(hmep) != DDI_SUCCESS) {
1481		HME_FAULT_MSG1(hmep, SEVERITY_HIGH, CONFIG_MSG,
1482		    "buffer allocation failed");
1483		goto error_intr;
1484	}
1485
1486	hmestatinit(hmep);
1487
1488	/* our external (preferred) PHY is at address 0 */
1489	(void) ddi_prop_update_int(DDI_DEV_T_NONE, dip, "first-phy", 0);
1490
1491	hmep->hme_mii = mii_alloc(hmep, dip, &hme_mii_ops);
1492	if (hmep->hme_mii == NULL) {
1493		HME_FAULT_MSG1(hmep, SEVERITY_HIGH, CONFIG_MSG,
1494		    "mii_alloc failed");
1495		goto error_intr;
1496	}
1497	/* force a probe for the PHY */
1498	mii_probe(hmep->hme_mii);
1499
1500	if ((macp = mac_alloc(MAC_VERSION)) == NULL) {
1501		HME_FAULT_MSG1(hmep, SEVERITY_HIGH, CONFIG_MSG,
1502		    "mac_alloc failed");
1503		goto error_intr;
1504	}
1505	macp->m_type_ident = MAC_PLUGIN_IDENT_ETHER;
1506	macp->m_driver = hmep;
1507	macp->m_dip = dip;
1508	macp->m_src_addr = hmep->hme_ouraddr.ether_addr_octet;
1509	macp->m_callbacks = &hme_m_callbacks;
1510	macp->m_min_sdu = 0;
1511	macp->m_max_sdu = ETHERMTU;
1512	macp->m_margin = VLAN_TAGSZ;
1513	macp->m_priv_props = hme_priv_prop;
1514	if (mac_register(macp, &hmep->hme_mh) != 0) {
1515		mac_free(macp);
1516		goto error_intr;
1517	}
1518
1519	mac_free(macp);
1520
1521	ddi_report_dev(dip);
1522	return (DDI_SUCCESS);
1523
1524	/*
1525	 * Failure Exit
1526	 */
1527
1528error_intr:
1529	if (hmep->hme_cookie)
1530		ddi_remove_intr(dip, 0, (ddi_iblock_cookie_t)0);
1531
1532	if (hmep->hme_mii)
1533		mii_free(hmep->hme_mii);
1534
1535error_mutex:
1536	mutex_destroy(&hmep->hme_xmitlock);
1537	mutex_destroy(&hmep->hme_intrlock);
1538
1539error_unmap:
1540	if (hmep->hme_globregh)
1541		ddi_regs_map_free(&hmep->hme_globregh);
1542	if (hmep->hme_cheerio_mode == 0) {
1543		if (hmep->hme_etxregh)
1544			ddi_regs_map_free(&hmep->hme_etxregh);
1545		if (hmep->hme_erxregh)
1546			ddi_regs_map_free(&hmep->hme_erxregh);
1547		if (hmep->hme_bmacregh)
1548			ddi_regs_map_free(&hmep->hme_bmacregh);
1549		if (hmep->hme_mifregh)
1550			ddi_regs_map_free(&hmep->hme_mifregh);
1551	} else {
1552		if (hmep->pci_config_handle)
1553			(void) pci_config_teardown(&hmep->pci_config_handle);
1554		hmep->hme_etxregh = hmep->hme_erxregh = hmep->hme_bmacregh =
1555		    hmep->hme_mifregh = hmep->hme_globregh = NULL;
1556	}
1557
1558error_state:
1559	hmefreethings(hmep);
1560	hmefreebufs(hmep);
1561
1562	if (hmep) {
1563		kmem_free((caddr_t)hmep, sizeof (*hmep));
1564		ddi_set_driver_private(dip, NULL);
1565	}
1566
1567	return (DDI_FAILURE);
1568}
1569
1570int
1571hmedetach(dev_info_t *dip, ddi_detach_cmd_t cmd)
1572{
1573	struct hme *hmep;
1574
1575	if ((hmep = ddi_get_driver_private(dip)) == NULL)
1576		return (DDI_FAILURE);
1577
1578	switch (cmd) {
1579	case DDI_DETACH:
1580		break;
1581
1582	case DDI_SUSPEND:
1583		mii_suspend(hmep->hme_mii);
1584		hmep->hme_flags |= HMESUSPENDED;
1585		hmeuninit(hmep);
1586		return (DDI_SUCCESS);
1587
1588	default:
1589		return (DDI_FAILURE);
1590	}
1591
1592
1593	if (mac_unregister(hmep->hme_mh) != 0) {
1594		return (DDI_FAILURE);
1595	}
1596
1597	/*
1598	 * Make driver quiescent, we don't want to prevent the
1599	 * detach on failure.  Note that this should be redundant,
1600	 * since mac_stop should already have called hmeuninit().
1601	 */
1602	if (!(hmep->hme_flags & HMESUSPENDED)) {
1603		(void) hmestop(hmep);
1604	}
1605
1606	if (hmep->hme_mii)
1607		mii_free(hmep->hme_mii);
1608
1609	/*
1610	 * Remove instance of the intr
1611	 */
1612	ddi_remove_intr(dip, 0, (ddi_iblock_cookie_t)0);
1613
1614	/*
1615	 * Unregister kstats.
1616	 */
1617	if (hmep->hme_ksp != NULL)
1618		kstat_delete(hmep->hme_ksp);
1619	if (hmep->hme_intrstats != NULL)
1620		kstat_delete(hmep->hme_intrstats);
1621
1622	hmep->hme_ksp = NULL;
1623	hmep->hme_intrstats = NULL;
1624
1625	/*
1626	 * Destroy all mutexes and data structures allocated during
1627	 * attach time.
1628	 *
1629	 * Note: at this time we should be the only thread accessing
1630	 * the structures for this instance.
1631	 */
1632
1633	if (hmep->hme_globregh)
1634		ddi_regs_map_free(&hmep->hme_globregh);
1635	if (hmep->hme_cheerio_mode == 0) {
1636		if (hmep->hme_etxregh)
1637			ddi_regs_map_free(&hmep->hme_etxregh);
1638		if (hmep->hme_erxregh)
1639			ddi_regs_map_free(&hmep->hme_erxregh);
1640		if (hmep->hme_bmacregh)
1641			ddi_regs_map_free(&hmep->hme_bmacregh);
1642		if (hmep->hme_mifregh)
1643			ddi_regs_map_free(&hmep->hme_mifregh);
1644	} else {
1645		if (hmep->pci_config_handle)
1646			(void) pci_config_teardown(&hmep->pci_config_handle);
1647		hmep->hme_etxregh = hmep->hme_erxregh = hmep->hme_bmacregh =
1648		    hmep->hme_mifregh = hmep->hme_globregh = NULL;
1649	}
1650
1651	mutex_destroy(&hmep->hme_xmitlock);
1652	mutex_destroy(&hmep->hme_intrlock);
1653
1654	hmefreethings(hmep);
1655	hmefreebufs(hmep);
1656
1657	ddi_set_driver_private(dip, NULL);
1658	kmem_free(hmep, sizeof (struct hme));
1659
1660	return (DDI_SUCCESS);
1661}
1662
1663int
1664hmequiesce(dev_info_t *dip)
1665{
1666	struct hme *hmep;
1667
1668	if ((hmep = ddi_get_driver_private(dip)) == NULL)
1669		return (DDI_FAILURE);
1670
1671	(void) hmestop(hmep);
1672	return (DDI_SUCCESS);
1673}
1674
1675static boolean_t
1676hmeinit_xfer_params(struct hme *hmep)
1677{
1678	int hme_ipg1_conf, hme_ipg2_conf;
1679	int hme_ipg0_conf, hme_lance_mode_conf;
1680	int prop_len = sizeof (int);
1681	dev_info_t *dip;
1682
1683	dip = hmep->dip;
1684
1685	/*
1686	 * Set up the start-up values for user-configurable parameters
1687	 * Get the values from the global variables first.
1688	 * Use the MASK to limit the value to allowed maximum.
1689	 */
1690	hmep->hme_ipg1 = hme_ipg1 & HME_MASK_8BIT;
1691	hmep->hme_ipg2 = hme_ipg2 & HME_MASK_8BIT;
1692	hmep->hme_ipg0 = hme_ipg0 & HME_MASK_5BIT;
1693
1694	/*
1695	 * Get the parameter values configured in .conf file.
1696	 */
1697	if (ddi_getlongprop_buf(DDI_DEV_T_ANY, dip, 0, "ipg1",
1698	    (caddr_t)&hme_ipg1_conf, &prop_len) == DDI_PROP_SUCCESS) {
1699		hmep->hme_ipg1 = hme_ipg1_conf & HME_MASK_8BIT;
1700	}
1701
1702	if (ddi_getlongprop_buf(DDI_DEV_T_ANY, dip, 0, "ipg2",
1703	    (caddr_t)&hme_ipg2_conf, &prop_len) == DDI_PROP_SUCCESS) {
1704		hmep->hme_ipg2 = hme_ipg2_conf & HME_MASK_8BIT;
1705	}
1706
1707	if (ddi_getlongprop_buf(DDI_DEV_T_ANY, dip, 0, "ipg0",
1708	    (caddr_t)&hme_ipg0_conf, &prop_len) == DDI_PROP_SUCCESS) {
1709		hmep->hme_ipg0 = hme_ipg0_conf & HME_MASK_5BIT;
1710	}
1711
1712	if (ddi_getlongprop_buf(DDI_DEV_T_ANY, dip, 0, "lance_mode",
1713	    (caddr_t)&hme_lance_mode_conf, &prop_len) == DDI_PROP_SUCCESS) {
1714		hmep->hme_lance_mode = hme_lance_mode_conf & HME_MASK_1BIT;
1715	}
1716
1717	return (B_TRUE);
1718}
1719
1720/*
1721 * Return 0 upon success, 1 on failure.
1722 */
1723static uint_t
1724hmestop(struct hme *hmep)
1725{
1726	/*
1727	 * Disable the Tx dma engine.
1728	 */
1729	PUT_ETXREG(config, (GET_ETXREG(config) & ~HMET_CONFIG_TXDMA_EN));
1730	HMEDELAY(((GET_ETXREG(state_mach) & 0x1f) == 0x1), HMEMAXRSTDELAY);
1731
1732	/*
1733	 * Disable the Rx dma engine.
1734	 */
1735	PUT_ERXREG(config, (GET_ERXREG(config) & ~HMER_CONFIG_RXDMA_EN));
1736	HMEDELAY(((GET_ERXREG(state_mach) & 0x3f) == 0), HMEMAXRSTDELAY);
1737
1738	/*
1739	 * By this time all things should be quiet, so hit the
1740	 * chip with a reset.
1741	 */
1742	PUT_GLOBREG(reset, HMEG_RESET_GLOBAL);
1743
1744	HMEDELAY((GET_GLOBREG(reset) == 0), HMEMAXRSTDELAY);
1745	if (GET_GLOBREG(reset)) {
1746		return (1);
1747	}
1748
1749	CHECK_GLOBREG();
1750	return (0);
1751}
1752
1753static int
1754hmestat_kstat_update(kstat_t *ksp, int rw)
1755{
1756	struct hme *hmep;
1757	struct hmekstat *hkp;
1758
1759	hmep = (struct hme *)ksp->ks_private;
1760	hkp = (struct hmekstat *)ksp->ks_data;
1761
1762	if (rw != KSTAT_READ)
1763		return (EACCES);
1764
1765	/*
1766	 * Update all the stats by reading all the counter registers.
1767	 * Counter register stats are not updated till they overflow
1768	 * and interrupt.
1769	 */
1770
1771	mutex_enter(&hmep->hme_xmitlock);
1772	if (hmep->hme_flags & HMERUNNING) {
1773		hmereclaim(hmep);
1774		hmesavecntrs(hmep);
1775	}
1776	mutex_exit(&hmep->hme_xmitlock);
1777
1778	hkp->hk_cvc.value.ul		= hmep->hme_cvc;
1779	hkp->hk_lenerr.value.ul		= hmep->hme_lenerr;
1780	hkp->hk_buff.value.ul		= hmep->hme_buff;
1781	hkp->hk_missed.value.ul		= hmep->hme_missed;
1782	hkp->hk_allocbfail.value.ul	= hmep->hme_allocbfail;
1783	hkp->hk_babl.value.ul		= hmep->hme_babl;
1784	hkp->hk_tmder.value.ul		= hmep->hme_tmder;
1785	hkp->hk_txlaterr.value.ul	= hmep->hme_txlaterr;
1786	hkp->hk_rxlaterr.value.ul	= hmep->hme_rxlaterr;
1787	hkp->hk_slvparerr.value.ul	= hmep->hme_slvparerr;
1788	hkp->hk_txparerr.value.ul	= hmep->hme_txparerr;
1789	hkp->hk_rxparerr.value.ul	= hmep->hme_rxparerr;
1790	hkp->hk_slverrack.value.ul	= hmep->hme_slverrack;
1791	hkp->hk_txerrack.value.ul	= hmep->hme_txerrack;
1792	hkp->hk_rxerrack.value.ul	= hmep->hme_rxerrack;
1793	hkp->hk_txtagerr.value.ul	= hmep->hme_txtagerr;
1794	hkp->hk_rxtagerr.value.ul	= hmep->hme_rxtagerr;
1795	hkp->hk_eoperr.value.ul		= hmep->hme_eoperr;
1796	hkp->hk_notmds.value.ul		= hmep->hme_notmds;
1797	hkp->hk_notbufs.value.ul	= hmep->hme_notbufs;
1798	hkp->hk_norbufs.value.ul	= hmep->hme_norbufs;
1799
1800	/*
1801	 * Debug kstats
1802	 */
1803	hkp->hk_inits.value.ul		= hmep->inits;
1804	hkp->hk_phyfail.value.ul	= hmep->phyfail;
1805
1806	/*
1807	 * xcvr kstats
1808	 */
1809	hkp->hk_asic_rev.value.ul	= hmep->asic_rev;
1810
1811	return (0);
1812}
1813
1814static void
1815hmestatinit(struct hme *hmep)
1816{
1817	struct	kstat	*ksp;
1818	struct	hmekstat	*hkp;
1819	const char *driver;
1820	int	instance;
1821	char	buf[16];
1822
1823	instance = hmep->instance;
1824	driver = ddi_driver_name(hmep->dip);
1825
1826	if ((ksp = kstat_create(driver, instance,
1827	    "driver_info", "net", KSTAT_TYPE_NAMED,
1828	    sizeof (struct hmekstat) / sizeof (kstat_named_t), 0)) == NULL) {
1829		HME_FAULT_MSG1(hmep, SEVERITY_UNKNOWN, INIT_MSG,
1830		    "kstat_create failed");
1831		return;
1832	}
1833
1834	(void) snprintf(buf, sizeof (buf), "%sc%d", driver, instance);
1835	hmep->hme_intrstats = kstat_create(driver, instance, buf, "controller",
1836	    KSTAT_TYPE_INTR, 1, KSTAT_FLAG_PERSISTENT);
1837	if (hmep->hme_intrstats)
1838		kstat_install(hmep->hme_intrstats);
1839
1840	hmep->hme_ksp = ksp;
1841	hkp = (struct hmekstat *)ksp->ks_data;
1842	kstat_named_init(&hkp->hk_cvc,			"code_violations",
1843	    KSTAT_DATA_ULONG);
1844	kstat_named_init(&hkp->hk_lenerr,		"len_errors",
1845	    KSTAT_DATA_ULONG);
1846	kstat_named_init(&hkp->hk_buff,			"buff",
1847	    KSTAT_DATA_ULONG);
1848	kstat_named_init(&hkp->hk_missed,		"missed",
1849	    KSTAT_DATA_ULONG);
1850	kstat_named_init(&hkp->hk_nocanput,		"nocanput",
1851	    KSTAT_DATA_ULONG);
1852	kstat_named_init(&hkp->hk_allocbfail,		"allocbfail",
1853	    KSTAT_DATA_ULONG);
1854	kstat_named_init(&hkp->hk_babl,			"babble",
1855	    KSTAT_DATA_ULONG);
1856	kstat_named_init(&hkp->hk_tmder,		"tmd_error",
1857	    KSTAT_DATA_ULONG);
1858	kstat_named_init(&hkp->hk_txlaterr,		"tx_late_error",
1859	    KSTAT_DATA_ULONG);
1860	kstat_named_init(&hkp->hk_rxlaterr,		"rx_late_error",
1861	    KSTAT_DATA_ULONG);
1862	kstat_named_init(&hkp->hk_slvparerr,		"slv_parity_error",
1863	    KSTAT_DATA_ULONG);
1864	kstat_named_init(&hkp->hk_txparerr,		"tx_parity_error",
1865	    KSTAT_DATA_ULONG);
1866	kstat_named_init(&hkp->hk_rxparerr,		"rx_parity_error",
1867	    KSTAT_DATA_ULONG);
1868	kstat_named_init(&hkp->hk_slverrack,		"slv_error_ack",
1869	    KSTAT_DATA_ULONG);
1870	kstat_named_init(&hkp->hk_txerrack,		"tx_error_ack",
1871	    KSTAT_DATA_ULONG);
1872	kstat_named_init(&hkp->hk_rxerrack,		"rx_error_ack",
1873	    KSTAT_DATA_ULONG);
1874	kstat_named_init(&hkp->hk_txtagerr,		"tx_tag_error",
1875	    KSTAT_DATA_ULONG);
1876	kstat_named_init(&hkp->hk_rxtagerr,		"rx_tag_error",
1877	    KSTAT_DATA_ULONG);
1878	kstat_named_init(&hkp->hk_eoperr,		"eop_error",
1879	    KSTAT_DATA_ULONG);
1880	kstat_named_init(&hkp->hk_notmds,		"no_tmds",
1881	    KSTAT_DATA_ULONG);
1882	kstat_named_init(&hkp->hk_notbufs,		"no_tbufs",
1883	    KSTAT_DATA_ULONG);
1884	kstat_named_init(&hkp->hk_norbufs,		"no_rbufs",
1885	    KSTAT_DATA_ULONG);
1886
1887	/*
1888	 * Debugging kstats
1889	 */
1890	kstat_named_init(&hkp->hk_inits,		"inits",
1891	    KSTAT_DATA_ULONG);
1892	kstat_named_init(&hkp->hk_phyfail,		"phy_failures",
1893	    KSTAT_DATA_ULONG);
1894
1895	/*
1896	 * xcvr kstats
1897	 */
1898	kstat_named_init(&hkp->hk_asic_rev,		"asic_rev",
1899	    KSTAT_DATA_ULONG);
1900
1901	ksp->ks_update = hmestat_kstat_update;
1902	ksp->ks_private = (void *) hmep;
1903	kstat_install(ksp);
1904}
1905
1906int
1907hme_m_getprop(void *arg, const char *name, mac_prop_id_t num, uint_t sz,
1908    void *val)
1909{
1910	struct hme *hmep = arg;
1911	int value;
1912	int rv;
1913
1914	rv = mii_m_getprop(hmep->hme_mii, name, num, sz, val);
1915	if (rv != ENOTSUP)
1916		return (rv);
1917
1918	switch (num) {
1919	case MAC_PROP_PRIVATE:
1920		break;
1921	default:
1922		return (ENOTSUP);
1923	}
1924
1925	if (strcmp(name, "_ipg0") == 0) {
1926		value = hmep->hme_ipg0;
1927	} else if (strcmp(name, "_ipg1") == 0) {
1928		value = hmep->hme_ipg1;
1929	} else if (strcmp(name, "_ipg2") == 0) {
1930		value = hmep->hme_ipg2;
1931	} else if (strcmp(name, "_lance_mode") == 0) {
1932		value = hmep->hme_lance_mode;
1933	} else {
1934		return (ENOTSUP);
1935	}
1936	(void) snprintf(val, sz, "%d", value);
1937	return (0);
1938}
1939
1940static void
1941hme_m_propinfo(void *arg, const char *name, mac_prop_id_t num,
1942    mac_prop_info_handle_t mph)
1943{
1944	struct hme *hmep = arg;
1945
1946	mii_m_propinfo(hmep->hme_mii, name, num, mph);
1947
1948	switch (num) {
1949	case MAC_PROP_PRIVATE: {
1950		char valstr[64];
1951		int default_val;
1952
1953		if (strcmp(name, "_ipg0") == 0) {
1954			default_val = hme_ipg0;
1955		} else if (strcmp(name, "_ipg1") == 0) {
1956			default_val = hme_ipg1;
1957		} else if (strcmp(name, "_ipg2") == 0) {
1958			default_val = hme_ipg2;
1959		} if (strcmp(name, "_lance_mode") == 0) {
1960			default_val = hme_lance_mode;
1961		} else {
1962			return;
1963		}
1964
1965		(void) snprintf(valstr, sizeof (valstr), "%d", default_val);
1966		mac_prop_info_set_default_str(mph, valstr);
1967		break;
1968	}
1969	}
1970}
1971
1972int
1973hme_m_setprop(void *arg, const char *name, mac_prop_id_t num, uint_t sz,
1974    const void *val)
1975{
1976	struct hme *hmep = arg;
1977	int rv;
1978	long lval;
1979	boolean_t init = B_FALSE;
1980
1981	rv = mii_m_setprop(hmep->hme_mii, name, num, sz, val);
1982	if (rv != ENOTSUP)
1983		return (rv);
1984	rv = 0;
1985
1986	switch (num) {
1987	case MAC_PROP_PRIVATE:
1988		break;
1989	default:
1990		return (ENOTSUP);
1991	}
1992
1993	(void) ddi_strtol(val, NULL, 0, &lval);
1994
1995	if (strcmp(name, "_ipg1") == 0) {
1996		if ((lval >= 0) && (lval <= 255)) {
1997			hmep->hme_ipg1 = lval & 0xff;
1998			init = B_TRUE;
1999		} else {
2000			return (EINVAL);
2001		}
2002
2003	} else if (strcmp(name, "_ipg2") == 0) {
2004		if ((lval >= 0) && (lval <= 255)) {
2005			hmep->hme_ipg2 = lval & 0xff;
2006			init = B_TRUE;
2007		} else {
2008			return (EINVAL);
2009		}
2010
2011	} else if (strcmp(name, "_ipg0") == 0) {
2012		if ((lval >= 0) && (lval <= 31)) {
2013			hmep->hme_ipg0 = lval & 0xff;
2014			init = B_TRUE;
2015		} else {
2016			return (EINVAL);
2017		}
2018	} else if (strcmp(name, "_lance_mode") == 0) {
2019		if ((lval >= 0) && (lval <= 1)) {
2020			hmep->hme_lance_mode = lval & 0xff;
2021			init = B_TRUE;
2022		} else {
2023			return (EINVAL);
2024		}
2025
2026	} else {
2027		rv = ENOTSUP;
2028	}
2029
2030	if (init) {
2031		(void) hmeinit(hmep);
2032	}
2033	return (rv);
2034}
2035
2036
2037/*ARGSUSED*/
2038static boolean_t
2039hme_m_getcapab(void *arg, mac_capab_t cap, void *cap_data)
2040{
2041	switch (cap) {
2042	case MAC_CAPAB_HCKSUM:
2043		*(uint32_t *)cap_data = HCKSUM_INET_PARTIAL;
2044		return (B_TRUE);
2045	default:
2046		return (B_FALSE);
2047	}
2048}
2049
2050static int
2051hme_m_promisc(void *arg, boolean_t on)
2052{
2053	struct hme *hmep = arg;
2054
2055	hmep->hme_promisc = on;
2056	(void) hmeinit(hmep);
2057	return (0);
2058}
2059
2060static int
2061hme_m_unicst(void *arg, const uint8_t *macaddr)
2062{
2063	struct hme *hmep = arg;
2064
2065	/*
2066	 * Set new interface local address and re-init device.
2067	 * This is destructive to any other streams attached
2068	 * to this device.
2069	 */
2070	mutex_enter(&hmep->hme_intrlock);
2071	bcopy(macaddr, &hmep->hme_ouraddr, ETHERADDRL);
2072	mutex_exit(&hmep->hme_intrlock);
2073	(void) hmeinit(hmep);
2074	return (0);
2075}
2076
2077static int
2078hme_m_multicst(void *arg, boolean_t add, const uint8_t *macaddr)
2079{
2080	struct hme	*hmep = arg;
2081	uint32_t	ladrf_bit;
2082	boolean_t	doinit = B_FALSE;
2083
2084	/*
2085	 * If this address's bit was not already set in the local address
2086	 * filter, add it and re-initialize the Hardware.
2087	 */
2088	ladrf_bit = hmeladrf_bit(macaddr);
2089
2090	mutex_enter(&hmep->hme_intrlock);
2091	if (add) {
2092		hmep->hme_ladrf_refcnt[ladrf_bit]++;
2093		if (hmep->hme_ladrf_refcnt[ladrf_bit] == 1) {
2094			hmep->hme_ladrf[ladrf_bit >> 4] |=
2095			    1 << (ladrf_bit & 0xf);
2096			hmep->hme_multi++;
2097			doinit = B_TRUE;
2098		}
2099	} else {
2100		hmep->hme_ladrf_refcnt[ladrf_bit]--;
2101		if (hmep->hme_ladrf_refcnt[ladrf_bit] == 0) {
2102			hmep->hme_ladrf[ladrf_bit >> 4] &=
2103			    ~(1 << (ladrf_bit & 0xf));
2104			doinit = B_TRUE;
2105		}
2106	}
2107	mutex_exit(&hmep->hme_intrlock);
2108
2109	if (doinit) {
2110		(void) hmeinit(hmep);
2111	}
2112
2113	return (0);
2114}
2115
2116static int
2117hme_m_start(void *arg)
2118{
2119	struct hme *hmep = arg;
2120
2121	if (hmeinit(hmep) != 0) {
2122		/* initialization failed -- really want DL_INITFAILED */
2123		return (EIO);
2124	} else {
2125		hmep->hme_started = B_TRUE;
2126		mii_start(hmep->hme_mii);
2127		return (0);
2128	}
2129}
2130
2131static void
2132hme_m_stop(void *arg)
2133{
2134	struct hme *hmep = arg;
2135
2136	mii_stop(hmep->hme_mii);
2137	hmep->hme_started = B_FALSE;
2138	hmeuninit(hmep);
2139}
2140
2141static int
2142hme_m_stat(void *arg, uint_t stat, uint64_t *val)
2143{
2144	struct hme	*hmep = arg;
2145
2146	mutex_enter(&hmep->hme_xmitlock);
2147	if (hmep->hme_flags & HMERUNNING) {
2148		hmereclaim(hmep);
2149		hmesavecntrs(hmep);
2150	}
2151	mutex_exit(&hmep->hme_xmitlock);
2152
2153
2154	if (mii_m_getstat(hmep->hme_mii, stat, val) == 0) {
2155		return (0);
2156	}
2157	switch (stat) {
2158	case MAC_STAT_IPACKETS:
2159		*val = hmep->hme_ipackets;
2160		break;
2161	case MAC_STAT_RBYTES:
2162		*val = hmep->hme_rbytes;
2163		break;
2164	case MAC_STAT_IERRORS:
2165		*val = hmep->hme_ierrors;
2166		break;
2167	case MAC_STAT_OPACKETS:
2168		*val = hmep->hme_opackets;
2169		break;
2170	case MAC_STAT_OBYTES:
2171		*val = hmep->hme_obytes;
2172		break;
2173	case MAC_STAT_OERRORS:
2174		*val = hmep->hme_oerrors;
2175		break;
2176	case MAC_STAT_MULTIRCV:
2177		*val = hmep->hme_multircv;
2178		break;
2179	case MAC_STAT_MULTIXMT:
2180		*val = hmep->hme_multixmt;
2181		break;
2182	case MAC_STAT_BRDCSTRCV:
2183		*val = hmep->hme_brdcstrcv;
2184		break;
2185	case MAC_STAT_BRDCSTXMT:
2186		*val = hmep->hme_brdcstxmt;
2187		break;
2188	case MAC_STAT_UNDERFLOWS:
2189		*val = hmep->hme_uflo;
2190		break;
2191	case MAC_STAT_OVERFLOWS:
2192		*val = hmep->hme_oflo;
2193		break;
2194	case MAC_STAT_COLLISIONS:
2195		*val = hmep->hme_coll;
2196		break;
2197	case MAC_STAT_NORCVBUF:
2198		*val = hmep->hme_norcvbuf;
2199		break;
2200	case MAC_STAT_NOXMTBUF:
2201		*val = hmep->hme_noxmtbuf;
2202		break;
2203	case ETHER_STAT_LINK_DUPLEX:
2204		*val = hmep->hme_duplex;
2205		break;
2206	case ETHER_STAT_ALIGN_ERRORS:
2207		*val = hmep->hme_align_errors;
2208		break;
2209	case ETHER_STAT_FCS_ERRORS:
2210		*val = hmep->hme_fcs_errors;
2211		break;
2212	case ETHER_STAT_EX_COLLISIONS:
2213		*val = hmep->hme_excol;
2214		break;
2215	case ETHER_STAT_DEFER_XMTS:
2216		*val = hmep->hme_defer_xmts;
2217		break;
2218	case ETHER_STAT_SQE_ERRORS:
2219		*val = hmep->hme_sqe_errors;
2220		break;
2221	case ETHER_STAT_FIRST_COLLISIONS:
2222		*val = hmep->hme_fstcol;
2223		break;
2224	case ETHER_STAT_TX_LATE_COLLISIONS:
2225		*val = hmep->hme_tlcol;
2226		break;
2227	case ETHER_STAT_TOOLONG_ERRORS:
2228		*val = hmep->hme_toolong_errors;
2229		break;
2230	case ETHER_STAT_TOOSHORT_ERRORS:
2231		*val = hmep->hme_runt;
2232		break;
2233	case ETHER_STAT_CARRIER_ERRORS:
2234		*val = hmep->hme_carrier_errors;
2235		break;
2236	default:
2237		return (EINVAL);
2238	}
2239	return (0);
2240}
2241
2242static mblk_t *
2243hme_m_tx(void *arg, mblk_t *mp)
2244{
2245	struct hme *hmep = arg;
2246	mblk_t *next;
2247
2248	while (mp != NULL) {
2249		next = mp->b_next;
2250		mp->b_next = NULL;
2251		if (!hmestart(hmep, mp)) {
2252			mp->b_next = next;
2253			break;
2254		}
2255		mp = next;
2256	}
2257	return (mp);
2258}
2259
2260/*
2261 * Software IP checksum, for the edge cases that the
2262 * hardware can't handle.  See hmestart for more info.
2263 */
2264static uint16_t
2265hme_cksum(void *data, int len)
2266{
2267	uint16_t	*words = data;
2268	int		i, nwords = len / 2;
2269	uint32_t	sum = 0;
2270
2271	/* just add up the words */
2272	for (i = 0; i < nwords; i++) {
2273		sum += *words++;
2274	}
2275
2276	/* pick up residual byte ... assume even half-word allocations */
2277	if (len % 2) {
2278		sum += (*words & htons(0xff00));
2279	}
2280
2281	sum = (sum >> 16) + (sum & 0xffff);
2282	sum = (sum >> 16) + (sum & 0xffff);
2283
2284	return (~(sum & 0xffff));
2285}
2286
2287static boolean_t
2288hmestart(struct hme *hmep, mblk_t *mp)
2289{
2290	uint32_t	len;
2291	boolean_t	retval = B_TRUE;
2292	hmebuf_t	*tbuf;
2293	uint32_t	txptr;
2294
2295	uint32_t	csflags = 0;
2296	uint32_t	flags;
2297	uint32_t	start_offset;
2298	uint32_t	stuff_offset;
2299
2300	mac_hcksum_get(mp, &start_offset, &stuff_offset, NULL, NULL, &flags);
2301
2302	if (flags & HCK_PARTIALCKSUM) {
2303		if (get_ether_type(mp->b_rptr) == ETHERTYPE_VLAN) {
2304			start_offset += sizeof (struct ether_header) + 4;
2305			stuff_offset += sizeof (struct ether_header) + 4;
2306		} else {
2307			start_offset += sizeof (struct ether_header);
2308			stuff_offset += sizeof (struct ether_header);
2309		}
2310		csflags = HMETMD_CSENABL |
2311		    (start_offset << HMETMD_CSSTART_SHIFT) |
2312		    (stuff_offset << HMETMD_CSSTUFF_SHIFT);
2313	}
2314
2315	mutex_enter(&hmep->hme_xmitlock);
2316
2317	if (hmep->hme_flags & HMESUSPENDED) {
2318		hmep->hme_carrier_errors++;
2319		hmep->hme_oerrors++;
2320		goto bad;
2321	}
2322
2323	if (hmep->hme_txindex != hmep->hme_txreclaim) {
2324		hmereclaim(hmep);
2325	}
2326	if ((hmep->hme_txindex - HME_TMDMAX) == hmep->hme_txreclaim)
2327		goto notmds;
2328	txptr = hmep->hme_txindex % HME_TMDMAX;
2329	tbuf = &hmep->hme_tbuf[txptr];
2330
2331	/*
2332	 * Note that for checksum offload, the hardware cannot
2333	 * generate correct checksums if the packet is smaller than
2334	 * 64-bytes.  In such a case, we bcopy the packet and use
2335	 * a software checksum.
2336	 */
2337
2338	len = msgsize(mp);
2339	if (len < 64) {
2340		/* zero fill the padding */
2341		bzero(tbuf->kaddr, 64);
2342	}
2343	mcopymsg(mp, tbuf->kaddr);
2344
2345	if ((csflags != 0) && (len < 64)) {
2346		uint16_t sum;
2347		sum = hme_cksum(tbuf->kaddr + start_offset,
2348		    len - start_offset);
2349		bcopy(&sum, tbuf->kaddr + stuff_offset, sizeof (sum));
2350		csflags = 0;
2351	}
2352
2353	if (ddi_dma_sync(tbuf->dmah, 0, len, DDI_DMA_SYNC_FORDEV) ==
2354	    DDI_FAILURE) {
2355		HME_FAULT_MSG1(hmep, SEVERITY_HIGH, DDI_MSG,
2356		    "ddi_dma_sync failed");
2357	}
2358
2359	/*
2360	 * update MIB II statistics
2361	 */
2362	BUMP_OutNUcast(hmep, tbuf->kaddr);
2363
2364	PUT_TMD(txptr, tbuf->paddr, len,
2365	    HMETMD_OWN | HMETMD_SOP | HMETMD_EOP | csflags);
2366
2367	HMESYNCTMD(txptr, DDI_DMA_SYNC_FORDEV);
2368	hmep->hme_txindex++;
2369
2370	PUT_ETXREG(txpend, HMET_TXPEND_TDMD);
2371	CHECK_ETXREG();
2372
2373	mutex_exit(&hmep->hme_xmitlock);
2374
2375	hmep->hme_starts++;
2376	return (B_TRUE);
2377
2378bad:
2379	mutex_exit(&hmep->hme_xmitlock);
2380	freemsg(mp);
2381	return (B_TRUE);
2382
2383notmds:
2384	hmep->hme_notmds++;
2385	hmep->hme_wantw = B_TRUE;
2386	hmereclaim(hmep);
2387	retval = B_FALSE;
2388done:
2389	mutex_exit(&hmep->hme_xmitlock);
2390
2391	return (retval);
2392}
2393
2394/*
2395 * Initialize channel.
2396 * Return 0 on success, nonzero on error.
2397 *
2398 * The recommended sequence for initialization is:
2399 * 1. Issue a Global Reset command to the Ethernet Channel.
2400 * 2. Poll the Global_Reset bits until the execution of the reset has been
2401 *    completed.
2402 * 2(a). Use the MIF Frame/Output register to reset the transceiver.
2403 *	 Poll Register 0 to till the Resetbit is 0.
2404 * 2(b). Use the MIF Frame/Output register to set the PHY in in Normal-Op,
2405 *	 100Mbps and Non-Isolated mode. The main point here is to bring the
2406 *	 PHY out of Isolate mode so that it can generate the rx_clk and tx_clk
2407 *	 to the MII interface so that the Bigmac core can correctly reset
2408 *	 upon a software reset.
2409 * 2(c).  Issue another Global Reset command to the Ethernet Channel and poll
2410 *	  the Global_Reset bits till completion.
2411 * 3. Set up all the data structures in the host memory.
2412 * 4. Program the TX_MAC registers/counters (excluding the TX_MAC Configuration
2413 *    Register).
2414 * 5. Program the RX_MAC registers/counters (excluding the RX_MAC Configuration
2415 *    Register).
2416 * 6. Program the Transmit Descriptor Ring Base Address in the ETX.
2417 * 7. Program the Receive Descriptor Ring Base Address in the ERX.
2418 * 8. Program the Global Configuration and the Global Interrupt Mask Registers.
2419 * 9. Program the ETX Configuration register (enable the Transmit DMA channel).
2420 * 10. Program the ERX Configuration register (enable the Receive DMA channel).
2421 * 11. Program the XIF Configuration Register (enable the XIF).
2422 * 12. Program the RX_MAC Configuration Register (Enable the RX_MAC).
2423 * 13. Program the TX_MAC Configuration Register (Enable the TX_MAC).
2424 */
2425
2426
2427#ifdef FEPS_URUN_BUG
2428static int hme_palen = 32;
2429#endif
2430
2431static int
2432hmeinit(struct hme *hmep)
2433{
2434	uint32_t		i;
2435	int			ret;
2436	boolean_t		fdx;
2437	int			phyad;
2438
2439	/*
2440	 * Lock sequence:
2441	 *	hme_intrlock, hme_xmitlock.
2442	 */
2443	mutex_enter(&hmep->hme_intrlock);
2444
2445	/*
2446	 * Don't touch the hardware if we are suspended.  But don't
2447	 * fail either.  Some time later we may be resumed, and then
2448	 * we'll be back here to program the device using the settings
2449	 * in the soft state.
2450	 */
2451	if (hmep->hme_flags & HMESUSPENDED) {
2452		mutex_exit(&hmep->hme_intrlock);
2453		return (0);
2454	}
2455
2456	/*
2457	 * This should prevent us from clearing any interrupts that
2458	 * may occur by temporarily stopping interrupts from occurring
2459	 * for a short time.  We need to update the interrupt mask
2460	 * later in this function.
2461	 */
2462	PUT_GLOBREG(intmask, ~HMEG_MASK_MIF_INTR);
2463
2464
2465	/*
2466	 * Rearranged the mutex acquisition order to solve the deadlock
2467	 * situation as described in bug ID 4065896.
2468	 */
2469
2470	mutex_enter(&hmep->hme_xmitlock);
2471
2472	hmep->hme_flags = 0;
2473	hmep->hme_wantw = B_FALSE;
2474
2475	if (hmep->inits)
2476		hmesavecntrs(hmep);
2477
2478	/*
2479	 * Perform Global reset of the Sbus/FEPS ENET channel.
2480	 */
2481	(void) hmestop(hmep);
2482
2483	/*
2484	 * Clear all descriptors.
2485	 */
2486	bzero(hmep->hme_rmdp, HME_RMDMAX * sizeof (struct hme_rmd));
2487	bzero(hmep->hme_tmdp, HME_TMDMAX * sizeof (struct hme_tmd));
2488
2489	/*
2490	 * Hang out receive buffers.
2491	 */
2492	for (i = 0; i < HME_RMDMAX; i++) {
2493		PUT_RMD(i, hmep->hme_rbuf[i].paddr);
2494	}
2495
2496	/*
2497	 * DMA sync descriptors.
2498	 */
2499	(void) ddi_dma_sync(hmep->hme_rmd_dmah, 0, 0, DDI_DMA_SYNC_FORDEV);
2500	(void) ddi_dma_sync(hmep->hme_tmd_dmah, 0, 0, DDI_DMA_SYNC_FORDEV);
2501
2502	/*
2503	 * Reset RMD and TMD 'walking' pointers.
2504	 */
2505	hmep->hme_rxindex = 0;
2506	hmep->hme_txindex = hmep->hme_txreclaim = 0;
2507
2508	/*
2509	 * This is the right place to initialize MIF !!!
2510	 */
2511
2512	PUT_MIFREG(mif_imask, HME_MIF_INTMASK);	/* mask all interrupts */
2513
2514	if (!hmep->hme_frame_enable)
2515		PUT_MIFREG(mif_cfg, GET_MIFREG(mif_cfg) | HME_MIF_CFGBB);
2516	else
2517		PUT_MIFREG(mif_cfg, GET_MIFREG(mif_cfg) & ~HME_MIF_CFGBB);
2518						/* enable frame mode */
2519
2520	/*
2521	 * Depending on the transceiver detected, select the source
2522	 * of the clocks for the MAC. Without the clocks, TX_MAC does
2523	 * not reset. When the Global Reset is issued to the Sbus/FEPS
2524	 * ASIC, it selects Internal by default.
2525	 */
2526
2527	switch ((phyad = mii_get_addr(hmep->hme_mii))) {
2528	case -1:
2529		HME_FAULT_MSG1(hmep, SEVERITY_HIGH, XCVR_MSG, no_xcvr_msg);
2530		goto init_fail;	/* abort initialization */
2531
2532	case HME_INTERNAL_PHYAD:
2533		PUT_MACREG(xifc, 0);
2534		break;
2535	case HME_EXTERNAL_PHYAD:
2536		/* Isolate the Int. xcvr */
2537		PUT_MACREG(xifc, BMAC_XIFC_MIIBUFDIS);
2538		break;
2539	}
2540
2541	hmep->inits++;
2542
2543	/*
2544	 * Initialize BigMAC registers.
2545	 * First set the tx enable bit in tx config reg to 0 and poll on
2546	 * it till it turns to 0. Same for rx config, hash and address
2547	 * filter reg.
2548	 * Here is the sequence per the spec.
2549	 * MADD2 - MAC Address 2
2550	 * MADD1 - MAC Address 1
2551	 * MADD0 - MAC Address 0
2552	 * HASH3, HASH2, HASH1, HASH0 for group address
2553	 * AFR2, AFR1, AFR0 and AFMR for address filter mask
2554	 * Program RXMIN and RXMAX for packet length if not 802.3
2555	 * RXCFG - Rx config for not stripping CRC
2556	 * XXX Anything else to hme configured in RXCFG
2557	 * IPG1, IPG2, ALIMIT, SLOT, PALEN, PAPAT, TXSFD, JAM, TXMAX, TXMIN
2558	 * if not 802.3 compliant
2559	 * XIF register for speed selection
2560	 * MASK  - Interrupt mask
2561	 * Set bit 0 of TXCFG
2562	 * Set bit 0 of RXCFG
2563	 */
2564
2565	/*
2566	 * Initialize the TX_MAC registers
2567	 * Initialization of jamsize to work around rx crc bug
2568	 */
2569	PUT_MACREG(jam, jamsize);
2570
2571#ifdef	FEPS_URUN_BUG
2572	if (hme_urun_fix)
2573		PUT_MACREG(palen, hme_palen);
2574#endif
2575
2576	PUT_MACREG(ipg1, hmep->hme_ipg1);
2577	PUT_MACREG(ipg2, hmep->hme_ipg2);
2578
2579	PUT_MACREG(rseed,
2580	    ((hmep->hme_ouraddr.ether_addr_octet[0] << 8) & 0x3) |
2581	    hmep->hme_ouraddr.ether_addr_octet[1]);
2582
2583	/* Initialize the RX_MAC registers */
2584
2585	/*
2586	 * Program BigMAC with local individual ethernet address.
2587	 */
2588	PUT_MACREG(madd2, (hmep->hme_ouraddr.ether_addr_octet[4] << 8) |
2589	    hmep->hme_ouraddr.ether_addr_octet[5]);
2590	PUT_MACREG(madd1, (hmep->hme_ouraddr.ether_addr_octet[2] << 8) |
2591	    hmep->hme_ouraddr.ether_addr_octet[3]);
2592	PUT_MACREG(madd0, (hmep->hme_ouraddr.ether_addr_octet[0] << 8) |
2593	    hmep->hme_ouraddr.ether_addr_octet[1]);
2594
2595	/*
2596	 * Set up multicast address filter by passing all multicast
2597	 * addresses through a crc generator, and then using the
2598	 * low order 6 bits as a index into the 64 bit logical
2599	 * address filter. The high order three bits select the word,
2600	 * while the rest of the bits select the bit within the word.
2601	 */
2602	PUT_MACREG(hash0, hmep->hme_ladrf[0]);
2603	PUT_MACREG(hash1, hmep->hme_ladrf[1]);
2604	PUT_MACREG(hash2, hmep->hme_ladrf[2]);
2605	PUT_MACREG(hash3, hmep->hme_ladrf[3]);
2606
2607	/*
2608	 * Configure parameters to support VLAN.  (VLAN encapsulation adds
2609	 * four bytes.)
2610	 */
2611	PUT_MACREG(txmax, ETHERMAX + ETHERFCSL + 4);
2612	PUT_MACREG(rxmax, ETHERMAX + ETHERFCSL + 4);
2613
2614	/*
2615	 * Initialize HME Global registers, ETX registers and ERX registers.
2616	 */
2617
2618	PUT_ETXREG(txring, hmep->hme_tmd_paddr);
2619	PUT_ERXREG(rxring, hmep->hme_rmd_paddr);
2620
2621	/*
2622	 * ERX registers can be written only if they have even no. of bits set.
2623	 * So, if the value written is not read back, set the lsb and write
2624	 * again.
2625	 * static	int	hme_erx_fix = 1;   : Use the fix for erx bug
2626	 */
2627	{
2628		uint32_t temp;
2629		temp  = hmep->hme_rmd_paddr;
2630
2631		if (GET_ERXREG(rxring) != temp)
2632			PUT_ERXREG(rxring, (temp | 4));
2633	}
2634
2635	PUT_GLOBREG(config, (hmep->hme_config |
2636	    (hmep->hme_64bit_xfer << HMEG_CONFIG_64BIT_SHIFT)));
2637
2638	/*
2639	 * Significant performance improvements can be achieved by
2640	 * disabling transmit interrupt. Thus TMD's are reclaimed only
2641	 * when we run out of them in hmestart().
2642	 */
2643	PUT_GLOBREG(intmask,
2644	    HMEG_MASK_INTR | HMEG_MASK_TINT | HMEG_MASK_TX_ALL);
2645
2646	PUT_ETXREG(txring_size, ((HME_TMDMAX -1)>> HMET_RINGSZ_SHIFT));
2647	PUT_ETXREG(config, (GET_ETXREG(config) | HMET_CONFIG_TXDMA_EN
2648	    | HMET_CONFIG_TXFIFOTH));
2649	/* get the rxring size bits */
2650	switch (HME_RMDMAX) {
2651	case 32:
2652		i = HMER_CONFIG_RXRINGSZ32;
2653		break;
2654	case 64:
2655		i = HMER_CONFIG_RXRINGSZ64;
2656		break;
2657	case 128:
2658		i = HMER_CONFIG_RXRINGSZ128;
2659		break;
2660	case 256:
2661		i = HMER_CONFIG_RXRINGSZ256;
2662		break;
2663	default:
2664		HME_FAULT_MSG1(hmep, SEVERITY_HIGH, INIT_MSG,
2665		    unk_rx_ringsz_msg);
2666		goto init_fail;
2667	}
2668	i |= (HME_FSTBYTE_OFFSET << HMER_CONFIG_FBO_SHIFT)
2669	    | HMER_CONFIG_RXDMA_EN;
2670
2671	/* h/w checks start offset in half words */
2672	i |= ((sizeof (struct ether_header) / 2) << HMER_RX_CSSTART_SHIFT);
2673
2674	PUT_ERXREG(config, i);
2675
2676	/*
2677	 * Bug related to the parity handling in ERX. When erxp-config is
2678	 * read back.
2679	 * Sbus/FEPS drives the parity bit. This value is used while
2680	 * writing again.
2681	 * This fixes the RECV problem in SS5.
2682	 * static	int	hme_erx_fix = 1;   : Use the fix for erx bug
2683	 */
2684	{
2685		uint32_t temp;
2686		temp = GET_ERXREG(config);
2687		PUT_ERXREG(config, i);
2688
2689		if (GET_ERXREG(config) != i)
2690			HME_FAULT_MSG4(hmep, SEVERITY_UNKNOWN, ERX_MSG,
2691			    "error:temp = %x erxp->config = %x, should be %x",
2692			    temp, GET_ERXREG(config), i);
2693	}
2694
2695	/*
2696	 * Set up the rxconfig, txconfig and seed register without enabling
2697	 * them the former two at this time
2698	 *
2699	 * BigMAC strips the CRC bytes by default. Since this is
2700	 * contrary to other pieces of hardware, this bit needs to
2701	 * enabled to tell BigMAC not to strip the CRC bytes.
2702	 * Do not filter this node's own packets.
2703	 */
2704
2705	if (hme_reject_own) {
2706		PUT_MACREG(rxcfg,
2707		    ((hmep->hme_promisc ? BMAC_RXCFG_PROMIS : 0) |
2708		    BMAC_RXCFG_MYOWN | BMAC_RXCFG_HASH));
2709	} else {
2710		PUT_MACREG(rxcfg,
2711		    ((hmep->hme_promisc ? BMAC_RXCFG_PROMIS : 0) |
2712		    BMAC_RXCFG_HASH));
2713	}
2714
2715	drv_usecwait(10);	/* wait after setting Hash Enable bit */
2716
2717	fdx = (mii_get_duplex(hmep->hme_mii) == LINK_DUPLEX_FULL);
2718
2719	if (hme_ngu_enable)
2720		PUT_MACREG(txcfg, (fdx ? BMAC_TXCFG_FDX : 0) |
2721		    BMAC_TXCFG_NGU);
2722	else
2723		PUT_MACREG(txcfg, (fdx ? BMAC_TXCFG_FDX: 0));
2724
2725	i = 0;
2726	if ((hmep->hme_lance_mode) && (hmep->hme_lance_mode_enable))
2727		i = ((hmep->hme_ipg0 & HME_MASK_5BIT) << BMAC_XIFC_IPG0_SHIFT)
2728		    | BMAC_XIFC_LANCE_ENAB;
2729	if (phyad == HME_INTERNAL_PHYAD)
2730		PUT_MACREG(xifc, i | (BMAC_XIFC_ENAB));
2731	else
2732		PUT_MACREG(xifc, i | (BMAC_XIFC_ENAB | BMAC_XIFC_MIIBUFDIS));
2733
2734	PUT_MACREG(rxcfg, GET_MACREG(rxcfg) | BMAC_RXCFG_ENAB);
2735	PUT_MACREG(txcfg, GET_MACREG(txcfg) | BMAC_TXCFG_ENAB);
2736
2737	hmep->hme_flags |= (HMERUNNING | HMEINITIALIZED);
2738	/*
2739	 * Update the interrupt mask : this will re-allow interrupts to occur
2740	 */
2741	PUT_GLOBREG(intmask, HMEG_MASK_INTR);
2742	mac_tx_update(hmep->hme_mh);
2743
2744init_fail:
2745	/*
2746	 * Release the locks in reverse order
2747	 */
2748	mutex_exit(&hmep->hme_xmitlock);
2749	mutex_exit(&hmep->hme_intrlock);
2750
2751	ret = !(hmep->hme_flags & HMERUNNING);
2752	if (ret) {
2753		HME_FAULT_MSG1(hmep, SEVERITY_HIGH, INIT_MSG,
2754		    init_fail_gen_msg);
2755	}
2756
2757	/*
2758	 * Hardware checks.
2759	 */
2760	CHECK_GLOBREG();
2761	CHECK_MIFREG();
2762	CHECK_MACREG();
2763	CHECK_ERXREG();
2764	CHECK_ETXREG();
2765
2766init_exit:
2767	return (ret);
2768}
2769
2770/*
2771 * Calculate the dvma burstsize by setting up a dvma temporarily.  Return
2772 * 0 as burstsize upon failure as it signifies no burst size.
2773 * Requests for 64-bit transfer setup, if the platform supports it.
2774 * NOTE: Do not use ddi_dma_alloc_handle(9f) then ddi_dma_burstsize(9f),
2775 * sun4u Ultra-2 incorrectly returns a 32bit transfer.
2776 */
2777static int
2778hmeburstsizes(struct hme *hmep)
2779{
2780	int burstsizes;
2781	ddi_dma_handle_t handle;
2782
2783	if (ddi_dma_alloc_handle(hmep->dip, &hme_dma_attr,
2784	    DDI_DMA_DONTWAIT, NULL, &handle)) {
2785		return (0);
2786	}
2787
2788	hmep->hme_burstsizes = burstsizes = ddi_dma_burstsizes(handle);
2789	ddi_dma_free_handle(&handle);
2790
2791	/*
2792	 * Use user-configurable parameter for enabling 64-bit transfers
2793	 */
2794	burstsizes = (hmep->hme_burstsizes >> 16);
2795	if (burstsizes)
2796		hmep->hme_64bit_xfer = hme_64bit_enable; /* user config value */
2797	else
2798		burstsizes = hmep->hme_burstsizes;
2799
2800	if (hmep->hme_cheerio_mode)
2801		hmep->hme_64bit_xfer = 0; /* Disable for cheerio */
2802
2803	if (burstsizes & 0x40)
2804		hmep->hme_config = HMEG_CONFIG_BURST64;
2805	else if (burstsizes & 0x20)
2806		hmep->hme_config = HMEG_CONFIG_BURST32;
2807	else
2808		hmep->hme_config = HMEG_CONFIG_BURST16;
2809
2810	return (DDI_SUCCESS);
2811}
2812
2813static int
2814hmeallocbuf(struct hme *hmep, hmebuf_t *buf, int dir)
2815{
2816	ddi_dma_cookie_t	dmac;
2817	size_t			len;
2818	unsigned		ccnt;
2819
2820	if (ddi_dma_alloc_handle(hmep->dip, &hme_dma_attr,
2821	    DDI_DMA_DONTWAIT, NULL, &buf->dmah) != DDI_SUCCESS) {
2822		HME_FAULT_MSG1(hmep, SEVERITY_HIGH, INIT_MSG,
2823		    "cannot allocate buf dma handle - failed");
2824		return (DDI_FAILURE);
2825	}
2826
2827	if (ddi_dma_mem_alloc(buf->dmah, ROUNDUP(HMEBUFSIZE, 512),
2828	    &hme_buf_attr, DDI_DMA_STREAMING, DDI_DMA_DONTWAIT, NULL,
2829	    &buf->kaddr, &len, &buf->acch) != DDI_SUCCESS) {
2830		HME_FAULT_MSG1(hmep, SEVERITY_HIGH, INIT_MSG,
2831		    "cannot allocate buf memory - failed");
2832		return (DDI_FAILURE);
2833	}
2834
2835	if (ddi_dma_addr_bind_handle(buf->dmah, NULL, buf->kaddr,
2836	    len, dir | DDI_DMA_CONSISTENT, DDI_DMA_DONTWAIT, NULL,
2837	    &dmac, &ccnt) != DDI_DMA_MAPPED) {
2838		HME_FAULT_MSG1(hmep, SEVERITY_HIGH, INIT_MSG,
2839		    "cannot map buf for dma - failed");
2840		return (DDI_FAILURE);
2841	}
2842	buf->paddr = dmac.dmac_address;
2843
2844	/* apparently they don't handle multiple cookies */
2845	if (ccnt > 1) {
2846		HME_FAULT_MSG1(hmep, SEVERITY_HIGH, INIT_MSG,
2847		    "too many buf dma cookies");
2848		return (DDI_FAILURE);
2849	}
2850	return (DDI_SUCCESS);
2851}
2852
2853static int
2854hmeallocbufs(struct hme *hmep)
2855{
2856	hmep->hme_tbuf = kmem_zalloc(HME_TMDMAX * sizeof (hmebuf_t), KM_SLEEP);
2857	hmep->hme_rbuf = kmem_zalloc(HME_RMDMAX * sizeof (hmebuf_t), KM_SLEEP);
2858
2859	/* Alloc RX buffers. */
2860	for (int i = 0; i < HME_RMDMAX; i++) {
2861		if (hmeallocbuf(hmep, &hmep->hme_rbuf[i], DDI_DMA_READ) !=
2862		    DDI_SUCCESS) {
2863			return (DDI_FAILURE);
2864		}
2865	}
2866
2867	/* Alloc TX buffers. */
2868	for (int i = 0; i < HME_TMDMAX; i++) {
2869		if (hmeallocbuf(hmep, &hmep->hme_tbuf[i], DDI_DMA_WRITE) !=
2870		    DDI_SUCCESS) {
2871			return (DDI_FAILURE);
2872		}
2873	}
2874	return (DDI_SUCCESS);
2875}
2876
2877static void
2878hmefreebufs(struct hme *hmep)
2879{
2880	int i;
2881
2882	if (hmep->hme_rbuf == NULL)
2883		return;
2884
2885	/*
2886	 * Free and unload pending xmit and recv buffers.
2887	 * Maintaining the 1-to-1 ordered sequence of
2888	 * We have written the routine to be idempotent.
2889	 */
2890
2891	for (i = 0; i < HME_TMDMAX; i++) {
2892		hmebuf_t *tbuf = &hmep->hme_tbuf[i];
2893		if (tbuf->paddr) {
2894			(void) ddi_dma_unbind_handle(tbuf->dmah);
2895		}
2896		if (tbuf->kaddr) {
2897			ddi_dma_mem_free(&tbuf->acch);
2898		}
2899		if (tbuf->dmah) {
2900			ddi_dma_free_handle(&tbuf->dmah);
2901		}
2902	}
2903	for (i = 0; i < HME_RMDMAX; i++) {
2904		hmebuf_t *rbuf = &hmep->hme_rbuf[i];
2905		if (rbuf->paddr) {
2906			(void) ddi_dma_unbind_handle(rbuf->dmah);
2907		}
2908		if (rbuf->kaddr) {
2909			ddi_dma_mem_free(&rbuf->acch);
2910		}
2911		if (rbuf->dmah) {
2912			ddi_dma_free_handle(&rbuf->dmah);
2913		}
2914	}
2915	kmem_free(hmep->hme_rbuf, HME_RMDMAX * sizeof (hmebuf_t));
2916	kmem_free(hmep->hme_tbuf, HME_TMDMAX * sizeof (hmebuf_t));
2917}
2918
2919/*
2920 * Un-initialize (STOP) HME channel.
2921 */
2922static void
2923hmeuninit(struct hme *hmep)
2924{
2925	/*
2926	 * Allow up to 'HMEDRAINTIME' for pending xmit's to complete.
2927	 */
2928	HMEDELAY((hmep->hme_txindex == hmep->hme_txreclaim), HMEDRAINTIME);
2929
2930	mutex_enter(&hmep->hme_intrlock);
2931	mutex_enter(&hmep->hme_xmitlock);
2932
2933	hmep->hme_flags &= ~HMERUNNING;
2934
2935	(void) hmestop(hmep);
2936
2937	mutex_exit(&hmep->hme_xmitlock);
2938	mutex_exit(&hmep->hme_intrlock);
2939}
2940
2941/*
2942 * Allocate CONSISTENT memory for rmds and tmds with appropriate alignment and
2943 * map it in IO space. Allocate space for transmit and receive ddi_dma_handle
2944 * structures to use the DMA interface.
2945 */
2946static int
2947hmeallocthings(struct hme *hmep)
2948{
2949	int			size;
2950	int			rval;
2951	size_t			real_len;
2952	uint_t			cookiec;
2953	ddi_dma_cookie_t	dmac;
2954	dev_info_t		*dip = hmep->dip;
2955
2956	/*
2957	 * Allocate the TMD and RMD descriptors and extra for page alignment.
2958	 */
2959
2960	rval = ddi_dma_alloc_handle(dip, &hme_dma_attr, DDI_DMA_DONTWAIT, NULL,
2961	    &hmep->hme_rmd_dmah);
2962	if (rval != DDI_SUCCESS) {
2963		HME_FAULT_MSG1(hmep, SEVERITY_HIGH, INIT_MSG,
2964		    "cannot allocate rmd handle - failed");
2965		return (DDI_FAILURE);
2966	}
2967	size = HME_RMDMAX * sizeof (struct hme_rmd);
2968	rval = ddi_dma_mem_alloc(hmep->hme_rmd_dmah, size,
2969	    &hmep->hme_dev_attr, DDI_DMA_CONSISTENT, DDI_DMA_DONTWAIT, NULL,
2970	    &hmep->hme_rmd_kaddr, &real_len, &hmep->hme_rmd_acch);
2971	if (rval != DDI_SUCCESS) {
2972		HME_FAULT_MSG1(hmep, SEVERITY_HIGH, INIT_MSG,
2973		    "cannot allocate rmd dma mem - failed");
2974		return (DDI_FAILURE);
2975	}
2976	hmep->hme_rmdp = (void *)(hmep->hme_rmd_kaddr);
2977	rval = ddi_dma_addr_bind_handle(hmep->hme_rmd_dmah, NULL,
2978	    hmep->hme_rmd_kaddr, size, DDI_DMA_RDWR | DDI_DMA_CONSISTENT,
2979	    DDI_DMA_DONTWAIT, NULL, &dmac, &cookiec);
2980	if (rval != DDI_DMA_MAPPED) {
2981		HME_FAULT_MSG1(hmep, SEVERITY_HIGH, INIT_MSG,
2982		    "cannot allocate rmd dma - failed");
2983		return (DDI_FAILURE);
2984	}
2985	hmep->hme_rmd_paddr = dmac.dmac_address;
2986	if (cookiec != 1) {
2987		HME_FAULT_MSG1(hmep, SEVERITY_HIGH, INIT_MSG,
2988		    "too many rmd cookies - failed");
2989		return (DDI_FAILURE);
2990	}
2991
2992	rval = ddi_dma_alloc_handle(dip, &hme_dma_attr, DDI_DMA_DONTWAIT, NULL,
2993	    &hmep->hme_tmd_dmah);
2994	if (rval != DDI_SUCCESS) {
2995		HME_FAULT_MSG1(hmep, SEVERITY_HIGH, INIT_MSG,
2996		    "cannot allocate tmd handle - failed");
2997		return (DDI_FAILURE);
2998	}
2999	size = HME_TMDMAX * sizeof (struct hme_rmd);
3000	rval = ddi_dma_mem_alloc(hmep->hme_tmd_dmah, size,
3001	    &hmep->hme_dev_attr, DDI_DMA_CONSISTENT, DDI_DMA_DONTWAIT, NULL,
3002	    &hmep->hme_tmd_kaddr, &real_len, &hmep->hme_tmd_acch);
3003	if (rval != DDI_SUCCESS) {
3004		HME_FAULT_MSG1(hmep, SEVERITY_HIGH, INIT_MSG,
3005		    "cannot allocate tmd dma mem - failed");
3006		return (DDI_FAILURE);
3007	}
3008	hmep->hme_tmdp = (void *)(hmep->hme_tmd_kaddr);
3009	rval = ddi_dma_addr_bind_handle(hmep->hme_tmd_dmah, NULL,
3010	    hmep->hme_tmd_kaddr, size, DDI_DMA_RDWR | DDI_DMA_CONSISTENT,
3011	    DDI_DMA_DONTWAIT, NULL, &dmac, &cookiec);
3012	if (rval != DDI_DMA_MAPPED) {
3013		HME_FAULT_MSG1(hmep, SEVERITY_HIGH, INIT_MSG,
3014		    "cannot allocate tmd dma - failed");
3015		return (DDI_FAILURE);
3016	}
3017	hmep->hme_tmd_paddr = dmac.dmac_address;
3018	if (cookiec != 1) {
3019		HME_FAULT_MSG1(hmep, SEVERITY_HIGH, INIT_MSG,
3020		    "too many tmd cookies - failed");
3021		return (DDI_FAILURE);
3022	}
3023
3024	return (DDI_SUCCESS);
3025}
3026
3027static void
3028hmefreethings(struct hme *hmep)
3029{
3030	if (hmep->hme_rmd_paddr) {
3031		(void) ddi_dma_unbind_handle(hmep->hme_rmd_dmah);
3032		hmep->hme_rmd_paddr = 0;
3033	}
3034	if (hmep->hme_rmd_acch)
3035		ddi_dma_mem_free(&hmep->hme_rmd_acch);
3036	if (hmep->hme_rmd_dmah)
3037		ddi_dma_free_handle(&hmep->hme_rmd_dmah);
3038
3039	if (hmep->hme_tmd_paddr) {
3040		(void) ddi_dma_unbind_handle(hmep->hme_tmd_dmah);
3041		hmep->hme_tmd_paddr = 0;
3042	}
3043	if (hmep->hme_tmd_acch)
3044		ddi_dma_mem_free(&hmep->hme_tmd_acch);
3045	if (hmep->hme_tmd_dmah)
3046		ddi_dma_free_handle(&hmep->hme_tmd_dmah);
3047}
3048
3049/*
3050 *	First check to see if it our device interrupting.
3051 */
3052static uint_t
3053hmeintr(caddr_t arg)
3054{
3055	struct hme	*hmep = (void *)arg;
3056	uint32_t	hmesbits;
3057	uint32_t	serviced = DDI_INTR_UNCLAIMED;
3058	uint32_t	num_reads = 0;
3059	uint32_t	rflags;
3060	mblk_t		*mp, *head, **tail;
3061
3062
3063	head = NULL;
3064	tail = &head;
3065
3066	mutex_enter(&hmep->hme_intrlock);
3067
3068	/*
3069	 * The status register auto-clears on read except for
3070	 * MIF Interrupt bit
3071	 */
3072	hmesbits = GET_GLOBREG(status);
3073	CHECK_GLOBREG();
3074
3075	/*
3076	 * Note: TINT is sometimes enabled in thr hmereclaim()
3077	 */
3078
3079	/*
3080	 * Bugid 1227832 - to handle spurious interrupts on fusion systems.
3081	 * Claim the first interrupt after initialization
3082	 */
3083	if (hmep->hme_flags & HMEINITIALIZED) {
3084		hmep->hme_flags &= ~HMEINITIALIZED;
3085		serviced = DDI_INTR_CLAIMED;
3086	}
3087
3088	if ((hmesbits & (HMEG_STATUS_INTR | HMEG_STATUS_TINT)) == 0) {
3089						/* No interesting interrupt */
3090		if (hmep->hme_intrstats) {
3091			if (serviced == DDI_INTR_UNCLAIMED)
3092				KIOIP->intrs[KSTAT_INTR_SPURIOUS]++;
3093			else
3094				KIOIP->intrs[KSTAT_INTR_HARD]++;
3095		}
3096		mutex_exit(&hmep->hme_intrlock);
3097		return (serviced);
3098	}
3099
3100	serviced = DDI_INTR_CLAIMED;
3101
3102	if (!(hmep->hme_flags & HMERUNNING)) {
3103		if (hmep->hme_intrstats)
3104			KIOIP->intrs[KSTAT_INTR_HARD]++;
3105		mutex_exit(&hmep->hme_intrlock);
3106		hmeuninit(hmep);
3107		return (serviced);
3108	}
3109
3110	if (hmesbits & (HMEG_STATUS_FATAL_ERR | HMEG_STATUS_NONFATAL_ERR)) {
3111		if (hmesbits & HMEG_STATUS_FATAL_ERR) {
3112
3113			if (hmep->hme_intrstats)
3114				KIOIP->intrs[KSTAT_INTR_HARD]++;
3115			hme_fatal_err(hmep, hmesbits);
3116
3117			mutex_exit(&hmep->hme_intrlock);
3118			(void) hmeinit(hmep);
3119			return (serviced);
3120		}
3121		hme_nonfatal_err(hmep, hmesbits);
3122	}
3123
3124	if (hmesbits & (HMEG_STATUS_TX_ALL | HMEG_STATUS_TINT)) {
3125		mutex_enter(&hmep->hme_xmitlock);
3126
3127		hmereclaim(hmep);
3128		mutex_exit(&hmep->hme_xmitlock);
3129	}
3130
3131	if (hmesbits & HMEG_STATUS_RINT) {
3132
3133		/*
3134		 * This dummy PIO is required to flush the SBus
3135		 * Bridge buffers in QFE.
3136		 */
3137		(void) GET_GLOBREG(config);
3138
3139		/*
3140		 * Loop through each RMD no more than once.
3141		 */
3142		while (num_reads++ < HME_RMDMAX) {
3143			hmebuf_t *rbuf;
3144			int rxptr;
3145
3146			rxptr = hmep->hme_rxindex % HME_RMDMAX;
3147			HMESYNCRMD(rxptr, DDI_DMA_SYNC_FORKERNEL);
3148
3149			rflags = GET_RMD_FLAGS(rxptr);
3150			if (rflags & HMERMD_OWN) {
3151				/*
3152				 * Chip still owns it.  We're done.
3153				 */
3154				break;
3155			}
3156
3157			/*
3158			 * Retrieve the packet.
3159			 */
3160			rbuf = &hmep->hme_rbuf[rxptr];
3161			mp = hmeread(hmep, rbuf, rflags);
3162
3163			/*
3164			 * Return ownership of the RMD.
3165			 */
3166			PUT_RMD(rxptr, rbuf->paddr);
3167			HMESYNCRMD(rxptr, DDI_DMA_SYNC_FORDEV);
3168
3169			if (mp != NULL) {
3170				*tail = mp;
3171				tail = &mp->b_next;
3172			}
3173
3174			/*
3175			 * Advance to the next RMD.
3176			 */
3177			hmep->hme_rxindex++;
3178		}
3179	}
3180
3181	if (hmep->hme_intrstats)
3182		KIOIP->intrs[KSTAT_INTR_HARD]++;
3183
3184	mutex_exit(&hmep->hme_intrlock);
3185
3186	if (head != NULL)
3187		mac_rx(hmep->hme_mh, NULL, head);
3188
3189	return (serviced);
3190}
3191
3192/*
3193 * Transmit completion reclaiming.
3194 */
3195static void
3196hmereclaim(struct hme *hmep)
3197{
3198	boolean_t	reclaimed = B_FALSE;
3199
3200	/*
3201	 * Loop through each TMD.
3202	 */
3203	while (hmep->hme_txindex > hmep->hme_txreclaim) {
3204
3205		int		reclaim;
3206		uint32_t	flags;
3207
3208		reclaim = hmep->hme_txreclaim % HME_TMDMAX;
3209		HMESYNCTMD(reclaim, DDI_DMA_SYNC_FORKERNEL);
3210
3211		flags = GET_TMD_FLAGS(reclaim);
3212		if (flags & HMETMD_OWN) {
3213			/*
3214			 * Chip still owns it.  We're done.
3215			 */
3216			break;
3217		}
3218
3219		/*
3220		 * Count a chained packet only once.
3221		 */
3222		if (flags & HMETMD_SOP) {
3223			hmep->hme_opackets++;
3224		}
3225
3226		/*
3227		 * MIB II
3228		 */
3229		hmep->hme_obytes += flags & HMETMD_BUFSIZE;
3230
3231		reclaimed = B_TRUE;
3232		hmep->hme_txreclaim++;
3233	}
3234
3235	if (reclaimed) {
3236		/*
3237		 * we could reclaim some TMDs so turn off interrupts
3238		 */
3239		if (hmep->hme_wantw) {
3240			PUT_GLOBREG(intmask,
3241			    HMEG_MASK_INTR | HMEG_MASK_TINT |
3242			    HMEG_MASK_TX_ALL);
3243			hmep->hme_wantw = B_FALSE;
3244			mac_tx_update(hmep->hme_mh);
3245		}
3246	} else {
3247		/*
3248		 * enable TINTS: so that even if there is no further activity
3249		 * hmereclaim will get called
3250		 */
3251		if (hmep->hme_wantw)
3252			PUT_GLOBREG(intmask,
3253			    GET_GLOBREG(intmask) & ~HMEG_MASK_TX_ALL);
3254	}
3255	CHECK_GLOBREG();
3256}
3257
3258/*
3259 * Handle interrupts for fatal errors
3260 * Need reinitialization of the ENET channel.
3261 */
3262static void
3263hme_fatal_err(struct hme *hmep, uint_t hmesbits)
3264{
3265
3266	if (hmesbits & HMEG_STATUS_SLV_PAR_ERR) {
3267		hmep->hme_slvparerr++;
3268	}
3269
3270	if (hmesbits & HMEG_STATUS_SLV_ERR_ACK) {
3271		hmep->hme_slverrack++;
3272	}
3273
3274	if (hmesbits & HMEG_STATUS_TX_TAG_ERR) {
3275		hmep->hme_txtagerr++;
3276		hmep->hme_oerrors++;
3277	}
3278
3279	if (hmesbits & HMEG_STATUS_TX_PAR_ERR) {
3280		hmep->hme_txparerr++;
3281		hmep->hme_oerrors++;
3282	}
3283
3284	if (hmesbits & HMEG_STATUS_TX_LATE_ERR) {
3285		hmep->hme_txlaterr++;
3286		hmep->hme_oerrors++;
3287	}
3288
3289	if (hmesbits & HMEG_STATUS_TX_ERR_ACK) {
3290		hmep->hme_txerrack++;
3291		hmep->hme_oerrors++;
3292	}
3293
3294	if (hmesbits & HMEG_STATUS_EOP_ERR) {
3295		hmep->hme_eoperr++;
3296	}
3297
3298	if (hmesbits & HMEG_STATUS_RX_TAG_ERR) {
3299		hmep->hme_rxtagerr++;
3300		hmep->hme_ierrors++;
3301	}
3302
3303	if (hmesbits & HMEG_STATUS_RX_PAR_ERR) {
3304		hmep->hme_rxparerr++;
3305		hmep->hme_ierrors++;
3306	}
3307
3308	if (hmesbits & HMEG_STATUS_RX_LATE_ERR) {
3309		hmep->hme_rxlaterr++;
3310		hmep->hme_ierrors++;
3311	}
3312
3313	if (hmesbits & HMEG_STATUS_RX_ERR_ACK) {
3314		hmep->hme_rxerrack++;
3315		hmep->hme_ierrors++;
3316	}
3317}
3318
3319/*
3320 * Handle interrupts regarding non-fatal errors.
3321 */
3322static void
3323hme_nonfatal_err(struct hme *hmep, uint_t hmesbits)
3324{
3325
3326	if (hmesbits & HMEG_STATUS_RX_DROP) {
3327		hmep->hme_missed++;
3328		hmep->hme_ierrors++;
3329	}
3330
3331	if (hmesbits & HMEG_STATUS_DEFTIMR_EXP) {
3332		hmep->hme_defer_xmts++;
3333	}
3334
3335	if (hmesbits & HMEG_STATUS_FSTCOLC_EXP) {
3336		hmep->hme_fstcol += 256;
3337	}
3338
3339	if (hmesbits & HMEG_STATUS_LATCOLC_EXP) {
3340		hmep->hme_tlcol += 256;
3341		hmep->hme_oerrors += 256;
3342	}
3343
3344	if (hmesbits & HMEG_STATUS_EXCOLC_EXP) {
3345		hmep->hme_excol += 256;
3346		hmep->hme_oerrors += 256;
3347	}
3348
3349	if (hmesbits & HMEG_STATUS_NRMCOLC_EXP) {
3350		hmep->hme_coll += 256;
3351	}
3352
3353	if (hmesbits & HMEG_STATUS_MXPKTSZ_ERR) {
3354		hmep->hme_babl++;
3355		hmep->hme_oerrors++;
3356	}
3357
3358	/*
3359	 * This error is fatal and the board needs to
3360	 * be reinitialized. Comments?
3361	 */
3362	if (hmesbits & HMEG_STATUS_TXFIFO_UNDR) {
3363		hmep->hme_uflo++;
3364		hmep->hme_oerrors++;
3365	}
3366
3367	if (hmesbits & HMEG_STATUS_SQE_TST_ERR) {
3368		hmep->hme_sqe_errors++;
3369	}
3370
3371	if (hmesbits & HMEG_STATUS_RCV_CNT_EXP) {
3372		if (hmep->hme_rxcv_enable) {
3373			hmep->hme_cvc += 256;
3374		}
3375	}
3376
3377	if (hmesbits & HMEG_STATUS_RXFIFO_OVFL) {
3378		hmep->hme_oflo++;
3379		hmep->hme_ierrors++;
3380	}
3381
3382	if (hmesbits & HMEG_STATUS_LEN_CNT_EXP) {
3383		hmep->hme_lenerr += 256;
3384		hmep->hme_ierrors += 256;
3385	}
3386
3387	if (hmesbits & HMEG_STATUS_ALN_CNT_EXP) {
3388		hmep->hme_align_errors += 256;
3389		hmep->hme_ierrors += 256;
3390	}
3391
3392	if (hmesbits & HMEG_STATUS_CRC_CNT_EXP) {
3393		hmep->hme_fcs_errors += 256;
3394		hmep->hme_ierrors += 256;
3395	}
3396}
3397
3398static mblk_t *
3399hmeread(struct hme *hmep, hmebuf_t *rbuf, uint32_t rflags)
3400{
3401	mblk_t		*bp;
3402	uint32_t	len;
3403	t_uscalar_t	type;
3404
3405	len = (rflags & HMERMD_BUFSIZE) >> HMERMD_BUFSIZE_SHIFT;
3406
3407	/*
3408	 * Check for short packet
3409	 * and check for overflow packet also. The processing is the
3410	 * same for both the cases - reuse the buffer. Update the Buffer
3411	 * overflow counter.
3412	 */
3413	if ((len < ETHERMIN) || (rflags & HMERMD_OVFLOW) ||
3414	    (len > (ETHERMAX + 4))) {
3415		if (len < ETHERMIN)
3416			hmep->hme_runt++;
3417
3418		else {
3419			hmep->hme_buff++;
3420			hmep->hme_toolong_errors++;
3421		}
3422		hmep->hme_ierrors++;
3423		return (NULL);
3424	}
3425
3426	/*
3427	 * Sync the received buffer before looking at it.
3428	 */
3429
3430	(void) ddi_dma_sync(rbuf->dmah, 0, 0, DDI_DMA_SYNC_FORKERNEL);
3431
3432	/*
3433	 * copy the packet data and then recycle the descriptor.
3434	 */
3435
3436	if ((bp = allocb(len + HME_FSTBYTE_OFFSET, BPRI_HI)) == NULL) {
3437
3438		hmep->hme_allocbfail++;
3439		hmep->hme_norcvbuf++;
3440
3441		return (NULL);
3442	}
3443
3444	bcopy(rbuf->kaddr, bp->b_rptr, len + HME_FSTBYTE_OFFSET);
3445
3446	hmep->hme_ipackets++;
3447
3448	/*  Add the First Byte offset to the b_rptr and copy */
3449	bp->b_rptr += HME_FSTBYTE_OFFSET;
3450	bp->b_wptr = bp->b_rptr + len;
3451
3452	/*
3453	 * update MIB II statistics
3454	 */
3455	BUMP_InNUcast(hmep, bp->b_rptr);
3456	hmep->hme_rbytes += len;
3457
3458	type = get_ether_type(bp->b_rptr);
3459
3460	/*
3461	 * TCP partial checksum in hardware
3462	 */
3463	if (type == ETHERTYPE_IP || type == ETHERTYPE_IPV6) {
3464		uint16_t cksum = ~rflags & HMERMD_CKSUM;
3465		uint_t end = len - sizeof (struct ether_header);
3466		mac_hcksum_set(bp, 0, 0, end, htons(cksum), HCK_PARTIALCKSUM);
3467	}
3468
3469	return (bp);
3470}
3471
3472/*VARARGS*/
3473static void
3474hme_fault_msg(struct hme *hmep, uint_t severity, msg_t type, char *fmt, ...)
3475{
3476	char	msg_buffer[255];
3477	va_list	ap;
3478
3479	va_start(ap, fmt);
3480	(void) vsnprintf(msg_buffer, sizeof (msg_buffer), fmt, ap);
3481
3482	if (hmep == NULL) {
3483		cmn_err(CE_NOTE, "hme : %s", msg_buffer);
3484
3485	} else if (type == DISPLAY_MSG) {
3486		cmn_err(CE_CONT, "?%s%d : %s\n", ddi_driver_name(hmep->dip),
3487		    hmep->instance, msg_buffer);
3488	} else if (severity == SEVERITY_HIGH) {
3489		cmn_err(CE_WARN, "%s%d : %s, SEVERITY_HIGH, %s\n",
3490		    ddi_driver_name(hmep->dip), hmep->instance,
3491		    msg_buffer, msg_string[type]);
3492	} else {
3493		cmn_err(CE_CONT, "%s%d : %s\n", ddi_driver_name(hmep->dip),
3494		    hmep->instance, msg_buffer);
3495	}
3496	va_end(ap);
3497}
3498
3499/*
3500 * if this is the first init do not bother to save the
3501 * counters. They should be 0, but do not count on it.
3502 */
3503static void
3504hmesavecntrs(struct hme *hmep)
3505{
3506	uint32_t fecnt, aecnt, lecnt, rxcv;
3507	uint32_t ltcnt, excnt;
3508
3509	/* XXX What all gets added in ierrors and oerrors? */
3510	fecnt = GET_MACREG(fecnt);
3511	PUT_MACREG(fecnt, 0);
3512
3513	aecnt = GET_MACREG(aecnt);
3514	hmep->hme_align_errors += aecnt;
3515	PUT_MACREG(aecnt, 0);
3516
3517	lecnt = GET_MACREG(lecnt);
3518	hmep->hme_lenerr += lecnt;
3519	PUT_MACREG(lecnt, 0);
3520
3521	rxcv = GET_MACREG(rxcv);
3522#ifdef HME_CODEVIOL_BUG
3523	/*
3524	 * Ignore rxcv errors for Sbus/FEPS 2.1 or earlier
3525	 */
3526	if (!hmep->hme_rxcv_enable) {
3527		rxcv = 0;
3528	}
3529#endif
3530	hmep->hme_cvc += rxcv;
3531	PUT_MACREG(rxcv, 0);
3532
3533	ltcnt = GET_MACREG(ltcnt);
3534	hmep->hme_tlcol += ltcnt;
3535	PUT_MACREG(ltcnt, 0);
3536
3537	excnt = GET_MACREG(excnt);
3538	hmep->hme_excol += excnt;
3539	PUT_MACREG(excnt, 0);
3540
3541	hmep->hme_fcs_errors += fecnt;
3542	hmep->hme_ierrors += (fecnt + aecnt + lecnt);
3543	hmep->hme_oerrors += (ltcnt + excnt);
3544	hmep->hme_coll += (GET_MACREG(nccnt) + ltcnt);
3545
3546	PUT_MACREG(nccnt, 0);
3547	CHECK_MACREG();
3548}
3549
3550/*
3551 * To set up the mac address for the network interface:
3552 * The adapter card may support a local mac address which is published
3553 * in a device node property "local-mac-address". This mac address is
3554 * treated as the factory-installed mac address for DLPI interface.
3555 * If the adapter firmware has used the device for diskless boot
3556 * operation it publishes a property called "mac-address" for use by
3557 * inetboot and the device driver.
3558 * If "mac-address" is not found, the system options property
3559 * "local-mac-address" is used to select the mac-address. If this option
3560 * is set to "true", and "local-mac-address" has been found, then
3561 * local-mac-address is used; otherwise the system mac address is used
3562 * by calling the "localetheraddr()" function.
3563 */
3564static void
3565hme_setup_mac_address(struct hme *hmep, dev_info_t *dip)
3566{
3567	char	*prop;
3568	int	prop_len = sizeof (int);
3569
3570	hmep->hme_addrflags = 0;
3571
3572	/*
3573	 * Check if it is an adapter with its own local mac address
3574	 * If it is present, save it as the "factory-address"
3575	 * for this adapter.
3576	 */
3577	if (ddi_getlongprop(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
3578	    "local-mac-address",
3579	    (caddr_t)&prop, &prop_len) == DDI_PROP_SUCCESS) {
3580		if (prop_len == ETHERADDRL) {
3581			hmep->hme_addrflags = HME_FACTADDR_PRESENT;
3582			ether_bcopy(prop, &hmep->hme_factaddr);
3583			HME_FAULT_MSG2(hmep, SEVERITY_NONE, DISPLAY_MSG,
3584			    "Local Ethernet address = %s",
3585			    ether_sprintf(&hmep->hme_factaddr));
3586		}
3587		kmem_free(prop, prop_len);
3588	}
3589
3590	/*
3591	 * Check if the adapter has published "mac-address" property.
3592	 * If it is present, use it as the mac address for this device.
3593	 */
3594	if (ddi_getlongprop(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
3595	    "mac-address", (caddr_t)&prop, &prop_len) == DDI_PROP_SUCCESS) {
3596		if (prop_len >= ETHERADDRL) {
3597			ether_bcopy(prop, &hmep->hme_ouraddr);
3598			kmem_free(prop, prop_len);
3599			return;
3600		}
3601		kmem_free(prop, prop_len);
3602	}
3603
3604#ifdef	__sparc
3605	/*
3606	 * On sparc, we might be able to use the mac address from the
3607	 * system.  However, on all other systems, we need to use the
3608	 * address from the PROM.
3609	 */
3610	if (ddi_getlongprop(DDI_DEV_T_ANY, dip, 0, "local-mac-address?",
3611	    (caddr_t)&prop, &prop_len) == DDI_PROP_SUCCESS) {
3612		if ((strncmp("true", prop, prop_len) == 0) &&
3613		    (hmep->hme_addrflags & HME_FACTADDR_PRESENT)) {
3614			hmep->hme_addrflags |= HME_FACTADDR_USE;
3615			ether_bcopy(&hmep->hme_factaddr, &hmep->hme_ouraddr);
3616			kmem_free(prop, prop_len);
3617			HME_FAULT_MSG1(hmep, SEVERITY_NONE, DISPLAY_MSG,
3618			    "Using local MAC address");
3619			return;
3620		}
3621		kmem_free(prop, prop_len);
3622	}
3623
3624	/*
3625	 * Get the system ethernet address.
3626	 */
3627	(void) localetheraddr((struct ether_addr *)NULL, &hmep->hme_ouraddr);
3628#else
3629	ether_bcopy(&hmep->hme_factaddr, &hmep->hme_ouraddr);
3630#endif
3631}
3632
3633/* ARGSUSED */
3634static void
3635hme_check_acc_handle(char *file, uint_t line, struct hme *hmep,
3636    ddi_acc_handle_t handle)
3637{
3638}
3639