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