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