#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 |
| 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.
| NATSEMI | NIC |
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.
| netdev | Net device |
| 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.
| netdev | Network device | |
| iobuf | I/O buffer |
| 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.
| 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.
| 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.
| 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.
| 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.
| pci | PCI device | |
| id | PCI ID |
| 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 }
struct net_device_operations natsemi_operations [static] |
Initial value:
{
.open = natsemi_open,
.close = natsemi_close,
.transmit = natsemi_transmit,
.poll = natsemi_poll,
.irq = natsemi_irq,
}
struct bit_basher_operations natsemi_basher_ops [static] |
Initial value:
{
.read = natsemi_spi_read_bit,
.write = natsemi_spi_write_bit,
}
struct nvo_fragment natsemi_nvo_fragments[] [static] |
struct pci_device_id natsemi_nics[] [static] |
| 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,
}
1.5.7.1