📄 w740mac.c
字号:
{
unsigned long flags;
save_flags(flags); cli();
if(priv->lock==1)
while(priv->lock==1);
priv->lock=1;
restore_flags(flags);
}
void DescriptorUnLock(struct w740_priv * priv)
{
unsigned long flags;
save_flags(flags); cli();
priv->lock=0;
restore_flags(flags);
}
/*0:failed,1:success*/
int DescriptorTryLock(struct w740_priv * priv)
{
unsigned long flags;
save_flags(flags); cli();
if(priv->lock)
return 0;
priv->lock=1;
restore_flags(flags);
return 1;
}
#endif
/* We have a good packet(s), get it/them out of the buffers. */
static void netdev_rx(struct net_device *dev)
{
struct w740_priv * priv = (struct w740_priv *)dev->priv;
RXBD *rxbd;
unsigned long length;
unsigned long status;
int flag=0;
rxbd=(RXBD *)priv->rx_ptr ;
do
{
#if 0
if(!priv->is_rx_all&&(w740_ReadReg(CRXDSA,priv->which)==(unsigned long)rxbd))
{
break;
}
priv->is_rx_all = 0;
#endif
if(priv->is_rx_all>0)
{
flag=1;
--priv->is_rx_all;
}
else if(flag==1)
{
flag=0;
break;
}
else if(((w740_ReadReg(CRXDSA,priv->which)==(unsigned long)rxbd)||(rxbd->SL & RXfOwnership_NAT)))
{
break;
}
/* if(!(rxbd->SL & RXfOwnership_CPU))
{
if(priv->is_rx_all)
rxbd->SL |=RXfOwnership_DMA;
priv->rx_ptr=( RXBD *)rxbd->next;
rxbd=priv->rx_ptr;
continue;
}
*/
length = rxbd->SL & 0xFFFF;
status = (rxbd->SL & 0xFFFF0000)&((unsigned long)~0 >>2);
if(status & RXDS_RXGD)
{
unsigned char * data;
struct sk_buff * skb;
//When NATA Hit ,Transmit it derictly
#ifdef WINBOND_NATA
if(status & (RXDS_NATFSH|RXDS_Hit))
{
TRACE("NATA Hit");
//if(prossess_nata(dev,(unsigned char *) rxbd->buffer))
continue;
}
#endif //end WINBOND_NATA
#if 0
if(which==1)
printk("****Good****\n");
#endif
data = (unsigned char *) rxbd->buffer;
skb = dev_alloc_skb(length+2); //Get Skb Buffer;
if(!skb) {
TRACE_ERROR("W90N740: I Have Not Got Memory In Fun %s\n",__FUNCTION__);
priv->stats.rx_dropped++;
return;
}
skb->dev = dev;
skb_reserve(skb, 2); //For IP Align 4-byte
skb_put(skb, length);
eth_copy_and_sum(skb, data, length, 0); //copy
skb->protocol = eth_type_trans(skb, dev);
priv->stats.rx_packets++;
priv->stats.rx_bytes += length;
netif_rx(skb); // Enqueue for Up Layer
}
else
{
if(priv->is_rx_all==RX_DESC_SIZE)
TRACE_ERROR("Rx error:%x,rxbd:%x,priv->is_rx_all:%d\n",status,rxbd,priv->is_rx_all);
priv->stats.rx_errors++;
if(status & RXDS_RP )
{
TRACE_ERROR("W90N740 MAC: Receive Runt Packet Drop it!\n");
priv->stats.rx_length_errors++;
}
if(status & RXDS_CRCE )
{
TRACE_ERROR("W90N740 MAC Receive CRC Packet Drop It! \n");
priv->stats.rx_crc_errors ++;
}
if(status & RXDS_ALIE )
{
TRACE_ERROR("W90N740 MAC Receive Aligment Packet Dropt It!\n");
priv->stats.rx_frame_errors++;
}
if(status & RXDS_PTLE)
{
TRACE_ERROR("W90N740 MAC Receive Too Long Packet Dropt It!\n");
priv->stats.rx_over_errors++;
}
}
//rxbd->SL= RX_OWNERSHIP_DMA; //clear status and set dma flag
rxbd->SL =RXfOwnership_DMA;
rxbd->reserved = 0;
priv->rx_ptr=(unsigned long)rxbd->next;
rxbd=(RXBD *)priv->rx_ptr;
dev->last_rx = jiffies;
}while(1);
priv->is_rx_all = 0;
}
static void w740_set_multicast_list(struct net_device *dev)
{
struct w740_priv *priv = (struct w740_priv *)dev->priv;
unsigned long rx_mode;
//printk("w740_set_multicast_list\n");
int which=priv->which;
if(dev->flags&IFF_PROMISC)
{
rx_mode = CAMCMR_AUP|CAMCMR_AMP|CAMCMR_ABP|CAMCMR_ECMP;
TRACE("W90N740 : Set Prommisc Flag \n");
}
else if((dev->flags&IFF_ALLMULTI)||dev->mc_list)
{
rx_mode=CAMCMR_AMP|CAMCMR_ABP|CAMCMR_ECMP;
}
else
{
rx_mode = CAMCMR_ECMP|CAMCMR_ABP;
TRACE("W90N740 :Set Compare Flag\n");
}
//rx_mode=CAMCMR_AMP|CAMCMR_ABP|CAMCMR_ECMP;//|CAMCMR_AUP;
priv->rx_mode=rx_mode;
w740_WriteReg(CAMCMR,rx_mode,which);
}
#define SIODEVSTARTNATA 0x6677
#define SIODEVSTARTNATA 0x6688
static int w740_do_ioctl(struct net_device *dev,struct ifreq *ifr,int cmd)
{
//u16 *data = (u16 *)&ifr->ifr_data;
struct w740_priv *priv=dev->priv;
int which = priv->which;
printk("W90N740 IOCTL:\n");
switch(cmd)
{
case SIOCSIFHWADDR:
if(dev->flags&IFF_PROMISC)
return -1;
memcpy(dev->dev_addr,ifr->ifr_hwaddr.sa_data,ETH_ALEN);
if(which)
memcpy(w740_mac_address1,dev->dev_addr,ETH_ALEN);
else
memcpy(w740_mac_address0,dev->dev_addr,ETH_ALEN);
w740_set_mac_address(dev,dev->dev_addr);
break;
#define SIOCW740MACDEGUG SIOCDEVPRIVATE+1
case SIOCW740MACDEGUG : //For Debug;
output_register_context(which);
break;
default:
return -EOPNOTSUPP;
}
return 0;
}
void output_register_context(int which)
{
printk(" ** W90N740 EMC Register %d **\n",which);
printk("CAMCMR:%x ",w740_ReadReg(CAMCMR,which));
printk("CAMEN:%x ",w740_ReadReg(CAMEN,which));
printk("MIEN: %x ",w740_ReadReg(MIEN,which));
printk("MCMDR: %x ",w740_ReadReg(MCMDR,which));
printk("MISTA: %x ",w740_ReadReg(MISTA,which));
printk("TXDLSA:%x ", w740_ReadReg(TXDLSA,which));
printk("RXDLSA:%x \n", w740_ReadReg(RXDLSA,which));
printk("DMARFC:%x ", w740_ReadReg(DMARFC,which));
printk("TSDR:%x ", w740_ReadReg(TSDR,which));
printk("RSDR:%x ", w740_ReadReg(RSDR,which));
printk("FIFOTHD:%x ", w740_ReadReg(FIFOTHD,which));
printk("MISTA:%x ", w740_ReadReg(MISTA,which));
printk("MGSTA:%x ", w740_ReadReg(MGSTA,which));
printk("CTXDSA:%x \n",w740_ReadReg(CTXDSA,which));
printk("CTXBSA:%x ",w740_ReadReg(CTXBSA,which));
printk("CRXDSA:%x ", w740_ReadReg(CRXDSA,which));
printk("CRXBSA:%x ", w740_ReadReg(CRXBSA,which));
printk("RXFSM:%x ",w740_ReadReg(RXFSM,which));
printk("TXFSM:%x ",w740_ReadReg(TXFSM,which));
printk("FSM0:%x ",w740_ReadReg(FSM0,which));
printk("FSM1:%x \n",w740_ReadReg(FSM1,which));
#if 0
printk("EMC01 :\n");
printk("MCMDR: %x ",w740_ReadReg(MCMDR,1));
printk("MISTA: %x ",w740_ReadReg(MISTA,1));
printk("RXDLSA:%x ", w740_ReadReg(RXDLSA,1));
printk("CTXDSA:%x \n",w740_ReadReg(CTXDSA,1));
#endif
}
void ShowDescriptor(struct net_device *dev)
{
int i;
struct w740_priv * w740_priv=dev->priv;
for(i=0;i<TX_DESC_SIZE;i++)
printk("%x mode:%lx,2 SL:%lx\n",&w740_priv->tx_desc[i],w740_priv->tx_desc[i].mode,w740_priv->tx_desc[i].SL);
for(i=0;i<RX_DESC_SIZE;i++)
printk("%x SL:%x\n",&w740_priv->rx_desc[i],w740_priv->rx_desc[i].SL);
printk("tx_ptr:%x,tx_entry:%d\n",w740_priv->tx_ptr,w740_priv->cur_tx_entry);
printk("rx_ptr:%x\n",w740_priv->rx_ptr);
return;
}
int prossess_nata(struct net_device *dev,RXBD * rxbd )
{
#if 0
struct net_device which_dev;
struct w740_priv *priv;
int lenght=rxbd->SL&0xFFFF;
int which=(priv->which==0);
which_dev=&w740_netdevice[which];
notify_hit(dev,rxbd);
send_frame(which_dev,(unsigned char * ) rxbd->buffer,length);
#endif
return 1;
}
int send_frame(struct net_device *dev ,unsigned char *data,int length)
{
struct w740_priv * priv= dev->priv;
int which;
TXBD *txbd;
unsigned long flags;
which=priv->which;
//if (!down_trylock(&priv->locksend)) {
txbd=( TXBD *)priv->tx_ptr;
//Have a Descriptor For Transmition?
/*
if((txbd->mode&TXfOwnership_DMA))
{
TRACE_ERROR("send_frame failed\n");
netif_stop_queue(dev);
return -1;
}
*/
//txbd->mode=(TX_OWNERSHIP_DMA|TX_MODE_PAD|TX_MODE_CRC|TX_MODE_IE);
//Check Frame Length
if(length>1514)
{
TRACE(" Send Data %d Bytes ,Please Recheck Again\n",length);
length=1514;
}
txbd->SL=length&0xFFFF;
memcpy((void *)txbd->buffer,data,length);
txbd->mode=(PaddingMode | CRCMode | MACTxIntEn);
txbd->mode|= TXfOwnership_DMA;
{
int val=w740_ReadReg(MCMDR,which);
if(!(val& MCMDR_TXON))
{
//printk("****w740_WriteReg(MCMDR\n");
w740_WriteReg(MCMDR,val|MCMDR_TXON,which);
}
w740_WriteReg(TSDR ,0,which);
}
txbd=(TXBD *)txbd->next;
priv->tx_ptr=(unsigned long)txbd;
dev->trans_start=jiffies;
save_flags(flags); cli();
if(txbd->mode&TXfOwnership_DMA)
netif_stop_queue(dev);
restore_flags(flags);
return 0;
}
void notify_hit(struct net_device *dev ,RXBD *rxbd)
{
TRACE("notify_hit not implement\n");
}
#define MAC0_ADDR 0x7F010008
#define MAC1_ADDR 0x7F010014
static int w740_init(struct net_device *dev)
{
static int which=1;
struct w740_priv *priv;
printk("01 %s initial ok!\n",dev->name);
//if( w740_netdevice[0].name[0]=='\0')
if(dev==&w740_netdevice[0])
which=0;
else
which=1;
printk("which:%d\n",which);
ether_setup(dev);
dev->open=w740_open;
dev->stop=w740_close;
dev->do_ioctl=w740_do_ioctl;
dev->hard_start_xmit=w740_start_xmit;
dev->tx_timeout=w740_timeout;
dev->get_stats=w740_get_stats;
dev->watchdog_timeo =TX_TIMEOUT;
dev->irq=13+which;
dev->set_multicast_list=w740_set_multicast_list;
dev->set_mac_address=w740_set_mac_address;
dev->priv =(void *)(((unsigned long) kmalloc(sizeof(struct w740_priv),GFP_KERNEL))|NON_CACHE_FLAG);
if(dev->priv == NULL)
return -ENOMEM;
memset(dev->priv, 0, sizeof(struct w740_priv));
if(which)
{
//if( info.type == BOOTLOADER_INFO )
memcpy(w740_mac_address1,(char*)(MAC1_ADDR),ETH_ALEN);
memcpy(dev->dev_addr,w740_mac_address1,ETH_ALEN);
}
else
{
//if( info.type == BOOTLOADER_INFO )
memcpy(w740_mac_address0,(char*)(MAC0_ADDR),ETH_ALEN);
memcpy(dev->dev_addr,w740_mac_address0,ETH_ALEN);
}
priv=(struct w740_priv *)dev->priv;
priv->which=which;
priv->cur_tx_entry=0;
priv->cur_rx_entry=0;
TRACE("%s initial ok!\n",dev->name);
return 0;
}
int init_module(void)
{
int ret;
memset((void *)w740_netdevice[0].name ,0 ,IFNAMSIZ);
ret=register_netdev((struct net_device *)&w740_netdevice[0]);
if(ret!=0)
{
TRACE_ERROR("Regiter EMC 0 W90N740 FAILED\n");
return -ENODEV;
}
memset((void*)w740_netdevice[1].name ,0 ,IFNAMSIZ);
ret=register_netdev((struct net_device *)&w740_netdevice[1]);
if(ret!=0)
{
TRACE_ERROR("Regiter EMC 1 W90N740 FAILED\n");
return -ENODEV;
}
return 0;
}
void cleanup_module(void)
{
unregister_netdev((struct net_device *)&w740_netdevice[0]);
unregister_netdev((struct net_device *)&w740_netdevice[1]);
}
module_init(init_module);
module_exit(cleanup_module);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -