00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056 FILE_LICENCE ( GPL2_OR_LATER );
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102 #include <stdint.h>
00103 #include <byteswap.h>
00104 #include <errno.h>
00105 #include <stdio.h>
00106 #include <unistd.h>
00107 #include <gpxe/ethernet.h>
00108 #include <gpxe/if_ether.h>
00109 #include <gpxe/iobuf.h>
00110 #include <gpxe/malloc.h>
00111 #include <gpxe/pci.h>
00112 #include <gpxe/spi_bit.h>
00113 #include <gpxe/timer.h>
00114 #include <gpxe/nvs.h>
00115 #include <gpxe/threewire.h>
00116 #include <gpxe/netdevice.h>
00117 #include "eepro100.h"
00118
00119
00120
00121
00122
00123
00124
00125 static struct ifec_cfg ifec_cfg = {
00126 .status = 0,
00127 .command = CmdConfigure | CmdSuspend,
00128 .link = 0,
00129 .byte = { 22,
00130 ( TX_FIFO << 4 ) | RX_FIFO,
00131 0, 0,
00132 RX_DMA_COUNT,
00133 TX_DMA_COUNT + 0x80,
00134 0x32,
00135 0x03,
00136 1,
00137 0,
00138 0x2E,
00139 0,
00140 0x60,
00141 0, 0xf2,
00142 0x48,
00143 0, 0x40,
00144 0xf2,
00145 0x80,
00146 0x3f,
00147 0x0D }
00148 };
00149
00150 static struct net_device_operations ifec_operations = {
00151 .open = ifec_net_open,
00152 .close = ifec_net_close,
00153 .transmit = ifec_net_transmit,
00154 .poll = ifec_net_poll,
00155 .irq = ifec_net_irq
00156 };
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170 static int ifec_pci_probe ( struct pci_device *pci,
00171 const struct pci_device_id *id __unused )
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
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
00206 nvs_read ( &priv->eeprom.nvs, EEPROM_ADDR_MAC_0, netdev->hw_addr,
00207 ETH_ALEN );
00208
00209 nvs_read ( &priv->eeprom.nvs, EEPROM_ADDR_MDIO_REGISTER,
00210 &priv->mdio_register, 2 );
00211
00212 ifec_link_update ( netdev );
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 }
00228
00229
00230
00231
00232
00233
00234
00235
00236 static void ifec_pci_remove ( struct pci_device *pci )
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 }
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257 static void ifec_net_close ( struct net_device *netdev )
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
00266 ifec_net_irq ( netdev, 0 );
00267
00268
00269 intr_status = inw ( ioaddr + SCBStatus );
00270 outw ( intr_status, ioaddr + SCBStatus );
00271 inw ( ioaddr + SCBStatus );
00272
00273 ifec_reset ( netdev );
00274
00275
00276 ifec_free ( netdev );
00277 }
00278
00279
00280 #define INTERRUPT_MASK ( SCBMaskEarlyRx | SCBMaskFlowCtl )
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290 static void ifec_net_irq ( struct net_device *netdev, int enable )
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 }
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309 static int ifec_net_open ( struct net_device *netdev )
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
00320 ifec_net_irq ( netdev, 0 );
00321
00322
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
00328 if ( ( rc = ifec_rx_setup ( netdev ) ) != 0 )
00329 goto error;
00330 if ( ( rc = ifec_tx_setup ( netdev ) ) != 0 )
00331 goto error;
00332
00333
00334 options = 0x00;
00335 ifec_mdio_setup ( netdev, options );
00336
00337
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
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
00359 ifec_scb_cmd ( netdev, virt_to_bus ( ias ), CUStart );
00360 ifec_scb_cmd_wait ( netdev );
00361 priv->configured = 1;
00362
00363
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
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 }
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400 static void ifec_net_poll ( struct net_device *netdev )
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
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 );
00418 }
00419
00420
00421 if ( ( intr_status & ( ~INTERRUPT_MASK ) ) == 0 )
00422 return;
00423
00424
00425 ifec_tx_process ( netdev );
00426 ifec_rx_process ( netdev );
00427
00428 ifec_check_ru_status ( netdev, intr_status );
00429
00430 return;
00431 }
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442 static int ifec_net_transmit ( struct net_device *netdev,
00443 struct io_buffer *iobuf )
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
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
00469 priv->tcb_head = tcb;
00470
00471 return 0;
00472 }
00473
00474
00475
00476
00477 static const uint16_t ifec_ee_bits[] = {
00478 [SPI_BIT_SCLK] = EE_SHIFT_CLK,
00479 [SPI_BIT_MOSI] = EE_DATA_WRITE,
00480 [SPI_BIT_MISO] = EE_DATA_READ,
00481 [SPI_BIT_SS(0)] = EE_ENB,
00482 };
00483
00484
00485
00486
00487
00488
00489
00490
00491 static int ifec_spi_read_bit ( struct bit_basher *basher,
00492 unsigned int bit_id )
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 }
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516 static void ifec_spi_write_bit ( struct bit_basher *basher,
00517 unsigned int bit_id,
00518 unsigned long data )
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 }
00534
00535
00536 static struct bit_basher_operations ifec_basher_ops = {
00537 .read = ifec_spi_read_bit,
00538 .write = ifec_spi_write_bit,
00539 };
00540
00541
00542
00543
00544
00545
00546 static void ifec_init_eeprom ( struct net_device *netdev )
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
00559
00560
00561 init_at93c46 ( &priv->eeprom, 16 );
00562
00563
00564 threewire_detect_address_len ( &priv->eeprom );
00565
00566
00567 if ( priv->eeprom.address_len == 8 )
00568 init_at93c66 ( &priv->eeprom, 16 );
00569 }
00570
00571
00572
00573
00574
00575
00576
00577 static int ifec_link_check ( struct net_device *netdev )
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
00585 ifec_mdio_read ( netdev, mdio_register & 0x1f, 1 );
00586
00587 if ( ! ( ifec_mdio_read ( netdev, mdio_register & 0x1f, 1 )
00588 & ( 1 << 2 ) ) ) {
00589 return 0;
00590 }
00591 return 1;
00592 }
00593
00594
00595
00596
00597
00598
00599 static void ifec_link_update ( struct net_device *netdev )
00600 {
00601 DBGP ( "ifec_link_update\n" );
00602
00603
00604 if ( ifec_link_check ( netdev ) )
00605 netdev_link_up ( netdev );
00606 else
00607 netdev_link_down ( netdev );
00608 }
00609
00610
00611
00612
00613
00614
00615
00616 static int ifec_mdio_read ( struct net_device *netdev, int phy_id,
00617 int location )
00618 {
00619 struct ifec_private *priv = netdev->priv;
00620 unsigned long ioaddr = priv->ioaddr;
00621 int val;
00622 int boguscnt = 64*4;
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 }
00641
00642
00643
00644
00645
00646
00647
00648 static void ifec_mdio_setup ( struct net_device *netdev, int options )
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 }
00673
00674
00675
00676
00677
00678
00679
00680 static int ifec_mdio_write ( struct net_device *netdev,
00681 int phy_id, int location, int value )
00682 {
00683 struct ifec_private *priv = netdev->priv;
00684 unsigned long ioaddr = priv->ioaddr;
00685 int val;
00686 int boguscnt = 64*4;
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 }
00704
00705
00706
00707
00708
00709
00710 static void ifec_reset ( struct net_device *netdev )
00711 {
00712 struct ifec_private *priv = netdev->priv;
00713 unsigned long ioaddr = priv->ioaddr;
00714
00715 DBGP ( "ifec_reset\n" );
00716
00717
00718 outl ( PortPartialReset, ioaddr + CSRPort );
00719 inw ( ioaddr + SCBStatus );
00720 udelay ( 20 );
00721
00722
00723 outl ( PortReset, ioaddr + CSRPort );
00724 inw ( ioaddr + SCBStatus );
00725 udelay ( 20 );
00726
00727
00728 ifec_net_irq ( netdev, 0 );
00729 }
00730
00731
00732
00733
00734
00735
00736 static void ifec_free ( struct net_device *netdev )
00737 {
00738 struct ifec_private *priv = netdev_priv ( netdev );
00739 int i;
00740
00741 DBGP ( "ifec_free\n" );
00742
00743
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
00751 free_dma ( priv->tcbs, TX_RING_BYTES );
00752
00753 priv->tcbs = NULL;
00754 }
00755
00756
00757
00758
00759
00760
00761
00762
00763 static void ifec_rfd_init ( struct ifec_rfd *rfd, s16 command, u32 link )
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 }
00774
00775
00776
00777
00778
00779
00780 static void ifec_reprime_ru ( struct net_device *netdev )
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 }
00793
00794
00795
00796
00797
00798
00799 static void ifec_check_ru_status ( struct net_device *netdev,
00800 unsigned short intr_status )
00801 {
00802 struct ifec_private *priv = netdev->priv;
00803
00804 DBGP ( "ifec_check_ru_status\n" );
00805
00806
00807
00808
00809
00810 switch ( ( intr_status >> 2 ) & 0xf ) {
00811 case 0:
00812 case 4:
00813 break;
00814 case 1:
00815 case 2:
00816 case 9:
00817 case 10:
00818 case 12:
00819 DBG ( "ifec_net_poll: RU reprimed.\n" );
00820 ifec_reprime_ru ( netdev );
00821 break;
00822 default:
00823
00824 DBG ( "ifec_net_poll: RU state anomaly: %i\n",
00825 ( inw ( priv->ioaddr + SCBStatus ) >> 2 ) & 0xf );
00826 break;
00827 }
00828 }
00829
00830 #define RFD_STATUS ( RFD_OK | RFDRxCol | RFDRxErr | RFDShort | \
00831 RFDDMAOverrun | RFDNoBufs | RFDCRCError )
00832
00833
00834
00835
00836
00837
00838 static void ifec_rx_process ( struct net_device *netdev )
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
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
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
00869 priv->rx_iobs[cur_rx] = NULL;
00870 priv->rfds[cur_rx] = NULL;
00871
00872
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 }
00881
00882
00883
00884
00885
00886
00887
00888
00889
00890
00891
00892 static int ifec_get_rx_desc ( struct net_device *netdev, int cur, int cmd,
00893 int link )
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
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 }
00914
00915
00916
00917
00918
00919
00920 static void ifec_refill_rx_ring ( struct net_device *netdev )
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
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 }
00953
00954
00955
00956
00957
00958
00959
00960 static int ifec_rx_setup ( struct net_device *netdev )
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
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 }
00978
00979
00980
00981
00982
00983
00984
00985
00986
00987 static int ifec_scb_cmd ( struct net_device *netdev, u32 ptr, u8 cmd )
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 );
00996 if ( !rc ) {
00997 outl ( ptr, ioaddr + SCBPointer );
00998 outb ( cmd, ioaddr + SCBCmd );
00999 }
01000 return rc;
01001 }
01002
01003
01004
01005
01006
01007
01008
01009 static int ifec_scb_cmd_wait ( struct net_device *netdev )
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 }
01024
01025
01026
01027
01028
01029
01030 static void ifec_tx_process ( struct net_device *netdev )
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
01039 while ( ( status = tcb->status ) && tcb->iob ) {
01040 if ( status & TCB_U ) {
01041
01042 DBG ( "ifec_tx_process : tx error!\n " );
01043 netdev_tx_complete_err ( netdev, tcb->iob, -EINVAL );
01044 } else {
01045
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;
01054 tcb = tcb->next;
01055 }
01056 }
01057
01058
01059
01060
01061
01062
01063
01064 static int ifec_tx_setup ( struct net_device *netdev )
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
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
01092
01093 priv->tcb_head = --tcb;
01094 tcb->link = virt_to_bus ( priv->tcbs );
01095 tcb->next = priv->tcbs;
01096
01097 return 0;
01098 }
01099
01100
01101
01102
01103
01104
01105
01106
01107
01108
01109
01110
01111
01112
01113
01114
01115
01116
01117 void ifec_tx_wake ( struct net_device *netdev )
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
01126
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
01135 switch ( ( inw ( ioaddr + SCBStatus ) >> 6 ) & 0x3 ) {
01136 case 0:
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:
01142 DBG2 ( "s" );
01143 break;
01144 default:
01145 DBG2 ( "a" );
01146 }
01147 ifec_scb_cmd_wait ( netdev );
01148 outl ( 0, ioaddr + SCBPointer );
01149 priv->tcb_head->command &= ~CmdSuspend;
01150
01151 outb ( CUResume, ioaddr + SCBCmd );
01152 ifec_scb_cmd_wait ( netdev );
01153 }
01154
01155
01156
01157 static struct pci_device_id ifec_nics[] = {
01158 PCI_ROM(0x8086, 0x1029, "id1029", "Intel EtherExpressPro100 ID1029", 0),
01159 PCI_ROM(0x8086, 0x1030, "id1030", "Intel EtherExpressPro100 ID1030", 0),
01160 PCI_ROM(0x8086, 0x1031, "82801cam", "Intel 82801CAM (ICH3) Chipset Ethernet Controller", 0),
01161 PCI_ROM(0x8086, 0x1032, "eepro100-1032", "Intel PRO/100 VE Network Connection", 0),
01162 PCI_ROM(0x8086, 0x1033, "eepro100-1033", "Intel PRO/100 VM Network Connection", 0),
01163 PCI_ROM(0x8086, 0x1034, "eepro100-1034", "Intel PRO/100 VM Network Connection", 0),
01164 PCI_ROM(0x8086, 0x1035, "eepro100-1035", "Intel 82801CAM (ICH3) Chipset Ethernet Controller", 0),
01165 PCI_ROM(0x8086, 0x1036, "eepro100-1036", "Intel 82801CAM (ICH3) Chipset Ethernet Controller", 0),
01166 PCI_ROM(0x8086, 0x1037, "eepro100-1037", "Intel 82801CAM (ICH3) Chipset Ethernet Controller", 0),
01167 PCI_ROM(0x8086, 0x1038, "id1038", "Intel PRO/100 VM Network Connection", 0),
01168 PCI_ROM(0x8086, 0x1039, "82562et", "Intel PRO100 VE 82562ET", 0),
01169 PCI_ROM(0x8086, 0x103a, "id103a", "Intel Corporation 82559 InBusiness 10/100", 0),
01170 PCI_ROM(0x8086, 0x103b, "82562etb", "Intel PRO100 VE 82562ETB", 0),
01171 PCI_ROM(0x8086, 0x103c, "eepro100-103c", "Intel PRO/100 VM Network Connection", 0),
01172 PCI_ROM(0x8086, 0x103d, "eepro100-103d", "Intel PRO/100 VE Network Connection", 0),
01173 PCI_ROM(0x8086, 0x103e, "eepro100-103e", "Intel PRO/100 VM Network Connection", 0),
01174 PCI_ROM(0x8086, 0x1051, "prove", "Intel PRO/100 VE Network Connection", 0),
01175 PCI_ROM(0x8086, 0x1059, "82551qm", "Intel PRO/100 M Mobile Connection", 0),
01176 PCI_ROM(0x8086, 0x1209, "82559er", "Intel EtherExpressPro100 82559ER", 0),
01177 PCI_ROM(0x8086, 0x1227, "82865", "Intel 82865 EtherExpress PRO/100A", 0),
01178 PCI_ROM(0x8086, 0x1228, "82556", "Intel 82556 EtherExpress PRO/100 Smart", 0),
01179 PCI_ROM(0x8086, 0x1229, "eepro100", "Intel EtherExpressPro100", 0),
01180 PCI_ROM(0x8086, 0x2449, "82562em", "Intel EtherExpressPro100 82562EM", 0),
01181 PCI_ROM(0x8086, 0x2459, "82562-1", "Intel 82562 based Fast Ethernet Connection", 0),
01182 PCI_ROM(0x8086, 0x245d, "82562-2", "Intel 82562 based Fast Ethernet Connection", 0),
01183 PCI_ROM(0x8086, 0x1050, "82562ez", "Intel 82562EZ Network Connection", 0),
01184 PCI_ROM(0x8086, 0x1051, "eepro100-1051", "Intel 82801EB/ER (ICH5/ICH5R) Chipset Ethernet Controller", 0),
01185 PCI_ROM(0x8086, 0x1065, "82562-3", "Intel 82562 based Fast Ethernet Connection", 0),
01186 PCI_ROM(0x8086, 0x5200, "eepro100-5200", "Intel EtherExpress PRO/100 Intelligent Server", 0),
01187 PCI_ROM(0x8086, 0x5201, "eepro100-5201", "Intel EtherExpress PRO/100 Intelligent Server", 0),
01188 };
01189
01190
01191
01192
01193
01194 struct pci_driver ifec_driver __pci_driver = {
01195 .ids = ifec_nics,
01196 .id_count = ( sizeof (ifec_nics) / sizeof (ifec_nics[0]) ),
01197 .probe = ifec_pci_probe,
01198 .remove = ifec_pci_remove
01199 };
01200
01201
01202
01203
01204
01205
01206
01207