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