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

📄 if_i82559.c

📁 intel82559的以太网驱动
💻 C
📖 第 1 页 / 共 5 页
字号:
            return 0;        }    }    // If this device is not present, exit    if (0 == p_i82559->found)        return 0;    p_i82559->mac_addr_ok = 0;    ioaddr = p_i82559->io_address; // get I/O address for 82559#ifdef DEBUG    os_printf("Init82559 %d @ %x\n82559 Self Test\n",              p_i82559->index, (int)ndp);#endif    ints = Mask82559Interrupt(p_i82559);    // Reset device    i82559_reset(p_i82559);    // Perform a system self-test. (get enough mem to round address)    if ( (selftest = (cyg_uint32)pciwindow_mem_alloc(32) ) == 0)        return (0);    p_selftest = (cyg_uint32 *) ((selftest + 15) & ~0xf);    p_selftest[0] = p_selftest[1] = -1;    OUTL( (VIRT_TO_BUS(p_selftest)) | I82559_SELFTEST, ioaddr + SCBPort);    count = 0x7FFFF;                // Timeout for self-test.    do {        udelay(10);    } while ( (p_selftest[1] == -1)  &&  (--count >= 0) );    // Reset device again after selftest    i82559_reset(p_i82559);    Acknowledge82559Interrupt(p_i82559);    UnMask82559Interrupt(p_i82559, ints );        if (count < 0) {        // Test timed out.#ifdef DEBUG        os_printf("Self test failed\n");#endif        return (0);    }#ifdef DEBUG    os_printf("  General self-test: %s.\n"              "  Serial sub-system self-test: %s.\n"              "  Internal registers self-test: %s.\n"              "  ROM checksum self-test: %s (%08X).\n",              HAL_LE32TOC(p_selftest[1]) & 0x1000 ? "failed" : "passed",              HAL_LE32TOC(p_selftest[1]) & 0x0020 ? "failed" : "passed",              HAL_LE32TOC(p_selftest[1]) & 0x0008 ? "failed" : "passed",              HAL_LE32TOC(p_selftest[1]) & 0x0004 ? "failed" : "passed",              HAL_LE32TOC(p_selftest[0]));#endif    // free self-test memory?    // No, there's no point: this "heap" does not support free.    if (p_i82559->hardwired_esa) {        // Hardwire the address without consulting the EEPROM.        // When this flag is set, the p_i82559 will already contain        // the ESA. Copy it to a mac_address for call to set_mac_addr        mac_address[0] = p_i82559->mac_address[0];        mac_address[1] = p_i82559->mac_address[1];        mac_address[2] = p_i82559->mac_address[2];        mac_address[3] = p_i82559->mac_address[3];        mac_address[4] = p_i82559->mac_address[4];        mac_address[5] = p_i82559->mac_address[5];        eth_set_mac_address(p_i82559, mac_address, 0);    } else {        // Acquire the ESA either from extenal means (probably RedBoot        // variables) or from the attached EEPROM - if there is one.#ifdef CYGHWR_DEVS_ETH_INTEL_I82559_GET_ESA        int ok = false;        int wflag = 0;        CYGHWR_DEVS_ETH_INTEL_I82559_GET_ESA( p_i82559, mac_address, ok );        if ( ok ) {#ifndef CYGHWR_DEVS_ETH_INTEL_I82559_HAS_NO_EEPROM#ifdef CYGHWR_DEVS_ETH_INTEL_I82559_HAS_ONE_EEPROM	    if ( CYGHWR_DEVS_ETH_INTEL_I82559_HAS_ONE_EEPROM == p_i82559->index )#endif // CYGHWR_DEVS_ETH_INTEL_I82559_HAS_ONE_EEPROM	    {		cyg_uint8 tmp_addr[ETHER_ADDR_LEN];		// write eeprom address unless it is already there		wflag = 1;		if (read_eeprom_esa(p_i82559, tmp_addr)) {		    int i;		    for (i = 0; i < ETHER_ADDR_LEN; i++)			if (tmp_addr[i] != mac_address[i])			    break;		    if (i >= ETHER_ADDR_LEN)			wflag = 0;		}	    }#endif // ! CYGHWR_DEVS_ETH_INTEL_I82559_HAS_NO_EEPROM	    eth_set_mac_address(p_i82559, mac_address, wflag);	}#else // ! CYGHWR_DEVS_ETH_INTEL_I82559_GET_ESA#ifndef CYGHWR_DEVS_ETH_INTEL_I82559_HAS_NO_EEPROM#ifdef CYGHWR_DEVS_ETH_INTEL_I82559_HAS_ONE_EEPROM        if ( CYGHWR_DEVS_ETH_INTEL_I82559_HAS_ONE_EEPROM == p_i82559->index ) {#endif // CYGHWR_DEVS_ETH_INTEL_I82559_HAS_ONE_EEPROM	    if (read_eeprom_esa(p_i82559, mac_address)) {		// record the MAC address in the device structure		p_i82559->mac_address[0] = mac_address[0];		p_i82559->mac_address[1] = mac_address[1];		p_i82559->mac_address[2] = mac_address[2];		p_i82559->mac_address[3] = mac_address[3];		p_i82559->mac_address[4] = mac_address[4];		p_i82559->mac_address[5] = mac_address[5];                p_i82559->mac_addr_ok = 1;                eth_set_mac_address(p_i82559, mac_address, 0);	    }#ifdef CYGHWR_DEVS_ETH_INTEL_I82559_HAS_ONE_EEPROM        }        else { // We are now "in" another device#if 1 < CYGNUM_DEVS_ETH_INTEL_I82559_DEV_COUNT            struct i82559 *other; // The one that *is* set up from EEPROM            other = i82559_priv_array[CYGHWR_DEVS_ETH_INTEL_I82559_HAS_ONE_EEPROM];            if ( other->mac_addr_ok ) {                mac_address[0] = other->mac_address[0];                mac_address[1] = other->mac_address[1];                mac_address[2] = other->mac_address[2];                mac_address[3] = other->mac_address[3];                mac_address[4] = other->mac_address[4];                mac_address[5] = other->mac_address[5];#ifdef CYGHWR_DEVS_ETH_INTEL_I82559_HAS_ONE_EEPROM_MAC_ADJUST                mac_address[5] += CYGHWR_DEVS_ETH_INTEL_I82559_HAS_ONE_EEPROM_MAC_ADJUST;#endif                eth_set_mac_address(p_i82559, mac_address, 0);            }#endif // 1 < CYGNUM_DEVS_ETH_INTEL_I82559_DEV_COUNT        }#endif // CYGHWR_DEVS_ETH_INTEL_I82559_HAS_ONE_EEPROM#endif // ! CYGHWR_DEVS_ETH_INTEL_I82559_HAS_NO_EEPROM#endif // ! CYGHWR_DEVS_ETH_INTEL_I82559_GET_ESA    }#ifdef DEBUG    os_printf("i82559_init: MAC Address = %02X %02X %02X %02X %02X %02X\n",              p_i82559->mac_address[0], p_i82559->mac_address[1],              p_i82559->mac_address[2], p_i82559->mac_address[3],              p_i82559->mac_address[4], p_i82559->mac_address[5]);#endif        // and record the net dev pointer    p_i82559->ndp = (void *)ndp;        p_i82559->within_send = 0; // init recursion level    p_i82559->promisc = 0;  // None of these initially    p_i82559->multicast_all = 0;    p_i82559->oversized = 1;    // Enable this for VLAN mode by default    InitRxRing(p_i82559);    InitTxRing(p_i82559);    CheckRxRing(p_i82559,__FUNCTION__,__LINE__);    // Initialize upper level driver    if ( p_i82559->mac_addr_ok )        (sc->funs->eth_drv->init)(sc, &(p_i82559->mac_address[0]) );    else        (sc->funs->eth_drv->init)(sc, NULL );    CheckRxRing(p_i82559,__FUNCTION__,__LINE__);    return (1);}// ------------------------------------------------------------------------////  Function : i82559_start//// ------------------------------------------------------------------------static void i82559_start( struct eth_drv_sc *sc, unsigned char *enaddr, int flags ){    struct i82559 *p_i82559;    cyg_uint32 ioaddr;#ifdef KEEP_STATISTICS    void *p_statistics;#endif#ifdef CYGPKG_NET    struct ifnet *ifp = &sc->sc_arpcom.ac_if;#endif    p_i82559 = (struct i82559 *)sc->driver_private;    ioaddr = p_i82559->io_address; // get 82559's I/O address        IF_BAD_82559( p_i82559 ) {#ifdef DEBUG        os_printf( "i82559_start: Bad device pointer %x\n", p_i82559 );#endif        return;    }    if ( ! p_i82559->mac_addr_ok ) {#ifdef DEBUG        os_printf("i82559_start %d: invalid MAC address, "                  "can't bring up interface\n",                  p_i82559->index );#endif        return;    }    if ( p_i82559->active )        i82559_stop( sc );#ifdef KEEP_STATISTICS#ifdef CYGDBG_DEVS_ETH_INTEL_I82559_KEEP_STATISTICS    p_statistics = p_i82559->p_statistics;    memset(p_statistics, 0xFFFFFFFF, sizeof(I82559_COUNTERS));    // set statistics dump address    wait_for_cmd_done(ioaddr, WAIT_CU);    OUTL(VIRT_TO_BUS(p_statistics), ioaddr + SCBPointer);    OUTW(SCB_M | CU_STATSADDR, ioaddr + SCBCmd);    // Start dump command    wait_for_cmd_done(ioaddr, WAIT_CU);    OUTW(SCB_M | CU_DUMPSTATS, ioaddr + SCBCmd); // start register dump    // ...and wait for it to complete operation    // The code to wait was bogus; it was looking at the structure in the    // wrong way.  In any case, there is no need to wait, the    // wait_for_cmd_done() in any following activity is good enough.#endif#endif    // Enable device    p_i82559->active = 1;    /* Enable promiscuous mode if requested, reception of oversized frames always.     * The latter is needed for VLAN support and shouldn't hurt even if we're not     * using VLANs.  Reset multicastALL reception choice.     */    p_i82559->promisc = 0#ifdef CYGPKG_NET                     || !!(ifp->if_flags & IFF_PROMISC)#endif#ifdef ETH_DRV_FLAGS_PROMISC_MODE                     || !!(flags & ETH_DRV_FLAGS_PROMISC_MODE)#endif            ;    p_i82559->multicast_all = 0;    i82559_configure(p_i82559,                     p_i82559->promisc,                     p_i82559->oversized,                     p_i82559->multicast_all );#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    i82559_restart(p_i82559);    CheckRxRing(p_i82559,__FUNCTION__,__LINE__);}static void i82559_restart(struct i82559 *p_i82559){    cyg_uint32 ioaddr;    ioaddr = p_i82559->io_address; // get 82559's I/O address    // Load pointer to Rx Ring and enable receiver    wait_for_cmd_done(ioaddr, WAIT_RU);    OUTL(VIRT_TO_BUS(p_i82559->rx_ring[0]), ioaddr + SCBPointer);    OUTW(RUC_START, ioaddr + SCBCmd);}// ------------------------------------------------------------------------////  Function : i82559_status//// ------------------------------------------------------------------------inti82559_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 voidi82559_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    // Now that it's inactive, return all pending tx status to the higher    // layers:    // "Done" txen are from here to active, OR     // the remove one if the queue is full AND its status is nonz

⌨️ 快捷键说明

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