Linux 网卡驱动


刺猬@http://blog.csdn.net/littlehedgehog






网上一位前辈写的,时至今日,代码很多编译通不过(主要是Linux 内核变化实在太快),我把代码移植到我的ubuntu 8.10下测试成功,里面也加上了我的注解。不过还有不少东西没有搞懂,手头上也没有相关的硬件资料,就一份Realtek 的datasheet。 TNND,后面要备考备荒,手头的事情只能放一放。



  1. #include <linux/module.h>
  2. #include <linux/kernel.h>
  3. #include <linux/compiler.h>
  4. #include <linux/pci.h>
  5. #include <linux/init.h>
  6. #include <linux/ioport.h>
  7. #include <linux/netdevice.h>
  8. #include <linux/etherdevice.h>
  9. #include <linux/rtnetlink.h>
  10. #include <linux/delay.h>
  11. #include <linux/ethtool.h>
  12. #include <linux/completion.h>
  13. #include <linux/crc32.h>
  14. #include <linux/mii.h>
  15. #include <asm/io.h>
  16. #include <asm/uaccess.h>
  17. #include <asm/irq.h>
  18. #if defined(CONFIG_SH_DREAMCAST)
  19. #define RX_BUF_IDX  1   /* 16K ring */
  20. #else
  21. #define RX_BUF_IDX  2   /* 32K ring */
  22. #endif
  23. #define RX_BUF_LEN  (8192 << RX_BUF_IDX)
  24. #define RX_BUF_PAD  16
  25. #define RX_BUF_WRAP_PAD 2048 /* spare padding to handle lack of packet wrap */
  26. #if RX_BUF_LEN == 65536
  27. #define RX_BUF_TOT_LEN  RX_BUF_LEN
  28. #else
  29. #define RX_BUF_TOT_LEN  (RX_BUF_LEN + RX_BUF_PAD + RX_BUF_WRAP_PAD)
  30. #endif
  31. typedef enum
  32. {
  33.     RTL8139 = 0,
  34.     RTL8129,
  35. } board_t;
  36. static struct pci_device_id xc_id[] =
  37. {
  38.     {0x10ec, 0x8139, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
  39.     {0x10ec, 0x8138, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
  40.     {0x1113, 0x1211, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
  41.     {0x1500, 0x1360, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
  42.     {0x4033, 0x1360, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
  43.     {0x1186, 0x1300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
  44.     {0x1186, 0x1340, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
  45.     {0x13d1, 0xab06, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
  46.     {0x1259, 0xa117, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
  47.     {0x1259, 0xa11e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
  48.     {0x14ea, 0xab06, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
  49.     {0x14ea, 0xab07, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
  50.     {0x11db, 0x1234, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
  51.     {0x1432, 0x9130, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
  52.     {0x02ac, 0x1012, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
  53.     {0x018a, 0x0106, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
  54.     {0x126c, 0x1211, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
  55.     {0x1743, 0x8139, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
  56.     {0x021b, 0x8139, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
  57. #ifdef CONFIG_SH_SECUREEDGE5410
  58.     /* Bogus 8139 silicon reports 8129 without external PROM :-*/
  59.     {0x10ec, 0x8129, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
  60. #endif
  61. #ifdef CONFIG_8139TOO_8129
  62.     {0x10ec, 0x8129, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8129 },
  63. #endif
  64.     {PCI_ANY_ID, 0x8139, 0x10ec, 0x8139, 0, 0, RTL8139 },
  65.     {PCI_ANY_ID, 0x8139, 0x1186, 0x1300, 0, 0, RTL8139 },
  66.     {PCI_ANY_ID, 0x8139, 0x13d1, 0xab06, 0, 0, RTL8139 },
  67.     {0,}
  68. };
  69. MODULE_DEVICE_TABLE (pci,xc_id);
  70. enum RTL8139_registers
  71. {
  72.     MAC0 = 0,       /* Ethernet hardware address. */
  73.     MAR0 = 8,       /* Multicast filter. */
  74.     TxStatus0 = 0x10,   /* Transmit status (Four 32bit registers). */
  75.     TxAddr0 = 0x20,     /*物理地址*/
  76.     RxBuf = 0x30,       /*物理地址*/
  77.     ChipCmd = 0x37,
  78.     RxBufPtr = 0x38,
  79.     IntrMask = 0x3C,
  80.     IntrStatus = 0x3E,
  81.     TxConfig = 0x40,
  82.     RxConfig = 0x44,
  83.     RxMissed = 0x4C,
  84.     Cfg9346 = 0x50,
  85.     Config1 = 0x52,
  86.     Config3 = 0x59,
  87.     Config4 = 0x5A,
  88.     HltClk = 0x5B,
  89.     MultiIntr = 0x5C,
  90.     /*MII*/
  91.     BasicModeCtrl = 0x62,
  92.     BasicModeStatus = 0x64,
  93.     NWayAdvert = 0x66,
  94.     NWayLPAR = 0x68,
  95.     NWayExpansion = 0x6A,
  96.     /*MII*/
  97.     CSCR = 0x74,
  98. };
  99. enum ChipCmdBits  /*ChipCmd = 0x37 register*/
  100. {
  101.     CmdReset = 0x10,/*chip重置*/
  102.     CmdRxEnb = 0x08,/*开启读*/
  103.     CmdTxEnb = 0x04,/*开启写*/
  104.     RxBufEmpty = 0x01,/*如果设置这个位表示接收缓冲区为空*/
  105. };
  106. enum IntrStatusBits
  107. {
  108.     PCIErr = 0x8000,
  109.     PCSTimeout = 0x4000,
  110.     RxFIFOOver = 0x40,
  111.     RxUnderrun = 0x20,
  112.     RxOverflow = 0x10,
  113.     TxErr = 0x08,
  114.     TxOK = 0x04,
  115.     RxErr = 0x02,
  116.     RxOK = 0x01,
  117.     RxAckBits = RxFIFOOver | RxOverflow | RxOK,
  118. };
  119. static const u16 xc_intr_mask =
  120.     PCIErr | PCSTimeout | RxUnderrun | RxOverflow | RxFIFOOver |
  121.     TxErr | TxOK | RxErr | RxOK;
  122. static const u16 xc_norx_intr_mask =/*不包含任何接收中断*/
  123.     PCIErr | PCSTimeout | RxUnderrun | TxErr | TxOK | RxErr ;
  124. enum Config1Bits  /*Config1 = 0x52*/
  125. {
  126.     Cfg1_PM_Enable = 0x01,/*开启电源管理(cfg9346要设置为可写)*/
  127.     LWAKE = 0x10,/*于Config4的LWPTN共同工作 同时设置为0为(active high)*/
  128. };
  129. enum Config3Bits  /*Config3 = 0x59*/
  130. {
  131.     Cfg3_Magic     = (1 << 5), /* 1 = wake up on Magic Packet (tm) */
  132. };
  133. enum Config4Bits  /*Config4 = 0x5A*/
  134. {
  135.     LWPTN = (1 << 2),/*于Config1的LWAKE共同工作 同时设置为0为(active high)*/
  136. };
  137. enum Cfg9346Bits
  138. {
  139.     Cfg9346_lock = 0x00,/*一般状态*/
  140.     Cfg9346_Unlock = 0xC0,/*可写状态*/
  141. };
  142. enum TxStatusBits  /*TxStatus0 = 0x10 共4个发送状态register 0x10-0x1f*/
  143. {
  144.     TxHostOwns = 0x2000,
  145.     TxUnderrun = 0x4000,/*在发送数据时如果,Tx FIFO耗尽时设置为1*/
  146.     TxStatOK = 0x8000,/*发送数据成功*/
  147.     TxOutOfWindow = 0x20000000,/*发生 "out of windown" 冲突*/
  148.     TxAborted = 0x40000000,/*设置为1表示发送被中止,该位是只读的*/
  149.     TxCarrierLost = 0x80000000,/*在发送数据包时,carrier丢失*/
  150. };
  151. /* Bits in RxConfig. */
  152. enum rx_mode_bits
  153. {
  154.     AcceptErr = 0x20,
  155.     AcceptRunt = 0x10,
  156.     AcceptBroadcast = 0x08,
  157.     AcceptMulticast = 0x04,
  158.     AcceptMyPhys = 0x02,
  159.     AcceptAllPhys = 0x01,
  160. };
  161. typedef enum
  162. {
  163.     CH_8139 = 0,
  164.     CH_8139_K,
  165.     CH_8139A,
  166.     CH_8139A_G,
  167.     CH_8139B,
  168.     CH_8130,
  169.     CH_8139C,
  170.     CH_8100,
  171.     CH_8100B_8139D,/*我的网卡类型 HOHO~ */
  172.     CH_8101,
  173. } chip_t;
  174. enum chip_flags
  175. {
  176.     HasHltClk = (1 << 0),
  177.     HasLWake = (1 << 1),
  178. };
  179. #define HW_REVID(b30, b29, b28, b27, b26, b23, b22) /
  180.     (b30<<30 | b29<<29 | b28<<28 | b27<<27 | b26<<26 | b23<<23 | b22<<22)
  181. #define HW_REVID_MASK   HW_REVID(1, 1, 1, 1, 1, 1, 1)
  182. static const struct
  183. {
  184.     const char *name;
  185.     u32 version; /* from RTL8139C/RTL8139D docs */
  186.     u32 flags;
  187. } rtl_chip_info[] =
  188. {
  189.     { "RTL-8139",HW_REVID(1, 0, 0, 0, 0, 0, 0),HasHltClk,},
  190.     { "RTL-8139 rev K",HW_REVID(1, 1, 0, 0, 0, 0, 0),HasHltClk,},
  191.     { "RTL-8139A",HW_REVID(1, 1, 1, 0, 0, 0, 0),HasHltClk,},
  192.     { "RTL-8139A rev G",HW_REVID(1, 1, 1, 0, 0, 1, 0),HasHltClk,},
  193.     { "RTL-8139B",HW_REVID(1, 1, 1, 1, 0, 0, 0),HasLWake,},
  194.     { "RTL-8130",HW_REVID(1, 1, 1, 1, 1, 0, 0),HasLWake,},
  195.     { "RTL-8139C",HW_REVID(1, 1, 1, 0, 1, 0, 0),HasLWake,},
  196.     { "RTL-8100",HW_REVID(1, 1, 1, 1, 0, 1, 0),HasLWake,},
  197.     { "RTL-8100B/8139D",HW_REVID(1, 1, 1, 0, 1, 0, 1),HasHltClk | HasLWake,},
  198.     { "RTL-8101", HW_REVID(1, 1, 1, 0, 1, 1, 1),HasLWake,},
  199. };
  200. struct xc_priv
  201. {
  202.     void __iomem *ioaddr;
  203.     spinlock_t lock;
  204.     spinlock_t rx_lock;
  205.     chip_t chipset;
  206.     struct napi_struct napi;
  207.     struct pci_dev *pdev;
  208.     struct net_device *dev;
  209.     struct net_device_stats stats;
  210.     u32 rx_config;
  211.     unsigned char *rx_bufs;
  212.     unsigned int cur_rx;
  213.     dma_addr_t rx_bufs_dma;
  214.     unsigned int tx_flag;
  215.     unsigned long cur_tx;
  216.     unsigned long dirty_tx;
  217.     unsigned char *tx_bufs;
  218.     unsigned char *tx_buf[4];
  219.     dma_addr_t tx_bufs_dma;
  220.     /*MII define*/
  221.     u32 msg_enable;
  222.     unsigned int default_port : 4;  /* Last dev->if_port value. */
  223.     signed char phys[4];            /* MII device addresses. */
  224.     struct mii_if_info mii;
  225.     /*MII*/
  226. };
  227. #if RX_BUF_IDX == 1
  228. static const unsigned int xc_rx_config =
  229.     (1 << 11) | (1 << 7) | (7 << 13) | (7 << 8);/*(1<<11) 16k-0x00002980*/
  230. #elif RX_BUF_IDX == 2
  231. static const unsigned int xc_rx_config =
  232.     (1 << 12) | (1 << 7) | (7 << 13) | (7 << 8);/*(1<<12) 32k-0x00003180*/
  233. #else
  234. #error "Invalid configuration for 8139_RXBUF_IDX"
  235. #endif
  236. /*MII*/
  237. static char mii_2_8139_map[8] =
  238. {
  239.     BasicModeCtrl,BasicModeStatus,0,0,
  240.     NWayAdvert,NWayLPAR,NWayExpansion,0
  241. };/*一些于MII相关的8139register*/
  242. static void xc_check_media(struct net_device *dev, unsigned int init_media)
  243. {
  244.     struct xc_priv *tp = netdev_priv(dev);
  245.     if (tp->phys[0] >= 0)
  246.         mii_check_media(&tp->mii, netif_msg_link(tp), init_media);
  247. }
  248. static int mdio_read (struct net_device *dev, int phy_id, int location)
  249. {
  250.     struct xc_priv *tp = netdev_priv(dev);
  251.     void __iomem *ioaddr = tp->ioaddr;
  252.     return location < 8 && mii_2_8139_map[location] ?
  253.            ioread16(ioaddr+mii_2_8139_map[location]) : 0;
  254. }
  255. static void mdio_write(struct net_device *dev, int phy_id, int location,int value)
  256. {
  257.     struct xc_priv *tp = netdev_priv(dev);
  258.     void __iomem *ioaddr = tp->ioaddr;
  259.     if (location < 8 && mii_2_8139_map[location])
  260.     {
  261.         if (location == 0)
  262.         {
  263.             iowrite8(Cfg9346_Unlock,ioaddr+Cfg9346);
  264.             iowrite16(value,ioaddr+BasicModeCtrl);
  265.             iowrite8(Cfg9346_lock,ioaddr+Cfg9346);
  266.         }
  267.         else
  268.             iowrite32(value,ioaddr+mii_2_8139_map[location]);
  269.     }
  270. }
  271. /*MII*/
  272. /*ethtool*/
  273. static u32 xc_get_link(struct net_device *dev)
  274. {
  275.     struct xc_priv *tp = netdev_priv(dev);
  276.     return mii_link_ok(&tp->mii);
  277. }
  278. static int xc_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
  279. {
  280.     struct xc_priv *tp = netdev_priv(dev);
  281.     spin_lock_irq(&tp->lock);
  282.     mii_ethtool_gset(&tp->mii, cmd);
  283.     spin_unlock_irq(&tp->lock);
  284.     return 0;
  285. }
  286. static struct ethtool_ops xc_ethtool_ops =
  287. {
  288.     .get_settings       = xc_get_settings,
  289.     .get_link       = xc_get_link,
  290. };
  291. /*ethtool*/
  292. static void __set_rx_mode (struct net_device *dev)
  293. {(leave)
  294.     struct xc_priv *tp = netdev_priv(dev);
  295.     void __iomem *ioaddr = tp->ioaddr;
  296.     u32 mc_filter[2];   /* Multicast hash filter */
  297.     int i, rx_mode;
  298.     u32 tmp;
  299.     struct dev_mc_list *mclist;
  300.     rx_mode = AcceptBroadcast | AcceptMyPhys;
  301.     mc_filter[1] = mc_filter[0] = 0;
  302.     for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count;
  303.             i++, mclist = mclist->next)
  304.     {
  305.         int bit_nr = ether_crc(ETH_ALEN, mclist->dmi_addr) >> 26;
  306.         mc_filter[bit_nr >> 5] |= 1 << (bit_nr & 31);
  307.         rx_mode |= AcceptMulticast;
  308.     }
  309.     /* We can safely update without stopping the chip. */
  310.     tmp = xc_rx_config | rx_mode;
  311.     if (tp->rx_config != tmp)
  312.     {
  313.         iowrite32(tmp,ioaddr+RxConfig);
  314.         ioread32(ioaddr+RxConfig);
  315.         tp->rx_config = tmp;
  316.     }
  317.     iowrite32(mc_filter[0],ioaddr+MAR0 + 0);
  318.     iowrite32(mc_filter[1],ioaddr+MAR0 + 4);
  319. }
  320. static void xc_set_multicast_list(struct net_device *dev)
  321. {
  322.     unsigned long flags;
  323.     struct xc_priv *tp = netdev_priv(dev);
  324.     spin_lock_irqsave (&tp->lock, flags);
  325.     __set_rx_mode(dev);
  326.     spin_unlock_irqrestore (&tp->lock, flags);
  327. }
  328. /*  Setting to 1 forces the RTL8139D(L) to a software reset state
  329.     which disables the transmitter and receiver, reinitializes the FIFOs,
  330.     resets the system buffer pointer to the initial value (Tx buffer is at
  331.     TSAD0, Rx buffer is empty). 
  332. */
  333. static void xc_reset(void __iomem *ioaddr)
  334. {
  335.     int i;
  336.     /* Soft reset the chip. */
  337.     iowrite8(CmdReset,ioaddr+ChipCmd);
  338.     /* Check that the chip has finished the reset. */
  339.     for (i = 1000; i > 0; i--)
  340.     {
  341.         barrier();
  342.         if ((ioread8(ioaddr+ChipCmd) & CmdReset) == 0)
  343.             break;
  344.         udelay (10);
  345.     }
  346. }
  347. static void xc_cleanup_dev(struct net_device *dev)
  348. {
  349.     struct xc_priv *tp = netdev_priv(dev);
  350.     if (tp->pdev == NULL || dev == NULL)
  351.         return;
  352.     if (tp->ioaddr)
  353.         pci_iounmap(tp->pdev,tp->ioaddr);
  354.     pci_release_regions(tp->pdev);
  355.     free_netdev(dev);
  356.     pci_set_drvdata(tp->pdev,NULL);
  357. }
  358. static int xc_rx(struct net_device *dev, struct xc_priv *tp, int budget)
  359. {
  360.     u16 status;
  361.     struct sk_buff *skb;
  362.     int packet_size,data_size;
  363.     int work_done = 0;
  364.     void __iomem *ioaddr = tp->ioaddr;
  365.     unsigned long cur_rx = tp->cur_rx;
  366.     while (netif_running(dev) && work_done < budget && ((ioread8(ioaddr+ChipCmd) & RxBufEmpty) == 0))
  367.     {
  368.         u32 tmp_size;
  369.         u32 offset = cur_rx % RX_BUF_LEN;
  370.         rmb();
  371.         tmp_size = le32_to_cpu(*(u32 *)(tp->rx_bufs+offset));
  372.         packet_size = tmp_size >> 16;
  373.         data_size = packet_size - 4;
  374.         skb = dev_alloc_skb(data_size + 2);
  375.         if (likely(skb))
  376.         {
  377.             skb->dev = dev;
  378.             skb_reserve(skb,2);
  379.             skb_copy_to_linear_data (skb, &tp->rx_bufs[offset + 4], data_size);
  380.             skb_put(skb,data_size);
  381.             skb->protocol = eth_type_trans (skb, dev);
  382.             dev->last_rx = jiffies;
  383.             tp->stats.rx_bytes += data_size;
  384.             tp->stats.rx_packets++;
  385.             netif_receive_skb (skb);
  386.         }
  387.         else
  388.             tp->stats.rx_dropped++;
  389.         ++work_done;
  390.         /* 这里需要保持双字对齐,不过加上4干什么?*/
  391.         cur_rx = (cur_rx + packet_size + 4 + 3) & ~3;   /*更新接收offset*/
  392.         iowrite16((u16)(cur_rx - 16), ioaddr+RxBufPtr); /*更新当前包读取地址*/
  393.         status = ioread16(ioaddr+IntrStatus) & RxAckBits;
  394.         /* 在datasheet里面我看到说往isr写没有任何效果 难道我又错了*/
  395.         /* Clear out errors and receive interrupts */
  396.         if (likely(status != 0))
  397.         {
  398.             iowrite16 (RxAckBits, ioaddr+IntrStatus);
  399.             ioread16(ioaddr+IntrStatus);
  400.         }
  401.     }
  402.     tp->cur_rx = cur_rx;
  403.     return work_done;
  404. }
  405. /* 轮询, 还好不是轮fuck 这里的budget是接受数据包的最大量 */
  406. static int xc_poll(struct napi_struct *napi, int budget)
  407. {
  408.     
  409.     struct xc_priv *tp = container_of(napi, struct xc_priv, napi);
  410.     struct net_device *dev = tp->dev;
  411.     int work_done = 0;
  412.     unsigned long flags = 0;
  413.     void __iomem *ioaddr = tp->ioaddr;
  414.     if (budget <= 0)
  415.         return -1;
  416.     spin_lock(&tp->rx_lock);
  417.     if (likely(ioread16(ioaddr+IntrStatus) & RxAckBits))
  418.     {
  419.         work_done = xc_rx(dev, tp, budget);
  420.     }
  421.     /* 这里加锁且禁用中断 貌似仅仅加锁已经足够了 毕竟我们不在中断中 */
  422.     if (budget > work_done)
  423.     {
  424.         spin_lock_irqsave(&tp->lock, flags);
  425.         iowrite16(xc_intr_mask, ioaddr+IntrMask);
  426.         __netif_rx_complete(dev, napi);         /* 这里我们摘下napi中poll_list 并且清除NAPI_STATE_SCHED 的标志 */
  427.         spin_unlock_irqrestore(&tp->lock, flags);
  428.     }
  429.     spin_unlock(&tp->rx_lock);
  430.     return work_done;
  431. }
  432. /* 发送: 发送过程包括两部分,第一部分是把上层协议层传递下来的 第二部分就是把发送命令写入我们选定的寄存器 */
  433. static int xc_tx(struct sk_buff *skb, struct net_device *dev)
  434. {
  435.     struct xc_priv *tp = netdev_priv(dev);
  436.     void __iomem *ioaddr = tp->ioaddr;
  437.     unsigned int entry = tp->cur_tx % 4;        /* 这里我们要选择一个发送寄存器 注意这里的cur_tx标记的是当前选取的发送寄存器(发送寄存器有四个)*/
  438.     unsigned int len = skb->len;
  439.     /* 这里我们由于指定了发送缓冲区只能是1536 octet */
  440.     if (skb->len < 1536)    
  441.     {
  442.         if (len < ETH_ZLEN)
  443.             memset(tp->tx_buf[entry], 0, ETH_ZLEN);
  444.         /* 把skb中的内容拷贝至发送缓冲区 */
  445.         skb_copy_and_csum_dev(skb, tp->tx_buf[entry]);
  446.         dev_kfree_skb(skb);
  447.     }
  448.     else    /* 如果多于指定缓冲区大小,我们只有丢弃该数据包了 */
  449.     {
  450.         dev_kfree_skb(skb);/*释放skb*/
  451.         tp->stats.tx_dropped++;/*更新统计数据*/
  452.         return 0;
  453.     }
  454.     spin_lock_irq(&tp->lock);
  455.     /* 发送寄存器的高位是一些其他的标识 */
  456.     iowrite32(tp->tx_flag | max(len, (unsigned int)ETH_ZLEN), ioaddr+TxStatus0 + (entry * sizeof (u32)));       
  457.     dev->trans_start = jiffies;         /*设置发送开始时间*/
  458.     tp->cur_tx++;                       /*设置下一个发送要用的register ,也就是直接递增cur_tx */
  459.     wmb();
  460.     if (tp->cur_tx - 4 == tp->dirty_tx)     /* 如果发送缓冲区都满了 关闭发送队列 */
  461.         netif_stop_queue(dev);
  462.     spin_unlock_irq(&tp->lock);
  463.     return 0;
  464. }
  465. /* 这里是发送中断调用的函数, 注意这里并不是发送数据,发送数据是xc_tx所完成的,网卡发送完数据要通知cpu "hey 我这儿工作ok了",这里就是cpu的应答*/
  466. static void tx_interrupt (struct net_device *dev,
  467.                           struct xc_priv *tp,void __iomem *ioaddr)
  468. {
  469.     unsigned long dirty_tx,tx_left;
  470.     if (dev == NULL || ioaddr == NULL)
  471.         return;
  472.     dirty_tx = tp->dirty_tx;            /* dirty_tx标记的是还没有来得及发送的数据缓冲区 (cur_tx依次递增)*/
  473.     tx_left = tp->cur_tx - dirty_tx;
  474.     while (tx_left > 0)
  475.     {
  476.         int entry = dirty_tx % 4;
  477.         int txstatus;
  478.         
  479.         txstatus = ioread32(ioaddr+TxStatus0 + (entry * sizeof (u32)));
  480.         if (!(txstatus & (TxStatOK | TxUnderrun | TxAborted)))          /* 看看是否真的有缓冲区被安排发出去了 */
  481.             break;/* It still hasn't been Txed */
  482.         
  483.         dirty_tx++;
  484.         tx_left--;
  485.     }
  486.     if (tp->dirty_tx != dirty_tx)
  487.     {
  488.         tp->dirty_tx = dirty_tx;
  489.         mb();
  490.         netif_wake_queue (dev);
  491.     }
  492. }
  493. /* linux 允许多个设备共享中断号 中断处理过程是把有相同中断号的中断处理程序依次执行一遍 */
  494. static irqreturn_t xc_interrupt(int irq, void *dev_inst, struct pt_regs *regs)
  495. {
  496.     u16 status,ackstat;
  497.     struct net_device *dev = (struct net_device *)dev_inst;
  498.     struct xc_priv *tp = netdev_priv(dev);
  499.     int handle = 0;
  500.     int link_changed = 0;
  501.     void __iomem *ioaddr = tp->ioaddr;
  502.     spin_lock(&tp->lock);
  503.     /* 读取中断寄存器的状态 这样我们就可以知道是不是我们网卡发出的中断 */
  504.     status = ioread16(ioaddr+IntrStatus);
  505.     if (unlikely(status & xc_intr_mask) == 0) 
  506.       goto out;
  507.     handle = 1;
  508.     
  509.     if (unlikely(status == 0xFFFF)) 
  510.       goto out;
  511.     if (unlikely(!netif_running(dev)))
  512.     {
  513.         iowrite16(0,ioaddr+IntrMask);
  514.         goto out;
  515.     }
  516.     
  517.     if (unlikely(status & RxUnderrun))
  518.         link_changed = ioread16(ioaddr+CSCR) & 0x0800;
  519.     /* 往这个寄存器写数值貌似没什么用*/
  520.     //ackstat = status & ~(RxAckBits | TxErr);
  521.     //if (ackstat)
  522.     //  iowrite16(0, ioaddr+IntrStatus);
  523.     
  524.     if (status & RxAckBits)
  525.     {
  526.         /* schedule prepare ! 在这里我们检测两个地方 第一个是napi这个结构里面的state,有两个状态一个是 NAPI_STATE_SCHED 表示poll已被调度;另一个是NAPI——STATE_DISABLE 表示Disable pending ()*/
  527.         if (netif_rx_schedule_prep(dev, &tp->napi))
  528.         {
  529.             /* 关闭接收数据包的中断 这个是NAPI这种数据包接收方式的"规定"*/
  530.             iowrite16(xc_norx_intr_mask,ioaddr+IntrStatus);
  531.             /* 其实下面这句最终执行的就是 list_add_tail(&n->poll_list, &__get_cpu_var(softnet_data).poll_list); 也就是把napi里面的poll_list加入CPU的poll_list */
  532.             __netif_rx_schedule(dev, &tp->napi);
  533.         }
  534.     }
  535.     /* 如果是发送成功或者发送错误... */
  536.     if (status & (TxOK | TxErr))
  537.     {
  538.         tx_interrupt(dev, tp, ioaddr);
  539.         if (status & TxErr)
  540.             iowrite16(TxErr,ioaddr+IntrStatus);
  541.     }
  542. out:
  543.     spin_unlock (&tp->lock);
  544.     return IRQ_RETVAL(handle);
  545. }
  546. static void xc_hw_start(struct net_device *dev)
  547. {
  548.     int i;
  549.     u8 tmp;
  550.     struct xc_priv *tp = netdev_priv(dev);
  551.     void __iomem *ioaddr = tp->ioaddr;
  552.     if (rtl_chip_info[tp->chipset].flags & HasHltClk)
  553.         iowrite8('R',ioaddr+HltClk);
  554.     xc_reset(ioaddr);
  555.     /* 写入mac地址 */
  556.     iowrite8(Cfg9346_Unlock,ioaddr+Cfg9346);
  557.     //iowrite32(cpu_to_le32(*(u32*)(dev->dev_addr+0)),ioaddr+MAC0+0);
  558.     //iowrite32(cpu_to_le32(*(u32*)(dev->dev_addr+4)),ioaddr+MAC0+4);
  559.     /* 开启读、写*/
  560.     iowrite8(CmdRxEnb | CmdTxEnb,ioaddr+ChipCmd);
  561.     
  562.     /* 接受广播和发送给自己的地址 */
  563.     tp->rx_config = xc_rx_config | AcceptBroadcast | AcceptMyPhys;
  564.     iowrite32(tp->rx_config,ioaddr+RxConfig);
  565.     iowrite32(xc_rx_config,ioaddr+TxConfig);
  566.     tp->cur_rx = 0;
  567.     xc_check_media (dev, 1);
  568.     if (tp->chipset >= CH_8139B)
  569.         iowrite8(ioread8(ioaddr+Config3) & ~Cfg3_Magic,ioaddr+Config3);
  570.     iowrite8(Cfg9346_lock, ioaddr+Cfg9346);
  571.     /* 数据包接收地址 */
  572.     iowrite32(tp->rx_bufs_dma, ioaddr+RxBuf);
  573.     ioread32(ioaddr+RxBuf);
  574.     for (i = 0; i < 4; i++)
  575.     {
  576.         iowrite32(tp->tx_bufs_dma + (tp->tx_buf[i] - tp->tx_bufs),
  577.                   ioaddr+TxAddr0 + (i * 4));
  578.         ioread32(ioaddr+TxAddr0 + (i * 4));
  579.     }
  580.     /* 初始化 miss counter 寄存器 */
  581.     iowrite32(0,ioaddr+RxMissed);
  582.     xc_set_multicast_list(dev);
  583.     iowrite16(ioread16(ioaddr+MultiIntr) & 0xF000,ioaddr+MultiIntr);
  584.     tmp = ioread8(ioaddr+ChipCmd);
  585.     if (!(tmp & CmdRxEnb) || !(tmp & CmdTxEnb))
  586.         iowrite8(CmdRxEnb | CmdTxEnb,ioaddr+ChipCmd);
  587.     /* 开启中断 注意mask的含义*/
  588.     iowrite16(xc_intr_mask,ioaddr+IntrMask);
  589. }
  590. /* 通常在ifconfig调用 */
  591. static int xc_open(struct net_device *dev)
  592. {
  593.     int rc,i;
  594.     struct xc_priv *tp = netdev_priv(dev);;
  595.     rc = request_irq (dev->irq, xc_interrupt, IRQF_SHARED, dev->name, dev);
  596.     if (rc) 
  597.       return rc;
  598.     
  599.     /* 这里申请DMA地址 并且在tx_bufs_dma里返回了申请的总线地址 */
  600.     tp->tx_bufs = pci_alloc_consistent(tp->pdev, 1536*4, &tp->tx_bufs_dma);
  601.     tp->rx_bufs = pci_alloc_consistent(tp->pdev, RX_BUF_TOT_LEN, &tp->rx_bufs_dma);
  602.     if (tp->rx_bufs == NULL || tp->tx_bufs == NULL)
  603.     {
  604.         free_irq(dev->irq, dev);
  605.         if (tp->tx_bufs)
  606.             pci_free_consistent(tp->pdev, 1536*4,tp->tx_bufs,tp->tx_bufs_dma);
  607.         if (tp->rx_bufs)
  608.             pci_free_consistent(tp->pdev, RX_BUF_TOT_LEN,tp->rx_bufs,tp->rx_bufs_dma);
  609.         return -ENOMEM;
  610.     }
  611.     napi_enable(&tp->napi);
  612.     tp->mii.full_duplex = tp->mii.force_media;
  613.     tp->tx_flag = (256 << 11) & 0x003f0000;
  614.     /* 初始化缓冲队列*/
  615.     tp->cur_rx = 0;
  616.     tp->cur_tx = 0;
  617.     tp->dirty_tx = 0;
  618.     for (i = 0; i < 4; i++)
  619.         tp->tx_buf[i] = &tp->tx_bufs[i * 1536];
  620.     xc_hw_start(dev);
  621.     /* 开启队列 */
  622.     netif_start_queue(dev);
  623.     return 0;
  624. }
  625. static int xc_stop(struct net_device *dev)
  626. {
  627.     unsigned long flags;
  628.     struct xc_priv *tp = netdev_priv(dev);
  629.     void __iomem *ioaddr = tp->ioaddr;
  630.     netif_stop_queue(dev);
  631.     napi_disable(&tp->napi);
  632.     spin_lock_irqsave(&tp->lock,flags);
  633.     iowrite8(0,ioaddr+ChipCmd);
  634.     iowrite16(0,ioaddr+IntrMask);
  635.     tp->stats.rx_missed_errors += ioread32(ioaddr+RxMissed);
  636.     iowrite32(0,ioaddr+RxMissed);
  637.     spin_unlock_irqrestore (&tp->lock, flags);
  638.     synchronize_irq (dev->irq);/* racy, but that's ok here */
  639.     free_irq (dev->irq, dev);
  640.     tp->cur_tx = 0;
  641.     tp->dirty_tx = 0;
  642.     pci_free_consistent(tp->pdev, RX_BUF_TOT_LEN,tp->rx_bufs, tp->rx_bufs_dma);
  643.     pci_free_consistent(tp->pdev, 1536*4,tp->tx_bufs, tp->tx_bufs_dma);
  644.     tp->rx_bufs = NULL;
  645.     tp->tx_bufs = NULL;
  646.     /* Green! Put the chip in low-power mode. */
  647.     iowrite8(Cfg9346_Unlock,ioaddr+Cfg9346);
  648.     if (rtl_chip_info[tp->chipset].flags & HasHltClk)
  649.         iowrite8('H',ioaddr+HltClk);
  650.     return 0;
  651. }
  652. static struct net_device_stats *xc_get_stats (struct net_device *dev)
  653. {
  654.     struct xc_priv *tp = netdev_priv(dev);
  655.     return &tp->stats;
  656. }
  657. static void xc_tx_timeout(struct net_device *dev)
  658. {
  659.     struct xc_priv *tp = netdev_priv(dev);
  660.     void __iomem *ioaddr = tp->ioaddr;
  661.     u8 tmp8;
  662.     tmp8= ioread8(ioaddr+ChipCmd);
  663.     if (tmp8 & CmdTxEnb)
  664.         iowrite8(CmdRxEnb,ioaddr+ChipCmd);/*如果8139任开启写则关闭,只保留读*/
  665.     spin_lock_bh(&tp->rx_lock);
  666.     /* Disable interrupts by clearing the interrupt mask. */
  667.     iowrite16(0x0000,ioaddr+IntrMask);
  668.     /* Stop a shared interrupt from scavenging while we are. */
  669.     spin_lock_irq(&tp->lock);
  670.     tp->cur_tx = 0;
  671.     tp->dirty_tx = 0;
  672.     spin_unlock_irq(&tp->lock);
  673.     if (netif_running(dev))
  674.     {/*重新设置8139所有信息*/
  675.         xc_hw_start (dev);
  676.         netif_wake_queue (dev);
  677.     }
  678.     spin_unlock_bh(&tp->rx_lock);
  679. }
  680. /* 初始化网卡设备 */
  681. static int __devinit xc_board(struct pci_dev *pdev,struct net_device **dev_out)
  682. {
  683.     struct net_device *dev;
  684.     struct xc_priv *tp;
  685.     void __iomem *ioaddr;
  686.     int rc,dev_on,i;
  687.     u32 version;
  688.     u8 tmp;
  689.     if (pdev == NULL)
  690.         return -1;
  691.     dev_on = 0;
  692.     *dev_out = NULL;
  693.     dev = alloc_etherdev(sizeof(*tp));
  694.     if (dev == NULL)
  695.         return -ENOMEM;
  696.     //dev->owner = THIS_MODULE;
  697.     SET_NETDEV_DEV(dev, &pdev->dev);
  698.     tp = netdev_priv(dev);
  699.     tp->pdev = pdev;
  700.     tp->dev = dev;
  701.     
  702.     rc = pci_enable_device(pdev);
  703.     if (rc) 
  704.       goto err_out;
  705.     rc = pci_request_regions (pdev, "xc8139too");
  706.     if (rc) 
  707.       goto err_out;
  708.     
  709.     dev_on = 1;
  710.     
  711.         /*
  712.          * PCI网卡被BIOS配置后,某些特性可能会被屏蔽掉。比如,多数BIOS都会清掉“master”位,
  713.          * 这导致板卡不能随意向主存中拷贝数据。pci_set_master函数数会检查是否需要设置标志位,
  714.          * 如果需要,则会将“master”位置位。
  715.          * PS:什么是PCI master?
  716.          * 不同于ISA总线,PCI总线的地址总线与数据总线是分时复用的。这样做的好处是,一方面
  717.          * 可以节省接插件的管脚数,另一方面便于实现突发数据传输。在做数据传输时,由一个PCI
  718.          * 设备做发起者(主控,Initiator或Master),而另一个PCI设备做目标(从设备,Target或Slave)。
  719.          * 总线上的所有时序的产生与控制,都由Master来发起。PCI总线在同一时刻只能供一对设备完成传输。
  720.          */
  721.     pci_set_master (pdev);
  722.     ioaddr = pci_iomap(pdev, 1, 0);
  723.     if (ioaddr == NULL)
  724.     {
  725.         rc = -EIO;
  726.         goto err_out;
  727.     }
  728.     tp->ioaddr = ioaddr;
  729.     dev->base_addr = (long)ioaddr;
  730.     iowrite8('R',ioaddr+HltClk);
  731.     
  732.     /*为什么这样能判断出来?*/
  733.     if (ioread32(ioaddr+TxConfig) == 0xFFFFFFFF)
  734.     {
  735.         rc = -EIO;
  736.         goto err_out;
  737.     }
  738.     /* 判断网卡型号 */
  739.     version = ioread32(ioaddr+TxConfig) & HW_REVID_MASK;
  740.     for (i=0;i<ARRAY_SIZE(rtl_chip_info);++i)
  741.         if (version == rtl_chip_info[i].version)
  742.         {
  743.             tp->chipset = i;
  744.             goto match;
  745.         }
  746.     tp->chipset = 0;
  747.     
  748.     /*      这里设置为默认的方式 active high
  749.      *
  750.      *      摘抄自datasheet 
  751.      *
  752.      *      The LWACT bit and LWPTN bit in CONFIG4 register
  753.             are used to program the LWAKE pin’s output signal. According to the
  754.             combination of these two bits, there may be 4 choices of LWAKE signal, i.e.,
  755.             active high, active low, positive (high) pulse, and negative (low) pulse. The
  756.             output pulse width is about 150ms.
  757.     */
  758. match:
  759.     if (tp->chipset >= CH_8139B)
  760.     {
  761.         u8 ntmp = tmp = ioread8(ioaddr+Config1);
  762.         /*  Software may use this bit to make sure that the driver has been loaded 这样我们可以确保驱动加载 */
  763.         if ((rtl_chip_info[tp->chipset].flags & HasLWake) && (ntmp & LWAKE))
  764.             ntmp = ntmp & ~LWAKE;
  765.         ntmp = ntmp | Cfg1_PM_Enable;           //这里我们要开启电源管理
  766.         if (ntmp != tmp)
  767.         {
  768.             iowrite8(Cfg9346_Unlock,ioaddr+Cfg9346);
  769.             iowrite8(ntmp,ioaddr+Config1);
  770.             iowrite8(Cfg9346_lock,ioaddr+Cfg9346);
  771.         }
  772.         if (rtl_chip_info[tp->chipset].flags & HasLWake)
  773.         {
  774.             tmp = ioread8(ioaddr+Config4);
  775.             if (tmp & LWPTN)
  776.             {
  777.                 iowrite8(Cfg9346_Unlock,ioaddr+Cfg9346);
  778.                 iowrite8(tmp & ~LWPTN,ioaddr+Config4);
  779.                 iowrite8(Cfg9346_lock,ioaddr+Cfg9346);
  780.             }
  781.         }
  782.     }
  783.     else
  784.     {
  785.         tmp = ioread8(ioaddr+Config1);
  786.         tmp = tmp & ~((1 << 1) | (1 << 0));
  787.         iowrite8(tmp,ioaddr+Config1);
  788.     }
  789.     xc_reset(ioaddr);
  790.     *dev_out = dev;
  791.     return 0;
  792. err_out:
  793.     xc_cleanup_dev (dev);
  794.     if (dev_on)
  795.         pci_disable_device(pdev);
  796.     return rc;
  797. }
  798. static int __devinit xc_probe(struct pci_dev *pdev,const struct pci_device_id *ent)
  799. {
  800.     int i;
  801.     struct xc_priv *tp;
  802.     void __iomem *ioaddr;
  803.     struct net_device *dev = NULL;
  804.     int rc,option;
  805.     static int index = -1;
  806.     if (pdev == NULL || ent == NULL)
  807.         return -ENODEV;
  808.     ++index;
  809.     rc = xc_board(pdev,&dev);
  810.     if (rc < 0)
  811.         return rc;
  812.     if (dev == NULL)
  813.         return -1;
  814.     tp = netdev_priv(dev);
  815.     ioaddr = tp->ioaddr;
  816.     if (ioaddr == NULL)
  817.         return -1;
  818.     if (!dev->addr_len)
  819.     {
  820.         printk(KERN_INFO "XC:%i:dev->addr_len is set here/n",dev->addr_len);
  821.         dev->addr_len = 6;
  822.     }
  823.     /*硬件mac地址*/
  824.     
  825.     ((u32 *)dev->dev_addr)[0] = ioread32(ioaddr + MAC0) ;
  826.     ((u16 *)dev->dev_addr)[2] = ioread32(ioaddr + MAC0 + 4);
  827.     memcpy(dev->perm_addr,dev->dev_addr,dev->addr_len);
  828.     
  829.     /*dev function init*/
  830.     dev->open       = xc_open;
  831.     dev->stop       = xc_stop;
  832.     dev->hard_start_xmit    = xc_tx;
  833.     netif_napi_add(dev, &tp->napi, xc_poll, 64);
  834.     dev->get_stats      = xc_get_stats;
  835.     dev->set_multicast_list = xc_set_multicast_list;
  836.     dev->do_ioctl       = NULL;
  837.     dev->ethtool_ops    = &xc_ethtool_ops;
  838.     dev->tx_timeout     = xc_tx_timeout;
  839.     dev->watchdog_timeo = 6*HZ;
  840.     /* 如果你的接口可以发送一个报文, 它由几个不同的内存段组成, 你应当设置 NETIF_F_SG
  841.      * 如果你的硬件自己做校验, 设置 NETIF_F_HW_CWSUM.
  842.      * 设置这个标志, 如果你的设备能够对高端内存进行 DMA.
  843.      */
  844.     dev->features       |= NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_HIGHDMA;
  845.     /* 这里设置中断号,其实内核在初始化的时候已经为设备分配好了中断号*/
  846.     dev->irq        = pdev->irq;
  847.     tp      = netdev_priv(dev);
  848.     ioaddr      = tp->ioaddr;
  849.     /* 不知道什么意思 */
  850.     tp->msg_enable  = NETIF_MSG_DRV | NETIF_MSG_PROBE | NETIF_MSG_LINK;
  851.     spin_lock_init(&tp->lock);
  852.     spin_lock_init(&tp->rx_lock);
  853.     /* 不是特别清楚 */
  854.     tp->mii.dev     = dev;
  855.     tp->mii.mdio_read   = mdio_read;
  856.     tp->mii.mdio_write  = mdio_write;
  857.     tp->mii.phy_id_mask = 0x3f;     //
  858.     tp->mii.reg_num_mask    = 0x1f;
  859.     
  860.     rc = register_netdev(dev);
  861.     if (rc) 
  862.       goto err_out;
  863.     
  864.     pci_set_drvdata (pdev, dev);
  865.     printk (KERN_INFO "%s:0x%lx--%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x,IRQ %d/n",
  866.             dev->name,dev->base_addr,dev->dev_addr[0], dev->dev_addr[1],
  867.             dev->dev_addr[2], dev->dev_addr[3],dev->dev_addr[4], dev->dev_addr[5],
  868.             dev->irq);
  869.     printk (KERN_DEBUG "%s:  Identified 8139 chip type '%s'/n",
  870.             dev->name, rtl_chip_info[tp->chipset].name);
  871.     /* */
  872.     /*MII define*/
  873.     tp->phys[0] = 32;
  874.     tp->mii.phy_id = tp->phys[0];
  875.     /* The lower four bits are the media type. */
  876.     option = (index >= 8) ? 0 : -1;
  877.     if (tp->mii.full_duplex)
  878.     {
  879.         printk(KERN_INFO "%s: Media type forced to Full Duplex./n", dev->name);
  880.         /* Changing the MII-advertised media because might prevent
  881.            re-connection. */
  882.         tp->mii.force_media = 1;
  883.     }
  884.     if (tp->default_port)
  885.     {
  886.         printk(KERN_INFO "  Forcing %dMbps %s-duplex operation./n",
  887.                (option & 0x20 ? 100 : 10),
  888.                (option & 0x10 ? "full" : "half"));
  889.         mdio_write(dev, tp->phys[0], 0,
  890.                    ((option & 0x20) ? 0x2000 : 0) |     /* 100Mbps? */
  891.                    ((option & 0x10) ? 0x0100 : 0)); /* Full duplex? */
  892.     }
  893.     /*MII*/
  894.     if (rtl_chip_info[tp->chipset].flags & HasHltClk)
  895.         iowrite8('H',ioaddr+HltClk);
  896.     return 0;
  897. err_out:
  898.     xc_cleanup_dev (dev);
  899.     pci_disable_device (pdev);
  900.     return rc;
  901. }
  902. static void __devexit xc_remove(struct pci_dev *pdev)
  903. {
  904.     struct net_device *dev = pci_get_drvdata(pdev);
  905.     unregister_netdev(dev);
  906.     xc_cleanup_dev(dev);
  907.     pci_disable_device(pdev);
  908. }
  909. struct pci_driver xc_driver =
  910. {
  911.     .name       = "xc8139too",
  912.     .id_table   = xc_id,
  913.     .probe      = xc_probe,
  914.     .remove     = __devexit_p(xc_remove),
  915. };
  916. static int __init xc_module_init(void)
  917. {
  918.     return pci_register_driver(&xc_driver);
  919. }
  920. static void __exit xc_module_exit(void)
  921. {
  922.     pci_unregister_driver(&xc_driver);
  923. }
  924. module_init(xc_module_init);
  925. module_exit(xc_module_exit);

GitHub 加速计划 / li / linux-dash
10.39 K
1.2 K
下载
A beautiful web dashboard for Linux
最近提交(Master分支:2 个月前 )
186a802e added ecosystem file for PM2 4 年前
5def40a3 Add host customization support for the NodeJS version 4 年前
Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐