#include <stdint.h>#include <byteswap.h>#include <errno.h>#include <stdio.h>#include <unistd.h>#include <gpxe/ethernet.h>#include <gpxe/if_ether.h>#include <gpxe/iobuf.h>#include <gpxe/malloc.h>#include <gpxe/pci.h>#include <gpxe/spi_bit.h>#include <gpxe/timer.h>#include <gpxe/nvs.h>#include <gpxe/threewire.h>#include <gpxe/netdevice.h>#include "eepro100.h"Go to the source code of this file.
Defines | |
| #define | INTERRUPT_MASK ( SCBMaskEarlyRx | SCBMaskFlowCtl ) |
| #define | RFD_STATUS |
Functions | |
| FILE_LICENCE (GPL2_OR_LATER) | |
| static int | ifec_pci_probe (struct pci_device *pci, const struct pci_device_id *id __unused) |
| static void | ifec_pci_remove (struct pci_device *pci) |
| static void | ifec_net_close (struct net_device *netdev) |
| static void | ifec_net_irq (struct net_device *netdev, int enable) |
| static int | ifec_net_open (struct net_device *netdev) |
| static void | ifec_net_poll (struct net_device *netdev) |
| static int | ifec_net_transmit (struct net_device *netdev, struct io_buffer *iobuf) |
| static int | ifec_spi_read_bit (struct bit_basher *basher, unsigned int bit_id) |
| static void | ifec_spi_write_bit (struct bit_basher *basher, unsigned int bit_id, unsigned long data) |
| static void | ifec_init_eeprom (struct net_device *netdev) |
| static int | ifec_link_check (struct net_device *netdev) |
| static void | ifec_link_update (struct net_device *netdev) |
| static int | ifec_mdio_read (struct net_device *netdev, int phy_id, int location) |
| static void | ifec_mdio_setup (struct net_device *netdev, int options) |
| static int | ifec_mdio_write (struct net_device *netdev, int phy_id, int location, int value) |
| static void | ifec_reset (struct net_device *netdev) |
| static void | ifec_free (struct net_device *netdev) |
| static void | ifec_rfd_init (struct ifec_rfd *rfd, s16 command, u32 link) |
| static void | ifec_reprime_ru (struct net_device *netdev) |
| static void | ifec_check_ru_status (struct net_device *netdev, unsigned short intr_status) |
| static void | ifec_rx_process (struct net_device *netdev) |
| static int | ifec_get_rx_desc (struct net_device *netdev, int cur, int cmd, int link) |
| static void | ifec_refill_rx_ring (struct net_device *netdev) |
| static int | ifec_rx_setup (struct net_device *netdev) |
| static int | ifec_scb_cmd (struct net_device *netdev, u32 ptr, u8 cmd) |
| static int | ifec_scb_cmd_wait (struct net_device *netdev) |
| static void | ifec_tx_process (struct net_device *netdev) |
| static int | ifec_tx_setup (struct net_device *netdev) |
| void | ifec_tx_wake (struct net_device *netdev) |
Variables | |
| static struct ifec_cfg | ifec_cfg |
| static struct net_device_operations | ifec_operations |
| static const uint16_t | ifec_ee_bits [] |
| static struct bit_basher_operations | ifec_basher_ops |
| static struct pci_device_id | ifec_nics [] |
| struct pci_driver ifec_driver | __pci_driver |
| #define INTERRUPT_MASK ( SCBMaskEarlyRx | SCBMaskFlowCtl ) |
| #define RFD_STATUS |
Value:
( RFD_OK | RFDRxCol | RFDRxErr | RFDShort | \ RFDDMAOverrun | RFDNoBufs | RFDCRCError )
Definition at line 830 of file eepro100.c.
Referenced by ifec_rx_process().
| FILE_LICENCE | ( | GPL2_OR_LATER | ) |
| static int ifec_pci_probe | ( | struct pci_device * | pci, | |
| const struct pci_device_id *id | __unused | |||
| ) | [static] |
Definition at line 170 of file eepro100.c.
References adjust_pci_device(), alloc_etherdev(), DBGP, pci_device::dev, net_device::dev, ifec_private::eeprom, EEPROM_ADDR_MAC_0, EEPROM_ADDR_MDIO_REGISTER, EINVAL, ENOMEM, ETH_ALEN, net_device::hw_addr, ifec_init_eeprom(), ifec_link_update(), ifec_reset(), ifec_private::ioaddr, pci_device::ioaddr, ifec_private::mdio_register, memset(), netdev, netdev_init(), netdev_nullify(), netdev_put(), spi_device::nvs, nvs_read(), pci_set_drvdata(), net_device::priv, priv, and register_netdev().
00172 { 00173 struct net_device *netdev; 00174 struct ifec_private *priv; 00175 int rc; 00176 00177 DBGP ( "ifec_pci_probe: " ); 00178 00179 if ( pci->ioaddr == 0 ) 00180 return -EINVAL; 00181 00182 netdev = alloc_etherdev ( sizeof(*priv) ); 00183 if ( !netdev ) 00184 return -ENOMEM; 00185 00186 netdev_init ( netdev, &ifec_operations ); 00187 priv = netdev->priv; 00188 00189 pci_set_drvdata ( pci, netdev ); 00190 netdev->dev = &pci->dev; 00191 00192 /* enable bus master, etc */ 00193 adjust_pci_device( pci ); 00194 00195 DBGP ( "pci " ); 00196 00197 memset ( priv, 0, sizeof(*priv) ); 00198 priv->ioaddr = pci->ioaddr; 00199 00200 ifec_reset ( netdev ); 00201 DBGP ( "reset " ); 00202 00203 ifec_init_eeprom ( netdev ); 00204 00205 /* read MAC address */ 00206 nvs_read ( &priv->eeprom.nvs, EEPROM_ADDR_MAC_0, netdev->hw_addr, 00207 ETH_ALEN ); 00208 /* read mdio_register */ 00209 nvs_read ( &priv->eeprom.nvs, EEPROM_ADDR_MDIO_REGISTER, 00210 &priv->mdio_register, 2 ); 00211 00212 ifec_link_update ( netdev ); /* Update link state */ 00213 00214 if ( ( rc = register_netdev ( netdev ) ) != 0 ) 00215 goto error; 00216 00217 DBGP ( "ints\n" ); 00218 00219 return 0; 00220 00221 error: 00222 ifec_reset ( netdev ); 00223 netdev_nullify ( netdev ); 00224 netdev_put ( netdev ); 00225 00226 return rc; 00227 }
| static void ifec_pci_remove | ( | struct pci_device * | pci | ) | [static] |
Definition at line 236 of file eepro100.c.
References DBGP, ifec_reset(), netdev, netdev_nullify(), netdev_put(), pci_get_drvdata(), and unregister_netdev().
00237 { 00238 struct net_device *netdev = pci_get_drvdata ( pci ); 00239 00240 DBGP ( "ifec_pci_remove\n" ); 00241 00242 unregister_netdev ( netdev ); 00243 ifec_reset ( netdev ); 00244 netdev_nullify ( netdev ); 00245 netdev_put ( netdev ); 00246 }
| static void ifec_net_close | ( | struct net_device * | netdev | ) | [static] |
Definition at line 257 of file eepro100.c.
References DBGP, ifec_free(), ifec_net_irq(), ifec_reset(), inw, ifec_private::ioaddr, ioaddr, outw, net_device::priv, priv, and SCBStatus.
00258 { 00259 struct ifec_private *priv = netdev->priv; 00260 unsigned long ioaddr = priv->ioaddr; 00261 unsigned short intr_status; 00262 00263 DBGP ( "ifec_net_close\n" ); 00264 00265 /* disable interrupts */ 00266 ifec_net_irq ( netdev, 0 ); 00267 00268 /* Ack & clear ints */ 00269 intr_status = inw ( ioaddr + SCBStatus ); 00270 outw ( intr_status, ioaddr + SCBStatus ); 00271 inw ( ioaddr + SCBStatus ); 00272 00273 ifec_reset ( netdev ); 00274 00275 /* Free any resources */ 00276 ifec_free ( netdev ); 00277 }
| static void ifec_net_irq | ( | struct net_device * | netdev, | |
| int | enable | |||
| ) | [static] |
Definition at line 290 of file eepro100.c.
References DBGP, INTERRUPT_MASK, ifec_private::ioaddr, ioaddr, outw, net_device::priv, priv, SCBCmd, and SCBMaskAll.
Referenced by ifec_net_close(), ifec_net_open(), and ifec_reset().
00291 { 00292 struct ifec_private *priv = netdev->priv; 00293 unsigned long ioaddr = priv->ioaddr; 00294 00295 DBGP ( "ifec_net_irq\n" ); 00296 00297 outw ( enable ? INTERRUPT_MASK : SCBMaskAll, ioaddr + SCBCmd ); 00298 }
| static int ifec_net_open | ( | struct net_device * | netdev | ) | [static] |
Definition at line 309 of file eepro100.c.
References ifec_cfg::byte, CB_ALIGN, cfg, CmdIASetup, ifec_ias::command, ifec_private::configured, CUCmdBase, CUStart, CUStatsAddr, DBG, DBG2, DBGP, ENOMEM, ETH_ALEN, free_dma(), ifec_ias::ia, ifec_free(), ifec_mdio_setup(), ifec_net_irq(), ifec_reset(), ifec_rx_setup(), ifec_scb_cmd(), ifec_scb_cmd_wait(), ifec_tx_setup(), ifec_ias::link, ifec_cfg::link, net_device::ll_addr, malloc_dma(), mdelay(), memcpy, NULL, options, net_device::priv, priv, ifec_private::rfds, RUAddrLoad, RUStart, ifec_private::stats, ifec_cfg::status, ifec_ias::status, ifec_private::tcbs, and virt_to_bus().
00310 { 00311 struct ifec_private *priv = netdev->priv; 00312 struct ifec_ias *ias = NULL; 00313 struct ifec_cfg *cfg = NULL; 00314 int i, options; 00315 int rc = -ENOMEM; 00316 00317 DBGP ( "ifec_net_open: " ); 00318 00319 /* Ensure interrupts are disabled. */ 00320 ifec_net_irq ( netdev, 0 ); 00321 00322 /* Initialize Command Unit and Receive Unit base addresses. */ 00323 ifec_scb_cmd ( netdev, 0, RUAddrLoad ); 00324 ifec_scb_cmd ( netdev, virt_to_bus ( &priv->stats ), CUStatsAddr ); 00325 ifec_scb_cmd ( netdev, 0, CUCmdBase ); 00326 00327 /* Initialize both rings */ 00328 if ( ( rc = ifec_rx_setup ( netdev ) ) != 0 ) 00329 goto error; 00330 if ( ( rc = ifec_tx_setup ( netdev ) ) != 0 ) 00331 goto error; 00332 00333 /* Initialize MDIO */ 00334 options = 0x00; /* 0x40 = 10mbps half duplex, 0x00 = Autosense */ 00335 ifec_mdio_setup ( netdev, options ); 00336 00337 /* Prepare MAC address w/ Individual Address Setup (ias) command.*/ 00338 ias = malloc_dma ( sizeof ( *ias ), CB_ALIGN ); 00339 if ( !ias ) { 00340 rc = -ENOMEM; 00341 goto error; 00342 } 00343 ias->command = CmdIASetup; 00344 ias->status = 0; 00345 memcpy ( ias->ia, netdev->ll_addr, ETH_ALEN ); 00346 00347 /* Prepare operating parameters w/ a configure command. */ 00348 cfg = malloc_dma ( sizeof ( *cfg ), CB_ALIGN ); 00349 if ( !cfg ) { 00350 rc = -ENOMEM; 00351 goto error; 00352 } 00353 memcpy ( cfg, &ifec_cfg, sizeof ( *cfg ) ); 00354 cfg->link = virt_to_bus ( priv->tcbs ); 00355 cfg->byte[19] = ( options & 0x10 ) ? 0xC0 : 0x80; 00356 ias->link = virt_to_bus ( cfg ); 00357 00358 /* Issue the ias and configure commands. */ 00359 ifec_scb_cmd ( netdev, virt_to_bus ( ias ), CUStart ); 00360 ifec_scb_cmd_wait ( netdev ); 00361 priv->configured = 1; 00362 00363 /* Wait up to 10 ms for configuration to initiate */ 00364 for ( i = 10; i && !cfg->status; i-- ) 00365 mdelay ( 1 ); 00366 if ( ! cfg->status ) { 00367 DBG ( "Failed to initiate!\n" ); 00368 goto error; 00369 } 00370 free_dma ( ias, sizeof ( *ias ) ); 00371 free_dma ( cfg, sizeof ( *cfg ) ); 00372 DBG2 ( "cfg " ); 00373 00374 /* Enable rx by sending ring address to card */ 00375 if ( priv->rfds[0] != NULL ) { 00376 ifec_scb_cmd ( netdev, virt_to_bus( priv->rfds[0] ), RUStart ); 00377 ifec_scb_cmd_wait ( netdev ); 00378 } 00379 DBG2 ( "rx_start\n" ); 00380 00381 return 0; 00382 00383 error: 00384 free_dma ( cfg, sizeof ( *cfg ) ); 00385 free_dma ( ias, sizeof ( *ias ) ); 00386 ifec_free ( netdev ); 00387 ifec_reset ( netdev ); 00388 return rc; 00389 }
| static void ifec_net_poll | ( | struct net_device * | netdev | ) | [static] |
Definition at line 400 of file eepro100.c.
References DBG2, DBGP, ifec_check_ru_status(), ifec_link_update(), ifec_rx_process(), ifec_tx_process(), INTERRUPT_MASK, inw, ifec_private::ioaddr, LINK_CHECK_PERIOD, outw, net_device::priv, priv, and SCBStatus.
00401 { 00402 struct ifec_private *priv = netdev->priv; 00403 static int linkpoll = 0; 00404 unsigned short intr_status; 00405 00406 DBGP ( "ifec_net_poll\n" ); 00407 00408 /* acknowledge interrupts ASAP */ 00409 intr_status = inw ( priv->ioaddr + SCBStatus ); 00410 outw ( intr_status, priv->ioaddr + SCBStatus ); 00411 inw ( priv->ioaddr + SCBStatus ); 00412 00413 DBG2 ( "poll - status: 0x%04X\n", intr_status ); 00414 00415 if ( ++linkpoll > LINK_CHECK_PERIOD ) { 00416 linkpoll = 0; 00417 ifec_link_update ( netdev ); /* Update link state */ 00418 } 00419 00420 /* anything to do here? */ 00421 if ( ( intr_status & ( ~INTERRUPT_MASK ) ) == 0 ) 00422 return; 00423 00424 /* process received and transmitted packets */ 00425 ifec_tx_process ( netdev ); 00426 ifec_rx_process ( netdev ); 00427 00428 ifec_check_ru_status ( netdev, intr_status ); 00429 00430 return; 00431 }
| static int ifec_net_transmit | ( | struct net_device * | netdev, | |
| struct io_buffer * | iobuf | |||
| ) | [static] |
Definition at line 442 of file eepro100.c.
References CmdSuspend, CmdTx, CmdTxFlex, ifec_tcb::command, ifec_tcb::count, io_buffer::data, DBG, DBG2, DBGP, ENOBUFS, ifec_tx_wake(), inw, ifec_private::ioaddr, ioaddr, ifec_tcb::iob, iob_len(), ifec_tcb::next, net_device::priv, priv, SCBCmd, ifec_tcb::status, ifec_tcb::tbd_addr0, ifec_tcb::tbd_size0, ifec_private::tcb_head, and virt_to_bus().
00444 { 00445 struct ifec_private *priv = netdev->priv; 00446 struct ifec_tcb *tcb = priv->tcb_head->next; 00447 unsigned long ioaddr = priv->ioaddr; 00448 00449 DBGP ( "ifec_net_transmit\n" ); 00450 00451 /* Wait for TCB to become available. */ 00452 if ( tcb->status || tcb->iob ) { 00453 DBG ( "TX overflow\n" ); 00454 return -ENOBUFS; 00455 } 00456 00457 DBG2 ( "transmitting packet (%d bytes). status = %hX, cmd=%hX\n", 00458 iob_len ( iobuf ), tcb->status, inw ( ioaddr + SCBCmd ) ); 00459 00460 tcb->command = CmdSuspend | CmdTx | CmdTxFlex; 00461 tcb->count = 0x01208000; 00462 tcb->tbd_addr0 = virt_to_bus ( iobuf->data ); 00463 tcb->tbd_size0 = 0x3FFF & iob_len ( iobuf ); 00464 tcb->iob = iobuf; 00465 00466 ifec_tx_wake ( netdev ); 00467 00468 /* Append to end of ring. */ 00469 priv->tcb_head = tcb; 00470 00471 return 0; 00472 }
| static int ifec_spi_read_bit | ( | struct bit_basher * | basher, | |
| unsigned int | bit_id | |||
| ) | [static] |
Definition at line 491 of file eepro100.c.
References spi_bit_basher::basher, container_of, CSREeprom, DBGP, inw, ifec_private::ioaddr, priv, and ifec_private::spi.
00493 { 00494 struct ifec_private *priv = 00495 container_of ( basher, struct ifec_private, spi.basher ); 00496 unsigned long ee_addr = priv->ioaddr + CSREeprom; 00497 unsigned int ret = 0; 00498 uint16_t mask; 00499 00500 DBGP ( "ifec_spi_read_bit\n" ); 00501 00502 mask = ifec_ee_bits[bit_id]; 00503 ret = inw (ee_addr); 00504 00505 return ( ret & mask ) ? 1 : 0; 00506 }
| static void ifec_spi_write_bit | ( | struct bit_basher * | basher, | |
| unsigned int | bit_id, | |||
| unsigned long | data | |||
| ) | [static] |
Definition at line 516 of file eepro100.c.
References spi_bit_basher::basher, container_of, CSREeprom, DBGP, inw, ifec_private::ioaddr, outw, priv, and ifec_private::spi.
00519 { 00520 struct ifec_private *priv = 00521 container_of ( basher, struct ifec_private, spi.basher ); 00522 unsigned long ee_addr = priv->ioaddr + CSREeprom; 00523 short val; 00524 uint16_t mask = ifec_ee_bits[bit_id]; 00525 00526 DBGP ( "ifec_spi_write_bit\n" ); 00527 00528 val = inw ( ee_addr ); 00529 val &= ~mask; 00530 val |= data & mask; 00531 00532 outw ( val, ee_addr ); 00533 }
| static void ifec_init_eeprom | ( | struct net_device * | netdev | ) | [static] |
Definition at line 546 of file eepro100.c.
References spi_device::address_len, spi_bit_basher::basher, spi_device::bus, spi_bit_basher::bus, DBGP, ifec_private::eeprom, init_spi_bit_basher(), spi_bus::mode, bit_basher::op, net_device::priv, priv, ifec_private::spi, SPI_MODE_THREEWIRE, and threewire_detect_address_len().
Referenced by ifec_pci_probe().
00547 { 00548 struct ifec_private *priv = netdev->priv; 00549 00550 DBGP ( "ifec_init_eeprom\n" ); 00551 00552 priv->spi.basher.op = &ifec_basher_ops; 00553 priv->spi.bus.mode = SPI_MODE_THREEWIRE; 00554 init_spi_bit_basher ( &priv->spi ); 00555 00556 priv->eeprom.bus = &priv->spi.bus; 00557 00558 /* init as 93c46(93c14 compatible) first, to set the command len, 00559 * block size and word len. Needs to be set for address len detection. 00560 */ 00561 init_at93c46 ( &priv->eeprom, 16 ); 00562 00563 /* detect address length, */ 00564 threewire_detect_address_len ( &priv->eeprom ); 00565 00566 /* address len == 8 means 93c66 instead of 93c46 */ 00567 if ( priv->eeprom.address_len == 8 ) 00568 init_at93c66 ( &priv->eeprom, 16 ); 00569 }
| static int ifec_link_check | ( | struct net_device * | netdev | ) | [static] |
Definition at line 577 of file eepro100.c.
References DBGP, ifec_mdio_read(), ifec_private::mdio_register, net_device::priv, and priv.
Referenced by ifec_link_update().
00578 { 00579 struct ifec_private *priv = netdev->priv; 00580 unsigned short mdio_register = priv->mdio_register; 00581 00582 DBGP ( "ifec_link_check\n" ); 00583 00584 /* Read the status register once to discard stale data */ 00585 ifec_mdio_read ( netdev, mdio_register & 0x1f, 1 ); 00586 /* Check to see if network cable is plugged in. */ 00587 if ( ! ( ifec_mdio_read ( netdev, mdio_register & 0x1f, 1 ) 00588 & ( 1 << 2 ) ) ) { 00589 return 0; 00590 } 00591 return 1; 00592 }
| static void ifec_link_update | ( | struct net_device * | netdev | ) | [static] |
Definition at line 599 of file eepro100.c.
References DBGP, ifec_link_check(), netdev_link_down(), and netdev_link_up().
Referenced by ifec_net_poll(), and ifec_pci_probe().
00600 { 00601 DBGP ( "ifec_link_update\n" ); 00602 00603 /* Update link state */ 00604 if ( ifec_link_check ( netdev ) ) 00605 netdev_link_up ( netdev ); 00606 else 00607 netdev_link_down ( netdev ); 00608 }
| static int ifec_mdio_read | ( | struct net_device * | netdev, | |
| int | phy_id, | |||
| int | location | |||
| ) | [static] |
Definition at line 616 of file eepro100.c.
References CSRCtrlMDI, DBG, DBGP, inl, ifec_private::ioaddr, ioaddr, outl, net_device::priv, priv, and udelay().
Referenced by ifec_link_check(), and ifec_mdio_setup().
00618 { 00619 struct ifec_private *priv = netdev->priv; 00620 unsigned long ioaddr = priv->ioaddr; 00621 int val; 00622 int boguscnt = 64*4; /* <64 usec. to complete, typ 27 ticks */ 00623 00624 DBGP ( "ifec_mdio_read\n" ); 00625 00626 outl ( 0x08000000 | ( location << 16 ) | ( phy_id << 21 ), 00627 ioaddr + CSRCtrlMDI ); 00628 do { 00629 udelay ( 16 ); 00630 00631 val = inl ( ioaddr + CSRCtrlMDI ); 00632 00633 if ( --boguscnt < 0 ) { 00634 DBG ( " ifec_mdio_read() time out with val = %X.\n", 00635 val ); 00636 break; 00637 } 00638 } while (! ( val & 0x10000000 ) ); 00639 return val & 0xffff; 00640 }
| static void ifec_mdio_setup | ( | struct net_device * | netdev, | |
| int | options | |||
| ) | [static] |
Definition at line 648 of file eepro100.c.
References CONGENB, DBG2, DBGP, DP83840, DP83840A, ifec_mdio_read(), ifec_mdio_write(), ifec_private::mdio_register, net_device::priv, and priv.
Referenced by ifec_net_open().
00649 { 00650 struct ifec_private *priv = netdev->priv; 00651 unsigned short mdio_register = priv->mdio_register; 00652 00653 DBGP ( "ifec_mdio_setup\n" ); 00654 00655 if ( ( (mdio_register>>8) & 0x3f ) == DP83840 00656 || ( (mdio_register>>8) & 0x3f ) == DP83840A ) { 00657 int mdi_reg23 = ifec_mdio_read ( netdev, mdio_register 00658 & 0x1f, 23 ) | 0x0422; 00659 if (CONGENB) 00660 mdi_reg23 |= 0x0100; 00661 DBG2 ( "DP83840 specific setup, setting register 23 to " 00662 "%hX.\n", mdi_reg23 ); 00663 ifec_mdio_write ( netdev, mdio_register & 0x1f, 23, mdi_reg23 ); 00664 } 00665 DBG2 ( "dp83840 " ); 00666 if ( options != 0 ) { 00667 ifec_mdio_write ( netdev, mdio_register & 0x1f, 0, 00668 ( (options & 0x20) ? 0x2000 : 0 ) | 00669 ( (options & 0x10) ? 0x0100 : 0 ) ); 00670 DBG2 ( "set mdio_register. " ); 00671 } 00672 }
| static int ifec_mdio_write | ( | struct net_device * | netdev, | |
| int | phy_id, | |||
| int | location, | |||
| int | value | |||
| ) | [static] |
Definition at line 680 of file eepro100.c.
References CSRCtrlMDI, DBG, DBGP, inl, ifec_private::ioaddr, ioaddr, outl, net_device::priv, priv, and udelay().
Referenced by ifec_mdio_setup().
00682 { 00683 struct ifec_private *priv = netdev->priv; 00684 unsigned long ioaddr = priv->ioaddr; 00685 int val; 00686 int boguscnt = 64*4; /* <64 usec. to complete, typ 27 ticks */ 00687 00688 DBGP ( "ifec_mdio_write\n" ); 00689 00690 outl ( 0x04000000 | ( location << 16 ) | ( phy_id << 21 ) | value, 00691 ioaddr + CSRCtrlMDI ); 00692 do { 00693 udelay ( 16 ); 00694 00695 val = inl ( ioaddr + CSRCtrlMDI ); 00696 if ( --boguscnt < 0 ) { 00697 DBG ( " ifec_mdio_write() time out with val = %X.\n", 00698 val ); 00699 break; 00700 } 00701 } while (! ( val & 0x10000000 ) ); 00702 return val & 0xffff; 00703 }
| static void ifec_reset | ( | struct net_device * | netdev | ) | [static] |
Definition at line 710 of file eepro100.c.
References CSRPort, DBGP, ifec_net_irq(), inw, ifec_private::ioaddr, ioaddr, outl, PortPartialReset, PortReset, net_device::priv, priv, SCBStatus, and udelay().
Referenced by ifec_net_close(), ifec_net_open(), ifec_pci_probe(), and ifec_pci_remove().
00711 { 00712 struct ifec_private *priv = netdev->priv; 00713 unsigned long ioaddr = priv->ioaddr; 00714 00715 DBGP ( "ifec_reset\n" ); 00716 00717 /* do partial reset first */ 00718 outl ( PortPartialReset, ioaddr + CSRPort ); 00719 inw ( ioaddr + SCBStatus ); 00720 udelay ( 20 ); 00721 00722 /* full reset */ 00723 outl ( PortReset, ioaddr + CSRPort ); 00724 inw ( ioaddr + SCBStatus ); 00725 udelay ( 20 ); 00726 00727 /* disable interrupts again */ 00728 ifec_net_irq ( netdev, 0 ); 00729 }
| static void ifec_free | ( | struct net_device * | netdev | ) | [static] |
Definition at line 736 of file eepro100.c.
References DBGP, free_dma(), free_iob(), netdev_priv(), NULL, priv, RFD_COUNT, ifec_private::rfds, ifec_private::rx_iobs, ifec_private::tcbs, and TX_RING_BYTES.
Referenced by ifec_net_close(), and ifec_net_open().
00737 { 00738 struct ifec_private *priv = netdev_priv ( netdev ); 00739 int i; 00740 00741 DBGP ( "ifec_free\n" ); 00742 00743 /* free all allocated receive io_buffers */ 00744 for ( i = 0; i < RFD_COUNT; i++ ) { 00745 free_iob ( priv->rx_iobs[i] ); 00746 priv->rx_iobs[i] = NULL; 00747 priv->rfds[i] = NULL; 00748 } 00749 00750 /* free TX ring buffer */ 00751 free_dma ( priv->tcbs, TX_RING_BYTES ); 00752 00753 priv->tcbs = NULL; 00754 }
Definition at line 763 of file eepro100.c.
References ifec_rfd::command, ifec_rfd::count, DBGP, ifec_rfd::link, RFD_PACKET_LEN, ifec_rfd::rx_buf_addr, ifec_rfd::size, and ifec_rfd::status.
Referenced by ifec_get_rx_desc().
00764 { 00765 DBGP ( "ifec_rfd_init\n" ); 00766 00767 rfd->status = 0; 00768 rfd->command = command; 00769 rfd->rx_buf_addr = 0xFFFFFFFF; 00770 rfd->count = 0; 00771 rfd->size = RFD_PACKET_LEN; 00772 rfd->link = link; 00773 }
| static void ifec_reprime_ru | ( | struct net_device * | netdev | ) | [static] |
Definition at line 780 of file eepro100.c.
References ifec_private::cur_rx, cur_rx, DBGP, ifec_scb_cmd(), ifec_scb_cmd_wait(), NULL, net_device::priv, priv, ifec_private::rfds, RUStart, and virt_to_bus().
Referenced by ifec_check_ru_status().
00781 { 00782 struct ifec_private *priv = netdev->priv; 00783 int cur_rx = priv->cur_rx; 00784 00785 DBGP ( "ifec_reprime_ru\n" ); 00786 00787 if ( priv->rfds[cur_rx] != NULL ) { 00788 ifec_scb_cmd ( netdev, virt_to_bus ( priv->rfds[cur_rx] ), 00789 RUStart ); 00790 ifec_scb_cmd_wait ( netdev ); 00791 } 00792 }
| static void ifec_check_ru_status | ( | struct net_device * | netdev, | |
| unsigned short | intr_status | |||
| ) | [static] |
Definition at line 799 of file eepro100.c.
References DBG, DBGP, ifec_reprime_ru(), inw, ifec_private::ioaddr, net_device::priv, priv, and SCBStatus.
Referenced by ifec_net_poll(), and ifec_refill_rx_ring().
00801 { 00802 struct ifec_private *priv = netdev->priv; 00803 00804 DBGP ( "ifec_check_ru_status\n" ); 00805 00806 /* 00807 * The chip may have suspended reception for various reasons. 00808 * Check for that, and re-prime it should this be the case. 00809 */ 00810 switch ( ( intr_status >> 2 ) & 0xf ) { 00811 case 0: /* Idle */ 00812 case 4: /* Ready */ 00813 break; 00814 case 1: /* Suspended */ 00815 case 2: /* No resources (RFDs) */ 00816 case 9: /* Suspended with no more RBDs */ 00817 case 10: /* No resources due to no RBDs */ 00818 case 12: /* Ready with no RBDs */ 00819 DBG ( "ifec_net_poll: RU reprimed.\n" ); 00820 ifec_reprime_ru ( netdev ); 00821 break; 00822 default: 00823 /* reserved values */ 00824 DBG ( "ifec_net_poll: RU state anomaly: %i\n", 00825 ( inw ( priv->ioaddr + SCBStatus ) >> 2 ) & 0xf ); 00826 break; 00827 } 00828 }
| static void ifec_rx_process | ( | struct net_device * | netdev | ) | [static] |
Definition at line 838 of file eepro100.c.
References ifec_rfd::count, ifec_private::cur_rx, cur_rx, DBG, DBG2, DBGIO_HD, DBGP, EINVAL, ifec_refill_rx_ring(), iob_put, netdev_rx(), netdev_rx_err(), NULL, ifec_rfd::packet, net_device::priv, priv, RFD_COUNT, RFD_OK, RFD_STATUS, RFDMaskCount, ifec_private::rfds, ifec_private::rx_iobs, and ifec_rfd::status.
Referenced by ifec_net_poll().
00839 { 00840 struct ifec_private *priv = netdev->priv; 00841 int cur_rx = priv->cur_rx; 00842 struct io_buffer *iob = priv->rx_iobs[cur_rx]; 00843 struct ifec_rfd *rfd = priv->rfds[cur_rx]; 00844 unsigned int rx_len; 00845 s16 status; 00846 00847 DBGP ( "ifec_rx_process\n" ); 00848 00849 /* Process any received packets */ 00850 while ( iob && rfd && ( status = rfd->status ) ) { 00851 rx_len = rfd->count & RFDMaskCount; 00852 00853 DBG2 ( "Got a packet: Len = %d, cur_rx = %d.\n", rx_len, 00854 cur_rx ); 00855 DBGIO_HD ( (void*)rfd->packet, 0x30 ); 00856 00857 if ( ( status & RFD_STATUS ) != RFD_OK ) { 00858 DBG ( "Corrupted packet received. " 00859 "Status = %#08hx\n", status ); 00860 netdev_rx_err ( netdev, iob, -EINVAL ); 00861 } else { 00862 /* Hand off the packet to the network subsystem */ 00863 iob_put ( iob, rx_len ); 00864 DBG2 ( "Received packet: %p, len: %d\n", iob, rx_len ); 00865 netdev_rx ( netdev, iob ); 00866 } 00867 00868 /* make sure we don't reuse this RFD */ 00869 priv->rx_iobs[cur_rx] = NULL; 00870 priv->rfds[cur_rx] = NULL; 00871 00872 /* Next RFD */ 00873 priv->cur_rx = ( cur_rx + 1 ) % RFD_COUNT; 00874 cur_rx = priv->cur_rx; 00875 iob = priv->rx_iobs[cur_rx]; 00876 rfd = priv->rfds[cur_rx]; 00877 } 00878 00879 ifec_refill_rx_ring ( netdev ); 00880 }
| static int ifec_get_rx_desc | ( | struct net_device * | netdev, | |
| int | cur, | |||
| int | cmd, | |||
| int | link | |||
| ) | [static] |
Definition at line 892 of file eepro100.c.
References alloc_iob(), io_buffer::data, DBG, DBGP, ENOMEM, ifec_rfd_init(), iob_reserve, NULL, net_device::priv, priv, RFD_HEADER_LEN, ifec_private::rfds, and ifec_private::rx_iobs.
Referenced by ifec_refill_rx_ring().
00894 { 00895 struct ifec_private *priv = netdev->priv; 00896 struct ifec_rfd *rfd = priv->rfds[cur]; 00897 00898 DBGP ( "ifec_get_rx_desc\n" ); 00899 00900 priv->rx_iobs[cur] = alloc_iob ( sizeof ( *rfd ) ); 00901 if ( ! priv->rx_iobs[cur] ) { 00902 DBG ( "alloc_iob failed. desc. nr: %d\n", cur ); 00903 priv->rfds[cur] = NULL; 00904 return -ENOMEM; 00905 } 00906 00907 /* Initialize new tail. */ 00908 priv->rfds[cur] = priv->rx_iobs[cur]->data; 00909 ifec_rfd_init ( priv->rfds[cur], cmd, link ); 00910 iob_reserve ( priv->rx_iobs[cur], RFD_HEADER_LEN ); 00911 00912 return 0; 00913 }
| static void ifec_refill_rx_ring | ( | struct net_device * | netdev | ) | [static] |
Definition at line 920 of file eepro100.c.
References CmdEndOfList, CmdSuspend, ifec_rfd::command, ifec_private::cur_rx, cur_rx, DBG2, DBGP, ifec_check_ru_status(), ifec_get_rx_desc(), inw, ifec_private::ioaddr, ifec_rfd::link, NULL, net_device::priv, priv, RFD_COUNT, ifec_private::rfds, ifec_private::rx_iobs, SCBStatus, and virt_to_bus().
Referenced by ifec_rx_process(), and ifec_rx_setup().
00921 { 00922 struct ifec_private *priv = netdev->priv; 00923 int i, cur_rx; 00924 unsigned short intr_status; 00925 00926 DBGP ( "ifec_refill_rx_ring\n" ); 00927 00928 for ( i = 0; i < RFD_COUNT; i++ ) { 00929 cur_rx = ( priv->cur_rx + i ) % RFD_COUNT; 00930 /* only refill if empty */ 00931 if ( priv->rfds[cur_rx] != NULL || 00932 priv->rx_iobs[cur_rx] != NULL ) 00933 continue; 00934 00935 DBG2 ( "refilling RFD %d\n", cur_rx ); 00936 00937 if ( ifec_get_rx_desc ( netdev, cur_rx, 00938 CmdSuspend | CmdEndOfList, 0 ) == 0 ) { 00939 if ( i > 0 ) { 00940 int prev_rx = ( ( ( cur_rx + RFD_COUNT ) - 1 ) 00941 % RFD_COUNT ); 00942 struct ifec_rfd *rfd = priv->rfds[prev_rx]; 00943 00944 rfd->command = 0; 00945 rfd->link = virt_to_bus ( priv->rfds[cur_rx] ); 00946 } 00947 } 00948 } 00949 00950 intr_status = inw ( priv->ioaddr + SCBStatus ); 00951 ifec_check_ru_status ( netdev, intr_status ); 00952 }
| static int ifec_rx_setup | ( | struct net_device * | netdev | ) | [static] |
Definition at line 960 of file eepro100.c.
References ifec_private::cur_rx, DBGP, ifec_refill_rx_ring(), NULL, net_device::priv, priv, RFD_COUNT, ifec_private::rfds, and ifec_private::rx_iobs.
Referenced by ifec_net_open().
00961 { 00962 struct ifec_private *priv = netdev->priv; 00963 int i; 00964 00965 DBGP ( "ifec_rx_setup\n" ); 00966 00967 priv->cur_rx = 0; 00968 00969 /* init values for ifec_refill_rx_ring() */ 00970 for ( i = 0; i < RFD_COUNT; i++ ) { 00971 priv->rfds[i] = NULL; 00972 priv->rx_iobs[i] = NULL; 00973 } 00974 ifec_refill_rx_ring ( netdev ); 00975 00976 return 0; 00977 }
| static int ifec_scb_cmd | ( | struct net_device * | netdev, | |
| u32 | ptr, | |||
| u8 | cmd | |||
| ) | [static] |
Definition at line 987 of file eepro100.c.
References DBGP, ifec_scb_cmd_wait(), ifec_private::ioaddr, ioaddr, outb, outl, net_device::priv, priv, SCBCmd, and SCBPointer.
Referenced by ifec_net_open(), ifec_reprime_ru(), and ifec_tx_wake().
00988 { 00989 struct ifec_private *priv = netdev->priv; 00990 unsigned long ioaddr = priv->ioaddr; 00991 int rc; 00992 00993 DBGP ( "ifec_scb_cmd\n" ); 00994 00995 rc = ifec_scb_cmd_wait ( netdev ); /* Wait until ready */ 00996 if ( !rc ) { 00997 outl ( ptr, ioaddr + SCBPointer ); 00998 outb ( cmd, ioaddr + SCBCmd ); /* Issue command */ 00999 } 01000 return rc; 01001 }
| static int ifec_scb_cmd_wait | ( | struct net_device * | netdev | ) | [static] |
Definition at line 1009 of file eepro100.c.
References CU_CMD_TIMEOUT, DBG, DBGP, inb, ifec_private::ioaddr, net_device::priv, priv, SCBCmd, and udelay().
Referenced by ifec_net_open(), ifec_reprime_ru(), ifec_scb_cmd(), and ifec_tx_wake().
01010 { 01011 struct ifec_private *priv = netdev->priv; 01012 unsigned long cmd_ioaddr = priv->ioaddr + SCBCmd; 01013 int rc, wait = CU_CMD_TIMEOUT; 01014 01015 DBGP ( "ifec_scb_cmd_wait\n" ); 01016 01017 for ( ; wait && ( rc = inb ( cmd_ioaddr ) ); wait-- ) 01018 udelay ( 1 ); 01019 01020 if ( !wait ) 01021 DBG ( "ifec_scb_cmd_wait timeout!\n" ); 01022 return rc; 01023 }
| static void ifec_tx_process | ( | struct net_device * | netdev | ) | [static] |
Definition at line 1030 of file eepro100.c.
References DBG, DBG2, DBGP, EINVAL, ifec_tcb::iob, netdev_tx_complete(), netdev_tx_complete_err(), ifec_tcb::next, NULL, net_device::priv, priv, ifec_tcb::status, ifec_private::tcb_tail, and TCB_U.
Referenced by ifec_net_poll().
01031 { 01032 struct ifec_private *priv = netdev->priv; 01033 struct ifec_tcb *tcb = priv->tcb_tail; 01034 s16 status; 01035 01036 DBGP ( "ifec_tx_process\n" ); 01037 01038 /* Check status of transmitted packets */ 01039 while ( ( status = tcb->status ) && tcb->iob ) { 01040 if ( status & TCB_U ) { 01041 /* report error to gPXE */ 01042 DBG ( "ifec_tx_process : tx error!\n " ); 01043 netdev_tx_complete_err ( netdev, tcb->iob, -EINVAL ); 01044 } else { 01045 /* report successful transmit */ 01046 netdev_tx_complete ( netdev, tcb->iob ); 01047 } 01048 DBG2 ( "tx completion\n" ); 01049 01050 tcb->iob = NULL; 01051 tcb->status = 0; 01052 01053 priv->tcb_tail = tcb->next; /* Next TCB */ 01054 tcb = tcb->next; 01055 } 01056 }
| static int ifec_tx_setup | ( | struct net_device * | netdev | ) | [static] |
Definition at line 1064 of file eepro100.c.
References CB_ALIGN, ifec_tcb::count, DBG, DBGP, ENOMEM, ifec_tcb::iob, ifec_tcb::link, malloc_dma(), ifec_tcb::next, NULL, net_device::priv, priv, ifec_tcb::status, ifec_tcb::tbd_addr0, ifec_tcb::tbda_addr, TCB_COUNT, ifec_private::tcb_head, ifec_private::tcb_tail, ifec_private::tcbs, ifec_private::tx_cnt, ifec_private::tx_curr, TX_RING_BYTES, ifec_private::tx_tail, and virt_to_bus().
Referenced by ifec_net_open().
01065 { 01066 struct ifec_private *priv = netdev->priv; 01067 struct ifec_tcb *tcb; 01068 int i; 01069 01070 DBGP ( "ifec_tx_setup\n" ); 01071 01072 /* allocate tx ring */ 01073 priv->tcbs = malloc_dma ( TX_RING_BYTES, CB_ALIGN ); 01074 if ( !priv->tcbs ) { 01075 DBG ( "TX-ring allocation failed\n" ); 01076 return -ENOMEM; 01077 } 01078 01079 tcb = priv->tcb_tail = priv->tcbs; 01080 priv->tx_curr = priv->tx_tail = 0; 01081 priv->tx_cnt = 0; 01082 01083 for ( i = 0; i < TCB_COUNT; i++, tcb++ ) { 01084 tcb->status = 0; 01085 tcb->count = 0x01208000; 01086 tcb->iob = NULL; 01087 tcb->tbda_addr = virt_to_bus ( &tcb->tbd_addr0 ); 01088 tcb->link = virt_to_bus ( tcb + 1 ); 01089 tcb->next = tcb + 1; 01090 } 01091 /* We point tcb_head at the last TCB, so the first ifec_net_transmit() 01092 * will use the first (head->next) TCB to transmit. */ 01093 priv->tcb_head = --tcb; 01094 tcb->link = virt_to_bus ( priv->tcbs ); 01095 tcb->next = priv->tcbs; 01096 01097 return 0; 01098 }
| void ifec_tx_wake | ( | struct net_device * | netdev | ) |
Definition at line 1117 of file eepro100.c.
References CmdSuspend, ifec_tcb::command, ifec_private::configured, CUResume, CUStart, DBG2, DBGP, ifec_scb_cmd(), ifec_scb_cmd_wait(), inw, ifec_private::ioaddr, ioaddr, ifec_tcb::next, outb, outl, net_device::priv, priv, SCBCmd, SCBPointer, SCBStatus, ifec_private::tcb_head, and virt_to_bus().
Referenced by ifec_net_transmit().
01118 { 01119 struct ifec_private *priv = netdev->priv; 01120 unsigned long ioaddr = priv->ioaddr; 01121 struct ifec_tcb *tcb = priv->tcb_head->next; 01122 01123 DBGP ( "ifec_tx_wake\n" ); 01124 01125 /* For the special case of the first transmit, we issue a START. The 01126 * card won't RESUME after the configure command. */ 01127 if ( priv->configured ) { 01128 priv->configured = 0; 01129 ifec_scb_cmd ( netdev, virt_to_bus ( tcb ), CUStart ); 01130 ifec_scb_cmd_wait ( netdev ); 01131 return; 01132 } 01133 01134 /* Resume if suspended. */ 01135 switch ( ( inw ( ioaddr + SCBStatus ) >> 6 ) & 0x3 ) { 01136 case 0: /* Idle - We should not reach this state. */ 01137 DBG2 ( "ifec_tx_wake: tx idle!\n" ); 01138 ifec_scb_cmd ( netdev, virt_to_bus ( tcb ), CUStart ); 01139 ifec_scb_cmd_wait ( netdev ); 01140 return; 01141 case 1: /* Suspended */ 01142 DBG2 ( "s" ); 01143 break; 01144 default: /* Active */ 01145 DBG2 ( "a" ); 01146 } 01147 ifec_scb_cmd_wait ( netdev ); 01148 outl ( 0, ioaddr + SCBPointer ); 01149 priv->tcb_head->command &= ~CmdSuspend; 01150 /* Immediately issue Resume command */ 01151 outb ( CUResume, ioaddr + SCBCmd ); 01152 ifec_scb_cmd_wait ( netdev ); 01153 }
Initial value:
{
.status = 0,
.command = CmdConfigure | CmdSuspend,
.link = 0,
.byte = { 22,
( TX_FIFO << 4 ) | RX_FIFO,
0, 0,
RX_DMA_COUNT,
TX_DMA_COUNT + 0x80,
0x32,
0x03,
1,
0,
0x2E,
0,
0x60,
0, 0xf2,
0x48,
0, 0x40,
0xf2,
0x80,
0x3f,
0x0D }
}
Definition at line 125 of file eepro100.c.
struct net_device_operations ifec_operations [static] |
Initial value:
{
.open = ifec_net_open,
.close = ifec_net_close,
.transmit = ifec_net_transmit,
.poll = ifec_net_poll,
.irq = ifec_net_irq
}
Definition at line 150 of file eepro100.c.
const uint16_t ifec_ee_bits[] [static] |
Initial value:
{
[SPI_BIT_SCLK] = EE_SHIFT_CLK,
[SPI_BIT_MOSI] = EE_DATA_WRITE,
[SPI_BIT_MISO] = EE_DATA_READ,
[SPI_BIT_SS(0)] = EE_ENB,
}
Definition at line 477 of file eepro100.c.
struct bit_basher_operations ifec_basher_ops [static] |
Initial value:
{
.read = ifec_spi_read_bit,
.write = ifec_spi_write_bit,
}
Definition at line 536 of file eepro100.c.
struct pci_device_id ifec_nics[] [static] |
Definition at line 1157 of file eepro100.c.
| struct pci_driver ifec_driver __pci_driver |
Initial value:
{
.ids = ifec_nics,
.id_count = ( sizeof (ifec_nics) / sizeof (ifec_nics[0]) ),
.probe = ifec_pci_probe,
.remove = ifec_pci_remove
}
Definition at line 1194 of file eepro100.c.
1.5.7.1