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

📄 if_ixdp2400.c

📁 基于ecos的redboot
💻 C
📖 第 1 页 / 共 5 页
字号:
        if ( 0 == retval )
        {
#ifdef DEBUG_EE
            printf(" EEPROM address bits found:i = %d \n", i);
#endif
            break; // The dummy zero est arrive'
        }
    }

    addrbits = i;
    if ( 6 != i && 8 != i ) {
#ifdef DEBUG_EE
        printf( "*****EEPROM data bits not 6 or 8*****\n" );
#endif
        i = 6;
        addrbits = 0;  // So caller can know if the EEPROM is missing
    }

    // clear the dataval, leave the clock low to read in the data regardless
    OUTW(EE_ENB, ee_addr);
    eeprom_delay(1);
    
    retval = INW(ee_addr);
    if ( (EE_DATA_READ & retval) != 0 ) {
#ifdef DEBUG_EE
        os_printf( "Size EEPROM: Dummy data bit not 0, reg %x\n" , retval );
#endif
    }
    eeprom_delay(1);
    
    for (i = EE_TOP_DATA_BIT; i >= 0; i--) {
        OUTW(EE_ENB | EE_SHIFT_CLK, ee_addr);
        eeprom_delay(EEPROM_SK_DELAY);
        retval = INW(ee_addr);
        eeprom_delay(EEPROM_SK_DELAY);
        OUTW(EE_ENB, ee_addr);
        eeprom_delay(EEPROM_SK_DELAY);
    }
    
    // Terminate the EEPROM access.
    OUTW(EE_ENB & ~EE_CS, ee_addr);
    eeprom_delay(EEPROM_DONE_DELAY);
    
    return addrbits;
}

// ------------------------------------------------------------------------
//
//                       READ EEPROM
//
// ------------------------------------------------------------------------
static int read_eeprom(long ioaddr, int location, int addr_len)
{
    unsigned short retval = 0;
    int ee_addr = ioaddr + SCBeeprom;
    int read_cmd = location | EE_READ_CMD(addr_len);
    int i, tries = 10;

 try_again:
    // Should already be not-selected, but anyway:
    OUTW(EE_ENB & ~EE_CS, ee_addr);
    eeprom_delay(EEPROM_ENABLE_DELAY);
    OUTW(EE_ENB, ee_addr);
    eeprom_delay(EEPROM_ENABLE_DELAY);
    
    // Shift the read command bits out, changing only one bit per time.
    for (i = EE_TOP_CMD_BIT(addr_len); i >= 0; i--) {
        short dataval = (read_cmd & (1 << i)) ? EE_DATA_WRITE : 0;
        OUTW(EE_ENB | dataval               , ee_addr);
        eeprom_delay(EEPROM_SK_DELAY);
        OUTW(EE_ENB | dataval | EE_SHIFT_CLK, ee_addr);
        eeprom_delay(EEPROM_SK_DELAY);
        OUTW(EE_ENB | dataval               , ee_addr);
        eeprom_delay(EEPROM_SK_DELAY);
    }

    // clear the dataval, leave the clock low
    OUTW(EE_ENB, ee_addr);
    eeprom_delay(1);
    
    retval = INW(ee_addr);
    // This should show a zero in the data read bit to confirm that the
    // address transfer is compelete.  If not, go to the start and try
    // again!
    if ( (0 != (retval & EE_DATA_READ)) && (tries-- > 0) ) {
    // Terminate the EEPROM access.
        OUTW(EE_ENB & ~EE_CS, ee_addr);
        eeprom_delay(EEPROM_DONE_DELAY);
#ifdef DEBUG_EE
        os_printf( "Warning: Retrying EEPROM read word %d, address %x, try %d\n",
                   location,  ee_addr, tries+1 );
#endif
        goto try_again;
    }

    // This fires with one device on one of the customer boards!
    // (but is OK on all other h/w.  Worrying huh.)
    if ( (EE_DATA_READ & retval) != 0 ) {
#ifdef DEBUG_EE
        os_printf( "Read EEPROM: Dummy data bit not 0, reg %x\n" , retval );
#endif
    }
    eeprom_delay(1);
    retval = 0;

    for (i = EE_TOP_DATA_BIT; i >= 0; i--) {
        OUTW(EE_ENB | EE_SHIFT_CLK, ee_addr);
        eeprom_delay(EEPROM_SK_DELAY);
        retval = (retval << 1) | ((INW(ee_addr) & EE_DATA_READ) ? 1 : 0);
        eeprom_delay(EEPROM_SK_DELAY);
        OUTW(EE_ENB, ee_addr);
        eeprom_delay(EEPROM_SK_DELAY);
    }
    
    // Terminate the EEPROM access.
    OUTW(EE_ENB & ~EE_CS, ee_addr);
    eeprom_delay(EEPROM_DONE_DELAY);
    
    return retval;
}

// ------------------------------------------------------------------------
//
//                       MDI
//
// ------------------------------------------------------------------------

#define SPEED_NOLINK	0
#define SPEED_10M		10
#define SPEED_100M		100

// MDI Control Register
typedef union
{
    struct
    {
#ifdef __ARMEB__
		cyg_uint32 rsrv    : 2;	// reserved
    	cyg_uint32 intEnab : 1;	// 1 = interrupt at end of cycle
    	cyg_uint32 ready   : 1;	// 1 = operation complete
    	cyg_uint32 op      : 2;	// opcode, 1 for MDI write, 2 for MDI read
    	cyg_uint32 phyAdd  : 5;	// PHY address
    	cyg_uint32 regAdd  : 5;	// PHY register address
    	cyg_uint32 data   : 16;	// data to write or data read
#else
    	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
#endif
    } 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
    OUTL(mdiCtrl.word, mdi_addr);

    // delay a bit
    udelay (1000);

    // poll for completion */
    mdiCtrl.word = INL(mdi_addr);

    while ((mdiCtrl.bits.ready == MDI_NOT_READY) && (num_ms != 2000)) { // wait max 2secs
	mdiCtrl.word = INL(mdi_addr);
	udelay(1000);
	num_ms++;
    }	
	
    if (num_ms >= 2000)	{
	printf ("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
    OUTL(mdiCtrl.word, mdi_addr);

    // delay a bit
    udelay(1000);

    // poll for completion
    mdiCtrl.word = INL(mdi_addr);

    while ((mdiCtrl.bits.ready == MDI_NOT_READY) && (num_ms != 2000)) {
	mdiCtrl.word = INL(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 bool
ixdp2400_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;
    int count;
    int i, ints;
    cyg_uint16 checksum;
    int addr_length;
    cyg_uint8 mac_address[6];
    struct i82559 *p_i82559;
	cyg_uint8 *cfg_mac_addr;

#ifdef DEBUG
    db_printf("ixdp2400_i82559_init\n");
#endif

	display_led('E', 'T', 'H', 'I');

    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
        printf( "%2d: %04x\n", count, value );
#endif
        checksum += value;

⌨️ 快捷键说明

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