]> git.sur5r.net Git - u-boot/blob - drivers/net/ns8382x.c
arm: imx6ul: Add Engicam GEAM6UL Starter Kit initial support
[u-boot] / 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, void *packet, int length);
262 static int ns8382x_poll(struct eth_device *dev);
263 static void ns8382x_disable(struct eth_device *dev);
264
265 static struct pci_device_id supported[] = {
266         {PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_83820},
267         {}
268 };
269
270 #define bus_to_phys(a)  pci_mem_to_phys((pci_dev_t)dev->priv, a)
271 #define phys_to_bus(a)  pci_phys_to_mem((pci_dev_t)dev->priv, a)
272
273 static inline int
274 INW(struct eth_device *dev, u_long addr)
275 {
276         return le16_to_cpu(*(vu_short *) (addr + dev->iobase));
277 }
278
279 static int
280 INL(struct eth_device *dev, u_long addr)
281 {
282         return le32_to_cpu(*(vu_long *) (addr + dev->iobase));
283 }
284
285 static inline void
286 OUTW(struct eth_device *dev, int command, u_long addr)
287 {
288         *(vu_short *) ((addr + dev->iobase)) = cpu_to_le16(command);
289 }
290
291 static inline void
292 OUTL(struct eth_device *dev, int command, u_long addr)
293 {
294         *(vu_long *) ((addr + dev->iobase)) = cpu_to_le32(command);
295 }
296
297 /* Function: ns8382x_initialize
298  * Description: Retrieves the MAC address of the card, and sets up some
299  *  globals required by other routines, and initializes the NIC, making it
300  *  ready to send and receive packets.
301  * Side effects: initializes ns8382xs, ready to receive packets.
302  * Returns:   int:          number of cards found
303  */
304
305 int
306 ns8382x_initialize(bd_t * bis)
307 {
308         pci_dev_t devno;
309         int card_number = 0;
310         struct eth_device *dev;
311         u32 iobase, status;
312         int i, idx = 0;
313         u32 phyAddress;
314         u32 tmp;
315         u32 chip_config;
316
317         while (1) {             /* Find PCI device(s) */
318                 if ((devno = pci_find_devices(supported, idx++)) < 0)
319                         break;
320
321                 pci_read_config_dword(devno, PCI_BASE_ADDRESS_1, &iobase);
322                 iobase &= ~0x3; /* 1: unused and 0:I/O Space Indicator */
323
324                 debug("ns8382x: NatSemi dp8382x @ 0x%x\n", iobase);
325
326                 pci_write_config_dword(devno, PCI_COMMAND,
327                                        PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
328
329                 /* Check if I/O accesses and Bus Mastering are enabled. */
330                 pci_read_config_dword(devno, PCI_COMMAND, &status);
331                 if (!(status & PCI_COMMAND_MEMORY)) {
332                         printf("Error: Can not enable MEM access.\n");
333                         continue;
334                 } else if (!(status & PCI_COMMAND_MASTER)) {
335                         printf("Error: Can not enable Bus Mastering.\n");
336                         continue;
337                 }
338
339                 dev = (struct eth_device *) malloc(sizeof *dev);
340                 if (!dev) {
341                         printf("ns8382x: Can not allocate memory\n");
342                         break;
343                 }
344                 memset(dev, 0, sizeof(*dev));
345
346                 sprintf(dev->name, "dp8382x#%d", card_number);
347                 dev->iobase = bus_to_phys(iobase);
348                 dev->priv = (void *) devno;
349                 dev->init = ns8382x_init;
350                 dev->halt = ns8382x_disable;
351                 dev->send = ns8382x_send;
352                 dev->recv = ns8382x_poll;
353
354                 /* ns8382x has a non-standard PM control register
355                  * in PCI config space.  Some boards apparently need
356                  * to be brought to D0 in this manner.  */
357                 pci_read_config_dword(devno, PCIPM, &tmp);
358                 if (tmp & (0x03 | 0x100)) {     /* D0 state, disable PME assertion */
359                         u32 newtmp = tmp & ~(0x03 | 0x100);
360                         pci_write_config_dword(devno, PCIPM, newtmp);
361                 }
362
363                 /* get MAC address */
364                 for (i = 0; i < 3; i++) {
365                         u32 data;
366                         char *mac = (char *)&dev->enetaddr[i * 2];
367
368                         OUTL(dev, i * 2, RxFilterAddr);
369                         data = INL(dev, RxFilterData);
370                         *mac++ = data;
371                         *mac++ = data >> 8;
372                 }
373                 /* get PHY address, can't be zero */
374                 for (phyAddress = 1; phyAddress < 32; phyAddress++) {
375                         u32 rev, phy1;
376
377                         phy1 = mdio_read(dev, phyAddress, PHYIDR1);
378                         if (phy1 == 0x2000) {   /*check for 83861/91 */
379                                 rev = mdio_read(dev, phyAddress, PHYIDR2);
380                                 if ((rev & ~(0x000f)) == 0x00005c50 ||
381                                     (rev & ~(0x000f)) == 0x00005c60) {
382                                         debug("phy rev is %x\n", rev);
383                                         debug("phy address is %x\n",
384                                                phyAddress);
385                                         break;
386                                 }
387                         }
388                 }
389
390                 /* set phy to autonegotiate && advertise everything */
391                 mdio_write(dev, phyAddress, KTCR,
392                            (ktcr_adv_1000H | ktcr_adv_1000F));
393                 mdio_write(dev, phyAddress, ANAR,
394                            (anar_adv_100F | anar_adv_100H | anar_adv_10H |
395                             anar_adv_10F | anar_ieee_8023));
396                 mdio_write(dev, phyAddress, BMCR, 0x0); /*restore */
397                 mdio_write(dev, phyAddress, BMCR,
398                            (Bmcr_AutoNegEn | Bmcr_RstAutoNeg));
399                 /* Reset the chip to erase any previous misconfiguration. */
400                 OUTL(dev, (ChipReset), ChipCmd);
401
402                 chip_config = INL(dev, ChipConfig);
403                 /* reset the phy */
404                 OUTL(dev, (chip_config | PhyRst), ChipConfig);
405                 /* power up and initialize transceiver */
406                 OUTL(dev, (chip_config & ~(PhyDis)), ChipConfig);
407
408                 mdio_sync(dev, EECtrl);
409
410                 {
411                         u32 chpcfg =
412                             INL(dev, ChipConfig) ^ SpeedStatus_Polarity;
413
414                         debug("%s: Transceiver 10%s %s duplex.\n", dev->name,
415                                (chpcfg & GigSpeed) ? "00" : (chpcfg & HundSpeed)
416                                ? "0" : "",
417                                chpcfg & FullDuplex ? "full" : "half");
418                         debug("%s: %02x:%02x:%02x:%02x:%02x:%02x\n", dev->name,
419                                dev->enetaddr[0], dev->enetaddr[1],
420                                dev->enetaddr[2], dev->enetaddr[3],
421                                dev->enetaddr[4], dev->enetaddr[5]);
422                 }
423
424                 /* Disable PME:
425                  * The PME bit is initialized from the EEPROM contents.
426                  * PCI cards probably have PME disabled, but motherboard
427                  * implementations may have PME set to enable WakeOnLan.
428                  * With PME set the chip will scan incoming packets but
429                  * nothing will be written to memory. */
430                 SavedClkRun = INL(dev, ClkRun);
431                 OUTL(dev, SavedClkRun & ~0x100, ClkRun);
432
433                 eth_register(dev);
434
435                 card_number++;
436
437                 pci_write_config_byte(devno, PCI_LATENCY_TIMER, 0x60);
438
439                 udelay(10 * 1000);
440         }
441         return card_number;
442 }
443
444 /*  MII transceiver control section.
445         Read and write MII registers using software-generated serial MDIO
446         protocol.  See the MII specifications or DP83840A data sheet for details.
447
448         The maximum data clock rate is 2.5 MHz.  To meet minimum timing we
449         must flush writes to the PCI bus with a PCI read. */
450 #define mdio_delay(mdio_addr) INL(dev, mdio_addr)
451
452 #define MDIO_EnbIn  (0)
453 #define MDIO_WRITE0 (MDIO_EnbOutput)
454 #define MDIO_WRITE1 (MDIO_Data | MDIO_EnbOutput)
455
456 /* Generate the preamble required for initial synchronization and
457    a few older transceivers. */
458 static void
459 mdio_sync(struct eth_device *dev, u32 offset)
460 {
461         int bits = 32;
462
463         /* Establish sync by sending at least 32 logic ones. */
464         while (--bits >= 0) {
465                 OUTL(dev, MDIO_WRITE1, offset);
466                 mdio_delay(offset);
467                 OUTL(dev, MDIO_WRITE1 | MDIO_ShiftClk, offset);
468                 mdio_delay(offset);
469         }
470 }
471
472 static int
473 mdio_read(struct eth_device *dev, int phy_id, int addr)
474 {
475         int mii_cmd = (0xf6 << 10) | (phy_id << 5) | addr;
476         int i, retval = 0;
477
478         /* Shift the read command bits out. */
479         for (i = 15; i >= 0; i--) {
480                 int dataval = (mii_cmd & (1 << i)) ? MDIO_WRITE1 : MDIO_WRITE0;
481
482                 OUTL(dev, dataval, EECtrl);
483                 mdio_delay(EECtrl);
484                 OUTL(dev, dataval | MDIO_ShiftClk, EECtrl);
485                 mdio_delay(EECtrl);
486         }
487         /* Read the two transition, 16 data, and wire-idle bits. */
488         for (i = 19; i > 0; i--) {
489                 OUTL(dev, MDIO_EnbIn, EECtrl);
490                 mdio_delay(EECtrl);
491                 retval =
492                     (retval << 1) | ((INL(dev, EECtrl) & MDIO_Data) ? 1 : 0);
493                 OUTL(dev, MDIO_EnbIn | MDIO_ShiftClk, EECtrl);
494                 mdio_delay(EECtrl);
495         }
496         return (retval >> 1) & 0xffff;
497 }
498
499 static void
500 mdio_write(struct eth_device *dev, int phy_id, int addr, int value)
501 {
502         int mii_cmd = (0x5002 << 16) | (phy_id << 23) | (addr << 18) | value;
503         int i;
504
505         /* Shift the command bits out. */
506         for (i = 31; i >= 0; i--) {
507                 int dataval = (mii_cmd & (1 << i)) ? MDIO_WRITE1 : MDIO_WRITE0;
508
509                 OUTL(dev, dataval, EECtrl);
510                 mdio_delay(EECtrl);
511                 OUTL(dev, dataval | MDIO_ShiftClk, EECtrl);
512                 mdio_delay(EECtrl);
513         }
514         /* Clear out extra bits. */
515         for (i = 2; i > 0; i--) {
516                 OUTL(dev, MDIO_EnbIn, EECtrl);
517                 mdio_delay(EECtrl);
518                 OUTL(dev, MDIO_EnbIn | MDIO_ShiftClk, EECtrl);
519                 mdio_delay(EECtrl);
520         }
521         return;
522 }
523
524 /* Function: ns8382x_init
525  * Description: resets the ethernet controller chip and configures
526  *    registers and data structures required for sending and receiving packets.
527  * Arguments: struct eth_device *dev:       NIC data structure
528  * returns:     int.
529  */
530
531 static int
532 ns8382x_init(struct eth_device *dev, bd_t * bis)
533 {
534         u32 config;
535
536         ns8382x_reset(dev);
537
538         /* Disable PME:
539          * The PME bit is initialized from the EEPROM contents.
540          * PCI cards probably have PME disabled, but motherboard
541          * implementations may have PME set to enable WakeOnLan.
542          * With PME set the chip will scan incoming packets but
543          * nothing will be written to memory. */
544         OUTL(dev, SavedClkRun & ~0x100, ClkRun);
545
546         ns8382x_init_rxfilter(dev);
547         ns8382x_init_txd(dev);
548         ns8382x_init_rxd(dev);
549
550         /*set up ChipConfig */
551         config = INL(dev, ChipConfig);
552         /*turn off 64 bit ops && Ten-bit interface
553          * && big-endian mode && extended status */
554         config &= ~(TBIEn | Mode1000 | T64En | D64En | M64En | BEMode | PhyDis | ExtStEn);
555         OUTL(dev, config, ChipConfig);
556
557         /* Configure the PCI bus bursts and FIFO thresholds. */
558         tx_config = TxCarrierIgn | TxHeartIgn | TxAutoPad
559             | TxCollRetry | TxMxdma_1024 | (0x1002);
560         rx_config = RxMxdma_1024 | 0x20;
561
562         debug("%s: Setting TxConfig Register %#08X\n", dev->name, tx_config);
563         debug("%s: Setting RxConfig Register %#08X\n", dev->name, rx_config);
564
565         OUTL(dev, tx_config, TxConfig);
566         OUTL(dev, rx_config, RxConfig);
567
568         /*turn off priority queueing */
569         OUTL(dev, 0x0, PriQueue);
570
571         ns8382x_check_duplex(dev);
572         ns8382x_set_rx_mode(dev);
573
574         OUTL(dev, (RxOn | TxOn), ChipCmd);
575         return 1;
576 }
577
578 /* Function: ns8382x_reset
579  * Description: soft resets the controller chip
580  * Arguments: struct eth_device *dev:          NIC data structure
581  * Returns:   void.
582  */
583 static void
584 ns8382x_reset(struct eth_device *dev)
585 {
586         OUTL(dev, ChipReset, ChipCmd);
587         while (INL(dev, ChipCmd))
588                 /*wait until done */ ;
589         OUTL(dev, 0, IntrMask);
590         OUTL(dev, 0, IntrEnable);
591 }
592
593 /* Function: ns8382x_init_rxfilter
594  * Description: sets receive filter address to our MAC address
595  * Arguments: struct eth_device *dev:          NIC data structure
596  * returns:   void.
597  */
598
599 static void
600 ns8382x_init_rxfilter(struct eth_device *dev)
601 {
602         int i;
603
604         for (i = 0; i < ETH_ALEN; i += 2) {
605                 OUTL(dev, i, RxFilterAddr);
606                 OUTW(dev, dev->enetaddr[i] + (dev->enetaddr[i + 1] << 8),
607                      RxFilterData);
608         }
609 }
610
611 /* Function: ns8382x_init_txd
612  * Description: initializes the Tx descriptor
613  * Arguments: struct eth_device *dev:          NIC data structure
614  * returns:   void.
615  */
616
617 static void
618 ns8382x_init_txd(struct eth_device *dev)
619 {
620         txd.link = (u32) 0;
621         txd.bufptr = cpu_to_le32((u32) & txb[0]);
622         txd.cmdsts = (u32) 0;
623         txd.extsts = (u32) 0;
624
625         OUTL(dev, 0x0, TxRingPtrHi);
626         OUTL(dev, phys_to_bus((u32)&txd), TxRingPtr);
627
628         debug("ns8382x_init_txd: TX descriptor register loaded with: %#08X (&txd: %p)\n",
629                INL(dev, TxRingPtr), &txd);
630 }
631
632 /* Function: ns8382x_init_rxd
633  * Description: initializes the Rx descriptor ring
634  * Arguments: struct eth_device *dev:          NIC data structure
635  * Returns:   void.
636  */
637
638 static void
639 ns8382x_init_rxd(struct eth_device *dev)
640 {
641         int i;
642
643         OUTL(dev, 0x0, RxRingPtrHi);
644
645         cur_rx = 0;
646         for (i = 0; i < NUM_RX_DESC; i++) {
647                 rxd[i].link =
648                     cpu_to_le32((i + 1 <
649                                  NUM_RX_DESC) ? (u32) & rxd[i +
650                                                             1] : (u32) &
651                                 rxd[0]);
652                 rxd[i].extsts = cpu_to_le32((u32) 0x0);
653                 rxd[i].cmdsts = cpu_to_le32((u32) RX_BUF_SIZE);
654                 rxd[i].bufptr = cpu_to_le32((u32) & rxb[i * RX_BUF_SIZE]);
655
656                 debug
657                     ("ns8382x_init_rxd: rxd[%d]=%p link=%X cmdsts=%X bufptr=%X\n",
658                      i, &rxd[i], le32_to_cpu(rxd[i].link),
659                      le32_to_cpu(rxd[i].cmdsts), le32_to_cpu(rxd[i].bufptr));
660         }
661         OUTL(dev, phys_to_bus((u32) & rxd), RxRingPtr);
662
663         debug("ns8382x_init_rxd: RX descriptor register loaded with: %X\n",
664                INL(dev, RxRingPtr));
665 }
666
667 /* Function: ns8382x_set_rx_mode
668  * Description:
669  *    sets the receive mode to accept all broadcast packets and packets
670  *    with our MAC address, and reject all multicast packets.
671  * Arguments: struct eth_device *dev:          NIC data structure
672  * Returns:   void.
673  */
674
675 static void
676 ns8382x_set_rx_mode(struct eth_device *dev)
677 {
678         u32 rx_mode = 0x0;
679         /*spec says RxFilterEnable has to be 0 for rest of
680          * this stuff to be properly configured. Linux driver
681          * seems to support this*/
682 /*      OUTL(dev, rx_mode, RxFilterAddr);*/
683         rx_mode = (RxFilterEnable | AcceptAllBroadcast | AcceptPerfectMatch);
684         OUTL(dev, rx_mode, RxFilterAddr);
685         printf("ns8382x_set_rx_mode: set to %X\n", rx_mode);
686         /*now we turn RxFilterEnable back on */
687         /*rx_mode |= RxFilterEnable;
688         OUTL(dev, rx_mode, RxFilterAddr);*/
689 }
690
691 static void
692 ns8382x_check_duplex(struct eth_device *dev)
693 {
694         int gig = 0;
695         int hun = 0;
696         int duplex = 0;
697         int config = (INL(dev, ChipConfig) ^ SpeedStatus_Polarity);
698
699         duplex = (config & FullDuplex) ? 1 : 0;
700         gig = (config & GigSpeed) ? 1 : 0;
701         hun = (config & HundSpeed) ? 1 : 0;
702
703         debug("%s: Setting 10%s %s-duplex based on negotiated link"
704                " capability.\n", dev->name, (gig) ? "00" : (hun) ? "0" : "",
705                duplex ? "full" : "half");
706
707         if (duplex) {
708                 rx_config |= RxAcceptTx;
709                 tx_config |= (TxCarrierIgn | TxHeartIgn);
710         } else {
711                 rx_config &= ~RxAcceptTx;
712                 tx_config &= ~(TxCarrierIgn | TxHeartIgn);
713         }
714
715         debug("%s: Resetting TxConfig Register %#08X\n", dev->name, tx_config);
716         debug("%s: Resetting RxConfig Register %#08X\n", dev->name, rx_config);
717
718         OUTL(dev, tx_config, TxConfig);
719         OUTL(dev, rx_config, RxConfig);
720
721         /*if speed is 10 or 100, remove MODE1000,
722          * if it's 1000, then set it */
723         config = INL(dev, ChipConfig);
724         if (gig)
725                 config |= Mode1000;
726         else
727                 config &= ~Mode1000;
728
729         debug("%s: %setting Mode1000\n", dev->name, (gig) ? "S" : "Uns");
730
731         OUTL(dev, config, ChipConfig);
732 }
733
734 /* Function: ns8382x_send
735  * Description: transmits a packet and waits for completion or timeout.
736  * Returns:   void.  */
737 static int ns8382x_send(struct eth_device *dev, void *packet, int length)
738 {
739         u32 i, status = 0;
740         vu_long tx_stat = 0;
741
742         /* Stop the transmitter */
743         OUTL(dev, TxOff, ChipCmd);
744
745         debug("ns8382x_send: sending %d bytes\n", (int)length);
746
747         /* set the transmit buffer descriptor and enable Transmit State Machine */
748         txd.link = cpu_to_le32(0x0);
749         txd.bufptr = cpu_to_le32(phys_to_bus((u32)packet));
750         txd.extsts = cpu_to_le32(0x0);
751         txd.cmdsts = cpu_to_le32(DescOwn | length);
752
753         /* load Transmit Descriptor Register */
754         OUTL(dev, phys_to_bus((u32) & txd), TxRingPtr);
755
756         debug("ns8382x_send: TX descriptor register loaded with: %#08X\n",
757                INL(dev, TxRingPtr));
758         debug("\ttxd.link:%X\tbufp:%X\texsts:%X\tcmdsts:%X\n",
759                le32_to_cpu(txd.link), le32_to_cpu(txd.bufptr),
760                le32_to_cpu(txd.extsts), le32_to_cpu(txd.cmdsts));
761
762         /* restart the transmitter */
763         OUTL(dev, TxOn, ChipCmd);
764
765         for (i = 0; (tx_stat = le32_to_cpu(txd.cmdsts)) & DescOwn; i++) {
766                 if (i >= TOUT_LOOP) {
767                         printf ("%s: tx error buffer not ready: txd.cmdsts %#lX\n",
768                              dev->name, tx_stat);
769                         goto Done;
770                 }
771         }
772
773         if (!(tx_stat & DescPktOK)) {
774                 printf("ns8382x_send: Transmit error, Tx status %lX.\n", tx_stat);
775                 goto Done;
776         }
777
778         debug("ns8382x_send: tx_stat: %#08lX\n", tx_stat);
779
780         status = 1;
781 Done:
782         return status;
783 }
784
785 /* Function: ns8382x_poll
786  * Description: checks for a received packet and returns it if found.
787  * Arguments: struct eth_device *dev:          NIC data structure
788  * Returns:   1 if    packet was received.
789  *            0 if no packet was received.
790  * Side effects:
791  *            Returns (copies) the packet to the array dev->packet.
792  *            Returns the length of the packet.
793  */
794
795 static int
796 ns8382x_poll(struct eth_device *dev)
797 {
798         int retstat = 0;
799         int length = 0;
800         vu_long rx_status = le32_to_cpu(rxd[cur_rx].cmdsts);
801
802         if (!(rx_status & (u32) DescOwn))
803                 return retstat;
804
805         debug("ns8382x_poll: got a packet: cur_rx:%u, status:%lx\n",
806                cur_rx, rx_status);
807
808         length = (rx_status & DSIZE) - CRC_SIZE;
809
810         if ((rx_status & (DescMore | DescPktOK | DescRxLong)) != DescPktOK) {
811                 /* corrupted packet received */
812                 printf("ns8382x_poll: Corrupted packet, status:%lx\n",
813                        rx_status);
814                 retstat = 0;
815         } else {
816                 /* give packet to higher level routine */
817                 net_process_received_packet((rxb + cur_rx * RX_BUF_SIZE),
818                                             length);
819                 retstat = 1;
820         }
821
822         /* return the descriptor and buffer to receive ring */
823         rxd[cur_rx].cmdsts = cpu_to_le32(RX_BUF_SIZE);
824         rxd[cur_rx].bufptr = cpu_to_le32((u32) & rxb[cur_rx * RX_BUF_SIZE]);
825
826         if (++cur_rx == NUM_RX_DESC)
827                 cur_rx = 0;
828
829         /* re-enable the potentially idle receive state machine */
830         OUTL(dev, RxOn, ChipCmd);
831
832         return retstat;
833 }
834
835 /* Function: ns8382x_disable
836  * Description: Turns off interrupts and stops Tx and Rx engines
837  * Arguments: struct eth_device *dev:          NIC data structure
838  * Returns:   void.
839  */
840
841 static void
842 ns8382x_disable(struct eth_device *dev)
843 {
844         /* Disable interrupts using the mask. */
845         OUTL(dev, 0, IntrMask);
846         OUTL(dev, 0, IntrEnable);
847
848         /* Stop the chip's Tx and Rx processes. */
849         OUTL(dev, (RxOff | TxOff), ChipCmd);
850
851         /* Restore PME enable bit */
852         OUTL(dev, SavedClkRun, ClkRun);
853 }