blob: 4aee0481dbe48b09b325699394cfd66607b8ccf5 [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>
56#include <asm/io.h>
57#include <pci.h>
58
wdenkfe8c2802002-11-03 00:38:21 +000059/* defines */
60#define EEPROM_SIZE 0xb /*12 16-bit chunks, or 24 bytes*/
61
Wolfgang Denk53677ef2008-05-20 16:00:29 +020062#define DSIZE 0x00000FFF
wdenkfe8c2802002-11-03 00:38:21 +000063#define ETH_ALEN 6
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);
239static int natsemi_send(struct eth_device *dev, volatile void *packet,
240 int length);
241static int natsemi_poll(struct eth_device *dev);
242static void natsemi_disable(struct eth_device *dev);
243
244static struct pci_device_id supported[] = {
245 {PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_83815},
246 {}
247};
248
249#define bus_to_phys(a) pci_mem_to_phys((pci_dev_t)dev->priv, a)
250#define phys_to_bus(a) pci_phys_to_mem((pci_dev_t)dev->priv, a)
251
252static inline int
253INW(struct eth_device *dev, u_long addr)
254{
255 return le16_to_cpu(*(vu_short *) (addr + dev->iobase));
256}
257
258static int
259INL(struct eth_device *dev, u_long addr)
260{
261 return le32_to_cpu(*(vu_long *) (addr + dev->iobase));
262}
263
264static inline void
265OUTW(struct eth_device *dev, int command, u_long addr)
266{
267 *(vu_short *) ((addr + dev->iobase)) = cpu_to_le16(command);
268}
269
270static inline void
271OUTL(struct eth_device *dev, int command, u_long addr)
272{
273 *(vu_long *) ((addr + dev->iobase)) = cpu_to_le32(command);
274}
275
276/*
277 * Function: natsemi_initialize
278 *
279 * Description: Retrieves the MAC address of the card, and sets up some
280 * globals required by other routines, and initializes the NIC, making it
281 * ready to send and receive packets.
282 *
283 * Side effects:
284 * leaves the natsemi initialized, and ready to recieve packets.
285 *
286 * Returns: struct eth_device *: pointer to NIC data structure
287 */
288
289int
290natsemi_initialize(bd_t * bis)
291{
292 pci_dev_t devno;
293 int card_number = 0;
294 struct eth_device *dev;
295 u32 iobase, status, chip_config;
296 int i, idx = 0;
297 int prev_eedata;
298 u32 tmp;
299
300 while (1) {
301 /* Find PCI device(s) */
302 if ((devno = pci_find_devices(supported, idx++)) < 0) {
303 break;
304 }
305
wdenk8564acf2003-07-14 22:13:32 +0000306 pci_read_config_dword(devno, PCI_BASE_ADDRESS_0, &iobase);
307 iobase &= ~0x3; /* bit 1: unused and bit 0: I/O Space Indicator */
wdenkfe8c2802002-11-03 00:38:21 +0000308
309 pci_write_config_dword(devno, PCI_COMMAND,
310 PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
311
312 /* Check if I/O accesses and Bus Mastering are enabled. */
313 pci_read_config_dword(devno, PCI_COMMAND, &status);
314 if (!(status & PCI_COMMAND_MEMORY)) {
315 printf("Error: Can not enable MEM access.\n");
316 continue;
317 } else if (!(status & PCI_COMMAND_MASTER)) {
318 printf("Error: Can not enable Bus Mastering.\n");
319 continue;
320 }
321
322 dev = (struct eth_device *) malloc(sizeof *dev);
323
324 sprintf(dev->name, "dp83815#%d", card_number);
325 dev->iobase = bus_to_phys(iobase);
326#ifdef NATSEMI_DEBUG
327 printf("natsemi: NatSemi ns8381[56] @ %#x\n", dev->iobase);
328#endif
329 dev->priv = (void *) devno;
330 dev->init = natsemi_init;
331 dev->halt = natsemi_disable;
332 dev->send = natsemi_send;
333 dev->recv = natsemi_poll;
334
335 eth_register(dev);
336
337 card_number++;
338
339 /* Set the latency timer for value. */
340 pci_write_config_byte(devno, PCI_LATENCY_TIMER, 0x20);
341
342 udelay(10 * 1000);
343
344 /* natsemi has a non-standard PM control register
345 * in PCI config space. Some boards apparently need
346 * to be brought to D0 in this manner. */
347 pci_read_config_dword(devno, PCIPM, &tmp);
348 if (tmp & (0x03 | 0x100)) {
349 /* D0 state, disable PME assertion */
350 u32 newtmp = tmp & ~(0x03 | 0x100);
351 pci_write_config_dword(devno, PCIPM, newtmp);
352 }
353
354 printf("natsemi: EEPROM contents:\n");
355 for (i = 0; i <= EEPROM_SIZE; i++) {
356 short eedata = read_eeprom(dev, EECtrl, i);
357 printf(" %04hx", eedata);
358 }
359 printf("\n");
360
361 /* get MAC address */
362 prev_eedata = read_eeprom(dev, EECtrl, 6);
363 for (i = 0; i < 3; i++) {
364 int eedata = read_eeprom(dev, EECtrl, i + 7);
365 dev->enetaddr[i*2] = (eedata << 1) + (prev_eedata >> 15);
366 dev->enetaddr[i*2+1] = eedata >> 7;
367 prev_eedata = eedata;
368 }
369
370 /* Reset the chip to erase any previous misconfiguration. */
371 OUTL(dev, ChipReset, ChipCmd);
372
373 advertising = mdio_read(dev, 1, 4);
374 chip_config = INL(dev, ChipConfig);
375#ifdef NATSEMI_DEBUG
376 printf("%s: Transceiver status %#08X advertising %#08X\n",
Wolfgang Denk53677ef2008-05-20 16:00:29 +0200377 dev->name, (int) INL(dev, BasicStatus), advertising);
wdenkfe8c2802002-11-03 00:38:21 +0000378 printf("%s: Transceiver default autoneg. %s 10%s %s duplex.\n",
379 dev->name, chip_config & AnegMask ? "enabled, advertise" :
380 "disabled, force", chip_config & SpeedMask ? "0" : "",
381 chip_config & DuplexMask ? "full" : "half");
382#endif
383 chip_config |= AnegEnBothBoth;
384#ifdef NATSEMI_DEBUG
385 printf("%s: changed to autoneg. %s 10%s %s duplex.\n",
386 dev->name, chip_config & AnegMask ? "enabled, advertise" :
387 "disabled, force", chip_config & SpeedMask ? "0" : "",
388 chip_config & DuplexMask ? "full" : "half");
389#endif
390 /*write new autoneg bits, reset phy*/
391 OUTL(dev, (chip_config | PhyRst), ChipConfig);
392 /*un-reset phy*/
393 OUTL(dev, chip_config, ChipConfig);
394
395 /* Disable PME:
396 * The PME bit is initialized from the EEPROM contents.
397 * PCI cards probably have PME disabled, but motherboard
398 * implementations may have PME set to enable WakeOnLan.
399 * With PME set the chip will scan incoming packets but
400 * nothing will be written to memory. */
401 SavedClkRun = INL(dev, ClkRun);
402 OUTL(dev, SavedClkRun & ~0x100, ClkRun);
403 }
404 return card_number;
405}
406
407/* Read the EEPROM and MII Management Data I/O (MDIO) interfaces.
408 The EEPROM code is for common 93c06/46 EEPROMs w/ 6bit addresses. */
409
410/* Delay between EEPROM clock transitions.
411 No extra delay is needed with 33Mhz PCI, but future 66Mhz
412 access may need a delay. */
413#define eeprom_delay(ee_addr) INL(dev, ee_addr)
414
415enum EEPROM_Ctrl_Bits {
416 EE_ShiftClk = 0x04,
417 EE_DataIn = 0x01,
418 EE_ChipSelect = 0x08,
419 EE_DataOut = 0x02
420};
421
422#define EE_Write0 (EE_ChipSelect)
423#define EE_Write1 (EE_ChipSelect | EE_DataIn)
424/* The EEPROM commands include the alway-set leading bit. */
425enum EEPROM_Cmds {
426 EE_WrEnCmd = (4 << 6), EE_WriteCmd = (5 << 6),
427 EE_ReadCmd = (6 << 6), EE_EraseCmd = (7 << 6),
428};
429
430#if 0
431static void
432write_eeprom(struct eth_device *dev, long addr, int location, short value)
433{
434 int i;
435 int ee_addr = (typeof(ee_addr))addr;
436 short wren_cmd = EE_WrEnCmd | 0x30; /*wren is 100 + 11XXXX*/
437 short write_cmd = location | EE_WriteCmd;
438
439#ifdef NATSEMI_DEBUG
440 printf("write_eeprom: %08x, %04hx, %04hx\n",
441 dev->iobase + ee_addr, write_cmd, value);
442#endif
443 /* Shift the write enable command bits out. */
444 for (i = 9; i >= 0; i--) {
445 short cmdval = (wren_cmd & (1 << i)) ? EE_Write1 : EE_Write0;
446 OUTL(dev, cmdval, ee_addr);
447 eeprom_delay(ee_addr);
448 OUTL(dev, cmdval | EE_ShiftClk, ee_addr);
449 eeprom_delay(ee_addr);
450 }
451
452 OUTL(dev, 0, ee_addr); /*bring chip select low*/
453 OUTL(dev, EE_ShiftClk, ee_addr);
454 eeprom_delay(ee_addr);
455
456 /* Shift the write command bits out. */
457 for (i = 9; i >= 0; i--) {
458 short cmdval = (write_cmd & (1 << i)) ? EE_Write1 : EE_Write0;
459 OUTL(dev, cmdval, ee_addr);
460 eeprom_delay(ee_addr);
461 OUTL(dev, cmdval | EE_ShiftClk, ee_addr);
462 eeprom_delay(ee_addr);
463 }
464
465 for (i = 0; i < 16; i++) {
466 short cmdval = (value & (1 << i)) ? EE_Write1 : EE_Write0;
467 OUTL(dev, cmdval, ee_addr);
468 eeprom_delay(ee_addr);
469 OUTL(dev, cmdval | EE_ShiftClk, ee_addr);
470 eeprom_delay(ee_addr);
471 }
472
473 OUTL(dev, 0, ee_addr); /*bring chip select low*/
474 OUTL(dev, EE_ShiftClk, ee_addr);
475 for (i = 0; i < 200000; i++) {
476 OUTL(dev, EE_Write0, ee_addr); /*poll for done*/
477 if (INL(dev, ee_addr) & EE_DataOut) {
478 break; /*finished*/
479 }
480 }
481 eeprom_delay(ee_addr);
482
483 /* Terminate the EEPROM access. */
484 OUTL(dev, EE_Write0, ee_addr);
485 OUTL(dev, 0, ee_addr);
486 return;
487}
488#endif
489
490static int
491read_eeprom(struct eth_device *dev, long addr, int location)
492{
493 int i;
494 int retval = 0;
495 int ee_addr = (typeof(ee_addr))addr;
496 int read_cmd = location | EE_ReadCmd;
497
498 OUTL(dev, EE_Write0, ee_addr);
499
500 /* Shift the read command bits out. */
501 for (i = 10; i >= 0; i--) {
502 short dataval = (read_cmd & (1 << i)) ? EE_Write1 : EE_Write0;
503 OUTL(dev, dataval, ee_addr);
504 eeprom_delay(ee_addr);
505 OUTL(dev, dataval | EE_ShiftClk, ee_addr);
506 eeprom_delay(ee_addr);
507 }
508 OUTL(dev, EE_ChipSelect, ee_addr);
509 eeprom_delay(ee_addr);
510
511 for (i = 0; i < 16; i++) {
512 OUTL(dev, EE_ChipSelect | EE_ShiftClk, ee_addr);
513 eeprom_delay(ee_addr);
514 retval |= (INL(dev, ee_addr) & EE_DataOut) ? 1 << i : 0;
515 OUTL(dev, EE_ChipSelect, ee_addr);
516 eeprom_delay(ee_addr);
517 }
518
519 /* Terminate the EEPROM access. */
520 OUTL(dev, EE_Write0, ee_addr);
521 OUTL(dev, 0, ee_addr);
522#ifdef NATSEMI_DEBUG
523 if (natsemi_debug)
524 printf("read_eeprom: %08x, %08x, retval %08x\n",
525 dev->iobase + ee_addr, read_cmd, retval);
526#endif
527 return retval;
528}
529
530/* MII transceiver control section.
531 The 83815 series has an internal transceiver, and we present the
532 management registers as if they were MII connected. */
533
534static int
535mdio_read(struct eth_device *dev, int phy_id, int location)
536{
537 if (phy_id == 1 && location < 32)
538 return INL(dev, BasicControl+(location<<2))&0xffff;
539 else
540 return 0xffff;
541}
542
543/* Function: natsemi_init
544 *
545 * Description: resets the ethernet controller chip and configures
546 * registers and data structures required for sending and receiving packets.
547 *
548 * Arguments: struct eth_device *dev: NIC data structure
549 *
Wolfgang Denk53677ef2008-05-20 16:00:29 +0200550 * returns: int.
wdenkfe8c2802002-11-03 00:38:21 +0000551 */
552
553static int
554natsemi_init(struct eth_device *dev, bd_t * bis)
555{
556
557 natsemi_reset(dev);
558
559 /* Disable PME:
560 * The PME bit is initialized from the EEPROM contents.
561 * PCI cards probably have PME disabled, but motherboard
562 * implementations may have PME set to enable WakeOnLan.
563 * With PME set the chip will scan incoming packets but
564 * nothing will be written to memory. */
565 OUTL(dev, SavedClkRun & ~0x100, ClkRun);
566
567 natsemi_init_rxfilter(dev);
568 natsemi_init_txd(dev);
569 natsemi_init_rxd(dev);
570
571 /* Configure the PCI bus bursts and FIFO thresholds. */
572 tx_config = TxAutoPad | TxCollRetry | TxMxdma_256 | (0x1002);
573 rx_config = RxMxdma_256 | 0x20;
574
575#ifdef NATSEMI_DEBUG
576 printf("%s: Setting TxConfig Register %#08X\n", dev->name, tx_config);
577 printf("%s: Setting RxConfig Register %#08X\n", dev->name, rx_config);
578#endif
579 OUTL(dev, tx_config, TxConfig);
580 OUTL(dev, rx_config, RxConfig);
581
582 natsemi_check_duplex(dev);
583 natsemi_set_rx_mode(dev);
584
585 OUTL(dev, (RxOn | TxOn), ChipCmd);
586 return 1;
587}
588
589/*
590 * Function: natsemi_reset
591 *
592 * Description: soft resets the controller chip
593 *
594 * Arguments: struct eth_device *dev: NIC data structure
595 *
596 * Returns: void.
597 */
598static void
599natsemi_reset(struct eth_device *dev)
600{
601 OUTL(dev, ChipReset, ChipCmd);
602
603 /* On page 78 of the spec, they recommend some settings for "optimum
604 performance" to be done in sequence. These settings optimize some
605 of the 100Mbit autodetection circuitry. Also, we only want to do
606 this for rev C of the chip. */
607 if (INL(dev, SiliconRev) == 0x302) {
608 OUTW(dev, 0x0001, PGSEL);
609 OUTW(dev, 0x189C, PMDCSR);
610 OUTW(dev, 0x0000, TSTDAT);
611 OUTW(dev, 0x5040, DSPCFG);
612 OUTW(dev, 0x008C, SDCFG);
613 }
614 /* Disable interrupts using the mask. */
615 OUTL(dev, 0, IntrMask);
616 OUTL(dev, 0, IntrEnable);
617}
618
619/* Function: natsemi_init_rxfilter
620 *
621 * Description: sets receive filter address to our MAC address
622 *
623 * Arguments: struct eth_device *dev: NIC data structure
624 *
625 * returns: void.
626 */
627
628static void
629natsemi_init_rxfilter(struct eth_device *dev)
630{
631 int i;
632
633 for (i = 0; i < ETH_ALEN; i += 2) {
634 OUTL(dev, i, RxFilterAddr);
635 OUTW(dev, dev->enetaddr[i] + (dev->enetaddr[i + 1] << 8),
636 RxFilterData);
637 }
638}
639
640/*
641 * Function: natsemi_init_txd
642 *
643 * Description: initializes the Tx descriptor
644 *
645 * Arguments: struct eth_device *dev: NIC data structure
646 *
647 * returns: void.
648 */
649
650static void
651natsemi_init_txd(struct eth_device *dev)
652{
653 txd.link = (u32) 0;
654 txd.cmdsts = (u32) 0;
655 txd.bufptr = (u32) & txb[0];
656
657 /* load Transmit Descriptor Register */
658 OUTL(dev, (u32) & txd, TxRingPtr);
659#ifdef NATSEMI_DEBUG
660 printf("natsemi_init_txd: TX descriptor reg loaded with: %#08X\n",
661 INL(dev, TxRingPtr));
662#endif
663}
664
665/* Function: natsemi_init_rxd
666 *
667 * Description: initializes the Rx descriptor ring
668 *
669 * Arguments: struct eth_device *dev: NIC data structure
670 *
671 * Returns: void.
672 */
673
674static void
675natsemi_init_rxd(struct eth_device *dev)
676{
677 int i;
678
679 cur_rx = 0;
680
681 /* init RX descriptor */
682 for (i = 0; i < NUM_RX_DESC; i++) {
683 rxd[i].link =
684 cpu_to_le32((i + 1 <
685 NUM_RX_DESC) ? (u32) & rxd[i +
686 1] : (u32) &
687 rxd[0]);
688 rxd[i].cmdsts = cpu_to_le32((u32) RX_BUF_SIZE);
689 rxd[i].bufptr = cpu_to_le32((u32) & rxb[i * RX_BUF_SIZE]);
690#ifdef NATSEMI_DEBUG
691 printf
692 ("natsemi_init_rxd: rxd[%d]=%p link=%X cmdsts=%lX bufptr=%X\n",
Wolfgang Denk53677ef2008-05-20 16:00:29 +0200693 i, &rxd[i], le32_to_cpu(rxd[i].link),
694 rxd[i].cmdsts, rxd[i].bufptr);
wdenkfe8c2802002-11-03 00:38:21 +0000695#endif
696 }
697
698 /* load Receive Descriptor Register */
699 OUTL(dev, (u32) & rxd[0], RxRingPtr);
700
701#ifdef NATSEMI_DEBUG
702 printf("natsemi_init_rxd: RX descriptor register loaded with: %X\n",
703 INL(dev, RxRingPtr));
704#endif
705}
706
707/* Function: natsemi_set_rx_mode
708 *
709 * Description:
710 * sets the receive mode to accept all broadcast packets and packets
711 * with our MAC address, and reject all multicast packets.
712 *
713 * Arguments: struct eth_device *dev: NIC data structure
714 *
715 * Returns: void.
716 */
717
718static void
719natsemi_set_rx_mode(struct eth_device *dev)
720{
721 u32 rx_mode = AcceptBroadcast | AcceptMyPhys;
722
723 OUTL(dev, rx_mode, RxFilterAddr);
724}
725
726static void
727natsemi_check_duplex(struct eth_device *dev)
728{
729 int duplex = INL(dev, ChipConfig) & FullDuplex ? 1 : 0;
730
731#ifdef NATSEMI_DEBUG
732 printf("%s: Setting %s-duplex based on negotiated link"
733 " capability.\n", dev->name, duplex ? "full" : "half");
734#endif
735 if (duplex) {
736 rx_config |= RxAcceptTx;
737 tx_config |= (TxCarrierIgn | TxHeartIgn);
738 } else {
739 rx_config &= ~RxAcceptTx;
740 tx_config &= ~(TxCarrierIgn | TxHeartIgn);
741 }
742 OUTL(dev, tx_config, TxConfig);
743 OUTL(dev, rx_config, RxConfig);
744}
745
746/* Function: natsemi_send
747 *
748 * Description: transmits a packet and waits for completion or timeout.
749 *
750 * Returns: void. */
751static int
752natsemi_send(struct eth_device *dev, volatile void *packet, int length)
753{
754 u32 i, status = 0;
755 u32 tx_status = 0;
Wolfgang Denk77ddac92005-10-13 16:45:02 +0200756 vu_long *res = (vu_long *)&tx_status;
wdenkfe8c2802002-11-03 00:38:21 +0000757
758 /* Stop the transmitter */
759 OUTL(dev, TxOff, ChipCmd);
760
761#ifdef NATSEMI_DEBUG
762 if (natsemi_debug)
763 printf("natsemi_send: sending %d bytes\n", (int) length);
764#endif
765
766 /* set the transmit buffer descriptor and enable Transmit State Machine */
767 txd.link = cpu_to_le32(0);
768 txd.bufptr = cpu_to_le32(phys_to_bus((u32) packet));
769 txd.cmdsts = cpu_to_le32(DescOwn | length);
770
771 /* load Transmit Descriptor Register */
772 OUTL(dev, phys_to_bus((u32) & txd), TxRingPtr);
773#ifdef NATSEMI_DEBUG
774 if (natsemi_debug)
775 printf("natsemi_send: TX descriptor register loaded with: %#08X\n",
776 INL(dev, TxRingPtr));
777#endif
778 /* restart the transmitter */
779 OUTL(dev, TxOn, ChipCmd);
780
781 for (i = 0;
Wolfgang Denk77ddac92005-10-13 16:45:02 +0200782 (*res = le32_to_cpu(txd.cmdsts)) & DescOwn;
wdenkfe8c2802002-11-03 00:38:21 +0000783 i++) {
784 if (i >= TOUT_LOOP) {
785 printf
786 ("%s: tx error buffer not ready: txd.cmdsts == %#X\n",
787 dev->name, tx_status);
788 goto Done;
789 }
790 }
791
792 if (!(tx_status & DescPktOK)) {
793 printf("natsemi_send: Transmit error, Tx status %X.\n",
794 tx_status);
795 goto Done;
796 }
797
798 status = 1;
799 Done:
800 return status;
801}
802
803/* Function: natsemi_poll
804 *
805 * Description: checks for a received packet and returns it if found.
806 *
807 * Arguments: struct eth_device *dev: NIC data structure
808 *
809 * Returns: 1 if packet was received.
810 * 0 if no packet was received.
811 *
812 * Side effects:
813 * Returns (copies) the packet to the array dev->packet.
814 * Returns the length of the packet.
815 */
816
817static int
818natsemi_poll(struct eth_device *dev)
819{
820 int retstat = 0;
821 int length = 0;
822 u32 rx_status = le32_to_cpu(rxd[cur_rx].cmdsts);
823
824 if (!(rx_status & (u32) DescOwn))
825 return retstat;
826#ifdef NATSEMI_DEBUG
827 if (natsemi_debug)
828 printf("natsemi_poll: got a packet: cur_rx:%d, status:%X\n",
829 cur_rx, rx_status);
830#endif
831 length = (rx_status & DSIZE) - CRC_SIZE;
832
833 if ((rx_status & (DescMore | DescPktOK | DescRxLong)) != DescPktOK) {
834 printf
835 ("natsemi_poll: Corrupted packet received, buffer status = %X\n",
836 rx_status);
837 retstat = 0;
838 } else { /* give packet to higher level routine */
839 NetReceive((rxb + cur_rx * RX_BUF_SIZE), length);
840 retstat = 1;
841 }
842
843 /* return the descriptor and buffer to receive ring */
844 rxd[cur_rx].cmdsts = cpu_to_le32(RX_BUF_SIZE);
845 rxd[cur_rx].bufptr = cpu_to_le32((u32) & rxb[cur_rx * RX_BUF_SIZE]);
846
847 if (++cur_rx == NUM_RX_DESC)
848 cur_rx = 0;
849
850 /* re-enable the potentially idle receive state machine */
851 OUTL(dev, RxOn, ChipCmd);
852
853 return retstat;
854}
855
856/* Function: natsemi_disable
857 *
858 * Description: Turns off interrupts and stops Tx and Rx engines
859 *
860 * Arguments: struct eth_device *dev: NIC data structure
861 *
862 * Returns: void.
863 */
864
865static void
866natsemi_disable(struct eth_device *dev)
867{
868 /* Disable interrupts using the mask. */
869 OUTL(dev, 0, IntrMask);
870 OUTL(dev, 0, IntrEnable);
871
872 /* Stop the chip's Tx and Rx processes. */
873 OUTL(dev, RxOff | TxOff, ChipCmd);
874
875 /* Restore PME enable bit */
876 OUTL(dev, SavedClkRun, ClkRun);
877}