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