if_i21143.c

来自「eCos操作系统源码」· C语言 代码 · 共 1,953 行 · 第 1/5 页

C
1,953
字号
            diag_printf( "pci_init_find_21143s failed" );#endif            return 0;        }    }    // If this device is not present, exit    if (0 == p_i21143->found)        return 0;    p_i21143->mac_addr_ok = 0;    if ( p_i21143->hardwired_esa )        eth_set_mac_address( p_i21143, NULL ); // use that already there                                        // (actually a NOP because !active)    else {        int ee_addrbits;        int val[3];        int good = 0;        ee_addrbits = get_eeprom_size( p_i21143->io_address );#ifdef DEBUG_EE        diag_printf( "EEPROM size = %d\n", ee_addrbits );#endif        if ( 6 == ee_addrbits || 8 == ee_addrbits ) {            int i;            for ( i = 0; i < 3; i++ ) {                val[i] = read_eeprom_word( p_i21143->io_address,                                           ee_addrbits,                                           i );#ifdef DEBUG_EE                diag_printf( "EEPROM: word at %04x = %04x\n", i, val[i] );#endif            }            if ( 0x0000 != (val[0] | val[1] | val[2] ) && // some nonzero bits                 0xffff != (val[0] & val[1] & val[2] ) && // not all ones                 0x0000 == (val[0] & 0x80) ) {            // not multicast                mac_address[0] = val[0] & 0xff;                mac_address[1] = val[0] >> 8;                mac_address[2] = val[1] & 0xff;                mac_address[3] = val[1] >> 8;                mac_address[4] = val[2] & 0xff;                mac_address[5] = val[2] >> 8;                good = 1;#ifdef DEBUG_MAC                diag_printf( "EEPROM ESA OK: %04x %04x %04x\n",                             val[0], val[1], val[2] );#endif            }        }                        if ( !good ) {            // Invent one            mac_address[0] = 0x01;            mac_address[1] = 0x23;            mac_address[2] = 0x45;            mac_address[3] = 0x67;            mac_address[4] = 0x98;            mac_address[5] = 0x76;        }        // Just copy into the structure - not into hardware 'cos !active        eth_set_mac_address( p_i21143, &mac_address[0] );    }#if defined( DEBUG ) || defined( DEBUG_MAC )    diag_printf("MAC Address %s, ESA = %02X %02X %02X %02X %02X %02X\n",                p_i21143->mac_addr_ok ? "OK" : "**BAD**",                 p_i21143->mac_address[0],                p_i21143->mac_address[1],                p_i21143->mac_address[2],                p_i21143->mac_address[3],                p_i21143->mac_address[4],                p_i21143->mac_address[5]);#endif    // Initialize upper level driver    if ( p_i21143->mac_addr_ok )        (sc->funs->eth_drv->init)(sc, &(p_i21143->mac_address[0]) );    else        (sc->funs->eth_drv->init)(sc, NULL );    return (1);}// ------------------------------------------------------------------------////  Function : i21143_start//// ------------------------------------------------------------------------static void i21143_start( struct eth_drv_sc *sc, unsigned char *enaddr, int flags ){    struct i21143 *p_i21143;    cyg_uint32 ioaddr;    cyg_uint32 l;#ifdef CYGPKG_NET    struct ifnet *ifp = &sc->sc_arpcom.ac_if;#endif    p_i21143 = (struct i21143 *)sc->driver_private;    ioaddr = p_i21143->io_address; // get 21143's I/O address        IF_BAD_21143( p_i21143 ) {#ifdef DEBUG        diag_printf( "i21143_start: Bad device pointer %x\n", p_i21143 );#endif        return;    }    if ( ! p_i21143->mac_addr_ok ) {#ifdef DEBUG        diag_printf("i21143_start %d: invalid MAC address, "                  "can't bring up interface\n",                  p_i21143->index );#endif        return;    }#ifdef DEBUG    diag_printf( "i21143_start: enters\n" );#endif    if ( p_i21143->active )        i21143_stop( sc );    // Update the cached copy of the status reg just in case    l = i21143_status( p_i21143 );    if ( l != p_i21143->line_status ) {        // It has changed!        i21143_reset(p_i21143);             // sets line_status itself    }    // Enable device    p_i21143->active = 1;    // Initialize tx status    p_i21143->tx_endbuf = NO_TX_IN_PROGRESS;    eth_set_mac_address( p_i21143, NULL ); // to put it in the device    // After eth_set_mac_address() initialize the data structs for use:    InitRxRing( p_i21143 );    InitTxRing( p_i21143 );    // Enable promiscuous mode if requested.    i21143_configure(p_i21143, 0#ifdef CYGPKG_NET                     || !!(ifp->if_flags & IFF_PROMISC)#endif#ifdef ETH_DRV_FLAGS_PROMISC_MODE                     || !!(flags & ETH_DRV_FLAGS_PROMISC_MODE)#endif                     );#ifdef DEBUG    {        int status = p_i21143->line_status;        diag_printf("i21143_start %d flg %x Link = %s, %s Mbps, %s Duplex\n",                    p_i21143->index,                    *(int *)p_i21143,                    (GEN_STATUS_LINK    & status) ?   "Up" : "Down",                    (GEN_STATUS_100MBPS & status) ?  "100" : "10",                    (GEN_STATUS_FDX     & status) ? "Full" : "Half");    }#endif    // Load pointer to Rx Ring and enable receiver    OUTL( CYGHWR_PCI_VIRT_TO_BUS( (cyg_uint32)p_i21143->rx_ring ), CSR_RXBASE );    // Enable receive interrupts    l = INL( CSR_INTR_ENABLE );    l |= 0     | CSR_STATUS_NIS           | CSR_STATUS_AIS           // CSR_STATUS_ERI           // CSR_STATUS_FBE           // CSR_STATUS_LNF           // CSR_STATUS_GTE           // CSR_STATUS_ETI           // CSR_STATUS_RWT           | CSR_STATUS_RX_STOPPED     | CSR_STATUS_RBU           | CSR_STATUS_RX_INTR       // CSR_STATUS_UNF           // CSR_STATUS_LNP_ANC       // CSR_STATUS_TJT           | CSR_STATUS_TBU           | CSR_STATUS_TX_STOPPED     | CSR_STATUS_TX_INTR          ;    OUTL( l, CSR_INTR_ENABLE );    // and start the receiver    l = INL( CSR_OPMODE );    l |= (CSR_OPMODE_RX_START);    OUTL( l, CSR_OPMODE );    INCR_STAT( rx_restart );#ifdef DEBUG_DUMP_REGS    debug_dump_regs( ioaddr, BOTH );#endif}// ------------------------------------------------------------------------////  Function : i21143_status//// ------------------------------------------------------------------------inti21143_status( struct i21143* p_i21143 ){    int status;    int i, j;    cyg_uint32 ioaddr;        IF_BAD_21143( p_i21143 ) {#ifdef DEBUG        diag_printf( "i21143_status: Bad device pointer %x\n", p_i21143 );#endif        return 0;    }    ioaddr = p_i21143->io_address; // get 21143's I/O address    // Some of these bits latch and only reflect "the truth" on a 2nd reading.    // So read and discard.    status = mii_read_register( ioaddr, PHY_CONTROL_REG );    status = mii_read_register( ioaddr, PHY_STATUS_REG  );    // Use the "and" of the local and remote capabilities words to infer    // what is selected:    status = 0;    i = mii_read_register( ioaddr, PHY_STATUS_REG );    if ( PHY_STATUS_LINK_OK & i )        status |= GEN_STATUS_LINK;    i = mii_read_register( ioaddr, PHY_AUTONEG_ADVERT );    j = mii_read_register( ioaddr, PHY_AUTONEG_REMOTE );    p_i21143->phy_autoneg_remote = j;#if defined( DEBUG_TRAFFIC ) || defined( DEBUG_IOCTL )    diag_printf( "MII: capabilities are %04x, %04x; common %04x\n",               i, j, i & j );#endif    j &= i; // select only common capabilities    if ( (PHY_AUTONEG_100BASET4 |          PHY_AUTONEG_100BASETX_FDX |          PHY_AUTONEG_100BASETX_HDX)  & j )        status |= GEN_STATUS_100MBPS;    if ( (PHY_AUTONEG_100BASETX_FDX | PHY_AUTONEG_10BASET_FDX) & j )        status |= GEN_STATUS_FDX;    return status;}inti21143_status_changed( struct i21143* p_i21143 ){    cyg_uint32 ioaddr;    int j;    ioaddr = p_i21143->io_address; // get 21143's I/O address    j = mii_read_register( ioaddr, PHY_AUTONEG_REMOTE );    return ( j != p_i21143->phy_autoneg_remote );}// ------------------------------------------------------------------------////  Function : i21143_stop//// ------------------------------------------------------------------------static voidi21143_stop( struct eth_drv_sc *sc ){    struct i21143 *p_i21143;    p_i21143 = (struct i21143 *)sc->driver_private;    IF_BAD_21143( p_i21143 ) {#ifdef DEBUG        diag_printf( "i21143_stop: Bad device pointer %x\n", p_i21143 );#endif        return;    }   #ifdef DEBUG_STARTSTOPRESET    diag_printf("i21143_stop %d flg %x\n", p_i21143->index, *(int *)p_i21143 );#endif    p_i21143->active = 0;               // stop people tormenting it    if ( NO_TX_IN_PROGRESS != p_i21143->tx_endbuf) {        cyg_uint32 key;                CYG_ASSERT( TX_DESCRIPTORS > p_i21143->tx_endbuf, "tx_endbuf range" );        key = p_i21143->tx_keys[ 0 ];        // Common "done" code - key nonzero => report done        if (key) {            p_i21143->tx_keys[ 0 ] = 0;            p_i21143->tx_endbuf = NO_TX_IN_PROGRESS;            // Then tell the stack we are done:            INCR_STAT( tx_complete );            (sc->funs->eth_drv->tx_done)( sc, key, 0 );        }    }    i21143_reset(p_i21143);             // that should stop it}// ------------------------------------------------------------------------////  Function : InitRxRing//// ------------------------------------------------------------------------static voidInitRxRing(struct i21143* p_i21143){    int i;    volatile BUFDES *bp;    p_i21143->rx_ring =        (BUFDES *)CYGHWR_CACHED_TO_UNCACHED( &(p_i21143->_rx[0]) );    bp = p_i21143->rx_ring;    for ( i = 0 ; i < RX_DESCRIPTORS; i++ ) {        bp->des0 = DES0_STATUS_OWN_OPEN; // NIC owns it, not the CPU        bp->des1 = (MAX_RX_PACKET_SIZE << DES1_B1SIZE_SHIFT);        bp->buf1 = CYGHWR_PCI_VIRT_TO_BUS( &( p_i21143->_rxbufs[i][0] ) );        bp->buf2 = 0;        bp++;    }    bp--; // last one    bp->des1 |= DES1_ENDRING;    p_i21143->next_rx_descriptor = 0;}// ------------------------------------------------------------------------////  Function : PacketRxReady     (Called from delivery thread & foreground)//// ------------------------------------------------------------------------static voidPacketRxReady(struct i21143* p_i21143){    volatile BUFDES *bp;    int index;    struct eth_drv_sc *sc;    int count;    {        struct cyg_netdevtab_entry *ndp;        ndp = (struct cyg_netdevtab_entry *)(p_i21143->ndp);        sc = (struct eth_drv_sc *)(ndp->device_instance);        CHECK_NDP_SC_LINK();    }    CYG_ASSERT( 0 <= p_i21143->next_rx_descriptor, "rx descriptor underflow" );    CYG_ASSERT( RX_DESCRIPTORS > p_i21143->next_rx_descriptor, "rx descriptor overflow" );    index = p_i21143->next_rx_descriptor;    // Scan receive buffers    for ( count = 0; count < RX_DESCRIPTORS; count++ ) {        cyg_uint32 ldes0;        int length;        bp = &p_i21143->rx_ring[ index ];        CYG_ASSERT( 0 == bp->buf2, "Corrupt bp->buf2" );        CYG_ASSERT( 0 != bp->buf1, "Null bp->buf1" );        CYG_ASSERT( (MAX_RX_PACKET_SIZE << DES1_B1SIZE_SHIFT) == (bp->des1 &~ DES1_ENDRING),                    "Corrupt bp->des1" );        ldes0 = bp->des0;#ifdef DEBUG_TRAFFIC        diag_printf( "PacketRxReady: index %d des0 = %08x, %s, %s, %d bytes\n",                     index, ldes0,                     (ldes0 & DES0_STATUS_OWN) ? "open" : "done",                     ((RDES0_STATUS_FIRST | RDES0_STATUS_LAST | DES0_STATUS_ERROR) & ldes0)                     == (RDES0_STATUS_FIRST | RDES0_STATUS_LAST) ? "OK" : "--",                     (RDES0_COUNT_MASK & ldes0) >> RDES0_COUNT_SHIFT );#endif                if ( DES0_STATUS_OWN_OPEN == (ldes0 & DES0_STATUS_OWN) )            // This buffer bilong the device            break;        INCR_STAT( rx_count );        // Otherwise, this one is for us        if ( ((RDES0_STATUS_FIRST | RDES0_STATUS_LAST | DES0_STATUS_ERROR) & ldes0)             == (RDES0_STATUS_FIRST | RDES0_STATUS_LAST) ) {

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?