Annotation of qemu/roms/ipxe/src/drivers/net/pcnet32.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 2010 Andrei Faur <[email protected]>
                      3:  *
                      4:  * This program is free software; you can redistribute it and/or
                      5:  * modify it under the terms of the GNU General Public License as
                      6:  * published by the Free Software Foundation; either version 2 of the
                      7:  * License, or any later version.
                      8:  *
                      9:  * This program is distributed in the hope that it will be useful, but
                     10:  * WITHOUT ANY WARRANTY; without even the implied warranty of
                     11:  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
                     12:  * General Public License for more details.
                     13:  *
                     14:  * You should have received a copy of the GNU General Public License
                     15:  * along with this program; if not, write to the Free Software
                     16:  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
                     17:  *
                     18:  */
                     19: 
                     20: FILE_LICENCE ( GPL2_OR_LATER );
                     21: 
                     22: #include <stdint.h>
                     23: #include <stdio.h>
                     24: #include <stdlib.h>
                     25: #include <string.h>
                     26: #include <unistd.h>
                     27: #include <assert.h>
                     28: #include <byteswap.h>
                     29: #include <errno.h>
                     30: #include <ipxe/ethernet.h>
                     31: #include <ipxe/if_ether.h>
                     32: #include <ipxe/io.h>
                     33: #include <ipxe/iobuf.h>
                     34: #include <ipxe/malloc.h>
                     35: #include <ipxe/netdevice.h>
                     36: #include <ipxe/pci.h>
                     37: #include <ipxe/timer.h>
                     38: #include <mii.h>
                     39: #include "pcnet32.h"
                     40: 
                     41: static u16 pcnet32_wio_read_csr ( unsigned long addr, int index )
                     42: {
                     43:        outw ( index, addr + PCNET32_WIO_RAP );
                     44:        return inw ( addr + PCNET32_WIO_RDP );
                     45: }
                     46: 
                     47: static void pcnet32_wio_write_csr ( unsigned long addr, int index, u16 val )
                     48: {
                     49:        outw ( index, addr + PCNET32_WIO_RAP );
                     50:        outw ( val, addr + PCNET32_WIO_RDP );
                     51: }
                     52: 
                     53: static u16 pcnet32_wio_read_bcr ( unsigned long addr, int index )
                     54: {
                     55:        outw ( index, addr + PCNET32_WIO_RAP );
                     56:        return inw ( addr + PCNET32_WIO_BDP );
                     57: }
                     58: 
                     59: static void pcnet32_wio_write_bcr ( unsigned long addr, int index, u16 val )
                     60: {
                     61:        outw ( index, addr + PCNET32_WIO_RAP );
                     62:        outw ( val, addr + PCNET32_WIO_BDP );
                     63: }
                     64: 
                     65: static u16 pcnet32_wio_read_rap ( unsigned long addr )
                     66: {
                     67:        return inw ( addr + PCNET32_WIO_RAP );
                     68: }
                     69: 
                     70: static void pcnet32_wio_write_rap ( unsigned long addr , u16 val )
                     71: {
                     72:        outw ( val, addr + PCNET32_WIO_RAP );
                     73: }
                     74: 
                     75: static void pcnet32_wio_reset ( unsigned long addr )
                     76: {
                     77:        inw ( addr + PCNET32_WIO_RESET );
                     78: }
                     79: 
                     80: static int pcnet32_wio_check ( unsigned long addr )
                     81: {
                     82:        outw ( 88, addr + PCNET32_WIO_RAP );
                     83:        return ( inw ( addr + PCNET32_WIO_RAP ) == 88 );
                     84: }
                     85: 
                     86: static struct pcnet32_access pcnet32_wio = {
                     87:        .read_csr       = pcnet32_wio_read_csr,
                     88:        .write_csr      = pcnet32_wio_write_csr,
                     89:        .read_bcr       = pcnet32_wio_read_bcr,
                     90:        .write_bcr      = pcnet32_wio_write_bcr,
                     91:        .read_rap       = pcnet32_wio_read_rap,
                     92:        .write_rap      = pcnet32_wio_write_rap,
                     93:        .reset          = pcnet32_wio_reset,
                     94: };
                     95: 
                     96: static u16 pcnet32_dwio_read_csr ( unsigned long addr, int index )
                     97: {
                     98:        outl ( index, addr + PCNET32_DWIO_RAP );
                     99:        return ( inl ( addr + PCNET32_DWIO_RDP ) & 0xffff );
                    100: }
                    101: 
                    102: static void pcnet32_dwio_write_csr ( unsigned long addr, int index, u16 val )
                    103: {
                    104:        outl ( index, addr + PCNET32_DWIO_RAP );
                    105:        outl ( val, addr + PCNET32_DWIO_RDP );
                    106: }
                    107: 
                    108: static u16 pcnet32_dwio_read_bcr ( unsigned long addr, int index )
                    109: {
                    110:        outl ( index, addr + PCNET32_DWIO_RAP );
                    111:        return ( inl ( addr + PCNET32_DWIO_BDP ) & 0xffff );
                    112: }
                    113: 
                    114: static void pcnet32_dwio_write_bcr ( unsigned long addr, int index, u16 val )
                    115: {
                    116:        outl ( index, addr + PCNET32_DWIO_RAP );
                    117:        outl ( val, addr + PCNET32_DWIO_BDP );
                    118: }
                    119: 
                    120: static u16 pcnet32_dwio_read_rap ( unsigned long addr )
                    121: {
                    122:        return ( inl ( addr + PCNET32_DWIO_RAP ) & 0xffff );
                    123: }
                    124: 
                    125: static void pcnet32_dwio_write_rap ( unsigned long addr , u16 val )
                    126: {
                    127:        outl ( val, addr + PCNET32_DWIO_RAP );
                    128: }
                    129: 
                    130: static void pcnet32_dwio_reset ( unsigned long addr )
                    131: {
                    132:        inl ( addr + PCNET32_DWIO_RESET );
                    133: }
                    134: 
                    135: static int pcnet32_dwio_check ( unsigned long addr )
                    136: {
                    137:        outl ( 88, addr + PCNET32_DWIO_RAP );
                    138:        return ( ( inl ( addr + PCNET32_DWIO_RAP ) & 0xffff ) == 88 );
                    139: }
                    140: 
                    141: 
                    142: static struct pcnet32_access pcnet32_dwio = {
                    143:        .read_csr       = pcnet32_dwio_read_csr,
                    144:        .write_csr      = pcnet32_dwio_write_csr,
                    145:        .read_bcr       = pcnet32_dwio_read_bcr,
                    146:        .write_bcr      = pcnet32_dwio_write_bcr,
                    147:        .read_rap       = pcnet32_dwio_read_rap,
                    148:        .write_rap      = pcnet32_dwio_write_rap,
                    149:        .reset          = pcnet32_dwio_reset,
                    150: };
                    151: 
                    152: static int
                    153: pcnet32_mdio_read ( struct net_device *netdev, int phy, int reg )
                    154: {
                    155:        struct pcnet32_private *priv = netdev->priv;
                    156:        unsigned long ioaddr = priv->pci_dev->ioaddr;
                    157:        u16 val_out;
                    158: 
                    159:        if ( ! priv->mii )
                    160:                return 0;
                    161: 
                    162:        /* First, select PHY chip and the register we want to read */
                    163:        priv->a->write_bcr ( ioaddr, 33,
                    164:                ( ( phy & 0x1f ) << 5 ) | ( reg & 0x1f ) );
                    165: 
                    166:        /* Read the selected register's value */
                    167:        val_out = priv->a->read_bcr ( ioaddr, 34 );
                    168: 
                    169:        return val_out;
                    170: }
                    171: 
                    172: static void
                    173: __unused pcnet32_mdio_write ( struct net_device *netdev, int phy, int reg, int val )
                    174: {
                    175:        struct pcnet32_private *priv = netdev->priv;
                    176:        unsigned long ioaddr = priv->pci_dev->ioaddr;
                    177: 
                    178:        if ( ! priv->mii )
                    179:                return;
                    180: 
                    181:        /* First, select PHY chip and the register we want to write to */
                    182:        priv->a->write_bcr ( ioaddr, 33,
                    183:                ( ( phy & 0x1f ) << 5 ) | ( reg & 0x1f ) );
                    184: 
                    185:        /* Write val to the selected register */
                    186:        priv->a->write_bcr ( ioaddr, 34, val );
                    187: }
                    188: 
                    189: 
                    190: /**
                    191:  * pcnet32_refill_rx_ring - Allocates iobufs for every Rx descriptor
                    192:  * that doesn't have one and isn't in use by the hardware
                    193:  *
                    194:  * @v priv     Driver private structure
                    195:  */
                    196: static void
                    197: pcnet32_refill_rx_ring ( struct pcnet32_private *priv )
                    198: {
                    199:        struct pcnet32_rx_desc *rx_curr_desc;
                    200:        u16 status;
                    201:        int i;
                    202: 
                    203:        DBGP ( "pcnet32_refill_rx_ring\n" );
                    204: 
                    205:        for ( i = 0; i < RX_RING_SIZE; i++ ) {
                    206:                rx_curr_desc = priv->rx_base + i;
                    207: 
                    208:                status = le16_to_cpu ( rx_curr_desc->status );
                    209: 
                    210:                /* Don't touch descriptors owned by the hardware */
                    211:                if ( status & DescOwn )
                    212:                        continue;
                    213: 
                    214:                /* Descriptors with iobufs still need to be processed */
                    215:                if ( priv->rx_iobuf[i] != NULL )
                    216:                        continue;
                    217: 
                    218:                /* If alloc_iob fails, try again later (next poll) */
                    219:                if ( ! ( priv->rx_iobuf[i] = alloc_iob ( PKT_BUF_SIZE ) ) ) {
                    220:                        DBG ( "Refill rx ring failed\n" );
                    221:                        break;
                    222:                }
                    223: 
                    224:                rx_curr_desc->base =
                    225:                        cpu_to_le32 ( virt_to_bus ( priv->rx_iobuf[i]->data ) );
                    226:                rx_curr_desc->buf_length = cpu_to_le16 ( -PKT_BUF_SIZE );
                    227:                rx_curr_desc->msg_length = rx_curr_desc->reserved = 0;
                    228: 
                    229:                /* Owner changes after the other status fields are set */
                    230:                wmb();
                    231:                rx_curr_desc->status = cpu_to_le16 ( DescOwn );
                    232:        }
                    233: 
                    234: }
                    235: 
                    236: /**
                    237:  * pcnet32_setup_rx_resources - allocate Rx resources (Descriptors)
                    238:  *
                    239:  * @v priv     Driver private structure
                    240:  *
                    241:  * @ret rc     Returns 0 on success, negative on failure
                    242:  */
                    243: static int
                    244: pcnet32_setup_rx_resources ( struct pcnet32_private *priv )
                    245: {
                    246:        DBGP ( "pcnet32_setup_rx_resources\n" );
                    247: 
                    248:        priv->rx_base = malloc_dma ( RX_RING_BYTES, RX_RING_ALIGN );
                    249: 
                    250:        DBG ( "priv->rx_base = %#08lx\n", virt_to_bus ( priv->rx_base ) );
                    251: 
                    252:        if ( ! priv->rx_base ) {
                    253:                return -ENOMEM;
                    254:        }
                    255: 
                    256:        memset ( priv->rx_base, 0, RX_RING_BYTES );
                    257: 
                    258:        pcnet32_refill_rx_ring ( priv );
                    259: 
                    260:        priv->rx_curr = 0;
                    261: 
                    262:        return 0;
                    263: }
                    264: 
                    265: static void
                    266: pcnet32_free_rx_resources ( struct pcnet32_private *priv )
                    267: {
                    268:        int i;
                    269: 
                    270:        DBGP ( "pcnet32_free_rx_resources\n" );
                    271: 
                    272:        free_dma ( priv->rx_base, RX_RING_BYTES );
                    273: 
                    274:        for ( i = 0; i < RX_RING_SIZE; i++ ) {
                    275:                free_iob ( priv->rx_iobuf[i] );
                    276:                priv->rx_iobuf[i] = NULL;
                    277:        }
                    278: }
                    279: 
                    280: /**
                    281:  * pcnet32_setup_tx_resources - allocate Tx resources (Descriptors)
                    282:  *
                    283:  * @v priv     Driver private structure
                    284:  *
                    285:  * @ret rc     Returns 0 on success, negative on failure
                    286:  */
                    287: static int
                    288: pcnet32_setup_tx_resources ( struct pcnet32_private *priv )
                    289: {
                    290:        DBGP ( "pcnet32_setup_tx_resources\n" );
                    291: 
                    292:        priv->tx_base = malloc_dma ( TX_RING_BYTES, TX_RING_ALIGN );
                    293: 
                    294:        if ( ! priv->tx_base ) {
                    295:                return -ENOMEM;
                    296:        }
                    297: 
                    298:        memset ( priv->tx_base, 0, TX_RING_BYTES );
                    299: 
                    300:        DBG ( "priv->tx_base = %#08lx\n", virt_to_bus ( priv->tx_base ) );
                    301: 
                    302:        priv->tx_curr = 0;
                    303:        priv->tx_fill_ctr = 0;
                    304:        priv->tx_tail = 0;
                    305: 
                    306:        return 0;
                    307: }
                    308: 
                    309: static void
                    310: pcnet32_free_tx_resources ( struct pcnet32_private *priv )
                    311: {
                    312:        DBGP ( "pcnet32_free_tx_resources\n" );
                    313: 
                    314:        free_dma ( priv->tx_base, TX_RING_BYTES );
                    315: }
                    316: 
                    317: static int
                    318: pcnet32_chip_detect ( struct pcnet32_private *priv )
                    319: {
                    320:        int fdx, mii, fset;
                    321:        int media;
                    322:        int rc;
                    323:        unsigned long ioaddr;
                    324:        struct pcnet32_access *a;
                    325:        int chip_version;
                    326:        char *chipname;
                    327: 
                    328:        ioaddr = priv->pci_dev->ioaddr;
                    329:        a = priv->a;
                    330: 
                    331:        chip_version = a->read_csr ( ioaddr, 88 )
                    332:                | ( a->read_csr ( ioaddr, 89 ) << 16 );
                    333: 
                    334:        rc = -ENODEV;
                    335: 
                    336:        DBG ( "PCnet chip version is 0x%X\n", chip_version );
                    337:        if ( ( chip_version & 0xfff ) != 0x003 )
                    338:                goto err_unsupported;
                    339: 
                    340:        fdx = mii = fset = 0;
                    341:        chip_version = ( chip_version >> 12 ) & 0xffff;
                    342: 
                    343:        switch (chip_version) {
                    344:        case 0x2420:
                    345:                chipname = "PCnet/PCI 79C970";
                    346:                break;
                    347:        case 0x2430:
                    348:                /* 970 gives the wrong chip id back */
                    349:                chipname = "PCnet/PCI 79C970";
                    350:                break;
                    351:        case 0x2621:
                    352:                chipname = "PCnet/PCI II 79C970A";
                    353:                fdx = 1;
                    354:                break;
                    355:        case 0x2623:
                    356:                chipname = "PCnet/FAST 79C971";
                    357:                fdx = 1;
                    358:                mii = 1;
                    359:                fset = 1;
                    360:                break;
                    361:        case 0x2624:
                    362:                chipname = "PCnet/FAST+ 79C972";
                    363:                fdx = 1;
                    364:                mii = 1;
                    365:                fset = 1;
                    366:                break;
                    367:        case 0x2625:
                    368:                chipname = "PCnet/FAST III 79C973";
                    369:                fdx = 1;
                    370:                mii = 1;
                    371:                break;
                    372:        case 0x2626:
                    373:                chipname = "PCnet/Home 79C978";
                    374:                fdx = 1;
                    375:                /*
                    376:                 * This is based on specs published at www.amd.com. This section
                    377:                 * assumes that a NIC with a 79C978 wants to go into 1Mb HomePNA
                    378:                 * mode. The 79C978 can also go into standard ethernet, and
                    379:                 * there probably should be some sort of module option to select
                    380:                 * the mode by which the card should operate
                    381:                 */
                    382:                /* switch to home wiring mode */
                    383:                media = a->read_bcr(ioaddr, 49);
                    384: 
                    385:                DBG ( "media reset to %#x.\n", media );
                    386:                a->write_bcr(ioaddr, 49, media);
                    387:                break;
                    388:        case 0x2627:
                    389:                chipname = "PCnet/FAST III 79C975";
                    390:                fdx = 1;
                    391:                mii = 1;
                    392:                break;
                    393:        case 0x2628:
                    394:                chipname = "PCnet/PRO 79C976";
                    395:                fdx = 1;
                    396:                mii = 1;
                    397:                break;
                    398:        default:
                    399:                chipname = "UNKNOWN";
                    400:                DBG ( "PCnet version %#x, no PCnet32 chip.\n", chip_version );
                    401:                goto err_unsupported;
                    402:        }
                    403: 
                    404:        DBG ( "PCnet chipname %s\n", chipname );
                    405: 
                    406:        /*
                    407:         * On selected chips turn on the BCR18:NOUFLO bit. This stops transmit
                    408:         * starting until the packet is loaded. Strike one for reliability, lose
                    409:         * one for latency - although on PCI this isnt a big loss. Older chips
                    410:         * have FIFO's smaller than a packet, so you can't do this.
                    411:         * Turn on BCR18:BurstRdEn and BCR18:BurstWrEn.
                    412:         */
                    413:        if (fset) {
                    414:                a->write_bcr ( ioaddr, 18,
                    415:                        ( a->read_bcr ( ioaddr, 18 ) | 0x0860 ) );
                    416:                a->write_csr ( ioaddr, 80,
                    417:                        ( a->read_csr ( ioaddr, 80 ) & 0x0C00) | 0x0C00 );
                    418:        }
                    419: 
                    420:        priv->full_duplex = fdx;
                    421:        priv->mii = mii;
                    422: 
                    423:        return 0;
                    424: 
                    425: err_unsupported:
                    426:        return rc;
                    427: }
                    428: 
                    429: /**
                    430:  * pcnet32_set_ops - Determines the ops used to access the registers
                    431:  *
                    432:  * @v priv     Driver private structure
                    433:  *
                    434:  * @ret rc     Returns 0 on success, negative on failure
                    435:  */
                    436: static int
                    437: pcnet32_set_ops ( struct pcnet32_private *priv )
                    438: {
                    439:        int rc;
                    440:        unsigned long ioaddr;
                    441: 
                    442:        ioaddr = priv->pci_dev->ioaddr;
                    443: 
                    444:        /* Check if CSR0 has its default value and perform a write / read
                    445:           in the RAP register to see if it works. Based on these results
                    446:           determine what mode the NIC is in (WIO / DWIO)
                    447:         */
                    448:        rc = -ENODEV;
                    449: 
                    450:        if ( pcnet32_wio_read_csr ( ioaddr, 0 ) == 4 &&
                    451:             pcnet32_wio_check ( ioaddr ) ) {
                    452:                priv->a = &pcnet32_wio;
                    453:        } else {
                    454:                pcnet32_dwio_reset ( ioaddr );
                    455:                if ( pcnet32_dwio_read_csr ( ioaddr, 0 ) == 4 &&
                    456:                     pcnet32_dwio_check ( ioaddr ) ) {
                    457:                        priv->a = &pcnet32_dwio;
                    458:                } else {
                    459:                        goto err_unsupported;
                    460:                }
                    461:        }
                    462: 
                    463:        return 0;
                    464: 
                    465: err_unsupported:
                    466:        return rc;
                    467: }
                    468: 
                    469: /**
                    470:  * pcnet32_setup_init_block - setup the NICs initialization block
                    471:  *
                    472:  * @v priv     Driver private structure
                    473:  *
                    474:  * @ret rc     Returns 0 on success, negative on failure
                    475:  */
                    476: static void
                    477: pcnet32_setup_init_block ( struct pcnet32_private *priv )
                    478: {
                    479:        int i;
                    480: 
                    481:        /* Configure the network port based on what we've established so far */
                    482:        priv->init_block.mode =
                    483:                cpu_to_le16 ( ( priv->options & PCNET32_PORT_PORTSEL ) << 7 );
                    484: 
                    485:        /* Setup RLEN and TLEN fields */
                    486:        priv->init_block.tlen_rlen =
                    487:                cpu_to_le16 ( ( PCNET32_LOG_RX_BUFFERS << 4 ) |
                    488:                              ( PCNET32_LOG_TX_BUFFERS << 12 ) );
                    489: 
                    490:        /* Fill in physical address */
                    491:        for ( i = 0; i < ETH_ALEN; i++)
                    492:                priv->init_block.phys_addr[i] = priv->netdev->hw_addr[i];
                    493: 
                    494:        /* No multicasting scheme, accept everything */
                    495:        priv->init_block.filter[0] = 0xffffffff;
                    496:        priv->init_block.filter[1] = 0xffffffff;
                    497: 
                    498:        priv->init_block.rx_ring =
                    499:                cpu_to_le32 ( virt_to_bus ( priv->rx_base ) );
                    500:        priv->init_block.tx_ring =
                    501:                cpu_to_le32 ( virt_to_bus ( priv->tx_base ) );
                    502: 
                    503:        /* Make sure all changes are visible */
                    504:        wmb();
                    505: }
                    506: 
                    507: /**
                    508:  * pcnet32_setup_probe_phy - go through all PHYs and see which one is present
                    509:  *
                    510:  * @v priv     Driver private structure
                    511:  */
                    512: static void
                    513: pcnet32_setup_probe_phy ( struct pcnet32_private *priv )
                    514: {
                    515:        unsigned long ioaddr = priv->pci_dev->ioaddr;
                    516:        unsigned int phycount = 0;
                    517:        int phy_id;
                    518:        int i;
                    519: 
                    520:        if ( priv->mii ) {
                    521:                phy_id = ( ( priv->a->read_bcr ( ioaddr, 33 ) ) >> 5 ) & 0x1f;
                    522:                for ( i = 0; i < PCNET32_MAX_PHYS; i++ ) {
                    523:                        unsigned short id1, id2;
                    524:                        id1 = pcnet32_mdio_read ( priv->netdev, i, MII_PHYSID1 );
                    525:                        if ( id1 == 0xffff )
                    526:                                continue;
                    527:                        id2 = pcnet32_mdio_read ( priv->netdev, i, MII_PHYSID2 );
                    528:                        if ( id2 == 0xffff )
                    529:                                continue;
                    530:                        if ( i == 31 && ( ( priv->chip_version + 1 ) & 0xfffe ) == 0x2624 )
                    531:                                continue;
                    532: 
                    533:                        phycount++;
                    534:                        phy_id = i;
                    535:                }
                    536:                priv->a->write_bcr ( ioaddr, 33, phy_id << 5 );
                    537:                if ( phycount > 1 )
                    538:                        priv->options |= PCNET32_PORT_MII;
                    539:        }
                    540: }
                    541: 
                    542: /**
                    543:  * pcnet32_setup_mac_addr - check for inconsistency between CSR12-14
                    544:  * and PROM addresses
                    545:  *
                    546:  * @v priv     Driver private structure
                    547:  */
                    548: static int
                    549: pcnet32_setup_mac_addr ( struct pcnet32_private *priv )
                    550: {
                    551:        int i;
                    552:        u8 promaddr[ETH_ALEN];
                    553:        unsigned long ioaddr = priv->pci_dev->ioaddr;
                    554: 
                    555:        /* In most chips, after a chip reset, the ethernet address is read from
                    556:         * the station address PROM at the base address and programmed into the
                    557:         * "Physical Address Registers" CSR12-14.
                    558:         * As a precautionary measure, we read the PROM values and complain if
                    559:         * they disagree with the CSRs.  If they miscompare, and the PROM addr
                    560:         * is valid, then the PROM addr is used.
                    561:         */
                    562:        for ( i = 0; i < 3; i++ ) {
                    563:                unsigned int val;
                    564:                val = priv->a->read_csr ( ioaddr, i + 12 ) & 0x0ffff;
                    565:                /* There may be endianness issues here. */
                    566:                priv->netdev->hw_addr[2 * i] = val & 0x0ff;
                    567:                priv->netdev->hw_addr[2 * i + 1] = ( val >> 8 ) & 0x0ff;
                    568:        }
                    569: 
                    570:        for ( i = 0; i < ETH_ALEN; i++ )
                    571:                promaddr[i] = inb ( ioaddr + i );
                    572: 
                    573:        if ( memcmp ( promaddr, priv->netdev->hw_addr, ETH_ALEN ) ||
                    574:             ! is_valid_ether_addr ( priv->netdev->hw_addr ) ) {
                    575:                if ( is_valid_ether_addr ( promaddr ) ) {
                    576:                        DBG ( "CSR address is invalid, using PROM addr\n" );
                    577:                        memcpy ( priv->netdev->hw_addr, promaddr, ETH_ALEN );
                    578:                }
                    579:        }
                    580: 
                    581:        /* If ethernet address is not valid, return error */
                    582:        if ( ! is_valid_ether_addr ( priv->netdev->hw_addr ) )
                    583:                return -EADDRNOTAVAIL;
                    584: 
                    585:        return 0;
                    586: }
                    587: 
                    588: /**
                    589:  * pcnet32_setup_if_duplex - Sets the NICs used interface and duplex mode
                    590:  *
                    591:  * @v priv     Driver private structure
                    592:  */
                    593: static void
                    594: pcnet32_setup_if_duplex ( struct pcnet32_private *priv )
                    595: {
                    596:        unsigned long ioaddr = priv->pci_dev->ioaddr;
                    597:        u16 val;
                    598: 
                    599:        /* Set/Reset autoselect bit */
                    600:        val = priv->a->read_bcr ( ioaddr, 2 ) & ~2;
                    601:        if ( priv->options & PCNET32_PORT_ASEL )
                    602:                val |= 2;
                    603:        priv->a->write_bcr ( ioaddr, 2, val );
                    604: 
                    605:        /* Handle full duplex setting */
                    606:        if ( priv->full_duplex ) {
                    607:                val = priv->a->read_bcr ( ioaddr, 9 ) & ~3;
                    608:                if ( priv->options & PCNET32_PORT_FD ) {
                    609:                        val |= 1;
                    610:                        if ( priv->options == ( PCNET32_PORT_FD | PCNET32_PORT_AUI ) )
                    611:                                val |= 2;
                    612:                } else if ( priv->options & PCNET32_PORT_ASEL ) {
                    613:                        /* Workaround of xSeries 250, on for 79C975 only */
                    614:                        if ( priv->chip_version == 0x2627 )
                    615:                                val |= 3;
                    616:                }
                    617:                priv->a->write_bcr ( ioaddr, 9, val );
                    618:        }
                    619: 
                    620:        /* Set/Reset GPSI bit in test register */
                    621:        val = priv->a->read_csr ( ioaddr, 124 ) & ~0x10;
                    622:        if ( ( priv->options & PCNET32_PORT_PORTSEL ) == PCNET32_PORT_GPSI )
                    623:                val |= 0x10;
                    624:        priv->a->write_bcr ( ioaddr, 124, val );
                    625: 
                    626:        /* Allied Telesyn AT are 100Mbit only and do not negotiate */
                    627:        u16 subsys_vend_id, subsys_dev_id;
                    628:        pci_read_config_word ( priv->pci_dev,
                    629:                               PCI_SUBSYSTEM_VENDOR_ID,
                    630:                               &subsys_vend_id );
                    631:        pci_read_config_word ( priv->pci_dev,
                    632:                               PCI_SUBSYSTEM_ID,
                    633:                               &subsys_dev_id );
                    634:        if ( subsys_vend_id == PCI_VENDOR_ID_AT &&
                    635:             ( ( subsys_dev_id == PCI_SUBDEVICE_ID_AT_2700FX ) ||
                    636:               ( subsys_dev_id == PCI_SUBDEVICE_ID_AT_2701FX ) ) ) {
                    637:                priv->options = PCNET32_PORT_FD | PCNET32_PORT_100;
                    638:        }
                    639: 
                    640:        if ( priv->mii && ! ( priv->options & PCNET32_PORT_ASEL ) ) {
                    641:                /* Disable Auto Negotiation, set 10Mbps, HD */
                    642:                val = priv->a->read_bcr ( ioaddr, 32 ) & ~0x38;
                    643:                if ( priv->options & PCNET32_PORT_FD )
                    644:                        val |= 0x10;
                    645:                if ( priv->options & PCNET32_PORT_100 )
                    646:                        val |= 0x08;
                    647:                priv->a->write_bcr ( ioaddr, 32, val );
                    648:        } else if ( priv->options & PCNET32_PORT_ASEL ) {
                    649:                /* 79C970 chips do not have the BCR32 register */
                    650:                if ( ( priv->chip_version != 0x2420 ) &&
                    651:                     ( priv->chip_version != 0x2621 ) ) {
                    652:                        /* Enable Auto Negotiation, setup, disable FD */
                    653:                        val = priv->a->read_bcr ( ioaddr, 32 ) & ~0x98;
                    654:                        val |= 0x20;
                    655:                        priv->a->write_bcr ( ioaddr, 32, val );
                    656:                }
                    657:        }
                    658: }
                    659: 
                    660: /**
                    661:  * pcnet32_hw_start - Starts up the NIC
                    662:  *
                    663:  * @v priv     Driver private structure
                    664:  */
                    665: static void
                    666: pcnet32_hw_start ( struct pcnet32_private *priv )
                    667: {
                    668:        unsigned long ioaddr = priv->pci_dev->ioaddr;
                    669:        int i;
                    670: 
                    671:        /* Begin initialization procedure */
                    672:        priv->a->write_csr ( ioaddr, 0, Init );
                    673: 
                    674:        /* Wait for the initialization to be done */
                    675:        i = 0;
                    676:        while ( i++ < 100 )
                    677:                if ( priv->a->read_csr ( ioaddr, 0 ) & InitDone )
                    678:                        break;
                    679: 
                    680:        /* Start the chip */
                    681:        priv->a->write_csr ( ioaddr, 0, Strt );
                    682: }
                    683: 
                    684: /**
                    685:  * open - Called when a network interface is made active
                    686:  *
                    687:  * @v netdev   Network device
                    688:  * @ret rc     Return status code, 0 on success, negative value on failure
                    689:  **/
                    690: static int
                    691: pcnet32_open ( struct net_device *netdev )
                    692: {
                    693:        struct pcnet32_private *priv = netdev_priv ( netdev );
                    694:        unsigned long ioaddr = priv->pci_dev->ioaddr;
                    695:        int rc;
                    696:        u16 val;
                    697: 
                    698:        /* Setup TX and RX descriptors */
                    699:        if ( ( rc = pcnet32_setup_tx_resources ( priv ) ) != 0 ) {
                    700:                DBG ( "Error setting up TX resources\n" );
                    701:                goto err_setup_tx;
                    702:        }
                    703: 
                    704:        if ( ( rc = pcnet32_setup_rx_resources ( priv ) ) != 0 ) {
                    705:                DBG ( "Error setting up RX resources\n" );
                    706:                goto err_setup_rx;
                    707:        }
                    708: 
                    709:        /* Reset the chip */
                    710:        priv->a->reset ( ioaddr );
                    711: 
                    712:        /* Switch pcnet32 to 32bit mode */
                    713:        priv->a->write_bcr ( ioaddr, 20, PCNET32_SWSTYLE_PCNET32 );
                    714: 
                    715:        /* Setup the interface and duplex mode */
                    716:        pcnet32_setup_if_duplex ( priv );
                    717: 
                    718:        /* Disable interrupts */
                    719:        val = priv->a->read_csr ( ioaddr, 3 );
                    720:        val |= BablMask | MissFrameMask | RxIntMask | TxIntMask | InitDoneMask;
                    721:        priv->a->write_csr ( ioaddr, 3, val );
                    722: 
                    723:        /* Setup initialization block */
                    724:        pcnet32_setup_init_block ( priv );
                    725: 
                    726:        /* Fill in the address of the initialization block */
                    727:        priv->a->write_csr ( ioaddr, 1,
                    728:                ( virt_to_bus ( &priv->init_block ) ) & 0xffff );
                    729:        priv->a->write_csr ( ioaddr, 2,
                    730:                ( virt_to_bus ( &priv->init_block ) ) >> 16 );
                    731: 
                    732:        /* Enable Auto-Pad, disable interrupts */
                    733:        priv->a->write_csr ( ioaddr, 4, 0x0915 );
                    734: 
                    735:        pcnet32_hw_start ( priv );
                    736: 
                    737:        return 0;
                    738: 
                    739: err_setup_rx:
                    740:        pcnet32_free_tx_resources ( priv );
                    741: err_setup_tx:
                    742:        priv->a->reset( priv->pci_dev->ioaddr );
                    743:        return rc;
                    744: }
                    745: 
                    746: /**
                    747:  * transmit - Transmit a packet
                    748:  *
                    749:  * @v netdev   Network device
                    750:  * @v iobuf    I/O buffer
                    751:  *
                    752:  * @ret rc     Returns 0 on success, negative on failure
                    753:  */
                    754: static int
                    755: pcnet32_transmit ( struct net_device *netdev, struct io_buffer *iobuf )
                    756: {
                    757:        struct pcnet32_private *priv = netdev_priv ( netdev );
                    758:        unsigned long ioaddr = priv->pci_dev->ioaddr;
                    759:        uint32_t tx_len = iob_len ( iobuf );
                    760:        struct pcnet32_tx_desc *tx_curr_desc;
                    761: 
                    762:        DBGP ( "pcnet32_transmit\n" );
                    763: 
                    764:        if ( priv->tx_fill_ctr == TX_RING_SIZE ) {
                    765:                DBG ( "Tx overflow\n" );
                    766:                return -ENOTSUP;
                    767:        }
                    768: 
                    769:        priv->tx_iobuf[priv->tx_curr] = iobuf;
                    770: 
                    771:        tx_curr_desc = priv->tx_base + priv->tx_curr;
                    772: 
                    773:        /* Configure current descriptor to transmit packet */
                    774:        tx_curr_desc->length = cpu_to_le16 ( -tx_len );
                    775:        tx_curr_desc->misc = 0x00000000;
                    776:        tx_curr_desc->base = cpu_to_le32 ( virt_to_bus ( iobuf->data ) );
                    777: 
                    778:        /* Owner changes after the other status fields are set */
                    779:        wmb();
                    780:        tx_curr_desc->status =
                    781:                cpu_to_le16 ( DescOwn | StartOfPacket | EndOfPacket );
                    782: 
                    783:        /* Trigger an immediate send poll */
                    784:        priv->a->write_csr ( ioaddr, 0,
                    785:                ( priv->irq_enabled ? IntEnable : 0 ) | TxDemand );
                    786: 
                    787:        /* Point to the next free descriptor */
                    788:        priv->tx_curr = ( priv->tx_curr + 1 ) % TX_RING_SIZE;
                    789: 
                    790:        /* Increment number of tx descriptors in use */
                    791:        priv->tx_fill_ctr++;
                    792: 
                    793:        return 0;
                    794: }
                    795: 
                    796: /**
                    797:  * pcnet32_process_tx_packets - Checks for successfully sent packets,
                    798:  * reports them to iPXE with netdev_tx_complete()
                    799:  *
                    800:  * @v netdev   Network device
                    801:  */
                    802: static void
                    803: pcnet32_process_tx_packets ( struct net_device *netdev )
                    804: {
                    805:        struct pcnet32_private *priv = netdev_priv ( netdev );
                    806:        struct pcnet32_tx_desc *tx_curr_desc;
                    807: 
                    808:        DBGP ( "pcnet32_process_tx_packets\n" );
                    809: 
                    810:        while ( priv->tx_tail != priv->tx_curr ) {
                    811:                tx_curr_desc = priv->tx_base + priv->tx_tail;
                    812: 
                    813:                u16 status = le16_to_cpu ( tx_curr_desc->status );
                    814: 
                    815:                DBG ( "Before OWN bit check, status: %#08x\n", status );
                    816: 
                    817:                /* Skip this descriptor if hardware still owns it */
                    818:                if ( status & DescOwn )
                    819:                        break;
                    820: 
                    821:                DBG ( "Transmitted packet.\n" );
                    822:                DBG ( "priv->tx_fill_ctr= %d\n", priv->tx_fill_ctr );
                    823:                DBG ( "priv->tx_tail    = %d\n", priv->tx_tail );
                    824:                DBG ( "priv->tx_curr    = %d\n", priv->tx_curr );
                    825:                DBG ( "tx_curr_desc     = %#08lx\n", virt_to_bus ( tx_curr_desc ) );
                    826: 
                    827:                /* This packet is ready for completion */
                    828:                netdev_tx_complete ( netdev, priv->tx_iobuf[priv->tx_tail]);
                    829: 
                    830:                /* Clear the descriptor */
                    831:                memset ( tx_curr_desc, 0, sizeof(*tx_curr_desc) );
                    832: 
                    833:                /* Reduce the number of tx descriptors in use */
                    834:                priv->tx_fill_ctr--;
                    835: 
                    836:                /* Go to next available descriptor */
                    837:                priv->tx_tail = ( priv->tx_tail + 1 ) % TX_RING_SIZE;
                    838:        }
                    839: }
                    840: 
                    841: /**
                    842:  * pcnet32_process_rx_packets - Checks for received packets, reports them
                    843:  * to iPXE with netdev_rx() or netdev_rx_err() if there was an error receiving
                    844:  * the packet
                    845:  *
                    846:  * @v netdev   Network device
                    847:  */
                    848: static void
                    849: pcnet32_process_rx_packets ( struct net_device *netdev )
                    850: {
                    851:        struct pcnet32_private *priv = netdev_priv ( netdev );
                    852:        struct pcnet32_rx_desc *rx_curr_desc;
                    853:        u16 status;
                    854:        u32 len;
                    855:        int i;
                    856: 
                    857:        DBGP ( "pcnet32_process_rx_packets\n" );
                    858: 
                    859:        for ( i = 0; i < RX_RING_SIZE; i++ ) {
                    860:                rx_curr_desc = priv->rx_base + priv->rx_curr;
                    861: 
                    862:                status = le16_to_cpu ( rx_curr_desc->status );
                    863:                rmb();
                    864: 
                    865:                DBG ( "Before OWN bit check, status: %#08x\n", status );
                    866: 
                    867:                /* Skip this descriptor if hardware still owns it */
                    868:                if ( status & DescOwn )
                    869:                        break;
                    870: 
                    871:                /* We own the descriptor, but it has not been refilled yet */
                    872:                if ( priv->rx_iobuf[priv->rx_curr] == NULL )
                    873:                        break;
                    874: 
                    875:                DBG ( "Received packet.\n" );
                    876:                DBG ( "priv->rx_curr    = %d\n", priv->rx_curr );
                    877:                DBG ( "rx_len           = %d\n",
                    878:                      ( le32_to_cpu ( rx_curr_desc->msg_length ) & 0xfff ) - 4 );
                    879:                DBG ( "rx_curr_desc     = %#08lx\n",
                    880:                      virt_to_bus ( rx_curr_desc ) );
                    881: 
                    882:                /* Check ERR bit */
                    883:                if ( status & 0x4000 ) {
                    884:                        netdev_rx_err ( netdev, priv->rx_iobuf[priv->rx_curr],
                    885:                                        -EINVAL );
                    886:                        DBG ( "Corrupted packet received!\n");
                    887:                } else {
                    888:                        /* Adjust size of the iobuf to reflect received data */
                    889:                        len = ( le32_to_cpu ( rx_curr_desc->msg_length ) & 0xfff ) - 4;
                    890:                        iob_put ( priv->rx_iobuf[priv->rx_curr], len );
                    891: 
                    892:                        /* Add this packet to the receive queue */
                    893:                        netdev_rx ( netdev, priv->rx_iobuf[priv->rx_curr] );
                    894:                }
                    895: 
                    896:                /* Invalidate iobuf and descriptor */
                    897:                priv->rx_iobuf[priv->rx_curr] = NULL;
                    898:                memset ( rx_curr_desc, 0, sizeof(*rx_curr_desc) );
                    899: 
                    900:                /* Point to the next free descriptor */
                    901:                priv->rx_curr = ( priv->rx_curr + 1 ) % RX_RING_SIZE;
                    902:        }
                    903: 
                    904:        /* Allocate new iobufs where needed */
                    905:        pcnet32_refill_rx_ring ( priv );
                    906: }
                    907: 
                    908: /**
                    909:  * poll - Poll for received packets
                    910:  *
                    911:  * @v netdev   Network device
                    912:  */
                    913: static void
                    914: pcnet32_poll ( struct net_device *netdev )
                    915: {
                    916:        struct pcnet32_private *priv = netdev_priv ( netdev );
                    917:        unsigned long ioaddr = priv->pci_dev->ioaddr;
                    918:        u16 status;
                    919: 
                    920:        DBGP ( "pcnet32_poll\n" );
                    921: 
                    922:        status = priv->a->read_csr ( ioaddr, 0 );
                    923: 
                    924:        /* Clear interrupts */
                    925:        priv->a->write_csr ( ioaddr, 0, status );
                    926: 
                    927:        DBG ( "pcnet32_poll: mask = %#04x, status = %#04x\n",
                    928:                priv->a->read_csr ( ioaddr, 3 ), status );
                    929: 
                    930:        /* Return when RINT or TINT are not set */
                    931:        if ( ( status & 0x0500 ) == 0x0000 )
                    932:                return;
                    933: 
                    934:        /* Process transmitted packets */
                    935:        pcnet32_process_tx_packets ( netdev );
                    936: 
                    937:        /* Process received packets */
                    938:        pcnet32_process_rx_packets ( netdev );
                    939: }
                    940: 
                    941: /**
                    942:  * close - Disable network interface
                    943:  *
                    944:  * @v netdev   network interface device structure
                    945:  **/
                    946: static void
                    947: pcnet32_close ( struct net_device *netdev )
                    948: {
                    949:        struct pcnet32_private *priv = netdev_priv ( netdev );
                    950:        unsigned long ioaddr = priv->pci_dev->ioaddr;
                    951: 
                    952:        DBGP ( "pcnet32_close\n" );
                    953: 
                    954:        /* Reset the chip */
                    955:        pcnet32_wio_reset ( ioaddr );
                    956: 
                    957:        /* Stop the PCNET32 - it occasionally polls memory if we don't */
                    958:        priv->a->write_csr ( ioaddr, 0, Stop );
                    959: 
                    960:        /* Switch back to 16bit mode to avoid problems with dumb
                    961:         * DOS packet driver after a warm reboot */
                    962:        priv->a->write_bcr ( ioaddr, 20, PCNET32_SWSTYLE_LANCE );
                    963: 
                    964:        pcnet32_free_rx_resources ( priv );
                    965:        pcnet32_free_tx_resources ( priv );
                    966: }
                    967: 
                    968: static void pcnet32_irq_enable ( struct pcnet32_private *priv )
                    969: {
                    970:        unsigned long ioaddr = priv->pci_dev->ioaddr;
                    971:        u16 val;
                    972: 
                    973:        DBGP ( "pcnet32_irq_enable\n" );
                    974: 
                    975:        /* Enable TINT and RINT masks */
                    976:        val = priv->a->read_csr ( ioaddr, 3 );
                    977:        val &= ~( RxIntMask | TxIntMask );
                    978:        priv->a->write_csr ( ioaddr, 3, val );
                    979: 
                    980:        /* Enable interrupts */
                    981:        priv->a->write_csr ( ioaddr, 0, IntEnable );
                    982: 
                    983:        priv->irq_enabled = 1;
                    984: }
                    985: 
                    986: static void pcnet32_irq_disable ( struct pcnet32_private *priv )
                    987: {
                    988:        unsigned long ioaddr = priv->pci_dev->ioaddr;
                    989: 
                    990:        DBGP ( "pcnet32_irq_disable\n" );
                    991: 
                    992:        priv->a->write_csr ( ioaddr, 0, 0x0000 );
                    993: 
                    994:        priv->irq_enabled = 0;
                    995: }
                    996: 
                    997: /**
                    998:  * irq - enable or disable interrupts
                    999:  *
                   1000:  * @v netdev    network adapter
                   1001:  * @v action    requested interrupt action
                   1002:  **/
                   1003: static void
                   1004: pcnet32_irq ( struct net_device *netdev, int action )
                   1005: {
                   1006:        struct pcnet32_private *priv = netdev_priv ( netdev );
                   1007: 
                   1008:        DBGP ( "pcnet32_irq\n" );
                   1009: 
                   1010:        switch ( action ) {
                   1011:        case 0:
                   1012:                pcnet32_irq_disable ( priv );
                   1013:                break;
                   1014:        default:
                   1015:                pcnet32_irq_enable ( priv );
                   1016:                break;
                   1017:        }
                   1018: }
                   1019: 
                   1020: static struct net_device_operations pcnet32_operations = {
                   1021:        .open           = pcnet32_open,
                   1022:        .transmit       = pcnet32_transmit,
                   1023:        .poll           = pcnet32_poll,
                   1024:        .close          = pcnet32_close,
                   1025:        .irq            = pcnet32_irq,
                   1026: };
                   1027: 
                   1028: /**
                   1029:  * probe - Initial configuration of NIC
                   1030:  *
                   1031:  * @v pdev     PCI device
                   1032:  * @v ent      PCI IDs
                   1033:  *
                   1034:  * @ret rc     Return status code
                   1035:  **/
                   1036: static int
                   1037: pcnet32_probe ( struct pci_device *pdev )
                   1038: {
                   1039:        struct net_device *netdev;
                   1040:        struct pcnet32_private *priv;
                   1041:        unsigned long ioaddr;
                   1042:        int rc;
                   1043: 
                   1044:        DBGP ( "pcnet32_probe\n" );
                   1045: 
                   1046:        DBG ( "Found %s, vendor = %#04x, device = %#04x\n",
                   1047:                pdev->id->name, pdev->id->vendor, pdev->id->device );
                   1048: 
                   1049:        /* Allocate our private data */
                   1050:        netdev = alloc_etherdev ( sizeof ( *priv ) );
                   1051:        if ( ! netdev ) {
                   1052:                rc = -ENOMEM;
                   1053:                goto err_alloc_etherdev;
                   1054:        }
                   1055: 
                   1056:        /* Link our operations to the netdev struct */
                   1057:        netdev_init ( netdev, &pcnet32_operations );
                   1058: 
                   1059:        /* Link the PCI device to the netdev struct */
                   1060:        pci_set_drvdata ( pdev, netdev );
                   1061:        netdev->dev = &pdev->dev;
                   1062: 
                   1063:        /* Get a reference to our private data */
                   1064:        priv = netdev_priv ( netdev );
                   1065: 
                   1066:        /* We'll need these set up for the rest of the routines */
                   1067:        priv->pci_dev = pdev;
                   1068:        priv->netdev = netdev;
                   1069: 
                   1070:        ioaddr = pdev->ioaddr;
                   1071: 
                   1072:        /* Only use irqs under UNDI */
                   1073:        priv->irq_enabled = 0;
                   1074: 
                   1075:        /* Reset the chip */
                   1076:        pcnet32_wio_reset ( ioaddr );
                   1077: 
                   1078:        if ( ( rc = pcnet32_set_ops ( priv ) ) != 0 ) {
                   1079:                DBG ( "Setting driver operations failed\n");
                   1080:                goto err_set_ops;
                   1081:        }
                   1082: 
                   1083:        if ( ( rc = pcnet32_chip_detect ( priv ) ) != 0 ) {
                   1084:                DBG ( "pcnet32_chip_detect failed\n" );
                   1085:                goto err_chip_detect;
                   1086:        }
                   1087: 
                   1088:        /* Enter bus mastering mode */
                   1089:        adjust_pci_device ( pdev );
                   1090: 
                   1091:        /* Verify and get MAC address */
                   1092:        if ( ( rc = pcnet32_setup_mac_addr ( priv ) ) != 0 ) {
                   1093:                DBG ( "Setting MAC address failed\n" );
                   1094:                goto err_mac_addr;
                   1095:        }
                   1096: 
                   1097:        DBG ( "IO Addr 0x%lX, MAC Addr %s\n", ioaddr,
                   1098:                eth_ntoa ( netdev->hw_addr ) );
                   1099: 
                   1100:        priv->options = PCNET32_PORT_ASEL;
                   1101: 
                   1102:        /* Detect special T1/E1 WAN card by checking for MAC address */
                   1103:        if ( netdev->hw_addr[0] == 0x00 &&
                   1104:             netdev->hw_addr[1] == 0xE0 &&
                   1105:             netdev->hw_addr[2] == 0x75 )
                   1106:                priv->options = PCNET32_PORT_FD | PCNET32_PORT_GPSI;
                   1107: 
                   1108:        /* Probe the PHY so we can check link state and speed */
                   1109:        pcnet32_setup_probe_phy ( priv );
                   1110: 
                   1111:        if ( ( rc = register_netdev ( netdev ) ) != 0 ) {
                   1112:                DBG ( "Error registering netdev\n" );
                   1113:                goto err_register;
                   1114:        }
                   1115: 
                   1116:        netdev_link_up ( netdev );
                   1117: 
                   1118:        return 0;
                   1119: 
                   1120: err_register:
                   1121:        netdev_put ( netdev );
                   1122: err_chip_detect:
                   1123: err_set_ops:
                   1124: err_alloc_etherdev:
                   1125: err_mac_addr:
                   1126:        return rc;
                   1127: }
                   1128: 
                   1129: /**
                   1130:  * remove - Device Removal Routine
                   1131:  *
                   1132:  * @v pdev PCI device information struct
                   1133:  **/
                   1134: static void
                   1135: pcnet32_remove ( struct pci_device *pdev )
                   1136: {
                   1137:        struct net_device *netdev = pci_get_drvdata ( pdev );
                   1138:        unsigned long ioaddr = pdev->ioaddr;
                   1139: 
                   1140:        DBGP ( "pcnet32_remove\n" );
                   1141: 
                   1142:        /* Reset the chip */
                   1143:        pcnet32_wio_reset ( ioaddr );
                   1144: 
                   1145:        unregister_netdev ( netdev );
                   1146:        netdev_nullify ( netdev );
                   1147:        netdev_put ( netdev );
                   1148: }
                   1149: 
                   1150: static struct pci_device_id pcnet32_nics[] = {
                   1151:        PCI_ROM(0x1022, 0x2000, "pcnet32", "AMD PCnet/PCI", 0),
                   1152:        PCI_ROM(0x1022, 0x2625, "pcnetfastiii", "AMD PCNet FAST III", 0),
                   1153:        PCI_ROM(0x1022, 0x2001, "amdhomepna", "AMD PCnet/HomePNA", 0),
                   1154: };
                   1155: 
                   1156: struct pci_driver pcnet32_driver __pci_driver = {
                   1157:        .ids            = pcnet32_nics,
                   1158:        .id_count       = ARRAY_SIZE ( pcnet32_nics ),
                   1159:        .probe          = pcnet32_probe,
                   1160:        .remove         = pcnet32_remove,
                   1161: };

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.