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