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 + -
显示快捷键?