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