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

📄 nmclan_cs.c

📁 h内核
💻 C
📖 第 1 页 / 共 4 页
字号:
	    " 0x%X.\n", pkt_len, rx_status);      skb = dev_alloc_skb(pkt_len+2);      if (skb != NULL) {	skb->dev = dev;	skb_reserve(skb, 2);	insw(ioaddr + AM2150_RCV, skb_put(skb, pkt_len), pkt_len>>1);	if (pkt_len & 1)	    *(skb->tail-1) = inb(ioaddr + AM2150_RCV);	skb->protocol = eth_type_trans(skb, dev);		netif_rx(skb); /* Send the packet to the upper (protocol) layers. */	dev->last_rx = jiffies;	lp->linux_stats.rx_packets++;	lp->linux_stats.rx_bytes += skb->len;	outb(0xFF, ioaddr + AM2150_RCV_NEXT); /* skip to next frame */	continue;      } else {	DEBUG(1, "%s: couldn't allocate a sk_buff of size"	      " %d.\n", dev->name, pkt_len);	lp->linux_stats.rx_dropped++;      }    }    outb(0xFF, ioaddr + AM2150_RCV_NEXT); /* skip to next frame */  } /* while */  return 0;} /* mace_rx *//* ----------------------------------------------------------------------------pr_linux_stats---------------------------------------------------------------------------- */static void pr_linux_stats(struct net_device_stats *pstats){  DEBUG(2, "pr_linux_stats\n");  DEBUG(2, " rx_packets=%-7ld        tx_packets=%ld\n",	(long)pstats->rx_packets, (long)pstats->tx_packets);  DEBUG(2, " rx_errors=%-7ld         tx_errors=%ld\n",	(long)pstats->rx_errors, (long)pstats->tx_errors);  DEBUG(2, " rx_dropped=%-7ld        tx_dropped=%ld\n",	(long)pstats->rx_dropped, (long)pstats->tx_dropped);  DEBUG(2, " multicast=%-7ld         collisions=%ld\n",	(long)pstats->multicast, (long)pstats->collisions);  DEBUG(2, " rx_length_errors=%-7ld  rx_over_errors=%ld\n",	(long)pstats->rx_length_errors, (long)pstats->rx_over_errors);  DEBUG(2, " rx_crc_errors=%-7ld     rx_frame_errors=%ld\n",	(long)pstats->rx_crc_errors, (long)pstats->rx_frame_errors);  DEBUG(2, " rx_fifo_errors=%-7ld    rx_missed_errors=%ld\n",	(long)pstats->rx_fifo_errors, (long)pstats->rx_missed_errors);  DEBUG(2, " tx_aborted_errors=%-7ld tx_carrier_errors=%ld\n",	(long)pstats->tx_aborted_errors, (long)pstats->tx_carrier_errors);  DEBUG(2, " tx_fifo_errors=%-7ld    tx_heartbeat_errors=%ld\n",	(long)pstats->tx_fifo_errors, (long)pstats->tx_heartbeat_errors);  DEBUG(2, " tx_window_errors=%ld\n",	(long)pstats->tx_window_errors);} /* pr_linux_stats *//* ----------------------------------------------------------------------------pr_mace_stats---------------------------------------------------------------------------- */static void pr_mace_stats(mace_statistics *pstats){  DEBUG(2, "pr_mace_stats\n");  DEBUG(2, " xmtsv=%-7d             uflo=%d\n",	pstats->xmtsv, pstats->uflo);  DEBUG(2, " lcol=%-7d              more=%d\n",	pstats->lcol, pstats->more);  DEBUG(2, " one=%-7d               defer=%d\n",	pstats->one, pstats->defer);  DEBUG(2, " lcar=%-7d              rtry=%d\n",	pstats->lcar, pstats->rtry);  /* MACE_XMTRC */  DEBUG(2, " exdef=%-7d             xmtrc=%d\n",	pstats->exdef, pstats->xmtrc);  /* RFS1--Receive Status (RCVSTS) */  DEBUG(2, " oflo=%-7d              clsn=%d\n",	pstats->oflo, pstats->clsn);  DEBUG(2, " fram=%-7d              fcs=%d\n",	pstats->fram, pstats->fcs);  /* RFS2--Runt Packet Count (RNTPC) */  /* RFS3--Receive Collision Count (RCVCC) */  DEBUG(2, " rfs_rntpc=%-7d         rfs_rcvcc=%d\n",	pstats->rfs_rntpc, pstats->rfs_rcvcc);  /* MACE_IR */  DEBUG(2, " jab=%-7d               babl=%d\n",	pstats->jab, pstats->babl);  DEBUG(2, " cerr=%-7d              rcvcco=%d\n",	pstats->cerr, pstats->rcvcco);  DEBUG(2, " rntpco=%-7d            mpco=%d\n",	pstats->rntpco, pstats->mpco);  /* MACE_MPC */  DEBUG(2, " mpc=%d\n", pstats->mpc);  /* MACE_RNTPC */  DEBUG(2, " rntpc=%d\n", pstats->rntpc);  /* MACE_RCVCC */  DEBUG(2, " rcvcc=%d\n", pstats->rcvcc);} /* pr_mace_stats *//* ----------------------------------------------------------------------------update_stats	Update statistics.  We change to register window 1, so this	should be run single-threaded if the device is active. This is	expected to be a rare operation, and it's simpler for the rest	of the driver to assume that window 0 is always valid rather	than use a special window-state variable.	oflo & uflo should _never_ occur since it would mean the Xilinx	was not able to transfer data between the MACE FIFO and the	card's SRAM fast enough.  If this happens, something is	seriously wrong with the hardware.---------------------------------------------------------------------------- */static void update_stats(kio_addr_t ioaddr, struct net_device *dev){  mace_private *lp = netdev_priv(dev);  lp->mace_stats.rcvcc += mace_read(lp, ioaddr, MACE_RCVCC);  lp->mace_stats.rntpc += mace_read(lp, ioaddr, MACE_RNTPC);  lp->mace_stats.mpc += mace_read(lp, ioaddr, MACE_MPC);  /* At this point, mace_stats is fully updated for this call.     We may now update the linux_stats. */  /* The MACE has no equivalent for linux_stats field which are commented     out. */  /* lp->linux_stats.multicast; */  lp->linux_stats.collisions =     lp->mace_stats.rcvcco * 256 + lp->mace_stats.rcvcc;    /* Collision: The MACE may retry sending a packet 15 times       before giving up.  The retry count is in XMTRC.       Does each retry constitute a collision?       If so, why doesn't the RCVCC record these collisions? */  /* detailed rx_errors: */  lp->linux_stats.rx_length_errors =     lp->mace_stats.rntpco * 256 + lp->mace_stats.rntpc;  /* lp->linux_stats.rx_over_errors */  lp->linux_stats.rx_crc_errors = lp->mace_stats.fcs;  lp->linux_stats.rx_frame_errors = lp->mace_stats.fram;  lp->linux_stats.rx_fifo_errors = lp->mace_stats.oflo;  lp->linux_stats.rx_missed_errors =     lp->mace_stats.mpco * 256 + lp->mace_stats.mpc;  /* detailed tx_errors */  lp->linux_stats.tx_aborted_errors = lp->mace_stats.rtry;  lp->linux_stats.tx_carrier_errors = lp->mace_stats.lcar;    /* LCAR usually results from bad cabling. */  lp->linux_stats.tx_fifo_errors = lp->mace_stats.uflo;  lp->linux_stats.tx_heartbeat_errors = lp->mace_stats.cerr;  /* lp->linux_stats.tx_window_errors; */  return;} /* update_stats *//* ----------------------------------------------------------------------------mace_get_stats	Gathers ethernet statistics from the MACE chip.---------------------------------------------------------------------------- */static struct net_device_stats *mace_get_stats(struct net_device *dev){  mace_private *lp = netdev_priv(dev);  update_stats(dev->base_addr, dev);  DEBUG(1, "%s: updating the statistics.\n", dev->name);  pr_linux_stats(&lp->linux_stats);  pr_mace_stats(&lp->mace_stats);  return &lp->linux_stats;} /* net_device_stats *//* ----------------------------------------------------------------------------updateCRC	Modified from Am79C90 data sheet.---------------------------------------------------------------------------- */#ifdef BROKEN_MULTICASTstatic void updateCRC(int *CRC, int bit){  int poly[]={    1,1,1,0, 1,1,0,1,    1,0,1,1, 1,0,0,0,    1,0,0,0, 0,0,1,1,    0,0,1,0, 0,0,0,0  }; /* CRC polynomial.  poly[n] = coefficient of the x**n term of the	CRC generator polynomial. */  int j;  /* shift CRC and control bit (CRC[32]) */  for (j = 32; j > 0; j--)    CRC[j] = CRC[j-1];  CRC[0] = 0;  /* If bit XOR(control bit) = 1, set CRC = CRC XOR polynomial. */  if (bit ^ CRC[32])    for (j = 0; j < 32; j++)      CRC[j] ^= poly[j];} /* updateCRC *//* ----------------------------------------------------------------------------BuildLAF	Build logical address filter.	Modified from Am79C90 data sheet.Input	ladrf: logical address filter (contents initialized to 0)	adr: ethernet address---------------------------------------------------------------------------- */static void BuildLAF(int *ladrf, int *adr){  int CRC[33]={1}; /* CRC register, 1 word/bit + extra control bit */  int i, byte; /* temporary array indices */  int hashcode; /* the output object */  CRC[32]=0;  for (byte = 0; byte < 6; byte++)    for (i = 0; i < 8; i++)      updateCRC(CRC, (adr[byte] >> i) & 1);  hashcode = 0;  for (i = 0; i < 6; i++)    hashcode = (hashcode << 1) + CRC[i];  byte = hashcode >> 3;  ladrf[byte] |= (1 << (hashcode & 7));#ifdef PCMCIA_DEBUG  if (pc_debug > 2) {    printk(KERN_DEBUG "    adr =");    for (i = 0; i < 6; i++)      printk(" %02X", adr[i]);    printk("\n" KERN_DEBUG "    hashcode = %d(decimal), ladrf[0:63]"	   " =", hashcode);    for (i = 0; i < 8; i++)      printk(" %02X", ladrf[i]);    printk("\n");  }#endif} /* BuildLAF *//* ----------------------------------------------------------------------------restore_multicast_list	Restores the multicast filter for MACE chip to the last	set_multicast_list() call.Input	multicast_num_addrs	multicast_ladrf[]---------------------------------------------------------------------------- */static void restore_multicast_list(struct net_device *dev){  mace_private *lp = netdev_priv(dev);  int num_addrs = lp->multicast_num_addrs;  int *ladrf = lp->multicast_ladrf;  kio_addr_t ioaddr = dev->base_addr;  int i;  DEBUG(2, "%s: restoring Rx mode to %d addresses.\n",	dev->name, num_addrs);  if (num_addrs > 0) {    DEBUG(1, "Attempt to restore multicast list detected.\n");    mace_write(lp, ioaddr, MACE_IAC, MACE_IAC_ADDRCHG | MACE_IAC_LOGADDR);    /* Poll ADDRCHG bit */    while (mace_read(lp, ioaddr, MACE_IAC) & MACE_IAC_ADDRCHG)      ;    /* Set LADRF register */    for (i = 0; i < MACE_LADRF_LEN; i++)      mace_write(lp, ioaddr, MACE_LADRF, ladrf[i]);    mace_write(lp, ioaddr, MACE_UTR, MACE_UTR_RCVFCSE | MACE_UTR_LOOP_EXTERNAL);    mace_write(lp, ioaddr, MACE_MACCC, MACE_MACCC_ENXMT | MACE_MACCC_ENRCV);  } else if (num_addrs < 0) {    /* Promiscuous mode: receive all packets */    mace_write(lp, ioaddr, MACE_UTR, MACE_UTR_LOOP_EXTERNAL);    mace_write(lp, ioaddr, MACE_MACCC,      MACE_MACCC_PROM | MACE_MACCC_ENXMT | MACE_MACCC_ENRCV    );  } else {    /* Normal mode */    mace_write(lp, ioaddr, MACE_UTR, MACE_UTR_LOOP_EXTERNAL);    mace_write(lp, ioaddr, MACE_MACCC, MACE_MACCC_ENXMT | MACE_MACCC_ENRCV);  }} /* restore_multicast_list *//* ----------------------------------------------------------------------------set_multicast_list	Set or clear the multicast filter for this adaptor.Input	num_addrs == -1	Promiscuous mode, receive all packets	num_addrs == 0	Normal mode, clear multicast list	num_addrs > 0	Multicast mode, receive normal and MC packets, and do			best-effort filtering.Output	multicast_num_addrs	multicast_ladrf[]---------------------------------------------------------------------------- */static void set_multicast_list(struct net_device *dev){  mace_private *lp = netdev_priv(dev);  int adr[ETHER_ADDR_LEN] = {0}; /* Ethernet address */  int i;  struct dev_mc_list *dmi = dev->mc_list;#ifdef PCMCIA_DEBUG  if (pc_debug > 1) {    static int old;    if (dev->mc_count != old) {      old = dev->mc_count;      DEBUG(0, "%s: setting Rx mode to %d addresses.\n",	    dev->name, old);    }  }#endif  /* Set multicast_num_addrs. */  lp->multicast_num_addrs = dev->mc_count;  /* Set multicast_ladrf. */  if (num_addrs > 0) {    /* Calculate multicast logical address filter */    memset(lp->multicast_ladrf, 0, MACE_LADRF_LEN);    for (i = 0; i < dev->mc_count; i++) {      memcpy(adr, dmi->dmi_addr, ETHER_ADDR_LEN);      dmi = dmi->next;      BuildLAF(lp->multicast_ladrf, adr);    }  }  restore_multicast_list(dev);} /* set_multicast_list */#endif /* BROKEN_MULTICAST */static void restore_multicast_list(struct net_device *dev){  kio_addr_t ioaddr = dev->base_addr;  mace_private *lp = netdev_priv(dev);  DEBUG(2, "%s: restoring Rx mode to %d addresses.\n", dev->name,	lp->multicast_num_addrs);  if (dev->flags & IFF_PROMISC) {    /* Promiscuous mode: receive all packets */    mace_write(lp,ioaddr, MACE_UTR, MACE_UTR_LOOP_EXTERNAL);    mace_write(lp, ioaddr, MACE_MACCC,      MACE_MACCC_PROM | MACE_MACCC_ENXMT | MACE_MACCC_ENRCV    );  } else {    /* Normal mode */    mace_write(lp, ioaddr, MACE_UTR, MACE_UTR_LOOP_EXTERNAL);    mace_write(lp, ioaddr, MACE_MACCC, MACE_MACCC_ENXMT | MACE_MACCC_ENRCV);  }} /* restore_multicast_list */static void set_multicast_list(struct net_device *dev){  mace_private *lp = netdev_priv(dev);#ifdef PCMCIA_DEBUG  if (pc_debug > 1) {    static int old;    if (dev->mc_count != old) {      old = dev->mc_count;      DEBUG(0, "%s: setting Rx mode to %d addresses.\n",	    dev->name, old);    }  }#endif  lp->multicast_num_addrs = dev->mc_count;  restore_multicast_list(dev);} /* set_multicast_list */static struct pcmcia_driver nmclan_cs_driver = {	.owner		= THIS_MODULE,	.drv		= {		.name	= "nmclan_cs",	},	.attach		= nmclan_attach,	.detach		= nmclan_detach,};static int __init init_nmclan_cs(void){	return pcmcia_register_driver(&nmclan_cs_driver);}static void __exit exit_nmclan_cs(void){	pcmcia_unregister_driver(&nmclan_cs_driver);	BUG_ON(dev_list != NULL);}module_init(init_nmclan_cs);module_exit(exit_nmclan_cs);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -