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