2 * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
3 * Use is subject to license terms.
6 #pragma ident "%Z%%M% %I% %E% SMI"
9 * Copyright (c) 2001-2006 Advanced Micro Devices, Inc. All rights reserved.
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions are met:
14 * + Redistributions of source code must retain the above copyright notice,
15 * + this list of conditions and the following disclaimer.
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.
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.
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.
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.
56 #include <sys/types.h>
57 #include <sys/cmn_err.h>
58 #include <sys/debug.h>
60 #include <sys/sunddi.h>
61 #include "amd8111s_hw.h"
62 #include "amd8111s_main.h"
65 #pragma inline(mdlTransmit)
66 #pragma inline(mdlReceive)
68 #pragma inline(mdlReadInterrupt)
69 #pragma inline(mdlEnableInterrupt)
70 #pragma inline(mdlDisableInterrupt)
73 static void mdlEnableMagicPacketWakeUp(struct LayerPointers
*);
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 *);
81 static int mdlMulticastBitMapping(struct LayerPointers
*, unsigned char *, int);
83 static unsigned int mdlCalculateCRC(unsigned int, unsigned char *);
85 static void mdlChangeFilter(struct LayerPointers
*, unsigned long *);
86 static void mdlReceiveBroadCast(struct LayerPointers
*);
87 static void mdlDisableReceiveBroadCast(struct LayerPointers
*);
89 static void mdlRequestResources(ULONG
*);
90 static void mdlSetResources(struct LayerPointers
*, ULONG
*);
91 static void mdlFreeResources(struct LayerPointers
*, ULONG
*);
94 * Initialises the data used in Mdl.
97 mdlInitGlbds(struct LayerPointers
*pLayerPointers
)
99 struct mdl
*pMdl
= pLayerPointers
->pMdl
;
101 /* Disable Rx and Tx. */
102 pMdl
->init_blk
->MODE
= 0x0000;
104 /* Set Interrupt Delay Parameters */
105 pMdl
->IntrCoalescFlag
= 1;
106 pMdl
->rx_intrcoalesc_time
= 0xC8; /* 200 */
107 pMdl
->rx_intrcoalesc_events
= 5;
111 mdlPHYAutoNegotiation(struct LayerPointers
*pLayerPointers
, unsigned int type
)
114 struct mdl
*pMdl
= pLayerPointers
->pMdl
;
116 /* PHY auto negotiation or force speed/duplex */
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);
124 * Enable Autonegotiation the Phy now
125 * XPHYANE(eXternal PHY Auto Negotiation Enable)
127 WRITE_REG32(pLayerPointers
, pMdl
->Mem_Address
+ CTRL2
,
130 /* EN_PMGR: Enable the Port Manager */
131 WRITE_REG32(pLayerPointers
, pMdl
->Mem_Address
+ CMD3
,
134 drv_usecwait(500000);
137 pMdl
->FullDuplex
= B_TRUE
;
141 case PHY_FORCE_HD_100
: /* 100Mbps HD */
142 WRITE_REG32(pLayerPointers
, pMdl
->Mem_Address
+ CMD3
, EN_PMGR
);
144 /* Force 100 Mbps, half duplex */
146 WRITE_REG32(pLayerPointers
, pMdl
->Mem_Address
+ CTRL2
, iData
);
148 WRITE_REG32(pLayerPointers
, pMdl
->Mem_Address
+ CMD3
,
151 drv_usecwait(500000);
154 pMdl
->FullDuplex
= B_FALSE
;
158 case PHY_FORCE_FD_100
: /* 100Mbps FD */
159 WRITE_REG32(pLayerPointers
, pMdl
->Mem_Address
+ CMD3
, EN_PMGR
);
161 /* Force 100 Mbps, full duplex */
162 iData
|= (XPHYSP
| XPHYFD
);
163 WRITE_REG32(pLayerPointers
, pMdl
->Mem_Address
+ CTRL2
, iData
);
165 WRITE_REG32(pLayerPointers
, pMdl
->Mem_Address
+ CMD3
,
168 drv_usecwait(500000);
171 pMdl
->FullDuplex
= B_TRUE
;
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
,
182 drv_usecwait(500000);
185 pMdl
->FullDuplex
= B_FALSE
;
189 case PHY_FORCE_FD_10
: /* 10Mbps FD */
190 WRITE_REG32(pLayerPointers
, pMdl
->Mem_Address
+ CMD3
, EN_PMGR
);
193 WRITE_REG32(pLayerPointers
, pMdl
->Mem_Address
+ CTRL2
, iData
);
195 WRITE_REG32(pLayerPointers
, pMdl
->Mem_Address
+ CMD3
,
198 drv_usecwait(500000);
201 pMdl
->FullDuplex
= B_TRUE
;
208 * Clear HW configuration.
211 mdlClearHWConfig(struct LayerPointers
*pLayerPointers
)
214 * Before the network controller is ready for operation,
215 * several registers must be initialized.
218 int JumboFlag
= JUMBO_DISABLED
;
219 ULONG MemBaseAddress
;
221 MemBaseAddress
= pLayerPointers
->pMdl
->Mem_Address
;
223 /* AUTOPOLL0 Register */
224 WRITE_REG16(pLayerPointers
, MemBaseAddress
+ AUTOPOLL0
, 0x8101);
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);
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);
239 /* Clear CMD0 / CMD2 */
240 WRITE_REG32(pLayerPointers
, MemBaseAddress
+ CMD0
, 0x000F0F7F);
241 WRITE_REG32(pLayerPointers
, MemBaseAddress
+ CMD2
, 0x3F7F3F7F);
243 /* Enable Port Management */
244 WRITE_REG32(pLayerPointers
, MemBaseAddress
+ CMD3
, VAL1
| EN_PMGR
);
247 WRITE_REG32(pLayerPointers
, MemBaseAddress
+ CMD7
, 0x1B);
250 WRITE_REG32(pLayerPointers
, MemBaseAddress
+ CTRL1
, XMTSP_MASK
);
252 /* Clear DLY_INT_A/B */
253 WRITE_REG32(pLayerPointers
, MemBaseAddress
+ DLY_INT_A
, 0);
254 WRITE_REG32(pLayerPointers
, MemBaseAddress
+ DLY_INT_B
, 0);
256 /* Clear FLOW_CONTROL */
257 WRITE_REG32(pLayerPointers
, MemBaseAddress
+ FLOW_CONTROL
, 0);
260 data32
= READ_REG32(pLayerPointers
, MemBaseAddress
+ INT0
);
261 WRITE_REG32(pLayerPointers
, MemBaseAddress
+ INT0
, data32
);
264 WRITE_REG32(pLayerPointers
, MemBaseAddress
+ STVAL
, 0);
267 WRITE_REG32(pLayerPointers
, MemBaseAddress
+ INTEN0
, 0x1F7F7F1F);
270 WRITE_REG32(pLayerPointers
, MemBaseAddress
+ LADRF1
, 0);
271 WRITE_REG32(pLayerPointers
, MemBaseAddress
+ LADRF1
+ 4, 0);
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);
279 /* Set RCV_RING_CFG */
280 WRITE_REG16(pLayerPointers
, MemBaseAddress
+ RCV_RING_CFG
, 1);
282 /* SRAM_SIZE & SRAM_BOUNDARY register combined */
283 if (JumboFlag
== JUMBO_ENABLED
) {
284 WRITE_REG32(pLayerPointers
, MemBaseAddress
+ SRAM_SIZE
,
287 WRITE_REG32(pLayerPointers
, MemBaseAddress
+ SRAM_SIZE
,
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);
297 /* Clear XMT_RING_LIMIT */
298 WRITE_REG32(pLayerPointers
, MemBaseAddress
+ XMT_RING_LIMIT
, 0);
300 WRITE_REG16(pLayerPointers
, MemBaseAddress
+ MIB_ADDR
, MIB_CLEAR
);
304 mdlReadMib(struct LayerPointers
*pLayerPointers
, char MIB_COUNTER
)
308 unsigned long mmio
= pLayerPointers
->pMdl
->Mem_Address
;
310 WRITE_REG16(pLayerPointers
, mmio
+ MIB_ADDR
, MIB_RD_CMD
| MIB_COUNTER
);
312 status
= READ_REG16(pLayerPointers
, mmio
+ MIB_ADDR
);
313 } while ((status
& MIB_CMD_ACTIVE
));
315 data
= READ_REG32(pLayerPointers
, mmio
+ MIB_DATA
);
319 /* Return 1 on success, return 0 on fail */
321 mdlReadPHY(struct LayerPointers
*pLayerPointers
, unsigned char phyid
,
322 unsigned char regaddr
, unsigned int *value
)
324 unsigned int status
, data
, count
;
325 unsigned long mmio
= pLayerPointers
->pMdl
->Mem_Address
;
329 status
= READ_REG16(pLayerPointers
, mmio
+ PHY_ACCESS
);
332 } while ((status
& PHY_CMD_ACTIVE
) & (count
< PHY_MAX_RETRY
));
334 if (count
== PHY_MAX_RETRY
) {
338 data
= ((regaddr
& 0x1f) << 16) | ((phyid
& 0x1f) << 21) | PHY_RD_CMD
;
339 WRITE_REG32(pLayerPointers
, mmio
+ PHY_ACCESS
, data
);
341 status
= READ_REG16(pLayerPointers
, mmio
+ PHY_ACCESS
);
344 } while ((status
& PHY_CMD_ACTIVE
) & (count
< PHY_MAX_RETRY
));
346 if ((count
== PHY_MAX_RETRY
) || (status
& PHY_RD_ERR
)) {
350 *value
= status
& 0xffff;
355 mdlGetPHYID(struct LayerPointers
*pLayerPointers
)
357 unsigned int id1
, id2
, i
;
358 for (i
= 1; i
< 32; i
++) {
359 if (mdlReadPHY(pLayerPointers
, i
, MII_PHYSID1
, &id1
) == 0)
361 if (mdlReadPHY(pLayerPointers
, i
, MII_PHYSID2
, &id2
) == 0)
363 if ((id1
!= 0xffff) & (id2
!= 0xffff)) {
364 pLayerPointers
->pMdl
->phy_id
= i
;
370 /* Return 1 on success, return 0 on fail */
372 mdlWritePHY(struct LayerPointers
*pLayerPointers
, unsigned char phyid
,
373 unsigned char regaddr
, unsigned int value
)
375 unsigned int status
, data
, count
;
376 unsigned long mmio
= pLayerPointers
->pMdl
->Mem_Address
;
380 status
= READ_REG16(pLayerPointers
, mmio
+ PHY_ACCESS
);
383 } while ((status
& PHY_CMD_ACTIVE
) & (count
< PHY_MAX_RETRY
));
385 if (count
== PHY_MAX_RETRY
) {
389 data
= ((regaddr
& 0x1f) << 16) | ((phyid
& 0x1f) << 21) |
390 (value
& 0xffff) | PHY_WR_CMD
;
391 WRITE_REG32(pLayerPointers
, mmio
+ PHY_ACCESS
, data
);
394 status
= READ_REG16(pLayerPointers
, mmio
+ PHY_ACCESS
);
397 } while ((status
& PHY_CMD_ACTIVE
) & (count
< PHY_MAX_RETRY
));
399 if ((count
== PHY_MAX_RETRY
) && (status
& PHY_RD_ERR
)) {
407 * To Send the packet.
410 mdlTransmit(struct LayerPointers
*pLayerPointers
)
412 WRITE_REG32(pLayerPointers
, pLayerPointers
->pMdl
->Mem_Address
+ CMD0
,
417 * To Receive a packet.
420 mdlReceive(struct LayerPointers
*pLayerPointers
)
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.
427 WRITE_REG32(pLayerPointers
, pLayerPointers
->pMdl
->Mem_Address
+ CMD0
,
432 * Read the NIC interrupt.
435 * the value of interrupt causes register
438 mdlReadInterrupt(struct LayerPointers
*pLayerPointers
)
441 struct mdl
*pMdl
= 0;
443 pMdl
= (struct mdl
*)(pLayerPointers
->pMdl
);
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.
453 /* Read interrupt status */
454 nINT0
= READ_REG32(pLayerPointers
, pMdl
->Mem_Address
+ INT0
);
456 /* Process all the INT event until INTR bit is clear. */
457 WRITE_REG32(pLayerPointers
, pMdl
->Mem_Address
+ INT0
, nINT0
);
462 mdlHWReset(struct LayerPointers
*pLayerPointers
)
464 struct mdl
*pMdl
= pLayerPointers
->pMdl
;
465 unsigned int ulData
, i
= 0;
466 int JumboFlag
= JUMBO_DISABLED
;
467 ULONG Mem_Address
= pMdl
->Mem_Address
;
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.
475 mdlStopChip(pLayerPointers
);
479 * MAC Physical Address register. All bits in this register are
480 * restored to default values when the RST pin is asserted.
482 for (i
= 0; i
< ETH_LENGTH_OF_ADDRESS
; i
++) {
483 WRITE_REG8(pLayerPointers
, pMdl
->Mem_Address
+ PADR
+ i
,
487 /* Set RCV_RING_CFG */
489 if (JumboFlag
== JUMBO_ENABLED
) {
490 WRITE_REG32(pLayerPointers
, pMdl
->Mem_Address
+ CMD2
,
491 VAL0
| APAD_XMT
| REX_RTRY
| VAL1
| DXMTFCS
| RPA
| VAL2
);
493 WRITE_REG32(pLayerPointers
, pMdl
->Mem_Address
+ CMD3
,
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.
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.
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).
511 WRITE_REG32(pLayerPointers
, pMdl
->Mem_Address
+ CMD2
,
512 VAL0
| APAD_XMT
| REX_RTRY
| REX_UFLO
| VAL1
| DXMTFCS
513 | ASTRIP_RCV
| RPA
| VAL2
);
516 /* Transmit Start Point setting (csr80) */
517 ulData
= READ_REG32(pLayerPointers
, Mem_Address
+ CTRL1
);
518 ulData
&= ~XMTSP_MASK
;
520 WRITE_REG32(pLayerPointers
, pMdl
->Mem_Address
+ CTRL1
,
523 WRITE_REG32(pLayerPointers
, pMdl
->Mem_Address
+ CMD2
, PROM
);
525 mdlPHYAutoNegotiation(pLayerPointers
, pMdl
->External_Phy
);
527 pMdl
->IpgValue
= MIN_IPG_DEFAULT
;
528 /* Set the IPG value */
529 WRITE_REG16(pLayerPointers
, pMdl
->Mem_Address
+ IFS
,
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
|
538 SPNDINTEN
| MPINTEN
| SINTEN
| LCINTEN
);
540 /* Enable Following Interrupt */
541 WRITE_REG32(pLayerPointers
, pMdl
->Mem_Address
+ INTEN0
,
544 /* Base Address of Transmit Descriptor Ring 0. */
545 WRITE_REG32(pLayerPointers
, pMdl
->Mem_Address
+ XMT_RING_BASE_ADDR0
,
546 pMdl
->init_blk
->TDRA
);
548 /* Base Address of Receive Descriptor Ring. */
549 WRITE_REG32(pLayerPointers
, pMdl
->Mem_Address
+ RCV_RING_BASE_ADDR0
,
550 pMdl
->init_blk
->RDRA
);
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
);
557 * Receive Descriptor Ring Length. All bits in this register are
558 * restored to default values when the RST pin is asserted.
560 WRITE_REG16(pLayerPointers
, pMdl
->Mem_Address
+ RCV_RING_LEN0
,
561 (unsigned short)pLayerPointers
->pMdl
->RxRingSize
);
563 if (pLayerPointers
->pMdl
->IntrCoalescFlag
) {
564 SetIntrCoalesc(pLayerPointers
, B_TRUE
);
568 mdlStartChip(pLayerPointers
);
572 * Perform the open oerations on the adapter.
575 mdlOpen(struct LayerPointers
*pLayerPointers
)
578 struct mdl
*pMdl
= pLayerPointers
->pMdl
;
580 /* Get Mac address */
582 for (i
= 0; i
< 6; i
++) {
583 pMdl
->Mac
[i
] = READ_REG8(pLayerPointers
,
584 pMdl
->Mem_Address
+ PADR
+ i
);
588 for (i
= 0; i
< 6; i
++) {
593 /* Initialize the hardware */
594 mdlClearHWConfig(pLayerPointers
);
595 mdlGetPHYID(pLayerPointers
);
600 mdlGetMacAddress(struct LayerPointers
*pLayerPointers
,
601 unsigned char *macAddress
)
603 struct mdl
*pMdl
= pLayerPointers
->pMdl
;
606 for (i
= 0; i
< 6; i
++) {
607 macAddress
[i
] = pMdl
->Mac
[i
] = READ_REG8(pLayerPointers
,
608 pMdl
->Mem_Address
+ PADR
+ i
);
615 mdlSetMacAddress(struct LayerPointers
*pLayerPointers
,
616 unsigned char *macAddress
)
619 struct mdl
*pMdl
= 0;
621 pMdl
= (struct mdl
*)(pLayerPointers
->pMdl
);
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];
632 * MAC Physical Address register. All bits in this register are
633 * restored to default values when the RST pin is asserted.
635 for (i
= 0; i
< ETH_LENGTH_OF_ADDRESS
; i
++) {
636 WRITE_REG8(pLayerPointers
, pMdl
->Mem_Address
+ PADR
+ i
,
642 * This array is filled with the size of the memory required for
643 * allocating purposes.
646 mdlRequestResources(ULONG
*mem_req_array
)
648 /* 1) For mdl structure */
649 *mem_req_array
= VIRTUAL
; /* Type */
650 *(++mem_req_array
) = sizeof (struct mdl
); /* Size */
652 /* 2) For PMR PtrList array (PMR_ptrList) */
653 *(++mem_req_array
) = VIRTUAL
; /* Type */
655 *(++mem_req_array
) = sizeof (unsigned int) * (MAX_ALLOWED_PATTERNS
+ 2);
657 /* 3) For PMR Pattern List array (PatternList) */
658 *(++mem_req_array
) = VIRTUAL
; /* Type */
660 *(++mem_req_array
) = sizeof (unsigned char) * (MAX_PATTERNS
+ 2);
662 /* 4) For pmr PatternLength array (PatternLength) */
663 *(++mem_req_array
) = VIRTUAL
; /* Type */
665 *(++mem_req_array
) = sizeof (unsigned int) * (MAX_ALLOWED_PATTERNS
+ 2);
668 * 5) For the init_block (init_blk)
670 *(++mem_req_array
) = VIRTUAL
;
671 *(++mem_req_array
) = sizeof (struct init_block
);
673 *(++mem_req_array
) = 0;
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.
686 * Pointer to the adapter structure.
688 * Pointer to the array that holds the data after required
692 mdlSetResources(struct LayerPointers
*pLayerPointers
, ULONG
*pmem_set_array
)
694 struct mdl
*pMdl
= 0;
696 /* 1) For mdl structure */
697 pmem_set_array
++; /* Type */
698 pmem_set_array
++; /* Size */
699 pLayerPointers
->pMdl
= (struct mdl
*)(*pmem_set_array
);
701 pMdl
= (struct mdl
*)(pLayerPointers
->pMdl
);
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
;
709 * Default values that would be used if it does not enable
710 * enable dynamic ipg.
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
);
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
);
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
);
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
);
737 pMdl
->init_blk
->TLEN
= pMdl
->TxRingLenBits
;
738 pMdl
->init_blk
->RLEN
= pMdl
->RxRingLenBits
;
747 * This array is filled with the size of the structure & its
748 * pointer for freeing purposes.
752 * Pointer to the adapter structure.
754 * Pointer to the array that holds the data required for
758 mdlFreeResources(struct LayerPointers
*pLayerPointers
, ULONG
*pmem_free_array
)
760 struct mdl
*pMdl
= 0;
762 pMdl
= (struct mdl
*)(pLayerPointers
->pMdl
);
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 */
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 */
775 /* 3) For pattern list */
776 *(++pmem_free_array
) = VIRTUAL
; /* Type */
778 *(++pmem_free_array
) = sizeof (unsigned char) * (MAX_PATTERNS
+ 2);
779 *(++pmem_free_array
) = (ULONG
)pMdl
->PatternList
; /* VA */
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 */
787 /* 5) For init_blk structure */
788 *(++pmem_free_array
) = VIRTUAL
; /* Type */
790 *(++pmem_free_array
) = sizeof (struct init_block
);
791 *(++pmem_free_array
) = (ULONG
)pMdl
->init_blk
; /* VA */
793 *(++pmem_free_array
) = 0;
797 mdlStartChip(struct LayerPointers
*pLayerPointers
)
799 /* Enable Receiver */
800 WRITE_REG32(pLayerPointers
, pLayerPointers
->pMdl
->Mem_Address
+ CMD0
,
803 /* Enable Interrupt and Start processing descriptor, Rx and Tx */
804 WRITE_REG32(pLayerPointers
, pLayerPointers
->pMdl
->Mem_Address
+ CMD0
,
805 VAL0
| INTREN
| RUN
);
812 mdlStopChip(struct LayerPointers
*pLayerPointers
)
815 struct mdl
*pMdl
= 0;
817 pMdl
= (struct mdl
*)(pLayerPointers
->pMdl
);
819 /* Disable interrupt */
820 WRITE_REG32(pLayerPointers
, pMdl
->Mem_Address
+ CMD0
, INTREN
);
822 /* Clear interrupt status */
823 nINT0
= READ_REG32(pLayerPointers
, pMdl
->Mem_Address
+ INT0
);
824 WRITE_REG32(pLayerPointers
, pMdl
->Mem_Address
+ INT0
, nINT0
);
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.
836 WRITE_REG32(pLayerPointers
, pMdl
->Mem_Address
+ CMD0
, RUN
);
840 * Enables the interrupt.
843 mdlEnableInterrupt(struct LayerPointers
*pLayerPointers
)
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.
851 WRITE_REG32(pLayerPointers
, pLayerPointers
->pMdl
->Mem_Address
+ CMD0
,
855 #ifdef AMD8111S_DEBUG
857 mdlClearInterrupt(struct LayerPointers
*pLayerPointers
)
860 struct mdl
*pMdl
= 0;
862 pMdl
= (struct mdl
*)(pLayerPointers
->pMdl
);
864 /* Clear interrupt status */
865 nINT0
= READ_REG32(pLayerPointers
, pMdl
->Mem_Address
+ INT0
);
866 WRITE_REG32(pLayerPointers
, pMdl
->Mem_Address
+ INT0
, nINT0
);
872 * Disables the interrupt.
875 mdlDisableInterrupt(struct LayerPointers
*pLayerPointers
)
877 /* Disable interrupt */
878 WRITE_REG32(pLayerPointers
,
879 pLayerPointers
->pMdl
->Mem_Address
+ CMD0
, INTREN
);
883 * Reads the link status
886 mdlReadLink(struct LayerPointers
*pLayerPointers
)
888 unsigned int link_status
= 0;
890 link_status
= READ_REG32(pLayerPointers
,
891 pLayerPointers
->pMdl
->Mem_Address
+ STAT0
);
893 if ((link_status
& LINK_STAT
)) {
902 * Adds the wakeup pattern given by the upper layer.
906 * Pointer to the Adapter structure.
908 * The mask for the pattern to be added.
910 * The Pattern to be added.
911 * InfoBuffer_MaskSize
912 * The mask size as specified in the Information Buffer.
914 * The PatternSize as specified in the Information Buffer.
917 mdlAddWakeUpPattern(struct LayerPointers
*pLayerPointers
,
918 unsigned char *PatternMask
, unsigned char *Pattern
,
919 unsigned long InfoBuffer_MaskSize
, unsigned long PatternSize
, int *retval
)
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;
927 int PatternOffset
, SearchForStartOfPattern
= 1;
928 struct mdl
*pMdl
= 0;
930 pMdl
= pLayerPointers
->pMdl
;
932 if (pMdl
->TotalPatterns
>= MAX_ALLOWED_PATTERNS
) {
937 MaskSize
= PatternSize
/4 + (PatternSize
%4 ? 1 : 0);
939 ReqSize
= PatternSize
+ MaskSize
;
940 if (((PatternSize
+MaskSize
)%5) != 0)
941 ReqSize
+= 5 - ((PatternSize
+MaskSize
)%5);
944 (unsigned long)(MAX_PATTERNS
- pMdl
->PatternList_FreeIndex
)) {
949 if (InfoBuffer_MaskSize
!= PatternSize
/8 + (PatternSize
%8 ? 1 : 0)) {
954 i
= pMdl
->PatternList_FreeIndex
;
956 pMdl
->PMR_PtrList
[pMdl
->TotalPatterns
] = i
;
958 pMdl
->PatternLength
[pMdl
->TotalPatterns
] = (unsigned int)PatternSize
;
960 while (i
< (pMdl
->PatternList_FreeIndex
+ PatternSize
+ MaskSize
)) {
962 byteData
= *PatternMask
;
963 pMdl
->PatternList
[i
++] =
964 (unsigned int)((byteData
& 0x0F) | (Skip
<< 4));
967 pMdl
->PatternList
[i
++] = (unsigned int)
968 (((unsigned)(byteData
& 0xF0) >> 4) | (Skip
<< 4));
973 while ((count
< 5) && (i
<
974 pMdl
->PatternList_FreeIndex
+ PatternSize
+ MaskSize
)) {
977 pMdl
->PatternList
[i
++] = tmpData
;
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;
987 /* Set the EOP bit for the last mask!!! */
988 pMdl
->PatternList
[pMdl
->PatternList_FreeIndex
+ ReqSize
- 5] |= 0x80;
990 for (j
= 0; j
< 8; j
++) {
991 pMdl
->tmpPtrArray
[j
] = 0;
994 /* Zeroing the skip value of all the pattern masks */
996 while (j
< (pMdl
->PatternList_FreeIndex
+ ReqSize
)) {
997 pMdl
->PatternList
[j
] &= 0x8f;
1002 * Scan the whole array & update the start offset of the pattern in the
1003 * PMR and update the skip value.
1011 while (j
< (pMdl
->PatternList_FreeIndex
+ ReqSize
)) {
1013 if (pMdl
->PatternList
[j
] & 0x0f) {
1015 if (SearchForStartOfPattern
== 1) {
1016 SearchForStartOfPattern
= 0;
1017 pMdl
->tmpPtrArray
[i
++] = PatternOffset
;
1018 } else if (pMdl
->PatternList
[j
] & 0x80) {
1019 SearchForStartOfPattern
= 1;
1021 pMdl
->PatternList
[j
] |= (Skip
<< 4);
1029 /* valid pattern.. so update the house keeping info. */
1030 pMdl
->PatternList_FreeIndex
+= (unsigned short)ReqSize
;
1031 pMdl
->TotalPatterns
++;
1038 * Removes the specified wakeup pattern.
1042 * Pointer to the Adapter structure.
1044 * The Pattern to be added.
1046 * The PatternSize as specified in the Information Buffer.
1049 mdlRemoveWakeUpPattern(struct LayerPointers
*pLayerPointers
,
1050 unsigned char *Pattern
, unsigned long PatternSize
, int *retval
)
1052 unsigned long ReqSize
, MaskSize
;
1053 unsigned char tmpData
;
1055 unsigned short Data1
, Data2
, Data3
, Data4
, Data5
, Data6
, Data7
, Data8
;
1056 int PatternMismatch
= 0;
1057 int count
, StartIndex
, index
= 0;
1059 unsigned char Skip
= 0;
1060 struct mdl
*pMdl
= 0;
1061 int PatternOffset
, SearchForStartOfPattern
= 1;
1062 unsigned long tmpPtrArray
[8];
1065 Data1
= Data2
= Data3
= Data4
= Data5
= Data6
= Data7
= Data8
= 0;
1067 pMdl
= (struct mdl
*)(pLayerPointers
->pMdl
);
1069 /* Find the pattern to be removed. */
1070 if (pMdl
->TotalPatterns
== 0) {
1075 MaskSize
= PatternSize
/4 + (PatternSize
%4 ? 1 : 0);
1077 ReqSize
= PatternSize
+ MaskSize
;
1078 if (((PatternSize
+MaskSize
)%5) != 0)
1079 ReqSize
+= 5 - ((PatternSize
+MaskSize
)%5);
1081 count
= pMdl
->TotalPatterns
;
1084 PatternMismatch
= 0;
1085 StartIndex
= pMdl
->PMR_PtrList
[index
];
1087 if (pMdl
->PatternLength
[index
] != PatternSize
) {
1089 PatternMismatch
= 1;
1093 for (i
= StartIndex
; i
< (StartIndex
+ReqSize
); i
++) {
1098 if (pMdl
->PatternList
[i
] != tmpData
) {
1099 PatternMismatch
= 1;
1105 if (PatternMismatch
== 0) {
1106 i
= StartIndex
+ ReqSize
;
1108 /* Pattern found remove it from the arrays */
1109 while (i
< pMdl
->PatternList_FreeIndex
) {
1110 pMdl
->PatternList
[StartIndex
] =
1111 pMdl
->PatternList
[i
];
1116 pMdl
->PatternList_FreeIndex
=
1117 (unsigned short)(StartIndex
);
1119 while (StartIndex
< MAX_PATTERNS
)
1120 pMdl
->PatternList
[StartIndex
++] = 0;
1122 while (index
< (int)pMdl
->TotalPatterns
) {
1123 pMdl
->PMR_PtrList
[index
] =
1124 pMdl
->PMR_PtrList
[index
+1] - ReqSize
;
1126 pMdl
->PatternLength
[index
] =
1127 pMdl
->PatternLength
[index
+1];
1133 while (index
< MAX_ALLOWED_PATTERNS
) {
1134 pMdl
->PMR_PtrList
[index
+1] = 0;
1135 pMdl
->PatternLength
[index
+1] = 0;
1144 if (PatternMismatch
) {
1150 for (j
= 0; j
< 8; j
++) {
1154 /* Zeroing the skip value of all the pattern masks */
1156 while (j
< (pMdl
->PatternList_FreeIndex
)) {
1157 pMdl
->PatternList
[j
] &= 0x8f;
1162 * Scan the whole array & update the start offset of the pattern in the
1163 * PMR and update the skip value.
1170 while (j
< (pMdl
->PatternList_FreeIndex
)) {
1171 if (pMdl
->PatternList
[j
] & 0x0f) {
1174 if (SearchForStartOfPattern
== 1) {
1175 SearchForStartOfPattern
= 0;
1176 tmpPtrArray
[i
++] = PatternOffset
;
1177 } else if (pMdl
->PatternList
[j
] & 0x80) {
1178 SearchForStartOfPattern
= 1;
1180 pMdl
->PatternList
[j
] |= (Skip
<< 4);
1189 /* Write back the arrays to the PMR & lock the pmr */
1190 WRITE_REG32(pLayerPointers
, pMdl
->Mem_Address
+CMD7
, PMAT_MODE
);
1192 /* Write the data & ctrl patterns from the array to the PMR */
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
];
1204 WRITE_REG32(pLayerPointers
,
1205 pMdl
->Mem_Address
+PMAT1
, Data
);
1207 Data
= (unsigned long) ((1<<30) | (offset
<< 16) |
1208 pMdl
->PatternList
[i
+4]);
1210 WRITE_REG32(pLayerPointers
,
1211 pMdl
->Mem_Address
+PMAT0
, Data
);
1216 /* PMR is full !!!! */
1225 /* Valid pattern.. so update the house keeping info. */
1226 pMdl
->TotalPatterns
--;
1228 /* Update the pointer in the PMR */
1229 pMdl
->PatternEnableBit
= 0;
1230 for (i
= 0; i
< pMdl
->TotalPatterns
; i
++) {
1231 pMdl
->PatternEnableBit
|= (0x0001 << i
);
1234 Data1
= Data2
= Data3
= Data4
= Data5
= Data6
= Data7
= Data8
= 0;
1236 switch (pMdl
->TotalPatterns
) {
1238 Data8
= (unsigned short)tmpPtrArray
[7];
1241 Data7
= (unsigned short)tmpPtrArray
[6];
1244 Data6
= (unsigned short)tmpPtrArray
[5];
1247 Data5
= (unsigned short)tmpPtrArray
[4];
1250 Data4
= (unsigned short)tmpPtrArray
[3];
1253 Data3
= (unsigned short)tmpPtrArray
[2];
1256 Data2
= (unsigned short)tmpPtrArray
[1];
1259 Data1
= (unsigned short)tmpPtrArray
[0];
1263 Data
= pMdl
->PatternEnableBit
& 0x0f;
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
);
1269 Data
= (unsigned long) ((1<<30) | Data4
);
1270 WRITE_REG32(pLayerPointers
, pMdl
->Mem_Address
+ PMAT0
, Data
);
1272 /* Updating the pointers 4,5,6 & 7 */
1273 Data
= (unsigned short)((unsigned)(pMdl
->PatternEnableBit
& 0xf0) >> 4);
1275 Data
= (Data7
<< 24 | Data6
<< 16 | Data5
<< 8 | Data
);
1276 WRITE_REG32(pLayerPointers
, pMdl
->Mem_Address
+ PMAT1
, Data
);
1278 Data
= (unsigned long) ((1<<30) | (1<<16) | Data8
);
1279 WRITE_REG32(pLayerPointers
, pMdl
->Mem_Address
+ PMAT0
, Data
);
1281 /* Unlock the PMR */
1282 WRITE_REG32(pLayerPointers
, pMdl
->Mem_Address
+ CMD7
, VAL0
| PMAT_MODE
);
1289 * Checks the control register for the speed and the type of the
1290 * network connection.
1293 mdlGetActiveMediaInfo(struct LayerPointers
*pLayerPointers
)
1296 unsigned long ulData
;
1297 struct mdl
*pMdl
= 0;
1299 pMdl
= (struct mdl
*)(pLayerPointers
->pMdl
);
1301 ulData
= READ_REG32(pLayerPointers
, pMdl
->Mem_Address
+ STAT0
);
1303 switch (ulData
& SPEED_MASK
) {
1315 if (ulData
& FULL_DPLX
) {
1316 pMdl
->FullDuplex
= B_TRUE
;
1318 pMdl
->FullDuplex
= B_FALSE
;
1323 mdlChangeFilter(struct LayerPointers
*pLayerPointers
, unsigned long *ArrayPtr
)
1326 unsigned char *MulticastArray
;
1327 unsigned char *Pattern
, *PatternMask
;
1328 unsigned int InfoBuffer_MaskSize
, PatternSize
;
1330 int NumberOfAddress
, i
;
1331 unsigned int j
, CRCValue
= 0;
1332 unsigned char HashCode
= 0, FilterByte
= 0;
1333 int BitMapIndex
= 0;
1339 case DISABLE_BROADCAST
:
1340 mdlDisableReceiveBroadCast(pLayerPointers
);
1343 case ENABLE_BROADCAST
:
1344 mdlReceiveBroadCast(pLayerPointers
);
1347 case ENABLE_ALL_MULTICAST
:
1348 for (i
= 0; i
< 8; i
++) {
1349 pLayerPointers
->pMdl
->init_blk
->LADRF
[i
] = 0xff;
1351 WRITE_REG64(pLayerPointers
,
1352 (unsigned long)pLayerPointers
->pMdl
1353 ->Mem_Address
+ LADRF1
,
1354 (char *)pLayerPointers
->pMdl
->init_blk
->LADRF
);
1357 case DISABLE_ALL_MULTICAST
:
1358 if (pLayerPointers
->pMdl
->EnableMulticast
== 1) {
1359 for (i
= 0; i
< 8; i
++) {
1360 pLayerPointers
->pMdl
->init_blk
1362 pLayerPointers
->pMdl
->TempLADRF
[i
];
1366 WRITE_REG64(pLayerPointers
,
1367 (unsigned long)pLayerPointers
->pMdl
->Mem_Address
1369 (char *)pLayerPointers
->pMdl
->init_blk
->LADRF
);
1374 NumberOfAddress
= *(++Ptr
);
1375 MulticastArray
= (unsigned char *)(*(++Ptr
));
1376 mdlAddMulticastAddresses(pLayerPointers
,
1377 NumberOfAddress
, MulticastArray
);
1381 case ENABLE_MULTICAST
:
1382 for (i
= 0; i
< 8; i
++) {
1383 pLayerPointers
->pMdl
->init_blk
->LADRF
[i
] =
1384 pLayerPointers
->pMdl
->TempLADRF
[i
];
1386 pLayerPointers
->pMdl
->EnableMulticast
= 1;
1388 WRITE_REG64(pLayerPointers
,
1389 (unsigned long)pLayerPointers
->pMdl
->Mem_Address
1391 (char *)pLayerPointers
->pMdl
->init_blk
->LADRF
);
1394 case DISABLE_MULTICAST
:
1395 for (i
= 0; i
< 8; i
++) {
1396 pLayerPointers
->pMdl
->init_blk
->LADRF
[i
] = 0;
1399 pLayerPointers
->pMdl
->EnableMulticast
= 0;
1401 for (BitMapIndex
= 0; BitMapIndex
<
1402 MULTICAST_BITMAP_ARRAY_SIZE
; BitMapIndex
++)
1403 pLayerPointers
->pMdl
->MulticastBitMapArray
1405 WRITE_REG64(pLayerPointers
,
1406 (unsigned long)pLayerPointers
->pMdl
->Mem_Address
1408 (char *)pLayerPointers
->pMdl
->init_blk
->LADRF
);
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
));
1419 mdlAddWakeUpPattern(pLayerPointers
,
1422 InfoBuffer_MaskSize
,
1427 case REMOVE_WAKE_UP_PATTERN
:
1428 Pattern
= (unsigned char *)(*(++Ptr
));
1429 PatternSize
= *(++Ptr
);
1430 retval
= (int *)(*(++Ptr
));
1431 mdlRemoveWakeUpPattern(pLayerPointers
,
1437 case ENABLE_MAGIC_PACKET_WAKE_UP
:
1438 mdlEnableMagicPacketWakeUp(pLayerPointers
);
1441 case SET_SINGLE_MULTICAST
:
1442 NumberOfAddress
= *(++Ptr
);
1443 MulticastArray
= (unsigned char *)(*(++Ptr
));
1445 for (i
= 0; i
< 8; i
++) {
1446 pLayerPointers
->pMdl
->TempLADRF
[i
] =
1447 pLayerPointers
->pMdl
->init_blk
->LADRF
[i
];
1449 CRCValue
= mdlCalculateCRC(ETH_LENGTH_OF_ADDRESS
,
1451 for (j
= 0; j
< 6; j
++) {
1452 HashCode
= (HashCode
<< 1) +
1453 (((unsigned char)CRCValue
>> j
) & 0x01);
1456 * Bits 3-5 of HashCode point to byte in address
1458 * Bits 0-2 point to bit within that byte.
1460 FilterByte
= HashCode
>> 3;
1461 pLayerPointers
->pMdl
->TempLADRF
[FilterByte
] |=
1462 (1 << (HashCode
& 0x07));
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
];
1472 CRCValue
= mdlCalculateCRC(ETH_LENGTH_OF_ADDRESS
,
1474 for (j
= 0; j
< 6; j
++) {
1475 HashCode
= ((HashCode
<< 1) +
1476 (((unsigned char)CRCValue
>> j
) & 0x01));
1480 * Bits 3-5 of HashCode point to byte in address
1482 * Bits 0-2 point to bit within that byte.
1484 FilterByte
= HashCode
>> 3;
1485 pLayerPointers
->pMdl
->TempLADRF
[FilterByte
] &=
1486 !(1 << (HashCode
& 0x07));
1498 mdlAddMulticastAddresses(struct LayerPointers
*pLayerPointers
,
1499 int NumberOfAddress
, unsigned char *MulticastAddresses
)
1501 unsigned int j
, CRCValue
;
1502 unsigned char HashCode
, FilterByte
;
1505 for (i
= 0; i
< 8; i
++) {
1506 pLayerPointers
->pMdl
->TempLADRF
[i
] = 0x00;
1510 for (i
= 0; i
< NumberOfAddress
; i
++) {
1513 /* Calculate CRC value */
1514 CRCValue
= mdlCalculateCRC(ETH_LENGTH_OF_ADDRESS
,
1515 MulticastAddresses
);
1517 for (j
= 0; j
< 6; j
++) {
1518 HashCode
= (HashCode
<< 1) +
1519 (((unsigned char)CRCValue
>> j
) & 0x01);
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
;
1531 /* Receive all packets */
1533 mdlSetPromiscuous(struct LayerPointers
*pLayerPointers
)
1536 * Writable N == Can Be Written only when device is not running
1539 WRITE_REG32(pLayerPointers
, pLayerPointers
->pMdl
->Mem_Address
+ CMD2
,
1541 pLayerPointers
->pMdl
->FLAGS
|= PROM
; /* B16_MASK */
1544 /* Stop Receiving all packets */
1546 mdlDisablePromiscuous(struct LayerPointers
*pLayerPointers
)
1549 * Writable N == Can Be Written only when device is not running
1552 WRITE_REG32(pLayerPointers
, pLayerPointers
->pMdl
->Mem_Address
+ CMD2
,
1554 pLayerPointers
->pMdl
->FLAGS
&= (~ PROM
); /* B16_MASK */
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.
1565 mdlReceiveBroadCast(struct LayerPointers
*pLayerPointers
)
1567 ULONG MappedMemBaseAddress
;
1569 MappedMemBaseAddress
= pLayerPointers
->pMdl
->Mem_Address
;
1570 WRITE_REG32(pLayerPointers
, MappedMemBaseAddress
+ CMD2
, DRCVBC
);
1571 pLayerPointers
->pMdl
->FLAGS
|= DRCVBC
;
1575 mdlDisableReceiveBroadCast(struct LayerPointers
*pLayerPointers
)
1577 ULONG MappedMemBaseAddress
;
1579 MappedMemBaseAddress
= pLayerPointers
->pMdl
->Mem_Address
;
1580 WRITE_REG32(pLayerPointers
, MappedMemBaseAddress
+ CMD2
, VAL2
| DRCVBC
);
1581 pLayerPointers
->pMdl
->FLAGS
&= (~DRCVBC
);
1585 mdlEnableMagicPacketWakeUp(struct LayerPointers
*pLayerPointers
)
1587 WRITE_REG32(pLayerPointers
, pLayerPointers
->pMdl
->Mem_Address
+ CMD3
,
1589 WRITE_REG32(pLayerPointers
, pLayerPointers
->pMdl
->Mem_Address
+ CMD7
,
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.
1601 mdlMulticastBitMapping(struct LayerPointers
*pLayerPointers
,
1602 unsigned char *MulticastAddress
, int FLAG
)
1604 unsigned char HashCode
, FilterByte
;
1605 int j
= 0, BitMapIndex
= 0;
1606 unsigned int CRCValue
= 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);
1617 * Bits 3-5 of HashCode point to byte in address filter.
1618 * Bits 0-2 point to bit within that byte.
1620 FilterByte
= HashCode
& 0x38;
1621 FilterByte
= FilterByte
>> 3;
1622 BitMapIndex
= (int)FilterByte
* 8 + (HashCode
& 0x7);
1624 if (FLAG
== DELETE_MULTICAST
) {
1625 if ((pLayerPointers
->pMdl
->MulticastBitMapArray
[BitMapIndex
]
1626 == 0) || (--pLayerPointers
->pMdl
->MulticastBitMapArray
1627 [BitMapIndex
] == 0)) {
1634 if (FLAG
== ADD_MULTICAST
) {
1635 if (pLayerPointers
->pMdl
1636 ->MulticastBitMapArray
[BitMapIndex
] > 0) {
1637 pLayerPointers
->pMdl
1638 ->MulticastBitMapArray
[BitMapIndex
]++;
1640 } else if (pLayerPointers
->pMdl
1641 ->MulticastBitMapArray
[BitMapIndex
] == 0) {
1642 pLayerPointers
->pMdl
1643 ->MulticastBitMapArray
[BitMapIndex
]++;
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.
1659 SetIntrCoalesc(struct LayerPointers
*pLayerPointers
, boolean_t on
)
1661 long MemBaseAddress
= pLayerPointers
->pMdl
->Mem_Address
;
1662 struct mdl
*pMdl
= 0;
1663 unsigned int timeout
, event_count
;
1665 pMdl
= (struct mdl
*)(pLayerPointers
->pMdl
);
1668 /* Set Rx Interrupt Coalescing */
1669 timeout
= pLayerPointers
->pMdl
->rx_intrcoalesc_time
;
1671 event_count
|= pLayerPointers
->pMdl
->rx_intrcoalesc_events
;
1672 if (timeout
> 0x7ff) {
1675 if (event_count
> 0x1f) {
1679 event_count
= event_count
<< 16;
1680 WRITE_REG32(pLayerPointers
, MemBaseAddress
+ DLY_INT_A
,
1681 DLY_INT_A_R0
| event_count
| timeout
);
1684 /* Disable Software Timer Interrupt */
1685 WRITE_REG32(pLayerPointers
, MemBaseAddress
+ STVAL
, 0);
1686 WRITE_REG32(pLayerPointers
, pMdl
->Mem_Address
+ INTEN0
,
1689 WRITE_REG32(pLayerPointers
, MemBaseAddress
+ DLY_INT_A
, 0);
1690 WRITE_REG32(pLayerPointers
, MemBaseAddress
+ DLY_INT_B
, 0);
1695 mdlSendPause(struct LayerPointers
*pLayerPointers
)
1697 WRITE_REG32(pLayerPointers
, pLayerPointers
->pMdl
->Mem_Address
1698 + FLOW_CONTROL
, VAL2
| FIXP
| FCCMD
| 0x200);
1701 /* Reset all Tx descriptors and Tx buffers */
1703 milResetTxQ(struct LayerPointers
*pLayerPointers
)
1705 struct nonphysical
*pNonphysical
= pLayerPointers
->pMil
->pNonphysical
;
1708 pNonphysical
->TxDescQRead
= pNonphysical
->TxDescQStart
;
1709 pNonphysical
->TxDescQWrite
= pNonphysical
->TxDescQStart
;
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
++;
1718 pNonphysical
->TxDescQWrite
= pNonphysical
->TxDescQStart
;
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
;
1730 * Initialises the data used in Mil.
1733 milInitGlbds(struct LayerPointers
*pLayerPointers
)
1735 pLayerPointers
->pMil
->name
= DEVICE_CHIPNAME
;
1737 mdlInitGlbds(pLayerPointers
);
1742 * Initialises the RxBufDescQ with the packet pointer and physical
1743 * address filled in the FreeQ.
1747 * Pointer to the Adapter structure.
1750 milInitRxQ(struct LayerPointers
*pLayerPointers
)
1752 struct mil
*pMil
= pLayerPointers
->pMil
;
1753 struct nonphysical
*pNonphysical
= pMil
->pNonphysical
;
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]);
1761 pNonphysical
->RxBufDescQRead
->USpaceMap
= pMil
->USpaceMapArray
;
1762 pNonphysical
->RxBufDescQStart
->USpaceMap
= pMil
->USpaceMapArray
;
1763 pNonphysical
->RxBufDescQEnd
->USpaceMap
=
1764 &(pMil
->USpaceMapArray
[pMil
->RxRingSize
- 1]);
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
;
1771 *(pNonphysical
->RxBufDescQRead
->USpaceMap
) =
1772 (long)(pLayerPointers
->pOdl
->rx_buf
.next
->vir_addr
);
1774 pNonphysical
->RxBufDescQRead
->descriptor
->Rx_Base_Addr
1775 = pLayerPointers
->pOdl
->rx_buf
.next
->phy_addr
;
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
);
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
;
1794 * This array is filled with the size of the structure & its
1795 * pointer for freeing purposes.
1799 * Pointer to the adapter structure.
1801 * Pointer to the array that holds the data required
1805 milFreeResources(struct LayerPointers
*pLayerPointers
, ULONG
*mem_free_array
)
1807 /* 1) For mil structure (pLayerPointers->pMil) */
1809 *(mem_free_array
) = VIRTUAL
;
1811 *(++mem_free_array
) = sizeof (struct mil
);
1813 *(++mem_free_array
) = (ULONG
)pLayerPointers
->pMil
;
1816 /* 2) For USpaceMapArray queue */
1818 *(++mem_free_array
) = VIRTUAL
;
1820 *(++mem_free_array
) = pLayerPointers
->pMil
->RxRingSize
*
1821 sizeof (unsigned long);
1823 *(++mem_free_array
) = (ULONG
)pLayerPointers
->pMil
->USpaceMapArray
;
1826 /* 3) For non_physical structure */
1828 *(++mem_free_array
) = VIRTUAL
;
1830 *(++mem_free_array
) = sizeof (struct nonphysical
);
1832 *(++mem_free_array
) = (ULONG
)pLayerPointers
->pMil
->pNonphysical
;
1835 * 4~6) For four allocation are for abstracting the Rx_Descritor ring
1839 *(++mem_free_array
) = VIRTUAL
;
1841 *(++mem_free_array
) = sizeof (struct Rx_Buf_Desc
);
1843 *(++mem_free_array
) =
1844 (ULONG
)pLayerPointers
->pMil
->pNonphysical
->RxBufDescQRead
;
1847 *(++mem_free_array
) = VIRTUAL
;
1849 *(++mem_free_array
) = sizeof (struct Rx_Buf_Desc
);
1851 *(++mem_free_array
) =
1852 (ULONG
)pLayerPointers
->pMil
->pNonphysical
->RxBufDescQStart
;
1855 *(++mem_free_array
) = VIRTUAL
;
1857 *(++mem_free_array
) = sizeof (struct Rx_Buf_Desc
);
1859 *(++mem_free_array
) =
1860 (ULONG
)pLayerPointers
->pMil
->pNonphysical
->RxBufDescQEnd
;
1862 *(++mem_free_array
) = 0;
1864 mdlFreeResources(pLayerPointers
, mem_free_array
);
1871 * This array is filled with the size of the memory required for
1872 * allocating purposes.
1876 * Pointer to the adapter structure.
1878 * Pointer to the array that holds the data required for
1879 * allocating memory.
1882 milRequestResources(ULONG
*mem_req_array
)
1886 RxRingSize
= RX_RING_SIZE
; /* 128 */
1888 /* 1) For mil structure (pLayerPointers->pMil) */
1890 *mem_req_array
= VIRTUAL
;
1892 *(++mem_req_array
) = sizeof (struct mil
);
1894 /* 2) For USpaceMapArray queue (pLayerPointers->pMil->USpaceMapArray) */
1896 *(++mem_req_array
) = VIRTUAL
;
1898 *(++mem_req_array
) = RxRingSize
* sizeof (unsigned long);
1901 /* 3) For pNonphysical structure */
1903 *(++mem_req_array
) = VIRTUAL
;
1905 *(++mem_req_array
) = sizeof (struct nonphysical
);
1908 * 4~6) For four allocation are for abstracting the Rx_Descritor ring
1911 *(++mem_req_array
) = VIRTUAL
;
1913 *(++mem_req_array
) = sizeof (struct Rx_Buf_Desc
);
1916 *(++mem_req_array
) = VIRTUAL
;
1918 *(++mem_req_array
) = sizeof (struct Rx_Buf_Desc
);
1921 *(++mem_req_array
) = VIRTUAL
;
1923 *(++mem_req_array
) = sizeof (struct Rx_Buf_Desc
);
1925 *(++mem_req_array
) = 0;
1927 mdlRequestResources(mem_req_array
);
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.
1940 * Pointer to the adapter structure.
1942 * Pointer to the array that holds the data after required
1943 * allocating memory.
1946 milSetResources(struct LayerPointers
*pLayerPointers
, ULONG
*pmem_set_array
)
1948 int RxRingSize
, TxRingSize
;
1952 RxRingSize
= RX_RING_SIZE
;
1953 TxRingSize
= TX_RING_SIZE
;
1954 RxBufSize
= RX_BUF_SIZE
;
1956 /* 1) Set the pointers to the mil pointers */
1961 pMil
= (struct mil
*)(*pmem_set_array
);
1962 pLayerPointers
->pMil
= pMil
;
1964 pMil
->RxRingSize
= RxRingSize
;
1965 pMil
->TxRingSize
= TxRingSize
;
1966 pMil
->RxBufSize
= RxBufSize
;
1973 pMil
->USpaceMapArray
= (long *)(*pmem_set_array
);
1975 /* 3) Set the pointers to the NonPhysical part */
1980 /* Virtual Addr of NonPhysical */
1982 pMil
->pNonphysical
=
1983 (struct nonphysical
*)(*pmem_set_array
);
1986 * 4~6) Following four allocation are for abstracting the Rx_Descritor
1993 /* Virtual Addr of Abstracted RxDesc */
1995 pMil
->pNonphysical
->RxBufDescQRead
=
1996 (struct Rx_Buf_Desc
*)(*pmem_set_array
);
2002 /* Virtual Addr of Abstracted RxDesc */
2004 pMil
->pNonphysical
->RxBufDescQStart
=
2005 (struct Rx_Buf_Desc
*)(*pmem_set_array
);
2011 /* Virtual Addr of Abstracted RxDesc */
2013 pMil
->pNonphysical
->RxBufDescQEnd
=
2014 (struct Rx_Buf_Desc
*)(*pmem_set_array
);
2018 mdlSetResources(pLayerPointers
, pmem_set_array
);
2023 * This routine adds the Multicast addresses to the filter
2027 * Pointer to Layer pointers structure.
2028 * pucMulticastAddress
2029 * Pointer to the array of multicast addresses
2032 mdlAddMulticastAddress(struct LayerPointers
*pLayerPointers
,
2033 UCHAR
*pucMulticastAddress
)
2035 unsigned long MODE
[10];
2039 if (mdlMulticastBitMapping(pLayerPointers
, pucMulticastAddress
,
2040 ADD_MULTICAST
) != 0)
2043 tmp2
= SET_SINGLE_MULTICAST
;
2044 MODE
[0] = (unsigned long)tmp2
;
2046 tmp1
= (unsigned long)pucMulticastAddress
;
2048 MODE
[3] = ENABLE_MULTICAST
;
2050 mdlChangeFilter(pLayerPointers
, (unsigned long *)MODE
);
2056 * This routine deletes the Multicast addresses requested by OS.
2060 * Pointer to Layer pointers structure.
2061 * pucMulticastAddress
2062 * Pointer to the array of multicast addresses
2065 mdlDeleteMulticastAddress(struct LayerPointers
*pLayerPointers
,
2066 UCHAR
*pucMulticastAddress
)
2068 unsigned long MODE
[10];
2071 if (mdlMulticastBitMapping(pLayerPointers
, pucMulticastAddress
,
2072 DELETE_MULTICAST
) != 0)
2075 MODE
[0] = UNSET_SINGLE_MULTICAST
;
2077 tmp
= (unsigned long)pucMulticastAddress
;
2079 MODE
[3] = ENABLE_MULTICAST
;
2081 mdlChangeFilter(pLayerPointers
, (unsigned long *)MODE
);
2086 * Calculates the CRC value over the input number of bytes.
2090 * The number of bytes in the input.
2092 * An input "string" to calculate a CRC over.
2095 mdlCalculateCRC(unsigned int NumberOfBytes
, unsigned char *Input
)
2097 const unsigned int POLY
= 0x04c11db7;
2098 unsigned int CRCValue
= 0xffffffff;
2099 unsigned int CurrentBit
, CurrentCRCHigh
;
2100 unsigned char CurrentByte
;
2102 for (; NumberOfBytes
; NumberOfBytes
--) {
2103 CurrentByte
= *Input
;
2106 for (CurrentBit
= 8; CurrentBit
; CurrentBit
--) {
2107 CurrentCRCHigh
= CRCValue
>> 31;
2110 if (CurrentCRCHigh
^ (CurrentByte
& 0x01)) {
2112 CRCValue
|= 0x00000001;
2121 mdlRxFastSuspend(struct LayerPointers
*pLayerPointers
)
2123 WRITE_REG32(pLayerPointers
, pLayerPointers
->pMdl
->Mem_Address
+ CMD0
,
2124 VAL0
| RX_FAST_SPND
);
2128 mdlRxFastSuspendClear(struct LayerPointers
*pLayerPointers
)
2130 WRITE_REG32(pLayerPointers
, pLayerPointers
->pMdl
->Mem_Address
+ CMD0
,