📄 if_ixdp2400.c
字号:
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 + -