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