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