-
Notifications
You must be signed in to change notification settings - Fork 2
Igc driver #2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Igc driver #2
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,225 @@ | ||
| /** | ||
| * @file igc.h | ||
| * @author Paul Richter (paul.richter@spreewalddreieck.de) | ||
| * @brief header of igc driver containing class Igc_device | ||
| * @version 0.1 | ||
| * @date 2025-11-07 | ||
| * | ||
| * @copyright Copyright (c) 2025 | ||
| * | ||
| * The igc device driver was developed as part of the bachelor thesis: "Generic | ||
| * aspects of porting a Linux Ethernet driver to the L4Re microkernel" It is | ||
| * nearly an identical copy of the ixl igb driver with changed register | ||
| * definitions. More information about how it works can be found there. (link | ||
| * will be inserted to a later date) | ||
| */ | ||
|
|
||
| /* | ||
| Header file containing the structure of the ixl igc device driver heavly | ||
| based on the ixl igb device driver | ||
| */ | ||
|
|
||
| #pragma once | ||
|
|
||
| #include <stdbool.h> | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Blank line after this include. Also, what is the reason for including stdbool.h here? |
||
| #include <l4/ixl/stats.h> | ||
|
|
||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Delete that newline. The structure of includes is , , local header files with each category being separated by a newline. |
||
| #include <l4/ixl/memory.h> | ||
|
|
||
| #include "igc_type.h" | ||
| #include "../../pci.h" | ||
|
|
||
| namespace Ixl { | ||
|
|
||
| /** | ||
| * Device driver specialized for the igc NIC family (e.g. I225-IT). | ||
| * | ||
| * Note: For now, this software is only a slight adaptation of the E1000 driver, | ||
| * leaving out many features such as RSS (multi-queue receive) etc. Maybe we | ||
| * will add those later, which will make the igc driver much more similar to | ||
| * ixgbe than to the original E1000 one (even though many register definitions | ||
| * stay the same). | ||
| */ | ||
| class Igc_device : public Ixl_device { | ||
| public: | ||
| // set number of queue entries to linux default value | ||
| static const int NUM_RX_QUEUE_ENTRIES = 256; | ||
| static const int NUM_TX_QUEUE_ENTRIES = 256; | ||
|
|
||
| static const int MAX_RX_QUEUE_ENTRIES = 256; | ||
| static const int MAX_TX_QUEUE_ENTRIES = 256; | ||
|
|
||
| static const int PKT_BUF_ENTRY_SIZE = 2048; | ||
|
|
||
| // Reserve at least twice the RX queue depth of packets for mempools. This | ||
| // is what the driver needs to remain operational as every received packet | ||
| // is immediately replaced with a fresh one in the RX path. | ||
| static const int MIN_MEMPOOL_ENTRIES = 2 * NUM_RX_QUEUE_ENTRIES; | ||
|
|
||
| static const int TX_CLEAN_BATCH = 32; | ||
|
|
||
| static const uint64_t INTERRUPT_INITIAL_INTERVAL = 1000 * 1000 * 1000; | ||
|
|
||
| Igc_device(L4vbus::Pci_dev &&dev, struct Dev_cfg &cfg, uint32_t itr_rate); | ||
|
|
||
| std::string get_driver_name(void) { | ||
| return("ixl-igc"); | ||
| } | ||
|
|
||
| inline uint32_t get_max_frame_size(void) { | ||
| return 0; | ||
| } | ||
|
|
||
| uint32_t rx_batch(uint16_t queue_id, struct pkt_buf* bufs[], | ||
| uint32_t num_bufs); | ||
|
|
||
| uint32_t tx_batch(uint16_t queue_id, struct pkt_buf* bufs[], | ||
| uint32_t num_bufs); | ||
|
|
||
| void read_stats(struct device_stats *stats); | ||
|
|
||
| void set_promisc(bool enabled); | ||
|
|
||
| uint32_t get_link_speed(void); | ||
| uint32_t get_link_duplex(void); | ||
|
|
||
| struct mac_address get_mac_addr(void); | ||
|
|
||
| void set_mac_addr(struct mac_address mac); | ||
|
|
||
| bool check_recv_irq(uint16_t qid) override; | ||
|
|
||
| void ack_recv_irq(uint16_t qid) override; | ||
|
|
||
| // Get the number of descriptors per RX queue | ||
| uint32_t get_rx_queue_depth(void) { | ||
| return NUM_RX_QUEUE_ENTRIES; | ||
| } | ||
|
|
||
| // Get the number of descriptors per TX queue | ||
| uint32_t get_tx_queue_depth(void) { | ||
| return NUM_TX_QUEUE_ENTRIES; | ||
| } | ||
|
|
||
| // Extend an RX queue's mempool | ||
| bool extend_rxq_mempool(uint16_t qid, uint32_t count) { | ||
| if (qid >= num_rx_queues) | ||
| return false; | ||
|
|
||
| struct igc_rx_queue *queue = | ||
| ((struct igc_rx_queue *) rx_queues) + qid; | ||
|
|
||
| return queue->mempool->reserve(count); | ||
| } | ||
|
|
||
| // Shrink an RX queue's mempool | ||
| void shrink_rxq_mempool(uint16_t qid, uint32_t count) { | ||
| if (qid >= num_rx_queues) | ||
| return; | ||
|
|
||
| struct igc_rx_queue *queue = | ||
| ((struct igc_rx_queue *) rx_queues) + qid; | ||
|
|
||
| queue->mempool->cancel_reservation(count); | ||
| } | ||
|
|
||
| /* | ||
| * Initializes and returns the Igc device. | ||
| * | ||
| * \param pci_dev PCI device handle received from this task's vbus | ||
| * \param cfg An Ixl device configuration. See Dev_cfg for details. | ||
| * | ||
| * \return The initialized Igc device. | ||
| */ | ||
| static Igc_device* igc_init(L4vbus::Pci_dev&& pci_dev, struct Dev_cfg &cfg); | ||
|
|
||
| private: | ||
| // allocated for each rx queue, keeps state for the receive function | ||
| struct igc_rx_queue { | ||
| // DMA'able memory from that the individual descriptors are allocated | ||
| struct dma_memory descr_mem; | ||
|
|
||
| // Array of descriptors backed by descr_mem | ||
| volatile struct igc_rx_desc* descriptors; | ||
|
|
||
| // DMA'able memory for storing incoming packets | ||
| Mempool* mempool; | ||
|
|
||
| // No. of descriptors in the queue | ||
| uint16_t num_entries; | ||
| // position we are reading from | ||
| uint16_t rx_index; | ||
| // True if this RX queue contains descriptors not yet processed by the | ||
| // driver. We use this flag to skip IRQ receive operations if necessary. | ||
| bool rx_pending = false; | ||
| // virtual addresses to map descriptors back to their mbuf for freeing | ||
| void* virtual_addresses[]; | ||
| }; | ||
|
|
||
| // allocated for each tx queue, keeps state for the transmit function | ||
| struct igc_tx_queue { | ||
| // DMA'able memory from that the individual descriptors are allocated | ||
| struct dma_memory descr_mem; | ||
|
|
||
| // Array of descriptors backed by descr_mem | ||
| volatile struct igc_tx_desc* descriptors; | ||
|
|
||
| // No. of descriptors in the queue | ||
| uint16_t num_entries; | ||
| // position to clean up descriptors that where sent out by the nic | ||
| uint16_t clean_index; | ||
| // position to insert packets for transmission | ||
| uint16_t tx_index; | ||
| // virtual addresses to map descriptors back to their mbuf for freeing | ||
| void* virtual_addresses[]; | ||
| }; | ||
|
|
||
|
|
||
|
|
||
| /*** Functions ***/ | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could you center these intermediate headings, with the righthand delimiter being aligned to column 80? In this way, the code looks way more fancy :) |
||
|
|
||
| /** | ||
| * Enables an MSI for receive events. We will configure the NIC in a way | ||
| * that an MSI is generated for each packet received, while adhering to the | ||
| * ITR limit that the user can specify upon initializing the driver. | ||
| * | ||
| * \param qid Index of the queue for that the corresponding MSI-X shall be | ||
| * enabled. | ||
| */ | ||
| void enable_rx_interrupt(uint16_t qid); | ||
|
|
||
| /** | ||
| * Disables an MSI for receive events. | ||
| * | ||
| * \param qid Index of the RX queue for that the corresponding MSI-X shall | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For these multi-line doxygen statements: Could you align the descriptive text so that all lines of it start in the same column? Or does this break doxygen? |
||
| * be disabled. | ||
| */ | ||
| void disable_rx_interrupt(uint16_t qid); | ||
|
|
||
| void disable_interrupts(void); | ||
|
|
||
| void init_link(void); | ||
|
|
||
| void start_rx_queue(int queue_id); | ||
|
|
||
| void start_tx_queue(int queue_id); | ||
|
|
||
| void init_rx(void); | ||
|
|
||
| void init_tx(void); | ||
|
|
||
| void wait_for_link(void); | ||
|
|
||
| void reset_and_init(void); | ||
|
|
||
| void init_msix(void); | ||
|
|
||
| /*** Member variables ***/ | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. See above. |
||
|
|
||
| // MAC address of this device | ||
| struct mac_address mac_addr; | ||
| // Does mac_addr contain a valid value? | ||
| bool mac_init = false; | ||
| }; | ||
|
|
||
| } // namespace Ixl | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you follow the formatting of the other header files? The first comment block should have a one-line description on what the file does, along with your name and the year(s) in that the file was modified. Also dump all of the information of version, date, file. Have a look at e.g. igb.h. The same goes for the layout of comment blocks (where each line should be preceded with an asterisk.