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