⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 w90p710_mac.c

📁 w90p710网卡驱动程序源码,工作环境uClinu下
💻 C
📖 第 1 页 / 共 3 页
字号:
			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 + -