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