xref: /openbmc/u-boot/drivers/net/natsemi.c (revision 7fbeb642)
1 /*
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 <netdev.h>
57 #include <asm/io.h>
58 #include <pci.h>
59 
60 /* defines */
61 #define EEPROM_SIZE 0xb /*12 16-bit chunks, or 24 bytes*/
62 
63 #define DSIZE		0x00000FFF
64 #define ETH_ALEN	6
65 #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. */
70 
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.  */
75 enum register_offsets {
76 	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,
90 	BasicControl	= 0x80,
91 	BasicStatus	= 0x84,
92 	/* These are from the spec, around page 78... on a separate table. */
93 	PGSEL		= 0xCC,
94 	PMDCSR		= 0xE4,
95 	TSTDAT		= 0xFC,
96 	DSPCFG		= 0xF4,
97 	SDCFG		= 0x8C
98 };
99 
100 /* Bit in ChipCmd. */
101 enum ChipCmdBits {
102 	ChipReset	= 0x100,
103 	RxReset		= 0x20,
104 	TxReset		= 0x10,
105 	RxOff		= 0x08,
106 	RxOn		= 0x04,
107 	TxOff		= 0x02,
108 	TxOn		= 0x01
109 };
110 
111 enum ChipConfigBits {
112 	LinkSts	= 0x80000000,
113 	HundSpeed	= 0x40000000,
114 	FullDuplex	= 0x20000000,
115 	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,
128 	ExtPhy		= 0x00001000,
129 	PhyRst		= 0x00000400,
130 	PhyDis		= 0x00000200,
131 	BootRomDisable	= 0x00000004,
132 	BEMode		= 0x00000001,
133 };
134 
135 enum TxConfig_bits {
136 	TxDrthMask	= 0x3f,
137 	TxFlthMask	= 0x3f00,
138 	TxMxdmaMask	= 0x700000,
139 	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
152 };
153 
154 enum RxConfig_bits {
155 	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
169 };
170 
171 /* Bits in the RxMode register. */
172 enum rx_mode_bits {
173 	AcceptErr	= 0x20,
174 	AcceptRunt	= 0x10,
175 	AcceptBroadcast	= 0xC0000000,
176 	AcceptMulticast	= 0x00200000,
177 	AcceptAllMulticast = 0x20000000,
178 	AcceptAllPhys	= 0x10000000,
179 	AcceptMyPhys	= 0x08000000
180 };
181 
182 typedef 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 */
190 enum 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
209 static int natsemi_debug = 0;	/* 1 verbose debugging, 0 normal */
210 #endif
211 static u32 SavedClkRun;
212 static unsigned int cur_rx;
213 static unsigned int advertising;
214 static unsigned int rx_config;
215 static unsigned int tx_config;
216 
217 /* Note: transmit and receive buffers and descriptors must be
218    longword aligned */
219 static BufferDesc txd __attribute__ ((aligned(4)));
220 static BufferDesc rxd[NUM_RX_DESC] __attribute__ ((aligned(4)));
221 
222 static unsigned char txb[TX_BUF_SIZE] __attribute__ ((aligned(4)));
223 static unsigned char rxb[NUM_RX_DESC * RX_BUF_SIZE]
224     __attribute__ ((aligned(4)));
225 
226 /* Function Prototypes */
227 #if 0
228 static void write_eeprom(struct eth_device *dev, long addr, int location,
229 			 short value);
230 #endif
231 static int read_eeprom(struct eth_device *dev, long addr, int location);
232 static int mdio_read(struct eth_device *dev, int phy_id, int location);
233 static int natsemi_init(struct eth_device *dev, bd_t * bis);
234 static void natsemi_reset(struct eth_device *dev);
235 static void natsemi_init_rxfilter(struct eth_device *dev);
236 static void natsemi_init_txd(struct eth_device *dev);
237 static void natsemi_init_rxd(struct eth_device *dev);
238 static void natsemi_set_rx_mode(struct eth_device *dev);
239 static void natsemi_check_duplex(struct eth_device *dev);
240 static int natsemi_send(struct eth_device *dev, volatile void *packet,
241 			int length);
242 static int natsemi_poll(struct eth_device *dev);
243 static void natsemi_disable(struct eth_device *dev);
244 
245 static 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 
253 static inline int
254 INW(struct eth_device *dev, u_long addr)
255 {
256 	return le16_to_cpu(*(vu_short *) (addr + dev->iobase));
257 }
258 
259 static int
260 INL(struct eth_device *dev, u_long addr)
261 {
262 	return le32_to_cpu(*(vu_long *) (addr + dev->iobase));
263 }
264 
265 static inline void
266 OUTW(struct eth_device *dev, int command, u_long addr)
267 {
268 	*(vu_short *) ((addr + dev->iobase)) = cpu_to_le16(command);
269 }
270 
271 static inline void
272 OUTL(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 receive packets.
286  *
287  * Returns:   struct eth_device *:          pointer to NIC data structure
288  */
289 
290 int
291 natsemi_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 
307 		pci_read_config_dword(devno, PCI_BASE_ADDRESS_0, &iobase);
308 		iobase &= ~0x3;	/* bit 1: unused and bit 0: I/O Space Indicator */
309 
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 		if (!dev) {
325 			printf("natsemi: Can not allocate memory\n");
326 			break;
327 		}
328 		memset(dev, 0, sizeof(*dev));
329 
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",
383 			dev->name, (int) INL(dev, BasicStatus), advertising);
384 		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.
417    No extra delay is needed with 33MHz PCI, but future 66MHz
418    access may need a delay. */
419 #define eeprom_delay(ee_addr)	INL(dev, ee_addr)
420 
421 enum 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. */
431 enum 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
437 static void
438 write_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 
496 static int
497 read_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 
540 static int
541 mdio_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  *
556  * returns:	int.
557  */
558 
559 static int
560 natsemi_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  */
604 static void
605 natsemi_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 
634 static void
635 natsemi_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 
656 static void
657 natsemi_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 
680 static void
681 natsemi_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",
699 			i, &rxd[i], le32_to_cpu(rxd[i].link),
700 				rxd[i].cmdsts, rxd[i].bufptr);
701 #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 
724 static void
725 natsemi_set_rx_mode(struct eth_device *dev)
726 {
727 	u32 rx_mode = AcceptBroadcast | AcceptMyPhys;
728 
729 	OUTL(dev, rx_mode, RxFilterAddr);
730 }
731 
732 static void
733 natsemi_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.  */
757 static int
758 natsemi_send(struct eth_device *dev, volatile void *packet, int length)
759 {
760 	u32 i, status = 0;
761 	u32 tx_status = 0;
762 	u32 *tx_ptr = &tx_status;
763 	vu_long *res = (vu_long *)tx_ptr;
764 
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;
789 	     (*res = le32_to_cpu(txd.cmdsts)) & DescOwn;
790 	     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 
824 static int
825 natsemi_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 
872 static void
873 natsemi_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 }
885