diff options
author | Vishvananda Ishaya | 2017-03-09 14:54:13 +0100 |
---|---|---|
committer | Michael Brown | 2017-03-09 14:56:22 +0100 |
commit | 1d049002622da6a5a9cc98c42fd4dd27dc741b96 (patch) | |
tree | f5ef75498ab111610a6ed1a759d272053ba0786d /src/drivers/net/intel.c | |
parent | [scsi] Avoid duplicate calls to scsicmd_close() (diff) | |
download | ipxe-1d049002622da6a5a9cc98c42fd4dd27dc741b96.tar.gz ipxe-1d049002622da6a5a9cc98c42fd4dd27dc741b96.tar.xz ipxe-1d049002622da6a5a9cc98c42fd4dd27dc741b96.zip |
[intel] Reset all virtual function settings
Some VF data is not cleared with reset, so make sure to return all the
settings to default before configuring the VF.
This fixes an issue where network packets would fail to be received if
the VF was previously used by the linux ixgbevf driver.
Modified-by: Michael Brown <mcb30@ipxe.org>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Diffstat (limited to 'src/drivers/net/intel.c')
-rw-r--r-- | src/drivers/net/intel.c | 63 |
1 files changed, 57 insertions, 6 deletions
diff --git a/src/drivers/net/intel.c b/src/drivers/net/intel.c index ab6defde..534252ba 100644 --- a/src/drivers/net/intel.c +++ b/src/drivers/net/intel.c @@ -425,6 +425,61 @@ void intel_describe_rx ( struct intel_descriptor *rx, physaddr_t addr, */ /** + * Disable descriptor ring + * + * @v intel Intel device + * @v reg Register block + * @ret rc Return status code + */ +static int intel_disable_ring ( struct intel_nic *intel, unsigned int reg ) { + uint32_t dctl; + unsigned int i; + + /* Disable ring */ + writel ( 0, ( intel->regs + reg + INTEL_xDCTL ) ); + + /* Wait for disable to complete */ + for ( i = 0 ; i < INTEL_DISABLE_MAX_WAIT_MS ; i++ ) { + + /* Check if ring is disabled */ + dctl = readl ( intel->regs + reg + INTEL_xDCTL ); + if ( ! ( dctl & INTEL_xDCTL_ENABLE ) ) + return 0; + + /* Delay */ + mdelay ( 1 ); + } + + DBGC ( intel, "INTEL %p ring %05x timed out waiting for disable " + "(dctl %08x)\n", intel, reg, dctl ); + return -ETIMEDOUT; +} + +/** + * Reset descriptor ring + * + * @v intel Intel device + * @v reg Register block + * @ret rc Return status code + */ +void intel_reset_ring ( struct intel_nic *intel, unsigned int reg ) { + + /* Disable ring. Ignore errors and continue to reset the ring anyway */ + intel_disable_ring ( intel, reg ); + + /* Clear ring length */ + writel ( 0, ( intel->regs + reg + INTEL_xDLEN ) ); + + /* Clear ring address */ + writel ( 0, ( intel->regs + reg + INTEL_xDBAH ) ); + writel ( 0, ( intel->regs + reg + INTEL_xDBAL ) ); + + /* Reset head and tail pointers */ + writel ( 0, ( intel->regs + reg + INTEL_xDH ) ); + writel ( 0, ( intel->regs + reg + INTEL_xDT ) ); +} + +/** * Create descriptor ring * * @v intel Intel device @@ -484,12 +539,8 @@ int intel_create_ring ( struct intel_nic *intel, struct intel_ring *ring ) { */ void intel_destroy_ring ( struct intel_nic *intel, struct intel_ring *ring ) { - /* Clear ring length */ - writel ( 0, ( intel->regs + ring->reg + INTEL_xDLEN ) ); - - /* Clear ring address */ - writel ( 0, ( intel->regs + ring->reg + INTEL_xDBAL ) ); - writel ( 0, ( intel->regs + ring->reg + INTEL_xDBAH ) ); + /* Reset ring */ + intel_reset_ring ( intel, ring->reg ); /* Free descriptor ring */ free_dma ( ring->desc, ring->len ); |