]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - drivers/net/ns8382x.c
Merge branch 'master' of git://git.denx.de/u-boot-samsung
[karo-tx-uboot.git] / drivers / net / ns8382x.c
1 /*
2    ns8382x.c: A U-Boot driver for the NatSemi DP8382[01].
3    ported by: Mark A. Rakes (mark_rakes@vivato.net)
4
5    Adapted from:
6    1. an Etherboot driver for DP8381[56] written by:
7            Copyright (C) 2001 Entity Cyber, Inc.
8
9            This development of this Etherboot driver was funded by
10                   Sicom Systems: http://www.sicompos.com/
11
12            Author: Marty Connor (mdc@thinguin.org)
13            Adapted from a Linux driver which was written by Donald Becker
14
15            This software may be used and distributed according to the terms
16            of the GNU Public License (GPL), incorporated herein by reference.
17
18    2. A Linux driver by Donald Becker, ns820.c:
19                 Written/copyright 1999-2002 by Donald Becker.
20
21                 This software may be used and distributed according to the terms of
22                 the GNU General Public License (GPL), incorporated herein by reference.
23                 Drivers based on or derived from this code fall under the GPL and must
24                 retain the authorship, copyright and license notice.  This file is not
25                 a complete program and may only be used when the entire operating
26                 system is licensed under the GPL.  License for under other terms may be
27                 available.  Contact the original author for details.
28
29                 The original author may be reached as becker@scyld.com, or at
30                 Scyld Computing Corporation
31                 410 Severn Ave., Suite 210
32                 Annapolis MD 21403
33
34                 Support information and updates available at
35                 http://www.scyld.com/network/netsemi.html
36
37    Datasheets available from:
38    http://www.national.com/pf/DP/DP83820.html
39    http://www.national.com/pf/DP/DP83821.html
40 */
41
42 /* Revision History
43  * October 2002 mar     1.0
44  *   Initial U-Boot Release.
45  *      Tested with Netgear GA622T (83820)
46  *      and SMC9452TX (83821)
47  *      NOTE: custom boards with these chips may (likely) require
48  *      a programmed EEPROM device (if present) in order to work
49  *      correctly.
50 */
51
52 /* Includes */
53 #include <common.h>
54 #include <malloc.h>
55 #include <net.h>
56 #include <netdev.h>
57 #include <asm/io.h>
58 #include <pci.h>
59
60 /* defines */
61 #define DSIZE     0x00000FFF
62 #define ETH_ALEN                6
63 #define CRC_SIZE  4
64 #define TOUT_LOOP   500000
65 #define TX_BUF_SIZE    1536
66 #define RX_BUF_SIZE    1536
67 #define NUM_RX_DESC    4        /* Number of Rx descriptor registers. */
68
69 enum register_offsets {
70         ChipCmd = 0x00,
71         ChipConfig = 0x04,
72         EECtrl = 0x08,
73         IntrMask = 0x14,
74         IntrEnable = 0x18,
75         TxRingPtr = 0x20,
76         TxRingPtrHi = 0x24,
77         TxConfig = 0x28,
78         RxRingPtr = 0x30,
79         RxRingPtrHi = 0x34,
80         RxConfig = 0x38,
81         PriQueue = 0x3C,
82         RxFilterAddr = 0x48,
83         RxFilterData = 0x4C,
84         ClkRun = 0xCC,
85         PCIPM = 0x44,
86 };
87
88 enum ChipCmdBits {
89         ChipReset = 0x100,
90         RxReset = 0x20,
91         TxReset = 0x10,
92         RxOff = 0x08,
93         RxOn = 0x04,
94         TxOff = 0x02,
95         TxOn = 0x01
96 };
97
98 enum ChipConfigBits {
99         LinkSts = 0x80000000,
100         GigSpeed = 0x40000000,
101         HundSpeed = 0x20000000,
102         FullDuplex = 0x10000000,
103         TBIEn = 0x01000000,
104         Mode1000 = 0x00400000,
105         T64En = 0x00004000,
106         D64En = 0x00001000,
107         M64En = 0x00000800,
108         PhyRst = 0x00000400,
109         PhyDis = 0x00000200,
110         ExtStEn = 0x00000100,
111         BEMode = 0x00000001,
112 };
113 #define SpeedStatus_Polarity ( GigSpeed | HundSpeed | FullDuplex)
114
115 enum TxConfig_bits {
116         TxDrthMask      = 0x000000ff,
117         TxFlthMask      = 0x0000ff00,
118         TxMxdmaMask     = 0x00700000,
119         TxMxdma_8       = 0x00100000,
120         TxMxdma_16      = 0x00200000,
121         TxMxdma_32      = 0x00300000,
122         TxMxdma_64      = 0x00400000,
123         TxMxdma_128     = 0x00500000,
124         TxMxdma_256     = 0x00600000,
125         TxMxdma_512     = 0x00700000,
126         TxMxdma_1024    = 0x00000000,
127         TxCollRetry     = 0x00800000,
128         TxAutoPad       = 0x10000000,
129         TxMacLoop       = 0x20000000,
130         TxHeartIgn      = 0x40000000,
131         TxCarrierIgn    = 0x80000000
132 };
133
134 enum RxConfig_bits {
135         RxDrthMask      = 0x0000003e,
136         RxMxdmaMask     = 0x00700000,
137         RxMxdma_8       = 0x00100000,
138         RxMxdma_16      = 0x00200000,
139         RxMxdma_32      = 0x00300000,
140         RxMxdma_64      = 0x00400000,
141         RxMxdma_128     = 0x00500000,
142         RxMxdma_256     = 0x00600000,
143         RxMxdma_512     = 0x00700000,
144         RxMxdma_1024    = 0x00000000,
145         RxAcceptLenErr  = 0x04000000,
146         RxAcceptLong    = 0x08000000,
147         RxAcceptTx      = 0x10000000,
148         RxStripCRC      = 0x20000000,
149         RxAcceptRunt    = 0x40000000,
150         RxAcceptErr     = 0x80000000,
151 };
152
153 /* Bits in the RxMode register. */
154 enum rx_mode_bits {
155         RxFilterEnable          = 0x80000000,
156         AcceptAllBroadcast      = 0x40000000,
157         AcceptAllMulticast      = 0x20000000,
158         AcceptAllUnicast        = 0x10000000,
159         AcceptPerfectMatch      = 0x08000000,
160 };
161
162 typedef struct _BufferDesc {
163         u32 link;
164         u32 bufptr;
165         vu_long cmdsts;
166         u32 extsts;             /*not used here */
167 } BufferDesc;
168
169 /* Bits in network_desc.status */
170 enum desc_status_bits {
171         DescOwn = 0x80000000, DescMore = 0x40000000, DescIntr = 0x20000000,
172         DescNoCRC = 0x10000000, DescPktOK = 0x08000000,
173         DescSizeMask = 0xfff,
174
175         DescTxAbort = 0x04000000, DescTxFIFO = 0x02000000,
176         DescTxCarrier = 0x01000000, DescTxDefer = 0x00800000,
177         DescTxExcDefer = 0x00400000, DescTxOOWCol = 0x00200000,
178         DescTxExcColl = 0x00100000, DescTxCollCount = 0x000f0000,
179
180         DescRxAbort = 0x04000000, DescRxOver = 0x02000000,
181         DescRxDest = 0x01800000, DescRxLong = 0x00400000,
182         DescRxRunt = 0x00200000, DescRxInvalid = 0x00100000,
183         DescRxCRC = 0x00080000, DescRxAlign = 0x00040000,
184         DescRxLoop = 0x00020000, DesRxColl = 0x00010000,
185 };
186
187 /* Bits in MEAR */
188 enum mii_reg_bits {
189         MDIO_ShiftClk = 0x0040,
190         MDIO_EnbOutput = 0x0020,
191         MDIO_Data = 0x0010,
192 };
193
194 /* PHY Register offsets.  */
195 enum phy_reg_offsets {
196         BMCR = 0x00,
197         BMSR = 0x01,
198         PHYIDR1 = 0x02,
199         PHYIDR2 = 0x03,
200         ANAR = 0x04,
201         KTCR = 0x09,
202 };
203
204 /* basic mode control register bits */
205 enum bmcr_bits {
206         Bmcr_Reset = 0x8000,
207         Bmcr_Loop = 0x4000,
208         Bmcr_Speed0 = 0x2000,
209         Bmcr_AutoNegEn = 0x1000,        /*if set ignores Duplex, Speed[01] */
210         Bmcr_RstAutoNeg = 0x0200,
211         Bmcr_Duplex = 0x0100,
212         Bmcr_Speed1 = 0x0040,
213         Bmcr_Force10H = 0x0000,
214         Bmcr_Force10F = 0x0100,
215         Bmcr_Force100H = 0x2000,
216         Bmcr_Force100F = 0x2100,
217         Bmcr_Force1000H = 0x0040,
218         Bmcr_Force1000F = 0x0140,
219 };
220
221 /* auto negotiation advertisement register */
222 enum anar_bits {
223         anar_adv_100F = 0x0100,
224         anar_adv_100H = 0x0080,
225         anar_adv_10F = 0x0040,
226         anar_adv_10H = 0x0020,
227         anar_ieee_8023 = 0x0001,
228 };
229
230 /* 1K-base T control register */
231 enum ktcr_bits {
232         ktcr_adv_1000H = 0x0100,
233         ktcr_adv_1000F = 0x0200,
234 };
235
236 /* Globals */
237 static u32 SavedClkRun;
238 static unsigned int cur_rx;
239 static unsigned int rx_config;
240 static unsigned int tx_config;
241
242 /* Note: transmit and receive buffers and descriptors must be
243    long long word aligned */
244 static BufferDesc txd __attribute__ ((aligned(8)));
245 static BufferDesc rxd[NUM_RX_DESC] __attribute__ ((aligned(8)));
246 static unsigned char txb[TX_BUF_SIZE] __attribute__ ((aligned(8)));
247 static unsigned char rxb[NUM_RX_DESC * RX_BUF_SIZE]
248     __attribute__ ((aligned(8)));
249
250 /* Function Prototypes */
251 static int mdio_read(struct eth_device *dev, int phy_id, int addr);
252 static void mdio_write(struct eth_device *dev, int phy_id, int addr, int value);
253 static void mdio_sync(struct eth_device *dev, u32 offset);
254 static int ns8382x_init(struct eth_device *dev, bd_t * bis);
255 static void ns8382x_reset(struct eth_device *dev);
256 static void ns8382x_init_rxfilter(struct eth_device *dev);
257 static void ns8382x_init_txd(struct eth_device *dev);
258 static void ns8382x_init_rxd(struct eth_device *dev);
259 static void ns8382x_set_rx_mode(struct eth_device *dev);
260 static void ns8382x_check_duplex(struct eth_device *dev);
261 static int ns8382x_send(struct eth_device *dev, volatile void *packet,
262                         int length);
263 static int ns8382x_poll(struct eth_device *dev);
264 static void ns8382x_disable(struct eth_device *dev);
265
266 static struct pci_device_id supported[] = {
267         {PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_83820},
268         {}
269 };
270
271 #define bus_to_phys(a)  pci_mem_to_phys((pci_dev_t)dev->priv, a)
272 #define phys_to_bus(a)  pci_phys_to_mem((pci_dev_t)dev->priv, a)
273
274 static inline int
275 INW(struct eth_device *dev, u_long addr)
276 {
277         return le16_to_cpu(*(vu_short *) (addr + dev->iobase));
278 }
279
280 static int
281 INL(struct eth_device *dev, u_long addr)
282 {
283         return le32_to_cpu(*(vu_long *) (addr + dev->iobase));
284 }
285
286 static inline void
287 OUTW(struct eth_device *dev, int command, u_long addr)
288 {
289         *(vu_short *) ((addr + dev->iobase)) = cpu_to_le16(command);
290 }
291
292 static inline void
293 OUTL(struct eth_device *dev, int command, u_long addr)
294 {
295         *(vu_long *) ((addr + dev->iobase)) = cpu_to_le32(command);
296 }
297
298 /* Function: ns8382x_initialize
299  * Description: Retrieves the MAC address of the card, and sets up some
300  *  globals required by other routines, and initializes the NIC, making it
301  *  ready to send and receive packets.
302  * Side effects: initializes ns8382xs, ready to recieve packets.
303  * Returns:   int:          number of cards found
304  */
305
306 int
307 ns8382x_initialize(bd_t * bis)
308 {
309         pci_dev_t devno;
310         int card_number = 0;
311         struct eth_device *dev;
312         u32 iobase, status;
313         int i, idx = 0;
314         u32 phyAddress;
315         u32 tmp;
316         u32 chip_config;
317
318         while (1) {             /* Find PCI device(s) */
319                 if ((devno = pci_find_devices(supported, idx++)) < 0)
320                         break;
321
322                 pci_read_config_dword(devno, PCI_BASE_ADDRESS_1, &iobase);
323                 iobase &= ~0x3; /* 1: unused and 0:I/O Space Indicator */
324
325 #ifdef NS8382X_DEBUG
326                 printf("ns8382x: NatSemi dp8382x @ 0x%x\n", iobase);
327 #endif
328
329                 pci_write_config_dword(devno, PCI_COMMAND,
330                                        PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
331
332                 /* Check if I/O accesses and Bus Mastering are enabled. */
333                 pci_read_config_dword(devno, PCI_COMMAND, &status);
334                 if (!(status & PCI_COMMAND_MEMORY)) {
335                         printf("Error: Can not enable MEM access.\n");
336                         continue;
337                 } else if (!(status & PCI_COMMAND_MASTER)) {
338                         printf("Error: Can not enable Bus Mastering.\n");
339                         continue;
340                 }
341
342                 dev = (struct eth_device *) malloc(sizeof *dev);
343                 if (!dev) {
344                         printf("ns8382x: Can not allocate memory\n");
345                         break;
346                 }
347                 memset(dev, 0, sizeof(*dev));
348
349                 sprintf(dev->name, "dp8382x#%d", card_number);
350                 dev->iobase = bus_to_phys(iobase);
351                 dev->priv = (void *) devno;
352                 dev->init = ns8382x_init;
353                 dev->halt = ns8382x_disable;
354                 dev->send = ns8382x_send;
355                 dev->recv = ns8382x_poll;
356
357                 /* ns8382x has a non-standard PM control register
358                  * in PCI config space.  Some boards apparently need
359                  * to be brought to D0 in this manner.  */
360                 pci_read_config_dword(devno, PCIPM, &tmp);
361                 if (tmp & (0x03 | 0x100)) {     /* D0 state, disable PME assertion */
362                         u32 newtmp = tmp & ~(0x03 | 0x100);
363                         pci_write_config_dword(devno, PCIPM, newtmp);
364                 }
365
366                 /* get MAC address */
367                 for (i = 0; i < 3; i++) {
368                         u32 data;
369                         char *mac = (char *)&dev->enetaddr[i * 2];
370
371                         OUTL(dev, i * 2, RxFilterAddr);
372                         data = INL(dev, RxFilterData);
373                         *mac++ = data;
374                         *mac++ = data >> 8;
375                 }
376                 /* get PHY address, can't be zero */
377                 for (phyAddress = 1; phyAddress < 32; phyAddress++) {
378                         u32 rev, phy1;
379
380                         phy1 = mdio_read(dev, phyAddress, PHYIDR1);
381                         if (phy1 == 0x2000) {   /*check for 83861/91 */
382                                 rev = mdio_read(dev, phyAddress, PHYIDR2);
383                                 if ((rev & ~(0x000f)) == 0x00005c50 ||
384                                     (rev & ~(0x000f)) == 0x00005c60) {
385 #ifdef NS8382X_DEBUG
386                                         printf("phy rev is %x\n", rev);
387                                         printf("phy address is %x\n",
388                                                phyAddress);
389 #endif
390                                         break;
391                                 }
392                         }
393                 }
394
395                 /* set phy to autonegotiate && advertise everything */
396                 mdio_write(dev, phyAddress, KTCR,
397                            (ktcr_adv_1000H | ktcr_adv_1000F));
398                 mdio_write(dev, phyAddress, ANAR,
399                            (anar_adv_100F | anar_adv_100H | anar_adv_10H |
400                             anar_adv_10F | anar_ieee_8023));
401                 mdio_write(dev, phyAddress, BMCR, 0x0); /*restore */
402                 mdio_write(dev, phyAddress, BMCR,
403                            (Bmcr_AutoNegEn | Bmcr_RstAutoNeg));
404                 /* Reset the chip to erase any previous misconfiguration. */
405                 OUTL(dev, (ChipReset), ChipCmd);
406
407                 chip_config = INL(dev, ChipConfig);
408                 /* reset the phy */
409                 OUTL(dev, (chip_config | PhyRst), ChipConfig);
410                 /* power up and initialize transceiver */
411                 OUTL(dev, (chip_config & ~(PhyDis)), ChipConfig);
412
413                 mdio_sync(dev, EECtrl);
414 #ifdef NS8382X_DEBUG
415                 {
416                         u32 chpcfg =
417                             INL(dev, ChipConfig) ^ SpeedStatus_Polarity;
418
419                         printf("%s: Transceiver 10%s %s duplex.\n", dev->name,
420                                (chpcfg & GigSpeed) ? "00" : (chpcfg & HundSpeed)
421                                ? "0" : "",
422                                chpcfg & FullDuplex ? "full" : "half");
423                         printf("%s: %02x:%02x:%02x:%02x:%02x:%02x\n", dev->name,
424                                dev->enetaddr[0], dev->enetaddr[1],
425                                dev->enetaddr[2], dev->enetaddr[3],
426                                dev->enetaddr[4], dev->enetaddr[5]);
427                 }
428 #endif
429                 /* Disable PME:
430                  * The PME bit is initialized from the EEPROM contents.
431                  * PCI cards probably have PME disabled, but motherboard
432                  * implementations may have PME set to enable WakeOnLan.
433                  * With PME set the chip will scan incoming packets but
434                  * nothing will be written to memory. */
435                 SavedClkRun = INL(dev, ClkRun);
436                 OUTL(dev, SavedClkRun & ~0x100, ClkRun);
437
438                 eth_register(dev);
439
440                 card_number++;
441
442                 pci_write_config_byte(devno, PCI_LATENCY_TIMER, 0x60);
443
444                 udelay(10 * 1000);
445         }
446         return card_number;
447 }
448
449 /*  MII transceiver control section.
450         Read and write MII registers using software-generated serial MDIO
451         protocol.  See the MII specifications or DP83840A data sheet for details.
452
453         The maximum data clock rate is 2.5 MHz.  To meet minimum timing we
454         must flush writes to the PCI bus with a PCI read. */
455 #define mdio_delay(mdio_addr) INL(dev, mdio_addr)
456
457 #define MDIO_EnbIn  (0)
458 #define MDIO_WRITE0 (MDIO_EnbOutput)
459 #define MDIO_WRITE1 (MDIO_Data | MDIO_EnbOutput)
460
461 /* Generate the preamble required for initial synchronization and
462    a few older transceivers. */
463 static void
464 mdio_sync(struct eth_device *dev, u32 offset)
465 {
466         int bits = 32;
467
468         /* Establish sync by sending at least 32 logic ones. */
469         while (--bits >= 0) {
470                 OUTL(dev, MDIO_WRITE1, offset);
471                 mdio_delay(offset);
472                 OUTL(dev, MDIO_WRITE1 | MDIO_ShiftClk, offset);
473                 mdio_delay(offset);
474         }
475 }
476
477 static int
478 mdio_read(struct eth_device *dev, int phy_id, int addr)
479 {
480         int mii_cmd = (0xf6 << 10) | (phy_id << 5) | addr;
481         int i, retval = 0;
482
483         /* Shift the read command bits out. */
484         for (i = 15; i >= 0; i--) {
485                 int dataval = (mii_cmd & (1 << i)) ? MDIO_WRITE1 : MDIO_WRITE0;
486
487                 OUTL(dev, dataval, EECtrl);
488                 mdio_delay(EECtrl);
489                 OUTL(dev, dataval | MDIO_ShiftClk, EECtrl);
490                 mdio_delay(EECtrl);
491         }
492         /* Read the two transition, 16 data, and wire-idle bits. */
493         for (i = 19; i > 0; i--) {
494                 OUTL(dev, MDIO_EnbIn, EECtrl);
495                 mdio_delay(EECtrl);
496                 retval =
497                     (retval << 1) | ((INL(dev, EECtrl) & MDIO_Data) ? 1 : 0);
498                 OUTL(dev, MDIO_EnbIn | MDIO_ShiftClk, EECtrl);
499                 mdio_delay(EECtrl);
500         }
501         return (retval >> 1) & 0xffff;
502 }
503
504 static void
505 mdio_write(struct eth_device *dev, int phy_id, int addr, int value)
506 {
507         int mii_cmd = (0x5002 << 16) | (phy_id << 23) | (addr << 18) | value;
508         int i;
509
510         /* Shift the command bits out. */
511         for (i = 31; i >= 0; i--) {
512                 int dataval = (mii_cmd & (1 << i)) ? MDIO_WRITE1 : MDIO_WRITE0;
513
514                 OUTL(dev, dataval, EECtrl);
515                 mdio_delay(EECtrl);
516                 OUTL(dev, dataval | MDIO_ShiftClk, EECtrl);
517                 mdio_delay(EECtrl);
518         }
519         /* Clear out extra bits. */
520         for (i = 2; i > 0; i--) {
521                 OUTL(dev, MDIO_EnbIn, EECtrl);
522                 mdio_delay(EECtrl);
523                 OUTL(dev, MDIO_EnbIn | MDIO_ShiftClk, EECtrl);
524                 mdio_delay(EECtrl);
525         }
526         return;
527 }
528
529 /* Function: ns8382x_init
530  * Description: resets the ethernet controller chip and configures
531  *    registers and data structures required for sending and receiving packets.
532  * Arguments: struct eth_device *dev:       NIC data structure
533  * returns:     int.
534  */
535
536 static int
537 ns8382x_init(struct eth_device *dev, bd_t * bis)
538 {
539         u32 config;
540
541         ns8382x_reset(dev);
542
543         /* Disable PME:
544          * The PME bit is initialized from the EEPROM contents.
545          * PCI cards probably have PME disabled, but motherboard
546          * implementations may have PME set to enable WakeOnLan.
547          * With PME set the chip will scan incoming packets but
548          * nothing will be written to memory. */
549         OUTL(dev, SavedClkRun & ~0x100, ClkRun);
550
551         ns8382x_init_rxfilter(dev);
552         ns8382x_init_txd(dev);
553         ns8382x_init_rxd(dev);
554
555         /*set up ChipConfig */
556         config = INL(dev, ChipConfig);
557         /*turn off 64 bit ops && Ten-bit interface
558          * && big-endian mode && extended status */
559         config &= ~(TBIEn | Mode1000 | T64En | D64En | M64En | BEMode | PhyDis | ExtStEn);
560         OUTL(dev, config, ChipConfig);
561
562         /* Configure the PCI bus bursts and FIFO thresholds. */
563         tx_config = TxCarrierIgn | TxHeartIgn | TxAutoPad
564             | TxCollRetry | TxMxdma_1024 | (0x1002);
565         rx_config = RxMxdma_1024 | 0x20;
566 #ifdef NS8382X_DEBUG
567         printf("%s: Setting TxConfig Register %#08X\n", dev->name, tx_config);
568         printf("%s: Setting RxConfig Register %#08X\n", dev->name, rx_config);
569 #endif
570         OUTL(dev, tx_config, TxConfig);
571         OUTL(dev, rx_config, RxConfig);
572
573         /*turn off priority queueing */
574         OUTL(dev, 0x0, PriQueue);
575
576         ns8382x_check_duplex(dev);
577         ns8382x_set_rx_mode(dev);
578
579         OUTL(dev, (RxOn | TxOn), ChipCmd);
580         return 1;
581 }
582
583 /* Function: ns8382x_reset
584  * Description: soft resets the controller chip
585  * Arguments: struct eth_device *dev:          NIC data structure
586  * Returns:   void.
587  */
588 static void
589 ns8382x_reset(struct eth_device *dev)
590 {
591         OUTL(dev, ChipReset, ChipCmd);
592         while (INL(dev, ChipCmd))
593                 /*wait until done */ ;
594         OUTL(dev, 0, IntrMask);
595         OUTL(dev, 0, IntrEnable);
596 }
597
598 /* Function: ns8382x_init_rxfilter
599  * Description: sets receive filter address to our MAC address
600  * Arguments: struct eth_device *dev:          NIC data structure
601  * returns:   void.
602  */
603
604 static void
605 ns8382x_init_rxfilter(struct eth_device *dev)
606 {
607         int i;
608
609         for (i = 0; i < ETH_ALEN; i += 2) {
610                 OUTL(dev, i, RxFilterAddr);
611                 OUTW(dev, dev->enetaddr[i] + (dev->enetaddr[i + 1] << 8),
612                      RxFilterData);
613         }
614 }
615
616 /* Function: ns8382x_init_txd
617  * Description: initializes the Tx descriptor
618  * Arguments: struct eth_device *dev:          NIC data structure
619  * returns:   void.
620  */
621
622 static void
623 ns8382x_init_txd(struct eth_device *dev)
624 {
625         txd.link = (u32) 0;
626         txd.bufptr = cpu_to_le32((u32) & txb[0]);
627         txd.cmdsts = (u32) 0;
628         txd.extsts = (u32) 0;
629
630         OUTL(dev, 0x0, TxRingPtrHi);
631         OUTL(dev, phys_to_bus((u32)&txd), TxRingPtr);
632 #ifdef NS8382X_DEBUG
633         printf("ns8382x_init_txd: TX descriptor register loaded with: %#08X (&txd: %p)\n",
634                INL(dev, TxRingPtr), &txd);
635 #endif
636 }
637
638 /* Function: ns8382x_init_rxd
639  * Description: initializes the Rx descriptor ring
640  * Arguments: struct eth_device *dev:          NIC data structure
641  * Returns:   void.
642  */
643
644 static void
645 ns8382x_init_rxd(struct eth_device *dev)
646 {
647         int i;
648
649         OUTL(dev, 0x0, RxRingPtrHi);
650
651         cur_rx = 0;
652         for (i = 0; i < NUM_RX_DESC; i++) {
653                 rxd[i].link =
654                     cpu_to_le32((i + 1 <
655                                  NUM_RX_DESC) ? (u32) & rxd[i +
656                                                             1] : (u32) &
657                                 rxd[0]);
658                 rxd[i].extsts = cpu_to_le32((u32) 0x0);
659                 rxd[i].cmdsts = cpu_to_le32((u32) RX_BUF_SIZE);
660                 rxd[i].bufptr = cpu_to_le32((u32) & rxb[i * RX_BUF_SIZE]);
661 #ifdef NS8382X_DEBUG
662                 printf
663                     ("ns8382x_init_rxd: rxd[%d]=%p link=%X cmdsts=%X bufptr=%X\n",
664                      i, &rxd[i], le32_to_cpu(rxd[i].link),
665                      le32_to_cpu(rxd[i].cmdsts), le32_to_cpu(rxd[i].bufptr));
666 #endif
667         }
668         OUTL(dev, phys_to_bus((u32) & rxd), RxRingPtr);
669
670 #ifdef NS8382X_DEBUG
671         printf("ns8382x_init_rxd: RX descriptor register loaded with: %X\n",
672                INL(dev, RxRingPtr));
673 #endif
674 }
675
676 /* Function: ns8382x_set_rx_mode
677  * Description:
678  *    sets the receive mode to accept all broadcast packets and packets
679  *    with our MAC address, and reject all multicast packets.
680  * Arguments: struct eth_device *dev:          NIC data structure
681  * Returns:   void.
682  */
683
684 static void
685 ns8382x_set_rx_mode(struct eth_device *dev)
686 {
687         u32 rx_mode = 0x0;
688         /*spec says RxFilterEnable has to be 0 for rest of
689          * this stuff to be properly configured. Linux driver
690          * seems to support this*/
691 /*      OUTL(dev, rx_mode, RxFilterAddr);*/
692         rx_mode = (RxFilterEnable | AcceptAllBroadcast | AcceptPerfectMatch);
693         OUTL(dev, rx_mode, RxFilterAddr);
694         printf("ns8382x_set_rx_mode: set to %X\n", rx_mode);
695         /*now we turn RxFilterEnable back on */
696         /*rx_mode |= RxFilterEnable;
697         OUTL(dev, rx_mode, RxFilterAddr);*/
698 }
699
700 static void
701 ns8382x_check_duplex(struct eth_device *dev)
702 {
703         int gig = 0;
704         int hun = 0;
705         int duplex = 0;
706         int config = (INL(dev, ChipConfig) ^ SpeedStatus_Polarity);
707
708         duplex = (config & FullDuplex) ? 1 : 0;
709         gig = (config & GigSpeed) ? 1 : 0;
710         hun = (config & HundSpeed) ? 1 : 0;
711 #ifdef NS8382X_DEBUG
712         printf("%s: Setting 10%s %s-duplex based on negotiated link"
713                " capability.\n", dev->name, (gig) ? "00" : (hun) ? "0" : "",
714                duplex ? "full" : "half");
715 #endif
716         if (duplex) {
717                 rx_config |= RxAcceptTx;
718                 tx_config |= (TxCarrierIgn | TxHeartIgn);
719         } else {
720                 rx_config &= ~RxAcceptTx;
721                 tx_config &= ~(TxCarrierIgn | TxHeartIgn);
722         }
723 #ifdef NS8382X_DEBUG
724         printf("%s: Resetting TxConfig Register %#08X\n", dev->name, tx_config);
725         printf("%s: Resetting RxConfig Register %#08X\n", dev->name, rx_config);
726 #endif
727         OUTL(dev, tx_config, TxConfig);
728         OUTL(dev, rx_config, RxConfig);
729
730         /*if speed is 10 or 100, remove MODE1000,
731          * if it's 1000, then set it */
732         config = INL(dev, ChipConfig);
733         if (gig)
734                 config |= Mode1000;
735         else
736                 config &= ~Mode1000;
737
738 #ifdef NS8382X_DEBUG
739         printf("%s: %setting Mode1000\n", dev->name, (gig) ? "S" : "Uns");
740 #endif
741         OUTL(dev, config, ChipConfig);
742 }
743
744 /* Function: ns8382x_send
745  * Description: transmits a packet and waits for completion or timeout.
746  * Returns:   void.  */
747 static int
748 ns8382x_send(struct eth_device *dev, volatile void *packet, int length)
749 {
750         u32 i, status = 0;
751         vu_long tx_stat = 0;
752
753         /* Stop the transmitter */
754         OUTL(dev, TxOff, ChipCmd);
755 #ifdef NS8382X_DEBUG
756         printf("ns8382x_send: sending %d bytes\n", (int)length);
757 #endif
758
759         /* set the transmit buffer descriptor and enable Transmit State Machine */
760         txd.link = cpu_to_le32(0x0);
761         txd.bufptr = cpu_to_le32(phys_to_bus((u32)packet));
762         txd.extsts = cpu_to_le32(0x0);
763         txd.cmdsts = cpu_to_le32(DescOwn | length);
764
765         /* load Transmit Descriptor Register */
766         OUTL(dev, phys_to_bus((u32) & txd), TxRingPtr);
767 #ifdef NS8382X_DEBUG
768         printf("ns8382x_send: TX descriptor register loaded with: %#08X\n",
769                INL(dev, TxRingPtr));
770         printf("\ttxd.link:%X\tbufp:%X\texsts:%X\tcmdsts:%X\n",
771                le32_to_cpu(txd.link), le32_to_cpu(txd.bufptr),
772                le32_to_cpu(txd.extsts), le32_to_cpu(txd.cmdsts));
773 #endif
774         /* restart the transmitter */
775         OUTL(dev, TxOn, ChipCmd);
776
777         for (i = 0; (tx_stat = le32_to_cpu(txd.cmdsts)) & DescOwn; i++) {
778                 if (i >= TOUT_LOOP) {
779                         printf ("%s: tx error buffer not ready: txd.cmdsts %#lX\n",
780                              dev->name, tx_stat);
781                         goto Done;
782                 }
783         }
784
785         if (!(tx_stat & DescPktOK)) {
786                 printf("ns8382x_send: Transmit error, Tx status %lX.\n", tx_stat);
787                 goto Done;
788         }
789 #ifdef NS8382X_DEBUG
790         printf("ns8382x_send: tx_stat: %#08X\n", tx_stat);
791 #endif
792
793         status = 1;
794       Done:
795         return status;
796 }
797
798 /* Function: ns8382x_poll
799  * Description: checks for a received packet and returns it if found.
800  * Arguments: struct eth_device *dev:          NIC data structure
801  * Returns:   1 if    packet was received.
802  *            0 if no packet was received.
803  * Side effects:
804  *            Returns (copies) the packet to the array dev->packet.
805  *            Returns the length of the packet.
806  */
807
808 static int
809 ns8382x_poll(struct eth_device *dev)
810 {
811         int retstat = 0;
812         int length = 0;
813         vu_long rx_status = le32_to_cpu(rxd[cur_rx].cmdsts);
814
815         if (!(rx_status & (u32) DescOwn))
816                 return retstat;
817 #ifdef NS8382X_DEBUG
818         printf("ns8382x_poll: got a packet: cur_rx:%u, status:%lx\n",
819                cur_rx, rx_status);
820 #endif
821         length = (rx_status & DSIZE) - CRC_SIZE;
822
823         if ((rx_status & (DescMore | DescPktOK | DescRxLong)) != DescPktOK) {
824                 /* corrupted packet received */
825                 printf("ns8382x_poll: Corrupted packet, status:%lx\n", rx_status);
826                 retstat = 0;
827         } else {
828                 /* give packet to higher level routine */
829                 NetReceive((rxb + cur_rx * RX_BUF_SIZE), length);
830                 retstat = 1;
831         }
832
833         /* return the descriptor and buffer to receive ring */
834         rxd[cur_rx].cmdsts = cpu_to_le32(RX_BUF_SIZE);
835         rxd[cur_rx].bufptr = cpu_to_le32((u32) & rxb[cur_rx * RX_BUF_SIZE]);
836
837         if (++cur_rx == NUM_RX_DESC)
838                 cur_rx = 0;
839
840         /* re-enable the potentially idle receive state machine */
841         OUTL(dev, RxOn, ChipCmd);
842
843         return retstat;
844 }
845
846 /* Function: ns8382x_disable
847  * Description: Turns off interrupts and stops Tx and Rx engines
848  * Arguments: struct eth_device *dev:          NIC data structure
849  * Returns:   void.
850  */
851
852 static void
853 ns8382x_disable(struct eth_device *dev)
854 {
855         /* Disable interrupts using the mask. */
856         OUTL(dev, 0, IntrMask);
857         OUTL(dev, 0, IntrEnable);
858
859         /* Stop the chip's Tx and Rx processes. */
860         OUTL(dev, (RxOff | TxOff), ChipCmd);
861
862         /* Restore PME enable bit */
863         OUTL(dev, SavedClkRun, ClkRun);
864 }