Linux kernel--Network stack Implementation Analysis (11)--Driver layer (bottom)

Source: Internet
Author: User

This paper analyzes Linux Kernel 1.2.13 based on

Original works, reproduced please mark http://blog.csdn.net/yming0221/article/details/7555870

See column, Address http://blog.csdn.net/column/details/linux-kernel-net.html

Shuming

Note: In the title, "(UP)", "(bottom)" means that the analysis process is based on the delivery direction of the packet: "(top)" means that the analysis is parsed from the bottom up, and "(bottom)" indicates that the analysis is parsed from the top down.

In the blog post Linux kernel--Network stack Implementation Analysis (iii)--The driver layer (link layer) (above) on the network device structure, network device initialization functions such as a preliminary understanding, and lists the device's send and receive functions.

The device interface layer calls the function device driver layer Ei_start_xmit () function to send data, and there is no detailed analysis.

[CPP]View Plaincopy
  1. static int ei_start_xmit (struct sk_buff *skb, struct device *dev)
  2. {
  3. int e8390_base = dev->base_addr;
  4. struct Ei_device *ei_local = (struct Ei_device *) dev->priv;//Remove the private data of the network card device, and the specific NIC model, in the Ethdev_init () function has allocated space
  5. int length, send_length;
  6. unsigned long flags;
  7. /*
  8. * We normally shouldn ' t be called if dev->tbusy are set, but the
  9. * Existing code does anyway. If It has been too long since the
  10. * Last Tx, we assume the board have died and kick it.
  11. */
  12. if (dev->tbusy) {/* timeouts, just like the 8003 driver. */
  13. ........................................
  14. ........................................
  15. }
  16. /* Sending a NULL SKB means some higher layer thinks we ' ve missed an
  17. Tx-done interrupt. Caution:dev_tint () handles the CLI ()/sti ()
  18. itself. */
  19. if (SKB = = NULL) {//The condition does not seem to occur, which is used to handle bugs in the kernel
  20. Dev_tint (dev);//Send all cached packets in the device
  21. return 0;
  22. }
  23. Length = skb->len;
  24. if (skb->len <= 0)
  25. return 0;
  26. Save_flags (flags);
  27. CLI ();
  28. /* Block a timer-based transmit from overlapping. */
  29. if ((Set_bit (0, (void*) &dev->tbusy)! = 0) | | ei_local->irqlock) {
  30. PRINTK ("%S:TX access conflict. irq=%d lock=%d tx1=%d tx2=%d last=%d\n ",
  31. Dev->name, Dev->interrupt, Ei_local->irqlock, EI_LOCAL->TX1,
  32. EI_LOCAL->TX2, EI_LOCAL->LASTTX);
  33. Restore_flags (flags);
  34. return 1;
  35. }
  36. /* Mask interrupts from the Ethercard. */
  37. Outb (0x00, e8390_base + EN0_IMR);
  38. Ei_local->irqlock = 1;
  39. Restore_flags (flags);
  40. Send_length = Eth_zlen < length? Length:eth_zlen;
  41. if (Ei_local->pingpong) {
  42. int output_page;
  43. if (ei_local->tx1 = = 0) {
  44. Output_page = ei_local->tx_start_page;
  45. EI_LOCAL->TX1 = Send_length;
  46. if (ei_debug && ei_local->tx2 > 0)
  47. PRINTK ("%s:idle transmitter tx2=%d, lasttx=%d, txing=%d.\n",
  48. Dev->name, EI_LOCAL->TX2, EI_LOCAL->LASTTX,
  49. ei_local->txing);
  50. } else if (ei_local->tx2 = = 0) {
  51. Output_page = ei_local->tx_start_page + 6;
  52. EI_LOCAL->TX2 = Send_length;
  53. if (ei_debug && ei_local->tx1 > 0)
  54. PRINTK ("%s:idle transmitter, tx1=%d, lasttx=%d, txing=%d.\n",
  55. Dev->name, EI_LOCAL->TX1, EI_LOCAL->LASTTX,
  56. ei_local->txing);
  57. } else {/* We should never get here. */
  58. if (Ei_debug)
  59. PRINTK ("%s:no Tx buffers free. irq=%d tx1=%d tx2=%d last=%d\n ",
  60. Dev->name, Dev->interrupt, EI_LOCAL->TX1,
  61. EI_LOCAL->TX2, EI_LOCAL->LASTTX);
  62. Ei_local->irqlock = 0;
  63. Dev->tbusy = 1;
  64. Outb_p (Enisr_all, e8390_base + EN0_IMR);
  65. return 1;
  66. }
  67. Ei_block_output (Dev, length, skb->data, output_page);
  68. if (! ei_local->txing) {
  69. ei_local->txing = 1;
  70. Ns8390_trigger_send (Dev, send_length, output_page);
  71. Dev->trans_start = jiffies;
  72. if (output_page = = ei_local->tx_start_page)
  73. EI_LOCAL->TX1 =-1, Ei_local->lasttx =-1;
  74. Else
  75. EI_LOCAL->TX2 =-1, Ei_local->lasttx =-2;
  76. } else
  77. ei_local->txqueue++;
  78. Dev->tbusy = (ei_local->tx1 && ei_local->tx2);
  79. } else {/* No pingpong, just a single Tx buffer. */
  80. Ei_block_output (Dev, length, skb->data, ei_local->tx_start_page);
  81. ei_local->txing = 1;
  82. Ns8390_trigger_send (Dev, send_length, ei_local->tx_start_page);
  83. Dev->trans_start = jiffies;
  84. Dev->tbusy = 1;
  85. }
  86. /* Turn 8390 interrupts back on. */
  87. Ei_local->irqlock = 0;
  88. Outb_p (Enisr_all, e8390_base + EN0_IMR);
  89. DEV_KFREE_SKB (SKB, free_write);
  90. return 0;

One of the Dev_tint () functions is to send all of the data from all the cache queues in the device to Dev_queue_xmit ().

[CPP]View Plaincopy
  1. /*
  2. * This routine was called when an device driver (i.e. an
  3. * interface) is transmit a packet.
  4. */
  5. Function: Traverse the buffer queue of the device, send data to all packets called dev_queue_xmit () function
  6. void Dev_tint (struct device *dev)
  7. {
  8. int i;
  9. struct Sk_buff *skb;
  10. unsigned long flags;
  11. Save_flags (flags);
  12. /*
  13. * Work the queues in priority order
  14. */
  15. for (i = 0;i < dev_numbuffs; i++)
  16. {
  17. /*
  18. * Pull packets from the queue
  19. */
  20. CLI ();
  21. while ((Skb=skb_dequeue (&dev->buffs[i))!=null)
  22. {
  23. /*
  24. * Stop anyone freeing the buffer while we retransmit it
  25. */
  26. Skb_device_lock (SKB);
  27. Restore_flags (flags);
  28. /*
  29. * Feed them to the output stage and if it fails
  30. * Indicate they re-queue at the front.
  31. */
  32. Dev_queue_xmit (skb,dev,-i-1);//Pay attention to the calculation of the priority, in the function dev_queue_xmit () Priority if <0 is calculated pri=-pri-1=-(-i-1) -1=i,
  33. The purpose of this is to get the correct where value in the function (Dev_queue_xmit ())
  34. /*
  35. * If We can take no further then stop here.
  36. */
  37. if (dev->tbusy)
  38. Return
  39. CLI ();
  40. }
  41. }
  42. Restore_flags (flags);
  43. }

The driving layer is strictly not the content of the kernel network stack, and the hardware is closely related, not to mention this network card hardware equipment may have been used, there is no detailed analysis, if you are interested in network card driver can look at the analysis of the Arm-linux under the DM9000 network card driver analysis, links as follows:

      1. Arm-linux Drive analysis of driver--dm9000 NIC (i)
      2. Driver analysis of Arm-linux Drive--dm9000 NIC (ii)
      3. Driver analysis of Arm-linux Drive--dm9000 network card (iii)
      4. Arm-linux Driving analysis of--dm9000 network card driver (four)

Linux kernel--Network stack Implementation Analysis (11)--Driver layer (bottom)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.