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

📄 if_ixdp2400.c

📁 基于ecos的redboot
💻 C
📖 第 1 页 / 共 5 页
字号:
        if (count < 3) {
            mac_address[i++] = value & 0xFF;
            mac_address[i++] = (value >> 8) & 0xFF;
        }
    }

    if ((checksum & 0xFFFF) != 0xBABA)  {
        // selftest verified checksum, verify again
        printf( "Warning: Invalid EEPROM checksum %04X for device %d\n",
                   checksum, p_i82559->index);
    }

#ifndef USE_21555_PRI_NIC
	if(board_config_data->config_valid == CONFIG_DATA_VALID)
	{
		if(strap_options_val() & CFG_PCI_BOOT_HOST)
		{
			cfg_mac_addr = board_config_data->config_data.M_ether_mac_addr;
		}
		else
		{
			cfg_mac_addr = board_config_data->config_data.S_ether_mac_addr;
		}
		if((cfg_mac_addr[0] == 0) && (cfg_mac_addr[1] == 0) && (cfg_mac_addr[2] == 0) &&
			(cfg_mac_addr[3] == 0) && (cfg_mac_addr[4] == 0) && (cfg_mac_addr[5] == 0))
		{
			printf("Config MAC address is 0x000000000000\n");
			printf("Using NIC EEPROM MAC address\n");
		}
		else
		{
			if(memcmp(mac_address, cfg_mac_addr, 6))
			{
				printf("Config MAC address doesn't match with NIC EEPROM MAC address\n");
				printf("Config MAC Address     = %02X %02X %02X %02X %02X %02X\n",
					cfg_mac_addr[0], cfg_mac_addr[1], cfg_mac_addr[2], cfg_mac_addr[3],
					cfg_mac_addr[4], cfg_mac_addr[5]);
				printf("NIC EEPROM 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]);
				if(!verify_action("\tProgram config MAC address to NIC EEPROM"))
				{
					printf("Can't bring up the network interface\n");
					return 0;
				}
				memcpy(eeprom_burn, cfg_mac_addr, 6);
				program_eeprom(ioaddr, addr_length, eeprom_burn);
				
				// update 82559 driver data structure ...
				udelay(100000);
				for(i = 0, count = 0; count < 3; count++)
				{
					cyg_uint16 value;

					// read word from eeprom
					value = read_eeprom(ioaddr, count, addr_length);
					mac_address[i++] = value & 0xFF;
					mac_address[i++] = (value >> 8) & 0xFF;
				}
			}
		}
	}
	else
	{
		if((mac_address[0] == 0xFF) && (mac_address[1] == 0xFF) && (mac_address[2] == 0xFF) &&
			(mac_address[3] == 0xFF) && (mac_address[4] == 0xFF) && (mac_address[5] == 0xFF))
		{
			printf("NIC EEPROM is blank\n");
			printf("Couldn't find valid MAC address in config data\n");
			printf("Can't bring up the network interface. Please program config PROM\n");
			return 0;
		}
		else
		{
			printf("Using MAC address from NIC EEPROM\n");
		}
	}
#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
    }

    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_IXDP2400_KEEP_82559_STATISTICS
    p_i82559->p_statistics =
        p_statistics = pciwindow_mem_alloc(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);
	wait_for_cmd_done(ioaddr);
    OUTW(SCB_M | 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 = swap32(VIRT_TO_BUS(rfd));
        p_rfd = (RFD *)rfd;
    }
    // link last RFD to first:
    p_rfd->link = swap32(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;

⌨️ 快捷键说明

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