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