📄 smsc9118.c
字号:
if(mac_addr_hi16==0xFFFFFFFFUL) {
SMSC_TRACE(" mac_addr_hi16 = 0x%08lX, will attempt to read from LAN9118",mac_addr_hi16);
SMSC_TRACE(" mac_addr_lo32 = 0x%08lX, will attempt to read from LAN9118",mac_addr_lo32);
} else {
if(mac_addr_hi16&0xFFFF0000UL) {
//The high word is reserved
SMSC_WARNING(" mac_addr_hi16 = 0x%08lX, reserved bits are high.",mac_addr_hi16);
mac_addr_hi16&=0x0000FFFFUL;
SMSC_WARNING(" reseting to mac_addr_hi16 = 0x%08lX",mac_addr_hi16);
}
if(mac_addr_lo32&0x00000001UL) {
//bit 0 is the I/G bit
SMSC_WARNING(" mac_addr_lo32 = 0x%08lX, I/G bit is set.",mac_addr_lo32);
mac_addr_lo32&=0xFFFFFFFEUL;
SMSC_WARNING(" reseting to mac_addr_lo32 = 0x%08lX",mac_addr_lo32);
}
SMSC_TRACE(" mac_addr_hi16 = 0x%08lX",mac_addr_hi16);
SMSC_TRACE(" mac_addr_lo32 = 0x%08lX",mac_addr_lo32);
}
SMSC_TRACE( " debug_mode = 0x%08lX",debug_mode);
if(tx_fif_sz&(~HW_CFG_TX_FIF_SZ_)) {
SMSC_WARNING("tx_fif_sz = 0x%08lX is invalid",tx_fif_sz);
tx_fif_sz&=HW_CFG_TX_FIF_SZ_;
SMSC_WARNING(" resetting tx_fif_sz to 0x%08lX",tx_fif_sz);
}
if(tx_fif_sz>0x000E0000UL) {
SMSC_WARNING("tx_fif_sz = 0x%08lX is too high",tx_fif_sz);
tx_fif_sz=0x000E0000UL;
SMSC_WARNING(" resetting tx_fif_sz to 0x%08lX",tx_fif_sz);
}
if(tx_fif_sz<0x00020000UL) {
SMSC_WARNING("tx_fif_sz = 0x%08lX is too low",tx_fif_sz);
tx_fif_sz=0x00020000UL;
SMSC_WARNING(" resetting tx_fif_sz to 0x%08lX",tx_fif_sz);
}
SMSC_TRACE( " tx_fif_sz = 0x%08lX",tx_fif_sz);
if(afc_cfg==0xFFFFFFFFUL) {
SMSC_TRACE(" afc_cfg = 0x%08lX, driver will decide",afc_cfg);
} else {
if(afc_cfg&0xFF000000UL) {
SMSC_WARNING("afc_cfg = 0x%08lX is invalid",afc_cfg);
afc_cfg&=0xFFFFFFFFUL;
SMSC_WARNING(" resetting to afc_cfg = 0x%08lX, driver will decide",afc_cfg);
} else {
SMSC_TRACE(
" afc_cfg = 0x%08lX",afc_cfg);
}
}
if(tasklets) {
SMSC_TRACE(" tasklets = 0x%08lX, Tasklets enabled",tasklets);
} else {
SMSC_TRACE(" tasklets = 0, Tasklets disabled");
}
if(phy_addr==0xFFFFFFFFUL) {
SMSC_TRACE(" phy_addr = 0xFFFFFFFF, Use internal phy");
} else if(phy_addr<=31UL) {
SMSC_TRACE(" phy_addr = 0x%08lX, use this address for external phy",phy_addr);
} else {
SMSC_TRACE(" phy_addr = 0x%08lX, auto detect external phy",phy_addr);
}
if(max_throughput) {
SMSC_TRACE(" max_throughput = 0x%08lX, Use platform default",max_throughput);
} else {
SMSC_TRACE(" max_throughput = 0x%08lX",max_throughput);
}
if(max_packet_count) {
SMSC_TRACE(" max_packet_count = 0x%08lX, Use platform default",max_packet_count);
} else {
SMSC_TRACE(" max_packet_count = 0x%08lX",max_packet_count);
}
if(packet_cost) {
SMSC_TRACE(" packet_cost = 0x%08lX, Use platform default",packet_cost);
} else {
SMSC_TRACE(" packet_cost = 0x%08lX",packet_cost);
}
if(burst_period) {
SMSC_TRACE(" burst_period = 0x%08lX, Use platform default",burst_period);
} else {
SMSC_TRACE(" burst_period = 0x%08lX",burst_period);
}
if(max_work_load) {
SMSC_TRACE(" max_work_load = 0x%08lX, Use platform default",max_work_load);
} else {
SMSC_TRACE(" max_work_load = 0x%08lX",max_work_load);
}
strcpy(SMSC9118.name,"eth%d");
result=register_netdev(&SMSC9118);
if(result) {
SMSC_WARNING("error %i registering device",result);
} else {
device_present=1;
SMSC_TRACE(" Interface Name = \"%s\"",SMSC9118.name);
}
result=result;//make lint happy
SMSC_TRACE("<-- init_module()");
return device_present ? 0 : -ENODEV;
}
void Smsc9118_cleanup_module(void)
{
SMSC_TRACE("--> cleanup_module()");
if(SMSC9118.priv!=NULL) {
PPRIVATE_DATA privateData=(PPRIVATE_DATA)SMSC9118.priv;
PPLATFORM_DATA platformData=(PPLATFORM_DATA)&(privateData->PlatformData);
Platform_CleanUp(platformData);
kfree(SMSC9118.priv);
SMSC9118.priv=NULL;
}
unregister_netdev(&SMSC9118);
SMSC_TRACE("<-- cleanup_module()");
}
int Smsc9118_init(struct net_device *dev)
{
DWORD dwLanBase=0UL;
DWORD dwIdRev=0UL;
DWORD dwFpgaRev=0UL;
PPRIVATE_DATA privateData=NULL;
PPLATFORM_DATA platformData=NULL;
BOOLEAN platformInitialized=FALSE;
int result=-ENODEV;
SMSC_TRACE("-->Smsc9118_init(dev=0x%08lX)",(DWORD)dev);
if(dev==NULL) {
SMSC_WARNING("Smsc9118_init(dev==NULL)");
result=-EFAULT;
goto DONE;
}
if(dev->priv!=NULL) {
SMSC_WARNING("dev->priv!=NULL, going to overwrite pointer");
}
dev->priv=kmalloc(sizeof(PRIVATE_DATA),GFP_KERNEL);
if(dev->priv==NULL) {
SMSC_WARNING("Unable to allocate PRIVATE_DATA");
result=-ENOMEM;
goto DONE;
}
memset(dev->priv,0,sizeof(PRIVATE_DATA));
privateData=(PPRIVATE_DATA)(dev->priv);
platformData=&(privateData->PlatformData);
dwLanBase=Platform_Initialize(
platformData,
lan_base,bus_width);
if(dwLanBase==0UL) {
SMSC_WARNING("dwLanBase==0x00000000");
result=-ENODEV;
goto DONE;
}
platformInitialized=TRUE;
SMSC_TRACE("dwLanBase=0x%08lX",dwLanBase);
if(check_mem_region(dwLanBase,LAN_REGISTER_EXTENT)!=0) {
SMSC_WARNING(" Memory Region specified (0x%08lX to 0x%08lX) is not available.",
dwLanBase,dwLanBase+LAN_REGISTER_EXTENT-1UL);
result=-ENOMEM;
goto DONE;
}
privateData->dwLanBase=dwLanBase;
dwIdRev=Lan_GetRegDW(ID_REV);
if(HIWORD(dwIdRev)==LOWORD(dwIdRev)) {
//this may mean the chip is set for 32 bit
// while the bus is reading as 16 bit
UNKNOWN_CHIP:
SMSC_WARNING(" LAN9118 Family NOT Identified, dwIdRev==0x%08lX",dwIdRev);
result=-ENODEV;
goto DONE;
}
switch(dwIdRev&0xFFFF0000UL) {
case 0x01180000UL:
switch(dwIdRev&0x0000FFFFUL) {
case 0UL:
SMSC_TRACE(" LAN9118 Beacon identified, dwIdRev==0x%08lX",dwIdRev);
privateData->dwGeneration=0;
break;
case 1UL:
SMSC_TRACE(" LAN9118 Concord A0 identified, dwIdRev==0x%08lX",dwIdRev);
privateData->dwGeneration=1;
break;
case 2UL:
SMSC_TRACE(" LAN9118 Concord A1 identified, dwIdRev==0x%08lX",dwIdRev);
privateData->dwGeneration=2;
break;
default:
SMSC_TRACE(" LAN9118 Concord A1 identified (NEW), dwIdRev==0x%08lX",dwIdRev);
privateData->dwGeneration=2;
break;
};break;
case 0x01170000UL:
switch(dwIdRev&0x0000FFFFUL) {
case 0UL:
SMSC_TRACE(" LAN9117 Beacon identified, dwIdRev==0x%08lX",dwIdRev);
privateData->dwGeneration=0;
break;
case 1UL:
SMSC_TRACE(" LAN9117 Concord A0 identified, dwIdRev==0x%08lX",dwIdRev);
privateData->dwGeneration=1;
break;
case 2UL:
SMSC_TRACE(" LAN9117 Concord A1 identified, dwIdRev==0x%08lX",dwIdRev);
privateData->dwGeneration=2;
break;
default:
SMSC_TRACE(" LAN9117 Concord A1 identified (NEW), dwIdRev==0x%08lX",dwIdRev);
privateData->dwGeneration=2;
break;
};break;
case 0x01160000UL:
switch(dwIdRev&0x0000FFFFUL) {
case 0UL:
goto UNKNOWN_CHIP;
case 1UL:
SMSC_TRACE(" LAN9116 Concord A0 identified, dwIdRev==0x%08lX",dwIdRev);
privateData->dwGeneration=1;
break;
case 2UL:
SMSC_TRACE(" LAN9116 Concord A1 identified, dwIdRev==0x%08lX",dwIdRev);
privateData->dwGeneration=2;
break;
default:
SMSC_TRACE(" LAN9116 Concord A1 identified (NEW), dwIdRev==0x%08lX",dwIdRev);
privateData->dwGeneration=2;
break;
};break;
case 0x01150000UL:
switch(dwIdRev&0x0000FFFFUL) {
case 0UL:
goto UNKNOWN_CHIP;
case 1UL:
SMSC_TRACE(" LAN9115 Concord A0 identified, dwIdRev==0x%08lX",dwIdRev);
privateData->dwGeneration=1;
break;
case 2UL:
SMSC_TRACE(" LAN9115 Concord A1 identified, dwIdRev==0x%08lX",dwIdRev);
privateData->dwGeneration=2;
break;
default:
SMSC_TRACE(" LAN9115 Concord A1 identified (NEW), dwIdRev==0x%08lX",dwIdRev);
privateData->dwGeneration=2;
break;
};break;
case 0x01120000UL:
switch(dwIdRev&0x0000FFFFUL) {
case 0UL:
goto UNKNOWN_CHIP;
case 1UL:
SMSC_TRACE(" LAN9112 Concord A0 identified, dwIdRev==0x%08lX",dwIdRev);
privateData->dwGeneration=1;
break;
case 2UL:
SMSC_TRACE(" LAN9112 Concord A1 identified, dwIdRev==0x%08lX",dwIdRev);
privateData->dwGeneration=2;
break;
default:
SMSC_TRACE(" LAN9112 Concord A1 identified (NEW), dwIdRev==0x%08lX",dwIdRev);
privateData->dwGeneration=2;
break;
};break;
case 0x118A0000UL:
switch(dwIdRev&0x0000FFFFUL) {
case 0UL:
SMSC_TRACE(" LAN9218 Boylston identified, dwIdRev==0x%08lX",dwIdRev);
privateData->dwGeneration=3;
break;
default:
SMSC_TRACE(" LAN9218 Boylston identified (NEW), dwIdRev==0x%08lX",dwIdRev);
privateData->dwGeneration=3;
break;
};break;
case 0x117A0000UL:
switch(dwIdRev&0x0000FFFFUL) {
case 0UL:
SMSC_TRACE(" LAN9217 Boylston identified, dwIdRev==0x%08lX",dwIdRev);
privateData->dwGeneration=3;
break;
default:
SMSC_TRACE(" LAN9217 Boylston identified (NEW), dwIdRev==0x%08lX",dwIdRev);
privateData->dwGeneration=3;
break;
};break;
case 0x116A0000UL:
switch(dwIdRev&0x0000FFFFUL) {
case 0UL:
SMSC_TRACE(" LAN9216 Boylston identified, dwIdRev==0x%08lX",dwIdRev);
privateData->dwGeneration=3;
break;
default:
SMSC_TRACE(" LAN9216 Boylston identified (NEW), dwIdRev==0x%08lX",dwIdRev);
privateData->dwGeneration=3;
break;
};break;
case 0x115A0000UL:
switch(dwIdRev&0x0000FFFFUL) {
case 0UL:
SMSC_TRACE(" LAN9215 Boylston identified, dwIdRev==0x%08lX",dwIdRev);
privateData->dwGeneration=3;
break;
default:
SMSC_TRACE(" LAN9215 Boylston identified (NEW), dwIdRev==0x%08lX",dwIdRev);
privateData->dwGeneration=3;
break;
};break;
}
dwFpgaRev=Lan_GetRegDW(FPGA_REV);
SMSC_TRACE(" FPGA_REV == 0x%08lX",dwFpgaRev);
ether_setup(dev);
dev->open= Smsc9118_open;
dev->stop= Smsc9118_stop;
dev->hard_start_xmit= Smsc9118_hard_start_xmit;
dev->get_stats= Smsc9118_get_stats;
dev->do_ioctl= Smsc9118_do_ioctl;
dev->set_multicast_list=Smsc9118_set_multicast_list;
dev->flags|=IFF_MULTICAST;
SET_MODULE_OWNER(dev);
privateData->dwIdRev=dwIdRev;
privateData->dwFpgaRev=dwFpgaRev&(0x000000FFUL);
privateData->dev=dev;
sprintf(privateData->ifName,"%s",dev->name);
result=0;
DONE:
if(result!=0) {
if(dev!=NULL) {
if(dev->priv!=NULL) {
if(platformInitialized) {
Platform_CleanUp(platformData);
}
kfree(dev->priv);
dev->priv=NULL;
}
}
}
SMSC_TRACE("<--Smsc9118_init(), result=%d",result);
return result;
}
int Smsc9118_open(struct net_device *dev)
{
int i;
int result=-ENODEV;
PPRIVATE_DATA privateData=NULL;
PPLATFORM_DATA platformData=NULL;
BOOLEAN acquired_mem_region=FALSE;
BOOLEAN acquired_isr=FALSE;
SMSC_TRACE("-->Smsc9118_open(dev=0x%08lX)",(DWORD)dev);
if(dev==NULL) {
SMSC_WARNING("Smsc9118_open(dev==NULL)");
result=-EFAULT;
goto DONE;
}
privateData=(PPRIVATE_DATA)(dev->priv);
if(privateData==NULL) {
SMSC_WARNING("Smsc9118_open(privateData==NULL)");
result=-EFAULT;
goto DONE;
}
platformData=&(privateData->PlatformData);
for (i = 0; i < GPT_SCHEDULE_DEPTH; i++) {
privateData->GptFunction [i] = NULL;
}
privateData->Gpt_scheduled_slot_index = GPT_SCHEDULE_DEPTH;
//get memory region
if(check_mem_region(privateData->dwLanBase,LAN_REGISTER_EXTENT)!=0)
{
SMSC_WARNING("Device memory is already in use.");
result=-ENOMEM;
goto DONE;
}
request_mem_region(privateData->dwLanBase,LAN_REGISTER_EXTENT,"SMSC_LAN9118");
acquired_mem_region=TRUE;
//initialize the LAN9118
{
DWORD dwIntCfg=0;
if(irq_pol) {
dwIntCfg|=INT_CFG_IRQ_POL_;
}
if(irq_type) {
dwIntCfg|=INT_CFG_IRQ_TYPE_;
}
if(!Lan_Initialize(privateData,dwIntCfg,tx_fif_sz,afc_cfg))
{
SMSC_WARNING("Failed Lan_Initialize");
result=-ENODEV;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -