1 /* natsemi.c - gPXE driver for the NatSemi DP8381x series. */
6 natsemi.c: An Etherboot driver for the NatSemi DP8381x series.
8 Copyright (C) 2001 Entity Cyber, Inc.
10 This development of this Etherboot driver was funded by
12 Sicom Systems: http://www.sicompos.com/
14 Author: Marty Connor (mdc@thinguin.org)
15 Adapted from a Linux driver which was written by Donald Becker
17 This software may be used and distributed according to the terms
18 of the GNU Public License (GPL), incorporated herein by reference.
20 Original Copyright Notice:
22 Written/copyright 1999-2001 by Donald Becker.
24 This software may be used and distributed according to the terms of
25 the GNU General Public License (GPL), incorporated herein by reference.
26 Drivers based on or derived from this code fall under the GPL and must
27 retain the authorship, copyright and license notice. This file is not
28 a complete program and may only be used when the entire operating
29 system is licensed under the GPL. License for under other terms may be
30 available. Contact the original author for details.
32 The original author may be reached as becker@scyld.com, or at
33 Scyld Computing Corporation
34 410 Severn Ave., Suite 210
37 Support information and updates available at
38 http://www.scyld.com/network/netsemi.html
42 http://www.scyld.com/expert/100mbps.html
43 http://www.scyld.com/expert/NWay.html
44 Datasheet is available from:
45 http://www.national.com/pf/DP/DP83815.html
49 /* Revision History */
52 02 JUL 2007 Udayan Kumar 1.2 ported the driver from etherboot to gPXE API.
53 Fully rewritten,adapting the old driver.
54 Added a circular buffer for transmit and receive.
55 transmit routine will not wait for transmission to finish.
56 poll routine deals with it.
58 13 Dec 2003 timlegge 1.1 Enabled Multicast Support
60 Initial Release. Tested with Netgear FA311 and FA312 boards
75 #include <gpxe/if_ether.h>
76 #include <gpxe/ethernet.h>
77 #include <gpxe/iobuf.h>
78 #include <gpxe/netdevice.h>
79 #include <gpxe/spi_bit.h>
80 #include <gpxe/threewire.h>
84 #define TX_RING_SIZE 4
86 #define RX_BUF_SIZE 1536
87 #define OWN 0x80000000
88 #define DSIZE 0x00000FFF
104 unsigned short ioaddr;
105 unsigned short tx_cur;
106 unsigned short tx_dirty;
107 unsigned short rx_cur;
108 struct natsemi_tx tx[TX_RING_SIZE];
109 struct natsemi_rx rx[NUM_RX_DESC];
111 /* need to add iobuf as we cannot free iobuf->data in close without this
112 * alternatively substracting sizeof(head) and sizeof(list_head) can also
115 struct io_buffer *iobuf[NUM_RX_DESC];
117 /* netdev_tx_complete needs pointer to the iobuf of the data so as to free
118 * it from the memory.
120 struct io_buffer *tx_iobuf[TX_RING_SIZE];
121 struct spi_bit_basher spibit;
122 struct spi_device eeprom;
123 struct nvo_block nvo;
128 * Support for fibre connections on Am79C874:
129 * This phy needs a special setup when connected to a fibre cable.
130 * http://www.amd.com/files/connectivitysolutions/networking/archivednetworking/22235.pdf
132 #define PHYID_AM79C874 0x0022561b
135 MII_MCTRL = 0x15, /* mode control register */
136 MII_FX_SEL = 0x0001, /* 100BASE-FX (fiber) */
137 MII_EN_SCRM = 0x0004, /* enable scrambler (tp) */
142 /* values we might find in the silicon revision register */
143 #define SRR_DP83815_C 0x0302
144 #define SRR_DP83815_D 0x0403
145 #define SRR_DP83816_A4 0x0504
146 #define SRR_DP83816_A5 0x0505
148 /* NATSEMI: Offsets to the device registers.
149 * Unlike software-only systems, device drivers interact with complex hardware.
150 * It's not useful to define symbolic names for every register bit in the
153 enum register_offsets {
183 /* These are from the spec, around page 78... on a separate table.
195 /* the values for the 'magic' registers above (PGSEL=1) */
196 #define PMDCSR_VAL 0x189c /* enable preferred adaptation circuitry */
197 #define TSTDAT_VAL 0x0
198 #define DSPCFG_VAL 0x5040
199 #define SDCFG_VAL 0x008c /* set voltage thresholds for Signal Detect */
200 #define DSPCFG_LOCK 0x20 /* coefficient lock bit in DSPCFG */
201 #define DSPCFG_COEF 0x1000 /* see coefficient (in TSTDAT) bit in DSPCFG */
202 #define TSTDAT_FIXED 0xe8 /* magic number for bad coefficients */
216 enum ChipConfig_bits {
220 CfgAnegEnable = 0x2000,
222 CfgAnegFull = 0x8000,
223 CfgAnegDone = 0x8000000,
224 CfgFullDuplex = 0x20000000,
225 CfgSpeed100 = 0x40000000,
226 CfgLink = 0x80000000,
230 /* Bits in the RxMode register.
235 AcceptBroadcast = 0xC0000000,
236 AcceptMulticast = 0x00200000,
237 AcceptAllMulticast = 0x20000000,
238 AcceptAllPhys = 0x10000000,
239 AcceptMyPhys = 0x08000000,
240 RxFilterEnable = 0x80000000
243 /* Bits in network_desc.status
245 enum desc_status_bits {
246 DescOwn = 0x80000000,
247 DescMore = 0x40000000,
248 DescIntr = 0x20000000,
249 DescNoCRC = 0x10000000,
250 DescPktOK = 0x08000000,
251 RxTooLong = 0x00400000
254 /*Bits in Interrupt Mask register
256 enum Intr_mask_register_bits {
263 /* EEPROM access , values are devices specific
265 #define EE_CS 0x08 /* EEPROM chip select */
266 #define EE_SK 0x04 /* EEPROM shift clock */
267 #define EE_DI 0x01 /* Data in */
268 #define EE_DO 0x02 /* Data out */
270 /* Offsets within EEPROM (these are word offsets)
273 #define EE_REG EECtrl
274 static uint32_t SavedClkRun;
276 static const uint8_t nat_ee_bits[] = {
277 [SPI_BIT_SCLK] = EE_SK,
278 [SPI_BIT_MOSI] = EE_DI,
279 [SPI_BIT_MISO] = EE_DO,
280 [SPI_BIT_SS(0)] = EE_CS,
283 static int nat_spi_read_bit ( struct bit_basher *basher,
284 unsigned int bit_id ) {
285 struct natsemi_nic *nat = container_of ( basher, struct natsemi_nic,
287 uint8_t mask = nat_ee_bits[bit_id];
290 eereg = inb ( nat->ioaddr + EE_REG );
291 return ( eereg & mask );
294 static void nat_spi_write_bit ( struct bit_basher *basher,
295 unsigned int bit_id, unsigned long data ) {
296 struct natsemi_nic *nat = container_of ( basher, struct natsemi_nic,
298 uint8_t mask = nat_ee_bits[bit_id];
301 eereg = inb ( nat->ioaddr + EE_REG );
303 eereg |= ( data & mask );
304 outb ( eereg, nat->ioaddr + EE_REG );
307 static struct bit_basher_operations nat_basher_ops = {
308 .read = nat_spi_read_bit,
309 .write = nat_spi_write_bit,
312 /* It looks that this portion of EEPROM can be used for
313 * non-volatile stored options. Data sheet does not talk about this region.
314 * Currently it is not working. But with some efforts it can.
316 static struct nvo_fragment nat_nvo_fragments[] = {
322 * Set up for EEPROM access
326 void nat_init_eeprom ( struct natsemi_nic *nat ) {
328 /* Initialise three-wire bus
330 nat->spibit.basher.op = &nat_basher_ops;
331 nat->spibit.bus.mode = SPI_MODE_THREEWIRE;
332 nat->spibit.endianness = SPI_BIT_LITTLE_ENDIAN;
333 init_spi_bit_basher ( &nat->spibit );
335 /*natsemi DP 83815 only supports at93c46
337 init_at93c46 ( &nat->eeprom, 16 );
338 nat->eeprom.bus = &nat->spibit.bus;
340 nat->nvo.nvs = &nat->eeprom.nvs;
341 nat->nvo.fragments = nat_nvo_fragments;
349 * Issues a hardware reset and waits for the reset to complete.
351 static void nat_reset ( struct natsemi_nic *nat ) {
357 outl ( ChipReset, nat->ioaddr + ChipCmd );
361 for ( i = 0 ; i < TX_RING_SIZE ; i++ ) {
363 nat->tx[i].cmdsts = 0;
364 nat->tx[i].bufptr = 0;
367 outl ( virt_to_bus( &nat->tx[0] ),nat->ioaddr + TxRingPtr );
368 outl ( virt_to_bus( &nat->rx[0] ),nat->ioaddr + RxRingPtr );
370 outl ( TxOff|RxOff, nat->ioaddr + ChipCmd );
372 /* Restore PME enable bit
374 outl ( SavedClkRun, nat->ioaddr + ClkRun );
378 static int mdio_read(struct net_device *netdev, int reg) {
379 struct natsemi_nic *nat = netdev->priv;
381 /* The 83815 series has two ports:
382 * - an internal transceiver
383 * - an external mii bus
385 return inw(nat->ioaddr+BasicControl+(reg<<2));
388 static void mdio_write(struct net_device *netdev, int reg, u16 data) {
389 struct natsemi_nic *nat = netdev->priv;
391 /* The 83815 series has an internal transceiver; handle separately */
392 writew(data, nat->ioaddr+BasicControl+(reg<<2));
395 static void init_phy_fixup(struct net_device *netdev) {
396 struct natsemi_nic *nat = netdev->priv;
400 uint16_t advertising;
403 /* restore stuff lost when power was out */
404 tmp = mdio_read(netdev, MII_BMCR);
405 advertising= mdio_read(netdev, MII_ADVERTISE);
406 // if (np->autoneg == AUTONEG_ENABLE) {
407 /* renegotiate if something changed */
408 if ((tmp & BMCR_ANENABLE) == 0
409 || advertising != mdio_read(netdev, MII_ADVERTISE))
411 /* turn on autonegotiation and force negotiation */
412 tmp |= (BMCR_ANENABLE | BMCR_ANRESTART);
413 mdio_write(netdev, MII_ADVERTISE, advertising);
416 /* turn off auto negotiation, set speed and duplexity */
417 // tmp &= ~(BMCR_ANENABLE | BMCR_SPEED100 | BMCR_FULLDPLX);
418 // if (np->speed == SPEED_100)
419 /// tmp |= BMCR_SPEED100;
420 // if (np->duplex == DUPLEX_FULL)
421 // tmp |= BMCR_FULLDPLX;
423 * Note: there is no good way to inform the link partner
424 * that our capabilities changed. The user has to unplug
425 * and replug the network cable after some changes, e.g.
426 * after switching from 10HD, autoneg off to 100 HD,
430 mdio_write(netdev, MII_BMCR, tmp);
431 inl(nat->ioaddr + ChipConfig);
434 /* find out what phy this is */
435 mii = (mdio_read(netdev, MII_PHYSID1) << 16)
436 + mdio_read(netdev, MII_PHYSID2);
438 /* handle external phys here */
441 /* phy specific configuration for fibre/tp operation */
442 tmp = mdio_read(netdev, MII_MCTRL);
443 tmp &= ~(MII_FX_SEL | MII_EN_SCRM);
444 //if (dev->if_port == PORT_FIBRE)
445 // tmp |= MII_FX_SEL;
448 mdio_write(netdev, MII_MCTRL, tmp);
453 cfg = inl(nat->ioaddr + ChipConfig);
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. They say we only want to
460 do this for rev C of the chip, but engineers at NSC (Bradley
461 Kennedy) recommends always setting them. If you don't, you get
462 errors on some autonegotiations that make the device unusable.
464 It seems that the DSP needs a few usec to reinitialize after
465 the start of the phy. Just retry writing these values until they
468 uint32_t srr = inl(nat->ioaddr + SiliconRev);
469 DBG ( "Natsemi : silicon revision %#04x.\n",(unsigned int)srr);
470 int NATSEMI_HW_TIMEOUT = 400;
471 for (i=0;i<NATSEMI_HW_TIMEOUT;i++) {
474 outw(1, nat->ioaddr + PGSEL);
475 outw(PMDCSR_VAL, nat->ioaddr + PMDCSR);
476 outw(TSTDAT_VAL, nat->ioaddr + TSTDAT);
477 dspcfg = (srr <= SRR_DP83815_C)?
478 DSPCFG_VAL : (DSPCFG_COEF | readw(nat->ioaddr + DSPCFG));
479 outw(dspcfg, nat->ioaddr + DSPCFG);
480 outw(SDCFG_VAL, nat->ioaddr + SDCFG);
481 outw(0, nat->ioaddr + PGSEL);
482 inl(nat->ioaddr + ChipConfig);
485 outw(1, nat->ioaddr + PGSEL);
486 dspcfg_1 = readw(nat->ioaddr + DSPCFG);
487 outw(0, nat->ioaddr + PGSEL);
488 if (dspcfg == dspcfg_1)
492 if (i==NATSEMI_HW_TIMEOUT) {
493 DBG ( "Natsemi: DSPCFG mismatch after retrying for"
494 " %d usec.\n", i*10);
496 DBG ( "NATSEMI: DSPCFG accepted after %d usec.\n",
500 * Enable PHY Specific event based interrupts. Link state change
501 * and Auto-Negotiation Completion are among the affected.
502 * Read the intr status to clear it (needed for wake events).
504 inw(nat->ioaddr + MIntrStatus);
506 outw(0x2, nat->ioaddr + MIntrCtrl);
511 * Patch up for fixing CRC errors.
512 * adapted from linux natsemi driver
515 static void do_cable_magic ( struct net_device *netdev ) {
516 struct natsemi_nic *nat = netdev->priv;
519 * 100 MBit links with short cables can trip an issue with the chip.
520 * The problem manifests as lots of CRC errors and/or flickering
521 * activity LED while idle. This process is based on instructions
522 * from engineers at National.
524 if (inl(nat->ioaddr + ChipConfig) & CfgSpeed100) {
526 outw(1, nat->ioaddr + PGSEL);
528 * coefficient visibility should already be enabled via
531 data = inw(nat->ioaddr + TSTDAT) & 0xff;
533 * the value must be negative, and within certain values
534 * (these values all come from National)
536 if (!(data & 0x80) || ((data >= 0xd8) && (data <= 0xff))) {
538 /* the bug has been triggered - fix the coefficient */
539 outw(TSTDAT_FIXED, nat->ioaddr + TSTDAT);
541 data = inw(nat->ioaddr + DSPCFG);
542 //np->dspcfg = data | DSPCFG_LOCK;
543 outw(data | DSPCFG_LOCK , nat->ioaddr + DSPCFG);
545 outw(0, nat->ioaddr + PGSEL);
553 * @v netdev Net device
554 * @ret rc Return status code
556 static int nat_open ( struct net_device *netdev ) {
557 struct natsemi_nic *nat = netdev->priv;
559 uint32_t tx_config,rx_config;
562 * The PME bit is initialized from the EEPROM contents.
563 * PCI cards probably have PME disabled, but motherboard
564 * implementations may have PME set to enable WakeOnLan.
565 * With PME set the chip will scan incoming packets but
566 * nothing will be written to memory.
568 SavedClkRun = inl ( nat->ioaddr + ClkRun );
569 outl ( SavedClkRun & ~0x100, nat->ioaddr + ClkRun );
571 /* Setting up Mac address in the NIC
573 for ( i = 0 ; i < ETH_ALEN ; i+=2 ) {
574 outl ( i,nat->ioaddr + RxFilterAddr );
575 outw ( netdev->ll_addr[i] + ( netdev->ll_addr[i + 1] << 8 ),
576 nat->ioaddr + RxFilterData );
583 for ( i = 0 ; i < TX_RING_SIZE ; i++ ) {
584 nat->tx[i].link = virt_to_bus ( ( i + 1 < TX_RING_SIZE ) ? &nat->tx[i + 1] : &nat->tx[0] );
585 nat->tx[i].cmdsts = 0;
586 nat->tx[i].bufptr = 0;
592 for ( i = 0 ; i < NUM_RX_DESC ; i++ ) {
593 nat->iobuf[i] = alloc_iob ( RX_BUF_SIZE );
594 if ( !nat->iobuf[i] )
595 goto memory_alloc_err;
596 nat->rx[i].link = virt_to_bus ( ( i + 1 < NUM_RX_DESC ) ? &nat->rx[i + 1] : &nat->rx[0] );
597 nat->rx[i].cmdsts = RX_BUF_SIZE;
598 nat->rx[i].bufptr = virt_to_bus ( nat->iobuf[i]->data );
599 // DBG ( " Address of iobuf [%d] = %x and iobuf->data = %x \n", i,
600 // nat->iobuf[i],nat->iobuf[i]->data);
603 /* load Receive Descriptor Register
605 outl ( virt_to_bus ( &nat->rx[0] ), nat->ioaddr + RxRingPtr );
606 DBG ( "Natsemi Rx descriptor loaded with: %X\n",
607 (unsigned int) inl ( nat->ioaddr + RxRingPtr ) );
611 outl ( virt_to_bus ( &nat->tx[0] ),nat->ioaddr + TxRingPtr );
612 DBG ( "Natsemi Tx descriptor loaded with: %X\n",
613 (unsigned int)inl ( nat->ioaddr + TxRingPtr ) );
617 outl ( RxFilterEnable|AcceptBroadcast|AcceptAllMulticast|AcceptMyPhys,
618 nat->ioaddr + RxFilterAddr );
620 /* Initialize other registers.
621 * Configure the PCI bus bursts and FIFO thresholds.
622 * Configure for standard, in-spec Ethernet.
624 if ( inl ( nat->ioaddr + ChipConfig ) & 0x20000000 ) { /* Full duplex */
625 tx_config = 0xD0801002 | 0xC0000000;
626 DBG ( "Full duplex\n" );
627 rx_config = 0x10000020 | 0x10000000;
629 tx_config = 0x10801002 & ~0xC0000000;
630 DBG ( "Half duplex\n" );
631 rx_config = 0x0020 & ~0x10000000;
633 outl ( tx_config, nat->ioaddr + TxConfig );
634 outl ( rx_config, nat->ioaddr + RxConfig );
636 DBG ( "Tx config register = %x Rx config register = %x\n",
637 (unsigned int) inl ( nat->ioaddr + TxConfig),
638 (unsigned int) inl ( nat->ioaddr + RxConfig) );
641 outl ( RxOn, nat->ioaddr + ChipCmd );
643 /* lines 1586 linux-natsemi.c uses cable magic
644 * testing this feature is required or not
646 do_cable_magic ( netdev );
647 init_phy_fixup ( netdev );
651 /* mask the interrupts. note interrupt is not enabled here
657 /* this block frees the previously allocated buffers
658 * if memory for all the buffers is not available
661 while ( nat->rx[i].cmdsts == RX_BUF_SIZE ) {
662 free_iob ( nat->iobuf[i] );
671 * @v netdev Net device
673 static void nat_close ( struct net_device *netdev ) {
674 struct natsemi_nic *nat = netdev->priv;
677 /* Reset the hardware to disable everything in one go
683 for ( i = 0; i < NUM_RX_DESC ; i++ ) {
685 free_iob ( nat->iobuf[i] );
692 * @v netdev Network device
693 * @v iobuf I/O buffer
694 * @ret rc Return status code
696 static int nat_transmit ( struct net_device *netdev, struct io_buffer *iobuf ) {
697 struct natsemi_nic *nat = netdev->priv;
699 /* check for space in TX ring
701 if ( nat->tx[nat->tx_cur].cmdsts != 0 ) {
702 DBG ( "TX overflow\n" );
706 /* to be used in netdev_tx_complete
708 nat->tx_iobuf[nat->tx_cur] = iobuf;
710 /* Pad and align packet has not been used because its not required here
711 * iob_pad ( iobuf, ETH_ZLEN ); can be used to achieve it
716 DBG ( "TX id %d at %lx + %x\n", nat->tx_cur,
717 virt_to_bus ( &iobuf->data ), iob_len ( iobuf ) );
719 nat->tx[nat->tx_cur].bufptr = virt_to_bus ( iobuf->data );
720 nat->tx[nat->tx_cur].cmdsts = iob_len ( iobuf ) | OWN;
722 /* increment the circular buffer pointer to the next buffer location
724 nat->tx_cur = ( nat->tx_cur + 1 ) % TX_RING_SIZE;
726 /*start the transmitter
728 outl ( TxOn, nat->ioaddr + ChipCmd );
734 * Poll for received packets
736 * @v netdev Network device
737 * @v rx_quota Maximum number of packets to receive
739 static void nat_poll ( struct net_device *netdev) {
740 struct natsemi_nic *nat = netdev->priv;
742 unsigned int rx_status;
743 unsigned int intr_status;
745 struct io_buffer *rx_iob;
748 /* read the interrupt register
750 intr_status = inl ( nat->ioaddr + IntrStatus );
754 /* check the status of packets given to card for transmission
756 DBG ( "Intr status %X\n",intr_status );
759 while ( i!= nat->tx_cur ) {
760 status = nat->tx[nat->tx_dirty].cmdsts;
761 DBG ( "value of tx_dirty = %d tx_cur=%d status=%X\n",
762 nat->tx_dirty,nat->tx_cur,status );
764 /* check if current packet has been transmitted or not
769 /* Check if any errors in transmission
771 if (! ( status & DescPktOK ) ) {
772 DBG ( "Error in sending Packet status:%X\n",
773 (unsigned int) status );
774 netdev_tx_complete_err ( netdev,nat->tx_iobuf[nat->tx_dirty],-EINVAL );
776 DBG ( "Success in transmitting Packet\n" );
777 netdev_tx_complete ( netdev,nat->tx_iobuf[nat->tx_dirty] );
780 /* setting cmdsts zero, indicating that it can be reused
782 nat->tx[nat->tx_dirty].cmdsts = 0;
783 nat->tx_dirty = ( nat->tx_dirty + 1 ) % TX_RING_SIZE;
784 i = ( i + 1 ) % TX_RING_SIZE;
787 /* Handle received packets
789 rx_status = (unsigned int) nat->rx[nat->rx_cur].cmdsts;
790 while ( ( rx_status & OWN ) ) {
791 rx_len = ( rx_status & DSIZE ) - CRC_SIZE;
792 DBG ( " Status of received packet = %X , Lenght of Packet = %X\n",
795 /*check for the corrupt packet
797 if ( ( rx_status & ( DescMore|DescPktOK|RxTooLong ) ) != DescPktOK) {
798 DBG ( "natsemi_poll: Corrupted packet received, "
799 "buffer status = %X \n",
800 (unsigned int) nat->rx[nat->rx_cur].cmdsts );
801 //DBG_HD ( nat->iobuf[nat->rx_cur]->data,rx_len);
802 netdev_rx_err ( netdev,NULL,-EINVAL );
804 rx_iob = alloc_iob ( rx_len );
807 /* leave packet for next call to poll
810 memcpy ( iob_put ( rx_iob,rx_len ),
811 nat->iobuf[nat->rx_cur]->data,rx_len );
812 DBG ( "received packet\n" );
813 //DBG_HD ( nat->iobuf[nat->rx_cur]->data,30);
815 /* add to the receive queue.
817 netdev_rx ( netdev,rx_iob );
819 nat->rx[nat->rx_cur].cmdsts = RX_BUF_SIZE;
820 nat->rx_cur = ( nat->rx_cur + 1 ) % NUM_RX_DESC;
821 rx_status = nat->rx[nat->rx_cur].cmdsts;
825 /* re-enable the potentially idle receive state machine
827 outl ( RxOn, nat->ioaddr + ChipCmd );
831 * Enable/disable interrupts
833 * @v netdev Network device
834 * @v enable Interrupts should be enabled
836 static void nat_irq ( struct net_device *netdev, int enable ) {
837 struct natsemi_nic *nat = netdev->priv;
839 outl ( ( enable ? ( RxOk|RxErr|TxOk|TxErr ) :0 ),
840 nat->ioaddr + IntrMask);
841 outl ( ( enable ? 1:0 ),nat->ioaddr + IntrEnable );
848 /** natsemi net device operations */
849 static struct net_device_operations nat_operations = {
852 .transmit = nat_transmit,
862 * @ret rc Return status code
864 static int nat_probe ( struct pci_device *pci,
865 const struct pci_device_id *id __unused ) {
866 struct net_device *netdev;
867 struct natsemi_nic *nat = NULL;
870 uint8_t ll_addr_encoded[MAX_LL_ADDR_LEN];
873 uint8_t prev_bytes[2];
875 /* Allocate net device
877 netdev = alloc_etherdev ( sizeof ( *nat ) );
880 netdev_init ( netdev,&nat_operations );
882 pci_set_drvdata ( pci, netdev );
883 netdev->dev = &pci->dev;
884 memset ( nat, 0, sizeof ( *nat ) );
885 nat->ioaddr = pci->ioaddr;
889 adjust_pci_device ( pci );
891 /* Reset the NIC, set up EEPROM access and read MAC address
894 nat_init_eeprom ( nat );
895 nvs_read ( &nat->eeprom.nvs, EE_MAC-1, prev_bytes, 1 );
896 nvs_read ( &nat->eeprom.nvs, EE_MAC, ll_addr_encoded, ETH_ALEN );
898 /* decoding the MAC address read from NVS
899 * and save it in netdev->ll_addr
901 last = prev_bytes[1] >> 7;
902 for ( i = 0 ; i < ETH_ALEN ; i++ ) {
903 last1 = ll_addr_encoded[i] >> 7;
904 netdev->ll_addr[i] = ll_addr_encoded[i] << 1 | last;
908 /* Register network device
910 if ( ( rc = register_netdev ( netdev ) ) != 0 )
911 goto err_register_netdev;
923 netdev_put ( netdev );
932 static void nat_remove ( struct pci_device *pci ) {
933 struct net_device *netdev = pci_get_drvdata ( pci );
934 struct natsemi_nic *nat = netdev->priv;
937 nvo_unregister ( &nat->nvo );
939 unregister_netdev ( netdev );
941 netdev_put ( netdev );
944 static struct pci_device_id natsemi_nics[] = {
945 PCI_ROM(0x100b, 0x0020, "dp83815", "DP83815"),
948 struct pci_driver natsemi_driver __pci_driver = {
950 .id_count = ( sizeof ( natsemi_nics ) / sizeof ( natsemi_nics[0] ) ),
952 .remove = nat_remove,