Add support for friendly-arm SBC-2410X board
[oweals/u-boot.git] / drivers / natsemi.c
1 /*
2    natsemi.c: A U-Boot driver for the NatSemi DP8381x series.
3    Author: Mark A. Rakes (mark_rakes@vivato.net)
4
5    Adapted from an Etherboot driver written by:
6
7    Copyright (C) 2001 Entity Cyber, Inc.
8
9    This development of this Etherboot driver was funded by
10
11       Sicom Systems: http://www.sicompos.com/
12
13    Author: Marty Connor (mdc@thinguin.org)
14    Adapted from a Linux driver which was written by Donald Becker
15
16    This software may be used and distributed according to the terms
17    of the GNU Public License (GPL), incorporated herein by reference.
18
19    Original Copyright Notice:
20
21    Written/copyright 1999-2001 by Donald Becker.
22
23    This software may be used and distributed according to the terms of
24    the GNU General Public License (GPL), incorporated herein by reference.
25    Drivers based on or derived from this code fall under the GPL and must
26    retain the authorship, copyright and license notice.  This file is not
27    a complete program and may only be used when the entire operating
28    system is licensed under the GPL.  License for under other terms may be
29    available.  Contact the original author for details.
30
31    The original author may be reached as becker@scyld.com, or at
32    Scyld Computing Corporation
33    410 Severn Ave., Suite 210
34    Annapolis MD 21403
35
36    Support information and updates available at
37    http://www.scyld.com/network/netsemi.html
38
39    References:
40    http://www.scyld.com/expert/100mbps.html
41    http://www.scyld.com/expert/NWay.html
42    Datasheet is available from:
43    http://www.national.com/pf/DP/DP83815.html
44 */
45
46 /* Revision History
47  * October 2002 mar     1.0
48  *   Initial U-Boot Release.  Tested with Netgear FA311 board
49  *   and dp83815 chipset on custom board
50 */
51
52 /* Includes */
53 #include <common.h>
54 #include <malloc.h>
55 #include <net.h>
56 #include <asm/io.h>
57 #include <pci.h>
58
59 #if (CONFIG_COMMANDS & CFG_CMD_NET) && defined(CONFIG_NET_MULTI) && \
60         defined(CONFIG_NATSEMI)
61
62 /* defines */
63 #define EEPROM_SIZE 0xb /*12 16-bit chunks, or 24 bytes*/
64
65 #define DSIZE     0x00000FFF
66 #define ETH_ALEN        6
67 #define CRC_SIZE  4
68 #define TOUT_LOOP   500000
69 #define TX_BUF_SIZE    1536
70 #define RX_BUF_SIZE    1536
71 #define NUM_RX_DESC    4        /* Number of Rx descriptor registers. */
72
73 /* Offsets to the device registers.
74    Unlike software-only systems, device drivers interact with complex hardware.
75    It's not useful to define symbolic names for every register bit in the
76    device.  */
77 enum register_offsets {
78         ChipCmd         = 0x00,
79         ChipConfig      = 0x04,
80         EECtrl          = 0x08,
81         IntrMask        = 0x14,
82         IntrEnable      = 0x18,
83         TxRingPtr       = 0x20,
84         TxConfig        = 0x24,
85         RxRingPtr       = 0x30,
86         RxConfig        = 0x34,
87         ClkRun          = 0x3C,
88         RxFilterAddr    = 0x48,
89         RxFilterData    = 0x4C,
90         SiliconRev      = 0x58,
91         PCIPM           = 0x44,
92         BasicControl    = 0x80,
93         BasicStatus     = 0x84,
94         /* These are from the spec, around page 78... on a separate table. */
95         PGSEL           = 0xCC,
96         PMDCSR          = 0xE4,
97         TSTDAT          = 0xFC,
98         DSPCFG          = 0xF4,
99         SDCFG           = 0x8C
100 };
101
102 /* Bit in ChipCmd. */
103 enum ChipCmdBits {
104         ChipReset       = 0x100,
105         RxReset         = 0x20,
106         TxReset         = 0x10,
107         RxOff           = 0x08,
108         RxOn            = 0x04,
109         TxOff           = 0x02,
110         TxOn            = 0x01
111 };
112
113 enum ChipConfigBits {
114         LinkSts         = 0x80000000,
115         HundSpeed       = 0x40000000,
116         FullDuplex      = 0x20000000,
117         TenPolarity     = 0x10000000,
118         AnegDone        = 0x08000000,
119         AnegEnBothBoth  = 0x0000E000,
120         AnegDis100Full  = 0x0000C000,
121         AnegEn100Both   = 0x0000A000,
122         AnegDis100Half  = 0x00008000,
123         AnegEnBothHalf  = 0x00006000,
124         AnegDis10Full   = 0x00004000,
125         AnegEn10Both    = 0x00002000,
126         DuplexMask      = 0x00008000,
127         SpeedMask       = 0x00004000,
128         AnegMask        = 0x00002000,
129         AnegDis10Half   = 0x00000000,
130         ExtPhy          = 0x00001000,
131         PhyRst          = 0x00000400,
132         PhyDis          = 0x00000200,
133         BootRomDisable  = 0x00000004,
134         BEMode          = 0x00000001,
135 };
136
137 enum TxConfig_bits {
138         TxDrthMask      = 0x3f,
139         TxFlthMask      = 0x3f00,
140         TxMxdmaMask     = 0x700000,
141         TxMxdma_512     = 0x0,
142         TxMxdma_4       = 0x100000,
143         TxMxdma_8       = 0x200000,
144         TxMxdma_16      = 0x300000,
145         TxMxdma_32      = 0x400000,
146         TxMxdma_64      = 0x500000,
147         TxMxdma_128     = 0x600000,
148         TxMxdma_256     = 0x700000,
149         TxCollRetry     = 0x800000,
150         TxAutoPad       = 0x10000000,
151         TxMacLoop       = 0x20000000,
152         TxHeartIgn      = 0x40000000,
153         TxCarrierIgn    = 0x80000000
154 };
155
156 enum RxConfig_bits {
157         RxDrthMask      = 0x3e,
158         RxMxdmaMask     = 0x700000,
159         RxMxdma_512     = 0x0,
160         RxMxdma_4       = 0x100000,
161         RxMxdma_8       = 0x200000,
162         RxMxdma_16      = 0x300000,
163         RxMxdma_32      = 0x400000,
164         RxMxdma_64      = 0x500000,
165         RxMxdma_128     = 0x600000,
166         RxMxdma_256     = 0x700000,
167         RxAcceptLong    = 0x8000000,
168         RxAcceptTx      = 0x10000000,
169         RxAcceptRunt    = 0x40000000,
170         RxAcceptErr     = 0x80000000
171 };
172
173 /* Bits in the RxMode register. */
174 enum rx_mode_bits {
175         AcceptErr               = 0x20,
176         AcceptRunt              = 0x10,
177         AcceptBroadcast         = 0xC0000000,
178         AcceptMulticast         = 0x00200000,
179         AcceptAllMulticast      = 0x20000000,
180         AcceptAllPhys           = 0x10000000,
181         AcceptMyPhys            = 0x08000000
182 };
183
184 typedef struct _BufferDesc {
185         u32 link;
186         vu_long cmdsts;
187         u32 bufptr;
188         u32 software_use;
189 } BufferDesc;
190
191 /* Bits in network_desc.status */
192 enum desc_status_bits {
193         DescOwn = 0x80000000, DescMore = 0x40000000, DescIntr = 0x20000000,
194         DescNoCRC = 0x10000000, DescPktOK = 0x08000000,
195         DescSizeMask = 0xfff,
196
197         DescTxAbort = 0x04000000, DescTxFIFO = 0x02000000,
198         DescTxCarrier = 0x01000000, DescTxDefer = 0x00800000,
199         DescTxExcDefer = 0x00400000, DescTxOOWCol = 0x00200000,
200         DescTxExcColl = 0x00100000, DescTxCollCount = 0x000f0000,
201
202         DescRxAbort = 0x04000000, DescRxOver = 0x02000000,
203         DescRxDest = 0x01800000, DescRxLong = 0x00400000,
204         DescRxRunt = 0x00200000, DescRxInvalid = 0x00100000,
205         DescRxCRC = 0x00080000, DescRxAlign = 0x00040000,
206         DescRxLoop = 0x00020000, DesRxColl = 0x00010000,
207 };
208
209 /* Globals */
210 #ifdef NATSEMI_DEBUG
211 static int natsemi_debug = 0;   /* 1 verbose debugging, 0 normal */
212 #endif
213 static u32 SavedClkRun;
214 static unsigned int cur_rx;
215 static unsigned int advertising;
216 static unsigned int rx_config;
217 static unsigned int tx_config;
218
219 /* Note: transmit and receive buffers and descriptors must be
220    longword aligned */
221 static BufferDesc txd __attribute__ ((aligned(4)));
222 static BufferDesc rxd[NUM_RX_DESC] __attribute__ ((aligned(4)));
223
224 static unsigned char txb[TX_BUF_SIZE] __attribute__ ((aligned(4)));
225 static unsigned char rxb[NUM_RX_DESC * RX_BUF_SIZE]
226     __attribute__ ((aligned(4)));
227
228 /* Function Prototypes */
229 #if 0
230 static void write_eeprom(struct eth_device *dev, long addr, int location,
231                          short value);
232 #endif
233 static int read_eeprom(struct eth_device *dev, long addr, int location);
234 static int mdio_read(struct eth_device *dev, int phy_id, int location);
235 static int natsemi_init(struct eth_device *dev, bd_t * bis);
236 static void natsemi_reset(struct eth_device *dev);
237 static void natsemi_init_rxfilter(struct eth_device *dev);
238 static void natsemi_init_txd(struct eth_device *dev);
239 static void natsemi_init_rxd(struct eth_device *dev);
240 static void natsemi_set_rx_mode(struct eth_device *dev);
241 static void natsemi_check_duplex(struct eth_device *dev);
242 static int natsemi_send(struct eth_device *dev, volatile void *packet,
243                         int length);
244 static int natsemi_poll(struct eth_device *dev);
245 static void natsemi_disable(struct eth_device *dev);
246
247 static struct pci_device_id supported[] = {
248         {PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_83815},
249         {}
250 };
251
252 #define bus_to_phys(a)  pci_mem_to_phys((pci_dev_t)dev->priv, a)
253 #define phys_to_bus(a)  pci_phys_to_mem((pci_dev_t)dev->priv, a)
254
255 static inline int
256 INW(struct eth_device *dev, u_long addr)
257 {
258         return le16_to_cpu(*(vu_short *) (addr + dev->iobase));
259 }
260
261 static int
262 INL(struct eth_device *dev, u_long addr)
263 {
264         return le32_to_cpu(*(vu_long *) (addr + dev->iobase));
265 }
266
267 static inline void
268 OUTW(struct eth_device *dev, int command, u_long addr)
269 {
270         *(vu_short *) ((addr + dev->iobase)) = cpu_to_le16(command);
271 }
272
273 static inline void
274 OUTL(struct eth_device *dev, int command, u_long addr)
275 {
276         *(vu_long *) ((addr + dev->iobase)) = cpu_to_le32(command);
277 }
278
279 /*
280  * Function: natsemi_initialize
281  *
282  * Description: Retrieves the MAC address of the card, and sets up some
283  * globals required by other routines,  and initializes the NIC, making it
284  * ready to send and receive packets.
285  *
286  * Side effects:
287  *            leaves the natsemi initialized, and ready to recieve packets.
288  *
289  * Returns:   struct eth_device *:          pointer to NIC data structure
290  */
291
292 int
293 natsemi_initialize(bd_t * bis)
294 {
295         pci_dev_t devno;
296         int card_number = 0;
297         struct eth_device *dev;
298         u32 iobase, status, chip_config;
299         int i, idx = 0;
300         int prev_eedata;
301         u32 tmp;
302
303         while (1) {
304                 /* Find PCI device(s) */
305                 if ((devno = pci_find_devices(supported, idx++)) < 0) {
306                         break;
307                 }
308
309                 pci_read_config_dword(devno, PCI_BASE_ADDRESS_0, &iobase);
310                 iobase &= ~0x3; /* bit 1: unused and bit 0: I/O Space Indicator */
311
312                 pci_write_config_dword(devno, PCI_COMMAND,
313                                        PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
314
315                 /* Check if I/O accesses and Bus Mastering are enabled. */
316                 pci_read_config_dword(devno, PCI_COMMAND, &status);
317                 if (!(status & PCI_COMMAND_MEMORY)) {
318                         printf("Error: Can not enable MEM access.\n");
319                         continue;
320                 } else if (!(status & PCI_COMMAND_MASTER)) {
321                         printf("Error: Can not enable Bus Mastering.\n");
322                         continue;
323                 }
324
325                 dev = (struct eth_device *) malloc(sizeof *dev);
326
327                 sprintf(dev->name, "dp83815#%d", card_number);
328                 dev->iobase = bus_to_phys(iobase);
329 #ifdef NATSEMI_DEBUG
330                 printf("natsemi: NatSemi ns8381[56] @ %#x\n", dev->iobase);
331 #endif
332                 dev->priv = (void *) devno;
333                 dev->init = natsemi_init;
334                 dev->halt = natsemi_disable;
335                 dev->send = natsemi_send;
336                 dev->recv = natsemi_poll;
337
338                 eth_register(dev);
339
340                 card_number++;
341
342                 /* Set the latency timer for value. */
343                 pci_write_config_byte(devno, PCI_LATENCY_TIMER, 0x20);
344
345                 udelay(10 * 1000);
346
347                 /* natsemi has a non-standard PM control register
348                  * in PCI config space.  Some boards apparently need
349                  * to be brought to D0 in this manner.  */
350                 pci_read_config_dword(devno, PCIPM, &tmp);
351                 if (tmp & (0x03 | 0x100)) {
352                         /* D0 state, disable PME assertion */
353                         u32 newtmp = tmp & ~(0x03 | 0x100);
354                         pci_write_config_dword(devno, PCIPM, newtmp);
355                 }
356
357                 printf("natsemi: EEPROM contents:\n");
358                 for (i = 0; i <= EEPROM_SIZE; i++) {
359                         short eedata = read_eeprom(dev, EECtrl, i);
360                         printf(" %04hx", eedata);
361                 }
362                 printf("\n");
363
364                 /* get MAC address */
365                 prev_eedata = read_eeprom(dev, EECtrl, 6);
366                 for (i = 0; i < 3; i++) {
367                         int eedata = read_eeprom(dev, EECtrl, i + 7);
368                         dev->enetaddr[i*2] = (eedata << 1) + (prev_eedata >> 15);
369                         dev->enetaddr[i*2+1] = eedata >> 7;
370                         prev_eedata = eedata;
371                 }
372
373                 /* Reset the chip to erase any previous misconfiguration. */
374                 OUTL(dev, ChipReset, ChipCmd);
375
376                 advertising = mdio_read(dev, 1, 4);
377                 chip_config = INL(dev, ChipConfig);
378 #ifdef NATSEMI_DEBUG
379                 printf("%s: Transceiver status %#08X advertising %#08X\n",
380                         dev->name, (int) INL(dev, BasicStatus), advertising);
381                 printf("%s: Transceiver default autoneg. %s 10%s %s duplex.\n",
382                         dev->name, chip_config & AnegMask ? "enabled, advertise" :
383                         "disabled, force", chip_config & SpeedMask ? "0" : "",
384                         chip_config & DuplexMask ? "full" : "half");
385 #endif
386                 chip_config |= AnegEnBothBoth;
387 #ifdef NATSEMI_DEBUG
388                 printf("%s: changed to autoneg. %s 10%s %s duplex.\n",
389                         dev->name, chip_config & AnegMask ? "enabled, advertise" :
390                         "disabled, force", chip_config & SpeedMask ? "0" : "",
391                         chip_config & DuplexMask ? "full" : "half");
392 #endif
393                 /*write new autoneg bits, reset phy*/
394                 OUTL(dev, (chip_config | PhyRst), ChipConfig);
395                 /*un-reset phy*/
396                 OUTL(dev, chip_config, ChipConfig);
397
398                 /* Disable PME:
399                  * The PME bit is initialized from the EEPROM contents.
400                  * PCI cards probably have PME disabled, but motherboard
401                  * implementations may have PME set to enable WakeOnLan.
402                  * With PME set the chip will scan incoming packets but
403                  * nothing will be written to memory. */
404                 SavedClkRun = INL(dev, ClkRun);
405                 OUTL(dev, SavedClkRun & ~0x100, ClkRun);
406         }
407         return card_number;
408 }
409
410 /* Read the EEPROM and MII Management Data I/O (MDIO) interfaces.
411    The EEPROM code is for common 93c06/46 EEPROMs w/ 6bit addresses.  */
412
413 /* Delay between EEPROM clock transitions.
414    No extra delay is needed with 33Mhz PCI, but future 66Mhz
415    access may need a delay. */
416 #define eeprom_delay(ee_addr)   INL(dev, ee_addr)
417
418 enum EEPROM_Ctrl_Bits {
419         EE_ShiftClk = 0x04,
420         EE_DataIn = 0x01,
421         EE_ChipSelect = 0x08,
422         EE_DataOut = 0x02
423 };
424
425 #define EE_Write0 (EE_ChipSelect)
426 #define EE_Write1 (EE_ChipSelect | EE_DataIn)
427 /* The EEPROM commands include the alway-set leading bit. */
428 enum EEPROM_Cmds {
429         EE_WrEnCmd = (4 << 6), EE_WriteCmd = (5 << 6),
430         EE_ReadCmd = (6 << 6), EE_EraseCmd = (7 << 6),
431 };
432
433 #if 0
434 static void
435 write_eeprom(struct eth_device *dev, long addr, int location, short value)
436 {
437         int i;
438         int ee_addr = (typeof(ee_addr))addr;
439         short wren_cmd = EE_WrEnCmd | 0x30; /*wren is 100 + 11XXXX*/
440         short write_cmd = location | EE_WriteCmd;
441
442 #ifdef NATSEMI_DEBUG
443         printf("write_eeprom: %08x, %04hx, %04hx\n",
444                 dev->iobase + ee_addr, write_cmd, value);
445 #endif
446         /* Shift the write enable command bits out. */
447         for (i = 9; i >= 0; i--) {
448                 short cmdval = (wren_cmd & (1 << i)) ? EE_Write1 : EE_Write0;
449                 OUTL(dev, cmdval, ee_addr);
450                 eeprom_delay(ee_addr);
451                 OUTL(dev, cmdval | EE_ShiftClk, ee_addr);
452                 eeprom_delay(ee_addr);
453         }
454
455         OUTL(dev, 0, ee_addr); /*bring chip select low*/
456         OUTL(dev, EE_ShiftClk, ee_addr);
457         eeprom_delay(ee_addr);
458
459         /* Shift the write command bits out. */
460         for (i = 9; i >= 0; i--) {
461                 short cmdval = (write_cmd & (1 << i)) ? EE_Write1 : EE_Write0;
462                 OUTL(dev, cmdval, ee_addr);
463                 eeprom_delay(ee_addr);
464                 OUTL(dev, cmdval | EE_ShiftClk, ee_addr);
465                 eeprom_delay(ee_addr);
466         }
467
468         for (i = 0; i < 16; i++) {
469                 short cmdval = (value & (1 << i)) ? EE_Write1 : EE_Write0;
470                 OUTL(dev, cmdval, ee_addr);
471                 eeprom_delay(ee_addr);
472                 OUTL(dev, cmdval | EE_ShiftClk, ee_addr);
473                 eeprom_delay(ee_addr);
474         }
475
476         OUTL(dev, 0, ee_addr); /*bring chip select low*/
477         OUTL(dev, EE_ShiftClk, ee_addr);
478         for (i = 0; i < 200000; i++) {
479                 OUTL(dev, EE_Write0, ee_addr); /*poll for done*/
480                 if (INL(dev, ee_addr) & EE_DataOut) {
481                     break; /*finished*/
482                 }
483         }
484         eeprom_delay(ee_addr);
485
486         /* Terminate the EEPROM access. */
487         OUTL(dev, EE_Write0, ee_addr);
488         OUTL(dev, 0, ee_addr);
489         return;
490 }
491 #endif
492
493 static int
494 read_eeprom(struct eth_device *dev, long addr, int location)
495 {
496         int i;
497         int retval = 0;
498         int ee_addr = (typeof(ee_addr))addr;
499         int read_cmd = location | EE_ReadCmd;
500
501         OUTL(dev, EE_Write0, ee_addr);
502
503         /* Shift the read command bits out. */
504         for (i = 10; i >= 0; i--) {
505                 short dataval = (read_cmd & (1 << i)) ? EE_Write1 : EE_Write0;
506                 OUTL(dev, dataval, ee_addr);
507                 eeprom_delay(ee_addr);
508                 OUTL(dev, dataval | EE_ShiftClk, ee_addr);
509                 eeprom_delay(ee_addr);
510         }
511         OUTL(dev, EE_ChipSelect, ee_addr);
512         eeprom_delay(ee_addr);
513
514         for (i = 0; i < 16; i++) {
515                 OUTL(dev, EE_ChipSelect | EE_ShiftClk, ee_addr);
516                 eeprom_delay(ee_addr);
517                 retval |= (INL(dev, ee_addr) & EE_DataOut) ? 1 << i : 0;
518                 OUTL(dev, EE_ChipSelect, ee_addr);
519                 eeprom_delay(ee_addr);
520         }
521
522         /* Terminate the EEPROM access. */
523         OUTL(dev, EE_Write0, ee_addr);
524         OUTL(dev, 0, ee_addr);
525 #ifdef NATSEMI_DEBUG
526         if (natsemi_debug)
527                 printf("read_eeprom: %08x, %08x, retval %08x\n",
528                         dev->iobase + ee_addr, read_cmd, retval);
529 #endif
530         return retval;
531 }
532
533 /*  MII transceiver control section.
534         The 83815 series has an internal transceiver, and we present the
535         management registers as if they were MII connected. */
536
537 static int
538 mdio_read(struct eth_device *dev, int phy_id, int location)
539 {
540         if (phy_id == 1 && location < 32)
541                 return INL(dev, BasicControl+(location<<2))&0xffff;
542         else
543                 return 0xffff;
544 }
545
546 /* Function: natsemi_init
547  *
548  * Description: resets the ethernet controller chip and configures
549  *    registers and data structures required for sending and receiving packets.
550  *
551  * Arguments: struct eth_device *dev:          NIC data structure
552  *
553  * returns:     int.
554  */
555
556 static int
557 natsemi_init(struct eth_device *dev, bd_t * bis)
558 {
559
560         natsemi_reset(dev);
561
562         /* Disable PME:
563          * The PME bit is initialized from the EEPROM contents.
564          * PCI cards probably have PME disabled, but motherboard
565          * implementations may have PME set to enable WakeOnLan.
566          * With PME set the chip will scan incoming packets but
567          * nothing will be written to memory. */
568         OUTL(dev, SavedClkRun & ~0x100, ClkRun);
569
570         natsemi_init_rxfilter(dev);
571         natsemi_init_txd(dev);
572         natsemi_init_rxd(dev);
573
574         /* Configure the PCI bus bursts and FIFO thresholds. */
575         tx_config = TxAutoPad | TxCollRetry | TxMxdma_256 | (0x1002);
576         rx_config = RxMxdma_256 | 0x20;
577
578 #ifdef NATSEMI_DEBUG
579         printf("%s: Setting TxConfig Register %#08X\n", dev->name, tx_config);
580         printf("%s: Setting RxConfig Register %#08X\n", dev->name, rx_config);
581 #endif
582         OUTL(dev, tx_config, TxConfig);
583         OUTL(dev, rx_config, RxConfig);
584
585         natsemi_check_duplex(dev);
586         natsemi_set_rx_mode(dev);
587
588         OUTL(dev, (RxOn | TxOn), ChipCmd);
589         return 1;
590 }
591
592 /*
593  * Function: natsemi_reset
594  *
595  * Description: soft resets the controller chip
596  *
597  * Arguments: struct eth_device *dev:          NIC data structure
598  *
599  * Returns:   void.
600  */
601 static void
602 natsemi_reset(struct eth_device *dev)
603 {
604         OUTL(dev, ChipReset, ChipCmd);
605
606         /* On page 78 of the spec, they recommend some settings for "optimum
607            performance" to be done in sequence.  These settings optimize some
608            of the 100Mbit autodetection circuitry.  Also, we only want to do
609            this for rev C of the chip.  */
610         if (INL(dev, SiliconRev) == 0x302) {
611                 OUTW(dev, 0x0001, PGSEL);
612                 OUTW(dev, 0x189C, PMDCSR);
613                 OUTW(dev, 0x0000, TSTDAT);
614                 OUTW(dev, 0x5040, DSPCFG);
615                 OUTW(dev, 0x008C, SDCFG);
616         }
617         /* Disable interrupts using the mask. */
618         OUTL(dev, 0, IntrMask);
619         OUTL(dev, 0, IntrEnable);
620 }
621
622 /* Function: natsemi_init_rxfilter
623  *
624  * Description: sets receive filter address to our MAC address
625  *
626  * Arguments: struct eth_device *dev:          NIC data structure
627  *
628  * returns:   void.
629  */
630
631 static void
632 natsemi_init_rxfilter(struct eth_device *dev)
633 {
634         int i;
635
636         for (i = 0; i < ETH_ALEN; i += 2) {
637                 OUTL(dev, i, RxFilterAddr);
638                 OUTW(dev, dev->enetaddr[i] + (dev->enetaddr[i + 1] << 8),
639                      RxFilterData);
640         }
641 }
642
643 /*
644  * Function: natsemi_init_txd
645  *
646  * Description: initializes the Tx descriptor
647  *
648  * Arguments: struct eth_device *dev:          NIC data structure
649  *
650  * returns:   void.
651  */
652
653 static void
654 natsemi_init_txd(struct eth_device *dev)
655 {
656         txd.link = (u32) 0;
657         txd.cmdsts = (u32) 0;
658         txd.bufptr = (u32) & txb[0];
659
660         /* load Transmit Descriptor Register */
661         OUTL(dev, (u32) & txd, TxRingPtr);
662 #ifdef NATSEMI_DEBUG
663         printf("natsemi_init_txd: TX descriptor reg loaded with: %#08X\n",
664                INL(dev, TxRingPtr));
665 #endif
666 }
667
668 /* Function: natsemi_init_rxd
669  *
670  * Description: initializes the Rx descriptor ring
671  *
672  * Arguments: struct eth_device *dev:          NIC data structure
673  *
674  * Returns:   void.
675  */
676
677 static void
678 natsemi_init_rxd(struct eth_device *dev)
679 {
680         int i;
681
682         cur_rx = 0;
683
684         /* init RX descriptor */
685         for (i = 0; i < NUM_RX_DESC; i++) {
686                 rxd[i].link =
687                     cpu_to_le32((i + 1 <
688                                  NUM_RX_DESC) ? (u32) & rxd[i +
689                                                             1] : (u32) &
690                                 rxd[0]);
691                 rxd[i].cmdsts = cpu_to_le32((u32) RX_BUF_SIZE);
692                 rxd[i].bufptr = cpu_to_le32((u32) & rxb[i * RX_BUF_SIZE]);
693 #ifdef NATSEMI_DEBUG
694                 printf
695                     ("natsemi_init_rxd: rxd[%d]=%p link=%X cmdsts=%lX bufptr=%X\n",
696                         i, &rxd[i], le32_to_cpu(rxd[i].link),
697                                 rxd[i].cmdsts, rxd[i].bufptr);
698 #endif
699         }
700
701         /* load Receive Descriptor Register */
702         OUTL(dev, (u32) & rxd[0], RxRingPtr);
703
704 #ifdef NATSEMI_DEBUG
705         printf("natsemi_init_rxd: RX descriptor register loaded with: %X\n",
706                INL(dev, RxRingPtr));
707 #endif
708 }
709
710 /* Function: natsemi_set_rx_mode
711  *
712  * Description:
713  *    sets the receive mode to accept all broadcast packets and packets
714  *    with our MAC address, and reject all multicast packets.
715  *
716  * Arguments: struct eth_device *dev:          NIC data structure
717  *
718  * Returns:   void.
719  */
720
721 static void
722 natsemi_set_rx_mode(struct eth_device *dev)
723 {
724         u32 rx_mode = AcceptBroadcast | AcceptMyPhys;
725
726         OUTL(dev, rx_mode, RxFilterAddr);
727 }
728
729 static void
730 natsemi_check_duplex(struct eth_device *dev)
731 {
732         int duplex = INL(dev, ChipConfig) & FullDuplex ? 1 : 0;
733
734 #ifdef NATSEMI_DEBUG
735         printf("%s: Setting %s-duplex based on negotiated link"
736                " capability.\n", dev->name, duplex ? "full" : "half");
737 #endif
738         if (duplex) {
739                 rx_config |= RxAcceptTx;
740                 tx_config |= (TxCarrierIgn | TxHeartIgn);
741         } else {
742                 rx_config &= ~RxAcceptTx;
743                 tx_config &= ~(TxCarrierIgn | TxHeartIgn);
744         }
745         OUTL(dev, tx_config, TxConfig);
746         OUTL(dev, rx_config, RxConfig);
747 }
748
749 /* Function: natsemi_send
750  *
751  * Description: transmits a packet and waits for completion or timeout.
752  *
753  * Returns:   void.  */
754 static int
755 natsemi_send(struct eth_device *dev, volatile void *packet, int length)
756 {
757         u32 i, status = 0;
758         u32 tx_status = 0;
759         vu_long *res = (vu_long *)&tx_status;
760
761         /* Stop the transmitter */
762         OUTL(dev, TxOff, ChipCmd);
763
764 #ifdef NATSEMI_DEBUG
765         if (natsemi_debug)
766                 printf("natsemi_send: sending %d bytes\n", (int) length);
767 #endif
768
769         /* set the transmit buffer descriptor and enable Transmit State Machine */
770         txd.link = cpu_to_le32(0);
771         txd.bufptr = cpu_to_le32(phys_to_bus((u32) packet));
772         txd.cmdsts = cpu_to_le32(DescOwn | length);
773
774         /* load Transmit Descriptor Register */
775         OUTL(dev, phys_to_bus((u32) & txd), TxRingPtr);
776 #ifdef NATSEMI_DEBUG
777         if (natsemi_debug)
778             printf("natsemi_send: TX descriptor register loaded with: %#08X\n",
779              INL(dev, TxRingPtr));
780 #endif
781         /* restart the transmitter */
782         OUTL(dev, TxOn, ChipCmd);
783
784         for (i = 0;
785              (*res = le32_to_cpu(txd.cmdsts)) & DescOwn;
786              i++) {
787                 if (i >= TOUT_LOOP) {
788                         printf
789                             ("%s: tx error buffer not ready: txd.cmdsts == %#X\n",
790                              dev->name, tx_status);
791                         goto Done;
792                 }
793         }
794
795         if (!(tx_status & DescPktOK)) {
796                 printf("natsemi_send: Transmit error, Tx status %X.\n",
797                        tx_status);
798                 goto Done;
799         }
800
801         status = 1;
802       Done:
803         return status;
804 }
805
806 /* Function: natsemi_poll
807  *
808  * Description: checks for a received packet and returns it if found.
809  *
810  * Arguments: struct eth_device *dev:          NIC data structure
811  *
812  * Returns:   1 if    packet was received.
813  *            0 if no packet was received.
814  *
815  * Side effects:
816  *            Returns (copies) the packet to the array dev->packet.
817  *            Returns the length of the packet.
818  */
819
820 static int
821 natsemi_poll(struct eth_device *dev)
822 {
823         int retstat = 0;
824         int length = 0;
825         u32 rx_status = le32_to_cpu(rxd[cur_rx].cmdsts);
826
827         if (!(rx_status & (u32) DescOwn))
828                 return retstat;
829 #ifdef NATSEMI_DEBUG
830         if (natsemi_debug)
831                 printf("natsemi_poll: got a packet: cur_rx:%d, status:%X\n",
832                        cur_rx, rx_status);
833 #endif
834         length = (rx_status & DSIZE) - CRC_SIZE;
835
836         if ((rx_status & (DescMore | DescPktOK | DescRxLong)) != DescPktOK) {
837                 printf
838                     ("natsemi_poll: Corrupted packet received, buffer status = %X\n",
839                      rx_status);
840                 retstat = 0;
841         } else {                /* give packet to higher level routine */
842                 NetReceive((rxb + cur_rx * RX_BUF_SIZE), length);
843                 retstat = 1;
844         }
845
846         /* return the descriptor and buffer to receive ring */
847         rxd[cur_rx].cmdsts = cpu_to_le32(RX_BUF_SIZE);
848         rxd[cur_rx].bufptr = cpu_to_le32((u32) & rxb[cur_rx * RX_BUF_SIZE]);
849
850         if (++cur_rx == NUM_RX_DESC)
851                 cur_rx = 0;
852
853         /* re-enable the potentially idle receive state machine */
854         OUTL(dev, RxOn, ChipCmd);
855
856         return retstat;
857 }
858
859 /* Function: natsemi_disable
860  *
861  * Description: Turns off interrupts and stops Tx and Rx engines
862  *
863  * Arguments: struct eth_device *dev:          NIC data structure
864  *
865  * Returns:   void.
866  */
867
868 static void
869 natsemi_disable(struct eth_device *dev)
870 {
871         /* Disable interrupts using the mask. */
872         OUTL(dev, 0, IntrMask);
873         OUTL(dev, 0, IntrEnable);
874
875         /* Stop the chip's Tx and Rx processes. */
876         OUTL(dev, RxOff | TxOff, ChipCmd);
877
878         /* Restore PME enable bit */
879         OUTL(dev, SavedClkRun, ClkRun);
880 }
881
882 #endif