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