Skip to content

drivers/network: add ixgbe driver#682

Open
terryzbai wants to merge 2 commits intomainfrom
ixgbe_driver_cleanup
Open

drivers/network: add ixgbe driver#682
terryzbai wants to merge 2 commits intomainfrom
ixgbe_driver_cleanup

Conversation

@terryzbai
Copy link
Copy Markdown
Contributor

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.py and ethernet.c.

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>
Copy link
Copy Markdown
Contributor

@midnightveil midnightveil left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Brief skim.

Comment on lines +84 to +90
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);
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we really need these helpers?

void clear_interrupts(void)
{
set_reg(EIMC, IXGBE_IRQ_CLEAR_MASK);
get_reg(EICR); // Write Flush?
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what does this comment mean?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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(); */
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we link the manual we are referncing somewhere for these sections to make sense?

Comment on lines +336 to +356
// 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)); */
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Either these are needed or not; there's no need for commented out code.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As described in this PR, these are for manually switch which type of IRQs to use before a PCI driver is ready.

Comment on lines +14 to +15
#define declare_register(base, name, offset) \
uintptr_t name = (uintptr_t)(base + offset);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants