xref: /titanic_50/usr/src/uts/intel/io/amd8111s/amd8111s_main.c (revision f6acbf7c6543dc0aab58cae1df419f0147c46d77)
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 /*
23  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 #pragma ident	"%Z%%M%	%I%	%E% SMI"
28 
29 /*
30  * Copyright (c) 2001-2006 Advanced Micro Devices, Inc.  All rights reserved.
31  *
32  * Redistribution and use in source and binary forms, with or without
33  * modification, are permitted provided that the following conditions are met:
34  *
35  * + Redistributions of source code must retain the above copyright notice,
36  * + this list of conditions and the following disclaimer.
37  *
38  * + Redistributions in binary form must reproduce the above copyright
39  * + notice, this list of conditions and the following disclaimer in the
40  * + documentation and/or other materials provided with the distribution.
41  *
42  * + Neither the name of Advanced Micro Devices, Inc. nor the names of its
43  * + contributors may be used to endorse or promote products derived from
44  * + this software without specific prior written permission.
45  *
46  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
47  * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
48  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
49  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
50  * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. OR
51  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
52  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
53  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
54  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
55  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
56  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
57  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
58  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
59  *
60  * Import/Export/Re-Export/Use/Release/Transfer Restrictions and
61  * Compliance with Applicable Laws.  Notice is hereby given that
62  * the software may be subject to restrictions on use, release,
63  * transfer, importation, exportation and/or re-exportation under
64  * the laws and regulations of the United States or other
65  * countries ("Applicable Laws"), which include but are not
66  * limited to U.S. export control laws such as the Export
67  * Administration Regulations and national security controls as
68  * defined thereunder, as well as State Department controls under
69  * the U.S. Munitions List.  Permission to use and/or
70  * redistribute the software is conditioned upon compliance with
71  * all Applicable Laws, including U.S. export control laws
72  * regarding specifically designated persons, countries and
73  * nationals of countries subject to national security controls.
74  */
75 
76 
77 #pragma ident "@(#)$RCSfile: solaris_odl.c,v $ $Revision: 1.3 $ " \
78 " $Date: 2004/04/22 15:22:54 $ AMD"
79 
80 
81 /* include files */
82 #include <sys/disp.h>
83 #include <sys/atomic.h>
84 #include <sys/vlan.h>
85 #include "amd8111s_main.h"
86 
87 /* Global macro Definations */
88 #define	ROUNDUP(x, a)	(((x) + (a) - 1) & ~((a) - 1))
89 #define	INTERFACE_NAME "amd8111s"
90 #define	AMD8111S_SPLIT	128
91 #define	AMD8111S_SEND_MAX	64
92 
93 static char ident[] = "AMD8111 10/100M Ethernet 1.0";
94 
95 /*
96  * Driver Entry Points
97  */
98 static int amd8111s_attach(dev_info_t *, ddi_attach_cmd_t);
99 static int amd8111s_detach(dev_info_t *, ddi_detach_cmd_t);
100 
101 /*
102  * GLD Entry points prototype
103  */
104 static int amd8111s_m_unicst(void *, const uint8_t *);
105 static int amd8111s_m_promisc(void *, boolean_t);
106 static int amd8111s_m_stat(void *, uint_t, uint64_t *);
107 static void amd8111s_m_resources(void *arg);
108 static void amd8111s_m_ioctl(void *, queue_t *, mblk_t *);
109 static int amd8111s_m_multicst(void *, boolean_t, const uint8_t *addr);
110 static int amd8111s_m_start(void *);
111 static void amd8111s_m_stop(void *);
112 static mblk_t *amd8111s_m_tx(void *, mblk_t *mp);
113 static uint_t amd8111s_intr(caddr_t);
114 
115 static int amd8111s_unattach(dev_info_t *, struct LayerPointers *);
116 
117 static boolean_t amd8111s_allocate_buffers(struct LayerPointers *);
118 static int amd8111s_odlInit(struct LayerPointers *);
119 static boolean_t amd8111s_allocate_descriptors(struct LayerPointers *);
120 static void amd8111s_free_descriptors(struct LayerPointers *);
121 static boolean_t amd8111s_alloc_dma_ringbuf(struct LayerPointers *,
122 		struct amd8111s_dma_ringbuf *, uint32_t, uint32_t);
123 static void amd8111s_free_dma_ringbuf(struct amd8111s_dma_ringbuf *);
124 
125 
126 static void amd8111s_log(struct LayerPointers *adapter, int level,
127     char *fmt, ...);
128 
129 static struct cb_ops amd8111s_cb_ops = {
130 	nulldev,
131 	nulldev,
132 	nodev,
133 	nodev,
134 	nodev,
135 	nodev,
136 	nodev,
137 	nodev,
138 	nodev,
139 	nodev,
140 	nodev,
141 	nochpoll,
142 	ddi_prop_op,
143 	NULL,
144 	D_NEW | D_MP,
145 	CB_REV,		/* cb_rev */
146 	nodev,		/* cb_aread */
147 	nodev		/* cb_awrite */
148 };
149 
150 static struct dev_ops amd8111s_dev_ops = {
151 	DEVO_REV,		/* devo_rev */
152 	0,			/* devo_refcnt */
153 	NULL,			/* devo_getinfo */
154 	nulldev,		/* devo_identify */
155 	nulldev,		/* devo_probe */
156 	amd8111s_attach,	/* devo_attach */
157 	amd8111s_detach,	/* devo_detach */
158 	nodev,			/* devo_reset */
159 	&amd8111s_cb_ops,	/* devo_cb_ops */
160 	NULL,			/* devo_bus_ops */
161 	nodev
162 };
163 
164 struct modldrv amd8111s_modldrv = {
165 	&mod_driverops,		/* Type of module. This one is a driver */
166 	ident,			/* short description */
167 	&amd8111s_dev_ops	/* driver specific ops */
168 };
169 
170 struct modlinkage amd8111s_modlinkage = {
171 	MODREV_1, (void *)&amd8111s_modldrv, NULL
172 };
173 
174 /*
175  * Global Variables
176  */
177 struct LayerPointers *amd8111sadapter;
178 
179 static ddi_dma_attr_t pcn_buff_dma_attr_t = {
180 	DMA_ATTR_V0,	/* dma_attr_version */
181 	(uint64_t)0,		/* dma_attr_addr_lo */
182 	(uint64_t)0xFFFFFFFF,	/* dma_attr_addr_hi */
183 	(uint64_t)0xFFFFFFFF,	/* dma_attr_count_max */
184 	(uint64_t)1,		/* dma_attr_align */
185 	(uint_t)0x7F,		/* dma_attr_burstsizes */
186 	(uint32_t)1,		/* dma_attr_minxfer */
187 	(uint64_t)0xFFFFFFFF,	/* dma_attr_maxxfer */
188 	(uint64_t)0xFFFFFFFF,	/* dma_attr_seg */
189 	(int)1,			/* dma_attr_sgllen */
190 	(uint32_t)1,		/* granularity */
191 	(uint_t)0		/* dma_attr_flags */
192 };
193 
194 static ddi_dma_attr_t pcn_desc_dma_attr_t = {
195 	DMA_ATTR_V0,		/* dma_attr_version */
196 	(uint64_t)0,		/* dma_attr_addr_lo */
197 	(uint64_t)0xFFFFFFFF,	/* dma_attr_addr_hi */
198 	(uint64_t)0x7FFFFFFF,	/* dma_attr_count_max */
199 	(uint64_t)0x10,		/* dma_attr_align */
200 	(uint_t)0xFFFFFFFFU,	/* dma_attr_burstsizes */
201 	(uint32_t)1,		/* dma_attr_minxfer */
202 	(uint64_t)0xFFFFFFFF,	/* dma_attr_maxxfer */
203 	(uint64_t)0xFFFFFFFF,	/* dma_attr_seg */
204 	(int)1,			/* dma_attr_sgllen */
205 	(uint32_t)1,		/* granularity */
206 	(uint_t)0		/* dma_attr_flags */
207 };
208 
209 /* PIO access attributes for registers */
210 static ddi_device_acc_attr_t pcn_acc_attr = {
211 	DDI_DEVICE_ATTR_V0,
212 	DDI_STRUCTURE_LE_ACC,
213 	DDI_STRICTORDER_ACC
214 };
215 
216 #define	AMD8111S_M_CALLBACK_FLAGS	(MC_RESOURCES | MC_IOCTL)
217 
218 
219 static mac_callbacks_t amd8111s_m_callbacks = {
220 	AMD8111S_M_CALLBACK_FLAGS,
221 	amd8111s_m_stat,
222 	amd8111s_m_start,
223 	amd8111s_m_stop,
224 	amd8111s_m_promisc,
225 	amd8111s_m_multicst,
226 	amd8111s_m_unicst,
227 	amd8111s_m_tx,
228 	amd8111s_m_resources,
229 	amd8111s_m_ioctl
230 };
231 
232 
233 /*
234  * Standard Driver Load Entry Point
235  * It will be called at load time of driver.
236  */
237 int
238 _init()
239 {
240 	int status;
241 	mac_init_ops(&amd8111s_dev_ops, "amd8111s");
242 
243 	status = mod_install(&amd8111s_modlinkage);
244 	if (status != DDI_SUCCESS) {
245 		mac_fini_ops(&amd8111s_dev_ops);
246 	}
247 
248 	return (status);
249 }
250 
251 /*
252  * Standard Driver Entry Point for Query.
253  * It will be called at any time to get Driver info.
254  */
255 int
256 _info(struct modinfo *modinfop)
257 {
258 	return (mod_info(&amd8111s_modlinkage, modinfop));
259 }
260 
261 /*
262  *	Standard Driver Entry Point for Unload.
263  *	It will be called at unload time of driver.
264  */
265 int
266 _fini()
267 {
268 	int status;
269 
270 	status = mod_remove(&amd8111s_modlinkage);
271 	if (status == DDI_SUCCESS) {
272 		mac_fini_ops(&amd8111s_dev_ops);
273 	}
274 
275 	return (status);
276 }
277 
278 /* Adjust Interrupt Coalescing Register to coalesce interrupts */
279 static void
280 amd8111s_m_blank(void *arg, time_t ticks, uint32_t count)
281 {
282 	_NOTE(ARGUNUSED(arg, ticks, count));
283 }
284 
285 static void
286 amd8111s_m_resources(void *arg)
287 {
288 	struct LayerPointers *adapter = arg;
289 	mac_rx_fifo_t mrf;
290 
291 	mrf.mrf_type = MAC_RX_FIFO;
292 	mrf.mrf_blank = amd8111s_m_blank;
293 	mrf.mrf_arg = (void *)adapter;
294 	mrf.mrf_normal_blank_time = 128;
295 	mrf.mrf_normal_pkt_count = 8;
296 
297 	adapter->pOdl->mrh = mac_resource_add(adapter->pOdl->mh,
298 	    (mac_resource_t *)&mrf);
299 }
300 
301 /*
302  * Loopback Support
303  */
304 static lb_property_t loopmodes[] = {
305 	{ normal,	"normal",	AMD8111S_LB_NONE		},
306 	{ external,	"100Mbps",	AMD8111S_LB_EXTERNAL_100	},
307 	{ external,	"10Mbps",	AMD8111S_LB_EXTERNAL_10		},
308 	{ internal,	"MAC",		AMD8111S_LB_INTERNAL_MAC	}
309 };
310 
311 static void
312 amd8111s_set_loop_mode(struct LayerPointers *adapter, uint32_t mode)
313 {
314 
315 	/*
316 	 * If the mode isn't being changed, there's nothing to do ...
317 	 */
318 	if (mode == adapter->pOdl->loopback_mode)
319 		return;
320 
321 	/*
322 	 * Validate the requested mode and prepare a suitable message
323 	 * to explain the link down/up cycle that the change will
324 	 * probably induce ...
325 	 */
326 	switch (mode) {
327 	default:
328 		return;
329 
330 	case AMD8111S_LB_NONE:
331 		mdlStopChip(adapter);
332 		if (adapter->pOdl->loopback_mode == AMD8111S_LB_INTERNAL_MAC) {
333 			cmn_err(CE_NOTE, "LB_NONE restored from Interanl LB");
334 			WRITE_REG32(adapter, adapter->pMdl->Mem_Address + CMD2,
335 			    INLOOP);
336 			WRITE_REG32(adapter, adapter->pMdl->Mem_Address + CMD3,
337 			    FORCE_FULL_DUPLEX | FORCE_LINK_STATUS);
338 		} else {
339 			cmn_err(CE_NOTE, "LB_NONE restored from Exteranl LB");
340 			WRITE_REG32(adapter, adapter->pMdl->Mem_Address + CMD2,
341 			    EXLOOP);
342 		}
343 
344 		amd8111s_reset(adapter);
345 		adapter->pOdl->LinkStatus = LINK_STATE_DOWN;
346 		adapter->pOdl->rx_fcs_stripped = B_FALSE;
347 		mdlStartChip(adapter);
348 		break;
349 
350 	case AMD8111S_LB_EXTERNAL_100:
351 		cmn_err(CE_NOTE, "amd8111s_set_loop_mode LB_EXTERNAL_100");
352 		mdlStopChip(adapter);
353 		amd8111s_reset(adapter);
354 		SetIntrCoalesc(adapter, B_FALSE);
355 		mdlPHYAutoNegotiation(adapter, PHY_FORCE_FD_100);
356 		WRITE_REG32(adapter, adapter->pMdl->Mem_Address + CMD2,
357 		    VAL0 | EXLOOP);
358 		adapter->pOdl->LinkStatus = LINK_STATE_UP;
359 		adapter->pMdl->Speed = 100;
360 		adapter->pMdl->FullDuplex = B_TRUE;
361 		/* Tell GLD the state of the physical link. */
362 		mac_link_update(adapter->pOdl->mh, LINK_STATE_UP);
363 
364 		adapter->pOdl->rx_fcs_stripped = B_TRUE;
365 
366 		mdlStartChip(adapter);
367 		break;
368 
369 	case AMD8111S_LB_EXTERNAL_10:
370 		cmn_err(CE_NOTE, "amd8111s_set_loop_mode LB_EXTERNAL_10");
371 		mdlStopChip(adapter);
372 		amd8111s_reset(adapter);
373 		SetIntrCoalesc(adapter, B_FALSE);
374 		mdlPHYAutoNegotiation(adapter, PHY_FORCE_FD_10);
375 		WRITE_REG32(adapter, adapter->pMdl->Mem_Address + CMD2,
376 		    VAL0 | EXLOOP);
377 		adapter->pOdl->LinkStatus = LINK_STATE_UP;
378 		adapter->pMdl->Speed = 10;
379 		adapter->pMdl->FullDuplex = B_TRUE;
380 		/* Tell GLD the state of the physical link. */
381 		mac_link_update(adapter->pOdl->mh, LINK_STATE_UP);
382 
383 		adapter->pOdl->rx_fcs_stripped = B_TRUE;
384 
385 		mdlStartChip(adapter);
386 		break;
387 
388 	case AMD8111S_LB_INTERNAL_MAC:
389 		cmn_err(CE_NOTE, "amd8111s_set_loop_mode LB_INTERNAL_MAC");
390 		mdlStopChip(adapter);
391 		amd8111s_reset(adapter);
392 		SetIntrCoalesc(adapter, B_FALSE);
393 		/* Disable Port Manager */
394 		WRITE_REG32(adapter, adapter->pMdl->Mem_Address + CMD3,
395 		    EN_PMGR);
396 		WRITE_REG32(adapter, adapter->pMdl->Mem_Address + CMD2,
397 		    VAL0 | INLOOP);
398 
399 		WRITE_REG32(adapter, adapter->pMdl->Mem_Address + CMD3,
400 		    VAL1 | FORCE_FULL_DUPLEX | FORCE_LINK_STATUS);
401 
402 		adapter->pOdl->LinkStatus = LINK_STATE_UP;
403 		adapter->pMdl->FullDuplex = B_TRUE;
404 		/* Tell GLD the state of the physical link. */
405 		mac_link_update(adapter->pOdl->mh, LINK_STATE_UP);
406 
407 		adapter->pOdl->rx_fcs_stripped = B_TRUE;
408 
409 		mdlStartChip(adapter);
410 		break;
411 	}
412 
413 	/*
414 	 * All OK; tell the caller to reprogram
415 	 * the PHY and/or MAC for the new mode ...
416 	 */
417 	adapter->pOdl->loopback_mode = mode;
418 }
419 
420 static enum ioc_reply
421 amd8111s_loopback_ioctl(struct LayerPointers *adapter, struct iocblk *iocp,
422     mblk_t *mp)
423 {
424 	lb_info_sz_t *lbsp;
425 	lb_property_t *lbpp;
426 	uint32_t *lbmp;
427 	int cmd;
428 
429 	/*
430 	 * Validate format of ioctl
431 	 */
432 	if (mp->b_cont == NULL)
433 		return (IOC_INVAL);
434 
435 	cmd = iocp->ioc_cmd;
436 	switch (cmd) {
437 	default:
438 		/* NOTREACHED */
439 		amd8111s_log(adapter, CE_NOTE,
440 		    "amd8111s_loop_ioctl: invalid cmd 0x%x", cmd);
441 		return (IOC_INVAL);
442 
443 	case LB_GET_INFO_SIZE:
444 		if (iocp->ioc_count != sizeof (lb_info_sz_t)) {
445 			amd8111s_log(adapter, CE_NOTE,
446 			    "wrong LB_GET_INFO_SIZE size");
447 			return (IOC_INVAL);
448 		}
449 		lbsp = (lb_info_sz_t *)mp->b_cont->b_rptr;
450 		*lbsp = sizeof (loopmodes);
451 		break;
452 
453 	case LB_GET_INFO:
454 		if (iocp->ioc_count != sizeof (loopmodes)) {
455 			amd8111s_log(adapter, CE_NOTE,
456 			    "Wrong LB_GET_INFO size");
457 			return (IOC_INVAL);
458 		}
459 		lbpp = (lb_property_t *)mp->b_cont->b_rptr;
460 		bcopy(loopmodes, lbpp, sizeof (loopmodes));
461 		break;
462 
463 	case LB_GET_MODE:
464 		if (iocp->ioc_count != sizeof (uint32_t)) {
465 			amd8111s_log(adapter, CE_NOTE,
466 			    "Wrong LB_GET_MODE size");
467 			return (IOC_INVAL);
468 		}
469 		lbmp = (uint32_t *)mp->b_cont->b_rptr;
470 		*lbmp = adapter->pOdl->loopback_mode;
471 		break;
472 
473 	case LB_SET_MODE:
474 		if (iocp->ioc_count != sizeof (uint32_t)) {
475 			amd8111s_log(adapter, CE_NOTE,
476 			    "Wrong LB_SET_MODE size");
477 			return (IOC_INVAL);
478 		}
479 		lbmp = (uint32_t *)mp->b_cont->b_rptr;
480 		amd8111s_set_loop_mode(adapter, *lbmp);
481 		break;
482 	}
483 	return (IOC_REPLY);
484 }
485 
486 static void
487 amd8111s_m_ioctl(void *arg, queue_t *q, mblk_t *mp)
488 {
489 	struct iocblk *iocp;
490 	struct LayerPointers *adapter;
491 	enum ioc_reply status;
492 
493 	iocp = (struct iocblk *)mp->b_rptr;
494 	iocp->ioc_error = 0;
495 	adapter = (struct LayerPointers *)arg;
496 
497 	ASSERT(adapter);
498 	if (adapter == NULL) {
499 		miocnak(q, mp, 0, EINVAL);
500 		return;
501 	}
502 
503 	switch (iocp->ioc_cmd) {
504 
505 	case LB_GET_INFO_SIZE:
506 	case LB_GET_INFO:
507 	case LB_GET_MODE:
508 	case LB_SET_MODE:
509 		status = amd8111s_loopback_ioctl(adapter, iocp, mp);
510 		break;
511 
512 	default:
513 		status = IOC_INVAL;
514 		break;
515 	}
516 
517 	/*
518 	 * Decide how to reply
519 	 */
520 	switch (status) {
521 	default:
522 	case IOC_INVAL:
523 		/*
524 		 * Error, reply with a NAK and EINVAL or the specified error
525 		 */
526 		miocnak(q, mp, 0, iocp->ioc_error == 0 ?
527 		    EINVAL : iocp->ioc_error);
528 		break;
529 
530 	case IOC_DONE:
531 		/*
532 		 * OK, reply already sent
533 		 */
534 		break;
535 
536 	case IOC_ACK:
537 		/*
538 		 * OK, reply with an ACK
539 		 */
540 		miocack(q, mp, 0, 0);
541 		break;
542 
543 	case IOC_REPLY:
544 		/*
545 		 * OK, send prepared reply as ACK or NAK
546 		 */
547 		mp->b_datap->db_type = iocp->ioc_error == 0 ?
548 		    M_IOCACK : M_IOCNAK;
549 		qreply(q, mp);
550 		break;
551 	}
552 }
553 
554 /*
555  * Copy one packet from dma memory to mblk. Inc dma descriptor pointer.
556  */
557 static boolean_t
558 amd8111s_recv_copy(struct LayerPointers *pLayerPointers, mblk_t **last_mp)
559 {
560 	int length = 0;
561 	mblk_t *mp;
562 	struct rx_desc *descriptor;
563 	struct odl *pOdl = pLayerPointers->pOdl;
564 	struct amd8111s_statistics *statistics = &pOdl->statistics;
565 	struct nonphysical *pNonphysical = pLayerPointers->pMil
566 	    ->pNonphysical;
567 
568 	mutex_enter(&pOdl->mdlRcvLock);
569 	descriptor = pNonphysical->RxBufDescQRead->descriptor;
570 	(void) ddi_dma_sync(pOdl->rx_desc_dma_handle,
571 	    pNonphysical->RxBufDescQRead->descriptor -
572 	    pNonphysical->RxBufDescQStart->descriptor,
573 	    sizeof (struct rx_desc), DDI_DMA_SYNC_FORCPU);
574 	if ((descriptor->Rx_OWN) == 0) {
575 	/*
576 	 * If the frame is received with errors, then set MCNT
577 	 * of that pkt in ReceiveArray to 0. This packet would
578 	 * be discarded later and not indicated to OS.
579 	 */
580 		if (descriptor->Rx_ERR) {
581 			statistics->rx_desc_err ++;
582 			descriptor->Rx_ERR = 0;
583 			if (descriptor->Rx_FRAM == 1) {
584 				statistics->rx_desc_err_FRAM ++;
585 				descriptor->Rx_FRAM = 0;
586 			}
587 			if (descriptor->Rx_OFLO == 1) {
588 				statistics->rx_desc_err_OFLO ++;
589 				descriptor->Rx_OFLO = 0;
590 				pOdl->rx_overflow_counter ++;
591 				if ((pOdl->rx_overflow_counter > 5) &&
592 				    (pOdl->pause_interval == 0)) {
593 					statistics->rx_double_overflow ++;
594 					mdlSendPause(pLayerPointers);
595 					pOdl->rx_overflow_counter = 0;
596 					pOdl->pause_interval = 25;
597 				}
598 			}
599 			if (descriptor->Rx_CRC == 1) {
600 				statistics->rx_desc_err_CRC ++;
601 				descriptor->Rx_CRC = 0;
602 			}
603 			if (descriptor->Rx_BUFF == 1) {
604 				statistics->rx_desc_err_BUFF ++;
605 				descriptor->Rx_BUFF = 0;
606 			}
607 			goto Next_Descriptor;
608 		}
609 
610 		/* Length of incoming packet */
611 		if (pOdl->rx_fcs_stripped) {
612 			length = descriptor->Rx_MCNT -4;
613 		} else {
614 			length = descriptor->Rx_MCNT;
615 		}
616 		if (length < 62) {
617 			statistics->rx_error_zerosize ++;
618 		}
619 
620 		if ((mp = allocb(length, BPRI_MED)) == NULL) {
621 			statistics->rx_allocfail ++;
622 			goto failed;
623 		}
624 		/* Copy from virtual address of incoming packet */
625 		bcopy((long *)*(pNonphysical->RxBufDescQRead->USpaceMap),
626 		    mp->b_rptr, length);
627 		mp->b_wptr = mp->b_rptr + length;
628 		statistics->rx_ok_packets ++;
629 		if (*last_mp == NULL) {
630 			*last_mp = mp;
631 		} else {
632 			(*last_mp)->b_next = mp;
633 			*last_mp = mp;
634 		}
635 
636 Next_Descriptor:
637 		descriptor->Rx_MCNT = 0;
638 		descriptor->Rx_SOP = 0;
639 		descriptor->Rx_EOP = 0;
640 		descriptor->Rx_PAM = 0;
641 		descriptor->Rx_BAM = 0;
642 		descriptor->TT = 0;
643 		descriptor->Rx_OWN = 1;
644 		pNonphysical->RxBufDescQRead->descriptor++;
645 		pNonphysical->RxBufDescQRead->USpaceMap++;
646 		if (pNonphysical->RxBufDescQRead->descriptor >
647 		    pNonphysical->RxBufDescQEnd->descriptor) {
648 			pNonphysical->RxBufDescQRead->descriptor =
649 			    pNonphysical->RxBufDescQStart->descriptor;
650 			pNonphysical->RxBufDescQRead->USpaceMap =
651 			    pNonphysical->RxBufDescQStart->USpaceMap;
652 		}
653 		mutex_exit(&pOdl->mdlRcvLock);
654 
655 		return (B_TRUE);
656 	}
657 
658 failed:
659 	mutex_exit(&pOdl->mdlRcvLock);
660 	return (B_FALSE);
661 }
662 
663 /*
664  * Get the received packets from NIC card and send them to GLD.
665  */
666 static void
667 amd8111s_receive(struct LayerPointers *pLayerPointers)
668 {
669 	int numOfPkts = 0;
670 	struct odl *pOdl;
671 	mblk_t *ret_mp = NULL, *last_mp = NULL;
672 
673 	pOdl = pLayerPointers->pOdl;
674 
675 	rw_enter(&pOdl->chip_lock, RW_READER);
676 	if (!pLayerPointers->run) {
677 		rw_exit(&pOdl->chip_lock);
678 		return;
679 	}
680 
681 	if (pOdl->pause_interval > 0)
682 		pOdl->pause_interval --;
683 
684 	while (numOfPkts < RX_RING_SIZE) {
685 
686 		if (!amd8111s_recv_copy(pLayerPointers, &last_mp)) {
687 			break;
688 		}
689 		if (ret_mp == NULL)
690 			ret_mp = last_mp;
691 		numOfPkts++;
692 	}
693 
694 	if (ret_mp) {
695 		mac_rx(pOdl->mh, pOdl->mrh, ret_mp);
696 	}
697 
698 	(void) ddi_dma_sync(pOdl->rx_desc_dma_handle, 0, 0,
699 	    DDI_DMA_SYNC_FORDEV);
700 
701 	mdlReceive(pLayerPointers);
702 
703 	rw_exit(&pOdl->chip_lock);
704 
705 }
706 
707 /*
708  * Print message in release-version driver.
709  */
710 static void
711 amd8111s_log(struct LayerPointers *adapter, int level, char *fmt, ...)
712 {
713 	auto char name[32];
714 	auto char buf[256];
715 	va_list ap;
716 
717 	if (adapter != NULL) {
718 		(void) sprintf(name, "amd8111s%d",
719 		    ddi_get_instance(adapter->pOdl->devinfo));
720 	} else {
721 		(void) sprintf(name, "amd8111s");
722 	}
723 	va_start(ap, fmt);
724 	(void) vsprintf(buf, fmt, ap);
725 	va_end(ap);
726 	cmn_err(level, "%s: %s", name, buf);
727 }
728 
729 /*
730  * To allocate & initilize all resources.
731  * Called by amd8111s_attach().
732  */
733 static int
734 amd8111s_odlInit(struct LayerPointers *pLayerPointers)
735 {
736 	unsigned long mem_req_array[MEM_REQ_MAX];
737 	unsigned long mem_set_array[MEM_REQ_MAX];
738 	unsigned long *pmem_req_array;
739 	unsigned long *pmem_set_array;
740 	int i, size;
741 
742 	for (i = 0; i < MEM_REQ_MAX; i++) {
743 		mem_req_array[i] = 0;
744 		mem_set_array[i] = 0;
745 	}
746 
747 	milRequestResources(mem_req_array);
748 
749 	pmem_req_array = mem_req_array;
750 	pmem_set_array = mem_set_array;
751 	while (*pmem_req_array) {
752 		switch (*pmem_req_array) {
753 		case VIRTUAL:
754 			*pmem_set_array = VIRTUAL;
755 			pmem_req_array++;
756 			pmem_set_array++;
757 			*(pmem_set_array) = *(pmem_req_array);
758 			pmem_set_array++;
759 			*(pmem_set_array) = (unsigned long) kmem_zalloc(
760 			    *(pmem_req_array), KM_NOSLEEP);
761 			if (*pmem_set_array == NULL)
762 				goto odl_init_failure;
763 			break;
764 		}
765 		pmem_req_array++;
766 		pmem_set_array++;
767 	}
768 
769 	/*
770 	 * Initilize memory on lower layers
771 	 */
772 	milSetResources(pLayerPointers, mem_set_array);
773 
774 	/* Allocate Rx/Tx descriptors */
775 	if (amd8111s_allocate_descriptors(pLayerPointers) != B_TRUE) {
776 		*pmem_set_array = NULL;
777 		goto odl_init_failure;
778 	}
779 
780 	/*
781 	 * Allocate Rx buffer for each Rx descriptor. Then call mil layer
782 	 * routine to fill physical address of Rx buffer into Rx descriptor.
783 	 */
784 	if (amd8111s_allocate_buffers(pLayerPointers) == B_FALSE) {
785 		amd8111s_free_descriptors(pLayerPointers);
786 		*pmem_set_array = NULL;
787 		goto odl_init_failure;
788 	}
789 	milInitGlbds(pLayerPointers);
790 
791 	return (0);
792 
793 odl_init_failure:
794 	/*
795 	 * Free All memory allocated so far
796 	 */
797 	pmem_req_array = mem_set_array;
798 	while ((*pmem_req_array) && (pmem_req_array != pmem_set_array)) {
799 		switch (*pmem_req_array) {
800 		case VIRTUAL:
801 			pmem_req_array++;	/* Size */
802 			size = *(pmem_req_array);
803 			pmem_req_array++;	/* Virtual Address */
804 			if (pmem_req_array == NULL)
805 				return (1);
806 			kmem_free((int *)*pmem_req_array, size);
807 			break;
808 		}
809 		pmem_req_array++;
810 	}
811 	return (1);
812 }
813 
814 /*
815  * Allocate and initialize Tx/Rx descriptors
816  */
817 static boolean_t
818 amd8111s_allocate_descriptors(struct LayerPointers *pLayerPointers)
819 {
820 	struct odl *pOdl = pLayerPointers->pOdl;
821 	struct mil *pMil = pLayerPointers->pMil;
822 	dev_info_t *devinfo = pOdl->devinfo;
823 	uint_t length, count, i;
824 	size_t real_length;
825 
826 	/*
827 	 * Allocate Rx descriptors
828 	 */
829 	if (ddi_dma_alloc_handle(devinfo, &pcn_desc_dma_attr_t, DDI_DMA_SLEEP,
830 	    NULL, &pOdl->rx_desc_dma_handle) != DDI_SUCCESS) {
831 		amd8111s_log(pLayerPointers, CE_WARN,
832 		    "ddi_dma_alloc_handle for Rx desc failed");
833 		pOdl->rx_desc_dma_handle = NULL;
834 		return (B_FALSE);
835 	}
836 
837 	length = sizeof (struct rx_desc) * RX_RING_SIZE + ALIGNMENT;
838 	if (ddi_dma_mem_alloc(pOdl->rx_desc_dma_handle, length,
839 	    &pcn_acc_attr, DDI_DMA_CONSISTENT, DDI_DMA_SLEEP,
840 	    NULL, (caddr_t *)&pMil->Rx_desc_original, &real_length,
841 	    &pOdl->rx_desc_acc_handle) != DDI_SUCCESS) {
842 
843 		amd8111s_log(pLayerPointers, CE_WARN,
844 		    "ddi_dma_mem_handle for Rx desc failed");
845 		ddi_dma_free_handle(&pOdl->rx_desc_dma_handle);
846 		pOdl->rx_desc_dma_handle = NULL;
847 		return (B_FALSE);
848 	}
849 
850 	if (ddi_dma_addr_bind_handle(pOdl->rx_desc_dma_handle,
851 	    NULL, (caddr_t)pMil->Rx_desc_original, real_length,
852 	    DDI_DMA_RDWR | DDI_DMA_CONSISTENT, DDI_DMA_SLEEP,
853 	    NULL, &pOdl->rx_desc_dma_cookie,
854 	    &count) != DDI_SUCCESS) {
855 
856 		amd8111s_log(pLayerPointers, CE_WARN,
857 		    "ddi_dma_addr_bind_handle for Rx desc failed");
858 		ddi_dma_mem_free(&pOdl->rx_desc_acc_handle);
859 		ddi_dma_free_handle(&pOdl->rx_desc_dma_handle);
860 		pOdl->rx_desc_dma_handle = NULL;
861 		return (B_FALSE);
862 	}
863 	ASSERT(count == 1);
864 
865 	/* Initialize Rx descriptors related variables */
866 	pMil->Rx_desc = (struct rx_desc *)
867 	    ((pMil->Rx_desc_original + ALIGNMENT) & ~ALIGNMENT);
868 	pMil->Rx_desc_pa = (unsigned int)
869 	    ((pOdl->rx_desc_dma_cookie.dmac_laddress + ALIGNMENT) & ~ALIGNMENT);
870 
871 	pLayerPointers->pMdl->init_blk->RDRA = pMil->Rx_desc_pa;
872 
873 
874 	/*
875 	 * Allocate Tx descriptors
876 	 */
877 	if (ddi_dma_alloc_handle(devinfo, &pcn_desc_dma_attr_t, DDI_DMA_SLEEP,
878 	    NULL, &pOdl->tx_desc_dma_handle) != DDI_SUCCESS) {
879 		amd8111s_log(pLayerPointers, CE_WARN,
880 		    "ddi_dma_alloc_handle for Tx desc failed");
881 		goto allocate_desc_fail;
882 	}
883 
884 	length = sizeof (struct tx_desc) * TX_RING_SIZE + ALIGNMENT;
885 	if (ddi_dma_mem_alloc(pOdl->tx_desc_dma_handle, length,
886 	    &pcn_acc_attr, DDI_DMA_CONSISTENT, DDI_DMA_SLEEP,
887 	    NULL, (caddr_t *)&pMil->Tx_desc_original, &real_length,
888 	    &pOdl->tx_desc_acc_handle) != DDI_SUCCESS) {
889 
890 		amd8111s_log(pLayerPointers, CE_WARN,
891 		    "ddi_dma_mem_handle for Tx desc failed");
892 		ddi_dma_free_handle(&pOdl->tx_desc_dma_handle);
893 		goto allocate_desc_fail;
894 	}
895 
896 	if (ddi_dma_addr_bind_handle(pOdl->tx_desc_dma_handle,
897 	    NULL, (caddr_t)pMil->Tx_desc_original, real_length,
898 	    DDI_DMA_RDWR | DDI_DMA_CONSISTENT, DDI_DMA_SLEEP,
899 	    NULL, &pOdl->tx_desc_dma_cookie,
900 	    &count) != DDI_SUCCESS) {
901 
902 		amd8111s_log(pLayerPointers, CE_WARN,
903 		    "ddi_dma_addr_bind_handle for Tx desc failed");
904 		ddi_dma_mem_free(&pOdl->tx_desc_acc_handle);
905 		ddi_dma_free_handle(&pOdl->tx_desc_dma_handle);
906 		goto allocate_desc_fail;
907 	}
908 	ASSERT(count == 1);
909 	/* Set the DMA area to all zeros */
910 	bzero((caddr_t)pMil->Tx_desc_original, length);
911 
912 	/* Initialize Tx descriptors related variables */
913 	pMil->Tx_desc = (struct tx_desc *)
914 	    ((pMil->Tx_desc_original + ALIGNMENT) & ~ALIGNMENT);
915 	pMil->pNonphysical->TxDescQRead = pMil->Tx_desc;
916 	pMil->pNonphysical->TxDescQWrite = pMil->Tx_desc;
917 	pMil->pNonphysical->TxDescQStart = pMil->Tx_desc;
918 	pMil->pNonphysical->TxDescQEnd = &(pMil->Tx_desc[TX_RING_SIZE -1]);
919 
920 	/* Physical Addr of Tx_desc_original & Tx_desc */
921 	pLayerPointers->pMil->Tx_desc_pa =
922 	    ((pOdl->tx_desc_dma_cookie.dmac_laddress + ALIGNMENT) &
923 	    ~ALIGNMENT);
924 
925 	/* Setting the reserved bits in the tx descriptors */
926 	for (i = 0; i < TX_RING_SIZE; i++) {
927 		pMil->pNonphysical->TxDescQWrite->Tx_RES0 = 0x0f;
928 		pMil->pNonphysical->TxDescQWrite->Tx_OWN = 0;
929 		pMil->pNonphysical->TxDescQWrite++;
930 	}
931 	pMil->pNonphysical->TxDescQWrite = pMil->pNonphysical->TxDescQStart;
932 
933 	pLayerPointers->pMdl->init_blk->TDRA = pMil->Tx_desc_pa;
934 
935 	return (B_TRUE);
936 
937 allocate_desc_fail:
938 	pOdl->tx_desc_dma_handle = NULL;
939 	(void) ddi_dma_unbind_handle(pOdl->rx_desc_dma_handle);
940 	ddi_dma_mem_free(&pOdl->rx_desc_acc_handle);
941 	ddi_dma_free_handle(&pOdl->rx_desc_dma_handle);
942 	pOdl->rx_desc_dma_handle = NULL;
943 	return (B_FALSE);
944 }
945 
946 /*
947  * Free Tx/Rx descriptors
948  */
949 static void
950 amd8111s_free_descriptors(struct LayerPointers *pLayerPointers)
951 {
952 	struct odl *pOdl = pLayerPointers->pOdl;
953 
954 	/* Free Rx descriptors */
955 	if (pOdl->rx_desc_dma_handle) {
956 		(void) ddi_dma_unbind_handle(pOdl->rx_desc_dma_handle);
957 		ddi_dma_mem_free(&pOdl->rx_desc_acc_handle);
958 		ddi_dma_free_handle(&pOdl->rx_desc_dma_handle);
959 		pOdl->rx_desc_dma_handle = NULL;
960 	}
961 
962 	/* Free Rx descriptors */
963 	if (pOdl->tx_desc_dma_handle) {
964 		(void) ddi_dma_unbind_handle(pOdl->tx_desc_dma_handle);
965 		ddi_dma_mem_free(&pOdl->tx_desc_acc_handle);
966 		ddi_dma_free_handle(&pOdl->tx_desc_dma_handle);
967 		pOdl->tx_desc_dma_handle = NULL;
968 	}
969 }
970 
971 /*
972  * Allocate Tx/Rx Ring buffer
973  */
974 static boolean_t
975 amd8111s_alloc_dma_ringbuf(struct LayerPointers *pLayerPointers,
976 			struct amd8111s_dma_ringbuf *pRing,
977 			uint32_t ring_size, uint32_t msg_size)
978 {
979 	uint32_t idx, msg_idx = 0, msg_acc;
980 	dev_info_t *devinfo = pLayerPointers->pOdl->devinfo;
981 	size_t real_length;
982 	uint_t count = 0;
983 
984 	ASSERT(pcn_buff_dma_attr_t.dma_attr_align == 1);
985 	pRing->dma_buf_sz = msg_size;
986 	pRing->ring_size = ring_size;
987 	pRing->trunk_num = AMD8111S_SPLIT;
988 	pRing->buf_sz = msg_size * ring_size;
989 	if (ring_size < pRing->trunk_num)
990 		pRing->trunk_num = ring_size;
991 	ASSERT((pRing->buf_sz % pRing->trunk_num) == 0);
992 
993 	pRing->trunk_sz = pRing->buf_sz / pRing->trunk_num;
994 	ASSERT((pRing->trunk_sz % pRing->dma_buf_sz) == 0);
995 
996 	pRing->msg_buf = kmem_zalloc(sizeof (struct amd8111s_msgbuf) *
997 	    ring_size, KM_NOSLEEP);
998 	pRing->dma_hdl = kmem_zalloc(sizeof (ddi_dma_handle_t) *
999 	    pRing->trunk_num, KM_NOSLEEP);
1000 	pRing->acc_hdl = kmem_zalloc(sizeof (ddi_acc_handle_t) *
1001 	    pRing->trunk_num, KM_NOSLEEP);
1002 	pRing->dma_cookie = kmem_zalloc(sizeof (ddi_dma_cookie_t) *
1003 	    pRing->trunk_num, KM_NOSLEEP);
1004 	pRing->trunk_addr = kmem_zalloc(sizeof (caddr_t) *
1005 	    pRing->trunk_num, KM_NOSLEEP);
1006 	if (pRing->msg_buf == NULL || pRing->dma_hdl == NULL ||
1007 	    pRing->acc_hdl == NULL || pRing->trunk_addr == NULL ||
1008 	    pRing->dma_cookie == NULL) {
1009 		amd8111s_log(pLayerPointers, CE_NOTE,
1010 		    "kmem_zalloc failed");
1011 		goto failed;
1012 	}
1013 
1014 	for (idx = 0; idx < pRing->trunk_num; ++idx) {
1015 		if (ddi_dma_alloc_handle(devinfo, &pcn_buff_dma_attr_t,
1016 		    DDI_DMA_SLEEP, NULL, &(pRing->dma_hdl[idx]))
1017 		    != DDI_SUCCESS) {
1018 
1019 			amd8111s_log(pLayerPointers, CE_WARN,
1020 			    "ddi_dma_alloc_handle failed");
1021 			goto failed;
1022 		} else if (ddi_dma_mem_alloc(pRing->dma_hdl[idx],
1023 		    pRing->trunk_sz, &pcn_acc_attr, DDI_DMA_STREAMING,
1024 		    DDI_DMA_SLEEP, NULL,
1025 		    (caddr_t *)&(pRing->trunk_addr[idx]),
1026 		    (size_t *)(&real_length), &pRing->acc_hdl[idx])
1027 		    != DDI_SUCCESS) {
1028 
1029 			amd8111s_log(pLayerPointers, CE_WARN,
1030 			    "ddi_dma_mem_alloc failed");
1031 			goto failed;
1032 		} else if (real_length != pRing->trunk_sz) {
1033 			amd8111s_log(pLayerPointers, CE_WARN,
1034 			    "ddi_dma_mem_alloc failed");
1035 			goto failed;
1036 		} else if (ddi_dma_addr_bind_handle(pRing->dma_hdl[idx],
1037 		    NULL, (caddr_t)pRing->trunk_addr[idx], real_length,
1038 		    DDI_DMA_WRITE | DDI_DMA_STREAMING, DDI_DMA_SLEEP, NULL,
1039 		    &pRing->dma_cookie[idx], &count) != DDI_DMA_MAPPED) {
1040 
1041 			amd8111s_log(pLayerPointers, CE_WARN,
1042 			    "ddi_dma_addr_bind_handle failed");
1043 			goto failed;
1044 		} else {
1045 			for (msg_acc = 0;
1046 			    msg_acc < pRing->trunk_sz / pRing->dma_buf_sz;
1047 			    ++ msg_acc) {
1048 				pRing->msg_buf[msg_idx].offset =
1049 				    msg_acc * pRing->dma_buf_sz;
1050 				pRing->msg_buf[msg_idx].vir_addr =
1051 				    pRing->trunk_addr[idx] +
1052 				    pRing->msg_buf[msg_idx].offset;
1053 				pRing->msg_buf[msg_idx].phy_addr =
1054 				    pRing->dma_cookie[idx].dmac_laddress +
1055 				    pRing->msg_buf[msg_idx].offset;
1056 				pRing->msg_buf[msg_idx].p_hdl =
1057 				    pRing->dma_hdl[idx];
1058 				msg_idx ++;
1059 			}
1060 		}
1061 	}
1062 
1063 	pRing->free = pRing->msg_buf;
1064 	pRing->next = pRing->msg_buf;
1065 	pRing->curr = pRing->msg_buf;
1066 
1067 	return (B_TRUE);
1068 failed:
1069 	amd8111s_free_dma_ringbuf(pRing);
1070 	return (B_FALSE);
1071 }
1072 
1073 /*
1074  * Free Tx/Rx ring buffer
1075  */
1076 static void
1077 amd8111s_free_dma_ringbuf(struct amd8111s_dma_ringbuf *pRing)
1078 {
1079 	int idx;
1080 
1081 	if (pRing->dma_cookie != NULL) {
1082 		for (idx = 0; idx < pRing->trunk_num; idx ++) {
1083 			if (pRing->dma_cookie[idx].dmac_laddress == 0) {
1084 				break;
1085 			}
1086 			(void) ddi_dma_unbind_handle(pRing->dma_hdl[idx]);
1087 		}
1088 		kmem_free(pRing->dma_cookie,
1089 		    sizeof (ddi_dma_cookie_t) * pRing->trunk_num);
1090 	}
1091 
1092 	if (pRing->acc_hdl != NULL) {
1093 		for (idx = 0; idx < pRing->trunk_num; idx ++) {
1094 			if (pRing->acc_hdl[idx] == NULL)
1095 				break;
1096 			ddi_dma_mem_free(&pRing->acc_hdl[idx]);
1097 		}
1098 		kmem_free(pRing->acc_hdl,
1099 		    sizeof (ddi_acc_handle_t) * pRing->trunk_num);
1100 	}
1101 
1102 	if (pRing->dma_hdl != NULL) {
1103 		for (idx = 0; idx < pRing->trunk_num; idx ++) {
1104 			if (pRing->dma_hdl[idx] == 0) {
1105 				break;
1106 			}
1107 			ddi_dma_free_handle(&pRing->dma_hdl[idx]);
1108 		}
1109 		kmem_free(pRing->dma_hdl,
1110 		    sizeof (ddi_dma_handle_t) * pRing->trunk_num);
1111 	}
1112 
1113 	if (pRing->msg_buf != NULL) {
1114 		kmem_free(pRing->msg_buf,
1115 		    sizeof (struct amd8111s_msgbuf) * pRing->ring_size);
1116 	}
1117 
1118 	if (pRing->trunk_addr != NULL) {
1119 		kmem_free(pRing->trunk_addr,
1120 		    sizeof (caddr_t) * pRing->trunk_num);
1121 	}
1122 
1123 	bzero(pRing, sizeof (*pRing));
1124 }
1125 
1126 
1127 /*
1128  * Allocate all Tx buffer.
1129  * Allocate a Rx buffer for each Rx descriptor. Then
1130  * call mil routine to fill physical address of Rx
1131  * buffer into Rx descriptors
1132  */
1133 static boolean_t
1134 amd8111s_allocate_buffers(struct LayerPointers *pLayerPointers)
1135 {
1136 	struct odl *pOdl = pLayerPointers->pOdl;
1137 
1138 	/*
1139 	 * Allocate rx Buffers
1140 	 */
1141 	if (amd8111s_alloc_dma_ringbuf(pLayerPointers, &pOdl->rx_buf,
1142 	    RX_RING_SIZE, RX_BUF_SIZE) == B_FALSE) {
1143 		amd8111s_log(pLayerPointers, CE_WARN,
1144 		    "amd8111s_alloc_dma_ringbuf for tx failed");
1145 		goto allocate_buf_fail;
1146 	}
1147 
1148 	/*
1149 	 * Allocate Tx buffers
1150 	 */
1151 	if (amd8111s_alloc_dma_ringbuf(pLayerPointers, &pOdl->tx_buf,
1152 	    TX_COALESC_SIZE, TX_BUF_SIZE) == B_FALSE) {
1153 		amd8111s_log(pLayerPointers, CE_WARN,
1154 		    "amd8111s_alloc_dma_ringbuf for tx failed");
1155 		goto allocate_buf_fail;
1156 	}
1157 
1158 	/*
1159 	 * Initilize the mil Queues
1160 	 */
1161 	milInitGlbds(pLayerPointers);
1162 
1163 	milInitRxQ(pLayerPointers);
1164 
1165 	return (B_TRUE);
1166 
1167 allocate_buf_fail:
1168 
1169 	amd8111s_log(pLayerPointers, CE_WARN,
1170 	    "amd8111s_allocate_buffers failed");
1171 	return (B_FALSE);
1172 }
1173 
1174 /*
1175  * Free all Rx/Tx buffer
1176  */
1177 
1178 static void
1179 amd8111s_free_buffers(struct LayerPointers *pLayerPointers)
1180 {
1181 	/* Free Tx buffers */
1182 	amd8111s_free_dma_ringbuf(&pLayerPointers->pOdl->tx_buf);
1183 
1184 	/* Free Rx Buffers */
1185 	amd8111s_free_dma_ringbuf(&pLayerPointers->pOdl->rx_buf);
1186 }
1187 
1188 /*
1189  * Try to recycle all the descriptors and Tx buffers
1190  * which are already freed by hardware.
1191  */
1192 static int
1193 amd8111s_recycle_tx(struct LayerPointers *pLayerPointers)
1194 {
1195 	struct nonphysical *pNonphysical;
1196 	uint32_t count = 0;
1197 
1198 	pNonphysical = pLayerPointers->pMil->pNonphysical;
1199 	while (pNonphysical->TxDescQRead->Tx_OWN == 0 &&
1200 	    pNonphysical->TxDescQRead != pNonphysical->TxDescQWrite) {
1201 		pLayerPointers->pOdl->tx_buf.free =
1202 		    NEXT(pLayerPointers->pOdl->tx_buf, free);
1203 		pNonphysical->TxDescQRead++;
1204 		if (pNonphysical->TxDescQRead > pNonphysical->TxDescQEnd) {
1205 			pNonphysical->TxDescQRead = pNonphysical->TxDescQStart;
1206 		}
1207 		count ++;
1208 	}
1209 
1210 	if (pLayerPointers->pMil->tx_reschedule)
1211 		ddi_trigger_softintr(pLayerPointers->pOdl->drain_id);
1212 
1213 	return (count);
1214 }
1215 
1216 /*
1217  * Get packets in the Tx buffer, then copy them to the send buffer.
1218  * Trigger hardware to send out packets.
1219  */
1220 static void
1221 amd8111s_send_serial(struct LayerPointers *pLayerPointers)
1222 {
1223 	struct nonphysical *pNonphysical;
1224 	uint32_t count;
1225 
1226 	pNonphysical = pLayerPointers->pMil->pNonphysical;
1227 
1228 	mutex_enter(&pLayerPointers->pOdl->mdlSendLock);
1229 
1230 	for (count = 0; count < AMD8111S_SEND_MAX; count ++) {
1231 		if (pLayerPointers->pOdl->tx_buf.curr ==
1232 		    pLayerPointers->pOdl->tx_buf.next) {
1233 			break;
1234 		}
1235 		/* to verify if it needs to recycle the tx Buf */
1236 		if (((pNonphysical->TxDescQWrite + 1 >
1237 		    pNonphysical->TxDescQEnd) ? pNonphysical->TxDescQStart :
1238 		    (pNonphysical->TxDescQWrite + 1)) ==
1239 		    pNonphysical->TxDescQRead)
1240 			if (amd8111s_recycle_tx(pLayerPointers) == 0) {
1241 				pLayerPointers->pOdl
1242 				    ->statistics.tx_no_descriptor ++;
1243 				break;
1244 			}
1245 
1246 		/* Fill packet length */
1247 		pNonphysical->TxDescQWrite->Tx_BCNT = (uint16_t)pLayerPointers
1248 		    ->pOdl->tx_buf.curr->msg_size;
1249 
1250 		/* Fill physical buffer address */
1251 		pNonphysical->TxDescQWrite->Tx_Base_Addr = (unsigned int)
1252 		    pLayerPointers->pOdl->tx_buf.curr->phy_addr;
1253 
1254 		pNonphysical->TxDescQWrite->Tx_SOP = 1;
1255 		pNonphysical->TxDescQWrite->Tx_EOP = 1;
1256 		pNonphysical->TxDescQWrite->Tx_ADD_FCS = 1;
1257 		pNonphysical->TxDescQWrite->Tx_LTINT = 1;
1258 		pNonphysical->TxDescQWrite->Tx_USPACE = 0;
1259 		pNonphysical->TxDescQWrite->Tx_OWN = 1;
1260 
1261 		pNonphysical->TxDescQWrite++;
1262 		if (pNonphysical->TxDescQWrite > pNonphysical->TxDescQEnd) {
1263 			pNonphysical->TxDescQWrite = pNonphysical->TxDescQStart;
1264 		}
1265 
1266 		pLayerPointers->pOdl->tx_buf.curr =
1267 		    NEXT(pLayerPointers->pOdl->tx_buf, curr);
1268 
1269 	}
1270 
1271 	pLayerPointers->pOdl->statistics.tx_ok_packets += count;
1272 
1273 	mutex_exit(&pLayerPointers->pOdl->mdlSendLock);
1274 
1275 	/* Call mdlTransmit to send the pkt out on the network */
1276 	mdlTransmit(pLayerPointers);
1277 
1278 }
1279 
1280 /*
1281  * Softintr entrance. try to send out packets in the Tx buffer.
1282  * If reschedule is True, call mac_tx_update to re-enable the
1283  * transmit
1284  */
1285 static uint_t
1286 amd8111s_send_drain(caddr_t arg)
1287 {
1288 	struct LayerPointers *pLayerPointers = (struct LayerPointers *)arg;
1289 
1290 	amd8111s_send_serial(pLayerPointers);
1291 
1292 	if (pLayerPointers->pMil->tx_reschedule &&
1293 	    NEXT(pLayerPointers->pOdl->tx_buf, next) !=
1294 	    pLayerPointers->pOdl->tx_buf.free) {
1295 		mac_tx_update(pLayerPointers->pOdl->mh);
1296 		pLayerPointers->pMil->tx_reschedule = B_FALSE;
1297 	}
1298 
1299 	return (DDI_INTR_CLAIMED);
1300 }
1301 
1302 /*
1303  * Get a Tx buffer
1304  */
1305 static struct amd8111s_msgbuf *
1306 amd8111s_getTxbuf(struct LayerPointers *pLayerPointers)
1307 {
1308 	struct amd8111s_msgbuf *tmp, *next;
1309 
1310 	mutex_enter(&pLayerPointers->pOdl->mdlSendLock);
1311 	next = NEXT(pLayerPointers->pOdl->tx_buf, next);
1312 	if (next == pLayerPointers->pOdl->tx_buf.free) {
1313 		tmp = NULL;
1314 	} else {
1315 		tmp = pLayerPointers->pOdl->tx_buf.next;
1316 		pLayerPointers->pOdl->tx_buf.next = next;
1317 	}
1318 	mutex_exit(&pLayerPointers->pOdl->mdlSendLock);
1319 
1320 	return (tmp);
1321 }
1322 
1323 static boolean_t
1324 amd8111s_send(struct LayerPointers *pLayerPointers, mblk_t *mp)
1325 {
1326 	struct odl *pOdl;
1327 	size_t frag_len;
1328 	mblk_t *tmp;
1329 	struct amd8111s_msgbuf *txBuf;
1330 	uint8_t *pMsg;
1331 
1332 	pOdl = pLayerPointers->pOdl;
1333 
1334 	/* alloc send buffer */
1335 	txBuf = amd8111s_getTxbuf(pLayerPointers);
1336 	if (txBuf == NULL) {
1337 		pOdl->statistics.tx_no_buffer ++;
1338 		pLayerPointers->pMil->tx_reschedule = B_TRUE;
1339 		amd8111s_send_serial(pLayerPointers);
1340 		return (B_FALSE);
1341 	}
1342 
1343 	/* copy packet to send buffer */
1344 	txBuf->msg_size = 0;
1345 	pMsg = (uint8_t *)txBuf->vir_addr;
1346 	for (tmp = mp; tmp; tmp = tmp->b_cont) {
1347 		frag_len = MBLKL(tmp);
1348 		bcopy(tmp->b_rptr, pMsg, frag_len);
1349 		txBuf->msg_size += frag_len;
1350 		pMsg += frag_len;
1351 	}
1352 	freemsg(mp);
1353 
1354 	amd8111s_send_serial(pLayerPointers);
1355 
1356 	return (B_TRUE);
1357 }
1358 
1359 /*
1360  * (GLD Entry Point) Send the message block to lower layer
1361  */
1362 static mblk_t *
1363 amd8111s_m_tx(void *arg, mblk_t *mp)
1364 {
1365 	struct LayerPointers *pLayerPointers = arg;
1366 	mblk_t *next;
1367 
1368 	rw_enter(&pLayerPointers->pOdl->chip_lock, RW_READER);
1369 	if (!pLayerPointers->run) {
1370 		pLayerPointers->pOdl->statistics.tx_afterunplumb ++;
1371 		freemsgchain(mp);
1372 		mp = NULL;
1373 	}
1374 
1375 	while (mp != NULL) {
1376 		next = mp->b_next;
1377 		mp->b_next = NULL;
1378 		if (!amd8111s_send(pLayerPointers, mp)) {
1379 			/* Send fail */
1380 			mp->b_next = next;
1381 			break;
1382 		}
1383 		mp = next;
1384 	}
1385 
1386 	rw_exit(&pLayerPointers->pOdl->chip_lock);
1387 	return (mp);
1388 }
1389 
1390 /*
1391  * (GLD Entry Point) Interrupt Service Routine
1392  */
1393 static uint_t
1394 amd8111s_intr(caddr_t arg)
1395 {
1396 	unsigned int intrCauses;
1397 	struct LayerPointers *pLayerPointers = (struct LayerPointers *)arg;
1398 
1399 	/* Read the interrupt status from mdl */
1400 	intrCauses = mdlReadInterrupt(pLayerPointers);
1401 
1402 	if (intrCauses == 0) {
1403 		pLayerPointers->pOdl->statistics.intr_OTHER ++;
1404 		return (DDI_INTR_UNCLAIMED);
1405 	}
1406 
1407 	if (intrCauses & LCINT) {
1408 		if (mdlReadLink(pLayerPointers) == LINK_UP) {
1409 			mdlGetActiveMediaInfo(pLayerPointers);
1410 			/* Link status changed */
1411 			if (pLayerPointers->pOdl->LinkStatus !=
1412 			    LINK_STATE_UP) {
1413 				pLayerPointers->pOdl->LinkStatus =
1414 				    LINK_STATE_UP;
1415 				mac_link_update(pLayerPointers->pOdl->mh,
1416 				    LINK_STATE_UP);
1417 			}
1418 		} else {
1419 			if (pLayerPointers->pOdl->LinkStatus !=
1420 			    LINK_STATE_DOWN) {
1421 				pLayerPointers->pOdl->LinkStatus =
1422 				    LINK_STATE_DOWN;
1423 				mac_link_update(pLayerPointers->pOdl->mh,
1424 				    LINK_STATE_DOWN);
1425 			}
1426 		}
1427 	}
1428 	/*
1429 	 * RINT0: Receive Interrupt is set by the controller after the last
1430 	 * descriptor of a receive frame for this ring has been updated by
1431 	 * writing a 0 to the OWNership bit.
1432 	 */
1433 	if (intrCauses & RINT0) {
1434 		pLayerPointers->pOdl->statistics.intr_RINT0 ++;
1435 		amd8111s_receive(pLayerPointers);
1436 	}
1437 
1438 	/*
1439 	 * TINT0: Transmit Interrupt is set by the controller after the OWN bit
1440 	 * in the last descriptor of a transmit frame in this particular ring
1441 	 * has been cleared to indicate the frame has been copied to the
1442 	 * transmit FIFO.
1443 	 */
1444 	if (intrCauses & TINT0) {
1445 		pLayerPointers->pOdl->statistics.intr_TINT0 ++;
1446 		/*
1447 		 * if desc ring is NULL and tx buf is not NULL, it should
1448 		 * drain tx buffer
1449 		 */
1450 		amd8111s_send_serial(pLayerPointers);
1451 	}
1452 
1453 	if (intrCauses & STINT) {
1454 		pLayerPointers->pOdl->statistics.intr_STINT ++;
1455 	}
1456 
1457 
1458 	return (DDI_INTR_CLAIMED);
1459 }
1460 
1461 /*
1462  * To re-initilize data structures.
1463  */
1464 static void
1465 amd8111s_sw_reset(struct LayerPointers *pLayerPointers)
1466 {
1467 	/* Reset all Tx/Rx queues and descriptors */
1468 	milResetTxQ(pLayerPointers);
1469 	milInitRxQ(pLayerPointers);
1470 }
1471 
1472 /*
1473  * Send all pending tx packets
1474  */
1475 static void
1476 amd8111s_tx_drain(struct LayerPointers *adapter)
1477 {
1478 	struct tx_desc *pTx_desc = adapter->pMil->pNonphysical->TxDescQStart;
1479 	int i, desc_count = 0;
1480 	for (i = 0; i < 30; i++) {
1481 		while ((pTx_desc->Tx_OWN == 0) && (desc_count < TX_RING_SIZE)) {
1482 			/* This packet has been transmitted */
1483 			pTx_desc ++;
1484 			desc_count ++;
1485 		}
1486 		if (desc_count == TX_RING_SIZE) {
1487 			break;
1488 		}
1489 		/* Wait 1 ms */
1490 		drv_usecwait(1000);
1491 	}
1492 	adapter->pOdl->statistics.tx_draintime = i;
1493 }
1494 
1495 /*
1496  * (GLD Entry Point) To start card will be called at
1497  * ifconfig plumb
1498  */
1499 static int
1500 amd8111s_m_start(void *arg)
1501 {
1502 	struct LayerPointers *pLayerPointers = arg;
1503 	struct odl *pOdl = pLayerPointers->pOdl;
1504 
1505 	amd8111s_sw_reset(pLayerPointers);
1506 	mdlHWReset(pLayerPointers);
1507 	rw_enter(&pOdl->chip_lock, RW_WRITER);
1508 	pLayerPointers->run = B_TRUE;
1509 	rw_exit(&pOdl->chip_lock);
1510 	return (0);
1511 }
1512 
1513 /*
1514  * (GLD Entry Point) To stop card will be called at
1515  * ifconfig unplumb
1516  */
1517 static void
1518 amd8111s_m_stop(void *arg)
1519 {
1520 	struct LayerPointers *pLayerPointers = (struct LayerPointers *)arg;
1521 	struct odl *pOdl = pLayerPointers->pOdl;
1522 
1523 	/* Ensure send all pending tx packets */
1524 	amd8111s_tx_drain(pLayerPointers);
1525 	/*
1526 	 * Stop the controller and disable the controller interrupt
1527 	 */
1528 	rw_enter(&pOdl->chip_lock, RW_WRITER);
1529 	mdlStopChip(pLayerPointers);
1530 	pLayerPointers->run = B_FALSE;
1531 	rw_exit(&pOdl->chip_lock);
1532 }
1533 
1534 /*
1535  *	To clean up all
1536  */
1537 static void
1538 amd8111s_free_resource(struct LayerPointers *pLayerPointers)
1539 {
1540 	unsigned long mem_free_array[100];
1541 	unsigned long *pmem_free_array, size;
1542 
1543 	/* Free Rx/Tx descriptors */
1544 	amd8111s_free_descriptors(pLayerPointers);
1545 
1546 	/* Free memory on lower layers */
1547 	milFreeResources(pLayerPointers, mem_free_array);
1548 	pmem_free_array = mem_free_array;
1549 	while (*pmem_free_array) {
1550 		switch (*pmem_free_array) {
1551 		case VIRTUAL:
1552 			size = *(++pmem_free_array);
1553 			pmem_free_array++;
1554 			kmem_free((void *)*(pmem_free_array), size);
1555 			break;
1556 		}
1557 		pmem_free_array++;
1558 	}
1559 
1560 	amd8111s_free_buffers(pLayerPointers);
1561 }
1562 
1563 /*
1564  * (GLD Enty pointer) To add/delete multi cast addresses
1565  *
1566  */
1567 static int
1568 amd8111s_m_multicst(void *arg, boolean_t add, const uint8_t *addr)
1569 {
1570 	struct LayerPointers *pLayerPointers = arg;
1571 
1572 	if (add) {
1573 		/* Add a multicast entry */
1574 		mdlAddMulticastAddress(pLayerPointers, (UCHAR *)addr);
1575 	} else {
1576 		/* Delete a multicast entry */
1577 		mdlDeleteMulticastAddress(pLayerPointers, (UCHAR *)addr);
1578 	}
1579 
1580 	return (0);
1581 }
1582 
1583 #ifdef AMD8111S_DEBUG
1584 /*
1585  * The size of MIB registers is only 32 bits. Dump them before one
1586  * of them overflows.
1587  */
1588 static void
1589 amd8111s_dump_mib(struct LayerPointers *pLayerPointers)
1590 {
1591 	struct amd8111s_statistics *adapterStat;
1592 
1593 	adapterStat = &pLayerPointers->pOdl->statistics;
1594 
1595 	adapterStat->mib_dump_counter ++;
1596 
1597 	/*
1598 	 * Rx Counters
1599 	 */
1600 	adapterStat->rx_mib_unicst_packets +=
1601 	    mdlReadMib(pLayerPointers, RcvUniCastPkts);
1602 	adapterStat->rx_mib_multicst_packets +=
1603 	    mdlReadMib(pLayerPointers, RcvMultiCastPkts);
1604 	adapterStat->rx_mib_broadcst_packets +=
1605 	    mdlReadMib(pLayerPointers, RcvBroadCastPkts);
1606 	adapterStat->rx_mib_macctrl_packets +=
1607 	    mdlReadMib(pLayerPointers, RcvMACCtrl);
1608 	adapterStat->rx_mib_flowctrl_packets +=
1609 	    mdlReadMib(pLayerPointers, RcvFlowCtrl);
1610 
1611 	adapterStat->rx_mib_bytes +=
1612 	    mdlReadMib(pLayerPointers, RcvOctets);
1613 	adapterStat->rx_mib_good_bytes +=
1614 	    mdlReadMib(pLayerPointers, RcvGoodOctets);
1615 
1616 	adapterStat->rx_mib_undersize_packets +=
1617 	    mdlReadMib(pLayerPointers, RcvUndersizePkts);
1618 	adapterStat->rx_mib_oversize_packets +=
1619 	    mdlReadMib(pLayerPointers, RcvOversizePkts);
1620 
1621 	adapterStat->rx_mib_drop_packets +=
1622 	    mdlReadMib(pLayerPointers, RcvDropPktsRing0);
1623 	adapterStat->rx_mib_align_err_packets +=
1624 	    mdlReadMib(pLayerPointers, RcvAlignmentErrors);
1625 	adapterStat->rx_mib_fcs_err_packets +=
1626 	    mdlReadMib(pLayerPointers, RcvFCSErrors);
1627 	adapterStat->rx_mib_symbol_err_packets +=
1628 	    mdlReadMib(pLayerPointers, RcvSymbolErrors);
1629 	adapterStat->rx_mib_miss_packets +=
1630 	    mdlReadMib(pLayerPointers, RcvMissPkts);
1631 
1632 	/*
1633 	 * Tx Counters
1634 	 */
1635 	adapterStat->tx_mib_packets +=
1636 	    mdlReadMib(pLayerPointers, XmtPackets);
1637 	adapterStat->tx_mib_multicst_packets +=
1638 	    mdlReadMib(pLayerPointers, XmtMultiCastPkts);
1639 	adapterStat->tx_mib_broadcst_packets +=
1640 	    mdlReadMib(pLayerPointers, XmtBroadCastPkts);
1641 	adapterStat->tx_mib_flowctrl_packets +=
1642 	    mdlReadMib(pLayerPointers, XmtFlowCtrl);
1643 
1644 	adapterStat->tx_mib_bytes +=
1645 	    mdlReadMib(pLayerPointers, XmtOctets);
1646 
1647 	adapterStat->tx_mib_defer_trans_packets +=
1648 	    mdlReadMib(pLayerPointers, XmtDeferredTransmit);
1649 	adapterStat->tx_mib_collision_packets +=
1650 	    mdlReadMib(pLayerPointers, XmtCollisions);
1651 	adapterStat->tx_mib_one_coll_packets +=
1652 	    mdlReadMib(pLayerPointers, XmtOneCollision);
1653 	adapterStat->tx_mib_multi_coll_packets +=
1654 	    mdlReadMib(pLayerPointers, XmtMultipleCollision);
1655 	adapterStat->tx_mib_late_coll_packets +=
1656 	    mdlReadMib(pLayerPointers, XmtLateCollision);
1657 	adapterStat->tx_mib_ex_coll_packets +=
1658 	    mdlReadMib(pLayerPointers, XmtExcessiveCollision);
1659 
1660 
1661 	/* Clear all MIB registers */
1662 	WRITE_REG16(pLayerPointers, pLayerPointers->pMdl->Mem_Address
1663 	    + MIB_ADDR, MIB_CLEAR);
1664 }
1665 #endif
1666 
1667 /*
1668  * (GLD Entry Point) set/unset promiscus mode
1669  */
1670 static int
1671 amd8111s_m_promisc(void *arg, boolean_t on)
1672 {
1673 	struct LayerPointers *pLayerPointers = arg;
1674 
1675 	if (on) {
1676 		mdlSetPromiscuous(pLayerPointers);
1677 	} else {
1678 		mdlDisablePromiscuous(pLayerPointers);
1679 	}
1680 
1681 	return (0);
1682 }
1683 
1684 /*
1685  * (Gld Entry point) Changes the Mac address of card
1686  */
1687 static int
1688 amd8111s_m_unicst(void *arg, const uint8_t *macaddr)
1689 {
1690 	struct LayerPointers *pLayerPointers = arg;
1691 
1692 	mdlDisableInterrupt(pLayerPointers);
1693 	mdlSetMacAddress(pLayerPointers, (unsigned char *)macaddr);
1694 	mdlEnableInterrupt(pLayerPointers);
1695 
1696 	return (0);
1697 }
1698 
1699 /*
1700  * Reset the card
1701  */
1702 void
1703 amd8111s_reset(struct LayerPointers *pLayerPointers)
1704 {
1705 	amd8111s_sw_reset(pLayerPointers);
1706 	mdlHWReset(pLayerPointers);
1707 }
1708 
1709 /*
1710  * attach(9E) -- Attach a device to the system
1711  *
1712  * Called once for each board after successfully probed.
1713  * will do
1714  * 	a. creating minor device node for the instance.
1715  *	b. allocate & Initilize four layers (call odlInit)
1716  *	c. get MAC address
1717  *	d. initilize pLayerPointers to gld private pointer
1718  *	e. register with GLD
1719  * if any action fails does clean up & returns DDI_FAILURE
1720  * else retursn DDI_SUCCESS
1721  */
1722 static int
1723 amd8111s_attach(dev_info_t *devinfo, ddi_attach_cmd_t cmd)
1724 {
1725 	mac_register_t *macp;
1726 	struct LayerPointers *pLayerPointers;
1727 	struct odl *pOdl;
1728 	ddi_acc_handle_t *pci_handle;
1729 	ddi_device_acc_attr_t dev_attr;
1730 	caddr_t addrp = NULL;
1731 
1732 	switch (cmd) {
1733 	case DDI_ATTACH:
1734 		break;
1735 	default:
1736 		return (DDI_FAILURE);
1737 	}
1738 
1739 	pLayerPointers = (struct LayerPointers *)
1740 	    kmem_zalloc(sizeof (struct LayerPointers), KM_SLEEP);
1741 	amd8111sadapter = pLayerPointers;
1742 
1743 	/* Get device instance number */
1744 	pLayerPointers->instance = ddi_get_instance(devinfo);
1745 	ddi_set_driver_private(devinfo, (caddr_t)pLayerPointers);
1746 
1747 	pOdl = (struct odl *)kmem_zalloc(sizeof (struct odl), KM_SLEEP);
1748 	pLayerPointers->pOdl = pOdl;
1749 
1750 	pOdl->devinfo = devinfo;
1751 
1752 	/*
1753 	 * Here, we only allocate memory for struct odl and initilize it.
1754 	 * All other memory allocation & initilization will be done in odlInit
1755 	 * later on this routine.
1756 	 */
1757 	if (ddi_get_iblock_cookie(devinfo, 0, &pLayerPointers->pOdl->iblock)
1758 	    != DDI_SUCCESS) {
1759 		amd8111s_log(pLayerPointers, CE_NOTE,
1760 		    "attach: get iblock cookies failed");
1761 		goto attach_failure;
1762 	}
1763 
1764 	rw_init(&pOdl->chip_lock, NULL, RW_DRIVER, (void *)pOdl->iblock);
1765 	mutex_init(&pOdl->mdlSendLock, "amd8111s Send Protection Lock",
1766 	    MUTEX_DRIVER, (void *)pOdl->iblock);
1767 	mutex_init(&pOdl->mdlRcvLock, "amd8111s Rcv Protection Lock",
1768 	    MUTEX_DRIVER, (void *)pOdl->iblock);
1769 
1770 	/* Setup PCI space */
1771 	if (pci_config_setup(devinfo, &pOdl->pci_handle) != DDI_SUCCESS) {
1772 		return (DDI_FAILURE);
1773 	}
1774 	pLayerPointers->attach_progress = AMD8111S_ATTACH_PCI;
1775 	pci_handle = &pOdl->pci_handle;
1776 
1777 	pOdl->vendor_id = pci_config_get16(*pci_handle, PCI_CONF_VENID);
1778 	pOdl->device_id = pci_config_get16(*pci_handle, PCI_CONF_DEVID);
1779 
1780 	/*
1781 	 * Allocate and initialize all resource and map device registers.
1782 	 * If failed, it returns a non-zero value.
1783 	 */
1784 	if (amd8111s_odlInit(pLayerPointers) != 0) {
1785 		goto attach_failure;
1786 	}
1787 	pLayerPointers->attach_progress |= AMD8111S_ATTACH_RESOURCE;
1788 
1789 	dev_attr.devacc_attr_version = DDI_DEVICE_ATTR_V0;
1790 	dev_attr.devacc_attr_endian_flags = DDI_STRUCTURE_LE_ACC;
1791 	dev_attr.devacc_attr_dataorder = DDI_STRICTORDER_ACC;
1792 
1793 	if (ddi_regs_map_setup(devinfo, 1, &addrp, 0,  4096, &dev_attr,
1794 	    &(pLayerPointers->pOdl->MemBasehandle)) != 0) {
1795 		amd8111s_log(pLayerPointers, CE_NOTE,
1796 		    "attach: ddi_regs_map_setup failed");
1797 		goto attach_failure;
1798 	}
1799 	pLayerPointers->pMdl->Mem_Address = (unsigned long)addrp;
1800 
1801 	/* Initialize HW */
1802 	mdlOpen(pLayerPointers);
1803 	mdlGetActiveMediaInfo(pLayerPointers);
1804 	pLayerPointers->attach_progress |= AMD8111S_ATTACH_REGS;
1805 
1806 	/*
1807 	 * Setup the interrupt
1808 	 */
1809 	if (ddi_add_intr(devinfo, 0, &pOdl->iblock, 0, amd8111s_intr,
1810 	    (caddr_t)pLayerPointers) != DDI_SUCCESS) {
1811 		goto attach_failure;
1812 	}
1813 	pLayerPointers->attach_progress |= AMD8111S_ATTACH_INTRADDED;
1814 
1815 	/*
1816 	 * Setup soft intr
1817 	 */
1818 	if (ddi_add_softintr(devinfo, DDI_SOFTINT_LOW, &pOdl->drain_id,
1819 	    NULL, NULL, amd8111s_send_drain,
1820 	    (caddr_t)pLayerPointers) != DDI_SUCCESS) {
1821 		goto attach_failure;
1822 	}
1823 	pLayerPointers->attach_progress |= AMD8111S_ATTACH_RESCHED;
1824 
1825 	/*
1826 	 * Initilize the mac structure
1827 	 */
1828 	if ((macp = mac_alloc(MAC_VERSION)) == NULL)
1829 		goto attach_failure;
1830 
1831 	macp->m_type_ident = MAC_PLUGIN_IDENT_ETHER;
1832 	macp->m_driver = pLayerPointers;
1833 	macp->m_dip = devinfo;
1834 	/* Get MAC address */
1835 	mdlGetMacAddress(pLayerPointers, (unsigned char *)pOdl->MacAddress);
1836 	macp->m_src_addr = pOdl->MacAddress;
1837 	macp->m_callbacks = &amd8111s_m_callbacks;
1838 	macp->m_min_sdu = 0;
1839 	/* 1518 - 14 (ether header) - 4 (CRC) */
1840 	macp->m_max_sdu = ETHERMTU;
1841 	macp->m_margin = VLAN_TAGSZ;
1842 
1843 	/*
1844 	 * Finally, we're ready to register ourselves with the MAC layer
1845 	 * interface; if this succeeds, we're ready to start.
1846 	 */
1847 	if (mac_register(macp, &pOdl->mh) != DDI_SUCCESS) {
1848 		mac_free(macp);
1849 		goto attach_failure;
1850 	}
1851 	mac_free(macp);
1852 
1853 	pLayerPointers->attach_progress |= AMD8111S_ATTACH_MACREGED;
1854 
1855 	return (DDI_SUCCESS);
1856 
1857 attach_failure:
1858 	(void) amd8111s_unattach(devinfo, pLayerPointers);
1859 	return (DDI_FAILURE);
1860 
1861 }
1862 
1863 /*
1864  * detach(9E) -- Detach a device from the system
1865  *
1866  * It is called for each device instance when the system is preparing to
1867  * unload a dynamically unloadable driver.
1868  * will Do
1869  * 	a. check if any driver buffers are held by OS.
1870  *	b. do clean up of all allocated memory if it is not in use by OS.
1871  *	c. un register with GLD
1872  *	d. return DDI_SUCCESS on succes full free & unregister
1873  *	else GLD_FAILURE
1874  */
1875 static int
1876 amd8111s_detach(dev_info_t *devinfo, ddi_detach_cmd_t cmd)
1877 {
1878 	struct LayerPointers *pLayerPointers;
1879 
1880 	switch (cmd) {
1881 	case DDI_DETACH:
1882 		break;
1883 	default:
1884 		return (DDI_FAILURE);
1885 	}
1886 
1887 	/*
1888 	 * Get the driver private (struct LayerPointers *) structure
1889 	 */
1890 	if ((pLayerPointers = (struct LayerPointers *)ddi_get_driver_private
1891 	    (devinfo)) == NULL) {
1892 		return (DDI_FAILURE);
1893 	}
1894 
1895 	return (amd8111s_unattach(devinfo, pLayerPointers));
1896 }
1897 
1898 static int
1899 amd8111s_unattach(dev_info_t *devinfo, struct LayerPointers *pLayerPointers)
1900 {
1901 	struct odl *pOdl = pLayerPointers->pOdl;
1902 
1903 	if (pLayerPointers->attach_progress & AMD8111S_ATTACH_MACREGED) {
1904 		/* Unregister driver from the GLD interface */
1905 		if (mac_unregister(pOdl->mh) != DDI_SUCCESS) {
1906 			return (DDI_FAILURE);
1907 		}
1908 	}
1909 
1910 	if (pLayerPointers->attach_progress & AMD8111S_ATTACH_INTRADDED) {
1911 		ddi_remove_intr(devinfo, 0, pOdl->iblock);
1912 	}
1913 
1914 	if (pLayerPointers->attach_progress & AMD8111S_ATTACH_RESCHED) {
1915 		ddi_remove_softintr(pOdl->drain_id);
1916 	}
1917 
1918 	if (pLayerPointers->attach_progress & AMD8111S_ATTACH_REGS) {
1919 		/* Stop HW */
1920 		mdlStopChip(pLayerPointers);
1921 		ddi_regs_map_free(&(pOdl->MemBasehandle));
1922 	}
1923 
1924 	if (pLayerPointers->attach_progress & AMD8111S_ATTACH_RESOURCE) {
1925 		/* Free All memory allocated */
1926 		amd8111s_free_resource(pLayerPointers);
1927 	}
1928 
1929 	if (pLayerPointers->attach_progress & AMD8111S_ATTACH_PCI) {
1930 		pci_config_teardown(&pOdl->pci_handle);
1931 		mutex_destroy(&pOdl->mdlSendLock);
1932 		mutex_destroy(&pOdl->mdlRcvLock);
1933 		rw_destroy(&pOdl->chip_lock);
1934 	}
1935 
1936 	kmem_free(pOdl, sizeof (struct odl));
1937 	kmem_free(pLayerPointers, sizeof (struct LayerPointers));
1938 
1939 	return (DDI_SUCCESS);
1940 }
1941 
1942 /*
1943  * (GLD Entry Point)GLD will call this entry point perodicaly to
1944  * get driver statistices.
1945  */
1946 static int
1947 amd8111s_m_stat(void *arg, uint_t stat, uint64_t *val)
1948 {
1949 	struct LayerPointers *pLayerPointers = arg;
1950 	struct amd8111s_statistics *adapterStat;
1951 
1952 	adapterStat = &pLayerPointers->pOdl->statistics;
1953 
1954 	switch (stat) {
1955 
1956 	/*
1957 	 * Current Status
1958 	 */
1959 	case MAC_STAT_IFSPEED:
1960 		*val = 	pLayerPointers->pMdl->Speed * 1000000;
1961 		break;
1962 
1963 	case ETHER_STAT_LINK_DUPLEX:
1964 		if (pLayerPointers->pMdl->FullDuplex) {
1965 			*val = LINK_DUPLEX_FULL;
1966 		} else {
1967 			*val = LINK_DUPLEX_HALF;
1968 		}
1969 		break;
1970 
1971 	/*
1972 	 * Capabilities
1973 	 */
1974 	case ETHER_STAT_CAP_1000FDX:
1975 		*val = 0;
1976 		break;
1977 
1978 	case ETHER_STAT_CAP_1000HDX:
1979 		*val = 0;
1980 		break;
1981 
1982 	case ETHER_STAT_CAP_100FDX:
1983 		*val = 1;
1984 		break;
1985 
1986 	case ETHER_STAT_CAP_100HDX:
1987 		*val = 1;
1988 		break;
1989 
1990 	case ETHER_STAT_CAP_10FDX:
1991 		*val = 1;
1992 		break;
1993 
1994 	case ETHER_STAT_CAP_10HDX:
1995 		*val = 1;
1996 		break;
1997 
1998 	case ETHER_STAT_CAP_ASMPAUSE:
1999 		*val = 1;
2000 		break;
2001 
2002 	case ETHER_STAT_CAP_PAUSE:
2003 		*val = 1;
2004 		break;
2005 
2006 	case ETHER_STAT_CAP_AUTONEG:
2007 		*val = 1;
2008 		break;
2009 
2010 	case ETHER_STAT_ADV_CAP_1000FDX:
2011 		*val = 0;
2012 		break;
2013 
2014 	case ETHER_STAT_ADV_CAP_1000HDX:
2015 		*val = 0;
2016 		break;
2017 
2018 	case ETHER_STAT_ADV_CAP_100FDX:
2019 		*val = 1;
2020 		break;
2021 
2022 	case ETHER_STAT_ADV_CAP_100HDX:
2023 		*val = 1;
2024 		break;
2025 
2026 	case ETHER_STAT_ADV_CAP_10FDX:
2027 		*val = 1;
2028 		break;
2029 
2030 	case ETHER_STAT_ADV_CAP_10HDX:
2031 		*val = 1;
2032 		break;
2033 
2034 	case ETHER_STAT_ADV_CAP_ASMPAUSE:
2035 		*val = 1;
2036 		break;
2037 
2038 	case ETHER_STAT_ADV_CAP_PAUSE:
2039 		*val = 1;
2040 		break;
2041 
2042 	case ETHER_STAT_ADV_CAP_AUTONEG:
2043 		*val = 1;
2044 		break;
2045 
2046 	/*
2047 	 * Rx Counters
2048 	 */
2049 	case MAC_STAT_IPACKETS:
2050 		*val = adapterStat->rx_mib_unicst_packets +
2051 		    adapterStat->rx_mib_multicst_packets +
2052 		    adapterStat->rx_mib_broadcst_packets +
2053 		    mdlReadMib(pLayerPointers, RcvUniCastPkts) +
2054 		    mdlReadMib(pLayerPointers, RcvMultiCastPkts) +
2055 		    mdlReadMib(pLayerPointers, RcvBroadCastPkts);
2056 		break;
2057 
2058 	case MAC_STAT_RBYTES:
2059 		*val = adapterStat->rx_mib_bytes +
2060 		    mdlReadMib(pLayerPointers, RcvOctets);
2061 		break;
2062 
2063 	case MAC_STAT_MULTIRCV:
2064 		*val = adapterStat->rx_mib_multicst_packets +
2065 		    mdlReadMib(pLayerPointers, RcvMultiCastPkts);
2066 		break;
2067 
2068 	case MAC_STAT_BRDCSTRCV:
2069 		*val = adapterStat->rx_mib_broadcst_packets +
2070 		    mdlReadMib(pLayerPointers, RcvBroadCastPkts);
2071 		break;
2072 
2073 	case MAC_STAT_NORCVBUF:
2074 		*val = adapterStat->rx_allocfail +
2075 		    adapterStat->rx_mib_drop_packets +
2076 		    mdlReadMib(pLayerPointers, RcvDropPktsRing0);
2077 		break;
2078 
2079 	case MAC_STAT_IERRORS:
2080 		*val = adapterStat->rx_mib_align_err_packets +
2081 		    adapterStat->rx_mib_fcs_err_packets +
2082 		    adapterStat->rx_mib_symbol_err_packets +
2083 		    mdlReadMib(pLayerPointers, RcvAlignmentErrors) +
2084 		    mdlReadMib(pLayerPointers, RcvFCSErrors) +
2085 		    mdlReadMib(pLayerPointers, RcvSymbolErrors);
2086 		break;
2087 
2088 	case ETHER_STAT_ALIGN_ERRORS:
2089 		*val = adapterStat->rx_mib_align_err_packets +
2090 		    mdlReadMib(pLayerPointers, RcvAlignmentErrors);
2091 		break;
2092 
2093 	case ETHER_STAT_FCS_ERRORS:
2094 		*val = adapterStat->rx_mib_fcs_err_packets +
2095 		    mdlReadMib(pLayerPointers, RcvFCSErrors);
2096 		break;
2097 
2098 	/*
2099 	 * Tx Counters
2100 	 */
2101 	case MAC_STAT_OPACKETS:
2102 		*val = adapterStat->tx_mib_packets +
2103 		    mdlReadMib(pLayerPointers, XmtPackets);
2104 		break;
2105 
2106 	case MAC_STAT_OBYTES:
2107 		*val = adapterStat->tx_mib_bytes +
2108 		    mdlReadMib(pLayerPointers, XmtOctets);
2109 		break;
2110 
2111 	case MAC_STAT_MULTIXMT:
2112 		*val = adapterStat->tx_mib_multicst_packets +
2113 		    mdlReadMib(pLayerPointers, XmtMultiCastPkts);
2114 		break;
2115 
2116 	case MAC_STAT_BRDCSTXMT:
2117 		*val = adapterStat->tx_mib_broadcst_packets +
2118 		    mdlReadMib(pLayerPointers, XmtBroadCastPkts);
2119 		break;
2120 
2121 	case MAC_STAT_NOXMTBUF:
2122 		*val = adapterStat->tx_no_descriptor;
2123 		break;
2124 
2125 	case MAC_STAT_OERRORS:
2126 		*val = adapterStat->tx_mib_ex_coll_packets +
2127 		    mdlReadMib(pLayerPointers, XmtExcessiveCollision);
2128 		break;
2129 
2130 	case MAC_STAT_COLLISIONS:
2131 		*val = adapterStat->tx_mib_ex_coll_packets +
2132 		    mdlReadMib(pLayerPointers, XmtCollisions);
2133 		break;
2134 
2135 	case ETHER_STAT_FIRST_COLLISIONS:
2136 		*val = adapterStat->tx_mib_one_coll_packets +
2137 		    mdlReadMib(pLayerPointers, XmtOneCollision);
2138 		break;
2139 
2140 	case ETHER_STAT_MULTI_COLLISIONS:
2141 		*val = adapterStat->tx_mib_multi_coll_packets +
2142 		    mdlReadMib(pLayerPointers, XmtMultipleCollision);
2143 		break;
2144 
2145 	case ETHER_STAT_EX_COLLISIONS:
2146 		*val = adapterStat->tx_mib_ex_coll_packets +
2147 		    mdlReadMib(pLayerPointers, XmtExcessiveCollision);
2148 		break;
2149 
2150 	case ETHER_STAT_TX_LATE_COLLISIONS:
2151 		*val = adapterStat->tx_mib_late_coll_packets +
2152 		    mdlReadMib(pLayerPointers, XmtLateCollision);
2153 		break;
2154 
2155 	case ETHER_STAT_DEFER_XMTS:
2156 		*val = adapterStat->tx_mib_defer_trans_packets +
2157 		    mdlReadMib(pLayerPointers, XmtDeferredTransmit);
2158 		break;
2159 
2160 	default:
2161 		return (ENOTSUP);
2162 	}
2163 	return (0);
2164 }
2165 
2166 /*
2167  *	Memory Read Function Used by MDL to set card registers.
2168  */
2169 unsigned char
2170 READ_REG8(struct LayerPointers *pLayerPointers, long x)
2171 {
2172 	return (ddi_get8(pLayerPointers->pOdl->MemBasehandle, (uint8_t *)x));
2173 }
2174 
2175 int
2176 READ_REG16(struct LayerPointers *pLayerPointers, long x)
2177 {
2178 	return (ddi_get16(pLayerPointers->pOdl->MemBasehandle,
2179 	    (uint16_t *)(x)));
2180 }
2181 
2182 long
2183 READ_REG32(struct LayerPointers *pLayerPointers, long x)
2184 {
2185 	return (ddi_get32(pLayerPointers->pOdl->MemBasehandle,
2186 	    (uint32_t *)(x)));
2187 }
2188 
2189 void
2190 WRITE_REG8(struct LayerPointers *pLayerPointers, long x, int y)
2191 {
2192 	ddi_put8(pLayerPointers->pOdl->MemBasehandle, (uint8_t *)(x), y);
2193 }
2194 
2195 void
2196 WRITE_REG16(struct LayerPointers *pLayerPointers, long x, int y)
2197 {
2198 	ddi_put16(pLayerPointers->pOdl->MemBasehandle, (uint16_t *)(x), y);
2199 }
2200 
2201 void
2202 WRITE_REG32(struct LayerPointers *pLayerPointers, long x, int y)
2203 {
2204 	ddi_put32(pLayerPointers->pOdl->MemBasehandle, (uint32_t *)(x), y);
2205 }
2206 
2207 void
2208 WRITE_REG64(struct LayerPointers *pLayerPointers, long x, char *y)
2209 {
2210 	int i;
2211 	for (i = 0; i < 8; i++) {
2212 		WRITE_REG8(pLayerPointers, (x + i), y[i]);
2213 	}
2214 }
2215