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)); } }
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)); }
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)); } } }
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ÐER_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))ÐER_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"); } }