Beispiel #1
0
void ether00_mem_update(void* dev_id)
{
	struct net_device* dev=dev_id;
	struct net_priv* priv=dev->priv;
	struct sk_buff* skb;
	struct tx_fda_ent *fda_ptr=priv->tx_fdalist_vp;
	struct rx_blist_ent* blist_ent_ptr;
	unsigned long flags;

	priv->tq_memupdate.sync=0;
	//priv->tq_memupdate.list=
	priv->memupdate_scheduled=0;

	/* Transmit interrupt */
	while(fda_ptr<(priv->tx_fdalist_vp+TX_NUM_FDESC)){
		if(!(FDCTL_COWNSFD_MSK&fda_ptr->fd.FDCtl) && (ETHER_TX_STAT_COMP_MSK&fda_ptr->fd.FDStat)){
			priv->stats.tx_packets++;
			priv->stats.tx_bytes+=fda_ptr->bd.BuffLength;
			skb=(struct sk_buff*)fda_ptr->fd.FDSystem;
			//printk("%d:txcln:fda=%#x skb=%#x\n",jiffies,fda_ptr,skb);
			dev_kfree_skb(skb);
			fda_ptr->fd.FDSystem=0;
			fda_ptr->fd.FDStat=0;
			fda_ptr->fd.FDCtl=0;
		}
		fda_ptr++;
	}
	/* Fill in any missing buffers from the received queue */
	spin_lock_irqsave(&priv->rx_lock,flags);
	blist_ent_ptr=priv->rx_blist_vp;
	while(blist_ent_ptr<(priv->rx_blist_vp+RX_NUM_BUFF)){
		/* fd.FDSystem of 0 indicates we failed to allocate the buffer in the ISR */
		if(!blist_ent_ptr->fd.FDSystem){
			struct sk_buff *skb;
			skb=dev_alloc_skb(PKT_BUF_SZ);
			blist_ent_ptr->fd.FDSystem=(unsigned int)skb;
			if(skb){
				setup_blist_entry(skb,blist_ent_ptr);
			}
			else
			{
				break;
			}
		}
		blist_ent_ptr++;
	}
	spin_unlock_irqrestore(&priv->rx_lock,flags);
	if(priv->queue_stopped){
		//printk("%d:cln:start q\n",jiffies);
		netif_start_queue(dev);
	}
	if(priv->rx_disabled){
		//printk("%d:enable_irq\n",jiffies);
		priv->rx_disabled=0;
		writel(ETHER_RX_CTL_RXEN_MSK,ETHER_RX_CTL(dev->base_addr));

	}
}
Beispiel #2
0
static void ether00_reset(struct net_device *dev)
{
	/* reset the controller */
	writew(ETHER_MAC_CTL_RESET_MSK,ETHER_MAC_CTL(dev->base_addr));

	/*
	 * Make sure we're not going to send anything
	 */

	writew(ETHER_TX_CTL_TXHALT_MSK,ETHER_TX_CTL(dev->base_addr));

	/*
	 * Make sure we're not going to receive anything
	 */
	writew(ETHER_RX_CTL_RXHALT_MSK,ETHER_RX_CTL(dev->base_addr));

	/*
	 * Disable Interrupts for now, and set the burst size to 8 bytes
	 */

	writel(ETHER_DMA_CTL_INTMASK_MSK |
	       ((8 << ETHER_DMA_CTL_DMBURST_OFST) & ETHER_DMA_CTL_DMBURST_MSK)
	       |(2<<ETHER_DMA_CTL_RXALIGN_OFST),
	       ETHER_DMA_CTL(dev->base_addr));


	/*
	 * Set TxThrsh - start transmitting a packet after 1514
	 * bytes or when a packet is complete, whichever comes first
	 */
	 writew(1514,ETHER_TXTHRSH(dev->base_addr));

	/*
	 * Set TxPollCtr.  Each cycle is
	 * 61.44 microseconds with a 33 MHz bus
	 */
	 writew(1,ETHER_TXPOLLCTR(dev->base_addr));

	/*
	 * Set Rx_Ctl - Turn off reception and let RxData turn it
	 * on later
	 */
	 writew(ETHER_RX_CTL_RXHALT_MSK,ETHER_RX_CTL(dev->base_addr));

}
Beispiel #3
0
void ether00_mem_update(void* dev_id)
{
	struct net_device* dev=dev_id;
	struct net_priv* priv=dev->priv;
	struct rx_blist_ent* blist_ent_ptr;
	unsigned long flags;
        int enable_rx = 0;

	priv->tq_memupdate.sync=0;
	priv->memupdate_scheduled=0;

	/* Fill in any missing buffers from the received queue */
	blist_ent_ptr=priv->rx_blist_vp;
	while(blist_ent_ptr<(priv->rx_blist_vp+RX_NUM_BUFF)){
		spin_lock_irqsave(&priv->dma_lock,flags);
		/* fd.FDSystem of 0 indicates we failed to allocate the buffer in the ISR */
		if(!blist_ent_ptr->fd.FDSystem){
			struct sk_buff *skb;
			skb=dev_alloc_skb(PKT_BUF_SZ);
			blist_ent_ptr->fd.FDSystem=(unsigned int)skb;
			if(skb){
				setup_blist_entry(skb,blist_ent_ptr);
                                enable_rx = 1;
			}
			else
			{
                                /*
                                 * reschedule the clean up, since we
                                 * didn't patch up all the buffers
                                 */

	                         if(!priv->memupdate_scheduled){
				   schedule_task(&priv->tq_memupdate);
				   priv->memupdate_scheduled=1;
				 }
		                 spin_unlock_irqrestore(&priv->dma_lock,flags);
				 break;
			}
		}
		spin_unlock_irqrestore(&priv->dma_lock,flags);
		blist_ent_ptr++;
	}

	if(enable_rx){
	  if (!priv->rx_disabled){
	        priv->rx_disabled = 0;
		writel(ETHER_RX_CTL_RXEN_MSK,ETHER_RX_CTL(dev->base_addr));
	  }
	}
}
Beispiel #4
0
static void ether00_int( int irq_num, void* dev_id, struct pt_regs* regs)
{
	struct net_device* dev=dev_id;
	struct net_priv* priv=dev->priv;

	unsigned int   interruptValue;

	interruptValue=readl(ETHER_INT_SRC(dev->base_addr));

	//printk("INT_SRC=%x\n",interruptValue);

	if(!(readl(ETHER_INT_SRC(dev->base_addr)) & ETHER_INT_SRC_IRQ_MSK))
	{
		return;		/* Interrupt wasn't caused by us!! */
	}

	if(readl(ETHER_INT_SRC(dev->base_addr))&
	   (ETHER_INT_SRC_INTMACRX_MSK |
	    ETHER_INT_SRC_FDAEX_MSK |
	    ETHER_INT_SRC_BLEX_MSK)) {
		struct rx_blist_ent* blist_ent_ptr;
		struct rx_fda_ent* fda_ent_ptr;
		struct sk_buff* skb;

		fda_ent_ptr=priv->rx_fda_ptr;
		spin_lock(&priv->rx_lock);
		while(fda_ent_ptr<(priv->rx_fda_ptr+RX_NUM_FDESC)){
			int result;

			if(!(fda_ent_ptr->fd.FDCtl&FDCTL_COWNSFD_MSK))
			{
				/* This frame is ready for processing */
				/*find the corresponding buffer in the bufferlist */
				blist_ent_ptr=priv->rx_blist_vp+fda_ent_ptr->bd.BDStat;
				skb=(struct sk_buff*)blist_ent_ptr->fd.FDSystem;

				/* Pass this skb up the stack */
				skb->dev=dev;
				skb_put(skb,fda_ent_ptr->fd.FDLength);
				skb->protocol=eth_type_trans(skb,dev);
				skb->ip_summed=CHECKSUM_UNNECESSARY;
				result=netif_rx(skb);
				/* Update statistics */
				priv->stats.rx_packets++;
				priv->stats.rx_bytes+=fda_ent_ptr->fd.FDLength;

				/* Free the FDA entry */
				fda_ent_ptr->bd.BDStat=0xff;
				fda_ent_ptr->fd.FDCtl=FDCTL_COWNSFD_MSK;

				/* Allocate a new skb and point the bd entry to it */
				blist_ent_ptr->fd.FDSystem=0;
				skb=dev_alloc_skb(PKT_BUF_SZ);
				//printk("allocskb=%#x\n",skb);
				if(skb){
					setup_blist_entry(skb,blist_ent_ptr);

				}
				else if(!priv->memupdate_scheduled){
					int tmp;
					/* There are no buffers at the moment, so schedule */
					/* the background task to sort this out */
					schedule_task(&priv->tq_memupdate);
					priv->memupdate_scheduled=1;
					printk(KERN_DEBUG "%s:No buffers",dev->name);
					/* If this interrupt was due to a lack of buffers then
					 * we'd better stop the receiver too */
					if(interruptValue&ETHER_INT_SRC_BLEX_MSK){
						priv->rx_disabled=1;
						tmp=readl(ETHER_INT_SRC(dev->base_addr));
						writel(tmp&~ETHER_RX_CTL_RXEN_MSK,ETHER_RX_CTL(dev->base_addr));
						printk(KERN_DEBUG "%s:Halting rx",dev->name);
					}

				}

			}
			fda_ent_ptr++;
		}
		spin_unlock(&priv->rx_lock);

		/* Clear the  interrupts */
		writel(ETHER_INT_SRC_INTMACRX_MSK | ETHER_INT_SRC_FDAEX_MSK
		       | ETHER_INT_SRC_BLEX_MSK,ETHER_INT_SRC(dev->base_addr));

	}

	if(readl(ETHER_INT_SRC(dev->base_addr))&ETHER_INT_SRC_INTMACTX_MSK){

		if(!priv->memupdate_scheduled){
			schedule_task(&priv->tq_memupdate);
			priv->memupdate_scheduled=1;
		}
		/* Clear the interrupt */
		writel(ETHER_INT_SRC_INTMACTX_MSK,ETHER_INT_SRC(dev->base_addr));
	}

	if (readl(ETHER_INT_SRC(dev->base_addr)) & (ETHER_INT_SRC_SWINT_MSK|
						    ETHER_INT_SRC_INTEARNOT_MSK|
						    ETHER_INT_SRC_INTLINK_MSK|
						    ETHER_INT_SRC_INTEXBD_MSK|
						    ETHER_INT_SRC_INTTXCTLCMP_MSK))
	{
		/*
		 *	Not using any of these so they shouldn't happen
		 *
		 *	In the cased of INTEXBD - if you allocate more
		 *      than 28 decsriptors you may need to think about this
		 */
		printk("Not using this interrupt\n");
	}

	if (readl(ETHER_INT_SRC(dev->base_addr)) &
	    (ETHER_INT_SRC_INTSBUS_MSK |
	     ETHER_INT_SRC_INTNRABT_MSK
	     |ETHER_INT_SRC_DMPARERR_MSK))
	{
		/*
		 * Hardware errors, we can either ignore them and hope they go away
		 *or reset the device, I'll try the first for now to see if they happen
		 */
		printk("Hardware error\n");
	}
}