📄 if_iq80310.c
字号:
{ cyg_uint32 data : 16; // data to write or data read cyg_uint32 regAdd : 5; // PHY register address cyg_uint32 phyAdd : 5; // PHY address cyg_uint32 op : 2; // opcode, 1 for MDI write, 2 for MDI read cyg_uint32 ready : 1; // 1 = operation complete cyg_uint32 intEnab : 1; // 1 = interrupt at end of cycle cyg_uint32 rsrv : 2; // reserved } bits; cyg_uint32 word;} MDICTL;static cyg_uint16 readMDI (long ioaddr, cyg_uint8 phyAdd, cyg_uint8 regAdd){ int mdi_addr = ioaddr + SCBCtrlMDI; MDICTL mdiCtrl; int num_ms = 0; // prepare for the MDI operation mdiCtrl.bits.ready = MDI_NOT_READY; mdiCtrl.bits.intEnab = MDI_POLLED; // no interrupts mdiCtrl.bits.op = MDI_READ_OP; mdiCtrl.bits.phyAdd = phyAdd & 0x1f; mdiCtrl.bits.regAdd = regAdd & 0x1f; // start the operation OUTW(mdiCtrl.word, mdi_addr); // delay a bit udelay (1000); // poll for completion */ mdiCtrl.word = INW(mdi_addr); while ((mdiCtrl.bits.ready == MDI_NOT_READY) && (num_ms != 2000)) { // wait max 2secs mdiCtrl.word = INW(mdi_addr); udelay(1000); num_ms++; } if (num_ms >= 2000) { CYG_FAIL ("readMDI Timeout!\n"); return -1; } else return (cyg_uint16)mdiCtrl.bits.data;}static void writeMDI (long ioaddr, cyg_uint8 phyAdd, cyg_uint8 regAdd, cyg_uint16 data){ int mdi_addr = ioaddr + SCBCtrlMDI; register MDICTL mdiCtrl; int num_ms = 0; // prepare for the MDI operation mdiCtrl.bits.ready = MDI_NOT_READY; mdiCtrl.bits.intEnab = MDI_POLLED; // no interrupts mdiCtrl.bits.op = MDI_WRITE_OP; mdiCtrl.bits.phyAdd = phyAdd & 0x1f; mdiCtrl.bits.regAdd = regAdd & 0x1f; mdiCtrl.bits.data = data & 0xffff; // start the operation OUTW(mdiCtrl.word, mdi_addr); // delay a bit udelay(1000); // poll for completion mdiCtrl.word = INW(mdi_addr); while ((mdiCtrl.bits.ready == MDI_NOT_READY) && (num_ms != 2000)) { mdiCtrl.word = INW(mdi_addr); udelay(1000); num_ms++; } if (num_ms >= 2000) CYG_FAIL ("writeMDI Timeout!\n"); return;}static int initPHY (long ioaddr, cyg_uint32 device_type){ cyg_uint16 temp_reg; cyg_uint8 revision; // strip off revision and phy. id information revision = (cyg_uint8)(device_type & REVISION_MASK); device_type &= ~REVISION_MASK; switch (device_type) { case ICS1890_PHY_ID: temp_reg = readMDI(ioaddr, MDI_DEFAULT_PHY_ADDR, MDI_PHY_CTRL); // get ready for loopback setting writeMDI(ioaddr, MDI_DEFAULT_PHY_ADDR, MDI_PHY_CTRL, temp_reg); break; case DP83840_PHY_ID: // set the Intel-specified "must set" bits temp_reg = readMDI(ioaddr, MDI_DEFAULT_PHY_ADDR, DP83840_PCR_REG); temp_reg |= (PCR_TXREADY_SEL | PCR_FCONNECT); writeMDI (ioaddr, MDI_DEFAULT_PHY_ADDR, DP83840_PCR_REG, temp_reg); // get ready for loopback setting temp_reg = readMDI (ioaddr, MDI_DEFAULT_PHY_ADDR, DP83840_LOOPBACK_REG); temp_reg &= CLEAR_LOOP_BITS; writeMDI (ioaddr, MDI_DEFAULT_PHY_ADDR, DP83840_LOOPBACK_REG, temp_reg); break; case I82553_PHY_ID: case I82553_REVAB_PHY_ID: case I82555_PHY_ID: break; default: return 1; break; } return 0;}// ------------------------------------------------------------------------//// NETWORK INTERFACE INITIALIZATION//// Function : Init82559//// Description :// This routine resets, configures, and initializes the chip.// It also clears the ethernet statistics structure, and selects// which statistics are supported by this driver.//// ------------------------------------------------------------------------static booliq80310_i82559_init(struct cyg_netdevtab_entry * ndp){ static int initialized = 0; // only probe PCI et al *once* struct eth_drv_sc *sc; cyg_uint32 selftest; volatile cyg_uint32 *p_selftest; cyg_uint32 ioaddr; cyg_uint16 checksum; int count; int i, ints; int addr_length; cyg_uint8 mac_address[6]; struct i82559 *p_i82559;#ifdef DEBUG db_printf("iq80310_i82559_init\n");#endif sc = (struct eth_drv_sc *)(ndp->device_instance); p_i82559 = (struct i82559 *)(sc->driver_private); IF_BAD_82559( p_i82559 ) {#ifdef DEBUG os_printf( "Bad device private pointer %x\n", sc->driver_private );#endif return 0; } CHECK_NDP_SC_LINK(); if ( 0 == initialized++ ) { // then this is the first time ever: if ( ! pci_init_find_82559s() ) {#ifdef DEBUG os_printf( "pci_init_find_82559s failed" );#endif return 0; } } if ( ! p_i82559->found ) // no device on PCI bus return (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); wait_for_cmd_done(ioaddr); // make sure no command operating 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 = 0x1FFFFF; // Timeout for self-test. do { udelay(10); } while ( (p_selftest[1] == -1) && (--count >= 0) ); 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", p_selftest[1] & 0x1000 ? "failed" : "passed", p_selftest[1] & 0x0020 ? "failed" : "passed", p_selftest[1] & 0x0008 ? "failed" : "passed", p_selftest[1] & 0x0004 ? "failed" : "passed", p_selftest[0]);#endif // read eeprom and get 82559's mac address addr_length = get_eeprom_size(ioaddr); // (this is the length of the *EEPROM*s address, not MAC address) for (checksum = 0, i = 0, count = 0; count < 64; count++) { cyg_uint16 value; // read word from eeprom value = read_eeprom(ioaddr, count, addr_length);#ifdef DEBUG_EE // os_printf( "%2d: %04x\n", count, value );#endif checksum += value; if (count < 3) { mac_address[i++] = value & 0xFF; mac_address[i++] = (value >> 8) & 0xFF; } } // If the EEPROM checksum is wrong, the MAC address read from the // EEPROM is probably wrong as well. In that case, we don't set // mac_addr_ok, but continue the initialization. If then somebody calls // i82559_start without calling eth_set_mac_address() first, we refuse // to bring up the interface, because running with an invalid MAC // address is not a very brilliant idea.#if 0 if ((checksum & 0xFFFF) != 0xBABA) { // selftest verified checksum, verify again#ifdef DEBUG_EE os_printf( "Warning: Invalid EEPROM checksum %04X for device %d\n", checksum, p_i82559->index);#endif } else#endif { p_i82559->mac_addr_ok = 1;#ifdef DEBUG_EE os_printf("Valid EEPROM checksum\n");#endif }#ifdef DEBUG os_printf("MAC Address = %02X %02X %02X %02X %02X %02X\n", mac_address[0], mac_address[1], mac_address[2], mac_address[3], mac_address[4], mac_address[5]);#endif // 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]; // and record the net dev pointer p_i82559->ndp = (void *)ndp; InitRxRing(p_i82559); InitTxRing(p_i82559); // 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, 0 ); 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, phy_id; cyg_uint16 phy_addr_reg, temp1, temp2; int broadcom_flag = false; int link_speed = SPEED_NOLINK;#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; 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 ); ioaddr = p_i82559->io_address; // get 82559's I/O address phy_id = readMDI(ioaddr ,MDI_DEFAULT_PHY_ADDR, MDI_PHY_ID_1) << 16; phy_id |= readMDI(ioaddr ,MDI_DEFAULT_PHY_ADDR, MDI_PHY_ID_2); if ((phy_id & 0xfffffff0) == I82555_PHY_ID) {#ifdef DEBUG os_printf ("Intel 82555/558 PHY detected...\n");#endif // 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); phy_addr_reg = readMDI (ioaddr, MDI_DEFAULT_PHY_ADDR, I82555_STATCTRL_REG); if (temp1 & MDI_STAT_LINK) // speed only valid with good LNK link_speed = (phy_addr_reg & I82555_100_MBPS) ? SPEED_100M : SPEED_10M;#ifdef DEBUG else os_printf ("Connect Speed is NOT VALID\n");#endif } if ((phy_id & 0xfffffff0) == ICS1890_PHY_ID) {#ifdef DEBUG os_printf ("Integrated Circuit Systems ICS1890 PHY detected...\n"); os_printf ("Revision = %c\n", 'A' + (phy_id & REVISION_MASK));#endif // dummy read for reliable status (void)readMDI (ioaddr, MDI_DEFAULT_PHY_ADDR, ICS1890_QUICKPOLL_REG); temp1 = readMDI (ioaddr, MDI_DEFAULT_PHY_ADDR, ICS1890_QUICKPOLL_REG); if (temp1 & QUICK_LINK_VALID) // speed only valid with good LNK link_speed = (temp1 & QUICK_100_MBPS) ? SPEED_100M : SPEED_10M;#ifdef DEBUG else os_printf ("Connect Speed is NOT VALID\n");#endif } if ((phy_id & 0xfffffff0) == DP83840_PHY_ID) {#ifdef DEBUG os_printf ("National DP83840 PHY detected...\n"); os_printf ("Revision = %c\n", 'A' + (phy_id & REVISION_MASK));#endif // 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); phy_addr_reg = readMDI (ioaddr ,MDI_DEFAULT_PHY_ADDR, DP83840_PHY_ADDR_REG); if (temp1 & MDI_STAT_LINK) // speed only valid with good LNK link_speed = (phy_addr_reg & PHY_ADDR_SPEED_10_MBPS) ? SPEED_10M : SPEED_100M;#ifdef DEBUG else os_printf ("Connect Speed is NOT VALID\n");#endif }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -