7. Operations

This is a list of all of the operations involved in sending and receiving packets, across both hardware and software.

7.1. Packet transmission

  1. linux: The linux kernel calls mqnic_start_xmit() (via ndo_start_xmit()) with an sk_buff for transmission

  2. mqnic_start_xmit() (mqnic_tx.c): The driver determines the destination transmit queue with skb_get_queue_mapping

  3. mqnic_start_xmit() (mqnic_tx.c): The driver marks the sk_buff for timestamping, if requested

  4. mqnic_start_xmit() (mqnic_tx.c): The driver generates the hardware IP checksum command and writes it into the descriptor

  5. mqnic_map_skb() (mqnic_tx.c): The driver writes a reference to the sk_buff into ring->tx_info

  6. mqnic_map_skb() (mqnic_tx.c): The driver generates DMA mappings for the sk_buff (skb_frag_dma_map()/dma_map_single()) and builds the descriptor

  7. mqnic_start_xmit() (mqnic_tx.c): The driver enqueues the packet by incrementing its local copy of the producer pointer

  8. mqnic_start_xmit() (mqnic_tx.c): At the end of a batch of packets, the driver writes the updated producer pointer to the NIC via MMIO

  9. queue_manager s_axil_*: The MMIO write arrives at the queue manager via AXI lite

  10. queue_manager m_axis_doorbell_*: The queue manager updates the producer pointer and generates a doorbell event

  11. tx_scheduler_rr s_axis_doorbell_*: The doorbell event arrives at the port schedulers

  12. tx_scheduler_rr: The scheduler marks the queue as active and schedules it if necessary

  13. tx_scheduler_rr: The scheduler decides to send a packet

  14. tx_scheduler_rr m_axis_tx_req_*: The scheduler generates a transmit request

  15. tx_engine s_axis_tx_req_*: The transmit request arrives at the transmit engine

  16. tx_engine m_axis_desc_req_*: The transmit engine issues a descriptor request

  17. desc_fetch s_axis_desc_req_*: The descriptor request arrives at the descriptor fetch module

  18. desc_fetch m_axis_desc_dequeue_req_*: The descriptor fetch module issues a dequeue request to the queue manager

  19. queue_manager s_axis_dequeue_req_*: The dequeue request arrives at the queue manager module

  20. queue_manager: If the queue is not empty, the queue manager starts a dequeue operation on the queue

  21. queue_manager m_axis_dequeue_resp_*: The queue manager sends a response containing the operation status and DMA address

  22. desc_fetch s_axis_desc_dequeue_resp_*: The response arrives at the descriptor fetch module

  23. desc_fetch m_axis_req_status_*: The descriptor module reports the descriptor fetch status

  24. desc_fetch m_axis_dma_read_desc_*: The descriptor module issues a DMA read request

  25. dma_if_pcie_rd s_axis_read_desc_*: The requst arrives at the DMA read interface

  26. dma_if_pcie_rd: The DMA read interface issues a PCIe read request

  27. dma_if_pcie_rd: The read data comes back in a completion packet and is written to the descriptor fetch local DMA RAM

  28. dma_if_pcie_rd m_axis_read_desc_status_*: The DMA read interface issues a status message

  29. desc_fetch m_axis_desc_dequeue_commit_*: The descriptor fetch module issues a dequeue commit message

  30. queue_manager: The queue manager commits the dequeue operation and updates the consumer pointer

  31. desc_fetch dma_read_desc_*: The descriptor fetch module issues a read request to its internal DMA module

  32. desc_fetch m_axis_desc_*: The internal DMA module reads the descriptor and transfers it via AXI stream

  33. tx_engine: The descriptor arrives at the transmit engine

  34. tx_engine: The transmit engine stores the descriptor data

  35. tx_engine m_axis_dma_read_desc_*: The transmit engine issues a DMA read request

  36. dma_if_pcie_rd s_axis_read_desc_*: The requst arrives at the DMA read interface

  37. dma_if_pcie_rd: The DMA read interface issues a PCIe read request

  38. dma_if_pcie_rd: The read data comes back in a completion packet and is written to the interface local DMA RAM

  39. dma_if_pcie_rd m_axis_read_desc_status_*: The DMA read interface issues a status message

  40. tx_engine m_axis_tx_desc_*: The transmit engine issues a read request to the interface DMA engine

  41. tx_engine m_axis_tx_csum_cmd_*: The transmit engine issues a transmit checksum command

  42. mqnic_interface_tx tx_axis_*: The interface DMA module reads the packet data from interface local DMA RAM and transfers it via AXI stream

  43. mqnic_egress: egress processing

  44. tx_checksum: The transmit checksum module computes and inserts the checksum

  45. mqnic_app_block s_axis_if_tx: data is presented to the application section

  46. mqnic_app_block m_axis_if_tx: data is returned from the application section

  47. mqnic_core: Data passes enters per-interface transmit FIFO module and is divided into per-port, per-traffic-class FIFOs

  48. mqnic_app_block s_axis_sync_tx: data is presented to the application section

  49. mqnic_app_block m_axis_sync_tx: data is returned from the application section

  50. mqnic_core: Data passes through per-port transmit async FIFO module and is transferred to MAC TX clock domain

  51. mqnic_app_block s_axis_direct_tx: data is presented to the application section

  52. mqnic_app_block m_axis_direct_tx: data is returned from the application section

  53. mqnic_l2_egress: layer 2 egress processing

  54. mqnic_core: data leaves through transmit streaming interfaces

  55. The packet arrives at the MAC

  56. The MAC produces a PTP timestamp

  57. tx_engine: The PTP timestamp arrives at the transmit engine

  58. tx_engine m_axis_cpl_req_*: The transmit engine issues a completion write request

  59. cpl_write: The completion write module writes the completion data into its local DMA RAM

  60. cpl_write m_axis_cpl_enqueue_req_*: The completion write module issues an enqueue request to the completion queue manager

  61. cpl_queue_manager m_axis_enqueue_req_*: The enqueue request arrives at the completion queue manager module

  62. cpl_queue_manager: If the queue is not full, the queue manager starts an enqueue operation on the queue

  63. cpl_queue_manager m_axis_enqueue_resp_*: The completion queue manager sends a response containing the operation status and DMA address

  64. cpl_write: The response arrives at the completion write module

  65. cpl_write m_axis_req_status_*: The completion write module reports the completion write status

  66. desc_fetch m_axis_dma_write_desc_*: The completion write module issues a DMA write request

  67. dma_if_pcie_wr s_axis_write_desc_*: The requst arrives at the DMA write interface

  68. dma_if_pcie_wr: The DMA write interface reads the completion data from the completion write module local DMA RAM

  69. dma_if_pcie_wr: The DMA write interface issues a PCIe write request

  70. dma_if_pcie_wr m_axis_write_desc_status_*: The DMA write interface issues a status message

  71. cpl_write m_axis_desc_enqueue_commit_*: The completion write module issues an enqueue commit message

  72. cpl_queue_manager: The completion queue manager commits the enqueue operation and updates the producer pointer

  73. cpl_queue_manager m_axis_event_*: The completion queue manager issues an event, if armed

  74. cpl_write: The event arrives at the completion write module

  75. cpl_write: The completion write module writes the event data into its local DMA RAM

  76. cpl_write m_axis_cpl_enqueue_req_*: The completion write module issues an enqueue request to the completion queue manager

  77. cpl_queue_manager s_axis_enqueue_req_*: The enqueue request arrives at the completion queue manager module

  78. cpl_queue_manager: If the queue is not full, the queue manager starts an enqueue operation on the queue

  79. cpl_queue_manager m_axis_enqueue_resp_*: The completion queue manager sends a response containing the operation status and DMA address

  80. cpl_write s_axis_cpl_enqueue_resp_*: The response arrives at the completion write module

  81. cpl_write m_axis_req_status_*: The completion write module reports the completion write status

  82. desc_fetch m_axis_dma_write_desc_*: The completion write module issues a DMA write request

  83. dma_if_pcie_wr s_axis_write_desc_*: The requst arrives at the DMA write interface

  84. dma_if_pcie_wr: The DMA write interface reads the event data from the completion write module local DMA RAM

  85. dma_if_pcie_wr: The DMA write interface issues a PCIe write request

  86. dma_if_pcie_wr m_axis_write_desc_status_*: The DMA write interface issues a status message

  87. cpl_write m_axis_desc_enqueue_commit_*: The completion write module issues an enqueue commit message

  88. cpl_queue_manager: The completion queue manager commits the enqueue operation and updates the producer pointer

  89. cpl_queue_manager m_axis_event_*: The completion queue manager issues an interrupt, if armed

  90. linux: The linux kernel calls mqnic_irq_handler()

  91. mqnic_irq_handler() (mqnic_irq.c): The driver calls the EQ handler via the notifier chain (atomic_notifier_call_chain())

  92. mqnic_eq_int() (mqnic_eq.c): The driver calls mqnic_process_eq()

  93. mqnic_process_eq() (mqnic_eq.c): The driver processes the event queue, which calls the appropriate handler (mqnic_tx_irq())

  94. mqnic_tx_irq() (mqnic_tx.c): The driver enables NAPI polling on the queue (napi_schedule_irqoff())

  95. mqnic_eq_int() (mqnic_eq.c): The driver rearms the EQ (mqnic_arm_eq())

  96. NAPI: The linux kernel calls mqnic_poll_tx_cq()

  97. mqnic_poll_tx_cq() (mqnic_tx.c): The driver calls mqnic_process_tx_cq()

  98. mqnic_process_tx_cq() (mqnic_tx.c): The driver reads the completion queue producer pointer from the NIC

  99. mqnic_process_tx_cq() (mqnic_tx.c): The driver reads the completion record

  100. mqnic_process_tx_cq() (mqnic_tx.c): The driver reads the sk_buff from ring->tx_info

  101. mqnic_process_tx_cq() (mqnic_tx.c): The driver completes the transmit timestamp operation

  102. mqnic_process_tx_cq() (mqnic_tx.c): The driver calls mqnic_free_tx_desc()

  103. mqnic_free_tx_desc() (mqnic_tx.c): The driver unmaps the sk_buff (dma_unmap_single()/dma_unmap_page())

  104. mqnic_free_tx_desc() (mqnic_tx.c): The driver frees the sk_buff (napi_consume_skb())

  105. mqnic_process_tx_cq() (mqnic_tx.c): The driver dequeues the completion record by incrementing the completion queue consumer pointer

  106. mqnic_process_tx_cq() (mqnic_tx.c): The driver writes the updated consumer pointer via MMIO

  107. mqnic_process_tx_cq() (mqnic_tx.c): The driver reads the queue consumer pointer from the NIC

  108. mqnic_process_tx_cq() (mqnic_tx.c): The driver increments the ring consumer pointer for in-order freed descriptors

  109. mqnic_process_tx_cq() (mqnic_tx.c): The driver wakes the queue if it was stopped (netif_tx_wake_queue())

  110. mqnic_poll_tx_cq() (mqnic_tx.c): The driver disables NAPI polling, when idle (napi_complete())

  111. mqnic_poll_tx_cq() (mqnic_tx.c): The driver rearms the CQ (mqnic_arm_cq())

7.2. Packet reception

init:

  1. mqnic_activate_rx_ring() (mqnic_rx.c): The driver calls mqnic_refill_rx_buffers()

  2. mqnic_refill_rx_buffers() (mqnic_rx.c): The driver calls mqnic_prepare_rx_desc() for each empty location in the ring

  3. mqnic_prepare_rx_desc() (mqnic_rx.c): The driver allocates memory pages (dev_alloc_pages())

  4. mqnic_prepare_rx_desc() (mqnic_rx.c): The driver maps the pages (dev_alloc_pages())

  5. mqnic_prepare_rx_desc() (mqnic_rx.c): The driver writes a pointer to the page struct in ring->rx_info

  6. mqnic_prepare_rx_desc() (mqnic_rx.c): The driver writes a descriptor with the DMA pointer and length

  7. mqnic_refill_rx_buffers() (mqnic_rx.c): The driver enqueues the descriptor by incrementing its local copy of the producer pointer

  8. mqnic_refill_rx_buffers() (mqnic_rx.c): At the end of the loop, the driver writes the updated producer pointer to the NIC via MMIO

receive:

  1. A packet arrives at the MAC

  2. The MAC produces a PTP timestamp

  3. mqnic_core: data enters through receive streaming interfaces

  4. mqnic_l2_ingress: layer 2 ingress processing

  5. mqnic_app_block s_axis_direct_rx: data is presented to the application section

  6. mqnic_app_block m_axis_direct_rx: data is returned from the application section

  7. mqnic_core: Data passes through per-port receive async FIFO module and is transferred to core clock domain

  8. mqnic_app_block s_axis_sync_rx: data is presented to the application section

  9. mqnic_app_block m_axis_sync_rx: data is returned from the application section

  10. mqnic_core: Data passes enters per-interface receive FIFO module and is placed into per-port FIFOs, then aggregated into a single stream

  11. mqnic_app_block s_axis_if_rx: data is presented to the application section

  12. mqnic_app_block m_axis_if_rx: data is returned from the application section

  13. mqnic_ingress: ingress processing

  14. rx_hash: The receive hash module computes the packet flow hash

  15. rx_checksum: The receive checksum module computes the packet payload checksum

  16. mqnic_interface_rx: A receive request is generated

  17. rx_engine: The receive hash arrives at the receive engine

  18. rx_engine: The receive checksum arrives at the receive engine

  19. rx_engine: The receive request arrives at the receive engine

  20. rx_engine m_axis_rx_desc_*: The receive engine issues a write request to the interface DMA engine

  21. mqnic_interface_rx rx_axis_*: The interface DMA module writes the packet data from AXI stream to the interface local DMA RAM

  22. rx_engine m_axis_desc_req_*: The receive engine issues a descriptor request

  23. desc_fetch: The descriptor request arrives at the descriptor fetch module

  24. desc_fetch m_axis_desc_dequeue_req_*: The descriptor fetch module issues a dequeue request to the queue manager

  25. queue_manager s_axis_dequeue_req_*: The dequeue request arrives at the queue manager module

  26. queue_manager: If the queue is not empty, the queue manager starts a dequeue operation on the queue

  27. queue_manager m_axis_dequeue_resp_*: The queue manager sends a response containing the operation status and DMA address

  28. desc_fetch m_axis_desc_dequeue_resp_*: The response arrives at the descriptor fetch module

  29. desc_fetch m_axis_req_status_*: The descriptor module reports the descriptor fetch status

  30. desc_fetch m_axis_dma_read_desc_*: The descriptor module issues a DMA read request

  31. dma_if_pcie_us_rd s_axis_read_desc_*: The requst arrives at the DMA read interface

  32. dma_if_pcie_us_rd: The DMA read interface issues a PCIe read request

  33. dma_if_pcie_us_rd: The read data comes back in a completion packet and is written to the descriptor fetch local DMA RAM

  34. dma_if_pcie_us_rd m_axis_read_desc_status_*: The DMA read interface issues a status message

  35. desc_fetch m_axis_desc_dequeue_commit_*: The descriptor fetch module issues a dequeue commit message

  36. queue_manager: The queue manager commits the dequeue operation and updates the consumer pointer

  37. desc_fetch dma_read_desc_*: The descriptor fetch module issues a read request to its internal DMA module

  38. desc_fetch m_axis_desc_*: The internal DMA module reads the descriptor and transfers it via AXI stream

  39. rx_engine: The descriptor arrives at the receive engine

  40. rx_engine: The receive engine stores the descriptor data

  41. rx_engine m_axis_dma_write_desc_*: The receive engine issues a DMA write request

  42. dma_if_pcie_us_wr s_axis_write_desc_*: The requst arrives at the DMA write interface

  43. dma_if_pcie_us_wr: The DMA write interface reads the packet data from the interface local DMA RAM

  44. dma_if_pcie_us_wr: The DMA write interface issues a PCIe write request

  45. dma_if_pcie_us_wr m_axis_write_desc_status_*: The DMA write interface issues a status message

  46. rx_engine m_axis_cpl_req_*: The receive engine issues a completion write request

  47. cpl_write: The completion write module writes the completion data into its local DMA RAM

  48. cpl_write m_axis_cpl_enqueue_req_*: The completion write module issues an enqueue request to the completion queue manager

  49. cpl_queue_manager s_axis_enqueue_req_*: The enqueue request arrives at the completion queue manager module

  50. cpl_queue_manager: If the queue is not full, the queue manager starts an enqueue operation on the queue

  51. cpl_queue_manager m_axis_enqueue_resp_*: The completion queue manager sends a response containing the operation status and DMA address

  52. cpl_write s_axis_cpl_enqueue_resp_*: The response arrives at the completion write module

  53. cpl_write m_axis_req_status_*: The completion write module reports the completion write status

  54. desc_fetch m_axis_dma_write_desc_*: The completion write module issues a DMA write request

  55. dma_if_pcie_us_wr s_axis_write_desc_*: The requst arrives at the DMA write interface

  56. dma_if_pcie_us_wr: The DMA write interface reads the completion data from the completion write module local DMA RAM

  57. dma_if_pcie_us_wr: The DMA write interface issues a PCIe write request

  58. dma_if_pcie_us_wr m_axis_write_desc_status_*: The DMA write interface issues a status message

  59. cpl_write m_axis_desc_enqueue_commit_*: The completion write module issues an enqueue commit message

  60. cpl_queue_manager: The completion queue manager commits the enqueue operation and updates the producer pointer

  61. cpl_queue_manager m_axis_event_*: The completion queue manager issues an event, if armed

  62. cpl_write: The event arrives at the completion write module

  63. cpl_write: The completion write module writes the event data into its local DMA RAM

  64. cpl_write m_axis_cpl_enqueue_req_*: The completion write module issues an enqueue request to the completion queue manager

  65. cpl_queue_manager s_axis_enqueue_req_*: The enqueue request arrives at the completion queue manager module

  66. cpl_queue_manager: If the queue is not full, the queue manager starts an enqueue operation on the queue

  67. cpl_queue_manager m_axis_enqueue_resp_*: The completion queue manager sends a response containing the operation status and DMA address

  68. cpl_write s_axis_cpl_enqueue_resp_*: The response arrives at the completion write module

  69. cpl_write m_axis_req_status_*: The completion write module reports the completion write status

  70. desc_fetch m_axis_dma_write_desc_*: The completion write module issues a DMA write request

  71. dma_if_pcie_us_wr s_axis_write_desc_*: The requst arrives at the DMA write interface

  72. dma_if_pcie_us_wr: The DMA write interface reads the event data from the completion write module local DMA RAM

  73. dma_if_pcie_us_wr: The DMA write interface issues a PCIe write request

  74. dma_if_pcie_us_wr m_axis_write_desc_status_*: The DMA write interface issues a status message

  75. cpl_write m_axis_desc_enqueue_commit_*: The completion write module issues an enqueue commit message

  76. cpl_queue_manager: The completion queue manager commits the enqueue operation and updates the producer pointer

  77. cpl_queue_manager m_axis_event_*: The completion queue manager issues an interrupt, if armed

  78. linux: The linux kernel calls mqnic_irq_handler()

  79. mqnic_irq_handler() (mqnic_irq.c): The driver calls the EQ handler via the notifier chain (atomic_notifier_call_chain())

  80. mqnic_eq_int() (mqnic_eq.c): The driver calls mqnic_process_eq()

  81. mqnic_process_eq() (mqnic_eq.c): The driver processes the event queue, which calls the appropriate handler (mqnic_rx_irq())

  82. mqnic_rx_irq() (mqnic_rx.c): The driver enables NAPI polling on the queue (napi_schedule_irqoff())

  83. mqnic_eq_int() (mqnic_eq.c): The driver rearms the EQ (mqnic_arm_eq())

  84. NAPI: The linux kernel calls mqnic_poll_rx_cq()

  85. mqnic_poll_rx_cq() (mqnic_rx.c): The driver calls mqnic_process_rx_cq()

  86. mqnic_process_rx_cq() (mqnic_rx.c): The driver reads the CQ producer pointer from the NIC

  87. mqnic_process_rx_cq() (mqnic_rx.c): The driver reads the completion record

  88. mqnic_process_rx_cq() (mqnic_rx.c): The driver fetches a fresh sk_buff (napi_get_frags())

  89. mqnic_process_rx_cq() (mqnic_rx.c): The driver sets the sk_buff hardware timestamp

  90. mqnic_process_rx_cq() (mqnic_rx.c): The driver unmaps the pages (dma_unmap_page())

  91. mqnic_process_rx_cq() (mqnic_rx.c): The driver associates the pages with the sk_buff (__skb_fill_page_desc())

  92. mqnic_process_rx_cq() (mqnic_rx.c): The driver sets the sk_buff length

  93. mqnic_process_rx_cq() (mqnic_rx.c): The driver hands off the sk_buff to napi_gro_frags()

  94. mqnic_process_rx_cq() (mqnic_rx.c): The driver dequeues the completion record by incrementing the CQ consumer pointer

  95. mqnic_process_rx_cq() (mqnic_rx.c): The driver writes the updated CQ consumer pointer via MMIO

  96. mqnic_process_rx_cq() (mqnic_rx.c): The driver reads the queue consumer pointer from the NIC

  97. mqnic_process_rx_cq() (mqnic_rx.c): The driver increments the ring consumer pointer for in-order freed descriptors

  98. mqnic_process_rx_cq() (mqnic_rx.c): The driver calls mqnic_refill_rx_buffers()

  99. mqnic_refill_rx_buffers() (mqnic_rx.c): The driver calls mqnic_prepare_rx_desc() for each empty location in the ring

  100. mqnic_prepare_rx_desc() (mqnic_rx.c): The driver allocates memory pages (dev_alloc_pages())

  101. mqnic_prepare_rx_desc() (mqnic_rx.c): The driver maps the pages (dev_alloc_pages())

  102. mqnic_prepare_rx_desc() (mqnic_rx.c): The driver writes a pointer to the page struct in ring->rx_info

  103. mqnic_prepare_rx_desc() (mqnic_rx.c): The driver writes a descriptor with the DMA pointer and length

  104. mqnic_refill_rx_buffers() (mqnic_rx.c): The driver enqueues the descriptor by incrementing its local copy of the producer pointer

  105. mqnic_refill_rx_buffers() (mqnic_rx.c): At the end of the loop, the driver writes the updated producer pointer to the NIC via MMIO

  106. mqnic_poll_rx_cq() (mqnic_rx.c): The driver disables NAPI polling, when idle (napi_complete())

  107. mqnic_poll_rx_cq() (mqnic_rx.c): The driver rearms the CQ (mqnic_arm_cq())