iPXE
pcnet32.c
Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2010 Andrei Faur <da3drus@gmail.com>
00003  *
00004  * This program is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU General Public License as
00006  * published by the Free Software Foundation; either version 2 of the
00007  * License, or any later version.
00008  *
00009  * This program is distributed in the hope that it will be useful, but
00010  * WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012  * General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU General Public License
00015  * along with this program; if not, write to the Free Software
00016  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
00017  * 02110-1301, USA.
00018  *
00019  */
00020 
00021 FILE_LICENCE ( GPL2_OR_LATER );
00022 
00023 #include <stdint.h>
00024 #include <stdio.h>
00025 #include <stdlib.h>
00026 #include <string.h>
00027 #include <unistd.h>
00028 #include <assert.h>
00029 #include <byteswap.h>
00030 #include <errno.h>
00031 #include <ipxe/ethernet.h>
00032 #include <ipxe/if_ether.h>
00033 #include <ipxe/io.h>
00034 #include <ipxe/iobuf.h>
00035 #include <ipxe/malloc.h>
00036 #include <ipxe/netdevice.h>
00037 #include <ipxe/pci.h>
00038 #include <ipxe/timer.h>
00039 #include <mii.h>
00040 #include "pcnet32.h"
00041 
00042 static u16 pcnet32_wio_read_csr ( unsigned long addr, int index )
00043 {
00044         outw ( index, addr + PCNET32_WIO_RAP );
00045         return inw ( addr + PCNET32_WIO_RDP );
00046 }
00047 
00048 static void pcnet32_wio_write_csr ( unsigned long addr, int index, u16 val )
00049 {
00050         outw ( index, addr + PCNET32_WIO_RAP );
00051         outw ( val, addr + PCNET32_WIO_RDP );
00052 }
00053 
00054 static u16 pcnet32_wio_read_bcr ( unsigned long addr, int index )
00055 {
00056         outw ( index, addr + PCNET32_WIO_RAP );
00057         return inw ( addr + PCNET32_WIO_BDP );
00058 }
00059 
00060 static void pcnet32_wio_write_bcr ( unsigned long addr, int index, u16 val )
00061 {
00062         outw ( index, addr + PCNET32_WIO_RAP );
00063         outw ( val, addr + PCNET32_WIO_BDP );
00064 }
00065 
00066 static u16 pcnet32_wio_read_rap ( unsigned long addr )
00067 {
00068         return inw ( addr + PCNET32_WIO_RAP );
00069 }
00070 
00071 static void pcnet32_wio_write_rap ( unsigned long addr , u16 val )
00072 {
00073         outw ( val, addr + PCNET32_WIO_RAP );
00074 }
00075 
00076 static void pcnet32_wio_reset ( unsigned long addr )
00077 {
00078         inw ( addr + PCNET32_WIO_RESET );
00079 }
00080 
00081 static int pcnet32_wio_check ( unsigned long addr )
00082 {
00083         outw ( 88, addr + PCNET32_WIO_RAP );
00084         return ( inw ( addr + PCNET32_WIO_RAP ) == 88 );
00085 }
00086 
00087 static struct pcnet32_access pcnet32_wio = {
00088         .read_csr       = pcnet32_wio_read_csr,
00089         .write_csr      = pcnet32_wio_write_csr,
00090         .read_bcr       = pcnet32_wio_read_bcr,
00091         .write_bcr      = pcnet32_wio_write_bcr,
00092         .read_rap       = pcnet32_wio_read_rap,
00093         .write_rap      = pcnet32_wio_write_rap,
00094         .reset          = pcnet32_wio_reset,
00095 };
00096 
00097 static u16 pcnet32_dwio_read_csr ( unsigned long addr, int index )
00098 {
00099         outl ( index, addr + PCNET32_DWIO_RAP );
00100         return ( inl ( addr + PCNET32_DWIO_RDP ) & 0xffff );
00101 }
00102 
00103 static void pcnet32_dwio_write_csr ( unsigned long addr, int index, u16 val )
00104 {
00105         outl ( index, addr + PCNET32_DWIO_RAP );
00106         outl ( val, addr + PCNET32_DWIO_RDP );
00107 }
00108 
00109 static u16 pcnet32_dwio_read_bcr ( unsigned long addr, int index )
00110 {
00111         outl ( index, addr + PCNET32_DWIO_RAP );
00112         return ( inl ( addr + PCNET32_DWIO_BDP ) & 0xffff );
00113 }
00114 
00115 static void pcnet32_dwio_write_bcr ( unsigned long addr, int index, u16 val )
00116 {
00117         outl ( index, addr + PCNET32_DWIO_RAP );
00118         outl ( val, addr + PCNET32_DWIO_BDP );
00119 }
00120 
00121 static u16 pcnet32_dwio_read_rap ( unsigned long addr )
00122 {
00123         return ( inl ( addr + PCNET32_DWIO_RAP ) & 0xffff );
00124 }
00125 
00126 static void pcnet32_dwio_write_rap ( unsigned long addr , u16 val )
00127 {
00128         outl ( val, addr + PCNET32_DWIO_RAP );
00129 }
00130 
00131 static void pcnet32_dwio_reset ( unsigned long addr )
00132 {
00133         inl ( addr + PCNET32_DWIO_RESET );
00134 }
00135 
00136 static int pcnet32_dwio_check ( unsigned long addr )
00137 {
00138         outl ( 88, addr + PCNET32_DWIO_RAP );
00139         return ( ( inl ( addr + PCNET32_DWIO_RAP ) & 0xffff ) == 88 );
00140 }
00141 
00142 
00143 static struct pcnet32_access pcnet32_dwio = {
00144         .read_csr       = pcnet32_dwio_read_csr,
00145         .write_csr      = pcnet32_dwio_write_csr,
00146         .read_bcr       = pcnet32_dwio_read_bcr,
00147         .write_bcr      = pcnet32_dwio_write_bcr,
00148         .read_rap       = pcnet32_dwio_read_rap,
00149         .write_rap      = pcnet32_dwio_write_rap,
00150         .reset          = pcnet32_dwio_reset,
00151 };
00152 
00153 static int
00154 pcnet32_mdio_read ( struct net_device *netdev, int phy, int reg )
00155 {
00156         struct pcnet32_private *priv = netdev->priv;
00157         unsigned long ioaddr = priv->pci_dev->ioaddr;
00158         u16 val_out;
00159 
00160         if ( ! priv->mii )
00161                 return 0;
00162 
00163         /* First, select PHY chip and the register we want to read */
00164         priv->a->write_bcr ( ioaddr, 33,
00165                 ( ( phy & 0x1f ) << 5 ) | ( reg & 0x1f ) );
00166 
00167         /* Read the selected register's value */
00168         val_out = priv->a->read_bcr ( ioaddr, 34 );
00169 
00170         return val_out;
00171 }
00172 
00173 static void
00174 __unused pcnet32_mdio_write ( struct net_device *netdev, int phy, int reg, int val )
00175 {
00176         struct pcnet32_private *priv = netdev->priv;
00177         unsigned long ioaddr = priv->pci_dev->ioaddr;
00178 
00179         if ( ! priv->mii )
00180                 return;
00181 
00182         /* First, select PHY chip and the register we want to write to */
00183         priv->a->write_bcr ( ioaddr, 33,
00184                 ( ( phy & 0x1f ) << 5 ) | ( reg & 0x1f ) );
00185 
00186         /* Write val to the selected register */
00187         priv->a->write_bcr ( ioaddr, 34, val );
00188 }
00189 
00190 
00191 /**
00192  * pcnet32_refill_rx_ring - Allocates iobufs for every Rx descriptor
00193  * that doesn't have one and isn't in use by the hardware
00194  *
00195  * @v priv      Driver private structure
00196  */
00197 static void
00198 pcnet32_refill_rx_ring ( struct pcnet32_private *priv )
00199 {
00200         struct pcnet32_rx_desc *rx_curr_desc;
00201         u16 status;
00202         int i;
00203 
00204         DBGP ( "pcnet32_refill_rx_ring\n" );
00205 
00206         for ( i = 0; i < RX_RING_SIZE; i++ ) {
00207                 rx_curr_desc = priv->rx_base + i;
00208 
00209                 status = le16_to_cpu ( rx_curr_desc->status );
00210 
00211                 /* Don't touch descriptors owned by the hardware */
00212                 if ( status & DescOwn )
00213                         continue;
00214 
00215                 /* Descriptors with iobufs still need to be processed */
00216                 if ( priv->rx_iobuf[i] != NULL )
00217                         continue;
00218 
00219                 /* If alloc_iob fails, try again later (next poll) */
00220                 if ( ! ( priv->rx_iobuf[i] = alloc_iob ( PKT_BUF_SIZE ) ) ) {
00221                         DBG ( "Refill rx ring failed\n" );
00222                         break;
00223                 }
00224 
00225                 rx_curr_desc->base =
00226                         cpu_to_le32 ( virt_to_bus ( priv->rx_iobuf[i]->data ) );
00227                 rx_curr_desc->buf_length = cpu_to_le16 ( -PKT_BUF_SIZE );
00228                 rx_curr_desc->msg_length = rx_curr_desc->reserved = 0;
00229 
00230                 /* Owner changes after the other status fields are set */
00231                 wmb();
00232                 rx_curr_desc->status = cpu_to_le16 ( DescOwn );
00233         }
00234 
00235 }
00236 
00237 /**
00238  * pcnet32_setup_rx_resources - allocate Rx resources (Descriptors)
00239  *
00240  * @v priv      Driver private structure
00241  *
00242  * @ret rc      Returns 0 on success, negative on failure
00243  */
00244 static int
00245 pcnet32_setup_rx_resources ( struct pcnet32_private *priv )
00246 {
00247         DBGP ( "pcnet32_setup_rx_resources\n" );
00248 
00249         priv->rx_base = malloc_dma ( RX_RING_BYTES, RX_RING_ALIGN );
00250 
00251         DBG ( "priv->rx_base = %#08lx\n", virt_to_bus ( priv->rx_base ) );
00252 
00253         if ( ! priv->rx_base ) {
00254                 return -ENOMEM;
00255         }
00256 
00257         memset ( priv->rx_base, 0, RX_RING_BYTES );
00258 
00259         pcnet32_refill_rx_ring ( priv );
00260 
00261         priv->rx_curr = 0;
00262 
00263         return 0;
00264 }
00265 
00266 static void
00267 pcnet32_free_rx_resources ( struct pcnet32_private *priv )
00268 {
00269         int i;
00270 
00271         DBGP ( "pcnet32_free_rx_resources\n" );
00272 
00273         free_dma ( priv->rx_base, RX_RING_BYTES );
00274 
00275         for ( i = 0; i < RX_RING_SIZE; i++ ) {
00276                 free_iob ( priv->rx_iobuf[i] );
00277                 priv->rx_iobuf[i] = NULL;
00278         }
00279 }
00280 
00281 /**
00282  * pcnet32_setup_tx_resources - allocate Tx resources (Descriptors)
00283  *
00284  * @v priv      Driver private structure
00285  *
00286  * @ret rc      Returns 0 on success, negative on failure
00287  */
00288 static int
00289 pcnet32_setup_tx_resources ( struct pcnet32_private *priv )
00290 {
00291         DBGP ( "pcnet32_setup_tx_resources\n" );
00292 
00293         priv->tx_base = malloc_dma ( TX_RING_BYTES, TX_RING_ALIGN );
00294 
00295         if ( ! priv->tx_base ) {
00296                 return -ENOMEM;
00297         }
00298 
00299         memset ( priv->tx_base, 0, TX_RING_BYTES );
00300 
00301         DBG ( "priv->tx_base = %#08lx\n", virt_to_bus ( priv->tx_base ) );
00302 
00303         priv->tx_curr = 0;
00304         priv->tx_fill_ctr = 0;
00305         priv->tx_tail = 0;
00306 
00307         return 0;
00308 }
00309 
00310 static void
00311 pcnet32_free_tx_resources ( struct pcnet32_private *priv )
00312 {
00313         DBGP ( "pcnet32_free_tx_resources\n" );
00314 
00315         free_dma ( priv->tx_base, TX_RING_BYTES );
00316 }
00317 
00318 static int
00319 pcnet32_chip_detect ( struct pcnet32_private *priv )
00320 {
00321         int fdx, mii, fset;
00322         int media;
00323         int rc;
00324         unsigned long ioaddr;
00325         struct pcnet32_access *a;
00326         int chip_version;
00327         char *chipname;
00328 
00329         ioaddr = priv->pci_dev->ioaddr;
00330         a = priv->a;
00331 
00332         chip_version = a->read_csr ( ioaddr, 88 )
00333                 | ( a->read_csr ( ioaddr, 89 ) << 16 );
00334 
00335         rc = -ENODEV;
00336 
00337         DBG ( "PCnet chip version is 0x%X\n", chip_version );
00338         if ( ( chip_version & 0xfff ) != 0x003 )
00339                 goto err_unsupported;
00340 
00341         fdx = mii = fset = 0;
00342         chip_version = ( chip_version >> 12 ) & 0xffff;
00343 
00344         switch (chip_version) {
00345         case 0x2420:
00346                 chipname = "PCnet/PCI 79C970";
00347                 break;
00348         case 0x2430:
00349                 /* 970 gives the wrong chip id back */
00350                 chipname = "PCnet/PCI 79C970";
00351                 break;
00352         case 0x2621:
00353                 chipname = "PCnet/PCI II 79C970A";
00354                 fdx = 1;
00355                 break;
00356         case 0x2623:
00357                 chipname = "PCnet/FAST 79C971";
00358                 fdx = 1;
00359                 mii = 1;
00360                 fset = 1;
00361                 break;
00362         case 0x2624:
00363                 chipname = "PCnet/FAST+ 79C972";
00364                 fdx = 1;
00365                 mii = 1;
00366                 fset = 1;
00367                 break;
00368         case 0x2625:
00369                 chipname = "PCnet/FAST III 79C973";
00370                 fdx = 1;
00371                 mii = 1;
00372                 break;
00373         case 0x2626:
00374                 chipname = "PCnet/Home 79C978";
00375                 fdx = 1;
00376                 /*
00377                  * This is based on specs published at www.amd.com. This section
00378                  * assumes that a NIC with a 79C978 wants to go into 1Mb HomePNA
00379                  * mode. The 79C978 can also go into standard ethernet, and
00380                  * there probably should be some sort of module option to select
00381                  * the mode by which the card should operate
00382                  */
00383                 /* switch to home wiring mode */
00384                 media = a->read_bcr(ioaddr, 49);
00385 
00386                 DBG ( "media reset to %#x.\n", media );
00387                 a->write_bcr(ioaddr, 49, media);
00388                 break;
00389         case 0x2627:
00390                 chipname = "PCnet/FAST III 79C975";
00391                 fdx = 1;
00392                 mii = 1;
00393                 break;
00394         case 0x2628:
00395                 chipname = "PCnet/PRO 79C976";
00396                 fdx = 1;
00397                 mii = 1;
00398                 break;
00399         default:
00400                 chipname = "UNKNOWN";
00401                 DBG ( "PCnet version %#x, no PCnet32 chip.\n", chip_version );
00402                 goto err_unsupported;
00403         }
00404 
00405         DBG ( "PCnet chipname %s\n", chipname );
00406 
00407         /*
00408          * On selected chips turn on the BCR18:NOUFLO bit. This stops transmit
00409          * starting until the packet is loaded. Strike one for reliability, lose
00410          * one for latency - although on PCI this isn't a big loss. Older chips
00411          * have FIFO's smaller than a packet, so you can't do this.
00412          * Turn on BCR18:BurstRdEn and BCR18:BurstWrEn.
00413          */
00414         if (fset) {
00415                 a->write_bcr ( ioaddr, 18,
00416                         ( a->read_bcr ( ioaddr, 18 ) | 0x0860 ) );
00417                 a->write_csr ( ioaddr, 80, 0x0c00 );
00418         }
00419 
00420         priv->full_duplex = fdx;
00421         priv->mii = mii;
00422 
00423         return 0;
00424 
00425 err_unsupported:
00426         return rc;
00427 }
00428 
00429 /**
00430  * pcnet32_set_ops - Determines the ops used to access the registers
00431  *
00432  * @v priv      Driver private structure
00433  *
00434  * @ret rc      Returns 0 on success, negative on failure
00435  */
00436 static int
00437 pcnet32_set_ops ( struct pcnet32_private *priv )
00438 {
00439         int rc;
00440         unsigned long ioaddr;
00441 
00442         ioaddr = priv->pci_dev->ioaddr;
00443 
00444         /* Check if CSR0 has its default value and perform a write / read
00445            in the RAP register to see if it works. Based on these results
00446            determine what mode the NIC is in (WIO / DWIO)
00447          */
00448         rc = -ENODEV;
00449 
00450         if ( pcnet32_wio_read_csr ( ioaddr, 0 ) == 4 &&
00451              pcnet32_wio_check ( ioaddr ) ) {
00452                 priv->a = &pcnet32_wio;
00453         } else {
00454                 pcnet32_dwio_reset ( ioaddr );
00455                 if ( pcnet32_dwio_read_csr ( ioaddr, 0 ) == 4 &&
00456                      pcnet32_dwio_check ( ioaddr ) ) {
00457                         priv->a = &pcnet32_dwio;
00458                 } else {
00459                         goto err_unsupported;
00460                 }
00461         }
00462 
00463         return 0;
00464 
00465 err_unsupported:
00466         return rc;
00467 }
00468 
00469 /**
00470  * pcnet32_setup_init_block - setup the NICs initialization block
00471  *
00472  * @v priv      Driver private structure
00473  *
00474  * @ret rc      Returns 0 on success, negative on failure
00475  */
00476 static void
00477 pcnet32_setup_init_block ( struct pcnet32_private *priv )
00478 {
00479         int i;
00480 
00481         /* Configure the network port based on what we've established so far */
00482         priv->init_block.mode =
00483                 cpu_to_le16 ( ( priv->options & PCNET32_PORT_PORTSEL ) << 7 );
00484 
00485         /* Setup RLEN and TLEN fields */
00486         priv->init_block.tlen_rlen =
00487                 cpu_to_le16 ( ( PCNET32_LOG_RX_BUFFERS << 4 ) |
00488                               ( PCNET32_LOG_TX_BUFFERS << 12 ) );
00489 
00490         /* Fill in physical address */
00491         for ( i = 0; i < ETH_ALEN; i++)
00492                 priv->init_block.phys_addr[i] = priv->netdev->hw_addr[i];
00493 
00494         /* No multicasting scheme, accept everything */
00495         priv->init_block.filter[0] = 0xffffffff;
00496         priv->init_block.filter[1] = 0xffffffff;
00497 
00498         priv->init_block.rx_ring =
00499                 cpu_to_le32 ( virt_to_bus ( priv->rx_base ) );
00500         priv->init_block.tx_ring =
00501                 cpu_to_le32 ( virt_to_bus ( priv->tx_base ) );
00502 
00503         /* Make sure all changes are visible */
00504         wmb();
00505 }
00506 
00507 /**
00508  * pcnet32_setup_probe_phy - go through all PHYs and see which one is present
00509  *
00510  * @v priv      Driver private structure
00511  */
00512 static void
00513 pcnet32_setup_probe_phy ( struct pcnet32_private *priv )
00514 {
00515         unsigned long ioaddr = priv->pci_dev->ioaddr;
00516         unsigned int phycount = 0;
00517         int phy_id;
00518         int i;
00519 
00520         if ( priv->mii ) {
00521                 phy_id = ( ( priv->a->read_bcr ( ioaddr, 33 ) ) >> 5 ) & 0x1f;
00522                 for ( i = 0; i < PCNET32_MAX_PHYS; i++ ) {
00523                         unsigned short id1, id2;
00524                         id1 = pcnet32_mdio_read ( priv->netdev, i, MII_PHYSID1 );
00525                         if ( id1 == 0xffff )
00526                                 continue;
00527                         id2 = pcnet32_mdio_read ( priv->netdev, i, MII_PHYSID2 );
00528                         if ( id2 == 0xffff )
00529                                 continue;
00530                         if ( i == 31 && ( ( priv->chip_version + 1 ) & 0xfffe ) == 0x2624 )
00531                                 continue;
00532 
00533                         phycount++;
00534                         phy_id = i;
00535                 }
00536                 priv->a->write_bcr ( ioaddr, 33, phy_id << 5 );
00537                 if ( phycount > 1 )
00538                         priv->options |= PCNET32_PORT_MII;
00539         }
00540 }
00541 
00542 /**
00543  * pcnet32_setup_mac_addr - check for inconsistency between CSR12-14
00544  * and PROM addresses
00545  *
00546  * @v priv      Driver private structure
00547  */
00548 static int
00549 pcnet32_setup_mac_addr ( struct pcnet32_private *priv )
00550 {
00551         int i;
00552         u8 promaddr[ETH_ALEN];
00553         unsigned long ioaddr = priv->pci_dev->ioaddr;
00554 
00555         /* In most chips, after a chip reset, the ethernet address is read from
00556          * the station address PROM at the base address and programmed into the
00557          * "Physical Address Registers" CSR12-14.
00558          * As a precautionary measure, we read the PROM values and complain if
00559          * they disagree with the CSRs.  If they miscompare, and the PROM addr
00560          * is valid, then the PROM addr is used.
00561          */
00562         for ( i = 0; i < 3; i++ ) {
00563                 unsigned int val;
00564                 val = priv->a->read_csr ( ioaddr, i + 12 ) & 0x0ffff;
00565                 /* There may be endianness issues here. */
00566                 priv->netdev->hw_addr[2 * i] = val & 0x0ff;
00567                 priv->netdev->hw_addr[2 * i + 1] = ( val >> 8 ) & 0x0ff;
00568         }
00569 
00570         for ( i = 0; i < ETH_ALEN; i++ )
00571                 promaddr[i] = inb ( ioaddr + i );
00572 
00573         if ( memcmp ( promaddr, priv->netdev->hw_addr, ETH_ALEN ) ||
00574              ! is_valid_ether_addr ( priv->netdev->hw_addr ) ) {
00575                 if ( is_valid_ether_addr ( promaddr ) ) {
00576                         DBG ( "CSR address is invalid, using PROM addr\n" );
00577                         memcpy ( priv->netdev->hw_addr, promaddr, ETH_ALEN );
00578                 }
00579         }
00580 
00581         /* If ethernet address is not valid, return error */
00582         if ( ! is_valid_ether_addr ( priv->netdev->hw_addr ) )
00583                 return -EADDRNOTAVAIL;
00584 
00585         return 0;
00586 }
00587 
00588 /**
00589  * pcnet32_setup_if_duplex - Sets the NICs used interface and duplex mode
00590  *
00591  * @v priv      Driver private structure
00592  */
00593 static void
00594 pcnet32_setup_if_duplex ( struct pcnet32_private *priv )
00595 {
00596         unsigned long ioaddr = priv->pci_dev->ioaddr;
00597         u16 val;
00598 
00599         /* Set/Reset autoselect bit */
00600         val = priv->a->read_bcr ( ioaddr, 2 ) & ~2;
00601         if ( priv->options & PCNET32_PORT_ASEL )
00602                 val |= 2;
00603         priv->a->write_bcr ( ioaddr, 2, val );
00604 
00605         /* Handle full duplex setting */
00606         if ( priv->full_duplex ) {
00607                 val = priv->a->read_bcr ( ioaddr, 9 ) & ~3;
00608                 if ( priv->options & PCNET32_PORT_FD ) {
00609                         val |= 1;
00610                         if ( priv->options == ( PCNET32_PORT_FD | PCNET32_PORT_AUI ) )
00611                                 val |= 2;
00612                 } else if ( priv->options & PCNET32_PORT_ASEL ) {
00613                         /* Workaround of xSeries 250, on for 79C975 only */
00614                         if ( priv->chip_version == 0x2627 )
00615                                 val |= 3;
00616                 }
00617                 priv->a->write_bcr ( ioaddr, 9, val );
00618         }
00619 
00620         /* Set/Reset GPSI bit in test register */
00621         val = priv->a->read_csr ( ioaddr, 124 ) & ~0x10;
00622         if ( ( priv->options & PCNET32_PORT_PORTSEL ) == PCNET32_PORT_GPSI )
00623                 val |= 0x10;
00624         priv->a->write_bcr ( ioaddr, 124, val );
00625 
00626         /* Allied Telesyn AT are 100Mbit only and do not negotiate */
00627         u16 subsys_vend_id, subsys_dev_id;
00628         pci_read_config_word ( priv->pci_dev,
00629                                PCI_SUBSYSTEM_VENDOR_ID,
00630                                &subsys_vend_id );
00631         pci_read_config_word ( priv->pci_dev,
00632                                PCI_SUBSYSTEM_ID,
00633                                &subsys_dev_id );
00634         if ( subsys_vend_id == PCI_VENDOR_ID_AT &&
00635              ( ( subsys_dev_id == PCI_SUBDEVICE_ID_AT_2700FX ) ||
00636                ( subsys_dev_id == PCI_SUBDEVICE_ID_AT_2701FX ) ) ) {
00637                 priv->options = PCNET32_PORT_FD | PCNET32_PORT_100;
00638         }
00639 
00640         if ( priv->mii && ! ( priv->options & PCNET32_PORT_ASEL ) ) {
00641                 /* Disable Auto Negotiation, set 10Mbps, HD */
00642                 val = priv->a->read_bcr ( ioaddr, 32 ) & ~0x38;
00643                 if ( priv->options & PCNET32_PORT_FD )
00644                         val |= 0x10;
00645                 if ( priv->options & PCNET32_PORT_100 )
00646                         val |= 0x08;
00647                 priv->a->write_bcr ( ioaddr, 32, val );
00648         } else if ( priv->options & PCNET32_PORT_ASEL ) {
00649                 /* 79C970 chips do not have the BCR32 register */
00650                 if ( ( priv->chip_version != 0x2420 ) &&
00651                      ( priv->chip_version != 0x2621 ) ) {
00652                         /* Enable Auto Negotiation, setup, disable FD */
00653                         val = priv->a->read_bcr ( ioaddr, 32 ) & ~0x98;
00654                         val |= 0x20;
00655                         priv->a->write_bcr ( ioaddr, 32, val );
00656                 }
00657         }
00658 }
00659 
00660 /**
00661  * pcnet32_hw_start - Starts up the NIC
00662  *
00663  * @v priv      Driver private structure
00664  */
00665 static void
00666 pcnet32_hw_start ( struct pcnet32_private *priv )
00667 {
00668         unsigned long ioaddr = priv->pci_dev->ioaddr;
00669         int i;
00670 
00671         /* Begin initialization procedure */
00672         priv->a->write_csr ( ioaddr, 0, Init );
00673 
00674         /* Wait for the initialization to be done */
00675         i = 0;
00676         while ( i++ < 100 )
00677                 if ( priv->a->read_csr ( ioaddr, 0 ) & InitDone )
00678                         break;
00679 
00680         /* Start the chip */
00681         priv->a->write_csr ( ioaddr, 0, Strt );
00682 }
00683 
00684 /**
00685  * open - Called when a network interface is made active
00686  *
00687  * @v netdev    Network device
00688  * @ret rc      Return status code, 0 on success, negative value on failure
00689  **/
00690 static int
00691 pcnet32_open ( struct net_device *netdev )
00692 {
00693         struct pcnet32_private *priv = netdev_priv ( netdev );
00694         unsigned long ioaddr = priv->pci_dev->ioaddr;
00695         int rc;
00696         u16 val;
00697 
00698         /* Setup TX and RX descriptors */
00699         if ( ( rc = pcnet32_setup_tx_resources ( priv ) ) != 0 ) {
00700                 DBG ( "Error setting up TX resources\n" );
00701                 goto err_setup_tx;
00702         }
00703 
00704         if ( ( rc = pcnet32_setup_rx_resources ( priv ) ) != 0 ) {
00705                 DBG ( "Error setting up RX resources\n" );
00706                 goto err_setup_rx;
00707         }
00708 
00709         /* Reset the chip */
00710         priv->a->reset ( ioaddr );
00711 
00712         /* Switch pcnet32 to 32bit mode */
00713         priv->a->write_bcr ( ioaddr, 20, PCNET32_SWSTYLE_PCNET32 );
00714 
00715         /* Setup the interface and duplex mode */
00716         pcnet32_setup_if_duplex ( priv );
00717 
00718         /* Disable interrupts */
00719         val = priv->a->read_csr ( ioaddr, 3 );
00720         val |= BablMask | MissFrameMask | RxIntMask | TxIntMask | InitDoneMask;
00721         priv->a->write_csr ( ioaddr, 3, val );
00722 
00723         /* Setup initialization block */
00724         pcnet32_setup_init_block ( priv );
00725 
00726         /* Fill in the address of the initialization block */
00727         priv->a->write_csr ( ioaddr, 1,
00728                 ( virt_to_bus ( &priv->init_block ) ) & 0xffff );
00729         priv->a->write_csr ( ioaddr, 2,
00730                 ( virt_to_bus ( &priv->init_block ) ) >> 16 );
00731 
00732         /* Enable Auto-Pad, disable interrupts */
00733         priv->a->write_csr ( ioaddr, 4, 0x0915 );
00734 
00735         pcnet32_hw_start ( priv );
00736 
00737         return 0;
00738 
00739 err_setup_rx:
00740         pcnet32_free_tx_resources ( priv );
00741 err_setup_tx:
00742         priv->a->reset( priv->pci_dev->ioaddr );
00743         return rc;
00744 }
00745 
00746 /**
00747  * transmit - Transmit a packet
00748  *
00749  * @v netdev    Network device
00750  * @v iobuf     I/O buffer
00751  *
00752  * @ret rc      Returns 0 on success, negative on failure
00753  */
00754 static int
00755 pcnet32_transmit ( struct net_device *netdev, struct io_buffer *iobuf )
00756 {
00757         struct pcnet32_private *priv = netdev_priv ( netdev );
00758         unsigned long ioaddr = priv->pci_dev->ioaddr;
00759         uint32_t tx_len = iob_len ( iobuf );
00760         struct pcnet32_tx_desc *tx_curr_desc;
00761 
00762         DBGP ( "pcnet32_transmit\n" );
00763 
00764         if ( priv->tx_fill_ctr == TX_RING_SIZE ) {
00765                 DBG ( "Tx overflow\n" );
00766                 return -ENOTSUP;
00767         }
00768 
00769         priv->tx_iobuf[priv->tx_curr] = iobuf;
00770 
00771         tx_curr_desc = priv->tx_base + priv->tx_curr;
00772 
00773         /* Configure current descriptor to transmit packet */
00774         tx_curr_desc->length = cpu_to_le16 ( -tx_len );
00775         tx_curr_desc->misc = 0x00000000;
00776         tx_curr_desc->base = cpu_to_le32 ( virt_to_bus ( iobuf->data ) );
00777 
00778         /* Owner changes after the other status fields are set */
00779         wmb();
00780         tx_curr_desc->status =
00781                 cpu_to_le16 ( DescOwn | StartOfPacket | EndOfPacket );
00782 
00783         /* Trigger an immediate send poll */
00784         priv->a->write_csr ( ioaddr, 0,
00785                 ( priv->irq_enabled ? IntEnable : 0 ) | TxDemand );
00786 
00787         /* Point to the next free descriptor */
00788         priv->tx_curr = ( priv->tx_curr + 1 ) % TX_RING_SIZE;
00789 
00790         /* Increment number of tx descriptors in use */
00791         priv->tx_fill_ctr++;
00792 
00793         return 0;
00794 }
00795 
00796 /**
00797  * pcnet32_process_tx_packets - Checks for successfully sent packets,
00798  * reports them to iPXE with netdev_tx_complete()
00799  *
00800  * @v netdev    Network device
00801  */
00802 static void
00803 pcnet32_process_tx_packets ( struct net_device *netdev )
00804 {
00805         struct pcnet32_private *priv = netdev_priv ( netdev );
00806         struct pcnet32_tx_desc *tx_curr_desc;
00807 
00808         DBGP ( "pcnet32_process_tx_packets\n" );
00809 
00810         while ( priv->tx_tail != priv->tx_curr ) {
00811                 tx_curr_desc = priv->tx_base + priv->tx_tail;
00812 
00813                 u16 status = le16_to_cpu ( tx_curr_desc->status );
00814 
00815                 DBG ( "Before OWN bit check, status: %#08x\n", status );
00816 
00817                 /* Skip this descriptor if hardware still owns it */
00818                 if ( status & DescOwn )
00819                         break;
00820 
00821                 DBG ( "Transmitted packet.\n" );
00822                 DBG ( "priv->tx_fill_ctr= %d\n", priv->tx_fill_ctr );
00823                 DBG ( "priv->tx_tail    = %d\n", priv->tx_tail );
00824                 DBG ( "priv->tx_curr    = %d\n", priv->tx_curr );
00825                 DBG ( "tx_curr_desc     = %#08lx\n", virt_to_bus ( tx_curr_desc ) );
00826 
00827                 /* This packet is ready for completion */
00828                 netdev_tx_complete ( netdev, priv->tx_iobuf[priv->tx_tail]);
00829 
00830                 /* Clear the descriptor */
00831                 memset ( tx_curr_desc, 0, sizeof(*tx_curr_desc) );
00832 
00833                 /* Reduce the number of tx descriptors in use */
00834                 priv->tx_fill_ctr--;
00835 
00836                 /* Go to next available descriptor */
00837                 priv->tx_tail = ( priv->tx_tail + 1 ) % TX_RING_SIZE;
00838         }
00839 }
00840 
00841 /**
00842  * pcnet32_process_rx_packets - Checks for received packets, reports them
00843  * to iPXE with netdev_rx() or netdev_rx_err() if there was an error receiving
00844  * the packet
00845  *
00846  * @v netdev    Network device
00847  */
00848 static void
00849 pcnet32_process_rx_packets ( struct net_device *netdev )
00850 {
00851         struct pcnet32_private *priv = netdev_priv ( netdev );
00852         struct pcnet32_rx_desc *rx_curr_desc;
00853         u16 status;
00854         u32 len;
00855         int i;
00856 
00857         DBGP ( "pcnet32_process_rx_packets\n" );
00858 
00859         for ( i = 0; i < RX_RING_SIZE; i++ ) {
00860                 rx_curr_desc = priv->rx_base + priv->rx_curr;
00861 
00862                 status = le16_to_cpu ( rx_curr_desc->status );
00863                 rmb();
00864 
00865                 DBG ( "Before OWN bit check, status: %#08x\n", status );
00866 
00867                 /* Skip this descriptor if hardware still owns it */
00868                 if ( status & DescOwn )
00869                         break;
00870 
00871                 /* We own the descriptor, but it has not been refilled yet */
00872                 if ( priv->rx_iobuf[priv->rx_curr] == NULL )
00873                         break;
00874 
00875                 DBG ( "Received packet.\n" );
00876                 DBG ( "priv->rx_curr    = %d\n", priv->rx_curr );
00877                 DBG ( "rx_len           = %d\n",
00878                       ( le32_to_cpu ( rx_curr_desc->msg_length ) & 0xfff ) - 4 );
00879                 DBG ( "rx_curr_desc     = %#08lx\n",
00880                       virt_to_bus ( rx_curr_desc ) );
00881 
00882                 /* Check ERR bit */
00883                 if ( status & 0x4000 ) {
00884                         netdev_rx_err ( netdev, priv->rx_iobuf[priv->rx_curr],
00885                                         -EINVAL );
00886                         DBG ( "Corrupted packet received!\n");
00887                 } else {
00888                         /* Adjust size of the iobuf to reflect received data */
00889                         len = ( le32_to_cpu ( rx_curr_desc->msg_length ) & 0xfff ) - 4;
00890                         iob_put ( priv->rx_iobuf[priv->rx_curr], len );
00891 
00892                         /* Add this packet to the receive queue */
00893                         netdev_rx ( netdev, priv->rx_iobuf[priv->rx_curr] );
00894                 }
00895 
00896                 /* Invalidate iobuf and descriptor */
00897                 priv->rx_iobuf[priv->rx_curr] = NULL;
00898                 memset ( rx_curr_desc, 0, sizeof(*rx_curr_desc) );
00899 
00900                 /* Point to the next free descriptor */
00901                 priv->rx_curr = ( priv->rx_curr + 1 ) % RX_RING_SIZE;
00902         }
00903 
00904         /* Allocate new iobufs where needed */
00905         pcnet32_refill_rx_ring ( priv );
00906 }
00907 
00908 /**
00909  * poll - Poll for received packets
00910  *
00911  * @v netdev    Network device
00912  */
00913 static void
00914 pcnet32_poll ( struct net_device *netdev )
00915 {
00916         struct pcnet32_private *priv = netdev_priv ( netdev );
00917         unsigned long ioaddr = priv->pci_dev->ioaddr;
00918         u16 status;
00919 
00920         DBGP ( "pcnet32_poll\n" );
00921 
00922         status = priv->a->read_csr ( ioaddr, 0 );
00923 
00924         /* Clear interrupts */
00925         priv->a->write_csr ( ioaddr, 0, status );
00926 
00927         DBG ( "pcnet32_poll: mask = %#04x, status = %#04x\n",
00928                 priv->a->read_csr ( ioaddr, 3 ), status );
00929 
00930         /* Return when RINT or TINT are not set */
00931         if ( ( status & 0x0500 ) == 0x0000 )
00932                 return;
00933 
00934         /* Process transmitted packets */
00935         pcnet32_process_tx_packets ( netdev );
00936 
00937         /* Process received packets */
00938         pcnet32_process_rx_packets ( netdev );
00939 }
00940 
00941 /**
00942  * close - Disable network interface
00943  *
00944  * @v netdev    network interface device structure
00945  **/
00946 static void
00947 pcnet32_close ( struct net_device *netdev )
00948 {
00949         struct pcnet32_private *priv = netdev_priv ( netdev );
00950         unsigned long ioaddr = priv->pci_dev->ioaddr;
00951 
00952         DBGP ( "pcnet32_close\n" );
00953 
00954         /* Reset the chip */
00955         pcnet32_wio_reset ( ioaddr );
00956 
00957         /* Stop the PCNET32 - it occasionally polls memory if we don't */
00958         priv->a->write_csr ( ioaddr, 0, Stop );
00959 
00960         /* Switch back to 16bit mode to avoid problems with dumb
00961          * DOS packet driver after a warm reboot */
00962         priv->a->write_bcr ( ioaddr, 20, PCNET32_SWSTYLE_LANCE );
00963 
00964         pcnet32_free_rx_resources ( priv );
00965         pcnet32_free_tx_resources ( priv );
00966 }
00967 
00968 static void pcnet32_irq_enable ( struct pcnet32_private *priv )
00969 {
00970         unsigned long ioaddr = priv->pci_dev->ioaddr;
00971         u16 val;
00972 
00973         DBGP ( "pcnet32_irq_enable\n" );
00974 
00975         /* Enable TINT and RINT masks */
00976         val = priv->a->read_csr ( ioaddr, 3 );
00977         val &= ~( RxIntMask | TxIntMask );
00978         priv->a->write_csr ( ioaddr, 3, val );
00979 
00980         /* Enable interrupts */
00981         priv->a->write_csr ( ioaddr, 0, IntEnable );
00982 
00983         priv->irq_enabled = 1;
00984 }
00985 
00986 static void pcnet32_irq_disable ( struct pcnet32_private *priv )
00987 {
00988         unsigned long ioaddr = priv->pci_dev->ioaddr;
00989 
00990         DBGP ( "pcnet32_irq_disable\n" );
00991 
00992         priv->a->write_csr ( ioaddr, 0, 0x0000 );
00993 
00994         priv->irq_enabled = 0;
00995 }
00996 
00997 /**
00998  * irq - enable or disable interrupts
00999  *
01000  * @v netdev    network adapter
01001  * @v action    requested interrupt action
01002  **/
01003 static void
01004 pcnet32_irq ( struct net_device *netdev, int action )
01005 {
01006         struct pcnet32_private *priv = netdev_priv ( netdev );
01007 
01008         DBGP ( "pcnet32_irq\n" );
01009 
01010         switch ( action ) {
01011         case 0:
01012                 pcnet32_irq_disable ( priv );
01013                 break;
01014         default:
01015                 pcnet32_irq_enable ( priv );
01016                 break;
01017         }
01018 }
01019 
01020 static struct net_device_operations pcnet32_operations = {
01021         .open           = pcnet32_open,
01022         .transmit       = pcnet32_transmit,
01023         .poll           = pcnet32_poll,
01024         .close          = pcnet32_close,
01025         .irq            = pcnet32_irq,
01026 };
01027 
01028 /**
01029  * probe - Initial configuration of NIC
01030  *
01031  * @v pdev      PCI device
01032  * @v ent       PCI IDs
01033  *
01034  * @ret rc      Return status code
01035  **/
01036 static int
01037 pcnet32_probe ( struct pci_device *pdev )
01038 {
01039         struct net_device *netdev;
01040         struct pcnet32_private *priv;
01041         unsigned long ioaddr;
01042         int rc;
01043 
01044         DBGP ( "pcnet32_probe\n" );
01045 
01046         DBG ( "Found %s, vendor = %#04x, device = %#04x\n",
01047                 pdev->id->name, pdev->id->vendor, pdev->id->device );
01048 
01049         /* Allocate our private data */
01050         netdev = alloc_etherdev ( sizeof ( *priv ) );
01051         if ( ! netdev ) {
01052                 rc = -ENOMEM;
01053                 goto err_alloc_etherdev;
01054         }
01055 
01056         /* Link our operations to the netdev struct */
01057         netdev_init ( netdev, &pcnet32_operations );
01058 
01059         /* Link the PCI device to the netdev struct */
01060         pci_set_drvdata ( pdev, netdev );
01061         netdev->dev = &pdev->dev;
01062 
01063         /* Get a reference to our private data */
01064         priv = netdev_priv ( netdev );
01065 
01066         /* We'll need these set up for the rest of the routines */
01067         priv->pci_dev = pdev;
01068         priv->netdev = netdev;
01069 
01070         ioaddr = pdev->ioaddr;
01071 
01072         /* Only use irqs under UNDI */
01073         priv->irq_enabled = 0;
01074 
01075         /* Reset the chip */
01076         pcnet32_wio_reset ( ioaddr );
01077 
01078         if ( ( rc = pcnet32_set_ops ( priv ) ) != 0 ) {
01079                 DBG ( "Setting driver operations failed\n");
01080                 goto err_set_ops;
01081         }
01082 
01083         if ( ( rc = pcnet32_chip_detect ( priv ) ) != 0 ) {
01084                 DBG ( "pcnet32_chip_detect failed\n" );
01085                 goto err_chip_detect;
01086         }
01087 
01088         /* Enter bus mastering mode */
01089         adjust_pci_device ( pdev );
01090 
01091         /* Verify and get MAC address */
01092         if ( ( rc = pcnet32_setup_mac_addr ( priv ) ) != 0 ) {
01093                 DBG ( "Setting MAC address failed\n" );
01094                 goto err_mac_addr;
01095         }
01096 
01097         DBG ( "IO Addr 0x%lX, MAC Addr %s\n", ioaddr,
01098                 eth_ntoa ( netdev->hw_addr ) );
01099 
01100         priv->options = PCNET32_PORT_ASEL;
01101 
01102         /* Detect special T1/E1 WAN card by checking for MAC address */
01103         if ( netdev->hw_addr[0] == 0x00 &&
01104              netdev->hw_addr[1] == 0xE0 &&
01105              netdev->hw_addr[2] == 0x75 )
01106                 priv->options = PCNET32_PORT_FD | PCNET32_PORT_GPSI;
01107 
01108         /* Probe the PHY so we can check link state and speed */
01109         pcnet32_setup_probe_phy ( priv );
01110 
01111         if ( ( rc = register_netdev ( netdev ) ) != 0 ) {
01112                 DBG ( "Error registering netdev\n" );
01113                 goto err_register;
01114         }
01115 
01116         netdev_link_up ( netdev );
01117 
01118         return 0;
01119 
01120 err_register:
01121         netdev_put ( netdev );
01122 err_chip_detect:
01123 err_set_ops:
01124 err_alloc_etherdev:
01125 err_mac_addr:
01126         return rc;
01127 }
01128 
01129 /**
01130  * remove - Device Removal Routine
01131  *
01132  * @v pdev PCI device information struct
01133  **/
01134 static void
01135 pcnet32_remove ( struct pci_device *pdev )
01136 {
01137         struct net_device *netdev = pci_get_drvdata ( pdev );
01138         unsigned long ioaddr = pdev->ioaddr;
01139 
01140         DBGP ( "pcnet32_remove\n" );
01141 
01142         /* Reset the chip */
01143         pcnet32_wio_reset ( ioaddr );
01144 
01145         unregister_netdev ( netdev );
01146         netdev_nullify ( netdev );
01147         netdev_put ( netdev );
01148 }
01149 
01150 static struct pci_device_id pcnet32_nics[] = {
01151         PCI_ROM(0x1022, 0x2000, "pcnet32", "AMD PCnet/PCI", 0),
01152         PCI_ROM(0x1022, 0x2625, "pcnetfastiii", "AMD PCNet FAST III", 0),
01153         PCI_ROM(0x1022, 0x2001, "amdhomepna", "AMD PCnet/HomePNA", 0),
01154 };
01155 
01156 struct pci_driver pcnet32_driver __pci_driver = {
01157         .ids            = pcnet32_nics,
01158         .id_count       = ARRAY_SIZE ( pcnet32_nics ),
01159         .probe          = pcnet32_probe,
01160         .remove         = pcnet32_remove,
01161 };