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