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