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

📄 w740mac.c

📁 华邦w740以太网驱动 mac driver
💻 C
📖 第 1 页 / 共 3 页
字号:
{
	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 + -