📄 smsc911x.c
字号:
privateData->RxDmaChReserved=TRUE;
}
}
privateData->TxDmaChReserved=FALSE;
if(tx_dma==TRANSFER_REQUEST_DMA) {
dwTxDmaCh=Platform_RequestDmaChannel(&(privateData->PlatformData));
SMSC_ASSERT(dwTxDmaCh!=TRANSFER_REQUEST_DMA);
if(dwTxDmaCh<TRANSFER_REQUEST_DMA) {
privateData->TxDmaChReserved=TRUE;
}
}
Tx_Initialize(privateData,dwTxDmaCh,dma_threshold);
Rx_Initialize(privateData,dwRxDmaCh,dma_threshold);
}
#ifndef LINUX_2_6_OR_NEWER
MOD_INC_USE_COUNT;
#endif
privateData->Running=TRUE;
netif_start_queue(dev);
Tx_StopQueue(privateData,0x01UL);
spin_lock_init(&(privateData->GpTimerLock));
Lan_EnableInterrupt(privateData,INT_EN_GPT_INT_EN_);
result=0;
DONE:
if(result!=0) {
#ifndef LINUX_2_6_OR_NEWER
MOD_DEC_USE_COUNT;
#endif
if(privateData!=NULL) {
if(privateData->TxDmaChReserved) {
Platform_ReleaseDmaChannel(platformData,
privateData->dwTxDmaCh);
privateData->TxDmaChReserved=FALSE;
}
if(privateData->RxDmaChReserved) {
Platform_ReleaseDmaChannel(platformData,
privateData->dwRxDmaCh);
privateData->RxDmaChReserved=FALSE;
}
if(acquired_isr) {
Platform_FreeIRQ(platformData);
}
if(acquired_mem_region) {
release_mem_region(
privateData->dwLanBase,
LAN_REGISTER_EXTENT);
}
}
}
SMSC_TRACE("<--Smsc911x_open, result=%d",result);
return result;
}
int Smsc911x_stop(struct net_device *dev)
{
int result=0;
PPRIVATE_DATA privateData=NULL;
SMSC_TRACE("-->Smsc911x_stop(dev=0x%08lX)",(DWORD)dev);
if(dev==NULL) {
SMSC_WARNING("Smsc911x_stop(dev==NULL)");
result=-EFAULT;
goto DONE;
}
privateData=(PPRIVATE_DATA)(dev->priv);
if(privateData==NULL) {
SMSC_WARNING("Smsc911x_stop(privateData==NULL)");
result=-EFAULT;
goto DONE;
}
privateData->StopLinkPolling=TRUE;
del_timer_sync(&(privateData->LinkPollingTimer));
Lan_DisableInterrupt(privateData,INT_EN_GPT_INT_EN_);
Tx_UpdateTxCounters(privateData);
privateData->Running=FALSE;
Lan_DisableIRQ(privateData);
Tx_CompleteDma(privateData);
Tx_StopQueue(privateData,0x01UL);
#ifndef LINUX_2_6_OR_NEWER
MOD_DEC_USE_COUNT;
#endif
if(privateData->TxDmaChReserved) {
Platform_ReleaseDmaChannel(
&(privateData->PlatformData),
privateData->dwTxDmaCh);
privateData->TxDmaChReserved=FALSE;
}
if(privateData->RxDmaChReserved) {
Platform_ReleaseDmaChannel(
&(privateData->PlatformData),
privateData->dwRxDmaCh);
privateData->RxDmaChReserved=FALSE;
}
Platform_FreeIRQ(&(privateData->PlatformData));
release_mem_region(privateData->dwLanBase,LAN_REGISTER_EXTENT);
{
const DWORD dwLanBase=privateData->dwLanBase;
const DWORD dwIdRev=privateData->dwIdRev;
const DWORD dwFpgaRev=privateData->dwFpgaRev;
struct net_device * const tempDev=privateData->dev;
char ifName[SMSC_IF_NAME_SIZE];
memcpy(ifName,privateData->ifName,SMSC_IF_NAME_SIZE);
memset(privateData,0,sizeof(PRIVATE_DATA));
privateData->dwLanBase=dwLanBase;
privateData->dwIdRev=dwIdRev;
privateData->dwFpgaRev=dwFpgaRev;
privateData->dev=tempDev;
memcpy(privateData->ifName,ifName,SMSC_IF_NAME_SIZE);
}
DONE:
SMSC_TRACE("<--Smsc911x_stop, result=%d",result);
return result;
}
int Smsc911x_hard_start_xmit(
struct sk_buff *skb, struct net_device * const dev)
{
int result=0;
PPRIVATE_DATA privateData=NULL;
// SMSC_TRACE("-->Smsc911x_hard_start_xmit(skb=0x%08lX,dev=0x%08lX)",(DWORD)skb,(DWORD)dev);
if(skb==NULL) {
SMSC_WARNING("Smsc911x_hard_start_xmit(skb==NULL)");
result=-EFAULT;
goto DONE;
}
if(dev==NULL) {
SMSC_WARNING("Smsc911x_hard_start_xmit(dev==NULL)");
result=-EFAULT;
goto DONE;
}
if(dev->priv==NULL) {
SMSC_WARNING("Smsc911x_hard_start_xmit(dev->priv==NULL)");
result=-EFAULT;
goto DONE;
}
privateData=(PPRIVATE_DATA)(dev->priv);
// SET_GPIO(GP_TX);
Tx_SendSkb(privateData,skb);
// CLEAR_GPIO(GP_TX);
DONE:
// SMSC_TRACE("<--Smsc911x_hard_start_xmit, result=%d",result);
return result;
}
struct net_device_stats * Smsc911x_get_stats(struct net_device * const dev)
{
PPRIVATE_DATA privateData=NULL;
if(dev==NULL) {
SMSC_WARNING("Smsc911x_get_stats(dev==NULL)");
return NULL;
}
if(dev->priv==NULL) {
SMSC_WARNING("Smsc911x_get_stats(dev->priv==NULL)");
return NULL;
}
privateData=(PPRIVATE_DATA)(dev->priv);
if(privateData->Running) {
privateData->stats.rx_dropped+=Lan_GetRegDW(RX_DROP);
Tx_UpdateTxCounters(privateData);
}
return &(privateData->stats);
}
void Smsc911x_set_multicast_list(struct net_device *dev)
{
SMSC_ASSERT(dev!=NULL);
Rx_SetMulticastList(dev);
}
int Smsc911x_do_ioctl(
struct net_device *dev,
struct ifreq *ifr,
int cmd)
{
PPRIVATE_DATA privateData=NULL;
PSMSC911x_IOCTL_DATA ioctlData=NULL;
BOOLEAN success=FALSE;
// SMSC_TRACE("-->Smsc911x_do_ioctl");
// SMSC_TRACE("cmd=%d,SIOCGMIIPHY=%d,SIOCDEVPRIVATE=%d",
// cmd,SIOCGMIIPHY,SIOCDEVPRIVATE);
SMSC_ASSERT(dev!=NULL);
SMSC_ASSERT(dev->priv!=NULL);
privateData=((PPRIVATE_DATA)dev->priv);
if(ifr==NULL) {
// SMSC_WARNING("Smsc911x_do_ioctl(ifr==NULL)");
goto DONE;
}
if(privateData->LanInitialized) {
// standard MII IOC's
struct mii_ioctl_data * const data=
(struct mii_ioctl_data *) & ifr->ifr_data;
switch(cmd) {
case SIOCGMIIPHY:
case SIOCDEVPRIVATE:
data->phy_id=1;
// SMSC_TRACE("SIOCGMIIPHY: phy_id set to 0x%04X",data->phy_id);
return 0;
case SIOCGMIIREG:
case SIOCDEVPRIVATE+1:
{
DWORD dwIntFlags=0;
VL_KEY keyCode=Vl_WaitForLock(&(privateData->MacPhyLock),&dwIntFlags);
data->val_out=Phy_GetRegW(
privateData,data->reg_num,keyCode);
Vl_ReleaseLock(&(privateData->MacPhyLock),keyCode,&dwIntFlags);
}
// SMSC_TRACE("SIOCGMIIREG: phy_id=0x%04X, reg_num=0x%04X, val_out set to 0x%04X",
// data->phy_id,data->reg_num,data->val_out);
return 0;
case SIOCSMIIREG:
case SIOCDEVPRIVATE+2:
// SMSC_TRACE("SIOCSMIIREG: phy_id=0x%04X, reg_num=0x%04X, val_in=0x%04X",
// data->phy_id,data->reg_num,data->val_in);
{
DWORD dwIntFlags=0;
VL_KEY keyCode=Vl_WaitForLock(&(privateData->MacPhyLock),&dwIntFlags);
Phy_SetRegW(
privateData,data->reg_num,((WORD)(data->val_in)),keyCode);
Vl_ReleaseLock(&(privateData->MacPhyLock),keyCode,&dwIntFlags);
}
return 0;
default:break;//make lint happy
}
}
if(ifr->ifr_data==NULL) {
// SMSC_WARNING("Smsc911x_do_ioctl(ifr->ifr_data==NULL)");
goto DONE;
}
if(cmd!=((int)SMSC911x_IOCTL)) goto DONE;
ioctlData=(PSMSC911x_IOCTL_DATA)(ifr->ifr_data);
if(ioctlData->dwSignature!=SMSC911x_APP_SIGNATURE) {
goto DONE;
}
switch(ioctlData->dwCommand) {
case COMMAND_GET_SIGNATURE:
success=TRUE;
break;
case COMMAND_GET_FLOW_PARAMS:
ioctlData->Data[0]=privateData->RxFlowMeasuredMaxThroughput;
ioctlData->Data[1]=privateData->RxFlowMeasuredMaxPacketCount;
ioctlData->Data[2]=privateData->RxFlowParameters.MaxThroughput;
ioctlData->Data[3]=privateData->RxFlowParameters.MaxPacketCount;
ioctlData->Data[4]=privateData->RxFlowParameters.PacketCost;
ioctlData->Data[5]=privateData->RxFlowParameters.BurstPeriod;
ioctlData->Data[6]=privateData->RxFlowMaxWorkLoad;
ioctlData->Data[7]=Lan_GetRegDW(INT_CFG)>>24;
privateData->RxFlowMeasuredMaxThroughput=0;
privateData->RxFlowMeasuredMaxPacketCount=0;
success=TRUE;
break;
case COMMAND_SET_FLOW_PARAMS:
if(!(privateData->RxFlowControlActive)) {
privateData->RxFlowParameters.MaxThroughput=ioctlData->Data[2];
privateData->RxFlowParameters.MaxPacketCount=ioctlData->Data[3];
privateData->RxFlowParameters.PacketCost=ioctlData->Data[4];
privateData->RxFlowParameters.BurstPeriod=ioctlData->Data[5];
if(ioctlData->Data[6]==0xFFFFFFFFUL) {
privateData->RxFlowMaxWorkLoad=
privateData->RxFlowParameters.MaxThroughput+
(privateData->RxFlowParameters.MaxPacketCount*
privateData->RxFlowParameters.PacketCost);
} else {
privateData->RxFlowMaxWorkLoad=ioctlData->Data[6];
}
Lan_SetIntDeas(privateData,ioctlData->Data[7]);
privateData->RxFlowBurstMaxWorkLoad=
(privateData->RxFlowMaxWorkLoad*
privateData->RxFlowParameters.BurstPeriod)/1000;
success=TRUE;
};break;
case COMMAND_GET_CONFIGURATION:
ioctlData->Data[0]=DRIVER_VERSION;
ioctlData->Data[1]=lan_base;
ioctlData->Data[2]=bus_width;
ioctlData->Data[3]=link_mode;
ioctlData->Data[4]=irq;
ioctlData->Data[5]=int_deas;
ioctlData->Data[6]=irq_pol;
ioctlData->Data[7]=irq_type;
ioctlData->Data[8]=rx_dma;
ioctlData->Data[9]=tx_dma;
ioctlData->Data[10]=dma_threshold;
ioctlData->Data[11]=mac_addr_hi16;
ioctlData->Data[12]=mac_addr_lo32;
ioctlData->Data[13]=debug_mode;
ioctlData->Data[14]=tx_fif_sz;
ioctlData->Data[15]=afc_cfg;
ioctlData->Data[16]=tasklets;
ioctlData->Data[17]=max_throughput;
ioctlData->Data[18]=max_packet_count;
ioctlData->Data[19]=packet_cost;
ioctlData->Data[20]=burst_period;
ioctlData->Data[21]=max_work_load;
ioctlData->Data[22]=privateData->dwIdRev;
ioctlData->Data[23]=privateData->dwFpgaRev;
ioctlData->Data[24]=1;
ioctlData->Data[25]=privateData->dwPhyId;
ioctlData->Data[26]=privateData->bPhyModel;
ioctlData->Data[27]=privateData->bPhyRev;
ioctlData->Data[28]=privateData->dwLinkSpeed;
ioctlData->Data[29]=privateData->RxFlowMeasuredMaxThroughput;
ioctlData->Data[30]=privateData->RxFlowMeasuredMaxPacketCount;
ioctlData->Data[31]=privateData->RxFlowParameters.MaxThroughput;
ioctlData->Data[32]=privateData->RxFlowParameters.MaxPacketCount;
ioctlData->Data[33]=privateData->RxFlowParameters.PacketCost;
ioctlData->Data[34]=privateData->RxFlowParameters.BurstPeriod;
ioctlData->Data[35]=privateData->RxFlowMaxWorkLoad;
sprintf(ioctlData->Strng1,"%s, %s",__DATE__,__TIME__);
sprintf(ioctlData->Strng2,"%s",privateData->ifName);
privateData->RxFlowMeasuredMaxThroughput=0;
privateData->RxFlowMeasuredMaxPacketCount=0;
success=TRUE;
break;
case COMMAND_LAN_GET_REG:
if((ioctlData->Data[0]<LAN_REGISTER_EXTENT)&&
((ioctlData->Data[0]&0x3UL)==0))
{
ioctlData->Data[1]=
(*((volatile DWORD *)(privateData->dwLanBase+
ioctlData->Data[0])));
success=TRUE;
} else {
SMSC_WARNING("Reading LAN911x Mem Map Failed");
goto MEM_MAP_ACCESS_FAILED;
}
break;
case COMMAND_LAN_SET_REG:
if((ioctlData->Data[0]<LAN_REGISTER_EXTENT)&&
((ioctlData->Data[0]&0x3UL)==0))
{
(*((volatile DWORD *)(privateData->dwLanBase+
ioctlData->Data[0])))=ioctlData->Data[1];
success=TRUE;
} else {
SMSC_WARNING("Reading LAN911x Mem Map Failed");
MEM_MAP_ACCESS_FAILED:
SMSC_WARNING(" Invalid offset == 0x%08lX",ioctlData->Data[0]);
if(ioctlData->Data[0]>=LAN_REGISTER_EXTENT) {
SMSC_WARNING(" Out of range");
}
if(ioctlData->Data[0]&0x3UL) {
SMSC_WARNING(" Not DWORD aligned");
}
}
break;
case COMMAND_MAC_GET_REG:
if((ioctlData->Data[0]<=0xC)&&(privateData->LanInitialized)) {
DWORD dwIntFlags=0;
VL_KEY keyCode=Vl_WaitForLock(&(privateData->MacPhyLock),&dwIntFlags);
ioctlData->Data[1]=
Mac_GetRegDW(privateData,ioctlData->Data[0],keyCode);
Vl_ReleaseLock(&(privateData->MacPhyLock),keyCode,&dwIntFlags);
success=TRUE;
} else {
SMSC_WARNING("Reading Mac Register Failed");
goto MAC_ACCESS_FAILURE;
}
break;
case COMMAND_MAC_SET_REG:
if((ioctlData->Data[0]<=0xC)&&(privateData->LanInitialized)) {
DWORD dwIntFlags=0;
VL_KEY keyCode=Vl_WaitForLock(&(privateData->MacPhyLock),&dwIntFlags);
Mac_SetRegDW(
privateData,
ioctlData->Data[0],
ioctlData->Data[1],
keyCode);
Vl_ReleaseLock(&(privateData->MacPhyLock),keyCode,&dwIntFlags);
success=TRUE;
} else {
SMSC_WARNING("Writing Mac Register Failed");
MAC_
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -