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