diff options
| -rw-r--r-- | drivers/net/ixgbe/ixgbe.h | 2 | ||||
| -rw-r--r-- | drivers/net/ixgbe/ixgbe_ethtool.c | 4 | ||||
| -rw-r--r-- | drivers/net/ixgbe/ixgbe_main.c | 40 |
3 files changed, 39 insertions, 7 deletions
diff --git a/drivers/net/ixgbe/ixgbe.h b/drivers/net/ixgbe/ixgbe.h index 3ae30b8cb7d..bdeaa9e06c0 100644 --- a/drivers/net/ixgbe/ixgbe.h +++ b/drivers/net/ixgbe/ixgbe.h | |||
| @@ -508,6 +508,8 @@ extern void ixgbe_free_rx_resources(struct ixgbe_ring *); | |||
| 508 | extern void ixgbe_free_tx_resources(struct ixgbe_ring *); | 508 | extern void ixgbe_free_tx_resources(struct ixgbe_ring *); |
| 509 | extern void ixgbe_configure_rx_ring(struct ixgbe_adapter *,struct ixgbe_ring *); | 509 | extern void ixgbe_configure_rx_ring(struct ixgbe_adapter *,struct ixgbe_ring *); |
| 510 | extern void ixgbe_configure_tx_ring(struct ixgbe_adapter *,struct ixgbe_ring *); | 510 | extern void ixgbe_configure_tx_ring(struct ixgbe_adapter *,struct ixgbe_ring *); |
| 511 | extern void ixgbe_disable_rx_queue(struct ixgbe_adapter *adapter, | ||
| 512 | struct ixgbe_ring *); | ||
| 511 | extern void ixgbe_update_stats(struct ixgbe_adapter *adapter); | 513 | extern void ixgbe_update_stats(struct ixgbe_adapter *adapter); |
| 512 | extern int ixgbe_init_interrupt_scheme(struct ixgbe_adapter *adapter); | 514 | extern int ixgbe_init_interrupt_scheme(struct ixgbe_adapter *adapter); |
| 513 | extern void ixgbe_clear_interrupt_scheme(struct ixgbe_adapter *adapter); | 515 | extern void ixgbe_clear_interrupt_scheme(struct ixgbe_adapter *adapter); |
diff --git a/drivers/net/ixgbe/ixgbe_ethtool.c b/drivers/net/ixgbe/ixgbe_ethtool.c index 23ff23e8b39..a8bab1564d0 100644 --- a/drivers/net/ixgbe/ixgbe_ethtool.c +++ b/drivers/net/ixgbe/ixgbe_ethtool.c | |||
| @@ -1477,9 +1477,7 @@ static void ixgbe_free_desc_rings(struct ixgbe_adapter *adapter) | |||
| 1477 | reg_ctl = IXGBE_READ_REG(hw, IXGBE_RXCTRL); | 1477 | reg_ctl = IXGBE_READ_REG(hw, IXGBE_RXCTRL); |
| 1478 | reg_ctl &= ~IXGBE_RXCTRL_RXEN; | 1478 | reg_ctl &= ~IXGBE_RXCTRL_RXEN; |
| 1479 | IXGBE_WRITE_REG(hw, IXGBE_RXCTRL, reg_ctl); | 1479 | IXGBE_WRITE_REG(hw, IXGBE_RXCTRL, reg_ctl); |
| 1480 | reg_ctl = IXGBE_READ_REG(hw, IXGBE_RXDCTL(rx_ring->reg_idx)); | 1480 | ixgbe_disable_rx_queue(adapter, rx_ring); |
| 1481 | reg_ctl &= ~IXGBE_RXDCTL_ENABLE; | ||
| 1482 | IXGBE_WRITE_REG(hw, IXGBE_RXDCTL(rx_ring->reg_idx), reg_ctl); | ||
| 1483 | 1481 | ||
| 1484 | /* now Tx */ | 1482 | /* now Tx */ |
| 1485 | reg_ctl = IXGBE_READ_REG(hw, IXGBE_TXDCTL(tx_ring->reg_idx)); | 1483 | reg_ctl = IXGBE_READ_REG(hw, IXGBE_TXDCTL(tx_ring->reg_idx)); |
diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index 38ab4f3f819..e8ae311bbbe 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c | |||
| @@ -3024,6 +3024,36 @@ static void ixgbe_rx_desc_queue_enable(struct ixgbe_adapter *adapter, | |||
| 3024 | } | 3024 | } |
| 3025 | } | 3025 | } |
| 3026 | 3026 | ||
| 3027 | void ixgbe_disable_rx_queue(struct ixgbe_adapter *adapter, | ||
| 3028 | struct ixgbe_ring *ring) | ||
| 3029 | { | ||
| 3030 | struct ixgbe_hw *hw = &adapter->hw; | ||
| 3031 | int wait_loop = IXGBE_MAX_RX_DESC_POLL; | ||
| 3032 | u32 rxdctl; | ||
| 3033 | u8 reg_idx = ring->reg_idx; | ||
| 3034 | |||
| 3035 | rxdctl = IXGBE_READ_REG(hw, IXGBE_RXDCTL(reg_idx)); | ||
| 3036 | rxdctl &= ~IXGBE_RXDCTL_ENABLE; | ||
| 3037 | |||
| 3038 | /* write value back with RXDCTL.ENABLE bit cleared */ | ||
| 3039 | IXGBE_WRITE_REG(hw, IXGBE_RXDCTL(reg_idx), rxdctl); | ||
| 3040 | |||
| 3041 | if (hw->mac.type == ixgbe_mac_82598EB && | ||
| 3042 | !(IXGBE_READ_REG(hw, IXGBE_LINKS) & IXGBE_LINKS_UP)) | ||
| 3043 | return; | ||
| 3044 | |||
| 3045 | /* the hardware may take up to 100us to really disable the rx queue */ | ||
| 3046 | do { | ||
| 3047 | udelay(10); | ||
| 3048 | rxdctl = IXGBE_READ_REG(hw, IXGBE_RXDCTL(reg_idx)); | ||
| 3049 | } while (--wait_loop && (rxdctl & IXGBE_RXDCTL_ENABLE)); | ||
| 3050 | |||
| 3051 | if (!wait_loop) { | ||
| 3052 | e_err(drv, "RXDCTL.ENABLE on Rx queue %d not cleared within " | ||
| 3053 | "the polling period\n", reg_idx); | ||
| 3054 | } | ||
| 3055 | } | ||
| 3056 | |||
| 3027 | void ixgbe_configure_rx_ring(struct ixgbe_adapter *adapter, | 3057 | void ixgbe_configure_rx_ring(struct ixgbe_adapter *adapter, |
| 3028 | struct ixgbe_ring *ring) | 3058 | struct ixgbe_ring *ring) |
| 3029 | { | 3059 | { |
| @@ -3034,9 +3064,7 @@ void ixgbe_configure_rx_ring(struct ixgbe_adapter *adapter, | |||
| 3034 | 3064 | ||
| 3035 | /* disable queue to avoid issues while updating state */ | 3065 | /* disable queue to avoid issues while updating state */ |
| 3036 | rxdctl = IXGBE_READ_REG(hw, IXGBE_RXDCTL(reg_idx)); | 3066 | rxdctl = IXGBE_READ_REG(hw, IXGBE_RXDCTL(reg_idx)); |
| 3037 | IXGBE_WRITE_REG(hw, IXGBE_RXDCTL(reg_idx), | 3067 | ixgbe_disable_rx_queue(adapter, ring); |
| 3038 | rxdctl & ~IXGBE_RXDCTL_ENABLE); | ||
| 3039 | IXGBE_WRITE_FLUSH(hw); | ||
| 3040 | 3068 | ||
| 3041 | IXGBE_WRITE_REG(hw, IXGBE_RDBAL(reg_idx), (rdba & DMA_BIT_MASK(32))); | 3069 | IXGBE_WRITE_REG(hw, IXGBE_RDBAL(reg_idx), (rdba & DMA_BIT_MASK(32))); |
| 3042 | IXGBE_WRITE_REG(hw, IXGBE_RDBAH(reg_idx), (rdba >> 32)); | 3070 | IXGBE_WRITE_REG(hw, IXGBE_RDBAH(reg_idx), (rdba >> 32)); |
| @@ -4064,7 +4092,11 @@ void ixgbe_down(struct ixgbe_adapter *adapter) | |||
| 4064 | rxctrl = IXGBE_READ_REG(hw, IXGBE_RXCTRL); | 4092 | rxctrl = IXGBE_READ_REG(hw, IXGBE_RXCTRL); |
| 4065 | IXGBE_WRITE_REG(hw, IXGBE_RXCTRL, rxctrl & ~IXGBE_RXCTRL_RXEN); | 4093 | IXGBE_WRITE_REG(hw, IXGBE_RXCTRL, rxctrl & ~IXGBE_RXCTRL_RXEN); |
| 4066 | 4094 | ||
| 4067 | IXGBE_WRITE_FLUSH(hw); | 4095 | /* disable all enabled rx queues */ |
| 4096 | for (i = 0; i < adapter->num_rx_queues; i++) | ||
| 4097 | /* this call also flushes the previous write */ | ||
| 4098 | ixgbe_disable_rx_queue(adapter, adapter->rx_ring[i]); | ||
| 4099 | |||
| 4068 | msleep(10); | 4100 | msleep(10); |
| 4069 | 4101 | ||
| 4070 | netif_tx_stop_all_queues(netdev); | 4102 | netif_tx_stop_all_queues(netdev); |
