1 /* -*- Mode:C; c-basic-offset:4; -*- */
4 natsemi.c: An Etherboot driver for the NatSemi DP8381x series.
6 Copyright (C) 2001 Entity Cyber, Inc.
8 This development of this Etherboot driver was funded by
10 Sicom Systems: http://www.sicompos.com/
12 Author: Marty Connor (mdc@thinguin.org)
13 Adapted from a Linux driver which was written by Donald Becker
15 This software may be used and distributed according to the terms
16 of the GNU Public License (GPL), incorporated herein by reference.
18 Original Copyright Notice:
20 Written/copyright 1999-2001 by Donald Becker.
22 This software may be used and distributed according to the terms of
23 the GNU General Public License (GPL), incorporated herein by reference.
24 Drivers based on or derived from this code fall under the GPL and must
25 retain the authorship, copyright and license notice. This file is not
26 a complete program and may only be used when the entire operating
27 system is licensed under the GPL. License for under other terms may be
28 available. Contact the original author for details.
30 The original author may be reached as becker@scyld.com, or at
31 Scyld Computing Corporation
32 410 Severn Ave., Suite 210
35 Support information and updates available at
36 http://www.scyld.com/network/netsemi.html
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
47 /* Revision History */
50 13 Dec 2003 timlegge 1.1 Enabled Multicast Support
52 Initial Release. Tested with Netgear FA311 and FA312 boards
56 #include "etherboot.h"
62 #define OWN 0x80000000
63 #define DSIZE 0x00000FFF
66 /* Time in ticks before concluding the transmitter is hung. */
67 #define TX_TIMEOUT (4*TICKS_PER_SEC)
69 #define TX_BUF_SIZE 1536
70 #define RX_BUF_SIZE 1536
72 #define NUM_RX_DESC 4 /* Number of Rx descriptor registers. */
74 /* helpful macroes if on a big_endian machine for changing byte order.
75 not strictly needed on Intel */
76 #define get_unaligned(ptr) (*(ptr))
77 #define put_unaligned(val, ptr) ((void)( *(ptr) = (val) ))
78 #define get_u16(ptr) (*(u16 *)(ptr))
79 #define virt_to_le32desc(addr) virt_to_bus(addr)
84 PCI_USES_MASTER = 0x04,
89 /* MMIO operations required */
90 #define PCI_IOTYPE (PCI_USES_MASTER | PCI_USES_MEM | PCI_ADDR1)
92 /* Offsets to the device registers.
93 Unlike software-only systems, device drivers interact with complex hardware.
94 It's not useful to define symbolic names for every register bit in the
97 enum register_offsets {
127 /* These are from the spec, around page 78... on a separate table. */
135 /* Bit in ChipCmd. */
146 /* Bits in the RxMode register. */
150 AcceptBroadcast = 0xC0000000,
151 AcceptMulticast = 0x00200000,
152 AcceptAllMulticast = 0x20000000,
153 AcceptAllPhys = 0x10000000,
154 AcceptMyPhys = 0x08000000,
155 RxFilterEnable = 0x80000000
158 typedef struct _BufferDesc {
165 /* Bits in network_desc.status */
166 enum desc_status_bits {
167 DescOwn = 0x80000000,
168 DescMore = 0x40000000,
169 DescIntr = 0x20000000,
170 DescNoCRC = 0x10000000,
171 DescPktOK = 0x08000000,
172 RxTooLong = 0x00400000
177 static struct nic_operations natsemi_operations;
179 static int natsemi_debug = 1; /* 1 normal messages, 0 quiet .. 7 verbose. */
181 const char *nic_name;
183 static u32 SavedClkRun;
186 static unsigned short vendor, dev_id;
187 static unsigned long ioaddr;
189 static unsigned int cur_rx;
191 static unsigned int advertising;
193 static unsigned int rx_config;
194 static unsigned int tx_config;
196 /* Note: transmit and receive buffers and descriptors must be
201 BufferDesc txd __attribute__ ((aligned(4)));
202 BufferDesc rxd[NUM_RX_DESC] __attribute__ ((aligned(4)));
203 unsigned char txb[TX_BUF_SIZE] __attribute__ ((aligned(4)));
204 unsigned char rxb[NUM_RX_DESC * RX_BUF_SIZE] __attribute__ ((aligned(4)));
205 } natsemi_bufs __shared;
206 #define txd natsemi_bufs.txd
207 #define rxd natsemi_bufs.rxd
208 #define txb natsemi_bufs.txb
209 #define rxb natsemi_bufs.rxb
211 /* Function Prototypes */
213 static int natsemi_probe(struct nic *nic,struct pci_device *pci);
214 static int eeprom_read(long addr, int location);
215 static int mdio_read(int phy_id, int location);
216 static void natsemi_init(struct nic *nic);
217 static void natsemi_reset(struct nic *nic);
218 static void natsemi_init_rxfilter(struct nic *nic);
219 static void natsemi_init_txd(struct nic *nic);
220 static void natsemi_init_rxd(struct nic *nic);
221 static void natsemi_set_rx_mode(struct nic *nic);
222 static void natsemi_check_duplex(struct nic *nic);
223 static void natsemi_transmit(struct nic *nic, const char *d, unsigned int t, unsigned int s, const char *p);
224 static int natsemi_poll(struct nic *nic, int retrieve);
225 static void natsemi_disable(struct nic *nic, struct pci_device *pci);
226 static void natsemi_irq(struct nic *nic, irq_action_t action);
229 * Function: natsemi_probe
231 * Description: Retrieves the MAC address of the card, and sets up some
232 * globals required by other routines, and initializes the NIC, making it
233 * ready to send and receive packets.
236 * leaves the ioaddress of the natsemi chip in the variable ioaddr.
237 * leaves the natsemi initialized, and ready to recieve packets.
239 * Returns: struct nic *: pointer to NIC data structure
243 natsemi_probe ( struct nic *nic, struct pci_device *pci ) {
249 if (pci->ioaddr == 0)
252 adjust_pci_device(pci);
254 /* initialize some commonly used globals */
257 pci_fill_nic ( nic, pci );
258 nic->ioaddr = pci->ioaddr;
260 ioaddr = pci->ioaddr;
261 vendor = pci->vendor;
262 dev_id = pci->device;
263 nic_name = pci->name;
265 /* natsemi has a non-standard PM control register
266 * in PCI config space. Some boards apparently need
267 * to be brought to D0 in this manner.
269 pci_read_config_dword(pci, PCIPM, &tmp);
270 if (tmp & (0x03|0x100)) {
271 /* D0 state, disable PME assertion */
272 u32 newtmp = tmp & ~(0x03|0x100);
273 pci_write_config_dword(pci, PCIPM, newtmp);
276 /* get MAC address */
278 prev_eedata = eeprom_read(ioaddr, 6);
279 for (i = 0; i < 3; i++) {
280 int eedata = eeprom_read(ioaddr, i + 7);
281 nic->node_addr[i*2] = (eedata << 1) + (prev_eedata >> 15);
282 nic->node_addr[i*2+1] = eedata >> 7;
283 prev_eedata = eedata;
286 printf("\nnatsemi_probe: MAC addr %! at ioaddr %#hX\n",
287 nic->node_addr, ioaddr);
288 printf("natsemi_probe: Vendor:%#hX Device:%#hX\n", vendor, dev_id);
290 /* Reset the chip to erase any previous misconfiguration. */
291 outl(ChipReset, ioaddr + ChipCmd);
293 advertising = mdio_read(1, 4);
295 u32 chip_config = inl(ioaddr + ChipConfig);
296 printf("%s: Transceiver default autoneg. %s "
299 chip_config & 0x2000 ? "enabled, advertise" : "disabled, force",
300 chip_config & 0x4000 ? "0" : "",
301 chip_config & 0x8000 ? "full" : "half");
303 printf("%s: Transceiver status %hX advertising %hX\n",
304 nic_name, (int)inl(ioaddr + 0x84), advertising);
307 * The PME bit is initialized from the EEPROM contents.
308 * PCI cards probably have PME disabled, but motherboard
309 * implementations may have PME set to enable WakeOnLan.
310 * With PME set the chip will scan incoming packets but
311 * nothing will be written to memory. */
312 SavedClkRun = inl(ioaddr + ClkRun);
313 outl(SavedClkRun & ~0x100, ioaddr + ClkRun);
315 /* initialize device */
317 nic->nic_op = &natsemi_operations;
322 /* Read the EEPROM and MII Management Data I/O (MDIO) interfaces.
323 The EEPROM code is for the common 93c06/46 EEPROMs with 6 bit addresses.
326 /* Delay between EEPROM clock transitions.
327 No extra delay is needed with 33Mhz PCI, but future 66Mhz access may need
329 #define eeprom_delay(ee_addr) inl(ee_addr)
331 enum EEPROM_Ctrl_Bits {
334 EE_ChipSelect = 0x08,
338 #define EE_Write0 (EE_ChipSelect)
339 #define EE_Write1 (EE_ChipSelect | EE_DataIn)
341 /* The EEPROM commands include the alway-set leading bit. */
343 EE_WriteCmd=(5 << 6), EE_ReadCmd=(6 << 6), EE_EraseCmd=(7 << 6),
346 static int eeprom_read(long addr, int location)
350 int ee_addr = addr + EECtrl;
351 int read_cmd = location | EE_ReadCmd;
352 outl(EE_Write0, ee_addr);
354 /* Shift the read command bits out. */
355 for (i = 10; i >= 0; i--) {
356 short dataval = (read_cmd & (1 << i)) ? EE_Write1 : EE_Write0;
357 outl(dataval, ee_addr);
358 eeprom_delay(ee_addr);
359 outl(dataval | EE_ShiftClk, ee_addr);
360 eeprom_delay(ee_addr);
362 outl(EE_ChipSelect, ee_addr);
363 eeprom_delay(ee_addr);
365 for (i = 0; i < 16; i++) {
366 outl(EE_ChipSelect | EE_ShiftClk, ee_addr);
367 eeprom_delay(ee_addr);
368 retval |= (inl(ee_addr) & EE_DataOut) ? 1 << i : 0;
369 outl(EE_ChipSelect, ee_addr);
370 eeprom_delay(ee_addr);
373 /* Terminate the EEPROM access. */
374 outl(EE_Write0, ee_addr);
380 /* MII transceiver control section.
381 The 83815 series has an internal transceiver, and we present the
382 management registers as if they were MII connected. */
384 static int mdio_read(int phy_id, int location)
386 if (phy_id == 1 && location < 32)
387 return inl(ioaddr + 0x80 + (location<<2)) & 0xffff;
392 /* Function: natsemi_init
394 * Description: resets the ethernet controller chip and configures
395 * registers and data structures required for sending and receiving packets.
397 * Arguments: struct nic *nic: NIC data structure
403 natsemi_init(struct nic *nic)
408 * The PME bit is initialized from the EEPROM contents.
409 * PCI cards probably have PME disabled, but motherboard
410 * implementations may have PME set to enable WakeOnLan.
411 * With PME set the chip will scan incoming packets but
412 * nothing will be written to memory. */
413 outl(SavedClkRun & ~0x100, ioaddr + ClkRun);
415 natsemi_init_rxfilter(nic);
417 natsemi_init_txd(nic);
418 natsemi_init_rxd(nic);
420 /* Initialize other registers. */
421 /* Configure the PCI bus bursts and FIFO thresholds. */
422 /* Configure for standard, in-spec Ethernet. */
423 if (inl(ioaddr + ChipConfig) & 0x20000000) { /* Full duplex */
424 tx_config = 0xD0801002;
425 rx_config = 0x10000020;
427 tx_config = 0x10801002;
430 outl(tx_config, ioaddr + TxConfig);
431 outl(rx_config, ioaddr + RxConfig);
433 natsemi_check_duplex(nic);
434 natsemi_set_rx_mode(nic);
436 outl(RxOn, ioaddr + ChipCmd);
440 * Function: natsemi_reset
442 * Description: soft resets the controller chip
444 * Arguments: struct nic *nic: NIC data structure
449 natsemi_reset(struct nic *nic __unused)
451 outl(ChipReset, ioaddr + ChipCmd);
453 /* On page 78 of the spec, they recommend some settings for "optimum
454 performance" to be done in sequence. These settings optimize some
455 of the 100Mbit autodetection circuitry. Also, we only want to do
456 this for rev C of the chip.
458 if (inl(ioaddr + SiliconRev) == 0x302) {
459 outw(0x0001, ioaddr + PGSEL);
460 outw(0x189C, ioaddr + PMDCSR);
461 outw(0x0000, ioaddr + TSTDAT);
462 outw(0x5040, ioaddr + DSPCFG);
463 outw(0x008C, ioaddr + SDCFG);
465 /* Disable interrupts using the mask. */
466 outl(0, ioaddr + IntrMask);
467 outl(0, ioaddr + IntrEnable);
470 /* Function: natsemi_init_rxfilter
472 * Description: sets receive filter address to our MAC address
474 * Arguments: struct nic *nic: NIC data structure
480 natsemi_init_rxfilter(struct nic *nic)
484 for (i = 0; i < ETH_ALEN; i += 2) {
485 outl(i, ioaddr + RxFilterAddr);
486 outw(nic->node_addr[i] + (nic->node_addr[i+1] << 8), ioaddr + RxFilterData);
491 * Function: natsemi_init_txd
493 * Description: initializes the Tx descriptor
495 * Arguments: struct nic *nic: NIC data structure
501 natsemi_init_txd(struct nic *nic __unused)
504 txd.cmdsts = (u32) 0;
505 txd.bufptr = virt_to_bus(&txb[0]);
507 /* load Transmit Descriptor Register */
508 outl(virt_to_bus(&txd), ioaddr + TxRingPtr);
509 if (natsemi_debug > 1)
510 printf("natsemi_init_txd: TX descriptor register loaded with: %X\n",
511 inl(ioaddr + TxRingPtr));
514 /* Function: natsemi_init_rxd
516 * Description: initializes the Rx descriptor ring
518 * Arguments: struct nic *nic: NIC data structure
524 natsemi_init_rxd(struct nic *nic __unused)
530 /* init RX descriptor */
531 for (i = 0; i < NUM_RX_DESC; i++) {
532 rxd[i].link = virt_to_bus((i+1 < NUM_RX_DESC) ? &rxd[i+1] : &rxd[0]);
533 rxd[i].cmdsts = (u32) RX_BUF_SIZE;
534 rxd[i].bufptr = virt_to_bus(&rxb[i*RX_BUF_SIZE]);
535 if (natsemi_debug > 1)
536 printf("natsemi_init_rxd: rxd[%d]=%X link=%X cmdsts=%X bufptr=%X\n",
537 i, &rxd[i], rxd[i].link, rxd[i].cmdsts, rxd[i].bufptr);
540 /* load Receive Descriptor Register */
541 outl(virt_to_bus(&rxd[0]), ioaddr + RxRingPtr);
543 if (natsemi_debug > 1)
544 printf("natsemi_init_rxd: RX descriptor register loaded with: %X\n",
545 inl(ioaddr + RxRingPtr));
548 /* Function: natsemi_set_rx_mode
551 * sets the receive mode to accept all broadcast packets and packets
552 * with our MAC address, and reject all multicast packets.
554 * Arguments: struct nic *nic: NIC data structure
559 static void natsemi_set_rx_mode(struct nic *nic __unused)
561 u32 rx_mode = RxFilterEnable | AcceptBroadcast |
562 AcceptAllMulticast | AcceptMyPhys;
564 outl(rx_mode, ioaddr + RxFilterAddr);
567 static void natsemi_check_duplex(struct nic *nic __unused)
569 int duplex = inl(ioaddr + ChipConfig) & 0x20000000 ? 1 : 0;
572 printf("%s: Setting %s-duplex based on negotiated link"
573 " capability.\n", nic_name,
574 duplex ? "full" : "half");
576 rx_config |= 0x10000000;
577 tx_config |= 0xC0000000;
579 rx_config &= ~0x10000000;
580 tx_config &= ~0xC0000000;
582 outl(tx_config, ioaddr + TxConfig);
583 outl(rx_config, ioaddr + RxConfig);
586 /* Function: natsemi_transmit
588 * Description: transmits a packet and waits for completion or timeout.
590 * Arguments: char d[6]: destination ethernet address.
591 * unsigned short t: ethernet protocol type.
592 * unsigned short s: size of the data-part of the packet.
593 * char *p: the data for the packet.
599 natsemi_transmit(struct nic *nic,
600 const char *d, /* Destination */
601 unsigned int t, /* Type */
602 unsigned int s, /* size */
603 const char *p) /* Packet */
606 volatile u32 tx_status;
608 /* Stop the transmitter */
609 outl(TxOff, ioaddr + ChipCmd);
611 /* load Transmit Descriptor Register */
612 outl(virt_to_bus(&txd), ioaddr + TxRingPtr);
613 if (natsemi_debug > 1)
614 printf("natsemi_transmit: TX descriptor register loaded with: %X\n",
615 inl(ioaddr + TxRingPtr));
617 memcpy(txb, d, ETH_ALEN);
618 memcpy(txb + ETH_ALEN, nic->node_addr, ETH_ALEN);
620 memcpy(txb + 2 * ETH_ALEN, (char*)&nstype, 2);
621 memcpy(txb + ETH_HLEN, p, s);
626 if (natsemi_debug > 1)
627 printf("natsemi_transmit: sending %d bytes ethtype %hX\n", (int) s, t);
629 /* pad to minimum packet size */
633 /* set the transmit buffer descriptor and enable Transmit State Machine */
634 txd.bufptr = virt_to_bus(&txb[0]);
635 txd.cmdsts = (u32) OWN | s;
637 /* restart the transmitter */
638 outl(TxOn, ioaddr + ChipCmd);
640 if (natsemi_debug > 1)
641 printf("natsemi_transmit: Queued Tx packet size %d.\n", (int) s);
643 to = currticks() + TX_TIMEOUT;
645 while (((tx_status=txd.cmdsts) & OWN) && (currticks() < to))
648 if (currticks() >= to) {
649 printf("natsemi_transmit: TX Timeout! Tx status %X.\n", tx_status);
652 if (!(tx_status & 0x08000000)) {
653 printf("natsemi_transmit: Transmit error, Tx status %X.\n", tx_status);
657 /* Function: natsemi_poll
659 * Description: checks for a received packet and returns it if found.
661 * Arguments: struct nic *nic: NIC data structure
663 * Returns: 1 if packet was received.
664 * 0 if no packet was received.
667 * Returns (copies) the packet to the array nic->packet.
668 * Returns the length of the packet in nic->packetlen.
672 natsemi_poll(struct nic *nic, int retrieve)
674 u32 rx_status = rxd[cur_rx].cmdsts;
677 if (natsemi_debug > 2)
678 printf("natsemi_poll: cur_rx:%d, status:%X\n", cur_rx, rx_status);
680 if (!(rx_status & OWN))
683 if ( ! retrieve ) return 1;
685 if (natsemi_debug > 1)
686 printf("natsemi_poll: got a packet: cur_rx:%d, status:%X\n",
689 nic->packetlen = (rx_status & DSIZE) - CRC_SIZE;
691 if ((rx_status & (DescMore|DescPktOK|RxTooLong)) != DescPktOK) {
692 /* corrupted packet received */
693 printf("natsemi_poll: Corrupted packet received, buffer status = %X\n",
697 /* give packet to higher level routine */
698 memcpy(nic->packet, (rxb + cur_rx*RX_BUF_SIZE), nic->packetlen);
702 /* return the descriptor and buffer to receive ring */
703 rxd[cur_rx].cmdsts = RX_BUF_SIZE;
704 rxd[cur_rx].bufptr = virt_to_bus(&rxb[cur_rx*RX_BUF_SIZE]);
706 if (++cur_rx == NUM_RX_DESC)
709 /* re-enable the potentially idle receive state machine */
710 outl(RxOn, ioaddr + ChipCmd);
715 /* Function: natsemi_disable
717 * Description: Turns off interrupts and stops Tx and Rx engines
719 * Arguments: struct nic *nic: NIC data structure
725 natsemi_disable ( struct nic *nic, struct pci_device *pci __unused ) {
729 /* Disable interrupts using the mask. */
730 outl(0, ioaddr + IntrMask);
731 outl(0, ioaddr + IntrEnable);
733 /* Stop the chip's Tx and Rx processes. */
734 outl(RxOff | TxOff, ioaddr + ChipCmd);
736 /* Restore PME enable bit */
737 outl(SavedClkRun, ioaddr + ClkRun);
740 /* Function: natsemi_irq
742 * Description: Enable, Disable, or Force interrupts
744 * Arguments: struct nic *nic: NIC data structure
745 * irq_action_t action: requested action to perform
751 natsemi_irq(struct nic *nic __unused, irq_action_t action __unused)
763 static struct nic_operations natsemi_operations = {
764 .connect = dummy_connect,
765 .poll = natsemi_poll,
766 .transmit = natsemi_transmit,
771 static struct pci_device_id natsemi_nics[] = {
772 PCI_ROM(0x100b, 0x0020, "dp83815", "DP83815"),
775 PCI_DRIVER ( natsemi_driver, natsemi_nics, PCI_NO_CLASS );
777 DRIVER ( "NATSEMI", nic_driver, pci_driver, natsemi_driver,
778 natsemi_probe, natsemi_disable );