📄 pmcmspeth.c
字号:
{ if(smac.mac[i].t-jiffies>=MAC_TIME_OUT) memset(&(smac.mac[i]),0,sizeof(smac.mac[i])); } stime=jiffies; }/* macTimer.function =time_out ; macTimer.expires = jiffies + (60*100*HZ); macTimer_on = 1; add_timer(&macTimer);*/ }/************************************************************************** * Open/initialize the board. This is called (in the current kernel) * sometime after booting when the 'ifconfig' program is run. * * This routine should set everything up anew at each open, even * registers that "should" only need to be set once at boot, so that * there is non-reboot way to recover if something goes wrong. */static int mspeth_open(struct net_device *dev){ struct mspeth_local *lp = (struct mspeth_local *) dev->priv; /* should move much of the initialization out of probe and into this routine * somewhere. */ /* reset the hardware, initialize the queues and configure the hardware * must remember to set the station address otherwise no packets will come * our way ..... *///sxj add testmemset(&smac,0,sizeof(smac));//added by Shi ->//memset(&nPubPort,0,sizeof(nPubPort));//memset(&nPubIcmpPort,0,sizeof(nPubIcmpPort));memset(&scomp,0,sizeof(scomp));//added by Shi <-stime=jiffies;/*init_timer(&macTimer);macTimer.function =time_out ;macTimer.expires = jiffies + (HZ);macTimer_on = 1;printk("start timer\n");add_timer(&macTimer);*/ mspeth_mac_reset(dev); if (!(lp->option & MSP_OPT_SWITCH)) mspeth_phy_reset(dev); if (!mspeth_queue_init(dev)) { return -EAGAIN; } mspeth_mac_init(dev); mspeth_phy_init(dev); /* Initialize the link check timer. Do not set up timer if we are * directly connected to a switch. */ if (!(lp->option & MSP_OPT_SWITCH)) { init_timer(&lp->link_timer); lp->link_timer.expires = jiffies + HZ / LINK_DELAY_DIV; lp->link_timer.data = (u32) dev; lp->link_timer.function = mspeth_link_check; add_timer(&lp->link_timer); } /* and start up the queue up the stack */ netif_start_queue(dev); MOD_INC_USE_COUNT; return 0;}/************************************************************************** * The inverse routine to mspeth_open(). Close the device and clean up */static int mspeth_close(struct net_device *dev){ struct mspeth_local *lp = (struct mspeth_local *) dev->priv; u32 flags;//sxj add /* if (macTimer_on) del_timer(&macTimer);*///end /* please don't interrupt me while I'm shutting down everything */ local_irq_save(flags); /* stop the queue & let the world know about it */ netif_stop_queue(dev); netif_carrier_off(dev); /* smite the link check timers */ del_timer_sync(&lp->link_timer); /* Clean up the adaptor. */ mspeth_mac_reset(dev); if (!(lp->option & MSP_OPT_SWITCH)) mspeth_phy_reset(dev); /* free the the queue memeory */ mspeth_free_queues(dev); /* turn back on the interrupts */ local_irq_restore(flags); MOD_DEC_USE_COUNT; return 0;}/************************************************************************** * The typical workload of the driver: * Handle the network interface interrupts. */static void mspeth_interrupt(int irq, void *dev_id, struct pt_regs *regs){ struct net_device *dev = dev_id; struct mspeth_regs *tr = (struct mspeth_regs *) dev->base_addr; struct mspeth_local *lp = (struct mspeth_local *) dev->priv; u32 status; if (unlikely(dev == NULL)) { printk(KERN_WARNING "%s: irq %d for unknown device.\n", cardname, irq); return; } status = read_mspreg(&tr->Int_Src); /* acknowledge the interrupts and check for null entry */ if (unlikely(status == 0)) return; else write_mspreg(status, &tr->Int_Src); /* collect debugging stats */ if (status & IntSrc_MacRx) lp->lstats.rx_ints++; if (status & IntSrc_MacTx) lp->lstats.tx_ints++; /* handle most likely cases first */ if (likely(status == IntSrc_MacRx)) { /* disable interrupt and schedule tasklet */ /* hammtrev, 2005-11-25: * Should we be disabling more than just Rx_EnGood? */ write_mspreg(RX_CTL_CMD & ~Rx_EnGood, &tr->Rx_Ctl); tasklet_schedule(&lp->rx_tasklet); return; } if (likely(status == IntSrc_MacTx)) { /* disable interrupt and schedule tasklet */ write_mspreg(TX_CTL_CMD & ~Tx_EnComp, &tr->Tx_Ctl); tasklet_schedule(&lp->tx_tasklet); return; } if (likely(status == (IntSrc_MacTx | IntSrc_MacRx))) { /* disable interrupts and schedule tasklets */ write_mspreg(RX_CTL_CMD & ~Rx_EnGood, &tr->Rx_Ctl); write_mspreg(TX_CTL_CMD & ~Tx_EnComp, &tr->Tx_Ctl); tasklet_schedule(&lp->tx_tasklet); tasklet_schedule(&lp->rx_tasklet); return; } /* all other combined cases */ if (status & IntSrc_MacRx) { /* ack interrupt, disable and schedule tasklet */ write_mspreg(RX_CTL_CMD & ~Rx_EnGood, &tr->Rx_Ctl); tasklet_schedule(&lp->rx_tasklet); } if (status & IntSrc_MacTx) { /* ack interrupt, disable and schedule tasklet */ write_mspreg(TX_CTL_CMD & ~Tx_EnComp, &tr->Tx_Ctl); tasklet_schedule(&lp->tx_tasklet); } /* recoverable errors */ if (status & IntSrc_FDAEx) { /* disable FDAEx int. (until we make room...) */ write_mspreg(INT_EN_CMD & ~IntEn_FDAEx, &tr->Int_En); lp->lstats.fd_exha++; lp->stats.rx_dropped++; } /* Some boards generate a link state interrupt on power-up. We don't * know why, but ACK it and it will go away. * -- hammtrev, 2005/08/30 */ if (status & IntSrc_Link_St) { write_mspreg((read_mspreg(&tr->MAC_Ctl) | MAC_LnkChg), &tr->MAC_Ctl); } /* and now all the wacky unrecoverable fatal error conditions * this includes BLEx errors since we can *never* have one -- if we * do, it indicates that there is some sort of queue corruption. */ if (status & FATAL_ERROR_INT) { /* Disable further interrupts until device reset. */ write_mspreg(read_mspreg(&tr->DMA_Ctl) | DMA_IntMask, &tr->DMA_Ctl); /* this one may be overkill... */ write_mspreg(read_mspreg(&tr->MAC_Ctl) | MAC_HaltImm, &tr->MAC_Ctl); mspeth_fatal_error_interrupt(dev, status); } return;}/************************************************************************** * fatal error interrupts reset the entire device but they don't require * reallocating the queues, just clearing them */static voidmspeth_fatal_error_interrupt(struct net_device *dev, int status){ struct mspeth_local *lp = (struct mspeth_local *) dev->priv; printk(KERN_WARNING "MSPETH(fatal_error) %s: Fatal Error Interrupt (0x%08x):", dev->name, status); if (status & IntSrc_DmParErr) printk(" DmParErr"); if (status & IntSrc_NRAB) printk(" IntNRAB"); if (status & IntSrc_BLEx) printk(" IntBLEx"); printk("\n"); /* panic if it gets too crazy */ if (lp->fatal_icnt++ > 100) panic("MSPETH(fatal_error) %s: too many fatal errors.\n", dev->name); /* Dump our descriptors, if desired */ if (mspeth_debug > 0) { mspeth_dump_queues(dev); mspeth_dump_stats(dev); } /* Try to restart the adaptor. */ /* hammtrev, 2005/12/08: * This is too much work for a top-half interrupt handler, and * may result in unexpected race conditions with other tasklets. * Now deferring the device reset to a bottom-half tasklet, to * allow any currently-running tasklet to complete without unexpected * changes to frame/buffer descriptors, etc. */ /* mspeth_hard_restart(dev); */ tasklet_schedule(&lp->hard_restart_tasklet);}/************************************************************************** * Handle deferred processing of the IntBLEx interrupt. */static void mspeth_hard_restart_bh(unsigned long devaddr){ struct net_device *dev = (struct net_device *)devaddr; printk(KERN_WARNING "MSPETH(fatal_error) %s: restarting device\n", dev->name); mspeth_hard_restart(dev);}/************************************************************************** * process a single RX packet, including sending it up the stack and * reallocating the buffer. Return the next buffer in the RX queue. * This routine assumes that the current FD pointed to by rxfd_curr * has been invalidated with the cache and is current with main memory */static struct Q_Desc *__hotnet mspeth_rx_onepkt(struct net_device *dev){ struct mspeth_local *lp = (struct mspeth_local *) dev->priv; u32 status; struct Q_Desc *next_rxfd; int bdnum, len; struct sk_buff *skb;//sxj add testint i=0;//added by Shi ->int j=0;//added by Shi <-unsigned char temp[2000];int nPort;struct sk_buff *skb1;//added by Shi ->unsigned nSrcPort,nDstPort;unsigned nId;unsigned short id=0;unsigned int nserverip;//added by Shi <-//sxj add end /* collect all the relevent information */ status = lp->rxfd_curr->fd.FDStat; len = lp->rxfd_curr->bd.BDCtl & BD_BuffLength_MASK; bdnum = (lp->rxfd_curr->bd.BDCtl & 0x00FF0000) >> BD_RxBDID_SHIFT;#ifdef MSPETH_DUMP_QUEUES if (mspeth_debug > 2 && (!bdnum && (rx_bdnums[lp->unit][rx_bdnums_ind[lp->unit]] != ((RX_BUF_NUM << 1)-1)))) dump_qdesc(lp->rxfd_curr); catalog_rx_bdnum(lp->unit,bdnum);#endif /* MSPETH_DUMP_QUEUES */ /* the packet has been received correctly so prepare to send it up the stack */ if (likely(status & Rx_Good)||(status & Rx_LongErr)){ skb = lp->rx_skbp[bdnum]; /* basic non-interleaved buffer processing */ invalidate_buffer(skb->data, len); /* allocate a new buffer to replace it */ lp->rx_skbp[bdnum] = mspeth_alloc_skb(dev); /* if a replacement buffer can be allocated then send the skb up the stack * otherwise we drop the packet and reuse the existing buffer */ if (likely(lp->rx_skbp[bdnum] != NULL)) { /* complete the skb and send it up the stack */ __skb_put(skb, len);//sxj add //printk(" name %s len %d\n",dev->name ,skb->len);/*for(i=0;i<skb->len;i++) printk("%02x ",skb->data[i]);printk("\n");*/time_out();if(strcmp(skb->dev->name,"eth0")==0){ if(skb->data[27]==0x02){for(i=0;i<skb->len;i++){ printk("%02x ",skb->data[i]); if(i%16==0) printk("\n");}printk("\n");} //nPort=skb->data[13]&0xff; //sxj modi 2008.01.04 nPort=skb->data[13]&0x0f; memset(temp,0,2000); memcpy(temp,skb->data,12); memcpy(temp+12,skb->data+16,skb->len-16); skb->len-=4; memcpy(skb->data,temp,skb->len);// if(skb->len>=1514) skb->len-=4;//added by Shi ->//sxj add vlan tag//eth0 packet is com and vlan is use and is tcp or udp//if((svlan[nPort].flag==1)&&(nFlag[nPort]!=1)){ if((skb->data[12]==0x08)&&(skb->data[13]==0x00)) { id=getmol(skb->data+30); nserverip=makelong(makeword(skb->data[30]&0xff,skb->data[31]&0xff),makeword(skb->data[32]&0xff,skb->data[33]&0xff));if(skb->data[23]==0x02){ printk("port is %d\n",nPort); printk("eth0 id and ip is %d,%04x\n",id,nserverip);} for(i=0;i<scomp[id].nCount;i++) { if(scomp[id].Ip[i].ip==nserverip) {/* if(skb->data[23]==0x02) printk("old\n");*/ scomp[id].Ip[i].flag=nPort; scomp[id].Ip[i].t=jiffies; break; } } if(i>=scomp[id].nCount) {/* if(skb->data[23]==0x02) printk("new\n");*/ scomp[id].Ip[scomp[id].nCount].ip=nserverip; scomp[id].Ip[scomp[id].nCount].flag=nPort; scomp[id].Ip[scomp[id].nCount].t=jiffies; scomp[id].nCount++; } /* if((skb->data[23]==0x06)||(skb->data[23]==0x11)) { nSrcPort=((skb->data[34]&0xff)<<8)+(skb->data[35]&0xff);//printk(" src port is %d\n",nSrcPort); nPubPort[nSrcPort].flag=nPort; nPubPort[nSrcPort].count++;//printk("src port is ok\n"); } else if((skb->data[23]==0x01)) { nId=((skb->data[38]&0xff)<<8)+(skb->data[39]&0xff);//printk(" src port is %d\n",nSrcPort); nPubIcmpPort[nId].flag=nPort; nPubIcmpPort[nId].count++; }*/ } }//added by Shi <- if(nFlag[nPort]==1) { skb1=dev_alloc_skb(skb->len); if(!skb1) { dev_kfree_skb(skb);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -