Conversation
This driver is for Intel X540/X550 NICs and works with IO-APIC and MSI/MSI-X interrupts. Signed-off-by: Terry Bai <tianyi.bai@unsw.edu.au>
Signed-off-by: Terry Bai <tianyi.bai@unsw.edu.au>
drivers/network/ixgbe/ethernet.c
Outdated
| static inline void set_flags(uintptr_t reg, uint32_t flags) { | ||
| set_reg(reg, get_reg(reg) | flags); | ||
| } | ||
|
|
||
| static inline void clear_flags(uintptr_t reg, uint32_t flags) { | ||
| set_reg(reg, get_reg(reg) & ~flags); | ||
| } |
There was a problem hiding this comment.
do we really need these helpers?
| void clear_interrupts(void) | ||
| { | ||
| set_reg(EIMC, IXGBE_IRQ_CLEAR_MASK); | ||
| get_reg(EICR); // Write Flush? |
There was a problem hiding this comment.
what does this comment mean?
There was a problem hiding this comment.
The comment that I left is to figure out why the read is there. I suspect it's for making sure the previous write request has been completed, but not quite sure.
From "PCI Express® Base Specification Revision 5.0":
A Memory Read Request of 1 DW with no bytes enabled, or “zero-length Read,” may be used by devices as a type of flush Request. For a Requester, the flush semantic allows a device to ensure that previously issued Posted Writes have been completed at their PCI Express destination. To be effective in all cases, the address for the zero-length Read must target the same device as the Posted Writes that are being flushed. One recommended approach is using the same address as one of the Posted Writes being flushed.
| | (uint32_t)buffer.len; | ||
| desc->read.olinfo_status = ((uint32_t)buffer.len << IXGBE_ADVTXD_PAYLEN_SHIFT); | ||
|
|
||
| /* THREAD_MEMORY_RELEASE(); */ |
There was a problem hiding this comment.
either remove these comments or add the memory release
| config.virt_tx.active_queue.vaddr, | ||
| config.virt_tx.num_buffers); | ||
|
|
||
| // Disable Interrupts, see Section 4.6.3.1 |
There was a problem hiding this comment.
can we link the manual we are referncing somewhere for these sections to make sense?
| // Enable MSI. see PCI Express Technology 3.0 Chapter 17 for more details. | ||
| /* set_flags16(PCI_COMMAND_16, BIT(10)); */ | ||
| /* set_flags16(PCI_MSI_MESSAGE_CONTROL_16, BIT(0)); */ | ||
| /* clear_flags16(PCI_MSI_MESSAGE_CONTROL_16, BIT(4) | BIT(5) | BIT(6)); */ | ||
| /* set_reg(PCI_MSI_MESSAGE_ADDRESS_LOW, 0xFEEu << 20); */ | ||
| /* set_reg(PCI_MSI_MESSAGE_ADDRESS_HIGH, 0); */ | ||
| /* set_reg16(PCI_MSI_MESSAGE_DATA_16, 0x31); */ | ||
| /* clear_flags16(PCI_MSI_MASK, BIT(0)); */ | ||
|
|
||
| // Enable MSI-X, see PCI Express Technology 3.0 Chapter 17 for more details. | ||
| /* // Disable legacy interrupts. TODO: this should be done by PCI driver. */ | ||
| /* set_flags16(PCI_COMMAND_16, BIT(10)); */ | ||
| /* // Set vector message address to Local APIC of CPU0 */ | ||
| /* set_reg(DEVICE_MSIX_TABLE + 0x0, 0xFEEu << 20); */ | ||
| /* set_reg(DEVICE_MSIX_TABLE + 0x4, 0); */ | ||
| /* // Set vector data to Interrupt Vector */ | ||
| /* set_reg(DEVICE_MSIX_TABLE + 0x8, 0x32); */ | ||
| /* // Unmask vector 0 to enable interrupts through it */ | ||
| /* set_reg(DEVICE_MSIX_TABLE + 0xC, 0xFFFFFFFE); */ | ||
| /* // Enable MSI-X. TODO: this should be set by PCI driver. */ | ||
| /* set_flags(PCI_MSIX_CTRL, BIT(31)); */ |
There was a problem hiding this comment.
Either these are needed or not; there's no need for commented out code.
There was a problem hiding this comment.
As described in this PR, these are for manually switch which type of IRQs to use before a PCI driver is ready.
| #define declare_register(base, name, offset) \ | ||
| uintptr_t name = (uintptr_t)(base + offset); |
There was a problem hiding this comment.
Why?
Besides we won't have a base fixed at compile time so they should surely be a offset (not absolute ptr) of a dynamic base (even if it's constant for now).
Or.. like most of our other drivers do and have a struct that's volatile?
This driver is for Intel X540/X550 NICs and works with IO-APIC and MSI/MSI-X interrupts.
Before a proper PCI driver (#622) gets implemented, this experimental driver needs the access to PCI configuration space and set things up by itself. Interrupt types need to be manually switched by (un)commenting code snippets in
meta.pyandethernet.c.