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