iPXE
natsemi.c
Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2012 Michael Brown <mbrown@fensystems.co.uk>.
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 (at your option) 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 FILE_LICENCE ( GPL2_OR_LATER );
00021 
00022 #include <stdint.h>
00023 #include <string.h>
00024 #include <unistd.h>
00025 #include <errno.h>
00026 #include <byteswap.h>
00027 #include <ipxe/netdevice.h>
00028 #include <ipxe/ethernet.h>
00029 #include <ipxe/if_ether.h>
00030 #include <ipxe/iobuf.h>
00031 #include <ipxe/malloc.h>
00032 #include <ipxe/pci.h>
00033 #include <ipxe/nvs.h>
00034 #include <ipxe/bitbash.h>
00035 #include <ipxe/spi_bit.h>
00036 #include <ipxe/threewire.h>
00037 #include "natsemi.h"
00038 
00039 /** @file
00040  *
00041  * National Semiconductor "MacPhyter" network card driver
00042  *
00043  * Based on the following datasheets:
00044  *
00045  *    http://www.ti.com/lit/ds/symlink/dp83820.pdf
00046  *    http://www.datasheets.org.uk/indexdl/Datasheet-03/DSA0041338.pdf
00047  *
00048  */
00049 
00050 /******************************************************************************
00051  *
00052  * EEPROM interface
00053  *
00054  ******************************************************************************
00055  */
00056 
00057 /** Pin mapping for SPI bit-bashing interface */
00058 static const uint8_t natsemi_eeprom_bits[] = {
00059         [SPI_BIT_SCLK]  = NATSEMI_MEAR_EECLK,
00060         [SPI_BIT_MOSI]  = NATSEMI_MEAR_EEDI,
00061         [SPI_BIT_MISO]  = NATSEMI_MEAR_EEDO,
00062         [SPI_BIT_SS(0)] = NATSEMI_MEAR_EESEL,
00063 };
00064 
00065 /**
00066  * Read input bit
00067  *
00068  * @v basher            Bit-bashing interface
00069  * @v bit_id            Bit number
00070  * @ret zero            Input is a logic 0
00071  * @ret non-zero        Input is a logic 1
00072  */
00073 static int natsemi_spi_read_bit ( struct bit_basher *basher,
00074                                   unsigned int bit_id ) {
00075         struct natsemi_nic *natsemi = container_of ( basher, struct natsemi_nic,
00076                                                      spibit.basher );
00077         uint32_t mask = natsemi_eeprom_bits[bit_id];
00078         uint32_t reg;
00079 
00080         DBG_DISABLE ( DBGLVL_IO );
00081         reg = readl ( natsemi->regs + NATSEMI_MEAR );
00082         DBG_ENABLE ( DBGLVL_IO );
00083         return ( reg & mask );
00084 }
00085 
00086 /**
00087  * Set/clear output bit
00088  *
00089  * @v basher            Bit-bashing interface
00090  * @v bit_id            Bit number
00091  * @v data              Value to write
00092  */
00093 static void natsemi_spi_write_bit ( struct bit_basher *basher,
00094                                     unsigned int bit_id, unsigned long data ) {
00095         struct natsemi_nic *natsemi = container_of ( basher, struct natsemi_nic,
00096                                                      spibit.basher );
00097         uint32_t mask = natsemi_eeprom_bits[bit_id];
00098         uint32_t reg;
00099 
00100         DBG_DISABLE ( DBGLVL_IO );
00101         reg = readl ( natsemi->regs + NATSEMI_MEAR );
00102         reg &= ~mask;
00103         reg |= ( data & mask );
00104         writel ( reg, natsemi->regs + NATSEMI_MEAR );
00105         DBG_ENABLE ( DBGLVL_IO );
00106 }
00107 
00108 /** SPI bit-bashing interface */
00109 static struct bit_basher_operations natsemi_basher_ops = {
00110         .read = natsemi_spi_read_bit,
00111         .write = natsemi_spi_write_bit,
00112 };
00113 
00114 /**
00115  * Initialise EEPROM
00116  *
00117  * @v natsemi           National Semiconductor device
00118  */
00119 static void natsemi_init_eeprom ( struct natsemi_nic *natsemi ) {
00120 
00121         /* Initialise SPI bit-bashing interface */
00122         natsemi->spibit.basher.op = &natsemi_basher_ops;
00123         natsemi->spibit.bus.mode = SPI_MODE_THREEWIRE;
00124         natsemi->spibit.endianness =
00125                 ( ( natsemi->flags & NATSEMI_EEPROM_LITTLE_ENDIAN ) ?
00126                   SPI_BIT_LITTLE_ENDIAN : SPI_BIT_BIG_ENDIAN );
00127         init_spi_bit_basher ( &natsemi->spibit );
00128 
00129         /* Initialise EEPROM device */
00130         init_at93c06 ( &natsemi->eeprom, 16 );
00131         natsemi->eeprom.bus = &natsemi->spibit.bus;
00132 }
00133 
00134 /**
00135  * Get hardware address from sane EEPROM data
00136  *
00137  * @v natsemi           National Semiconductor device
00138  * @v eeprom            EEPROM data
00139  * @v hw_addr           Hardware address to fill in
00140  */
00141 static void natsemi_hwaddr_sane ( struct natsemi_nic *natsemi,
00142                                   const uint16_t *eeprom, uint16_t *hw_addr ) {
00143         int i;
00144 
00145         /* Copy MAC address from EEPROM data */
00146         for ( i = ( ( ETH_ALEN / 2 ) - 1 ) ; i >= 0 ; i-- )
00147                 *(hw_addr++) = eeprom[ NATSEMI_EEPROM_MAC_SANE + i ];
00148 
00149         DBGC ( natsemi, "NATSEMI %p has sane EEPROM layout\n", natsemi );
00150 }
00151 
00152 /**
00153  * Get hardware address from insane EEPROM data
00154  *
00155  * @v natsemi           National Semiconductor device
00156  * @v eeprom            EEPROM data
00157  * @v hw_addr           Hardware address to fill in
00158  */
00159 static void natsemi_hwaddr_insane ( struct natsemi_nic *natsemi,
00160                                     const uint16_t *eeprom,
00161                                     uint16_t *hw_addr ) {
00162         unsigned int i;
00163         unsigned int offset;
00164         uint16_t word;
00165 
00166         /* Copy MAC address from EEPROM data */
00167         for ( i = 0 ; i < ( ETH_ALEN / 2 ) ; i++ ) {
00168                 offset = ( NATSEMI_EEPROM_MAC_INSANE + i );
00169                 word = ( ( le16_to_cpu ( eeprom[ offset ] ) >> 15 ) |
00170                          ( le16_to_cpu ( eeprom[ offset + 1 ] << 1 ) ) );
00171                 hw_addr[i] = cpu_to_le16 ( word );
00172         }
00173 
00174         DBGC ( natsemi, "NATSEMI %p has insane EEPROM layout\n", natsemi );
00175 }
00176 
00177 /**
00178  * Get hardware address from EEPROM
00179  *
00180  * @v natsemi           National Semiconductor device
00181  * @v hw_addr           Hardware address to fill in
00182  * @ret rc              Return status code
00183  */
00184 static int natsemi_hwaddr ( struct natsemi_nic *natsemi, void *hw_addr ) {
00185         uint16_t buf[NATSEMI_EEPROM_SIZE];
00186         void ( * extract ) ( struct natsemi_nic *natsemi,
00187                              const uint16_t *eeprom, uint16_t *hw_addr );
00188         int rc;
00189 
00190         /* Read EEPROM contents */
00191         if ( ( rc = nvs_read ( &natsemi->eeprom.nvs, 0, buf,
00192                                sizeof ( buf ) ) ) != 0 ) {
00193                 DBGC ( natsemi, "NATSEMI %p could not read EEPROM: %s\n",
00194                        natsemi, strerror ( rc ) );
00195                 return rc;
00196         }
00197         DBGC2 ( natsemi, "NATSEMI %p EEPROM contents:\n", natsemi );
00198         DBGC2_HDA ( natsemi, 0, buf, sizeof ( buf ) );
00199 
00200         /* Extract MAC address from EEPROM contents */
00201         extract = ( ( natsemi->flags & NATSEMI_EEPROM_INSANE ) ?
00202                     natsemi_hwaddr_insane : natsemi_hwaddr_sane );
00203         extract ( natsemi, buf, hw_addr );
00204 
00205         return 0;
00206 }
00207 
00208 /******************************************************************************
00209  *
00210  * Device reset
00211  *
00212  ******************************************************************************
00213  */
00214 
00215 /**
00216  * Reset controller chip
00217  *
00218  * @v natsemi           National Semiconductor device
00219  * @ret rc              Return status code
00220  */
00221 static int natsemi_soft_reset ( struct natsemi_nic *natsemi ) {
00222         unsigned int i;
00223 
00224         /* Initiate reset */
00225         writel ( NATSEMI_CR_RST, natsemi->regs + NATSEMI_CR );
00226 
00227         /* Wait for reset to complete */
00228         for ( i = 0 ; i < NATSEMI_RESET_MAX_WAIT_MS ; i++ ) {
00229 
00230                 /* If reset is not complete, delay 1ms and retry */
00231                 if ( readl ( natsemi->regs + NATSEMI_CR ) & NATSEMI_CR_RST ) {
00232                         mdelay ( 1 );
00233                         continue;
00234                 }
00235 
00236                 return 0;
00237         }
00238 
00239         DBGC ( natsemi, "NATSEMI %p timed out waiting for reset\n", natsemi );
00240         return -ETIMEDOUT;
00241 }
00242 
00243 /**
00244  * Reload configuration from EEPROM
00245  *
00246  * @v natsemi           National Semiconductor device
00247  * @ret rc              Return status code
00248  */
00249 static int natsemi_reload_config ( struct natsemi_nic *natsemi ) {
00250         unsigned int i;
00251 
00252         /* Initiate reload */
00253         writel ( NATSEMI_PTSCR_EELOAD_EN, natsemi->regs + NATSEMI_PTSCR );
00254 
00255         /* Wait for reload to complete */
00256         for ( i = 0 ; i < NATSEMI_EELOAD_MAX_WAIT_MS ; i++ ) {
00257 
00258                 /* If reload is not complete, delay 1ms and retry */
00259                 if ( readl ( natsemi->regs + NATSEMI_PTSCR ) &
00260                      NATSEMI_PTSCR_EELOAD_EN ) {
00261                         mdelay ( 1 );
00262                         continue;
00263                 }
00264 
00265                 return 0;
00266         }
00267 
00268         DBGC ( natsemi, "NATSEMI %p timed out waiting for configuration "
00269                "reload\n", natsemi );
00270         return -ETIMEDOUT;
00271 }
00272 
00273 /**
00274  * Reset hardware
00275  *
00276  * @v natsemi           National Semiconductor device
00277  * @ret rc              Return status code
00278  */
00279 static int natsemi_reset ( struct natsemi_nic *natsemi ) {
00280         uint32_t cfg;
00281         int rc;
00282 
00283         /* Perform soft reset */
00284         if ( ( rc = natsemi_soft_reset ( natsemi ) ) != 0 )
00285                 return rc;
00286 
00287         /* Reload configuration from EEPROM */
00288         if ( ( rc = natsemi_reload_config ( natsemi ) ) != 0 )
00289                 return rc;
00290 
00291         /* Configure 64-bit operation, if applicable */
00292         cfg = readl ( natsemi->regs + NATSEMI_CFG );
00293         if ( natsemi->flags & NATSEMI_64BIT ) {
00294                 cfg |= ( NATSEMI_CFG_M64ADDR | NATSEMI_CFG_EXTSTS_EN );
00295                 if ( ! ( cfg & NATSEMI_CFG_PCI64_DET ) )
00296                         cfg &= ~NATSEMI_CFG_DATA64_EN;
00297         }
00298         writel ( cfg, natsemi->regs + NATSEMI_CFG );
00299 
00300         /* Invalidate link status cache to force an update */
00301         natsemi->cfg = ~cfg;
00302 
00303         DBGC ( natsemi, "NATSEMI %p using configuration %08x\n",
00304                natsemi, cfg );
00305         return 0;
00306 }
00307 
00308 /******************************************************************************
00309  *
00310  * Link state
00311  *
00312  ******************************************************************************
00313  */
00314 
00315 /**
00316  * Check link state
00317  *
00318  * @v netdev            Network device
00319  */
00320 static void natsemi_check_link ( struct net_device *netdev ) {
00321         struct natsemi_nic *natsemi = netdev->priv;
00322         uint32_t cfg;
00323 
00324         /* Read link status */
00325         cfg = readl ( natsemi->regs + NATSEMI_CFG );
00326 
00327         /* Do nothing unless link status has changed */
00328         if ( cfg == natsemi->cfg )
00329                 return;
00330 
00331         /* Set gigabit mode (if applicable) */
00332         if ( natsemi->flags & NATSEMI_1000 ) {
00333                 cfg &= ~NATSEMI_CFG_MODE_1000;
00334                 if ( ! ( cfg & NATSEMI_CFG_SPDSTS1 ) )
00335                         cfg |= NATSEMI_CFG_MODE_1000;
00336                 writel ( cfg, natsemi->regs + NATSEMI_CFG );
00337         }
00338 
00339         /* Update link status */
00340         natsemi->cfg = cfg;
00341         DBGC ( natsemi, "NATSEMI %p link status is %08x\n", natsemi, cfg );
00342 
00343         /* Update network device */
00344         if ( cfg & NATSEMI_CFG_LNKSTS ) {
00345                 netdev_link_up ( netdev );
00346         } else {
00347                 netdev_link_down ( netdev );
00348         }
00349 }
00350 
00351 /******************************************************************************
00352  *
00353  * Network device interface
00354  *
00355  ******************************************************************************
00356  */
00357 
00358 /**
00359  * Set perfect match filter address
00360  *
00361  * @v natsemi           National Semiconductor device
00362  * @v mac               MAC address
00363  */
00364 static void natsemi_pmatch ( struct natsemi_nic *natsemi, const void *mac ) {
00365         const uint16_t *pmatch = mac;
00366         uint32_t rfcr;
00367         unsigned int rfaddr;
00368         unsigned int i;
00369 
00370         for ( i = 0 ; i < ETH_ALEN ; i += sizeof ( *pmatch ) ) {
00371 
00372                 /* Select receive filter register address */
00373                 rfaddr = ( NATSEMI_RFADDR_PMATCH_BASE + i );
00374                 rfcr = readl ( natsemi->regs + NATSEMI_RFCR );
00375                 rfcr &= ~NATSEMI_RFCR_RFADDR_MASK;
00376                 rfcr |= NATSEMI_RFCR_RFADDR ( rfaddr );
00377                 writel ( rfcr, natsemi->regs + NATSEMI_RFCR );
00378 
00379                 /* Write receive filter data */
00380                 writel ( ( le16_to_cpu ( *(pmatch++) ) | NATSEMI_RFDR_BMASK ),
00381                          natsemi->regs + NATSEMI_RFDR );
00382         }
00383 }
00384 
00385 /**
00386  * Create descriptor ring
00387  *
00388  * @v natsemi           National Semiconductor device
00389  * @v ring              Descriptor ring
00390  * @ret rc              Return status code
00391  */
00392 static int natsemi_create_ring ( struct natsemi_nic *natsemi,
00393                                  struct natsemi_ring *ring ) {
00394         size_t len = ( ring->count * sizeof ( ring->desc[0] ) );
00395         union natsemi_descriptor *desc;
00396         union natsemi_descriptor *linked_desc;
00397         physaddr_t address;
00398         physaddr_t link;
00399         size_t offset;
00400         unsigned int i;
00401         int rc;
00402 
00403         /* Calculate descriptor offset */
00404         offset = ( ( natsemi->flags & NATSEMI_64BIT ) ? 0 :
00405                    offsetof ( typeof ( desc[i].d32pad ), d32 ) );
00406 
00407         /* Allocate descriptor ring.  Align ring on its own size to
00408          * ensure that it can't possibly cross the boundary of 32-bit
00409          * address space.
00410          */
00411         ring->desc = malloc_dma ( len, len );
00412         if ( ! ring->desc ) {
00413                 rc = -ENOMEM;
00414                 goto err_alloc;
00415         }
00416         address = ( virt_to_bus ( ring->desc ) + offset );
00417 
00418         /* Check address is usable by card */
00419         if ( ! natsemi_address_ok ( natsemi, address ) ) {
00420                 DBGC ( natsemi, "NATSEMI %p cannot support 64-bit ring "
00421                        "address\n", natsemi );
00422                 rc = -ENOTSUP;
00423                 goto err_64bit;
00424         }
00425 
00426         /* Initialise descriptor ring */
00427         memset ( ring->desc, 0, len );
00428         for ( i = 0 ; i < ring->count ; i++ ) {
00429                 linked_desc = &ring->desc [ ( i + 1 ) % ring->count ];
00430                 link = ( virt_to_bus ( linked_desc ) + offset );
00431                 if ( natsemi->flags & NATSEMI_64BIT ) {
00432                         ring->desc[i].d64.link = cpu_to_le64 ( link );
00433                 } else {
00434                         ring->desc[i].d32pad.d32.link = cpu_to_le32 ( link );
00435                 }
00436         }
00437 
00438         /* Program ring address */
00439         writel ( ( address & 0xffffffffUL ), natsemi->regs + ring->reg );
00440         if ( natsemi->flags & NATSEMI_64BIT ) {
00441                 if ( sizeof ( physaddr_t ) > sizeof ( uint32_t ) ) {
00442                         writel ( ( ( ( uint64_t ) address ) >> 32 ),
00443                                  natsemi->regs + ring->reg + 4 );
00444                 } else {
00445                         writel ( 0, natsemi->regs + ring->reg + 4 );
00446                 }
00447         }
00448 
00449         DBGC ( natsemi, "NATSEMI %p ring %02x is at [%08llx,%08llx)\n",
00450                natsemi, ring->reg,
00451                ( ( unsigned long long ) virt_to_bus ( ring->desc ) ),
00452                ( ( unsigned long long ) virt_to_bus ( ring->desc ) + len ) );
00453 
00454         return 0;
00455 
00456  err_64bit:
00457         free_dma ( ring->desc, len );
00458         ring->desc = NULL;
00459  err_alloc:
00460         return rc;
00461 }
00462 
00463 /**
00464  * Destroy descriptor ring
00465  *
00466  * @v natsemi           National Semiconductor device
00467  * @v ring              Descriptor ring
00468  */
00469 static void natsemi_destroy_ring ( struct natsemi_nic *natsemi,
00470                                    struct natsemi_ring *ring ) {
00471         size_t len = ( ring->count * sizeof ( ring->desc[0] ) );
00472 
00473         /* Clear ring address */
00474         writel ( 0, natsemi->regs + ring->reg );
00475         if ( natsemi->flags & NATSEMI_64BIT )
00476                 writel ( 0, natsemi->regs + ring->reg + 4 );
00477 
00478         /* Free descriptor ring */
00479         free_dma ( ring->desc, len );
00480         ring->desc = NULL;
00481         ring->prod = 0;
00482         ring->cons = 0;
00483 }
00484 
00485 /**
00486  * Refill receive descriptor ring
00487  *
00488  * @v netdev            Network device
00489  */
00490 static void natsemi_refill_rx ( struct net_device *netdev ) {
00491         struct natsemi_nic *natsemi = netdev->priv;
00492         union natsemi_descriptor *rx;
00493         struct io_buffer *iobuf;
00494         unsigned int rx_idx;
00495         physaddr_t address;
00496 
00497         while ( ( natsemi->rx.prod - natsemi->rx.cons ) < NATSEMI_NUM_RX_DESC ){
00498 
00499                 /* Allocate I/O buffer */
00500                 iobuf = alloc_iob ( NATSEMI_RX_MAX_LEN );
00501                 if ( ! iobuf ) {
00502                         /* Wait for next refill */
00503                         return;
00504                 }
00505 
00506                 /* Check address is usable by card */
00507                 address = virt_to_bus ( iobuf->data );
00508                 if ( ! natsemi_address_ok ( natsemi, address ) ) {
00509                         DBGC ( natsemi, "NATSEMI %p cannot support 64-bit RX "
00510                                "buffer address\n", natsemi );
00511                         netdev_rx_err ( netdev, iobuf, -ENOTSUP );
00512                         return;
00513                 }
00514 
00515                 /* Get next receive descriptor */
00516                 rx_idx = ( natsemi->rx.prod++ % NATSEMI_NUM_RX_DESC );
00517                 rx = &natsemi->rx.desc[rx_idx];
00518 
00519                 /* Populate receive descriptor */
00520                 if ( natsemi->flags & NATSEMI_64BIT ) {
00521                         rx->d64.bufptr = cpu_to_le64 ( address );
00522                 } else {
00523                         rx->d32pad.d32.bufptr = cpu_to_le32 ( address );
00524                 }
00525                 wmb();
00526                 rx->common.cmdsts = cpu_to_le32 ( NATSEMI_DESC_INTR |
00527                                                   NATSEMI_RX_MAX_LEN );
00528                 wmb();
00529 
00530                 /* Record I/O buffer */
00531                 assert ( natsemi->rx_iobuf[rx_idx] == NULL );
00532                 natsemi->rx_iobuf[rx_idx] = iobuf;
00533 
00534                 /* Notify card that there are descriptors available */
00535                 writel ( NATSEMI_CR_RXE, natsemi->regs + NATSEMI_CR );
00536 
00537                 DBGC2 ( natsemi, "NATSEMI %p RX %d is [%llx,%llx)\n", natsemi,
00538                         rx_idx, ( ( unsigned long long ) address ),
00539                         ( ( unsigned long long ) address + NATSEMI_RX_MAX_LEN));
00540         }
00541 }
00542 
00543 /**
00544  * Open network device
00545  *
00546  * @v netdev            Network device
00547  * @ret rc              Return status code
00548  */
00549 static int natsemi_open ( struct net_device *netdev ) {
00550         struct natsemi_nic *natsemi = netdev->priv;
00551         int rc;
00552 
00553         /* Set MAC address */
00554         natsemi_pmatch ( natsemi, netdev->ll_addr );
00555 
00556         /* Create transmit descriptor ring */
00557         if ( ( rc = natsemi_create_ring ( natsemi, &natsemi->tx ) ) != 0 )
00558                 goto err_create_tx;
00559 
00560         /* Set transmit configuration */
00561         writel ( ( NATSEMI_TXCFG_CSI | NATSEMI_TXCFG_HBI | NATSEMI_TXCFG_ATP |
00562                    NATSEMI_TXCFG_ECRETRY | NATSEMI_TXCFG_MXDMA_DEFAULT |
00563                    NATSEMI_TXCFG_FLTH_DEFAULT | NATSEMI_TXCFG_DRTH_DEFAULT ),
00564                  ( natsemi->regs + ( ( natsemi->flags & NATSEMI_64BIT ) ?
00565                                      NATSEMI_TXCFG_64 : NATSEMI_TXCFG_32 ) ) );
00566 
00567         /* Create receive descriptor ring */
00568         if ( ( rc = natsemi_create_ring ( natsemi, &natsemi->rx ) ) != 0 )
00569                 goto err_create_rx;
00570 
00571         /* Set receive configuration */
00572         writel ( ( NATSEMI_RXCFG_ARP | NATSEMI_RXCFG_ATX | NATSEMI_RXCFG_ALP |
00573                    NATSEMI_RXCFG_MXDMA_DEFAULT | NATSEMI_RXCFG_DRTH_DEFAULT ),
00574                  ( natsemi->regs + ( ( natsemi->flags & NATSEMI_64BIT ) ?
00575                                      NATSEMI_RXCFG_64 : NATSEMI_RXCFG_32 ) ) );
00576 
00577         /* Set receive filter configuration */
00578         writel ( ( NATSEMI_RFCR_RFEN | NATSEMI_RFCR_AAB | NATSEMI_RFCR_AAM |
00579                    NATSEMI_RFCR_AAU ), natsemi->regs + NATSEMI_RFCR );
00580 
00581         /* Fill receive ring */
00582         natsemi_refill_rx ( netdev );
00583 
00584         /* Unmask transmit and receive interrupts.  (Interrupts will
00585          * not be generated unless enabled via the IER.)
00586          */
00587         writel ( ( NATSEMI_IRQ_TXDESC | NATSEMI_IRQ_RXDESC ),
00588                  natsemi->regs + NATSEMI_IMR );
00589 
00590         /* Update link state */
00591         natsemi_check_link ( netdev );
00592 
00593         return 0;
00594 
00595         natsemi_destroy_ring ( natsemi, &natsemi->rx );
00596  err_create_rx:
00597         natsemi_destroy_ring ( natsemi, &natsemi->tx );
00598  err_create_tx:
00599         return rc;
00600 }
00601 
00602 /**
00603  * Close network device
00604  *
00605  * @v netdev            Network device
00606  */
00607 static void natsemi_close ( struct net_device *netdev ) {
00608         struct natsemi_nic *natsemi = netdev->priv;
00609         unsigned int i;
00610 
00611         /* Mask transmit and receive interrupts */
00612         writel ( 0, natsemi->regs + NATSEMI_IMR );
00613 
00614         /* Reset and disable transmitter and receiver */
00615         writel ( ( NATSEMI_CR_RXR | NATSEMI_CR_TXR ),
00616                  natsemi->regs + NATSEMI_CR );
00617 
00618         /* Discard any unused receive buffers */
00619         for ( i = 0 ; i < NATSEMI_NUM_RX_DESC ; i++ ) {
00620                 if ( natsemi->rx_iobuf[i] )
00621                         free_iob ( natsemi->rx_iobuf[i] );
00622                 natsemi->rx_iobuf[i] = NULL;
00623         }
00624 
00625         /* Destroy receive descriptor ring */
00626         natsemi_destroy_ring ( natsemi, &natsemi->rx );
00627 
00628         /* Destroy transmit descriptor ring */
00629         natsemi_destroy_ring ( natsemi, &natsemi->tx );
00630 }
00631 
00632 /**
00633  * Transmit packet
00634  *
00635  * @v netdev            Network device
00636  * @v iobuf             I/O buffer
00637  * @ret rc              Return status code
00638  */
00639 static int natsemi_transmit ( struct net_device *netdev,
00640                                struct io_buffer *iobuf ) {
00641         struct natsemi_nic *natsemi = netdev->priv;
00642         union natsemi_descriptor *tx;
00643         unsigned int tx_idx;
00644         physaddr_t address;
00645 
00646         /* Check address is usable by card */
00647         address = virt_to_bus ( iobuf->data );
00648         if ( ! natsemi_address_ok ( natsemi, address ) ) {
00649                 DBGC ( natsemi, "NATSEMI %p cannot support 64-bit TX buffer "
00650                        "address\n", natsemi );
00651                 return -ENOTSUP;
00652         }
00653 
00654         /* Get next transmit descriptor */
00655         if ( ( natsemi->tx.prod - natsemi->tx.cons ) >= NATSEMI_NUM_TX_DESC ) {
00656                 DBGC ( natsemi, "NATSEMI %p out of transmit descriptors\n",
00657                        natsemi );
00658                 return -ENOBUFS;
00659         }
00660         tx_idx = ( natsemi->tx.prod++ % NATSEMI_NUM_TX_DESC );
00661         tx = &natsemi->tx.desc[tx_idx];
00662 
00663         /* Populate transmit descriptor */
00664         if ( natsemi->flags & NATSEMI_64BIT ) {
00665                 tx->d64.bufptr = cpu_to_le64 ( address );
00666         } else {
00667                 tx->d32pad.d32.bufptr = cpu_to_le32 ( address );
00668         }
00669         wmb();
00670         tx->common.cmdsts = cpu_to_le32 ( NATSEMI_DESC_OWN | NATSEMI_DESC_INTR |
00671                                           iob_len ( iobuf ) );
00672         wmb();
00673 
00674         /* Notify card that there are packets ready to transmit */
00675         writel ( NATSEMI_CR_TXE, natsemi->regs + NATSEMI_CR );
00676 
00677         DBGC2 ( natsemi, "NATSEMI %p TX %d is [%llx,%llx)\n", natsemi, tx_idx,
00678                 ( ( unsigned long long ) address ),
00679                 ( ( unsigned long long ) address + iob_len ( iobuf ) ) );
00680 
00681         return 0;
00682 }
00683 
00684 /**
00685  * Poll for completed packets
00686  *
00687  * @v netdev            Network device
00688  */
00689 static void natsemi_poll_tx ( struct net_device *netdev ) {
00690         struct natsemi_nic *natsemi = netdev->priv;
00691         union natsemi_descriptor *tx;
00692         unsigned int tx_idx;
00693 
00694         /* Check for completed packets */
00695         while ( natsemi->tx.cons != natsemi->tx.prod ) {
00696 
00697                 /* Get next transmit descriptor */
00698                 tx_idx = ( natsemi->tx.cons % NATSEMI_NUM_TX_DESC );
00699                 tx = &natsemi->tx.desc[tx_idx];
00700 
00701                 /* Stop if descriptor is still in use */
00702                 if ( tx->common.cmdsts & cpu_to_le32 ( NATSEMI_DESC_OWN ) )
00703                         return;
00704 
00705                 /* Complete TX descriptor */
00706                 if ( tx->common.cmdsts & cpu_to_le32 ( NATSEMI_DESC_OK ) ) {
00707                         DBGC2 ( natsemi, "NATSEMI %p TX %d complete\n",
00708                                 natsemi, tx_idx );
00709                         netdev_tx_complete_next ( netdev );
00710                 } else {
00711                         DBGC ( natsemi, "NATSEMI %p TX %d completion error "
00712                                "(%08x)\n", natsemi, tx_idx,
00713                                le32_to_cpu ( tx->common.cmdsts ) );
00714                         netdev_tx_complete_next_err ( netdev, -EIO );
00715                 }
00716                 natsemi->tx.cons++;
00717         }
00718 }
00719 
00720 /**
00721  * Poll for received packets
00722  *
00723  * @v netdev            Network device
00724  */
00725 static void natsemi_poll_rx ( struct net_device *netdev ) {
00726         struct natsemi_nic *natsemi = netdev->priv;
00727         union natsemi_descriptor *rx;
00728         struct io_buffer *iobuf;
00729         unsigned int rx_idx;
00730         size_t len;
00731 
00732         /* Check for received packets */
00733         while ( natsemi->rx.cons != natsemi->rx.prod ) {
00734 
00735                 /* Get next receive descriptor */
00736                 rx_idx = ( natsemi->rx.cons % NATSEMI_NUM_RX_DESC );
00737                 rx = &natsemi->rx.desc[rx_idx];
00738 
00739                 /* Stop if descriptor is still in use */
00740                 if ( ! ( rx->common.cmdsts & NATSEMI_DESC_OWN ) )
00741                         return;
00742 
00743                 /* Populate I/O buffer */
00744                 iobuf = natsemi->rx_iobuf[rx_idx];
00745                 natsemi->rx_iobuf[rx_idx] = NULL;
00746                 len = ( le32_to_cpu ( rx->common.cmdsts ) &
00747                         NATSEMI_DESC_SIZE_MASK );
00748                 iob_put ( iobuf, len - 4 /* strip CRC */ );
00749 
00750                 /* Hand off to network stack */
00751                 if ( rx->common.cmdsts & cpu_to_le32 ( NATSEMI_DESC_OK ) ) {
00752                         DBGC2 ( natsemi, "NATSEMI %p RX %d complete (length "
00753                                 "%zd)\n", natsemi, rx_idx, len );
00754                         netdev_rx ( netdev, iobuf );
00755                 } else {
00756                         DBGC ( natsemi, "NATSEMI %p RX %d error (length %zd, "
00757                                "status %08x)\n", natsemi, rx_idx, len,
00758                                le32_to_cpu ( rx->common.cmdsts ) );
00759                         netdev_rx_err ( netdev, iobuf, -EIO );
00760                 }
00761                 natsemi->rx.cons++;
00762         }
00763 }
00764 
00765 /**
00766  * Poll for completed and received packets
00767  *
00768  * @v netdev            Network device
00769  */
00770 static void natsemi_poll ( struct net_device *netdev ) {
00771         struct natsemi_nic *natsemi = netdev->priv;
00772         uint32_t isr;
00773 
00774         /* Poll for link state.  The PHY interrupt seems not to
00775          * function as expected, and polling for the link state is
00776          * only a single register read.
00777          */
00778         natsemi_check_link ( netdev );
00779 
00780         /* Check for and acknowledge interrupts */
00781         isr = readl ( natsemi->regs + NATSEMI_ISR );
00782         if ( ! isr )
00783                 return;
00784 
00785         /* Poll for TX completions, if applicable */
00786         if ( isr & NATSEMI_IRQ_TXDESC )
00787                 natsemi_poll_tx ( netdev );
00788 
00789         /* Poll for RX completionsm, if applicable */
00790         if ( isr & NATSEMI_IRQ_RXDESC )
00791                 natsemi_poll_rx ( netdev );
00792 
00793         /* Refill RX ring */
00794         natsemi_refill_rx ( netdev );
00795 }
00796 
00797 /**
00798  * Enable or disable interrupts
00799  *
00800  * @v netdev            Network device
00801  * @v enable            Interrupts should be enabled
00802  */
00803 static void natsemi_irq ( struct net_device *netdev, int enable ) {
00804         struct natsemi_nic *natsemi = netdev->priv;
00805 
00806         /* Enable or disable interrupts */
00807         writel ( ( enable ? NATSEMI_IER_IE : 0 ), natsemi->regs + NATSEMI_IER );
00808 }
00809 
00810 /** National Semiconductor network device operations */
00811 static struct net_device_operations natsemi_operations = {
00812         .open           = natsemi_open,
00813         .close          = natsemi_close,
00814         .transmit       = natsemi_transmit,
00815         .poll           = natsemi_poll,
00816         .irq            = natsemi_irq,
00817 };
00818 
00819 /******************************************************************************
00820  *
00821  * PCI interface
00822  *
00823  ******************************************************************************
00824  */
00825 
00826 /**
00827  * Probe PCI device
00828  *
00829  * @v pci               PCI device
00830  * @ret rc              Return status code
00831  */
00832 static int natsemi_probe ( struct pci_device *pci ) {
00833         struct net_device *netdev;
00834         struct natsemi_nic *natsemi;
00835         int rc;
00836 
00837         /* Allocate and initialise net device */
00838         netdev = alloc_etherdev ( sizeof ( *natsemi ) );
00839         if ( ! netdev ) {
00840                 rc = -ENOMEM;
00841                 goto err_alloc;
00842         }
00843         netdev_init ( netdev, &natsemi_operations );
00844         natsemi = netdev->priv;
00845         pci_set_drvdata ( pci, netdev );
00846         netdev->dev = &pci->dev;
00847         memset ( natsemi, 0, sizeof ( *natsemi ) );
00848         natsemi->flags = pci->id->driver_data;
00849         natsemi_init_ring ( &natsemi->tx, NATSEMI_NUM_TX_DESC, NATSEMI_TXDP );
00850         natsemi_init_ring ( &natsemi->rx, NATSEMI_NUM_RX_DESC, NATSEMI_RXDP );
00851 
00852         /* Fix up PCI device */
00853         adjust_pci_device ( pci );
00854 
00855         /* Map registers */
00856         natsemi->regs = ioremap ( pci->membase, NATSEMI_BAR_SIZE );
00857         if ( ! natsemi->regs ) {
00858                 rc = -ENODEV;
00859                 goto err_ioremap;
00860         }
00861 
00862         /* Reset the NIC */
00863         if ( ( rc = natsemi_reset ( natsemi ) ) != 0 )
00864                 goto err_reset;
00865 
00866         /* Initialise EEPROM */
00867         natsemi_init_eeprom ( natsemi );
00868 
00869         /* Read initial MAC address */
00870         if ( ( rc = natsemi_hwaddr ( natsemi, netdev->hw_addr ) ) != 0 )
00871                 goto err_hwaddr;
00872 
00873         /* Register network device */
00874         if ( ( rc = register_netdev ( netdev ) ) != 0 )
00875                 goto err_register_netdev;
00876 
00877         /* Set initial link state */
00878         natsemi_check_link ( netdev );
00879 
00880         return 0;
00881 
00882         unregister_netdev ( netdev );
00883  err_register_netdev:
00884  err_hwaddr:
00885         natsemi_reset ( natsemi );
00886  err_reset:
00887         iounmap ( natsemi->regs );
00888  err_ioremap:
00889         netdev_nullify ( netdev );
00890         netdev_put ( netdev );
00891  err_alloc:
00892         return rc;
00893 }
00894 
00895 /**
00896  * Remove PCI device
00897  *
00898  * @v pci               PCI device
00899  */
00900 static void natsemi_remove ( struct pci_device *pci ) {
00901         struct net_device *netdev = pci_get_drvdata ( pci );
00902         struct natsemi_nic *natsemi = netdev->priv;
00903 
00904         /* Unregister network device */
00905         unregister_netdev ( netdev );
00906 
00907         /* Reset card */
00908         natsemi_reset ( natsemi );
00909 
00910         /* Free network device */
00911         iounmap ( natsemi->regs );
00912         netdev_nullify ( netdev );
00913         netdev_put ( netdev );
00914 }
00915 
00916 /** Flags for DP83815 */
00917 #define DP83815_FLAGS ( NATSEMI_EEPROM_LITTLE_ENDIAN | NATSEMI_EEPROM_INSANE )
00918 
00919 /** Flags for DP83820 */
00920 #define DP83820_FLAGS ( NATSEMI_64BIT | NATSEMI_1000 )
00921 
00922 /** National Semiconductor PCI device IDs */
00923 static struct pci_device_id natsemi_nics[] = {
00924         PCI_ROM ( 0x100b, 0x0020, "dp83815", "DP83815", DP83815_FLAGS ),
00925         PCI_ROM ( 0x100b, 0x0022, "dp83820", "DP83820", DP83820_FLAGS ),
00926 };
00927 
00928 /** National Semiconductor PCI driver */
00929 struct pci_driver natsemi_driver __pci_driver = {
00930         .ids = natsemi_nics,
00931         .id_count = ( sizeof ( natsemi_nics ) / sizeof ( natsemi_nics[0] ) ),
00932         .probe = natsemi_probe,
00933         .remove = natsemi_remove,
00934 };