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. */
81 /* helpful macroes if on a big_endian machine for changing byte order.
82 not strictly needed on Intel */
83 #define get_unaligned(ptr) (*(ptr))
84 #define put_unaligned(val, ptr) ((void)( *(ptr) = (val) ))
85 #define get_u16(ptr) (*(u16 *)(ptr))
86 #define virt_to_le32desc(addr) virt_to_bus(addr)
91 PCI_USES_MASTER
= 0x04,
96 /* MMIO operations required */
97 #define PCI_IOTYPE (PCI_USES_MASTER | PCI_USES_MEM | PCI_ADDR1)
99 /* Offsets to the device registers.
100 Unlike software-only systems, device drivers interact with complex hardware.
101 It's not useful to define symbolic names for every register bit in the
104 enum register_offsets
{
134 /* These are from the spec, around page 78... on a separate table. */
142 /* Bit in ChipCmd. */
153 /* Bits in the RxMode register. */
157 AcceptBroadcast
= 0xC0000000,
158 AcceptMulticast
= 0x00200000,
159 AcceptAllMulticast
= 0x20000000,
160 AcceptAllPhys
= 0x10000000,
161 AcceptMyPhys
= 0x08000000,
162 RxFilterEnable
= 0x80000000
165 typedef struct _BufferDesc
{
172 /* Bits in network_desc.status */
173 enum desc_status_bits
{
174 DescOwn
= 0x80000000,
175 DescMore
= 0x40000000,
176 DescIntr
= 0x20000000,
177 DescNoCRC
= 0x10000000,
178 DescPktOK
= 0x08000000,
179 RxTooLong
= 0x00400000
184 static int natsemi_debug
= 1; /* 1 normal messages, 0 quiet .. 7 verbose. */
186 const char *nic_name
;
188 static u32 SavedClkRun
;
191 static unsigned short vendor
, dev_id
;
192 static unsigned long ioaddr
;
194 static unsigned int cur_rx
;
196 static unsigned int advertising
;
198 static unsigned int rx_config
;
199 static unsigned int tx_config
;
201 /* Note: transmit and receive buffers and descriptors must be
205 static BufferDesc txd
__attribute__ ((aligned(4)));
206 static BufferDesc rxd
[NUM_RX_DESC
] __attribute__ ((aligned(4)));
208 static unsigned char txb
[TX_BUF_SIZE
] __attribute__ ((aligned(4)));
209 static unsigned char rxb
[NUM_RX_DESC
* RX_BUF_SIZE
] __attribute__ ((aligned(4)));
211 /* Function Prototypes */
213 static int natsemi_probe(struct dev
*dev
, 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 dev
*dev
);
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 dev
*dev
, struct pci_device
*pci
)
245 struct nic
*nic
= (struct nic
*)dev
;
250 if (pci
->ioaddr
== 0)
253 adjust_pci_device(pci
);
255 /* initialize some commonly used globals */
258 nic
->ioaddr
= pci
->ioaddr
& ~3;
260 ioaddr
= pci
->ioaddr
& ~3;
261 vendor
= pci
->vendor
;
262 dev_id
= pci
->dev_id
;
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 pcibios_read_config_dword(pci
->bus
, pci
->devfn
, PCIPM
, &tmp
);
270 if (tmp
& (0x03|0x100)) {
271 /* D0 state, disable PME assertion */
272 u32 newtmp
= tmp
& ~(0x03|0x100);
273 pcibios_write_config_dword(pci
->bus
, pci
->devfn
, 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 */
318 dev
->disable
= natsemi_disable
;
319 nic
->poll
= natsemi_poll
;
320 nic
->transmit
= natsemi_transmit
;
321 nic
->irq
= natsemi_irq
;
326 /* Read the EEPROM and MII Management Data I/O (MDIO) interfaces.
327 The EEPROM code is for the common 93c06/46 EEPROMs with 6 bit addresses.
330 /* Delay between EEPROM clock transitions.
331 No extra delay is needed with 33Mhz PCI, but future 66Mhz access may need
333 #define eeprom_delay(ee_addr) inl(ee_addr)
335 enum EEPROM_Ctrl_Bits
{
338 EE_ChipSelect
= 0x08,
342 #define EE_Write0 (EE_ChipSelect)
343 #define EE_Write1 (EE_ChipSelect | EE_DataIn)
345 /* The EEPROM commands include the alway-set leading bit. */
347 EE_WriteCmd
=(5 << 6), EE_ReadCmd
=(6 << 6), EE_EraseCmd
=(7 << 6),
350 static int eeprom_read(long addr
, int location
)
354 int ee_addr
= addr
+ EECtrl
;
355 int read_cmd
= location
| EE_ReadCmd
;
356 outl(EE_Write0
, ee_addr
);
358 /* Shift the read command bits out. */
359 for (i
= 10; i
>= 0; i
--) {
360 short dataval
= (read_cmd
& (1 << i
)) ? EE_Write1
: EE_Write0
;
361 outl(dataval
, ee_addr
);
362 eeprom_delay(ee_addr
);
363 outl(dataval
| EE_ShiftClk
, ee_addr
);
364 eeprom_delay(ee_addr
);
366 outl(EE_ChipSelect
, ee_addr
);
367 eeprom_delay(ee_addr
);
369 for (i
= 0; i
< 16; i
++) {
370 outl(EE_ChipSelect
| EE_ShiftClk
, ee_addr
);
371 eeprom_delay(ee_addr
);
372 retval
|= (inl(ee_addr
) & EE_DataOut
) ? 1 << i
: 0;
373 outl(EE_ChipSelect
, ee_addr
);
374 eeprom_delay(ee_addr
);
377 /* Terminate the EEPROM access. */
378 outl(EE_Write0
, ee_addr
);
384 /* MII transceiver control section.
385 The 83815 series has an internal transceiver, and we present the
386 management registers as if they were MII connected. */
388 static int mdio_read(int phy_id
, int location
)
390 if (phy_id
== 1 && location
< 32)
391 return inl(ioaddr
+ 0x80 + (location
<<2)) & 0xffff;
396 /* Function: natsemi_init
398 * Description: resets the ethernet controller chip and configures
399 * registers and data structures required for sending and receiving packets.
401 * Arguments: struct nic *nic: NIC data structure
407 natsemi_init(struct nic
*nic
)
412 * The PME bit is initialized from the EEPROM contents.
413 * PCI cards probably have PME disabled, but motherboard
414 * implementations may have PME set to enable WakeOnLan.
415 * With PME set the chip will scan incoming packets but
416 * nothing will be written to memory. */
417 outl(SavedClkRun
& ~0x100, ioaddr
+ ClkRun
);
419 natsemi_init_rxfilter(nic
);
421 natsemi_init_txd(nic
);
422 natsemi_init_rxd(nic
);
424 /* Initialize other registers. */
425 /* Configure the PCI bus bursts and FIFO thresholds. */
426 /* Configure for standard, in-spec Ethernet. */
427 if (inl(ioaddr
+ ChipConfig
) & 0x20000000) { /* Full duplex */
428 tx_config
= 0xD0801002;
429 rx_config
= 0x10000020;
431 tx_config
= 0x10801002;
434 outl(tx_config
, ioaddr
+ TxConfig
);
435 outl(rx_config
, ioaddr
+ RxConfig
);
437 natsemi_check_duplex(nic
);
438 natsemi_set_rx_mode(nic
);
440 outl(RxOn
, ioaddr
+ ChipCmd
);
444 * Function: natsemi_reset
446 * Description: soft resets the controller chip
448 * Arguments: struct nic *nic: NIC data structure
453 natsemi_reset(struct nic
*nic __unused
)
455 outl(ChipReset
, ioaddr
+ ChipCmd
);
457 /* On page 78 of the spec, they recommend some settings for "optimum
458 performance" to be done in sequence. These settings optimize some
459 of the 100Mbit autodetection circuitry. Also, we only want to do
460 this for rev C of the chip.
462 if (inl(ioaddr
+ SiliconRev
) == 0x302) {
463 outw(0x0001, ioaddr
+ PGSEL
);
464 outw(0x189C, ioaddr
+ PMDCSR
);
465 outw(0x0000, ioaddr
+ TSTDAT
);
466 outw(0x5040, ioaddr
+ DSPCFG
);
467 outw(0x008C, ioaddr
+ SDCFG
);
469 /* Disable interrupts using the mask. */
470 outl(0, ioaddr
+ IntrMask
);
471 outl(0, ioaddr
+ IntrEnable
);
474 /* Function: natsemi_init_rxfilter
476 * Description: sets receive filter address to our MAC address
478 * Arguments: struct nic *nic: NIC data structure
484 natsemi_init_rxfilter(struct nic
*nic
)
488 for (i
= 0; i
< ETH_ALEN
; i
+= 2) {
489 outl(i
, ioaddr
+ RxFilterAddr
);
490 outw(nic
->node_addr
[i
] + (nic
->node_addr
[i
+1] << 8), ioaddr
+ RxFilterData
);
495 * Function: natsemi_init_txd
497 * Description: initializes the Tx descriptor
499 * Arguments: struct nic *nic: NIC data structure
505 natsemi_init_txd(struct nic
*nic __unused
)
508 txd
.cmdsts
= (u32
) 0;
509 txd
.bufptr
= virt_to_bus(&txb
[0]);
511 /* load Transmit Descriptor Register */
512 outl(virt_to_bus(&txd
), ioaddr
+ TxRingPtr
);
513 if (natsemi_debug
> 1)
514 printf("natsemi_init_txd: TX descriptor register loaded with: %X\n",
515 inl(ioaddr
+ TxRingPtr
));
518 /* Function: natsemi_init_rxd
520 * Description: initializes the Rx descriptor ring
522 * Arguments: struct nic *nic: NIC data structure
528 natsemi_init_rxd(struct nic
*nic __unused
)
534 /* init RX descriptor */
535 for (i
= 0; i
< NUM_RX_DESC
; i
++) {
536 rxd
[i
].link
= virt_to_bus((i
+1 < NUM_RX_DESC
) ? &rxd
[i
+1] : &rxd
[0]);
537 rxd
[i
].cmdsts
= (u32
) RX_BUF_SIZE
;
538 rxd
[i
].bufptr
= virt_to_bus(&rxb
[i
*RX_BUF_SIZE
]);
539 if (natsemi_debug
> 1)
540 printf("natsemi_init_rxd: rxd[%d]=%X link=%X cmdsts=%X bufptr=%X\n",
541 i
, &rxd
[i
], rxd
[i
].link
, rxd
[i
].cmdsts
, rxd
[i
].bufptr
);
544 /* load Receive Descriptor Register */
545 outl(virt_to_bus(&rxd
[0]), ioaddr
+ RxRingPtr
);
547 if (natsemi_debug
> 1)
548 printf("natsemi_init_rxd: RX descriptor register loaded with: %X\n",
549 inl(ioaddr
+ RxRingPtr
));
552 /* Function: natsemi_set_rx_mode
555 * sets the receive mode to accept all broadcast packets and packets
556 * with our MAC address, and reject all multicast packets.
558 * Arguments: struct nic *nic: NIC data structure
563 static void natsemi_set_rx_mode(struct nic
*nic __unused
)
565 u32 rx_mode
= RxFilterEnable
| AcceptBroadcast
|
566 AcceptAllMulticast
| AcceptMyPhys
;
568 outl(rx_mode
, ioaddr
+ RxFilterAddr
);
571 static void natsemi_check_duplex(struct nic
*nic __unused
)
573 int duplex
= inl(ioaddr
+ ChipConfig
) & 0x20000000 ? 1 : 0;
576 printf("%s: Setting %s-duplex based on negotiated link"
577 " capability.\n", nic_name
,
578 duplex
? "full" : "half");
580 rx_config
|= 0x10000000;
581 tx_config
|= 0xC0000000;
583 rx_config
&= ~0x10000000;
584 tx_config
&= ~0xC0000000;
586 outl(tx_config
, ioaddr
+ TxConfig
);
587 outl(rx_config
, ioaddr
+ RxConfig
);
590 /* Function: natsemi_transmit
592 * Description: transmits a packet and waits for completion or timeout.
594 * Arguments: char d[6]: destination ethernet address.
595 * unsigned short t: ethernet protocol type.
596 * unsigned short s: size of the data-part of the packet.
597 * char *p: the data for the packet.
603 natsemi_transmit(struct nic
*nic
,
604 const char *d
, /* Destination */
605 unsigned int t
, /* Type */
606 unsigned int s
, /* size */
607 const char *p
) /* Packet */
612 /* Stop the transmitter */
613 outl(TxOff
, ioaddr
+ ChipCmd
);
615 /* load Transmit Descriptor Register */
616 outl(virt_to_bus(&txd
), ioaddr
+ TxRingPtr
);
617 if (natsemi_debug
> 1)
618 printf("natsemi_transmit: TX descriptor register loaded with: %X\n",
619 inl(ioaddr
+ TxRingPtr
));
621 memcpy(txb
, d
, ETH_ALEN
);
622 memcpy(txb
+ ETH_ALEN
, nic
->node_addr
, ETH_ALEN
);
624 memcpy(txb
+ 2 * ETH_ALEN
, (char*)&nstype
, 2);
625 memcpy(txb
+ ETH_HLEN
, p
, s
);
630 if (natsemi_debug
> 1)
631 printf("natsemi_transmit: sending %d bytes ethtype %hX\n", (int) s
, t
);
633 /* pad to minimum packet size */
637 /* set the transmit buffer descriptor and enable Transmit State Machine */
638 txd
.bufptr
= virt_to_bus(&txb
[0]);
639 txd
.cmdsts
= (u32
) OWN
| s
;
641 /* restart the transmitter */
642 outl(TxOn
, ioaddr
+ ChipCmd
);
644 if (natsemi_debug
> 1)
645 printf("natsemi_transmit: Queued Tx packet size %d.\n", (int) s
);
647 to
= currticks() + TX_TIMEOUT
;
649 while ((((volatile u32
) tx_status
=txd
.cmdsts
) & OWN
) && (currticks() < to
))
652 if (currticks() >= to
) {
653 printf("natsemi_transmit: TX Timeout! Tx status %X.\n", tx_status
);
656 if (!(tx_status
& 0x08000000)) {
657 printf("natsemi_transmit: Transmit error, Tx status %X.\n", tx_status
);
661 /* Function: natsemi_poll
663 * Description: checks for a received packet and returns it if found.
665 * Arguments: struct nic *nic: NIC data structure
667 * Returns: 1 if packet was received.
668 * 0 if no packet was received.
671 * Returns (copies) the packet to the array nic->packet.
672 * Returns the length of the packet in nic->packetlen.
676 natsemi_poll(struct nic
*nic
, int retrieve
)
678 u32 rx_status
= rxd
[cur_rx
].cmdsts
;
681 if (natsemi_debug
> 2)
682 printf("natsemi_poll: cur_rx:%d, status:%X\n", cur_rx
, rx_status
);
684 if (!(rx_status
& OWN
))
687 if ( ! retrieve
) return 1;
689 if (natsemi_debug
> 1)
690 printf("natsemi_poll: got a packet: cur_rx:%d, status:%X\n",
693 nic
->packetlen
= (rx_status
& DSIZE
) - CRC_SIZE
;
695 if ((rx_status
& (DescMore
|DescPktOK
|RxTooLong
)) != DescPktOK
) {
696 /* corrupted packet received */
697 printf("natsemi_poll: Corrupted packet received, buffer status = %X\n",
701 /* give packet to higher level routine */
702 memcpy(nic
->packet
, (rxb
+ cur_rx
*RX_BUF_SIZE
), nic
->packetlen
);
706 /* return the descriptor and buffer to receive ring */
707 rxd
[cur_rx
].cmdsts
= RX_BUF_SIZE
;
708 rxd
[cur_rx
].bufptr
= virt_to_bus(&rxb
[cur_rx
*RX_BUF_SIZE
]);
710 if (++cur_rx
== NUM_RX_DESC
)
713 /* re-enable the potentially idle receive state machine */
714 outl(RxOn
, ioaddr
+ ChipCmd
);
719 /* Function: natsemi_disable
721 * Description: Turns off interrupts and stops Tx and Rx engines
723 * Arguments: struct nic *nic: NIC data structure
729 natsemi_disable(struct dev
*dev
)
731 struct nic
*nic
= (struct nic
*)dev
;
732 /* merge reset and disable */
735 /* Disable interrupts using the mask. */
736 outl(0, ioaddr
+ IntrMask
);
737 outl(0, ioaddr
+ IntrEnable
);
739 /* Stop the chip's Tx and Rx processes. */
740 outl(RxOff
| TxOff
, ioaddr
+ ChipCmd
);
742 /* Restore PME enable bit */
743 outl(SavedClkRun
, ioaddr
+ ClkRun
);
746 /* Function: natsemi_irq
748 * Description: Enable, Disable, or Force interrupts
750 * Arguments: struct nic *nic: NIC data structure
751 * irq_action_t action: requested action to perform
757 natsemi_irq(struct nic
*nic __unused
, irq_action_t action __unused
)
769 static struct pci_id natsemi_nics
[] = {
770 PCI_ROM(0x100b, 0x0020, "dp83815", "DP83815"),
773 struct pci_driver natsemi_driver
= {
776 .probe
= natsemi_probe
,
778 .id_count
= sizeof(natsemi_nics
)/sizeof(natsemi_nics
[0]),