📄 w90p710_mac.c
字号:
netif_wake_queue(dev);
TRACE_ERROR("queue restart TDU\n");
}
}
TRACE("After %d tx_interrupt status %x \n",which,status);
}
volatile unsigned long rx_jiffies0=0;
volatile unsigned long rx_jiffies1=0;
extern volatile unsigned long jiffies;
static void rx_interrupt(int irq, void *dev_id, struct pt_regs * regs)
{
struct net_device *dev = (struct net_device *)dev_id;
struct p710_priv *priv = (struct p710_priv *) dev->priv;
unsigned long status;
int which=priv->which;
unsigned long flags;
if(which==0)
rx_jiffies0 = jiffies;
else if(which==1)
rx_jiffies1 = jiffies;
status=p710_ReadReg(MISTA,which); //get interrupt status;
save_flags(flags); cli();
//p710_WriteReg(MISTA,status&0xFFFF,which); //clear interrupt
p710_WriteReg(MISTA,status,which); //clear interrupt
restore_flags(flags);
priv->cur_rx_entry++;
if(status & (MISTA_RDU|MISTA_RxBErr))
{
//printk("No Descript available\n");
priv->is_rx_all=RX_DESC_SIZE; //receive all
netdev_rx(dev); //start doing
priv->is_rx_all=0;
if(status&MISTA_RxBErr)
{
printk("MISTA_RxBErr\n");
ResetMAC(dev);
}
p710_WriteReg(RSDR ,0,which);
TRACE("* %d rx_interrupt MISTA %x \n",irq,status);
return ;
}
save_flags(flags); cli();
p710_WriteReg(MISTA,status,which); //clear interrupt
restore_flags(flags);
netdev_rx(dev);
}
void ResetMACRx(struct net_device * dev)
{
struct p710_priv * priv=(struct p710_priv *)dev->priv;
unsigned long val=p710_ReadReg(MCMDR,priv->which);
//printk("In ResetMAC Rx \n");
ResetRxRing(dev->priv);
p710_WriteReg(MCMDR,(MCMDR_RXON|val),priv->which);
}
void ResetMACTx(struct net_device * dev)
{
struct p710_priv * priv=(struct p710_priv *)dev->priv;
unsigned long val=p710_ReadReg(MCMDR,priv->which);
printk("In ResetMAC Tx \n");
//ResetTxRing(dev->priv);
p710_WriteReg(MCMDR,(MCMDR_TXON|val),priv->which);
}
void ResetRxRing(struct p710_priv * p710_priv)
{
int i;
for( i =0 ; i < RX_DESC_SIZE ; i++)
{
p710_priv->rx_desc[i].SL=0;
p710_priv->rx_desc[i].SL|=RXfOwnership_DMA;
}
}
#if 0
void DescriptorLock(struct p710_priv * priv)
{
unsigned long flags;
save_flags(flags); cli();
if(priv->lock==1)
while(priv->lock==1);
priv->lock=1;
restore_flags(flags);
}
void DescriptorUnLock(struct p710_priv * priv)
{
unsigned long flags;
save_flags(flags); cli();
priv->lock=0;
restore_flags(flags);
}
/*0:failed,1:success*/
int DescriptorTryLock(struct p710_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 p710_priv * priv = (struct p710_priv *)dev->priv;
RXBD *rxbd;
unsigned long length;
unsigned long status;
int flag=0;
rxbd=(RXBD *)priv->rx_ptr ;
do
{
if(priv->is_rx_all>0)
{
flag=1;
--priv->is_rx_all;
}
else if(flag==1)
{
flag=0;
break;
}
else if((p710_ReadReg(CRXDSA,priv->which)==(unsigned long)rxbd))
{
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;
data = (unsigned char *) rxbd->buffer;
skb = dev_alloc_skb(length+2); //Get Skb Buffer;
if(!skb) {
TRACE_ERROR("W90P710: 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("W90P710 MAC: Receive Runt Packet Drop it!\n");
priv->stats.rx_length_errors++;
}
if(status & RXDS_CRCE )
{
TRACE_ERROR("W90P710 MAC Receive CRC Packet Drop It! \n");
priv->stats.rx_crc_errors ++;
}
if(status & RXDS_ALIE )
{
TRACE_ERROR("W90P710 MAC Receive Aligment Packet Dropt It!\n");
priv->stats.rx_frame_errors++;
}
if(status & RXDS_PTLE)
{
TRACE_ERROR("W90P710 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 p710_set_multicast_list(struct net_device *dev)
{
struct p710_priv *priv = (struct p710_priv *)dev->priv;
unsigned long rx_mode;
//printk("p710_set_multicast_list\n");
int which=priv->which;
if(dev->flags&IFF_PROMISC)
{
rx_mode = CAMCMR_AUP|CAMCMR_AMP|CAMCMR_ABP|CAMCMR_ECMP;
TRACE("W90P710 : 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("W90P710 :Set Compare Flag\n");
}
//rx_mode=CAMCMR_AMP|CAMCMR_ABP|CAMCMR_ECMP;//|CAMCMR_AUP;
priv->rx_mode=rx_mode;
p710_WriteReg(CAMCMR,rx_mode,which);
}
#define SIODEVSTARTNATA 0x6677
#define SIODEVSTARTNATA 0x6688
static int p710_do_ioctl(struct net_device *dev,struct ifreq *ifr,int cmd)
{
//u16 *data = (u16 *)&ifr->ifr_data;
struct p710_priv *priv=dev->priv;
int which = priv->which;
printk("W90P710 IOCTL:\n");
switch(cmd)
{
case SIOCSIFHWADDR:
if(dev->flags&IFF_PROMISC)
return -1;
memcpy(dev->dev_addr,ifr->ifr_hwaddr.sa_data,ETH_ALEN);
memcpy(p710_mac_address0,dev->dev_addr,ETH_ALEN);
p710_set_mac_address(dev,dev->dev_addr);
break;
#define SIOCp710MACDEGUG SIOCDEVPRIVATE+1
case SIOCp710MACDEGUG : //For Debug;
output_register_context(which);
break;
default:
return -EOPNOTSUPP;
}
return 0;
}
void output_register_context(int which)
{
printk(" ** W90P710 EMC Register %d **\n",which);
printk("CAMCMR:%x ",p710_ReadReg(CAMCMR,which));
printk("CAMEN:%x ",p710_ReadReg(CAMEN,which));
printk("MIEN: %x ",p710_ReadReg(MIEN,which));
printk("MCMDR: %x ",p710_ReadReg(MCMDR,which));
printk("MISTA: %x ",p710_ReadReg(MISTA,which));
printk("TXDLSA:%x ", p710_ReadReg(TXDLSA,which));
printk("RXDLSA:%x \n", p710_ReadReg(RXDLSA,which));
printk("DMARFC:%x ", p710_ReadReg(DMARFC,which));
printk("TSDR:%x ", p710_ReadReg(TSDR,which));
printk("RSDR:%x ", p710_ReadReg(RSDR,which));
printk("FIFOTHD:%x ", p710_ReadReg(FIFOTHD,which));
printk("MISTA:%x ", p710_ReadReg(MISTA,which));
printk("MGSTA:%x ", p710_ReadReg(MGSTA,which));
printk("CTXDSA:%x \n",p710_ReadReg(CTXDSA,which));
printk("CTXBSA:%x ",p710_ReadReg(CTXBSA,which));
printk("CRXDSA:%x ", p710_ReadReg(CRXDSA,which));
printk("CRXBSA:%x ", p710_ReadReg(CRXBSA,which));
printk("RXFSM:%x ",p710_ReadReg(RXFSM,which));
printk("TXFSM:%x ",p710_ReadReg(TXFSM,which));
printk("FSM0:%x ",p710_ReadReg(FSM0,which));
printk("FSM1:%x \n",p710_ReadReg(FSM1,which));
}
void ShowDescriptor(struct net_device *dev)
{
int i;
struct p710_priv * p710_priv=dev->priv;
for(i=0;i<TX_DESC_SIZE;i++)
printk("%x mode:%lx,2 SL:%lx\n",&p710_priv->tx_desc[i],p710_priv->tx_desc[i].mode,p710_priv->tx_desc[i].SL);
for(i=0;i<RX_DESC_SIZE;i++)
printk("%x SL:%x\n",&p710_priv->rx_desc[i],p710_priv->rx_desc[i].SL);
printk("tx_ptr:%x,tx_entry:%d\n",p710_priv->tx_ptr,p710_priv->cur_tx_entry);
printk("rx_ptr:%x\n",p710_priv->rx_ptr);
return;
}
int prossess_nata(struct net_device *dev,RXBD * rxbd )
{
return 1;
}
int send_frame(struct net_device *dev ,unsigned char *data,int length)
{
struct p710_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=p710_ReadReg(MCMDR,which);
if(!(val& MCMDR_TXON))
{
//printk("****p710_WriteReg(MCMDR\n");
p710_WriteReg(MCMDR,val|MCMDR_TXON,which);
}
p710_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 MAC_ADDR 0x7F010008
static int p710_init(struct net_device *dev)
{
static int which=0;//Only one mac for W90P710
struct p710_priv *priv;
printk("01 %s initial ok!\n",dev->name);
printk("which:%d\n",which);
//*((unsigned volatile int *) 0xFFF83020) = 0x55555;//lsshi GPIO to PHY
ether_setup(dev);
dev->open=p710_open;
dev->stop=p710_close;
dev->do_ioctl=p710_do_ioctl;
dev->hard_start_xmit=p710_start_xmit;
dev->tx_timeout=p710_timeout;
dev->get_stats=p710_get_stats;
dev->watchdog_timeo =TX_TIMEOUT;
dev->irq=INT_EMCTXINT0+which;
dev->set_multicast_list=p710_set_multicast_list;
dev->set_mac_address=p710_set_mac_address;
dev->priv =(void *)(((unsigned long) kmalloc(sizeof(struct p710_priv),GFP_KERNEL))|NON_CACHE_FLAG);
if(dev->priv == NULL)
return -ENOMEM;
memset(dev->priv, 0, sizeof(struct p710_priv));
#ifdef CONFIG_WBFLASH
//if( info.type == BOOTLOADER_INFO )
memcpy(p710_mac_address0,(char*)(MAC_ADDR),ETH_ALEN);
#endif
memcpy(dev->dev_addr,p710_mac_address0,ETH_ALEN);
priv=(struct p710_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;
#ifdef CONFIG_W90P710FLASH
GetLoadImage();
#endif
memset((void *)p710_netdevice[0].name ,0 ,IFNAMSIZ);
ret=register_netdev((struct net_device *)&p710_netdevice[0]);
if(ret!=0)
{
TRACE_ERROR("Regiter EMC 0 W90P710 FAILED\n");
return -ENODEV;
}
return 0;
}
void cleanup_module(void)
{
unregister_netdev((struct net_device *)&p710_netdevice[0]);
}
module_init(init_module);
module_exit(cleanup_module);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -