Chinaunix首页 | 论坛 | 博客
  • 博客访问: 498894
  • 博文数量: 223
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 2145
  • 用 户 组: 普通用户
  • 注册时间: 2014-03-01 10:23
个人简介

该坚持的时候坚持,该妥协的时候妥协,该放弃的时候放弃

文章分类

全部博文(223)

文章存档

2017年(56)

2016年(118)

2015年(3)

2014年(46)

我的朋友

分类: 嵌入式

2016-11-20 22:08:27

1.Linux网络子系统

 系统调用接口层
为应用程序提供访问网络子系统的统一方法。
 协议无关层
提供通用的方法来使用传输层协议。
 协议栈的实现
实现具体的网络协议
 设备无关层
协议与设备驱动之前通信的通用接口
 设备驱动程序

2.重要数据结构 
2.1 网卡描述结构
在Linux内核中,每个网卡都由一个net_device结构来描述,其中的一些重要成员有:
  char name[IFNAMSIZ]
设备名,如:eth%d
  unsigned long base_addr
I/O 基地址
  const struct net_device_ops *netdev_ops;
记录了网卡所支持的操作

2.2 网卡操作集合
类似于字符设备驱动中的file_operations结构,net_device_ops结构记录了网卡所支持的操作。
static const struct net_device_ops dm9000_netdev_ops =
{
    .ndo_open = dm9000_open,
    .ndo_stop = dm9000_stop,
    .ndo_start_xmit = dm9000_start_xmit,
    .ndo_do_ioctl = dm9000_ioctl,
    .ndo_validate_addr = eth_validate_addr,
    .ndo_set_mac_address = eth_mac_addr,
};

2.3 网络数据包
Linux内核中的每个网络数据包都由一个套接字缓冲区结构 struct sk_buff 描述,即一个sk_buff结构就是一个网络包,指向sk_buff的指针通常被称做skb。



3.网卡驱动架构分析 
cs89x0.c:

  1. /* cs89x0.c: A Crystal Semiconductor (Now Cirrus Logic) CS89[02]0
  2.  * driver for linux.
  3.  */


  4. static const struct net_device_ops net_ops = {                                                                     //net_device_ops结构,各种网卡操作函数接口
  5.     .ndo_open        = net_open,
  6.     .ndo_stop        = net_close,
  7.     .ndo_tx_timeout        = net_timeout,
  8.     .ndo_start_xmit     = net_send_packet,
  9.     .ndo_get_stats        = net_get_stats,
  10.     .ndo_set_multicast_list = set_multicast_list,
  11.     .ndo_set_mac_address     = set_mac_address,
  12. #ifdef CONFIG_NET_POLL_CONTROLLER
  13.     .ndo_poll_controller    = net_poll_controller,
  14. #endif
  15.     .ndo_change_mtu        = eth_change_mtu,
  16.     .ndo_validate_addr    = eth_validate_addr,
  17. };

  18. static netdev_tx_t net_send_packet(struct sk_buff *skb,struct net_device *dev)                                     //网卡的发送函数
  19. {
  20.     struct net_local *lp = netdev_priv(dev);
  21.     unsigned long flags;

  22.     if (net_debug > 3) {
  23.         printk("%s: sent %d byte packet of type %x\n",
  24.             dev->name, skb->len,
  25.             (skb->data[ETH_ALEN+ETH_ALEN] << 8) | skb->data[ETH_ALEN+ETH_ALEN+1]);
  26.     }

  27.     /* keep the upload from being interrupted, since we
  28.                   ask the chip to start transmitting before the
  29.                   whole packet has been completely uploaded. */

  30.     spin_lock_irqsave(&lp->lock, flags);
  31.     netif_stop_queue(dev);                                                                                         //驱动程序通知网络子系统暂停数据包传输,从来进行实现流量控制。

  32.     /* initiate a transmit sequence */
  33.     writeword(dev->base_addr, TX_CMD_PORT, lp->send_cmd);
  34.     writeword(dev->base_addr, TX_LEN_PORT, skb->len);

  35.     /* Test to see if the chip has allocated memory for the packet */
  36.     if ((readreg(dev, PP_BusST) & READY_FOR_TX_NOW) == 0) {
  37.         /*
  38.          * It hasn't. But that shouldn't happen since
  39.          * we're waiting for TxOk, so return 1 and requeue this packet.
  40.          */

  41.         spin_unlock_irqrestore(&lp->lock, flags);
  42.         if (net_debug) printk("cs89x0: Tx buffer not free!\n");
  43.         return NETDEV_TX_BUSY;
  44.     }
  45.     /* Write the contents of the packet */
  46.     writewords(dev->base_addr, TX_FRAME_PORT,skb->data,(skb->len+1) >>1);                                         //将skb的内容写入寄存器,发送
  47.     spin_unlock_irqrestore(&lp->lock, flags);
  48.     dev->stats.tx_bytes += skb->len;
  49.     dev_kfree_skb (skb);                                                                                          //释放skb

  50.     /*
  51.      * We DO NOT call netif_wake_queue() here.
  52.      * We also DO NOT call netif_start_queue().
  53.      *
  54.      * Either of these would cause another bottom half run through
  55.      * net_send_packet() before this packet has fully gone out. That causes
  56.      * us to hit the "Gasp!" above and the send is rescheduled. it runs like
  57.      * a dog. We just return and wait for the Tx completion interrupt handler
  58.      * to restart the netdevice layer
  59.      */

  60.     return NETDEV_TX_OK;
  61. }

  62. /* The typical workload of the driver:
  63.    Handle the network interface interrupts. */

  64. static irqreturn_t net_interrupt(int irq, void *dev_id)                                                                   //网卡中断处理函数
  65. {
  66.     struct net_device *dev = dev_id;
  67.     struct net_local *lp;
  68.     int ioaddr, status;
  69.      int handled = 0;

  70.     ioaddr = dev->base_addr;
  71.     lp = netdev_priv(dev);

  72.     /* we MUST read all the events out of the ISQ, otherwise we'll never
  73.            get interrupted again. As a consequence, we can't have any limit
  74.            on the number of times we loop in the interrupt handler. The
  75.            hardware guarantees that eventually we'll run out of events. Of
  76.            course, if you're on a slow machine, and packets are arriving
  77.            faster than you can read them off, you're screwed. Hasta la
  78.            vista, */
  79.     while ((status = readword(dev->base_addr, ISQ_PORT))) {
  80.         if (net_debug > 4)printk("%s: event=%04x\n", dev->name, status);
  81.         handled = 1;
  82.         switch(status & ISQ_EVENT_MASK) {
  83.         case ISQ_RECEIVER_EVENT:
  84.             /* Got a packet(s). */
  85.             net_rx(dev);
  86.             break;
  87.         case ISQ_TRANSMITTER_EVENT:
  88.             dev->stats.tx_packets++;
  89.             netif_wake_queue(dev);    /* Inform upper layers. */                                                         //发送中停止设备,在这里被唤醒
  90.             if ((status & (    TX_OK |
  91.                     TX_LOST_CRS |
  92.                     TX_SQE_ERROR |
  93.                     TX_LATE_COL |
  94.                     TX_16_COL)) != TX_OK) {
  95.                 if ((status & TX_OK) == 0)
  96.                     dev->stats.tx_errors++;
  97.                 if (status & TX_LOST_CRS)
  98.                     dev->stats.tx_carrier_errors++;
  99.                 if (status & TX_SQE_ERROR)
  100.                     dev->stats.tx_heartbeat_errors++;
  101.                 if (status & TX_LATE_COL)
  102.                     dev->stats.tx_window_errors++;
  103.                 if (status & TX_16_COL)
  104.                     dev->stats.tx_aborted_errors++;
  105.             }
  106.             break;
  107.         case ISQ_BUFFER_EVENT:
  108.             if (status & READY_FOR_TX) {
  109.                 /* we tried to transmit a packet earlier,
  110.                                    but inexplicably ran out of buffers.
  111.                                    That shouldn't happen since we only ever
  112.                                    load one packet. Shrug. Do the right
  113.                                    thing anyway. */
  114.                 netif_wake_queue(dev);    /* Inform upper layers. */
  115.             }
  116.             if (status & TX_UNDERRUN) {
  117.                 if (net_debug > 0) printk("%s: transmit underrun\n", dev->name);
  118.                                 lp->send_underrun++;
  119.                                 if (lp->send_underrun == 3) lp->send_cmd = TX_AFTER_381;
  120.                                 else if (lp->send_underrun == 6) lp->send_cmd = TX_AFTER_ALL;
  121.                 /* transmit cycle is done, although
  122.                  frame wasn't transmitted - this
  123.                  avoids having to wait for the upper
  124.                  layers to timeout on us, in the
  125.                  event of a tx underrun */
  126.                 netif_wake_queue(dev);    /* Inform upper layers. */
  127.                         }
  128. #if ALLOW_DMA
  129.             if (lp->use_dma && (status & RX_DMA)) {
  130.                 int count = readreg(dev, PP_DmaFrameCnt);
  131.                 while(count) {
  132.                     if (net_debug > 5)
  133.                         printk("%s: receiving %d DMA frames\n", dev->name, count);
  134.                     if (net_debug > 2 && count >1)
  135.                         printk("%s: receiving %d DMA frames\n", dev->name, count);
  136.                     dma_rx(dev);
  137.                     if (--count == 0)
  138.                         count = readreg(dev, PP_DmaFrameCnt);
  139.                     if (net_debug > 2 && count > 0)
  140.                         printk("%s: continuing with %d DMA frames\n", dev->name, count);
  141.                 }
  142.             }
  143. #endif
  144.             break;
  145.         case ISQ_RX_MISS_EVENT:
  146.             dev->stats.rx_missed_errors += (status >> 6);
  147.             break;
  148.         case ISQ_TX_COL_EVENT:
  149.             dev->stats.collisions += (status >> 6);
  150.             break;
  151.         }
  152.     }
  153.     return IRQ_RETVAL(handled);
  154. }
  155.   
  156.      ...........

  157. /* We have a good packet(s), get it/them out of the buffers. */
  158. static void
  159. net_rx(struct net_device *dev)                                                                                             //网卡的接收函数
  160. {
  161.     struct sk_buff *skb;
  162.     int status, length;

  163.     int ioaddr = dev->base_addr;
  164.     status = readword(ioaddr, RX_FRAME_PORT);                                                                              //读取待接收的数据状态
  165.     length = readword(ioaddr, RX_FRAME_PORT);                                                                              //读取接收数据的长度

  166.     if ((status & RX_OK) == 0) {
  167.         count_rx_errors(status, dev);
  168.         return;
  169.     }

  170.     /* Malloc up new buffer. */
  171.     skb = dev_alloc_skb(length + 2);                                                                                       //分配skb长度+2的结构
  172.     if (skb == NULL) {
  173. #if 0        /* Again, this seems a cruel thing to do */
  174.         printk(KERN_WARNING "%s: Memory squeeze, dropping packet.\n", dev->name);
  175. #endif
  176.         dev->stats.rx_dropped++;
  177.         return;
  178.     }
  179.     skb_reserve(skb, 2);    /* longword align L3 header */

  180.     readwords(ioaddr, RX_FRAME_PORT, skb_put(skb, length), length >> 1);                                                    //从网卡寄存器中读出数据,存入skb
  181.     if (length & 1)
  182.         skb->data[length-1] = readword(ioaddr, RX_FRAME_PORT);

  183.     if (net_debug > 3) {
  184.         printk(    "%s: received %d byte packet of type %x\n",
  185.             dev->name, length,
  186.             (skb->data[ETH_ALEN+ETH_ALEN] << 8) | skb->data[ETH_ALEN+ETH_ALEN+1]);
  187.     }

  188.         skb->protocol=eth_type_trans(skb,dev);
  189.     netif_rx(skb);                                                                                                          //将接收到的数据包skb交给协议栈-netif_rx
  190.     dev->stats.rx_packets++;
  191.     dev->stats.rx_bytes += length;
  192. }

  193. #if ALLOW_DMA
  194. static void release_dma_buff(struct net_local *lp)
  195. {
  196.     if (lp->dma_buff) {
  197.         free_pages((unsigned long)(lp->dma_buff), get_order(lp->dmasize * 1024));
  198.         lp->dma_buff = NULL;
  199.     }
  200. }
  201. #endif

  202. /* The inverse routine to net_open(). */
  203. static int
  204. net_close(struct net_device *dev)
  205. {
  206. #if ALLOW_DMA
  207.     struct net_local *lp = netdev_priv(dev);
  208. #endif

  209.     netif_stop_queue(dev);

  210.     writereg(dev, PP_RxCFG, 0);
  211.     writereg(dev, PP_TxCFG, 0);
  212.     writereg(dev, PP_BufCFG, 0);
  213.     writereg(dev, PP_BusCTL, 0);

  214.     free_irq(dev->irq, dev);

  215. #if ALLOW_DMA
  216.     if (lp->use_dma && lp->dma) {
  217.         free_dma(dev->dma);
  218.         release_dma_buff(lp);
  219.     }
  220. #endif

  221.     /* Update the statistics here. */
  222.     return 0;
  223. }
  224.    
  225.       
  226.    ........

  227. int __init init_module(void)                                                                               //网卡初始化
  228. {
  229.     struct net_device *dev = alloc_etherdev(sizeof(struct net_local));                                     //分配net_device结构空间
  230.     struct net_local *lp;
  231.     int ret = 0;

  232. #if DEBUGGING
  233.     net_debug = debug;
  234. #else
  235.     debug = 0;
  236. #endif
  237.     if (!dev)
  238.         return -ENOMEM;

  239.     dev->irq = irq;                                                                                        //初始化分配的dev
  240.     dev->base_addr = io;
  241.     lp = netdev_priv(dev);

  242. #if ALLOW_DMA
  243.     if (use_dma) {
  244.         lp->use_dma = use_dma;
  245.         lp->dma = dma;
  246.         lp->dmasize = dmasize;
  247.     }
  248. #endif

  249.     spin_lock_init(&lp->lock);

  250.         /* boy, they'd better get these right */
  251.         if (!strcmp(media, "rj45"))
  252.         lp->adapter_cnf = A_CNF_MEDIA_10B_T | A_CNF_10B_T;
  253.     else if (!strcmp(media, "aui"))
  254.         lp->adapter_cnf = A_CNF_MEDIA_AUI | A_CNF_AUI;
  255.     else if (!strcmp(media, "bnc"))
  256.         lp->adapter_cnf = A_CNF_MEDIA_10B_2 | A_CNF_10B_2;
  257.     else
  258.         lp->adapter_cnf = A_CNF_MEDIA_10B_T | A_CNF_10B_T;

  259.         if (duplex==-1)
  260.         lp->auto_neg_cnf = AUTO_NEG_ENABLE;

  261.         if (io == 0) {
  262.                 printk(KERN_ERR "cs89x0.c: Module autoprobing not allowed.\n");
  263.                 printk(KERN_ERR "cs89x0.c: Append io=0xNNN\n");
  264.                 ret = -EPERM;
  265.         goto out;
  266.         } else if (io <= 0x1ff) {
  267.         ret = -ENXIO;
  268.         goto out;
  269.     }

  270. #if ALLOW_DMA
  271.     if (use_dma && dmasize != 16 && dmasize != 64) {
  272.         printk(KERN_ERR "cs89x0.c: dma size must be either 16K or 64K, not %dK\n", dmasize);
  273.         ret = -EPERM;
  274.         goto out;
  275.     }
  276. #endif
  277.     ret = cs89x0_probe1(dev, io, 1);                                                                                //这里依然在初始化:硬件初始化、MAC地址、注册网卡驱动(register_netdev)
  278.     if (ret)
  279.         goto out;

  280.     dev_cs89x0 = dev;
  281.     return 0;
  282. out:
  283.     free_netdev(dev);
  284.     return ret;
  285. }

  286. void __exit
  287. cleanup_module(void)
  288. {
  289.     unregister_netdev(dev_cs89x0);
  290.     writeword(dev_cs89x0->base_addr, ADD_PORT, PP_ChipID);
  291.     release_region(dev_cs89x0->base_addr, NETCARD_IO_EXTENT);
  292.     free_netdev(dev_cs89x0);
  293. }
  294. #endif /* MODULE */

  295. /*
  296.  * Local variables:
  297.  * version-control: t
  298.  * kept-new-versions: 5
  299.  * c-indent-level: 8
  300.  * tab-width: 8
  301.  * End:
  302.  *
  303.  */

阅读(782) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~