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 #include <sys/types.h>
78 #include <sys/cmn_err.h>
79 #include <sys/debug.h>
80 #include <sys/ddi.h>
81 #include <sys/sunddi.h>
82 #include "amd8111s_hw.h"
83 #include "amd8111s_main.h"
84 
85 
86 #pragma inline(mdlTransmit)
87 #pragma inline(mdlReceive)
88 
89 #pragma inline(mdlReadInterrupt)
90 #pragma inline(mdlEnableInterrupt)
91 #pragma inline(mdlDisableInterrupt)
92 
93 
94 static void mdlEnableMagicPacketWakeUp(struct LayerPointers *);
95 
96 /* PMR (Pattern Match RAM) */
97 static void mdlAddWakeUpPattern(struct LayerPointers *, unsigned char *,
98     unsigned char *, unsigned long, unsigned long, int *);
99 static void mdlRemoveWakeUpPattern(struct LayerPointers *, unsigned char *,
100     unsigned long, int *);
101 
102 static int mdlMulticastBitMapping(struct LayerPointers *, unsigned char *, int);
103 
104 static unsigned int mdlCalculateCRC(unsigned int, unsigned char *);
105 
106 static void mdlChangeFilter(struct LayerPointers *, unsigned long *);
107 static void mdlReceiveBroadCast(struct LayerPointers *);
108 static void mdlDisableReceiveBroadCast(struct LayerPointers *);
109 
110 static void mdlRequestResources(ULONG *);
111 static void mdlSetResources(struct LayerPointers *, ULONG *);
112 static void mdlFreeResources(struct LayerPointers *, ULONG *);
113 
114 /*
115  *	Initialises the data used in Mdl.
116  */
117 static void
118 mdlInitGlbds(struct LayerPointers *pLayerPointers)
119 {
120 	struct mdl *pMdl = pLayerPointers->pMdl;
121 
122 	/* Disable Rx and Tx. */
123 	pMdl->init_blk->MODE = 0x0000;
124 
125 	/* Set Interrupt Delay Parameters */
126 	pMdl->IntrCoalescFlag = 1;
127 	pMdl->rx_intrcoalesc_time = 0xC8;	/* 200 */
128 	pMdl->rx_intrcoalesc_events = 5;
129 }
130 
131 void
132 mdlPHYAutoNegotiation(struct LayerPointers *pLayerPointers, unsigned int type)
133 {
134 	int iData = 0;
135 	struct mdl *pMdl = pLayerPointers->pMdl;
136 
137 	/* PHY auto negotiation or force speed/duplex */
138 	switch (type) {
139 	case PHY_AUTO_NEGOTIATION: /* Auto Negotiation */
140 		/* EN_PMGR: Disable the Port Manager */
141 		WRITE_REG32(pLayerPointers, pMdl->Mem_Address + CMD3, EN_PMGR);
142 		drv_usecwait(100000);
143 
144 		/*
145 		 * Enable Autonegotiation the Phy now
146 		 *	XPHYANE(eXternal PHY Auto Negotiation Enable)
147 		 */
148 		WRITE_REG32(pLayerPointers, pMdl->Mem_Address + CTRL2,
149 		    XPHYANE | XPHYRST);
150 
151 		/* EN_PMGR: Enable the Port Manager */
152 		WRITE_REG32(pLayerPointers, pMdl->Mem_Address + CMD3,
153 		    VAL1 | EN_PMGR);
154 
155 		drv_usecwait(500000);
156 
157 		pMdl->Speed = 100;
158 		pMdl->FullDuplex = B_TRUE;
159 
160 		break;
161 
162 	case PHY_FORCE_HD_100:	/* 100Mbps HD */
163 		WRITE_REG32(pLayerPointers, pMdl->Mem_Address + CMD3, EN_PMGR);
164 
165 		/* Force 100 Mbps, half duplex */
166 		iData |= XPHYSP;
167 		WRITE_REG32(pLayerPointers, pMdl->Mem_Address + CTRL2, iData);
168 
169 		WRITE_REG32(pLayerPointers, pMdl->Mem_Address + CMD3,
170 		    VAL1 | EN_PMGR);
171 
172 		drv_usecwait(500000);
173 
174 		pMdl->Speed = 100;
175 		pMdl->FullDuplex = B_FALSE;
176 
177 		break;
178 
179 	case PHY_FORCE_FD_100:	/* 100Mbps FD */
180 		WRITE_REG32(pLayerPointers, pMdl->Mem_Address + CMD3, EN_PMGR);
181 
182 		/* Force 100 Mbps, full duplex */
183 		iData |= (XPHYSP | XPHYFD);
184 		WRITE_REG32(pLayerPointers, pMdl->Mem_Address + CTRL2, iData);
185 
186 		WRITE_REG32(pLayerPointers, pMdl->Mem_Address + CMD3,
187 		    VAL1 | EN_PMGR);
188 
189 		drv_usecwait(500000);
190 
191 		pMdl->Speed = 100;
192 		pMdl->FullDuplex = B_TRUE;
193 
194 		break;
195 
196 	case PHY_FORCE_HD_10: /* 10 Mbps HD  */
197 		/* Disable the Port Manager */
198 		WRITE_REG32(pLayerPointers, pMdl->Mem_Address + CMD3, EN_PMGR);
199 		WRITE_REG32(pLayerPointers, pMdl->Mem_Address + CTRL2, iData);
200 		WRITE_REG32(pLayerPointers, pMdl->Mem_Address + CMD3,
201 		    VAL1 | EN_PMGR);
202 
203 		drv_usecwait(500000);
204 
205 		pMdl->Speed = 10;
206 		pMdl->FullDuplex = B_FALSE;
207 
208 		break;
209 
210 	case PHY_FORCE_FD_10: /* 10Mbps FD  */
211 		WRITE_REG32(pLayerPointers, pMdl->Mem_Address + CMD3, EN_PMGR);
212 
213 		iData |= XPHYFD;
214 		WRITE_REG32(pLayerPointers, pMdl->Mem_Address + CTRL2, iData);
215 
216 		WRITE_REG32(pLayerPointers, pMdl->Mem_Address + CMD3,
217 		    VAL1 | EN_PMGR);
218 
219 		drv_usecwait(500000);
220 
221 		pMdl->Speed = 10;
222 		pMdl->FullDuplex = B_TRUE;
223 
224 		break;
225 	}
226 }
227 
228 /*
229  *	Clear HW configuration.
230  */
231 static void
232 mdlClearHWConfig(struct LayerPointers *pLayerPointers)
233 {
234 	/*
235 	 * Before the network controller is ready for operation,
236 	 * several registers must be initialized.
237 	 */
238 	unsigned int data32;
239 	int JumboFlag = JUMBO_DISABLED;
240 	ULONG MemBaseAddress;
241 
242 	MemBaseAddress = pLayerPointers->pMdl->Mem_Address;
243 
244 	/* AUTOPOLL0 Register */
245 	WRITE_REG16(pLayerPointers, MemBaseAddress + AUTOPOLL0, 0x8101);
246 
247 	/* Clear RCV_RING_BASE_ADDR */
248 	WRITE_REG32(pLayerPointers, MemBaseAddress + RCV_RING_BASE_ADDR0, 0);
249 	WRITE_REG32(pLayerPointers, MemBaseAddress + RCV_RING_BASE_ADDR1, 0);
250 	WRITE_REG32(pLayerPointers, MemBaseAddress + RCV_RING_BASE_ADDR0, 0);
251 	WRITE_REG32(pLayerPointers, MemBaseAddress + RCV_RING_BASE_ADDR2, 0);
252 	WRITE_REG32(pLayerPointers, MemBaseAddress + RCV_RING_BASE_ADDR3, 0);
253 
254 	/* Clear XMT_RING_BASE_ADDR */
255 	WRITE_REG32(pLayerPointers, MemBaseAddress + XMT_RING_BASE_ADDR0, 0);
256 	WRITE_REG32(pLayerPointers, MemBaseAddress + XMT_RING_BASE_ADDR1, 0);
257 	WRITE_REG32(pLayerPointers, MemBaseAddress + XMT_RING_BASE_ADDR2, 0);
258 	WRITE_REG32(pLayerPointers, MemBaseAddress + XMT_RING_BASE_ADDR3, 0);
259 
260 	/* Clear CMD0 / CMD2 */
261 	WRITE_REG32(pLayerPointers, MemBaseAddress + CMD0, 0x000F0F7F);
262 	WRITE_REG32(pLayerPointers, MemBaseAddress + CMD2, 0x3F7F3F7F);
263 
264 	/* Enable Port Management */
265 	WRITE_REG32(pLayerPointers, MemBaseAddress + CMD3, VAL1 | EN_PMGR);
266 
267 	/* Clear CMD7 */
268 	WRITE_REG32(pLayerPointers, MemBaseAddress + CMD7, 0x1B);
269 
270 	/* Clear CTRL0/1 */
271 	WRITE_REG32(pLayerPointers, MemBaseAddress + CTRL1, XMTSP_MASK);
272 
273 	/* Clear DLY_INT_A/B */
274 	WRITE_REG32(pLayerPointers, MemBaseAddress + DLY_INT_A, 0);
275 	WRITE_REG32(pLayerPointers, MemBaseAddress + DLY_INT_B, 0);
276 
277 	/* Clear FLOW_CONTROL */
278 	WRITE_REG32(pLayerPointers, MemBaseAddress + FLOW_CONTROL, 0);
279 
280 	/* Clear INT0 */
281 	data32 = READ_REG32(pLayerPointers, MemBaseAddress + INT0);
282 	WRITE_REG32(pLayerPointers, MemBaseAddress + INT0, data32);
283 
284 	/* Clear STVAL */
285 	WRITE_REG32(pLayerPointers, MemBaseAddress + STVAL, 0);
286 
287 	/* Clear INTEN0 */
288 	WRITE_REG32(pLayerPointers, MemBaseAddress + INTEN0, 0x1F7F7F1F);
289 
290 	/* Clear LADRF */
291 	WRITE_REG32(pLayerPointers, MemBaseAddress + LADRF1, 0);
292 	WRITE_REG32(pLayerPointers, MemBaseAddress + LADRF1 + 4, 0);
293 
294 	/* Clear LED0 */
295 	WRITE_REG32(pLayerPointers, MemBaseAddress + LED0, 0);
296 	WRITE_REG32(pLayerPointers, MemBaseAddress + LED1, 0);
297 	WRITE_REG32(pLayerPointers, MemBaseAddress + LED2, 0);
298 	WRITE_REG32(pLayerPointers, MemBaseAddress + LED3, 0);
299 
300 	/* Set RCV_RING_CFG */
301 	WRITE_REG16(pLayerPointers, MemBaseAddress + RCV_RING_CFG, 1);
302 
303 	/* SRAM_SIZE & SRAM_BOUNDARY register combined */
304 	if (JumboFlag == JUMBO_ENABLED) {
305 		WRITE_REG32(pLayerPointers, MemBaseAddress + SRAM_SIZE,
306 		    0xc0010);
307 	} else {
308 		WRITE_REG32(pLayerPointers, MemBaseAddress + SRAM_SIZE,
309 		    0x80010);
310 	}
311 
312 	/* Clear XMT_RING0/1/2/3_LEN */
313 	WRITE_REG32(pLayerPointers, MemBaseAddress + XMT_RING_LEN0, 0);
314 	WRITE_REG32(pLayerPointers, MemBaseAddress + XMT_RING_LEN1, 0);
315 	WRITE_REG32(pLayerPointers, MemBaseAddress + XMT_RING_LEN2, 0);
316 	WRITE_REG32(pLayerPointers, MemBaseAddress + XMT_RING_LEN3, 0);
317 
318 	/* Clear XMT_RING_LIMIT */
319 	WRITE_REG32(pLayerPointers, MemBaseAddress + XMT_RING_LIMIT, 0);
320 
321 	WRITE_REG16(pLayerPointers, MemBaseAddress + MIB_ADDR, MIB_CLEAR);
322 }
323 
324 unsigned int
325 mdlReadMib(struct LayerPointers *pLayerPointers, char MIB_COUNTER)
326 {
327 	unsigned int status;
328 	unsigned int data;
329 	unsigned long mmio = pLayerPointers->pMdl->Mem_Address;
330 
331 	WRITE_REG16(pLayerPointers, mmio + MIB_ADDR, MIB_RD_CMD | MIB_COUNTER);
332 	do {
333 		status = READ_REG16(pLayerPointers, mmio + MIB_ADDR);
334 	} while ((status & MIB_CMD_ACTIVE));
335 
336 	data = READ_REG32(pLayerPointers, mmio + MIB_DATA);
337 	return (data);
338 }
339 
340 /* Return 1 on success, return 0 on fail */
341 unsigned int
342 mdlReadPHY(struct LayerPointers *pLayerPointers, unsigned char phyid,
343     unsigned char regaddr, unsigned int *value)
344 {
345 	unsigned int status, data, count;
346 	unsigned long mmio = pLayerPointers->pMdl->Mem_Address;
347 
348 	count = 0;
349 	do {
350 		status = READ_REG16(pLayerPointers, mmio + PHY_ACCESS);
351 		count ++;
352 		drv_usecwait(10);
353 	} while ((status & PHY_CMD_ACTIVE) & (count < PHY_MAX_RETRY));
354 
355 	if (count == PHY_MAX_RETRY) {
356 		return (0);
357 	}
358 
359 	data = ((regaddr & 0x1f) << 16) | ((phyid & 0x1f) << 21) | PHY_RD_CMD;
360 	WRITE_REG32(pLayerPointers, mmio + PHY_ACCESS, data);
361 	do {
362 		status = READ_REG16(pLayerPointers, mmio + PHY_ACCESS);
363 		drv_usecwait(10);
364 		count ++;
365 	} while ((status & PHY_CMD_ACTIVE) & (count < PHY_MAX_RETRY));
366 
367 	if ((count == PHY_MAX_RETRY) || (status & PHY_RD_ERR)) {
368 		return (0);
369 	}
370 
371 	*value = status & 0xffff;
372 	return (1);
373 }
374 
375 void
376 mdlGetPHYID(struct LayerPointers *pLayerPointers)
377 {
378 	unsigned int id1, id2, i;
379 	for (i = 1; i < 32; i++) {
380 		if (mdlReadPHY(pLayerPointers, i, MII_PHYSID1, &id1) == 0)
381 			continue;
382 		if (mdlReadPHY(pLayerPointers, i, MII_PHYSID2, &id2) == 0)
383 			continue;
384 		if ((id1 != 0xffff) & (id2 != 0xffff)) {
385 			pLayerPointers->pMdl->phy_id = i;
386 			return;
387 		}
388 	}
389 }
390 
391 /* Return 1 on success, return 0 on fail */
392 unsigned int
393 mdlWritePHY(struct LayerPointers *pLayerPointers, unsigned char phyid,
394     unsigned char regaddr, unsigned int value)
395 {
396 	unsigned int status, data, count;
397 	unsigned long mmio = pLayerPointers->pMdl->Mem_Address;
398 
399 	count = 0;
400 	do {
401 		status = READ_REG16(pLayerPointers, mmio + PHY_ACCESS);
402 		count ++;
403 		drv_usecwait(10);
404 	} while ((status & PHY_CMD_ACTIVE) & (count < PHY_MAX_RETRY));
405 
406 	if (count == PHY_MAX_RETRY) {
407 		return (0);
408 	}
409 
410 	data = ((regaddr & 0x1f) << 16) | ((phyid & 0x1f) << 21) |
411 	    (value & 0xffff) | PHY_WR_CMD;
412 	WRITE_REG32(pLayerPointers, mmio + PHY_ACCESS, data);
413 
414 	do {
415 		status = READ_REG16(pLayerPointers, mmio + PHY_ACCESS);
416 		drv_usecwait(10);
417 		count ++;
418 	} while ((status & PHY_CMD_ACTIVE) & (count < PHY_MAX_RETRY));
419 
420 	if ((count == PHY_MAX_RETRY) && (status & PHY_RD_ERR)) {
421 		return (0);
422 	}
423 
424 	return (1);
425 }
426 
427 /*
428  *	To Send the packet.
429  */
430 void
431 mdlTransmit(struct LayerPointers *pLayerPointers)
432 {
433 	WRITE_REG32(pLayerPointers, pLayerPointers->pMdl->Mem_Address + CMD0,
434 	    VAL1 | TDMD0);
435 }
436 
437 /*
438  *	To Receive a packet.
439  */
440 void
441 mdlReceive(struct LayerPointers *pLayerPointers)
442 {
443 	/*
444 	 * Receive Demand for ring 0, which when set causes the Descriptor
445 	 * Management Unit to access the Receive Descriptor Ring if it does
446 	 * not already own the next descriptor.
447 	 */
448 	WRITE_REG32(pLayerPointers, pLayerPointers->pMdl->Mem_Address + CMD0,
449 	    VAL2 | RDMD0);
450 }
451 
452 /*
453  * Read the NIC interrupt.
454  *
455  * Returns:
456  *	the value of interrupt causes register
457  */
458 unsigned int
459 mdlReadInterrupt(struct LayerPointers *pLayerPointers)
460 {
461 	unsigned int nINT0;
462 	struct mdl *pMdl = 0;
463 
464 	pMdl = (struct mdl *)(pLayerPointers->pMdl);
465 
466 	/*
467 	 * INT0 identifies the source or sources of an interrupt. With the
468 	 * exception of INTR and INTPN, all bits in this register are "write
469 	 * 1 to clear" so that the CPU can clear the interrupt condition by
470 	 * reading the register and then writing back the same data that it
471 	 * read. Writing a 0 to a bit in this register has no effect.
472 	 */
473 
474 	/* Read interrupt status */
475 	nINT0 = READ_REG32(pLayerPointers, pMdl->Mem_Address + INT0);
476 
477 	/* Process all the INT event until INTR bit is clear. */
478 	WRITE_REG32(pLayerPointers, pMdl->Mem_Address + INT0, nINT0);
479 	return (nINT0);
480 }
481 
482 void
483 mdlHWReset(struct LayerPointers *pLayerPointers)
484 {
485 	struct mdl *pMdl = pLayerPointers->pMdl;
486 	unsigned int ulData, i = 0;
487 	int  JumboFlag = JUMBO_DISABLED;
488 	ULONG Mem_Address = pMdl->Mem_Address;
489 
490 	/*
491 	 * Stop the Card:
492 	 *	First we make sure that the device is stopped and no
493 	 *	more interrupts come out. Also some registers must be
494 	 *	programmed with CSR0 STOP bit set.
495 	 */
496 	mdlStopChip(pLayerPointers);
497 
498 	/*
499 	 * MAC Address Setup:
500 	 *	MAC Physical Address register. All bits in this register are
501 	 *	restored to default values when the RST pin is asserted.
502 	 */
503 	for (i = 0; i < ETH_LENGTH_OF_ADDRESS; i++) {
504 		WRITE_REG8(pLayerPointers, pMdl->Mem_Address + PADR + i,
505 		    pMdl->Mac[i]);
506 	}
507 
508 	/* Set RCV_RING_CFG */
509 
510 	if (JumboFlag == JUMBO_ENABLED) {
511 		WRITE_REG32(pLayerPointers, pMdl->Mem_Address + CMD2,
512 		    VAL0 | APAD_XMT | REX_RTRY | VAL1 | DXMTFCS | RPA | VAL2);
513 
514 		WRITE_REG32(pLayerPointers, pMdl->Mem_Address + CMD3,
515 		    VAL2 | JUMBO);
516 	} else {
517 		/*
518 		 * APAD_XMT: Auto Pad Transmit. When set, APAD_XMT enables
519 		 * the automatic padding feature. Transmit frames are padded
520 		 * to extend them to 64 bytes including FCS.
521 		 *
522 		 * DXMTFCS: Disable Transmit CRC. When DXMTFCS is set to 1, no
523 		 * Transmit CRC is generated. DXMTFCS is overridden when
524 		 * ADD_FCS and ENP bits are set in the transmit descriptor.
525 		 *
526 		 * ASTRIP_RCV: Auto Strip Receive. When ASTRP_RCV is set to 1,
527 		 * the receiver automatically strips pad bytes from the
528 		 * received message by observing the value in the length field
529 		 * and by stripping excess bytes if this value is below the
530 		 * minimum data size (46 bytes).
531 		 */
532 		WRITE_REG32(pLayerPointers, pMdl->Mem_Address + CMD2,
533 		    VAL0 | APAD_XMT | REX_RTRY | REX_UFLO | VAL1 | DXMTFCS
534 		    | ASTRIP_RCV | RPA | VAL2);
535 	}
536 
537 	/* Transmit Start Point setting (csr80) */
538 	ulData = READ_REG32(pLayerPointers, Mem_Address + CTRL1);
539 	ulData &= ~XMTSP_MASK;
540 
541 	WRITE_REG32(pLayerPointers, pMdl->Mem_Address + CTRL1,
542 	    ulData | XMTSP_128);
543 	/* Disable Prom  */
544 	WRITE_REG32(pLayerPointers, pMdl->Mem_Address + CMD2, PROM);
545 
546 	mdlPHYAutoNegotiation(pLayerPointers, pMdl->External_Phy);
547 
548 	pMdl->IpgValue = MIN_IPG_DEFAULT;
549 	/* Set the IPG value */
550 	WRITE_REG16(pLayerPointers, pMdl->Mem_Address + IFS,
551 	    pMdl->IpgValue);
552 
553 	/* Disable Following Interrupts. */
554 	WRITE_REG32(pLayerPointers, pMdl->Mem_Address + INTEN0,
555 	    APINT5EN | APINT4EN | APINT3EN |
556 	    APINT2EN | APINT1EN | APINT0EN | MIIPDTINTEN |
557 	    MCCIINTEN | MCCINTEN | MREINTEN |
558 	    TINTEN0 |
559 	    SPNDINTEN | MPINTEN | SINTEN | LCINTEN);
560 
561 	/* Enable Following Interrupt */
562 	WRITE_REG32(pLayerPointers, pMdl->Mem_Address + INTEN0,
563 	    VAL0 | RINTEN0);
564 
565 	/* Base Address of Transmit Descriptor Ring 0. */
566 	WRITE_REG32(pLayerPointers, pMdl->Mem_Address + XMT_RING_BASE_ADDR0,
567 	    pMdl->init_blk->TDRA);
568 
569 	/* Base Address of Receive Descriptor Ring. */
570 	WRITE_REG32(pLayerPointers, pMdl->Mem_Address + RCV_RING_BASE_ADDR0,
571 	    pMdl->init_blk->RDRA);
572 
573 	/* The number of descriptors in Transmit Descriptor Ring 0 */
574 	WRITE_REG16(pLayerPointers, pMdl->Mem_Address + XMT_RING_LEN0,
575 	    (unsigned short)pLayerPointers->pMdl->TxRingSize);
576 
577 	/*
578 	 * Receive Descriptor Ring Length. All bits in this register are
579 	 * restored to default values when the RST pin is asserted.
580 	 */
581 	WRITE_REG16(pLayerPointers, pMdl->Mem_Address + RCV_RING_LEN0,
582 	    (unsigned short)pLayerPointers->pMdl->RxRingSize);
583 
584 	if (pLayerPointers->pMdl->IntrCoalescFlag) {
585 		SetIntrCoalesc(pLayerPointers, B_TRUE);
586 	}
587 
588 	/* Start the chip */
589 	mdlStartChip(pLayerPointers);
590 }
591 
592 /*
593  * Perform the open oerations on the adapter.
594  */
595 void
596 mdlOpen(struct LayerPointers *pLayerPointers)
597 {
598 	int i, sum;
599 	struct mdl *pMdl = pLayerPointers->pMdl;
600 
601 	/* Get Mac address */
602 	sum = 0;
603 	for (i = 0; i < 6; i++) {
604 		pMdl->Mac[i] = READ_REG8(pLayerPointers,
605 		    pMdl->Mem_Address + PADR + i);
606 		sum += pMdl->Mac[i];
607 	}
608 	if (sum == 0) {
609 		for (i = 0; i < 6; i++) {
610 			pMdl->Mac[i] = 0;
611 		}
612 	}
613 
614 	/* Initialize the hardware */
615 	mdlClearHWConfig(pLayerPointers);
616 	mdlGetPHYID(pLayerPointers);
617 
618 }
619 
620 void
621 mdlGetMacAddress(struct LayerPointers *pLayerPointers,
622     unsigned char *macAddress)
623 {
624 	struct mdl *pMdl = pLayerPointers->pMdl;
625 	int i;
626 
627 	for (i = 0; i < 6; i++) {
628 		macAddress[i] =	pMdl->Mac[i] = READ_REG8(pLayerPointers,
629 		    pMdl->Mem_Address + PADR + i);
630 	}
631 
632 }
633 
634 
635 void
636 mdlSetMacAddress(struct LayerPointers *pLayerPointers,
637     unsigned char *macAddress)
638 {
639 	int i;
640 	struct mdl *pMdl = 0;
641 
642 	pMdl = (struct mdl *)(pLayerPointers->pMdl);
643 
644 	pMdl->Mac[0] = macAddress[0];
645 	pMdl->Mac[1] = macAddress[1];
646 	pMdl->Mac[2] = macAddress[2];
647 	pMdl->Mac[3] = macAddress[3];
648 	pMdl->Mac[4] = macAddress[4];
649 	pMdl->Mac[5] = macAddress[5];
650 
651 	/*
652 	 * MAC Address Setup:
653 	 *	MAC Physical Address register. All bits in this register are
654 	 *	restored to default values when the RST pin is asserted.
655 	 */
656 	for (i = 0; i < ETH_LENGTH_OF_ADDRESS; i++) {
657 		WRITE_REG8(pLayerPointers, pMdl->Mem_Address + PADR + i,
658 		    pMdl->Mac[i]);
659 	}
660 }
661 
662 /*
663  * This array is filled with the size of the memory required for
664  * allocating purposes.
665  */
666 static void
667 mdlRequestResources(ULONG *mem_req_array)
668 {
669 	/* 1) For mdl structure */
670 	*mem_req_array = VIRTUAL;		/* Type */
671 	*(++mem_req_array) = sizeof (struct mdl); /* Size */
672 
673 	/* 2) For PMR PtrList array (PMR_ptrList) */
674 	*(++mem_req_array) = VIRTUAL;		/* Type */
675 	/* Size */
676 	*(++mem_req_array) = sizeof (unsigned int) * (MAX_ALLOWED_PATTERNS + 2);
677 
678 	/* 3) For PMR Pattern List array (PatternList) */
679 	*(++mem_req_array) = VIRTUAL;			/* Type */
680 	/* Size */
681 	*(++mem_req_array) = sizeof (unsigned char) * (MAX_PATTERNS + 2);
682 
683 	/* 4) For pmr PatternLength array (PatternLength) */
684 	*(++mem_req_array) = VIRTUAL;			/* Type */
685 	/* Size */
686 	*(++mem_req_array) = sizeof (unsigned int) * (MAX_ALLOWED_PATTERNS + 2);
687 
688 	/*
689 	 * 5) For the init_block (init_blk)
690 	 */
691 	*(++mem_req_array) = VIRTUAL;
692 	*(++mem_req_array) = sizeof (struct init_block);
693 
694 	*(++mem_req_array) = 0;
695 	mem_req_array++;
696 }
697 
698 
699 /*
700  *	Purpose  :
701  *		This array contains the details of the allocated memory. The
702  *		pointers are taken from the respective locations in the array &
703  *		assigned appropriately to the respective structures.
704  *
705  *	Arguments :
706  *		pLayerPointers
707  *			Pointer to the adapter structure.
708  *		pmem_set_array
709  *			Pointer to the array that holds the data after required
710  *			allocating memory.
711  */
712 static void
713 mdlSetResources(struct LayerPointers *pLayerPointers, ULONG *pmem_set_array)
714 {
715 	struct mdl *pMdl = 0;
716 
717 	/* 1) For mdl structure */
718 	pmem_set_array++;	/* Type */
719 	pmem_set_array++;	/* Size */
720 	pLayerPointers->pMdl = (struct mdl *)(*pmem_set_array);
721 
722 	pMdl = (struct mdl *)(pLayerPointers->pMdl);
723 
724 	pMdl->RxRingLenBits = RX_RING_LEN_BITS;
725 	pMdl->TxRingLenBits = TX_RING_LEN_BITS;
726 	pMdl->TxRingSize = TX_RING_SIZE;
727 	pMdl->RxRingSize = RX_RING_SIZE;
728 
729 	/*
730 	 * Default values that would be used if it does not enable
731 	 * enable dynamic ipg.
732 	 */
733 
734 	/*  2) Set the pointers to the PMR Pointer List */
735 	pmem_set_array++;	/* Type */
736 	pmem_set_array++;	/* Size */
737 	pmem_set_array++;	/* Virtual Addr of PtrList */
738 	pMdl->PMR_PtrList = (unsigned int *)(*pmem_set_array);
739 
740 	/* 3) Set the pointers to the PMR Pattern List */
741 	pmem_set_array++;	/* Type */
742 	pmem_set_array++;	/* Size */
743 	pmem_set_array++;	/* Virtual Addr of PatternList */
744 	pMdl->PatternList = (unsigned char *)(*pmem_set_array);
745 
746 	/* 4) Set the pointers to the PMR Pattern Length */
747 	pmem_set_array++;	/* Type */
748 	pmem_set_array++;	/* Size */
749 	pmem_set_array++;	/* Virtual Addr of PatternLength */
750 	pMdl->PatternLength = (unsigned int *)(*pmem_set_array);
751 
752 	/* 5) Set the pointers to the init block */
753 	pmem_set_array++;	/* Type  */
754 	pmem_set_array++;	/* Size */
755 	pmem_set_array++;	/* Virtual Addr of init_block */
756 	pMdl->init_blk = (struct init_block *)(*pmem_set_array);
757 
758 	pMdl->init_blk->TLEN = pMdl->TxRingLenBits;
759 	pMdl->init_blk->RLEN = pMdl->RxRingLenBits;
760 
761 	pmem_set_array++;
762 
763 	*pmem_set_array = 0;
764 }
765 
766 /*
767  *	Purpose:
768  *		This array is filled with the size of the structure & its
769  *		pointer for freeing purposes.
770  *
771  *	Arguments:
772  *		pLayerPointers
773  *			Pointer to the adapter structure.
774  *		mem_free_array
775  *			Pointer to the array that holds the data required for
776  *			freeing.
777  */
778 static void
779 mdlFreeResources(struct LayerPointers *pLayerPointers, ULONG *pmem_free_array)
780 {
781 	struct mdl *pMdl = 0;
782 
783 	pMdl = (struct mdl *)(pLayerPointers->pMdl);
784 
785 	/* 1) For mdl structure */
786 	*(pmem_free_array) = VIRTUAL;		/* Type */
787 	*(++pmem_free_array) = sizeof (struct mdl); /* Size */
788 	*(++pmem_free_array) = (ULONG)pMdl;  /* VA */
789 
790 	/* 2) For ptr list */
791 	*(++pmem_free_array) = VIRTUAL;		/* Type */
792 	*(++pmem_free_array) =  sizeof (unsigned int)
793 	    * (MAX_ALLOWED_PATTERNS + 2);  /* Size */
794 	*(++pmem_free_array) = (ULONG)pMdl->PMR_PtrList;  /* VA */
795 
796 	/* 3) For pattern list */
797 	*(++pmem_free_array) = VIRTUAL;		/* Type	 */
798 	/* Size */
799 	*(++pmem_free_array) =  sizeof (unsigned char) * (MAX_PATTERNS + 2);
800 	*(++pmem_free_array) = (ULONG)pMdl->PatternList;  /* VA */
801 
802 	/* 4) For pattern length */
803 	*(++pmem_free_array) = VIRTUAL;				/* Type */
804 	*(++pmem_free_array) =  sizeof (unsigned int)
805 	    * (MAX_ALLOWED_PATTERNS + 2);			/* Size */
806 	*(++pmem_free_array) = (ULONG)pMdl->PatternLength;	/* VA */
807 
808 	/* 5) For init_blk structure */
809 	*(++pmem_free_array) = VIRTUAL;				/* Type */
810 	/* Size */
811 	*(++pmem_free_array) = sizeof (struct init_block);
812 	*(++pmem_free_array) = (ULONG)pMdl->init_blk;		/* VA */
813 
814 	*(++pmem_free_array) = 0;
815 }
816 
817 void
818 mdlStartChip(struct LayerPointers *pLayerPointers)
819 {
820 	/* Enable Receiver */
821 	WRITE_REG32(pLayerPointers, pLayerPointers->pMdl->Mem_Address + CMD0,
822 	    VAL2 | RDMD0);
823 
824 	/* Enable Interrupt and Start processing descriptor, Rx and Tx */
825 	WRITE_REG32(pLayerPointers, pLayerPointers->pMdl->Mem_Address + CMD0,
826 	    VAL0 | INTREN | RUN);
827 }
828 
829 /*
830  *	Stops the chip.
831  */
832 void
833 mdlStopChip(struct LayerPointers *pLayerPointers)
834 {
835 	int nINT0;
836 	struct mdl *pMdl = 0;
837 
838 	pMdl = (struct mdl *)(pLayerPointers->pMdl);
839 
840 	/* Disable interrupt */
841 	WRITE_REG32(pLayerPointers, pMdl->Mem_Address + CMD0, INTREN);
842 
843 	/* Clear interrupt status */
844 	nINT0 = READ_REG32(pLayerPointers, pMdl->Mem_Address + INT0);
845 	WRITE_REG32(pLayerPointers, pMdl->Mem_Address + INT0, nINT0);
846 
847 	/*
848 	 * Setting the RUN bit enables the controller to start processing
849 	 * descriptors and transmitting and  receiving packets. Clearing
850 	 * the RUN bit to 0 abruptly disables the transmitter, receiver, and
851 	 * descriptor processing logic, possibly while a frame is being
852 	 * transmitted or received.
853 	 * The act of changing the RUN bit from 1 to 0 causes the following
854 	 * bits to be reset to 0: TX_SPND, RX_SPND, TX_FAST_SPND, RX_FAST_SPND,
855 	 * RDMD, all TDMD bits, RINT, all TINT bits, MPINT, and SPNDINT.
856 	 */
857 	WRITE_REG32(pLayerPointers, pMdl->Mem_Address + CMD0, RUN);
858 }
859 
860 /*
861  *	Enables the interrupt.
862  */
863 void
864 mdlEnableInterrupt(struct LayerPointers *pLayerPointers)
865 {
866 	/*
867 	 * Interrupt Enable Bit:
868 	 * This bit allows INTA to be asserted if any bit in the interrupt
869 	 * register is set. If INTREN is cleared to 0, INTA will not be
870 	 * asserted, regardless of the state of the interrupt register.
871 	 */
872 	WRITE_REG32(pLayerPointers, pLayerPointers->pMdl->Mem_Address + CMD0,
873 	    VAL0 | INTREN);
874 }
875 
876 #ifdef AMD8111S_DEBUG
877 static void
878 mdlClearInterrupt(struct LayerPointers *pLayerPointers)
879 {
880 	unsigned int nINT0;
881 	struct mdl *pMdl = 0;
882 
883 	pMdl = (struct mdl *)(pLayerPointers->pMdl);
884 
885 	/* Clear interrupt status */
886 	nINT0 = READ_REG32(pLayerPointers, pMdl->Mem_Address + INT0);
887 	WRITE_REG32(pLayerPointers, pMdl->Mem_Address + INT0, nINT0);
888 
889 }
890 #endif
891 
892 /*
893  *	Disables the interrupt.
894  */
895 void
896 mdlDisableInterrupt(struct LayerPointers *pLayerPointers)
897 {
898 	/* Disable interrupt */
899 	WRITE_REG32(pLayerPointers,
900 	    pLayerPointers->pMdl->Mem_Address + CMD0, INTREN);
901 }
902 
903 /*
904  *	Reads the link status
905  */
906 int
907 mdlReadLink(struct LayerPointers *pLayerPointers)
908 {
909 	unsigned int link_status = 0;
910 
911 	link_status = READ_REG32(pLayerPointers,
912 	    pLayerPointers->pMdl->Mem_Address + STAT0);
913 
914 	if ((link_status & LINK_STAT)) {
915 		return (LINK_UP);
916 	} else {
917 		return (LINK_DOWN);
918 	}
919 }
920 
921 /*
922  *	Purpose  :
923  *		Adds the wakeup pattern given by the upper layer.
924  *
925  *	Arguments :
926  *		pLayerPointers
927  *			Pointer to the Adapter structure.
928  *		PatternMask
929  *			The mask for the pattern to be added.
930  *		Pattern
931  *			The Pattern to be added.
932  *		InfoBuffer_MaskSize
933  *			The mask size as specified in the Information Buffer.
934  *		PatternSize
935  *			The PatternSize as specified in the Information Buffer.
936  */
937 static void
938 mdlAddWakeUpPattern(struct LayerPointers *pLayerPointers,
939     unsigned char *PatternMask, unsigned char *Pattern,
940     unsigned long InfoBuffer_MaskSize, unsigned long PatternSize, int *retval)
941 {
942 	unsigned long MaskSize;
943 	unsigned long ReqSize;
944 	unsigned char byteData = 0, tmpData;
945 	unsigned char Skip = 0;
946 	unsigned int i = 0, flag = 1, count = 1;
947 	unsigned int j;
948 	int PatternOffset, SearchForStartOfPattern = 1;
949 	struct mdl *pMdl = 0;
950 
951 	pMdl = pLayerPointers->pMdl;
952 
953 	if (pMdl->TotalPatterns >= MAX_ALLOWED_PATTERNS) {
954 		*retval = -1;
955 		return;
956 	}
957 
958 	MaskSize = PatternSize/4 + (PatternSize%4 ? 1 : 0);
959 
960 	ReqSize = PatternSize + MaskSize;
961 	if (((PatternSize+MaskSize)%5) != 0)
962 		ReqSize +=  5 - ((PatternSize+MaskSize)%5);
963 
964 	if (ReqSize >
965 	    (unsigned long)(MAX_PATTERNS - pMdl->PatternList_FreeIndex)) {
966 		*retval = -1;
967 		return;
968 	}
969 
970 	if (InfoBuffer_MaskSize != PatternSize/8 + (PatternSize%8 ? 1 : 0)) {
971 		*retval = -1;
972 		return;
973 	}
974 
975 	i = pMdl->PatternList_FreeIndex;
976 
977 	pMdl->PMR_PtrList[pMdl->TotalPatterns] = i;
978 
979 	pMdl->PatternLength[pMdl->TotalPatterns] = (unsigned int)PatternSize;
980 
981 	while (i < (pMdl->PatternList_FreeIndex + PatternSize + MaskSize)) {
982 		if (flag) {
983 			byteData = *PatternMask;
984 			pMdl->PatternList[i++] =
985 			    (unsigned int)((byteData & 0x0F) | (Skip<< 4));
986 			flag = 0;
987 		} else {
988 			pMdl->PatternList[i++] = (unsigned int)
989 			    (((unsigned)(byteData & 0xF0) >> 4) | (Skip << 4));
990 			PatternMask++;
991 			flag = 1;
992 		}
993 		count = 1;
994 		while ((count < 5) && (i <
995 		    pMdl->PatternList_FreeIndex + PatternSize + MaskSize)) {
996 			tmpData = *Pattern;
997 			Pattern++;
998 			pMdl->PatternList[i++] = tmpData;
999 			count++;
1000 		}
1001 	}
1002 
1003 	/* Filling up the extra byte blocks in the row to 0. */
1004 	for (i = (pMdl->PatternList_FreeIndex + PatternSize + MaskSize);
1005 	    i < (pMdl->PatternList_FreeIndex + ReqSize); i++)
1006 		pMdl->PatternList[i] = 0;
1007 
1008 	/* Set the EOP bit for the last mask!!! */
1009 	pMdl->PatternList[pMdl->PatternList_FreeIndex + ReqSize - 5] |= 0x80;
1010 
1011 	for (j = 0; j < 8; j++) {
1012 		pMdl->tmpPtrArray[j] = 0;
1013 	}
1014 
1015 	/* Zeroing the skip value of all the pattern masks */
1016 	j = 0;
1017 	while (j < (pMdl->PatternList_FreeIndex + ReqSize)) {
1018 		pMdl->PatternList[j] &= 0x8f;
1019 		j += 5;
1020 	}
1021 
1022 	/*
1023 	 * Scan the whole array & update the start offset of the pattern in the
1024 	 * PMR and update the skip value.
1025 	 */
1026 	j = 0;
1027 	i = 0;
1028 
1029 	PatternOffset = 1;
1030 	Skip = 0;
1031 
1032 	while (j < (pMdl->PatternList_FreeIndex + ReqSize)) {
1033 
1034 		if (pMdl->PatternList[j] & 0x0f) {
1035 			PatternOffset ++;
1036 			if (SearchForStartOfPattern == 1) {
1037 				SearchForStartOfPattern = 0;
1038 				pMdl->tmpPtrArray[i++] = PatternOffset;
1039 			} else if (pMdl->PatternList[j] & 0x80) {
1040 				SearchForStartOfPattern = 1;
1041 			}
1042 			pMdl->PatternList[j] |= (Skip << 4);
1043 			Skip = 0;
1044 		} else {
1045 			Skip++;
1046 		}
1047 		j += 5;
1048 	}
1049 
1050 	/* valid pattern.. so update the house keeping info. */
1051 	pMdl->PatternList_FreeIndex += (unsigned short)ReqSize;
1052 	pMdl->TotalPatterns++;
1053 
1054 	*retval = 0;
1055 }
1056 
1057 /*
1058  *	Purpose:
1059  *		Removes the specified wakeup pattern.
1060  *
1061  *	Arguments :
1062  *		pLayerPointers
1063  *			Pointer to the Adapter structure.
1064  *		Pattern
1065  *			The Pattern to be added.
1066  *		PatternSize
1067  *			The PatternSize as specified in the Information Buffer.
1068  */
1069 static void
1070 mdlRemoveWakeUpPattern(struct LayerPointers *pLayerPointers,
1071     unsigned char *Pattern, unsigned long PatternSize, int *retval)
1072 {
1073 	unsigned long ReqSize, MaskSize;
1074 	unsigned char tmpData;
1075 	unsigned long Data;
1076 	unsigned short Data1, Data2, Data3, Data4, Data5, Data6, Data7, Data8;
1077 	int PatternMismatch = 0;
1078 	int count, StartIndex, index = 0;
1079 	unsigned int i, j;
1080 	unsigned char Skip = 0;
1081 	struct mdl *pMdl = 0;
1082 	int PatternOffset, SearchForStartOfPattern = 1;
1083 	unsigned long tmpPtrArray[8];
1084 	int offset;
1085 
1086 	Data1 = Data2 = Data3 = Data4 = Data5 = Data6 = Data7 = Data8 = 0;
1087 
1088 	pMdl = (struct mdl *)(pLayerPointers->pMdl);
1089 
1090 	/* Find the pattern to be removed. */
1091 	if (pMdl->TotalPatterns == 0) {
1092 		*retval = -1;
1093 		return;
1094 	}
1095 
1096 	MaskSize = PatternSize/4 + (PatternSize%4 ? 1 : 0);
1097 
1098 	ReqSize = PatternSize + MaskSize;
1099 	if (((PatternSize+MaskSize)%5) != 0)
1100 		ReqSize +=  5 - ((PatternSize+MaskSize)%5);
1101 
1102 	count = pMdl->TotalPatterns;
1103 
1104 	while (count--) {
1105 		PatternMismatch = 0;
1106 		StartIndex = pMdl->PMR_PtrList[index];
1107 
1108 		if (pMdl->PatternLength[index] != PatternSize) {
1109 			index++;
1110 			PatternMismatch = 1;
1111 			continue;
1112 		}
1113 
1114 		for (i = StartIndex; i < (StartIndex+ReqSize); i++) {
1115 			if (!(i%5))
1116 				i++;
1117 
1118 			tmpData = *Pattern;
1119 			if (pMdl->PatternList[i] != tmpData) {
1120 				PatternMismatch = 1;
1121 				break;
1122 			}
1123 			Pattern++;
1124 		}
1125 
1126 		if (PatternMismatch == 0) {
1127 			i = StartIndex + ReqSize;
1128 
1129 			/* Pattern found remove it from the arrays */
1130 			while (i < pMdl->PatternList_FreeIndex) {
1131 				pMdl->PatternList[StartIndex] =
1132 				    pMdl->PatternList[i];
1133 				i++;
1134 				StartIndex++;
1135 			}
1136 
1137 			pMdl->PatternList_FreeIndex =
1138 			    (unsigned short)(StartIndex);
1139 
1140 			while (StartIndex < MAX_PATTERNS)
1141 				pMdl->PatternList[StartIndex++] = 0;
1142 
1143 			while (index < (int)pMdl->TotalPatterns) {
1144 				pMdl->PMR_PtrList[index] =
1145 				    pMdl->PMR_PtrList[index+1] - ReqSize;
1146 
1147 				pMdl->PatternLength[index] =
1148 				    pMdl->PatternLength[index+1];
1149 
1150 				index ++;
1151 			}
1152 
1153 			index--;
1154 			while (index < MAX_ALLOWED_PATTERNS) {
1155 				pMdl->PMR_PtrList[index+1] = 0;
1156 				pMdl->PatternLength[index+1] = 0;
1157 				index++;
1158 			}
1159 
1160 			break;
1161 		}
1162 		index++;
1163 	}
1164 
1165 	if (PatternMismatch) {
1166 		*retval = -1;
1167 		return;
1168 	}
1169 
1170 
1171 	for (j = 0; j < 8; j++) {
1172 		tmpPtrArray[j] = 0;
1173 	}
1174 
1175 	/* Zeroing the skip value of all the pattern masks */
1176 	j = 0;
1177 	while (j < (pMdl->PatternList_FreeIndex)) {
1178 		pMdl->PatternList[j] &= 0x8f;
1179 		j += 5;
1180 	}
1181 
1182 	/*
1183 	 * Scan the whole array & update the start offset of the pattern in the
1184 	 * PMR and update the skip value.
1185 	 */
1186 	j = 0;
1187 	i = 0;
1188 	Skip = 0;
1189 	PatternOffset = 1;
1190 
1191 	while (j < (pMdl->PatternList_FreeIndex)) {
1192 		if (pMdl->PatternList[j] & 0x0f) {
1193 
1194 			PatternOffset++;
1195 			if (SearchForStartOfPattern == 1) {
1196 				SearchForStartOfPattern = 0;
1197 				tmpPtrArray[i++] = PatternOffset;
1198 			} else if (pMdl->PatternList[j] & 0x80) {
1199 				SearchForStartOfPattern = 1;
1200 			}
1201 			pMdl->PatternList[j] |= (Skip << 4);
1202 			Skip = 0;
1203 		} else {
1204 			Skip++;
1205 		}
1206 		j += 5;
1207 	}
1208 
1209 
1210 	/* Write back the arrays to the PMR & lock the pmr */
1211 	WRITE_REG32(pLayerPointers, pMdl->Mem_Address+CMD7, PMAT_MODE);
1212 
1213 	/* Write the data & ctrl patterns from the array to the PMR */
1214 	i = 0;
1215 
1216 	offset = 2;
1217 
1218 	while (i < MAX_PATTERNS) {
1219 		if (pMdl->PatternList[i] != 0) {
1220 			Data = pMdl->PatternList[i+3] << 24 |
1221 			    pMdl->PatternList[i+2] << 16 |
1222 			    pMdl->PatternList[i+1] << 8  |
1223 			    pMdl->PatternList[i];
1224 
1225 			WRITE_REG32(pLayerPointers,
1226 			    pMdl->Mem_Address+PMAT1, Data);
1227 
1228 			Data = (unsigned long) ((1<<30) | (offset << 16) |
1229 			    pMdl->PatternList[i+4]);
1230 
1231 			WRITE_REG32(pLayerPointers,
1232 			    pMdl->Mem_Address+PMAT0, Data);
1233 
1234 			offset++;
1235 
1236 			if (offset >= 64) {
1237 				/* PMR is full !!!! */
1238 				*retval = -1;
1239 				return;
1240 
1241 			}
1242 		}
1243 		i += 5;
1244 	}
1245 
1246 	/* Valid pattern.. so update the house keeping info. */
1247 	pMdl->TotalPatterns--;
1248 
1249 	/* Update the pointer in the PMR */
1250 	pMdl->PatternEnableBit = 0;
1251 	for (i = 0; i < pMdl->TotalPatterns; i++) {
1252 		pMdl->PatternEnableBit |= (0x0001 << i);
1253 	}
1254 
1255 	Data1 = Data2 = Data3 = Data4 = Data5 = Data6 = Data7 = Data8 = 0;
1256 
1257 	switch (pMdl->TotalPatterns) {
1258 	case 8 :
1259 		Data8 = (unsigned short)tmpPtrArray[7];
1260 		/* FALLTHROUGH */
1261 	case 7 :
1262 		Data7 = (unsigned short)tmpPtrArray[6];
1263 		/* FALLTHROUGH */
1264 	case 6 :
1265 		Data6 = (unsigned short)tmpPtrArray[5];
1266 		/* FALLTHROUGH */
1267 	case 5 :
1268 		Data5 = (unsigned short)tmpPtrArray[4];
1269 		/* FALLTHROUGH */
1270 	case 4 :
1271 		Data4 = (unsigned short)tmpPtrArray[3];
1272 		/* FALLTHROUGH */
1273 	case 3 :
1274 		Data3 = (unsigned short)tmpPtrArray[2];
1275 		/* FALLTHROUGH */
1276 	case 2 :
1277 		Data2 = (unsigned short)tmpPtrArray[1];
1278 		/* FALLTHROUGH */
1279 	case 1 :
1280 		Data1 = (unsigned short)tmpPtrArray[0];
1281 		break;
1282 	}
1283 
1284 	Data = pMdl->PatternEnableBit & 0x0f;
1285 
1286 	/* Updating the pointers 1,2,3 & 4 */
1287 	Data = (Data3 << 24 |   Data2 << 16 |   Data1 << 8  |   Data);
1288 	WRITE_REG32(pLayerPointers, pMdl->Mem_Address + PMAT1, Data);
1289 
1290 	Data = (unsigned long) ((1<<30) | Data4);
1291 	WRITE_REG32(pLayerPointers, pMdl->Mem_Address + PMAT0, Data);
1292 
1293 	/* Updating the pointers 4,5,6 & 7 */
1294 	Data = (unsigned short)((unsigned)(pMdl->PatternEnableBit & 0xf0) >> 4);
1295 
1296 	Data = (Data7 << 24 |   Data6 << 16 |   Data5 << 8  |   Data);
1297 	WRITE_REG32(pLayerPointers, pMdl->Mem_Address + PMAT1, Data);
1298 
1299 	Data = (unsigned long) ((1<<30) | (1<<16) | Data8);
1300 	WRITE_REG32(pLayerPointers, pMdl->Mem_Address + PMAT0, Data);
1301 
1302 	/* Unlock the PMR */
1303 	WRITE_REG32(pLayerPointers, pMdl->Mem_Address + CMD7, VAL0 | PMAT_MODE);
1304 
1305 	*retval = 0;
1306 }
1307 
1308 
1309 /*
1310  *	Checks the control register for the speed and the type of the
1311  *	network connection.
1312  */
1313 void
1314 mdlGetActiveMediaInfo(struct LayerPointers *pLayerPointers)
1315 {
1316 
1317 	unsigned long  ulData;
1318 	struct mdl *pMdl = 0;
1319 
1320 	pMdl = (struct mdl *)(pLayerPointers->pMdl);
1321 
1322 	ulData = READ_REG32(pLayerPointers, pMdl->Mem_Address + STAT0);
1323 
1324 	switch (ulData & SPEED_MASK) {
1325 	case SPEED_100Mbps:
1326 		pMdl->Speed = 100;
1327 		break;
1328 	case SPEED_10Mbps:
1329 		pMdl->Speed = 10;
1330 		break;
1331 	default:
1332 		pMdl->Speed = 100;
1333 		break;
1334 	}
1335 
1336 	if (ulData & FULL_DPLX) {
1337 		pMdl->FullDuplex = B_TRUE;
1338 	} else {
1339 		pMdl->FullDuplex = B_FALSE;
1340 	}
1341 }
1342 
1343 void
1344 mdlChangeFilter(struct LayerPointers *pLayerPointers, unsigned long  *ArrayPtr)
1345 {
1346 	unsigned long *Ptr;
1347 	unsigned char *MulticastArray;
1348 	unsigned char *Pattern, *PatternMask;
1349 	unsigned int InfoBuffer_MaskSize, PatternSize;
1350 	int *retval;
1351 	int NumberOfAddress, i;
1352 	unsigned int j, CRCValue = 0;
1353 	unsigned char HashCode = 0, FilterByte = 0;
1354 	int BitMapIndex = 0;
1355 
1356 	Ptr = ArrayPtr;
1357 
1358 	while (*Ptr) {
1359 		switch (*Ptr) {
1360 		case DISABLE_BROADCAST:
1361 			mdlDisableReceiveBroadCast(pLayerPointers);
1362 			break;
1363 
1364 		case ENABLE_BROADCAST:
1365 			mdlReceiveBroadCast(pLayerPointers);
1366 			break;
1367 
1368 		case ENABLE_ALL_MULTICAST:
1369 			for (i = 0; i < 8; i++) {
1370 				pLayerPointers->pMdl->init_blk->LADRF[i] = 0xff;
1371 			}
1372 			WRITE_REG64(pLayerPointers,
1373 			    (unsigned long)pLayerPointers->pMdl
1374 			    ->Mem_Address + LADRF1,
1375 			    (char *)pLayerPointers->pMdl->init_blk->LADRF);
1376 			break;
1377 
1378 		case DISABLE_ALL_MULTICAST:
1379 			if (pLayerPointers->pMdl->EnableMulticast == 1) {
1380 				for (i = 0; i < 8; i++) {
1381 					pLayerPointers->pMdl->init_blk
1382 					    ->LADRF[i] =
1383 					    pLayerPointers->pMdl->TempLADRF[i];
1384 				}
1385 			}
1386 
1387 			WRITE_REG64(pLayerPointers,
1388 			    (unsigned long)pLayerPointers->pMdl->Mem_Address
1389 			    + LADRF1,
1390 			    (char *)pLayerPointers->pMdl->init_blk->LADRF);
1391 			break;
1392 
1393 
1394 		case ADD_MULTICAST:
1395 			NumberOfAddress = *(++Ptr);
1396 			MulticastArray = (unsigned char *)(*(++Ptr));
1397 			mdlAddMulticastAddresses(pLayerPointers,
1398 			    NumberOfAddress, MulticastArray);
1399 			break;
1400 
1401 
1402 		case ENABLE_MULTICAST:
1403 			for (i = 0; i < 8; i++) {
1404 				pLayerPointers->pMdl->init_blk->LADRF[i]  =
1405 				    pLayerPointers->pMdl->TempLADRF[i];
1406 			}
1407 			pLayerPointers->pMdl->EnableMulticast = 1;
1408 
1409 			WRITE_REG64(pLayerPointers,
1410 			    (unsigned long)pLayerPointers->pMdl->Mem_Address
1411 			    + LADRF1,
1412 			    (char *)pLayerPointers->pMdl->init_blk->LADRF);
1413 			break;
1414 
1415 		case DISABLE_MULTICAST:
1416 			for (i = 0; i < 8; i++) {
1417 				pLayerPointers->pMdl->init_blk->LADRF[i] = 0;
1418 			}
1419 
1420 			pLayerPointers->pMdl->EnableMulticast = 0;
1421 
1422 			for (BitMapIndex = 0; BitMapIndex <
1423 			    MULTICAST_BITMAP_ARRAY_SIZE; BitMapIndex++)
1424 				pLayerPointers->pMdl->MulticastBitMapArray
1425 				    [BitMapIndex] = 0;
1426 			WRITE_REG64(pLayerPointers,
1427 			    (unsigned long)pLayerPointers->pMdl->Mem_Address
1428 			    + LADRF1,
1429 			    (char *)pLayerPointers->pMdl->init_blk->LADRF);
1430 			break;
1431 
1432 
1433 		case ADD_WAKE_UP_PATTERN:
1434 			PatternMask = (unsigned char *)(*(++Ptr));
1435 			Pattern = (unsigned char *)(*(++Ptr));
1436 			InfoBuffer_MaskSize = (*(++Ptr));
1437 			PatternSize = (*(++Ptr));
1438 			retval = (int *)(*(++Ptr));
1439 
1440 			mdlAddWakeUpPattern(pLayerPointers,
1441 			    PatternMask,
1442 			    Pattern,
1443 			    InfoBuffer_MaskSize,
1444 			    PatternSize,
1445 			    retval);
1446 			break;
1447 
1448 		case REMOVE_WAKE_UP_PATTERN:
1449 			Pattern = (unsigned char *)(*(++Ptr));
1450 			PatternSize = *(++Ptr);
1451 			retval = (int *)(*(++Ptr));
1452 			mdlRemoveWakeUpPattern(pLayerPointers,
1453 			    Pattern,
1454 			    PatternSize,
1455 			    retval);
1456 			break;
1457 
1458 		case ENABLE_MAGIC_PACKET_WAKE_UP:
1459 			mdlEnableMagicPacketWakeUp(pLayerPointers);
1460 			break;
1461 
1462 		case SET_SINGLE_MULTICAST:
1463 			NumberOfAddress = *(++Ptr);
1464 			MulticastArray = (unsigned char *)(*(++Ptr));
1465 
1466 			for (i = 0; i < 8; i++) {
1467 				pLayerPointers->pMdl->TempLADRF[i] =
1468 				    pLayerPointers->pMdl->init_blk->LADRF[i];
1469 			}
1470 			CRCValue = mdlCalculateCRC(ETH_LENGTH_OF_ADDRESS,
1471 			    MulticastArray);
1472 			for (j = 0; j < 6; j++) {
1473 				HashCode = (HashCode << 1) +
1474 				    (((unsigned char)CRCValue >> j) & 0x01);
1475 			}
1476 			/*
1477 			 * Bits 3-5 of HashCode point to byte in address
1478 			 * filter.
1479 			 * Bits 0-2 point to bit within that byte.
1480 			 */
1481 			FilterByte = HashCode >> 3;
1482 			pLayerPointers->pMdl->TempLADRF[FilterByte] |=
1483 			    (1 << (HashCode & 0x07));
1484 			break;
1485 
1486 		case UNSET_SINGLE_MULTICAST:
1487 			NumberOfAddress = *(++Ptr);
1488 			MulticastArray = (unsigned char *)(*(++Ptr));
1489 			for (i = 0; i < 8; i++) {
1490 				pLayerPointers->pMdl->TempLADRF[i] =
1491 				    pLayerPointers->pMdl->init_blk->LADRF[i];
1492 			}
1493 			CRCValue = mdlCalculateCRC(ETH_LENGTH_OF_ADDRESS,
1494 			    MulticastArray);
1495 			for (j = 0; j < 6; j++) {
1496 				HashCode = ((HashCode << 1) +
1497 				    (((unsigned char)CRCValue >> j) & 0x01));
1498 			}
1499 
1500 			/*
1501 			 * Bits 3-5 of HashCode point to byte in address
1502 			 * filter.
1503 			 * Bits 0-2 point to bit within that byte.
1504 			 */
1505 			FilterByte = HashCode >> 3;
1506 			pLayerPointers->pMdl->TempLADRF[FilterByte] &=
1507 			    !(1 << (HashCode & 0x07));
1508 			break;
1509 
1510 		default:
1511 			break;
1512 		}
1513 		Ptr++;
1514 	}
1515 }
1516 
1517 
1518 void
1519 mdlAddMulticastAddresses(struct LayerPointers *pLayerPointers,
1520     int NumberOfAddress, unsigned char *MulticastAddresses)
1521 {
1522 	unsigned int j, CRCValue;
1523 	unsigned char HashCode, FilterByte;
1524 	int i;
1525 
1526 	for (i = 0; i < 8; i++) {
1527 		pLayerPointers->pMdl->TempLADRF[i]  = 0x00;
1528 	}
1529 
1530 
1531 	for (i = 0; i < NumberOfAddress; i++) {
1532 		HashCode = 0;
1533 
1534 		/* Calculate CRC value */
1535 		CRCValue = mdlCalculateCRC(ETH_LENGTH_OF_ADDRESS,
1536 		    MulticastAddresses);
1537 
1538 		for (j = 0; j < 6; j++) {
1539 			HashCode = (HashCode << 1) +
1540 			    (((unsigned char)CRCValue >> j) & 0x01);
1541 		}
1542 
1543 		/* Bits 3-5 of HashCode point to byte in address filter. */
1544 		/* Bits 0-2 point to bit within that byte. */
1545 		FilterByte = HashCode >> 3;
1546 		pLayerPointers->pMdl->TempLADRF[FilterByte] |=
1547 		    (1 << (HashCode & 0x07));
1548 		MulticastAddresses += ETH_LENGTH_OF_ADDRESS;
1549 	}
1550 }
1551 
1552 /* Receive all packets  */
1553 void
1554 mdlSetPromiscuous(struct LayerPointers *pLayerPointers)
1555 {
1556 	/*
1557 	 * Writable N == Can Be Written only when device is not running
1558 	 * (RUN == 0)
1559 	 */
1560 	WRITE_REG32(pLayerPointers, pLayerPointers->pMdl->Mem_Address + CMD2,
1561 	    VAL2 | PROM);
1562 	pLayerPointers->pMdl->FLAGS |= PROM;	/* B16_MASK */
1563 }
1564 
1565 /* Stop Receiving all packets  */
1566 void
1567 mdlDisablePromiscuous(struct LayerPointers *pLayerPointers)
1568 {
1569 	/*
1570 	 * Writable N == Can Be Written only when device is not running
1571 	 * (RUN == 0)
1572 	 */
1573 	WRITE_REG32(pLayerPointers, pLayerPointers->pMdl->Mem_Address + CMD2,
1574 	    PROM);
1575 	pLayerPointers->pMdl->FLAGS &= (~ PROM); /* B16_MASK */
1576 }
1577 
1578 /*
1579  * Disable Receive Broadcast. When set, disables the controller from receiving
1580  * broadcast messages. Used for protocols that do not support broadcast
1581  * addressing, except as a function of multicast.
1582  * DRCVBC is cleared by activation of H_RESET (broadcast messages will be
1583  * received) and is unaffected by the clearing of the RUN bit.
1584  */
1585 static void
1586 mdlReceiveBroadCast(struct LayerPointers *pLayerPointers)
1587 {
1588 	ULONG MappedMemBaseAddress;
1589 
1590 	MappedMemBaseAddress = pLayerPointers->pMdl->Mem_Address;
1591 	WRITE_REG32(pLayerPointers, MappedMemBaseAddress + CMD2, DRCVBC);
1592 	pLayerPointers->pMdl->FLAGS |= DRCVBC;
1593 }
1594 
1595 static void
1596 mdlDisableReceiveBroadCast(struct LayerPointers *pLayerPointers)
1597 {
1598 	ULONG MappedMemBaseAddress;
1599 
1600 	MappedMemBaseAddress = pLayerPointers->pMdl->Mem_Address;
1601 	WRITE_REG32(pLayerPointers, MappedMemBaseAddress + CMD2, VAL2 | DRCVBC);
1602 	pLayerPointers->pMdl->FLAGS &= (~DRCVBC);
1603 }
1604 
1605 static void
1606 mdlEnableMagicPacketWakeUp(struct LayerPointers *pLayerPointers)
1607 {
1608 	WRITE_REG32(pLayerPointers, pLayerPointers->pMdl->Mem_Address + CMD3,
1609 	    VAL1 | MPPLBA);
1610 	WRITE_REG32(pLayerPointers, pLayerPointers->pMdl->Mem_Address + CMD7,
1611 	    VAL0 | MPEN_SW);
1612 }
1613 
1614 /*
1615  * BitMap for add/del the Multicast address Since more than one M/C address
1616  * can map to same bit in the filter matrix, we should maintain the count for
1617  * # of M/C addresses associated with each bit. Only when the bit<->count
1618  * becomes zero, we should go ahead with changing/reseting the bit, else just
1619  * reduce the count associated with each bit and return.
1620  */
1621 static int
1622 mdlMulticastBitMapping(struct LayerPointers *pLayerPointers,
1623     unsigned char *MulticastAddress, int FLAG)
1624 {
1625 	unsigned char HashCode, FilterByte;
1626 	int j = 0, BitMapIndex = 0;
1627 	unsigned int CRCValue = 0;
1628 
1629 	HashCode = 0;
1630 	/* Calculate the Bit Map location for the given Address */
1631 	CRCValue = mdlCalculateCRC(ETH_LENGTH_OF_ADDRESS, MulticastAddress);
1632 	for (j = 0; j < 6; j++) {
1633 		HashCode = (HashCode << 1) +
1634 		    (((unsigned char)CRCValue >> j) & 0x01);
1635 	}
1636 
1637 	/*
1638 	 * Bits 3-5 of HashCode point to byte in address filter.
1639 	 * Bits 0-2 point to bit within that byte.
1640 	 */
1641 	FilterByte = HashCode & 0x38;
1642 	FilterByte = FilterByte >> 3;
1643 	BitMapIndex =  (int)FilterByte * 8 + (HashCode & 0x7);
1644 
1645 	if (FLAG == DELETE_MULTICAST) {
1646 		if ((pLayerPointers->pMdl->MulticastBitMapArray[BitMapIndex]
1647 		    == 0) || (--pLayerPointers->pMdl->MulticastBitMapArray
1648 		    [BitMapIndex] == 0)) {
1649 			return (0);
1650 		} else {
1651 			return (-1);
1652 		}
1653 	}
1654 
1655 	if (FLAG == ADD_MULTICAST) {
1656 		if (pLayerPointers->pMdl
1657 		    ->MulticastBitMapArray[BitMapIndex] > 0) {
1658 			pLayerPointers->pMdl
1659 			    ->MulticastBitMapArray[BitMapIndex]++;
1660 			return (-1);
1661 		} else if (pLayerPointers->pMdl
1662 		    ->MulticastBitMapArray[BitMapIndex] == 0) {
1663 			pLayerPointers->pMdl
1664 			    ->MulticastBitMapArray[BitMapIndex]++;
1665 			return (0);
1666 		}
1667 	}
1668 	return (0);
1669 }
1670 
1671 /*
1672  * Set Interrupt Coalescing registers:
1673  *	To reduce the host CPU interrupt service overhead the network
1674  *	controller can be programmed to postpone the interrupt to the host
1675  *	CPU until either a programmable number of receive or transmit
1676  *	interrupt events have occurred or a programmable amount of time has
1677  *	elapsed since the first interrupt event occurred.
1678  */
1679 void
1680 SetIntrCoalesc(struct LayerPointers *pLayerPointers, boolean_t on)
1681 {
1682 	long MemBaseAddress = pLayerPointers->pMdl->Mem_Address;
1683 	struct mdl *pMdl = 0;
1684 	unsigned int timeout, event_count;
1685 
1686 	pMdl = (struct mdl *)(pLayerPointers->pMdl);
1687 
1688 	if (on) {
1689 		/* Set Rx Interrupt Coalescing */
1690 		timeout = pLayerPointers->pMdl->rx_intrcoalesc_time;
1691 		event_count = 0;
1692 		event_count |= pLayerPointers->pMdl->rx_intrcoalesc_events;
1693 		if (timeout > 0x7ff) {
1694 			timeout = 0x7ff;
1695 		}
1696 		if (event_count > 0x1f) {
1697 			event_count = 0x1f;
1698 		}
1699 
1700 		event_count =  event_count << 16;
1701 		WRITE_REG32(pLayerPointers, MemBaseAddress + DLY_INT_A,
1702 		    DLY_INT_A_R0 | event_count | timeout);
1703 
1704 	} else {
1705 		/* Disable Software Timer Interrupt */
1706 		WRITE_REG32(pLayerPointers, MemBaseAddress + STVAL, 0);
1707 		WRITE_REG32(pLayerPointers, pMdl->Mem_Address + INTEN0,
1708 		    STINTEN);
1709 
1710 		WRITE_REG32(pLayerPointers, MemBaseAddress + DLY_INT_A, 0);
1711 		WRITE_REG32(pLayerPointers, MemBaseAddress + DLY_INT_B, 0);
1712 	}
1713 }
1714 
1715 void
1716 mdlSendPause(struct LayerPointers *pLayerPointers)
1717 {
1718 	WRITE_REG32(pLayerPointers, pLayerPointers->pMdl->Mem_Address
1719 	    + FLOW_CONTROL, VAL2 | FIXP | FCCMD | 0x200);
1720 }
1721 
1722 /* Reset all Tx descriptors and Tx buffers */
1723 void
1724 milResetTxQ(struct LayerPointers *pLayerPointers)
1725 {
1726 	struct nonphysical *pNonphysical = pLayerPointers->pMil->pNonphysical;
1727 	int i;
1728 
1729 	pNonphysical->TxDescQRead = pNonphysical->TxDescQStart;
1730 	pNonphysical->TxDescQWrite = pNonphysical->TxDescQStart;
1731 
1732 	/* Clean all Tx descriptors */
1733 	for (i = 0; i < TX_RING_SIZE; i++) {
1734 		pNonphysical->TxDescQWrite->Tx_OWN = 0;
1735 		pNonphysical->TxDescQWrite->Tx_SOP = 0;
1736 		pNonphysical->TxDescQWrite->Tx_EOP = 0;
1737 		pNonphysical->TxDescQWrite++;
1738 	}
1739 	pNonphysical->TxDescQWrite = pNonphysical->TxDescQStart;
1740 
1741 	/* Re-init Tx Buffers */
1742 	pLayerPointers->pOdl->tx_buf.free =
1743 	    pLayerPointers->pOdl->tx_buf.msg_buf;
1744 	pLayerPointers->pOdl->tx_buf.next =
1745 	    pLayerPointers->pOdl->tx_buf.msg_buf;
1746 	pLayerPointers->pOdl->tx_buf.curr =
1747 	    pLayerPointers->pOdl->tx_buf.msg_buf;
1748 }
1749 
1750 /*
1751  *	Initialises the data used in Mil.
1752  */
1753 void
1754 milInitGlbds(struct LayerPointers *pLayerPointers)
1755 {
1756 	pLayerPointers->pMil->name = DEVICE_CHIPNAME;
1757 
1758 	mdlInitGlbds(pLayerPointers);
1759 }
1760 
1761 /*
1762  *	Purpose  :
1763  *		Initialises the RxBufDescQ with the packet pointer and physical
1764  *		address filled in the FreeQ.
1765  *
1766  *	Arguments :
1767  *		pLayerPointers
1768  *			Pointer to the Adapter structure.
1769  */
1770 void
1771 milInitRxQ(struct LayerPointers *pLayerPointers)
1772 {
1773 	struct mil *pMil = pLayerPointers->pMil;
1774 	struct nonphysical *pNonphysical = pMil->pNonphysical;
1775 	int i;
1776 
1777 	pNonphysical->RxBufDescQRead->descriptor = pMil->Rx_desc;
1778 	pNonphysical->RxBufDescQStart->descriptor = pMil->Rx_desc;
1779 	pNonphysical->RxBufDescQEnd->descriptor =
1780 	    &(pMil->Rx_desc[pMil->RxRingSize - 1]);
1781 
1782 	pNonphysical->RxBufDescQRead->USpaceMap = pMil->USpaceMapArray;
1783 	pNonphysical->RxBufDescQStart->USpaceMap = pMil->USpaceMapArray;
1784 	pNonphysical->RxBufDescQEnd->USpaceMap =
1785 	    &(pMil->USpaceMapArray[pMil->RxRingSize - 1]);
1786 
1787 	/* Initialize the adapter rx descriptor Q and rx buffer Q */
1788 	for (i = 0; i < pMil->RxRingSize; i++) {
1789 		pNonphysical->RxBufDescQRead->descriptor->Rx_BCNT
1790 		    = (unsigned)pMil->RxBufSize;
1791 
1792 		*(pNonphysical->RxBufDescQRead->USpaceMap) =
1793 		    (long)(pLayerPointers->pOdl->rx_buf.next->vir_addr);
1794 
1795 		pNonphysical->RxBufDescQRead->descriptor->Rx_Base_Addr
1796 		    = pLayerPointers->pOdl->rx_buf.next->phy_addr;
1797 
1798 		pNonphysical->RxBufDescQRead->descriptor->Rx_OWN = 1;
1799 		pNonphysical->RxBufDescQRead->descriptor++;
1800 		pNonphysical->RxBufDescQRead->USpaceMap++;
1801 		pLayerPointers->pOdl->rx_buf.next =
1802 		    NEXT(pLayerPointers->pOdl->rx_buf, next);
1803 	}
1804 
1805 	pNonphysical->RxBufDescQRead->descriptor =
1806 	    pNonphysical->RxBufDescQStart->descriptor;
1807 	pNonphysical->RxBufDescQRead->USpaceMap =
1808 	    pNonphysical->RxBufDescQStart->USpaceMap;
1809 	pLayerPointers->pOdl->rx_buf.next =
1810 	    pLayerPointers->pOdl->rx_buf.msg_buf;
1811 }
1812 
1813 /*
1814  *	Purpose		:
1815  *		This array is filled with the size of the structure & its
1816  *		pointer for freeing purposes.
1817  *
1818  *	Arguments	:
1819  *		pLayerPointers
1820  *			Pointer to the adapter structure.
1821  *		mem_free_array
1822  *			Pointer to the array that holds the data required
1823  *			for freeing.
1824  */
1825 void
1826 milFreeResources(struct LayerPointers *pLayerPointers, ULONG *mem_free_array)
1827 {
1828 	/* 1) For mil structure (pLayerPointers->pMil) */
1829 	/* Type */
1830 	*(mem_free_array) = VIRTUAL;
1831 	/* Size */
1832 	*(++mem_free_array) = sizeof (struct mil);
1833 	/* VA */
1834 	*(++mem_free_array) = (ULONG)pLayerPointers->pMil;
1835 
1836 
1837 	/* 2) For USpaceMapArray queue */
1838 	/* Type */
1839 	*(++mem_free_array) = VIRTUAL;
1840 	/* Size */
1841 	*(++mem_free_array) = pLayerPointers->pMil->RxRingSize *
1842 	    sizeof (unsigned long);
1843 	/* VA */
1844 	*(++mem_free_array) = (ULONG)pLayerPointers->pMil->USpaceMapArray;
1845 
1846 
1847 	/* 3) For non_physical structure */
1848 	/* Type */
1849 	*(++mem_free_array) = VIRTUAL;
1850 	/* Size */
1851 	*(++mem_free_array) =  sizeof (struct nonphysical);
1852 	/* VA */
1853 	*(++mem_free_array) = (ULONG)pLayerPointers->pMil->pNonphysical;
1854 
1855 	/*
1856 	 * 4~6) For four allocation are for abstracting the Rx_Descritor ring
1857 	 */
1858 
1859 	/* 4) Type */
1860 	*(++mem_free_array) = VIRTUAL;
1861 	/* Size */
1862 	*(++mem_free_array) =  sizeof (struct Rx_Buf_Desc);
1863 	/* VA */
1864 	*(++mem_free_array) =
1865 	    (ULONG)pLayerPointers->pMil->pNonphysical->RxBufDescQRead;
1866 
1867 	/* 5) Type */
1868 	*(++mem_free_array) = VIRTUAL;
1869 	/* Size */
1870 	*(++mem_free_array) =  sizeof (struct Rx_Buf_Desc);
1871 	/* VA */
1872 	*(++mem_free_array) =
1873 	    (ULONG)pLayerPointers->pMil->pNonphysical->RxBufDescQStart;
1874 
1875 	/* 6) Type */
1876 	*(++mem_free_array) = VIRTUAL;
1877 	/* Size */
1878 	*(++mem_free_array) =  sizeof (struct Rx_Buf_Desc);
1879 	/* VA */
1880 	*(++mem_free_array) =
1881 	    (ULONG)pLayerPointers->pMil->pNonphysical->RxBufDescQEnd;
1882 
1883 	*(++mem_free_array) = 0;
1884 
1885 	mdlFreeResources(pLayerPointers, mem_free_array);
1886 }
1887 
1888 
1889 
1890 /*
1891  *	Purpose  :
1892  *		This array is filled with the size of the memory required for
1893  *		allocating purposes.
1894  *
1895  *	Arguments :
1896  *		pLayerPointers
1897  *			Pointer to the adapter structure.
1898  *		mem_req_array
1899  *			Pointer to the array that holds the data required for
1900  *			allocating memory.
1901  */
1902 void
1903 milRequestResources(ULONG *mem_req_array)
1904 {
1905 	int RxRingSize;
1906 
1907 	RxRingSize = RX_RING_SIZE;	/* 128 */
1908 
1909 	/* 1) For mil structure (pLayerPointers->pMil) */
1910 	/* Type */
1911 	*mem_req_array   = VIRTUAL;
1912 	/* Size */
1913 	*(++mem_req_array) = sizeof (struct mil);
1914 
1915 	/* 2) For USpaceMapArray queue (pLayerPointers->pMil->USpaceMapArray) */
1916 	/* Type */
1917 	*(++mem_req_array) = VIRTUAL;
1918 	/* Size */
1919 	*(++mem_req_array) = RxRingSize * sizeof (unsigned long);
1920 
1921 
1922 	/* 3) For pNonphysical structure */
1923 	/* Type */
1924 	*(++mem_req_array) = VIRTUAL;
1925 	/* Size */
1926 	*(++mem_req_array) = sizeof (struct nonphysical);
1927 
1928 	/*
1929 	 * 4~6) For four allocation are for abstracting the Rx_Descritor ring
1930 	 */
1931 	/* 4) Type */
1932 	*(++mem_req_array) = VIRTUAL;
1933 	/* Size */
1934 	*(++mem_req_array) = sizeof (struct Rx_Buf_Desc);
1935 
1936 	/* 5) Type */
1937 	*(++mem_req_array) = VIRTUAL;
1938 	/* Size */
1939 	*(++mem_req_array) = sizeof (struct Rx_Buf_Desc);
1940 
1941 	/* 6) Type */
1942 	*(++mem_req_array) = VIRTUAL;
1943 	/* Size */
1944 	*(++mem_req_array) = sizeof (struct Rx_Buf_Desc);
1945 
1946 	*(++mem_req_array) = 0;
1947 
1948 	mdlRequestResources(mem_req_array);
1949 }
1950 
1951 
1952 
1953 /*
1954  *	Purpose  :
1955  *		This array contains the details of the allocated memory. The
1956  *		pointers are taken from the respective locations in the array
1957  *		& assigne appropriately to the respective structures.
1958  *
1959  *	Arguments :
1960  *		pLayerPointers
1961  *			Pointer to the adapter structure.
1962  *		pmem_set_array
1963  *			Pointer to the array that holds the data after required
1964  *			allocating memory.
1965  */
1966 void
1967 milSetResources(struct LayerPointers *pLayerPointers, ULONG *pmem_set_array)
1968 {
1969 	int RxRingSize, TxRingSize;
1970 	int RxBufSize;
1971 	struct mil *pMil;
1972 
1973 	RxRingSize = RX_RING_SIZE;
1974 	TxRingSize = TX_RING_SIZE;
1975 	RxBufSize = RX_BUF_SIZE;
1976 
1977 	/* 1) Set the pointers to the mil pointers */
1978 	/* Type */
1979 	pmem_set_array++;
1980 	/* Size */
1981 	pmem_set_array++;
1982 	pMil = (struct mil *)(*pmem_set_array);
1983 	pLayerPointers->pMil = pMil;
1984 
1985 	pMil->RxRingSize = RxRingSize;
1986 	pMil->TxRingSize = TxRingSize;
1987 	pMil->RxBufSize = RxBufSize;
1988 
1989 	/* 2) Type */
1990 	pmem_set_array++;
1991 	/* Size */
1992 	pmem_set_array++;
1993 	pmem_set_array++;
1994 	pMil->USpaceMapArray = (long *)(*pmem_set_array);
1995 
1996 	/* 3) Set the pointers to the NonPhysical part */
1997 	/* Type */
1998 	pmem_set_array++;
1999 	/* Size */
2000 	pmem_set_array++;
2001 	/* Virtual Addr of NonPhysical */
2002 	pmem_set_array++;
2003 	pMil->pNonphysical =
2004 	    (struct nonphysical *)(*pmem_set_array);
2005 
2006 	/*
2007 	 * 4~6) Following four allocation are for abstracting the Rx_Descritor
2008 	 * Ring.
2009 	 */
2010 	/* 4) Type */
2011 	pmem_set_array++;
2012 	/* Size */
2013 	pmem_set_array++;
2014 	/* Virtual Addr of Abstracted RxDesc */
2015 	pmem_set_array++;
2016 	pMil->pNonphysical->RxBufDescQRead =
2017 	    (struct Rx_Buf_Desc *)(*pmem_set_array);
2018 
2019 	/* 5) Type */
2020 	pmem_set_array++;
2021 	/* Size */
2022 	pmem_set_array++;
2023 	/* Virtual Addr of Abstracted RxDesc */
2024 	pmem_set_array++;
2025 	pMil->pNonphysical->RxBufDescQStart =
2026 	    (struct Rx_Buf_Desc *)(*pmem_set_array);
2027 
2028 	/* 6) Type */
2029 	pmem_set_array++;
2030 	/* Size */
2031 	pmem_set_array++;
2032 	/* Virtual Addr of Abstracted RxDesc */
2033 	pmem_set_array++;
2034 	pMil->pNonphysical->RxBufDescQEnd =
2035 	    (struct Rx_Buf_Desc *)(*pmem_set_array);
2036 
2037 	pmem_set_array++;
2038 
2039 	mdlSetResources(pLayerPointers, pmem_set_array);
2040 }
2041 
2042 /*
2043  *	Purpose  :
2044  *		This routine adds the Multicast addresses to the filter
2045  *
2046  *	Arguments :
2047  *		pLayerPointers
2048  *			Pointer to Layer pointers structure.
2049  *		pucMulticastAddress
2050  *			Pointer to the array of multicast addresses
2051  */
2052 void
2053 mdlAddMulticastAddress(struct LayerPointers *pLayerPointers,
2054     UCHAR *pucMulticastAddress)
2055 {
2056 	unsigned long MODE[10];
2057 	unsigned long tmp1;
2058 	unsigned long tmp2;
2059 
2060 	if (mdlMulticastBitMapping(pLayerPointers, pucMulticastAddress,
2061 	    ADD_MULTICAST) != 0)
2062 		return;
2063 
2064 	tmp2 = SET_SINGLE_MULTICAST;
2065 	MODE[0] = (unsigned long)tmp2;
2066 	MODE[1] = 1;
2067 	tmp1 = (unsigned long)pucMulticastAddress;
2068 	MODE[2] = tmp1;
2069 	MODE[3] = ENABLE_MULTICAST;
2070 	MODE[4] = 0;
2071 	mdlChangeFilter(pLayerPointers, (unsigned long *)MODE);
2072 }
2073 
2074 
2075 /*
2076  *	Purpose  :
2077  *		This routine deletes the Multicast addresses requested by OS.
2078  *
2079  *	Arguments :
2080  *		pLayerPointers
2081  *			Pointer to Layer pointers structure.
2082  *		pucMulticastAddress
2083  *			Pointer to the array of multicast addresses
2084  */
2085 void
2086 mdlDeleteMulticastAddress(struct LayerPointers *pLayerPointers,
2087     UCHAR *pucMulticastAddress)
2088 {
2089 	unsigned long MODE[10];
2090 	unsigned long tmp;
2091 
2092 	if (mdlMulticastBitMapping(pLayerPointers, pucMulticastAddress,
2093 	    DELETE_MULTICAST) != 0)
2094 		return;
2095 
2096 	MODE[0] = UNSET_SINGLE_MULTICAST;
2097 	MODE[1] = 1;
2098 	tmp = (unsigned long)pucMulticastAddress;
2099 	MODE[2] = tmp;
2100 	MODE[3] = ENABLE_MULTICAST;
2101 	MODE[4] = 0;
2102 	mdlChangeFilter(pLayerPointers, (unsigned long *)MODE);
2103 }
2104 
2105 /*
2106  *	Purpose  :
2107  *		Calculates the CRC value over the input number of bytes.
2108  *
2109  *	Arguments :
2110  *		NumberOfBytes
2111  *			The number of bytes in the input.
2112  *		Input
2113  *			An input "string" to calculate a CRC over.
2114  */
2115 static unsigned int
2116 mdlCalculateCRC(unsigned int NumberOfBytes, unsigned char *Input)
2117 {
2118 	const unsigned int POLY = 0x04c11db7;
2119 	unsigned int CRCValue = 0xffffffff;
2120 	unsigned int CurrentBit, CurrentCRCHigh;
2121 	unsigned char CurrentByte;
2122 
2123 	for (; NumberOfBytes; NumberOfBytes--) {
2124 		CurrentByte = *Input;
2125 		Input++;
2126 
2127 		for (CurrentBit = 8; CurrentBit; CurrentBit--) {
2128 			CurrentCRCHigh = CRCValue >> 31;
2129 			CRCValue <<= 1;
2130 
2131 			if (CurrentCRCHigh ^ (CurrentByte & 0x01)) {
2132 				CRCValue ^= POLY;
2133 				CRCValue |= 0x00000001;
2134 			}
2135 			CurrentByte >>= 1;
2136 		}
2137 	}
2138 	return (CRCValue);
2139 }
2140 
2141 void
2142 mdlRxFastSuspend(struct LayerPointers *pLayerPointers)
2143 {
2144 	WRITE_REG32(pLayerPointers, pLayerPointers->pMdl->Mem_Address + CMD0,
2145 	    VAL0 | RX_FAST_SPND);
2146 }
2147 
2148 void
2149 mdlRxFastSuspendClear(struct LayerPointers *pLayerPointers)
2150 {
2151 	WRITE_REG32(pLayerPointers, pLayerPointers->pMdl->Mem_Address + CMD0,
2152 	    RX_FAST_SPND);
2153 }
2154