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