⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 if_iq80310.c

📁 移植到WLIT项目的redboot源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
    if ((phy_id & 0xfffffff0) == I82553_PHY_ID)	{#ifdef DEBUG	os_printf ("Intel 82553 PHY detected...\n");	os_printf ("Revision = %c\n", 'A' + (phy_id & REVISION_MASK));#endif	broadcom_flag = true;    }    if (phy_id == I82553_REVAB_PHY_ID) {#ifdef DEBUG	os_printf ("Intel 82553 PHY detected...\n");	os_printf ("Revision = B\n");#endif	broadcom_flag = true;    }    if (broadcom_flag == true) {	temp2 = readMDI (ioaddr, MDI_DEFAULT_PHY_ADDR, I82553_PHY_EXT_REG0);	// dummy read for reliable status	(void)readMDI (ioaddr ,MDI_DEFAULT_PHY_ADDR, MDI_PHY_STAT);	temp1 = readMDI (ioaddr ,MDI_DEFAULT_PHY_ADDR, MDI_PHY_STAT);	if (temp1 & MDI_STAT_LINK) { // speed only valid with good LNK	    link_speed = (temp2 & EXT_REG0_100_MBPS) ? SPEED_100M : SPEED_10M;#ifdef DEBUG	else	    os_printf ("Connect Speed is NOT VALID\n");#endif	}    }#ifdef KEEP_STATISTICS#ifdef CYGDBG_DEVS_ETH_ARM_IQ80310_KEEP_82559_STATISTICS    p_i82559->p_statistics =        p_statistics = pciwindow_mem_alloc(sizeof(I82559_COUNTERS));    memset(p_statistics, 0xFFFFFFFF, sizeof(I82559_COUNTERS));    wait_for_cmd_done(ioaddr); // make sure no command operating                                        // set statistics dump address    OUTL(VIRT_TO_BUS(p_statistics), ioaddr + SCBPointer);    OUTW(SCB_M | CU_STATSADDR, ioaddr + SCBCmd);    wait_for_cmd_done(ioaddr); // make sure no command operating    OUTW(SCB_M | CU_DUMPSTATS, ioaddr + SCBCmd); // start register dump#endif#endif    // Set the base address    wait_for_cmd_done(ioaddr);    OUTL(0, ioaddr + SCBPointer);       // load ru base address = 0    OUTW(SCB_M | RUC_ADDR_LOAD, ioaddr + SCBCmd);    udelay( 1000 );                     // load pointer to Rx Ring    OUTL(VIRT_TO_BUS(p_i82559->rx_ring[0]), ioaddr + SCBPointer);    OUTW(RUC_START, ioaddr + SCBCmd);        p_i82559->active = 1;    initPHY(ioaddr, phy_id);#ifdef CYGPKG_NET    if (( 0#ifdef ETH_DRV_FLAGS_PROMISC_MODE         != (flags & ETH_DRV_FLAGS_PROMISC_MODE)#endif        ) || (ifp->if_flags & IFF_PROMISC)        ) {        eth_set_promiscuous_mode(p_i82559);    }#endif#ifdef DEBUG    {        int status = i82559_status( sc );        os_printf("i82559_start %d flg %x Link = %s, %s Mbps, %s Duplex\n",                  p_i82559->index,                  *(int *)p_i82559,                  status & GEN_STATUS_LINK ? "Up" : "Down",                  status & GEN_STATUS_100MBPS ?  "100" : "10",                  status & GEN_STATUS_FDX ? "Full" : "Half");    }#endif}// ------------------------------------------------------------------------////  Function : i82559_status//// ------------------------------------------------------------------------int i82559_status( struct eth_drv_sc *sc ){    int status;    struct i82559 *p_i82559;    cyg_uint32 ioaddr;    p_i82559 = (struct i82559 *)sc->driver_private;        IF_BAD_82559( p_i82559 ) {#ifdef DEBUG        os_printf( "i82559_status: Bad device pointer %x\n", p_i82559 );#endif        return 0;    }    ioaddr = p_i82559->io_address; // get 82559's I/O address    status = INB(ioaddr + SCBGenStatus);    return status;}// ------------------------------------------------------------------------////  Function : BringDown82559//// ------------------------------------------------------------------------static void i82559_stop( struct eth_drv_sc *sc ){    struct i82559 *p_i82559;    p_i82559 = (struct i82559 *)sc->driver_private;    IF_BAD_82559( p_i82559 ) {#ifdef DEBUG        os_printf( "i82559_stop: Bad device pointer %x\n", p_i82559 );#endif        return;    }   #ifdef DEBUG    os_printf("i82559_stop %d flg %x\n", p_i82559->index, *(int *)p_i82559 );#endif    p_i82559->active = 0;               // stop people tormenting it    i82559_reset(p_i82559);             // that should stop it    ResetRxRing( p_i82559 );    ResetTxRing( p_i82559 );}// ------------------------------------------------------------------------////  Function : InitRxRing//// ------------------------------------------------------------------------static void InitRxRing(struct i82559* p_i82559){    int i;    RFD *rfd;    RFD *p_rfd = 0;#ifdef DEBUG_82559    os_printf("InitRxRing %d\n", p_i82559->index);#endif    for ( i = 0; i < MAX_RX_DESCRIPTORS; i++ ) {        rfd = (RFD *)pciwindow_mem_alloc(sizeof(RFD) + MAX_RX_PACKET_SIZE);        p_i82559->rx_ring[i] = rfd;        if ( i )            p_rfd->link = VIRT_TO_BUS(rfd);        p_rfd = (RFD *)rfd;    }    // link last RFD to first:    p_rfd->link = VIRT_TO_BUS(p_i82559->rx_ring[0]);    ResetRxRing( p_i82559 );}// ------------------------------------------------------------------------////  Function : ResetRxRing//// ------------------------------------------------------------------------static void ResetRxRing(struct i82559* p_i82559){    RFD *p_rfd;    int i;#ifdef DEBUG_82559    os_printf("ResetRxRing %d\n", p_i82559->index);#endif    for ( i = 0; i < MAX_RX_DESCRIPTORS; i++ ) {        p_rfd = p_i82559->rx_ring[i];        CYG_ASSERT( (cyg_uint8 *)p_rfd >= i82559_heap_base, "rfd under" );        CYG_ASSERT( (cyg_uint8 *)p_rfd <  i82559_heap_free, "rfd over" );        CYG_ASSERT( p_i82559->rx_ring[                 ( i ? (i-1) : (MAX_RX_DESCRIPTORS-1) )            ]->link == VIRT_TO_BUS(p_rfd), "rfd linked list broken" );        p_rfd->rxstatus = 0;        p_rfd->count = 0;        p_rfd->f = 0;        p_rfd->eof = 0;        p_rfd->rdb_address = 0xFFFFFFFF;        p_rfd->size = MAX_RX_PACKET_SIZE;    }    p_i82559->next_rx_descriptor = 0;    // And set an end-of-list marker in the previous one.    p_rfd->rxstatus = RFD_STATUS_EL;}// ------------------------------------------------------------------------////  Function : PacketRxReady        (Called from delivery thread)//// ------------------------------------------------------------------------static void PacketRxReady(struct i82559* p_i82559){    RFD *p_rfd;    int next_descriptor;    int length, ints;    struct cyg_netdevtab_entry *ndp;    struct eth_drv_sc *sc;    cyg_uint32 ioaddr;    cyg_uint16 status;    ndp = (struct cyg_netdevtab_entry *)(p_i82559->ndp);    sc = (struct eth_drv_sc *)(ndp->device_instance);    CHECK_NDP_SC_LINK();    ioaddr = p_i82559->io_address;    next_descriptor = p_i82559->next_rx_descriptor;    p_rfd = p_i82559->rx_ring[next_descriptor];    CYG_ASSERT( (cyg_uint8 *)p_rfd >= i82559_heap_base, "rfd under" );    CYG_ASSERT( (cyg_uint8 *)p_rfd <  i82559_heap_free, "rfd over" );    while ( p_rfd->rxstatus & RFD_STATUS_C ) {        p_rfd->rxstatus_hi |= RFD_STATUS_HI_EL;        length = p_rfd->count;#ifdef DEBUG_82559        os_printf( "Device %d (eth%d), rx descriptor %d:\n",                    p_i82559->index, p_i82559->index, next_descriptor );//        dump_rfd( p_rfd, 1 );#endif        p_i82559->next_rx_descriptor = next_descriptor;        // Check for bogusly short packets; can happen in promisc mode:        // Asserted against and checked by upper layer driver.#ifdef CYGPKG_NET        if ( length > sizeof( struct ether_header ) )            // then it is acceptable; offer the data to the network stack#endif        (sc->funs->eth_drv->recv)( sc, length );        p_rfd->count = 0;        p_rfd->f = 0;        p_rfd->eof = 0;        p_rfd->rxstatus_lo = 0;        // The just-emptied slot is now ready for re-use and already marked EL;        // we can now remove the EL marker from the previous one.        if ( 0 == next_descriptor )            p_rfd = p_i82559->rx_ring[ MAX_RX_DESCRIPTORS-1 ];        else            p_rfd = p_i82559->rx_ring[ next_descriptor-1 ];        // The previous one: check it *was* marked before clearing.        CYG_ASSERT( p_rfd->rxstatus_hi & RFD_STATUS_HI_EL, "No prev EL" );        p_rfd->rxstatus_hi = 0; // that word is not written by the device.#ifdef KEEP_STATISTICS        statistics[p_i82559->index].rx_deliver++;#endif        if (++next_descriptor >= MAX_RX_DESCRIPTORS)            next_descriptor = 0;        p_rfd = p_i82559->rx_ring[next_descriptor];        CYG_ASSERT( (cyg_uint8 *)p_rfd >= i82559_heap_base, "rfd under" );        CYG_ASSERT( (cyg_uint8 *)p_rfd <  i82559_heap_free, "rfd over" );    }    // See if the RU has gone idle (usually because of out of resource    // condition) and restart it if needs be.    ints = Mask82559Interrupt(p_i82559);    status = INW(ioaddr + SCBStatus);    if ( RU_STATUS_READY != (status & RU_STATUS_MASK) ) {        // Acknowledge the RX INT sources        OUTW( SCB_INTACK_RX, ioaddr + SCBStatus);        // (see pages 6-10 & 6-90)#ifdef KEEP_STATISTICS        statistics[p_i82559->index].rx_restart++;#endif        // There's an end-of-list marker out there somewhere...        // So mop it up; it takes a little time but this is infrequent.        ResetRxRing( p_i82559 );          next_descriptor = 0;        // re-initialize next desc.        // wait for SCB command complete        wait_for_cmd_done(ioaddr);        // load pointer to Rx Ring        OUTL(VIRT_TO_BUS(p_i82559->rx_ring[0]),             ioaddr + SCBPointer);        OUTW(RUC_START, ioaddr + SCBCmd);        Acknowledge82559Interrupt(p_i82559);    }    UnMask82559Interrupt(p_i82559, ints);    p_i82559->next_rx_descriptor = next_descriptor;}// and the callback functionstatic void i82559_recv( struct eth_drv_sc *sc,                         struct eth_drv_sg *sg_list, int sg_len ){    struct i82559 *p_i82559;    RFD *p_rfd;    int next_descriptor;    int total_len;    struct eth_drv_sg *last_sg;    volatile cyg_uint8 *from_p;    p_i82559 = (struct i82559 *)sc->driver_private;        IF_BAD_82559( p_i82559 ) {#ifdef DEBUG        os_printf( "i82559_recv: Bad device pointer %x\n", p_i82559 );#endif        return;    }    next_descriptor = p_i82559->next_rx_descriptor;    p_rfd = p_i82559->rx_ring[next_descriptor];        CYG_ASSERT( (cyg_uint8 *)p_rfd >= i82559_heap_base, "rfd under" );    CYG_ASSERT( (cyg_uint8 *)p_rfd <  i82559_heap_free, "rfd over" );    CYG_ASSERT( p_rfd->rxstatus & RFD_STATUS_C, "No complete frame" );    CYG_ASSERT( p_rfd->rxstatus & RFD_STATUS_EL, "No marked frame" );    CYG_ASSERT( p_rfd->rxstatus_lo & RFD_STATUS_LO_C, "No complete frame 2" );    CYG_ASSERT( p_rfd->rxstatus_hi & RFD_STATUS_HI_EL, "No marked frame 2" );        if ( 0 == (p_rfd->rxstatus & RFD_STATUS_C) )        return;            total_len = p_rfd->count;    #ifdef DEBUG_82559    os_printf("Rx %d %x (status %x): %d sg's, %d bytes\n",              p_i82559->index, (int)p_i82559, p_rfd->rxstatus, sg_len, total_len);#endif    // Copy the data to the network stack    from_p = &p_rfd->buffer[0];    // check we have memory to copy into; we would be called even if    // caller was out of memory in order to maintain our state.    if ( 0 == sg_len || 0 == sg_list )        return; // caller was out of mbufs    CYG_ASSERT( 0 < sg_len, "sg_len underflow" );    CYG_ASSERT( MAX_ETH_DRV_SG >= sg_len, "sg_len overflow" );    for ( last_sg = &sg_list[sg_len]; sg_list < last_sg; sg_list++ ) {        cyg_uint8 *to_p;        int l;                    to_p = (cyg_uint8 *)(sg_list->buf);        l = sg_list->len;        CYG_ASSERT( 0 <= l, "sg length -ve" );        if ( 0 >= l || 0 == to_p )            return; // caller was out of mbufs        if ( l > total_len )            l = total_len;        memcpy( to_p, (unsigned char *)from_p, l );        from_p += l;        total_len -= l;    }    CYG_ASSERT( 0 == total_len, "total_len mismatch in rx" );    CYG_ASSERT( last_sg == sg_list, "sg count mismatch in rx" );    CYG_ASSERT( &p_rfd->buffer[0] < from_p, "from_p wild in rx" );    CYG_ASSERT( &p_rfd->buffer[0] + MAX_RX_PACKET_SIZE >= from_p,                "from_p overflow in rx" );}    // ------------------------------------------------------------------------////  Function : InitTxRing//// ------------------------------------------------------------------------static void InitTxRing(struct i82559* p_i82559){    int i;    cyg_uint32 ioaddr;#ifdef DEBUG_82559    os_printf("InitTxRing %d\n", p_i82559->index);#endif    ioaddr = p_i82559->io_address;    for ( i = 0; i < MAX_TX_DESCRIPTORS; i++) {        p_i82559->tx_ring[i] = (TxCB *)pciwindow_mem_alloc(            sizeof(TxCB) + MAX_TX_PACKET_SIZE);    }    ResetTxRing(p_i82559);

⌨️ 快捷键说明

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