diff options
Diffstat (limited to 'drivers/net/ethernet/intel/i40e/i40e_main.c')
| -rw-r--r-- | drivers/net/ethernet/intel/i40e/i40e_main.c | 68 |
1 files changed, 35 insertions, 33 deletions
diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c index f736c4470412..1b792ee592d0 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_main.c +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /******************************************************************************* | 1 | /******************************************************************************* |
| 2 | * | 2 | * |
| 3 | * Intel Ethernet Controller XL710 Family Linux Driver | 3 | * Intel Ethernet Controller XL710 Family Linux Driver |
| 4 | * Copyright(c) 2013 Intel Corporation. | 4 | * Copyright(c) 2013 - 2014 Intel Corporation. |
| 5 | * | 5 | * |
| 6 | * This program is free software; you can redistribute it and/or modify it | 6 | * This program is free software; you can redistribute it and/or modify it |
| 7 | * under the terms and conditions of the GNU General Public License, | 7 | * under the terms and conditions of the GNU General Public License, |
| @@ -12,9 +12,8 @@ | |||
| 12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | 12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for |
| 13 | * more details. | 13 | * more details. |
| 14 | * | 14 | * |
| 15 | * You should have received a copy of the GNU General Public License along with | 15 | * You should have received a copy of the GNU General Public License along |
| 16 | * this program; if not, write to the Free Software Foundation, Inc., | 16 | * with this program. If not, see <http://www.gnu.org/licenses/>. |
| 17 | * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 18 | * | 17 | * |
| 19 | * The full GNU General Public License is included in this distribution in | 18 | * The full GNU General Public License is included in this distribution in |
| 20 | * the file called "COPYING". | 19 | * the file called "COPYING". |
| @@ -423,7 +422,7 @@ void i40e_vsi_reset_stats(struct i40e_vsi *vsi) | |||
| 423 | memset(&vsi->net_stats_offsets, 0, sizeof(vsi->net_stats_offsets)); | 422 | memset(&vsi->net_stats_offsets, 0, sizeof(vsi->net_stats_offsets)); |
| 424 | memset(&vsi->eth_stats, 0, sizeof(vsi->eth_stats)); | 423 | memset(&vsi->eth_stats, 0, sizeof(vsi->eth_stats)); |
| 425 | memset(&vsi->eth_stats_offsets, 0, sizeof(vsi->eth_stats_offsets)); | 424 | memset(&vsi->eth_stats_offsets, 0, sizeof(vsi->eth_stats_offsets)); |
| 426 | if (vsi->rx_rings) | 425 | if (vsi->rx_rings && vsi->rx_rings[0]) { |
| 427 | for (i = 0; i < vsi->num_queue_pairs; i++) { | 426 | for (i = 0; i < vsi->num_queue_pairs; i++) { |
| 428 | memset(&vsi->rx_rings[i]->stats, 0 , | 427 | memset(&vsi->rx_rings[i]->stats, 0 , |
| 429 | sizeof(vsi->rx_rings[i]->stats)); | 428 | sizeof(vsi->rx_rings[i]->stats)); |
| @@ -434,6 +433,7 @@ void i40e_vsi_reset_stats(struct i40e_vsi *vsi) | |||
| 434 | memset(&vsi->tx_rings[i]->tx_stats, 0, | 433 | memset(&vsi->tx_rings[i]->tx_stats, 0, |
| 435 | sizeof(vsi->tx_rings[i]->tx_stats)); | 434 | sizeof(vsi->tx_rings[i]->tx_stats)); |
| 436 | } | 435 | } |
| 436 | } | ||
| 437 | vsi->stat_offsets_loaded = false; | 437 | vsi->stat_offsets_loaded = false; |
| 438 | } | 438 | } |
| 439 | 439 | ||
| @@ -786,8 +786,8 @@ void i40e_update_stats(struct i40e_vsi *vsi) | |||
| 786 | } while (u64_stats_fetch_retry_bh(&p->syncp, start)); | 786 | } while (u64_stats_fetch_retry_bh(&p->syncp, start)); |
| 787 | rx_b += bytes; | 787 | rx_b += bytes; |
| 788 | rx_p += packets; | 788 | rx_p += packets; |
| 789 | rx_buf += p->rx_stats.alloc_rx_buff_failed; | 789 | rx_buf += p->rx_stats.alloc_buff_failed; |
| 790 | rx_page += p->rx_stats.alloc_rx_page_failed; | 790 | rx_page += p->rx_stats.alloc_page_failed; |
| 791 | } | 791 | } |
| 792 | rcu_read_unlock(); | 792 | rcu_read_unlock(); |
| 793 | vsi->tx_restart = tx_restart; | 793 | vsi->tx_restart = tx_restart; |
| @@ -2068,8 +2068,11 @@ static void i40e_vsi_free_tx_resources(struct i40e_vsi *vsi) | |||
| 2068 | { | 2068 | { |
| 2069 | int i; | 2069 | int i; |
| 2070 | 2070 | ||
| 2071 | if (!vsi->tx_rings) | ||
| 2072 | return; | ||
| 2073 | |||
| 2071 | for (i = 0; i < vsi->num_queue_pairs; i++) | 2074 | for (i = 0; i < vsi->num_queue_pairs; i++) |
| 2072 | if (vsi->tx_rings[i]->desc) | 2075 | if (vsi->tx_rings[i] && vsi->tx_rings[i]->desc) |
| 2073 | i40e_free_tx_resources(vsi->tx_rings[i]); | 2076 | i40e_free_tx_resources(vsi->tx_rings[i]); |
| 2074 | } | 2077 | } |
| 2075 | 2078 | ||
| @@ -2102,8 +2105,11 @@ static void i40e_vsi_free_rx_resources(struct i40e_vsi *vsi) | |||
| 2102 | { | 2105 | { |
| 2103 | int i; | 2106 | int i; |
| 2104 | 2107 | ||
| 2108 | if (!vsi->rx_rings) | ||
| 2109 | return; | ||
| 2110 | |||
| 2105 | for (i = 0; i < vsi->num_queue_pairs; i++) | 2111 | for (i = 0; i < vsi->num_queue_pairs; i++) |
| 2106 | if (vsi->rx_rings[i]->desc) | 2112 | if (vsi->rx_rings[i] && vsi->rx_rings[i]->desc) |
| 2107 | i40e_free_rx_resources(vsi->rx_rings[i]); | 2113 | i40e_free_rx_resources(vsi->rx_rings[i]); |
| 2108 | } | 2114 | } |
| 2109 | 2115 | ||
| @@ -2758,16 +2764,16 @@ static irqreturn_t i40e_intr(int irq, void *data) | |||
| 2758 | { | 2764 | { |
| 2759 | struct i40e_pf *pf = (struct i40e_pf *)data; | 2765 | struct i40e_pf *pf = (struct i40e_pf *)data; |
| 2760 | struct i40e_hw *hw = &pf->hw; | 2766 | struct i40e_hw *hw = &pf->hw; |
| 2767 | irqreturn_t ret = IRQ_NONE; | ||
| 2761 | u32 icr0, icr0_remaining; | 2768 | u32 icr0, icr0_remaining; |
| 2762 | u32 val, ena_mask; | 2769 | u32 val, ena_mask; |
| 2763 | 2770 | ||
| 2764 | icr0 = rd32(hw, I40E_PFINT_ICR0); | 2771 | icr0 = rd32(hw, I40E_PFINT_ICR0); |
| 2772 | ena_mask = rd32(hw, I40E_PFINT_ICR0_ENA); | ||
| 2765 | 2773 | ||
| 2766 | /* if sharing a legacy IRQ, we might get called w/o an intr pending */ | 2774 | /* if sharing a legacy IRQ, we might get called w/o an intr pending */ |
| 2767 | if ((icr0 & I40E_PFINT_ICR0_INTEVENT_MASK) == 0) | 2775 | if ((icr0 & I40E_PFINT_ICR0_INTEVENT_MASK) == 0) |
| 2768 | return IRQ_NONE; | 2776 | goto enable_intr; |
| 2769 | |||
| 2770 | ena_mask = rd32(hw, I40E_PFINT_ICR0_ENA); | ||
| 2771 | 2777 | ||
| 2772 | /* if interrupt but no bits showing, must be SWINT */ | 2778 | /* if interrupt but no bits showing, must be SWINT */ |
| 2773 | if (((icr0 & ~I40E_PFINT_ICR0_INTEVENT_MASK) == 0) || | 2779 | if (((icr0 & ~I40E_PFINT_ICR0_INTEVENT_MASK) == 0) || |
| @@ -2843,7 +2849,9 @@ static irqreturn_t i40e_intr(int irq, void *data) | |||
| 2843 | } | 2849 | } |
| 2844 | ena_mask &= ~icr0_remaining; | 2850 | ena_mask &= ~icr0_remaining; |
| 2845 | } | 2851 | } |
| 2852 | ret = IRQ_HANDLED; | ||
| 2846 | 2853 | ||
| 2854 | enable_intr: | ||
| 2847 | /* re-enable interrupt causes */ | 2855 | /* re-enable interrupt causes */ |
| 2848 | wr32(hw, I40E_PFINT_ICR0_ENA, ena_mask); | 2856 | wr32(hw, I40E_PFINT_ICR0_ENA, ena_mask); |
| 2849 | if (!test_bit(__I40E_DOWN, &pf->state)) { | 2857 | if (!test_bit(__I40E_DOWN, &pf->state)) { |
| @@ -2851,7 +2859,7 @@ static irqreturn_t i40e_intr(int irq, void *data) | |||
| 2851 | i40e_irq_dynamic_enable_icr0(pf); | 2859 | i40e_irq_dynamic_enable_icr0(pf); |
| 2852 | } | 2860 | } |
| 2853 | 2861 | ||
| 2854 | return IRQ_HANDLED; | 2862 | return ret; |
| 2855 | } | 2863 | } |
| 2856 | 2864 | ||
| 2857 | /** | 2865 | /** |
| @@ -4514,10 +4522,13 @@ static void i40e_clean_adminq_subtask(struct i40e_pf *pf) | |||
| 4514 | dev_info(&pf->pdev->dev, "ARQ LAN queue overflow event received\n"); | 4522 | dev_info(&pf->pdev->dev, "ARQ LAN queue overflow event received\n"); |
| 4515 | i40e_handle_lan_overflow_event(pf, &event); | 4523 | i40e_handle_lan_overflow_event(pf, &event); |
| 4516 | break; | 4524 | break; |
| 4525 | case i40e_aqc_opc_send_msg_to_peer: | ||
| 4526 | dev_info(&pf->pdev->dev, "ARQ: Msg from other pf\n"); | ||
| 4527 | break; | ||
| 4517 | default: | 4528 | default: |
| 4518 | dev_info(&pf->pdev->dev, | 4529 | dev_info(&pf->pdev->dev, |
| 4519 | "ARQ Error: Unknown event %d received\n", | 4530 | "ARQ Error: Unknown event 0x%04x received\n", |
| 4520 | event.desc.opcode); | 4531 | opcode); |
| 4521 | break; | 4532 | break; |
| 4522 | } | 4533 | } |
| 4523 | } while (pending && (i++ < pf->adminq_work_limit)); | 4534 | } while (pending && (i++ < pf->adminq_work_limit)); |
| @@ -4647,7 +4658,7 @@ static int i40e_get_capabilities(struct i40e_pf *pf) | |||
| 4647 | } | 4658 | } |
| 4648 | } while (err); | 4659 | } while (err); |
| 4649 | 4660 | ||
| 4650 | if (pf->hw.revision_id == 0 && pf->hw.func_caps.npar_enable) { | 4661 | if (pf->hw.revision_id == 0 && (pf->flags & I40E_FLAG_MFP_ENABLED)) { |
| 4651 | pf->hw.func_caps.num_msix_vectors += 1; | 4662 | pf->hw.func_caps.num_msix_vectors += 1; |
| 4652 | pf->hw.func_caps.num_tx_qp = | 4663 | pf->hw.func_caps.num_tx_qp = |
| 4653 | min_t(int, pf->hw.func_caps.num_tx_qp, | 4664 | min_t(int, pf->hw.func_caps.num_tx_qp, |
| @@ -4784,7 +4795,7 @@ static int i40e_prep_for_reset(struct i40e_pf *pf) | |||
| 4784 | } | 4795 | } |
| 4785 | 4796 | ||
| 4786 | /** | 4797 | /** |
| 4787 | * i40e_reset_and_rebuild - reset and rebuid using a saved config | 4798 | * i40e_reset_and_rebuild - reset and rebuild using a saved config |
| 4788 | * @pf: board private structure | 4799 | * @pf: board private structure |
| 4789 | * @reinit: if the Main VSI needs to re-initialized. | 4800 | * @reinit: if the Main VSI needs to re-initialized. |
| 4790 | **/ | 4801 | **/ |
| @@ -5348,7 +5359,7 @@ static void i40e_vsi_clear_rings(struct i40e_vsi *vsi) | |||
| 5348 | { | 5359 | { |
| 5349 | int i; | 5360 | int i; |
| 5350 | 5361 | ||
| 5351 | if (vsi->tx_rings[0]) { | 5362 | if (vsi->tx_rings && vsi->tx_rings[0]) { |
| 5352 | for (i = 0; i < vsi->alloc_queue_pairs; i++) { | 5363 | for (i = 0; i < vsi->alloc_queue_pairs; i++) { |
| 5353 | kfree_rcu(vsi->tx_rings[i], rcu); | 5364 | kfree_rcu(vsi->tx_rings[i], rcu); |
| 5354 | vsi->tx_rings[i] = NULL; | 5365 | vsi->tx_rings[i] = NULL; |
| @@ -5763,16 +5774,8 @@ int i40e_reconfig_rss_queues(struct i40e_pf *pf, int queue_count) | |||
| 5763 | queue_count = rounddown_pow_of_two(queue_count); | 5774 | queue_count = rounddown_pow_of_two(queue_count); |
| 5764 | 5775 | ||
| 5765 | if (queue_count != pf->rss_size) { | 5776 | if (queue_count != pf->rss_size) { |
| 5766 | if (pf->queues_left < (queue_count - pf->rss_size)) { | ||
| 5767 | dev_info(&pf->pdev->dev, | ||
| 5768 | "Not enough queues to do RSS on %d queues: remaining queues %d\n", | ||
| 5769 | queue_count, pf->queues_left); | ||
| 5770 | return pf->rss_size; | ||
| 5771 | } | ||
| 5772 | i40e_prep_for_reset(pf); | 5777 | i40e_prep_for_reset(pf); |
| 5773 | 5778 | ||
| 5774 | pf->num_lan_qps += (queue_count - pf->rss_size); | ||
| 5775 | pf->queues_left -= (queue_count - pf->rss_size); | ||
| 5776 | pf->rss_size = queue_count; | 5779 | pf->rss_size = queue_count; |
| 5777 | 5780 | ||
| 5778 | i40e_reset_and_rebuild(pf, true); | 5781 | i40e_reset_and_rebuild(pf, true); |
| @@ -5809,7 +5812,6 @@ static int i40e_sw_init(struct i40e_pf *pf) | |||
| 5809 | pf->flags = I40E_FLAG_RX_CSUM_ENABLED | | 5812 | pf->flags = I40E_FLAG_RX_CSUM_ENABLED | |
| 5810 | I40E_FLAG_MSI_ENABLED | | 5813 | I40E_FLAG_MSI_ENABLED | |
| 5811 | I40E_FLAG_MSIX_ENABLED | | 5814 | I40E_FLAG_MSIX_ENABLED | |
| 5812 | I40E_FLAG_RX_PS_ENABLED | | ||
| 5813 | I40E_FLAG_RX_1BUF_ENABLED; | 5815 | I40E_FLAG_RX_1BUF_ENABLED; |
| 5814 | 5816 | ||
| 5815 | /* Depending on PF configurations, it is possible that the RSS | 5817 | /* Depending on PF configurations, it is possible that the RSS |
| @@ -5825,6 +5827,12 @@ static int i40e_sw_init(struct i40e_pf *pf) | |||
| 5825 | pf->rss_size = 1; | 5827 | pf->rss_size = 1; |
| 5826 | } | 5828 | } |
| 5827 | 5829 | ||
| 5830 | /* MFP mode enabled */ | ||
| 5831 | if (pf->hw.func_caps.npar_enable || pf->hw.func_caps.mfp_mode_1) { | ||
| 5832 | pf->flags |= I40E_FLAG_MFP_ENABLED; | ||
| 5833 | dev_info(&pf->pdev->dev, "MFP mode Enabled\n"); | ||
| 5834 | } | ||
| 5835 | |||
| 5828 | if (pf->hw.func_caps.dcb) | 5836 | if (pf->hw.func_caps.dcb) |
| 5829 | pf->num_tc_qps = I40E_DEFAULT_QUEUES_PER_TC; | 5837 | pf->num_tc_qps = I40E_DEFAULT_QUEUES_PER_TC; |
| 5830 | else | 5838 | else |
| @@ -5853,12 +5861,6 @@ static int i40e_sw_init(struct i40e_pf *pf) | |||
| 5853 | pf->num_vmdq_qps = I40E_DEFAULT_QUEUES_PER_VMDQ; | 5861 | pf->num_vmdq_qps = I40E_DEFAULT_QUEUES_PER_VMDQ; |
| 5854 | } | 5862 | } |
| 5855 | 5863 | ||
| 5856 | /* MFP mode enabled */ | ||
| 5857 | if (pf->hw.func_caps.npar_enable || pf->hw.func_caps.mfp_mode_1) { | ||
| 5858 | pf->flags |= I40E_FLAG_MFP_ENABLED; | ||
| 5859 | dev_info(&pf->pdev->dev, "MFP mode Enabled\n"); | ||
| 5860 | } | ||
| 5861 | |||
| 5862 | #ifdef CONFIG_PCI_IOV | 5864 | #ifdef CONFIG_PCI_IOV |
| 5863 | if (pf->hw.func_caps.num_vfs) { | 5865 | if (pf->hw.func_caps.num_vfs) { |
| 5864 | pf->num_vf_qps = I40E_DEFAULT_QUEUES_PER_VF; | 5866 | pf->num_vf_qps = I40E_DEFAULT_QUEUES_PER_VF; |
