natsemi.c File Reference

#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <gpxe/io.h>
#include <errno.h>
#include <byteswap.h>
#include <unistd.h>
#include <gpxe/pci.h>
#include <gpxe/if_ether.h>
#include <gpxe/ethernet.h>
#include <gpxe/iobuf.h>
#include <gpxe/netdevice.h>
#include <gpxe/spi_bit.h>
#include <gpxe/threewire.h>
#include <gpxe/nvo.h>
#include "natsemi.h"

Go to the source code of this file.

Functions

 FILE_LICENCE (GPL_ANY)
static int natsemi_spi_read_bit (struct bit_basher *, unsigned int)
static void natsemi_spi_write_bit (struct bit_basher *, unsigned int, unsigned long)
static void natsemi_init_eeprom (struct natsemi_private *)
static int natsemi_probe (struct pci_device *pci, const struct pci_device_id *id)
static void natsemi_reset (struct net_device *netdev)
 Reset NIC.
static int natsemi_open (struct net_device *netdev)
 Open NIC.
static int natsemi_transmit (struct net_device *netdev, struct io_buffer *iobuf)
 Transmit packet.
static void natsemi_poll (struct net_device *netdev)
 Poll for received packets.
static void natsemi_close (struct net_device *netdev)
 Close NIC.
static void natsemi_irq (struct net_device *netdev, int enable)
 Enable/disable interrupts.
static void natsemi_remove (struct pci_device *pci)
 Remove PCI device.
static int natsemi_probe (struct pci_device *pci, const struct pci_device_id *id __unused)
 Probe PCI device.

Variables

static struct net_device_operations natsemi_operations
 natsemi net device operations
static struct bit_basher_operations natsemi_basher_ops
static struct nvo_fragment natsemi_nvo_fragments []
static struct pci_device_id natsemi_nics []
struct pci_driver natsemi_driver __pci_driver


Function Documentation

FILE_LICENCE ( GPL_ANY   ) 

static int natsemi_spi_read_bit ( struct bit_basher basher,
unsigned int  bit_id 
) [static]

Definition at line 104 of file natsemi.c.

References spi_bit_basher::basher, container_of, EE_REG, inb, natsemi_private::ioaddr, natsemi_ee_bits, np, and natsemi_private::spibit.

00105                                                     {
00106         struct natsemi_private *np = container_of ( basher, struct natsemi_private,
00107                                                  spibit.basher );
00108         uint8_t mask = natsemi_ee_bits[bit_id];
00109         uint8_t eereg;
00110 
00111         eereg = inb ( np->ioaddr + EE_REG );
00112         return ( eereg & mask );
00113 }

static void natsemi_spi_write_bit ( struct bit_basher basher,
unsigned int  bit_id,
unsigned long  data 
) [static]

Definition at line 115 of file natsemi.c.

References spi_bit_basher::basher, container_of, EE_REG, inb, natsemi_private::ioaddr, natsemi_ee_bits, np, outb, and natsemi_private::spibit.

00116                                                                           {
00117         struct natsemi_private *np = container_of ( basher, struct natsemi_private,
00118                                                  spibit.basher );
00119         uint8_t mask = natsemi_ee_bits[bit_id];
00120         uint8_t eereg;
00121 
00122         eereg = inb ( np->ioaddr + EE_REG );
00123         eereg &= ~mask;
00124         eereg |= ( data & mask );
00125         outb ( eereg, np->ioaddr + EE_REG );
00126 }

static void natsemi_init_eeprom ( struct natsemi_private np  )  [static]

Definition at line 147 of file natsemi.c.

References spi_bit_basher::basher, spi_device::bus, spi_bit_basher::bus, natsemi_private::eeprom, spi_bit_basher::endianness, nvo_block::fragments, init_spi_bit_basher(), spi_bus::mode, natsemi_private::nvo, spi_device::nvs, nvo_block::nvs, bit_basher::op, SPI_BIT_LITTLE_ENDIAN, SPI_MODE_THREEWIRE, and natsemi_private::spibit.

Referenced by natsemi_probe().

00147                                                                {
00148 
00149         /* Initialise three-wire bus 
00150          */
00151         np->spibit.basher.op = &natsemi_basher_ops;
00152         np->spibit.bus.mode = SPI_MODE_THREEWIRE;
00153         np->spibit.endianness = SPI_BIT_LITTLE_ENDIAN;
00154         init_spi_bit_basher ( &np->spibit );
00155 
00156         /*natsemi DP 83815 only supports at93c46
00157          */
00158         init_at93c46 ( &np->eeprom, 16 );
00159         np->eeprom.bus = &np->spibit.bus;
00160         np->nvo.nvs = &np->eeprom.nvs;
00161         np->nvo.fragments = natsemi_nvo_fragments;
00162 }

static int natsemi_probe ( struct pci_device pci,
const struct pci_device_id id 
) [static]

static void natsemi_reset ( struct net_device netdev  )  [static]

Reset NIC.

Parameters:
NATSEMI NIC
Issues a hardware reset and waits for the reset to complete.

Definition at line 247 of file natsemi.c.

References cfg, CFG_RESET_SAVE, CfgExtPhy, CfgPhyDis, ChipCmd, ChipConfig, ChipReset, DBG, inl, inw, natsemi_private::ioaddr, NATSEMI_HW_TIMEOUT, natsemi_irq(), np, outl, outw, net_device::priv, rfcr, RFCR_RESET_SAVE, RxFilterAddr, RxFilterData, u16, u32, udelay(), WCSR_RESET_SAVE, and WOLCmd.

Referenced by natsemi_close(), natsemi_probe(), and natsemi_remove().

00248 {
00249         struct natsemi_private *np = netdev->priv;
00250         int i;
00251         u32 cfg;
00252         u32 wcsr;
00253         u32 rfcr;
00254         u16 pmatch[3];
00255         u16 sopass[3];
00256 
00257         natsemi_irq (netdev, 0);
00258 
00259         /*
00260          * Resetting the chip causes some registers to be lost.
00261          * Natsemi suggests NOT reloading the EEPROM while live, so instead
00262          * we save the state that would have been loaded from EEPROM
00263          * on a normal power-up (see the spec EEPROM map).
00264          */
00265 
00266         /* CFG */
00267         cfg = inl (np->ioaddr + ChipConfig) & CFG_RESET_SAVE;
00268 
00269         /* WCSR */
00270         wcsr = inl (np->ioaddr + WOLCmd) & WCSR_RESET_SAVE;
00271 
00272         /* RFCR */
00273         rfcr = inl (np->ioaddr + RxFilterAddr) & RFCR_RESET_SAVE;
00274 
00275         /* PMATCH */
00276         for (i = 0; i < 3; i++) {
00277                 outl(i*2, np->ioaddr + RxFilterAddr);
00278                 pmatch[i] = inw(np->ioaddr + RxFilterData);
00279         }
00280 
00281         /* SOPAS */
00282         for (i = 0; i < 3; i++) {
00283                 outl(0xa+(i*2), np->ioaddr + RxFilterAddr);
00284                 sopass[i] = inw(np->ioaddr + RxFilterData);
00285         }
00286 
00287         /* now whack the chip */
00288         outl(ChipReset, np->ioaddr + ChipCmd);
00289         for (i=0; i<NATSEMI_HW_TIMEOUT; i++) {
00290                 if (! (inl (np->ioaddr + ChipCmd) & ChipReset))
00291                        break;
00292                 udelay(5);
00293         }
00294         if (i == NATSEMI_HW_TIMEOUT) {
00295                 DBG ("natsemi_reset: reset did not complete in %d usec.\n", i*5);
00296         }
00297 
00298         /* restore CFG */
00299         cfg |= inl(np->ioaddr + ChipConfig) & ~CFG_RESET_SAVE;
00300         cfg &= ~(CfgExtPhy | CfgPhyDis);
00301         outl (cfg, np->ioaddr + ChipConfig);
00302 
00303         /* restore WCSR */
00304         wcsr |= inl (np->ioaddr + WOLCmd) & ~WCSR_RESET_SAVE;
00305         outl (wcsr, np->ioaddr + WOLCmd);
00306 
00307         /* read RFCR */
00308         rfcr |= inl (np->ioaddr + RxFilterAddr) & ~RFCR_RESET_SAVE;
00309 
00310         /* restore PMATCH */
00311         for (i = 0; i < 3; i++) {
00312                 outl (i*2, np->ioaddr + RxFilterAddr);
00313                 outw (pmatch[i], np->ioaddr + RxFilterData);
00314         }
00315         for (i = 0; i < 3; i++) {
00316                 outl (0xa+(i*2), np->ioaddr + RxFilterAddr);
00317                 outw (sopass[i], np->ioaddr + RxFilterData);
00318         }
00319         /* restore RFCR */
00320         outl (rfcr, np->ioaddr + RxFilterAddr);
00321 }

static int natsemi_open ( struct net_device netdev  )  [static]

Open NIC.

Parameters:
netdev Net device
Return values:
rc Return status code

Definition at line 329 of file natsemi.c.

References AcceptAllMulticast, AcceptBroadcast, AcceptMyPhys, alloc_iob(), natsemi_rx::bufptr, natsemi_tx::bufptr, ChipCmd, ChipConfig, ClkRun, natsemi_rx::cmdsts, natsemi_tx::cmdsts, io_buffer::data, DBG, ENOMEM, ETH_ALEN, free_iob(), inl, IntrMask, natsemi_private::ioaddr, natsemi_private::iobuf, natsemi_rx::link, natsemi_tx::link, net_device::ll_addr, np, NUM_RX_DESC, outl, outw, net_device::priv, natsemi_private::rx, RX_BUF_SIZE, natsemi_private::rx_cur, RxConfig, RxErr, RxFilterAddr, RxFilterData, RxFilterEnable, RxOk, RxOn, RxRingPtr, natsemi_private::tx, natsemi_private::tx_cur, natsemi_private::tx_dirty, TX_RING_SIZE, TxConfig, TxErr, TxOk, TxRingPtr, and virt_to_bus().

00330 {
00331         struct natsemi_private *np = netdev->priv;
00332         uint32_t tx_config, rx_config;
00333         int i;
00334         
00335         /* Disable PME:
00336          * The PME bit is initialized from the EEPROM contents.
00337          * PCI cards probably have PME disabled, but motherboard
00338          * implementations may have PME set to enable WakeOnLan. 
00339          * With PME set the chip will scan incoming packets but
00340          * nothing will be written to memory. 
00341          */
00342         outl (inl (np->ioaddr + ClkRun) & ~0x100, np->ioaddr + ClkRun);
00343 
00344         /* Set MAC address in NIC
00345          */
00346         for (i = 0 ; i < ETH_ALEN ; i+=2) {
00347                 outl (i, np->ioaddr + RxFilterAddr);
00348                 outw (netdev->ll_addr[i] + (netdev->ll_addr[i + 1] << 8),
00349                        np->ioaddr + RxFilterData);
00350         }
00351 
00352         /* Setup Tx Ring 
00353          */
00354         np->tx_cur = 0;
00355         np->tx_dirty = 0;
00356         for (i = 0 ; i < TX_RING_SIZE ; i++) {
00357                 np->tx[i].link   = virt_to_bus ((i + 1 < TX_RING_SIZE) ? &np->tx[i + 1] : &np->tx[0]);
00358                 np->tx[i].cmdsts = 0;
00359                 np->tx[i].bufptr = 0;
00360         }
00361         outl (virt_to_bus (&np->tx[0]),np->ioaddr + TxRingPtr);
00362 
00363         DBG ("Natsemi Tx descriptor loaded with: %#08x\n",
00364              inl (np->ioaddr + TxRingPtr));
00365 
00366         /* Setup RX ring
00367          */
00368         np->rx_cur = 0;
00369         for (i = 0 ; i < NUM_RX_DESC ; i++) {
00370                 np->iobuf[i] = alloc_iob (RX_BUF_SIZE);
00371                 if (! np->iobuf[i])
00372                         goto memory_alloc_err;
00373                 np->rx[i].link   = virt_to_bus ((i + 1 < NUM_RX_DESC) 
00374                                                 ? &np->rx[i + 1] : &np->rx[0]);
00375                 np->rx[i].cmdsts = RX_BUF_SIZE;
00376                 np->rx[i].bufptr = virt_to_bus (np->iobuf[i]->data);
00377                 DBG (" Address of iobuf [%d] = %p and iobuf->data = %p \n", i, 
00378                       &np->iobuf[i],  &np->iobuf[i]->data);
00379         }
00380         outl (virt_to_bus (&np->rx[0]), np->ioaddr + RxRingPtr);
00381 
00382         DBG ("Natsemi Rx descriptor loaded with: %#08x\n",
00383               inl (np->ioaddr + RxRingPtr));            
00384 
00385         /* Setup RX Filter 
00386          */
00387         outl (RxFilterEnable | AcceptBroadcast | AcceptAllMulticast | AcceptMyPhys,
00388               np->ioaddr + RxFilterAddr);
00389 
00390         /* Initialize other registers. 
00391          * Configure the PCI bus bursts and FIFO thresholds. 
00392          * Configure for standard, in-spec Ethernet. 
00393          */
00394         if (inl (np->ioaddr + ChipConfig) & 0x20000000) {       /* Full duplex */
00395                 DBG ("Full duplex\n");
00396                 tx_config = 0xD0801002 |  0xC0000000;
00397                 rx_config = 0x10000020 |  0x10000000;
00398         } else {
00399                 DBG ("Half duplex\n");
00400                 tx_config = 0x10801002 & ~0xC0000000;
00401                 rx_config = 0x00000020 & ~0x10000000;
00402         }
00403         outl (tx_config, np->ioaddr + TxConfig);
00404         outl (rx_config, np->ioaddr + RxConfig);
00405 
00406         DBG ("Tx config register = %#08x Rx config register = %#08x\n", 
00407                inl (np->ioaddr + TxConfig),
00408                inl (np->ioaddr + RxConfig));
00409 
00410         /*Set the Interrupt Mask register
00411          */
00412         outl((RxOk|RxErr|TxOk|TxErr),np->ioaddr + IntrMask);
00413         /*start the receiver 
00414          */
00415         outl (RxOn, np->ioaddr + ChipCmd);
00416         
00417         return 0;
00418                        
00419 memory_alloc_err:
00420 
00421         /* Frees any allocated buffers when memory
00422          * for all buffers requested is not available
00423          */
00424         i = 0;
00425         while (np->rx[i].cmdsts == RX_BUF_SIZE) {
00426                 free_iob (np->iobuf[i]);
00427                 i++;
00428         }
00429         return -ENOMEM; 
00430 }

static int natsemi_transmit ( struct net_device netdev,
struct io_buffer iobuf 
) [static]

Transmit packet.

Parameters:
netdev Network device
iobuf I/O buffer
Return values:
rc Return status code

Definition at line 456 of file natsemi.c.

References natsemi_tx::bufptr, ChipCmd, natsemi_tx::cmdsts, io_buffer::data, DBG, ENOBUFS, natsemi_private::ioaddr, iob_len(), np, outl, OWN, net_device::priv, natsemi_private::tx, natsemi_private::tx_cur, natsemi_private::tx_iobuf, TX_RING_SIZE, TxOn, and virt_to_bus().

00457 {
00458         struct natsemi_private *np = netdev->priv;
00459 
00460         if (np->tx[np->tx_cur].cmdsts != 0) {
00461                 DBG ("TX overflow\n");
00462                 return -ENOBUFS;
00463         }
00464 
00465         /* Used by netdev_tx_complete ()
00466          */
00467         np->tx_iobuf[np->tx_cur] = iobuf;
00468 
00469         /* Pad and align packet has not been used because its not required 
00470          * by the hardware.
00471          *      iob_pad (iobuf, ETH_ZLEN); 
00472          * can be used to achieve it, if required
00473          */
00474 
00475         /* Add the packet to TX ring
00476          */
00477         np->tx[np->tx_cur].bufptr = virt_to_bus (iobuf->data);
00478         np->tx[np->tx_cur].cmdsts = iob_len (iobuf) | OWN;
00479 
00480         DBG ("TX id %d at %#08lx + %#08zx\n", np->tx_cur,
00481              virt_to_bus (&iobuf->data), iob_len (iobuf));
00482 
00483         /* increment the circular buffer pointer to the next buffer location
00484          */
00485         np->tx_cur = (np->tx_cur + 1) % TX_RING_SIZE;
00486 
00487         /*start the transmitter 
00488          */
00489         outl (TxOn, np->ioaddr + ChipCmd);
00490 
00491         return 0;
00492 }

static void natsemi_poll ( struct net_device netdev  )  [static]

Poll for received packets.

Parameters:
netdev Network device

Definition at line 499 of file natsemi.c.

References alloc_iob(), ChipCmd, natsemi_rx::cmdsts, natsemi_tx::cmdsts, CRC_SIZE, io_buffer::data, DBG, DescMore, DescPktOK, DSIZE, EINVAL, io_buffer::end, inl, IntrStatus, natsemi_private::ioaddr, iob_put, natsemi_private::iobuf, memcpy, netdev_rx(), netdev_rx_err(), netdev_tx_complete(), netdev_tx_complete_err(), np, NULL, NUM_RX_DESC, outl, OWN, net_device::priv, natsemi_private::rx, RX_BUF_SIZE, natsemi_private::rx_cur, RxOn, RxTooLong, natsemi_private::tx, natsemi_private::tx_cur, natsemi_private::tx_dirty, natsemi_private::tx_iobuf, and TX_RING_SIZE.

00500 {
00501         struct natsemi_private *np = netdev->priv;
00502         unsigned int tx_status;
00503         unsigned int rx_status;
00504         unsigned int intr_status;
00505         unsigned int rx_len;
00506         struct io_buffer *rx_iob;
00507         int i;
00508         
00509         /* read the interrupt register
00510          */
00511         intr_status = inl (np->ioaddr + IntrStatus);
00512 
00513         if (!intr_status)
00514                 goto end;
00515 
00516         DBG ("natsemi_poll: intr_status = %#08x\n", intr_status);
00517 
00518         /* Check status of transmitted packets
00519          */
00520         i = np->tx_dirty;
00521         while (i != np->tx_cur) {
00522                 tx_status = np->tx[np->tx_dirty].cmdsts;
00523 
00524                 DBG ("tx_dirty = %d tx_cur=%d tx_status=%#08x\n",
00525                      np->tx_dirty, np->tx_cur, tx_status);
00526                 
00527                 if (tx_status & OWN) 
00528                         break;
00529 
00530                 if (! (tx_status & DescPktOK)) {
00531                         netdev_tx_complete_err (netdev,np->tx_iobuf[np->tx_dirty],-EINVAL);
00532                         DBG ("Error transmitting packet, tx_status: %#08x\n",
00533                              tx_status);
00534                 } else {
00535                         netdev_tx_complete (netdev, np->tx_iobuf[np->tx_dirty]);
00536                         DBG ("Success transmitting packet\n");
00537                 }
00538 
00539                 np->tx[np->tx_dirty].cmdsts = 0;
00540                 np->tx_dirty = (np->tx_dirty + 1) % TX_RING_SIZE;
00541                 i = (i + 1) % TX_RING_SIZE;
00542         }
00543         
00544         /* Process received packets 
00545          */
00546         rx_status = (unsigned int) np->rx[np->rx_cur].cmdsts; 
00547         while ((rx_status & OWN)) {
00548                 rx_len = (rx_status & DSIZE) - CRC_SIZE;
00549 
00550                 DBG ("Received packet, rx_curr = %d, rx_status = %#08x, rx_len = %d\n",
00551                      np->rx_cur, rx_status, rx_len);
00552                 
00553                 if ((rx_status & (DescMore | DescPktOK | RxTooLong)) != DescPktOK) {
00554                         netdev_rx_err (netdev, NULL, -EINVAL);
00555 
00556                         DBG ("natsemi_poll: Corrupted packet received!"
00557                              " Status = %#08x\n",
00558                               np->rx[np->rx_cur].cmdsts);
00559 
00560                 } else  {
00561 
00562 
00563                         /* If unable allocate space for this packet,
00564                          *  try again next poll
00565                          */
00566                         rx_iob = alloc_iob (rx_len);
00567                         if (! rx_iob) 
00568                                 goto end;
00569                         memcpy (iob_put (rx_iob, rx_len), 
00570                                 np->iobuf[np->rx_cur]->data, rx_len);
00571                         /* Add this packet to the receive queue. 
00572                          */
00573                         netdev_rx (netdev, rx_iob);
00574                 }
00575                 np->rx[np->rx_cur].cmdsts = RX_BUF_SIZE;
00576                 np->rx_cur = (np->rx_cur + 1) % NUM_RX_DESC;
00577                 rx_status = np->rx[np->rx_cur].cmdsts; 
00578         }
00579 end:
00580         /* re-enable the potentially idle receive state machine 
00581          */
00582         outl (RxOn, np->ioaddr + ChipCmd);      
00583 }                               

static void natsemi_close ( struct net_device netdev  )  [static]

Close NIC.

Parameters:
netdev Net device

Definition at line 437 of file natsemi.c.

References free_iob(), natsemi_private::iobuf, natsemi_reset(), np, NUM_RX_DESC, and net_device::priv.

00438 {
00439         struct natsemi_private *np = netdev->priv;
00440         int i;
00441 
00442         natsemi_reset (netdev);
00443 
00444         for (i = 0; i < NUM_RX_DESC ; i++) {
00445                 free_iob (np->iobuf[i]);
00446         }
00447 }

static void natsemi_irq ( struct net_device netdev,
int  enable 
) [static]

Enable/disable interrupts.

Parameters:
netdev Network device
enable Non-zero for enable, zero for disable

Definition at line 591 of file natsemi.c.

References IntrEnable, IntrMask, natsemi_private::ioaddr, np, outl, net_device::priv, RxErr, RxOk, TxErr, and TxOk.

Referenced by natsemi_reset().

00592 {
00593         struct natsemi_private *np = netdev->priv;
00594 
00595         outl ((enable ? (RxOk | RxErr | TxOk|TxErr) : 0),
00596               np->ioaddr + IntrMask); 
00597         outl ((enable ? 1 : 0), np->ioaddr + IntrEnable);
00598 }

static void natsemi_remove ( struct pci_device pci  )  [static]

Remove PCI device.

Parameters:
pci PCI device

Definition at line 231 of file natsemi.c.

References natsemi_reset(), netdev, netdev_nullify(), netdev_put(), pci_get_drvdata(), and unregister_netdev().

00231                                                     {
00232         struct net_device *netdev = pci_get_drvdata (pci);
00233  
00234         unregister_netdev (netdev);
00235         natsemi_reset (netdev);
00236         netdev_nullify ( netdev );
00237         netdev_put (netdev);
00238 }

static int natsemi_probe ( struct pci_device pci,
const struct pci_device_id *id  __unused 
) [static]

Probe PCI device.

Parameters:
pci PCI device
id PCI ID
Return values:
rc Return status code

Definition at line 171 of file natsemi.c.

References adjust_pci_device(), alloc_etherdev(), pci_device::dev, net_device::dev, EE_MAC, natsemi_private::eeprom, ENOMEM, ETH_ALEN, net_device::hw_addr, pci_device::ioaddr, natsemi_private::ioaddr, MAX_LL_ADDR_LEN, memset(), natsemi_init_eeprom(), natsemi_reset(), netdev, netdev_init(), netdev_link_up(), netdev_put(), np, NULL, spi_device::nvs, nvs_read(), pci_set_drvdata(), net_device::priv, and register_netdev().

00172                                                                 {
00173         struct net_device *netdev;
00174         struct natsemi_private *np = NULL;
00175         uint8_t ll_addr_encoded[MAX_LL_ADDR_LEN];
00176         uint8_t last=0,last1=0;
00177         uint8_t prev_bytes[2];
00178         int i;
00179         int rc;
00180 
00181         /* Allocate net device 
00182          */
00183         netdev = alloc_etherdev (sizeof (*np));
00184         if (! netdev) 
00185                 return -ENOMEM;
00186 
00187         netdev_init (netdev, &natsemi_operations);
00188         np = netdev->priv;
00189         pci_set_drvdata (pci, netdev);
00190         netdev->dev = &pci->dev;
00191         memset (np, 0, sizeof (*np));
00192         np->ioaddr = pci->ioaddr;
00193 
00194         adjust_pci_device (pci);
00195 
00196         natsemi_reset (netdev);
00197         natsemi_init_eeprom ( np );
00198         nvs_read ( &np->eeprom.nvs, EE_MAC-1, prev_bytes, 1 );
00199         nvs_read ( &np->eeprom.nvs, EE_MAC, ll_addr_encoded, ETH_ALEN );
00200 
00201         /* decoding the MAC address read from NVS 
00202          * and save it in netdev->ll_addr
00203          */
00204         last = prev_bytes[1] >> 7;
00205         for ( i = 0 ; i < ETH_ALEN ; i++ ) {
00206                 last1 = ll_addr_encoded[i] >> 7;
00207                 netdev->hw_addr[i] = ll_addr_encoded[i] << 1 | last;
00208                 last = last1;
00209         }
00210 
00211         /* Mark as link up; we don't yet handle link state */
00212         netdev_link_up ( netdev );
00213 
00214         if ((rc = register_netdev (netdev)) != 0)
00215                 goto err_register_netdev;
00216 
00217         return 0;
00218 
00219 err_register_netdev:
00220 
00221         natsemi_reset (netdev);
00222         netdev_put (netdev);
00223         return rc;
00224 }


Variable Documentation

Initial value:

 {
        .open           = natsemi_open,
        .close          = natsemi_close,
        .transmit       = natsemi_transmit,
        .poll           = natsemi_poll,
        .irq            = natsemi_irq,
}
natsemi net device operations

Definition at line 96 of file natsemi.c.

Initial value:

Definition at line 128 of file natsemi.c.

Initial value:

 {
        { 0x0c, 0x68 },
        { 0, 0 }
}

Definition at line 137 of file natsemi.c.

struct pci_device_id natsemi_nics[] [static]

Initial value:

 {
        PCI_ROM(0x100b, 0x0020, "dp83815", "DP83815", 0),
}

Definition at line 600 of file natsemi.c.

struct pci_driver natsemi_driver __pci_driver

Initial value:

 {
        .ids = natsemi_nics,
        .id_count = (sizeof (natsemi_nics) / sizeof (natsemi_nics[0])),
        .probe = natsemi_probe,
        .remove = natsemi_remove,
}

Definition at line 604 of file natsemi.c.


Generated on Tue Apr 6 20:01:36 2010 for gPXE by  doxygen 1.5.7.1