diff options
Diffstat (limited to 'drivers/net/ethernet/intel/i40e/i40e_main.c')
| -rw-r--r-- | drivers/net/ethernet/intel/i40e/i40e_main.c | 82 | 
1 files changed, 61 insertions, 21 deletions
| diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c index 353deae139f9..c2d145a56b5e 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_main.c +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c @@ -6,6 +6,7 @@  #include <linux/pci.h>  #include <linux/bpf.h>  #include <generated/utsrelease.h> +#include <linux/crash_dump.h>  /* Local includes */  #include "i40e.h" @@ -2023,7 +2024,7 @@ static void i40e_undo_add_filter_entries(struct i40e_vsi *vsi,  }  /** - * i40e_next_entry - Get the next non-broadcast filter from a list + * i40e_next_filter - Get the next non-broadcast filter from a list   * @next: pointer to filter in list   *   * Returns the next non-broadcast filter in the list. Required so that we @@ -2560,8 +2561,7 @@ int i40e_sync_vsi_filters(struct i40e_vsi *vsi)  				 i40e_stat_str(hw, aq_ret),  				 i40e_aq_str(hw, hw->aq.asq_last_status));  		} else { -			dev_info(&pf->pdev->dev, "%s is %s allmulti mode.\n", -				 vsi->netdev->name, +			dev_info(&pf->pdev->dev, "%s allmulti mode.\n",  				 cur_multipromisc ? "entering" : "leaving");  		}  	} @@ -3259,6 +3259,17 @@ static int i40e_configure_tx_ring(struct i40e_ring *ring)  }  /** + * i40e_rx_offset - Return expected offset into page to access data + * @rx_ring: Ring we are requesting offset of + * + * Returns the offset value for ring into the data buffer. + */ +static unsigned int i40e_rx_offset(struct i40e_ring *rx_ring) +{ +	return ring_uses_build_skb(rx_ring) ? I40E_SKB_PAD : 0; +} + +/**   * i40e_configure_rx_ring - Configure a receive ring context   * @ring: The Rx ring to configure   * @@ -3369,6 +3380,8 @@ static int i40e_configure_rx_ring(struct i40e_ring *ring)  	else  		set_ring_build_skb_enabled(ring); +	ring->rx_offset = i40e_rx_offset(ring); +  	/* cache tail for quicker writes, and clear the reg before use */  	ring->tail = hw->hw_addr + I40E_QRX_TAIL(pf_q);  	writel(0, ring->tail); @@ -5191,7 +5204,7 @@ static u8 i40e_pf_get_num_tc(struct i40e_pf *pf)  }  /** - * i40e_pf_get_pf_tc_map - Get bitmap for enabled traffic classes + * i40e_pf_get_tc_map - Get bitmap for enabled traffic classes   * @pf: PF being queried   *   * Return a bitmap for enabled traffic classes for this PF. @@ -6725,9 +6738,9 @@ out:  			set_bit(__I40E_CLIENT_SERVICE_REQUESTED, pf->state);  			set_bit(__I40E_CLIENT_L2_CHANGE, pf->state);  		} -	/* registers are set, lets apply */ -	if (pf->hw_features & I40E_HW_USE_SET_LLDP_MIB) -		ret = i40e_hw_set_dcb_config(pf, new_cfg); +		/* registers are set, lets apply */ +		if (pf->hw_features & I40E_HW_USE_SET_LLDP_MIB) +			ret = i40e_hw_set_dcb_config(pf, new_cfg);  	}  err: @@ -7326,7 +7339,7 @@ static void i40e_vsi_set_default_tc_config(struct i40e_vsi *vsi)  	qcount = min_t(int, vsi->alloc_queue_pairs,  		       i40e_pf_get_max_q_per_tc(vsi->back));  	for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++) { -		/* For the TC that is not enabled set the offset to to default +		/* For the TC that is not enabled set the offset to default  		 * queue and allocate one queue for the given TC.  		 */  		vsi->tc_config.tc_info[i].qoffset = 0; @@ -9454,7 +9467,7 @@ static void i40e_fdir_flush_and_replay(struct i40e_pf *pf)  }  /** - * i40e_get_current_atr_count - Get the count of total FD ATR filters programmed + * i40e_get_current_atr_cnt - Get the count of total FD ATR filters programmed   * @pf: board private structure   **/  u32 i40e_get_current_atr_cnt(struct i40e_pf *pf) @@ -10560,12 +10573,6 @@ static void i40e_rebuild(struct i40e_pf *pf, bool reinit, bool lock_acquired)  		goto end_core_reset;  	} -	if (!lock_acquired) -		rtnl_lock(); -	ret = i40e_setup_pf_switch(pf, reinit); -	if (ret) -		goto end_unlock; -  #ifdef CONFIG_I40E_DCB  	/* Enable FW to write a default DCB config on link-up  	 * unless I40E_FLAG_TC_MQPRIO was enabled or DCB @@ -10580,7 +10587,7 @@ static void i40e_rebuild(struct i40e_pf *pf, bool reinit, bool lock_acquired)  			i40e_aq_set_dcb_parameters(hw, false, NULL);  			dev_warn(&pf->pdev->dev,  				 "DCB is not supported for X710-T*L 2.5/5G speeds\n"); -				 pf->flags &= ~I40E_FLAG_DCB_CAPABLE; +			pf->flags &= ~I40E_FLAG_DCB_CAPABLE;  		} else {  			i40e_aq_set_dcb_parameters(hw, true, NULL);  			ret = i40e_init_pf_dcb(pf); @@ -10594,6 +10601,11 @@ static void i40e_rebuild(struct i40e_pf *pf, bool reinit, bool lock_acquired)  	}  #endif /* CONFIG_I40E_DCB */ +	if (!lock_acquired) +		rtnl_lock(); +	ret = i40e_setup_pf_switch(pf, reinit); +	if (ret) +		goto end_unlock;  	/* The driver only wants link up/down and module qualification  	 * reports from firmware.  Note the negative logic. @@ -10612,7 +10624,7 @@ static void i40e_rebuild(struct i40e_pf *pf, bool reinit, bool lock_acquired)  	 * need to rebuild the switch model in the HW.  	 *  	 * If there were VEBs but the reconstitution failed, we'll try -	 * try to recover minimal use by getting the basic PF VSI working. +	 * to recover minimal use by getting the basic PF VSI working.  	 */  	if (vsi->uplink_seid != pf->mac_seid) {  		dev_dbg(&pf->pdev->dev, "attempting to rebuild switch\n"); @@ -11028,6 +11040,11 @@ static int i40e_set_num_rings_in_vsi(struct i40e_vsi *vsi)  		return -ENODATA;  	} +	if (is_kdump_kernel()) { +		vsi->num_tx_desc = I40E_MIN_NUM_DESCRIPTORS; +		vsi->num_rx_desc = I40E_MIN_NUM_DESCRIPTORS; +	} +  	return 0;  } @@ -12346,6 +12363,7 @@ static int i40e_sw_init(struct i40e_pf *pf)  {  	int err = 0;  	int size; +	u16 pow;  	/* Set default capability flags */  	pf->flags = I40E_FLAG_RX_CSUM_ENABLED | @@ -12364,6 +12382,11 @@ static int i40e_sw_init(struct i40e_pf *pf)  	pf->rss_table_size = pf->hw.func_caps.rss_table_size;  	pf->rss_size_max = min_t(int, pf->rss_size_max,  				 pf->hw.func_caps.num_tx_qp); + +	/* find the next higher power-of-2 of num cpus */ +	pow = roundup_pow_of_two(num_online_cpus()); +	pf->rss_size_max = min_t(int, pf->rss_size_max, pow); +  	if (pf->hw.func_caps.rss) {  		pf->flags |= I40E_FLAG_RSS_ENABLED;  		pf->alloc_rss_size = min_t(int, pf->rss_size_max, @@ -15127,12 +15150,16 @@ static int i40e_init_recovery_mode(struct i40e_pf *pf, struct i40e_hw *hw)  	 * in order to register the netdev  	 */  	v_idx = i40e_vsi_mem_alloc(pf, I40E_VSI_MAIN); -	if (v_idx < 0) +	if (v_idx < 0) { +		err = v_idx;  		goto err_switch_setup; +	}  	pf->lan_vsi = v_idx;  	vsi = pf->vsi[v_idx]; -	if (!vsi) +	if (!vsi) { +		err = -EFAULT;  		goto err_switch_setup; +	}  	vsi->alloc_queue_pairs = 1;  	err = i40e_config_netdev(vsi);  	if (err) @@ -15321,8 +15348,13 @@ static int i40e_probe(struct pci_dev *pdev, const struct pci_device_id *ent)  	i40e_check_recovery_mode(pf); -	hw->aq.num_arq_entries = I40E_AQ_LEN; -	hw->aq.num_asq_entries = I40E_AQ_LEN; +	if (is_kdump_kernel()) { +		hw->aq.num_arq_entries = I40E_MIN_ARQ_LEN; +		hw->aq.num_asq_entries = I40E_MIN_ASQ_LEN; +	} else { +		hw->aq.num_arq_entries = I40E_AQ_LEN; +		hw->aq.num_asq_entries = I40E_AQ_LEN; +	}  	hw->aq.arq_buf_size = I40E_MAX_AQ_BUF_SIZE;  	hw->aq.asq_buf_size = I40E_MAX_AQ_BUF_SIZE;  	pf->adminq_work_limit = I40E_AQ_WORK_LIMIT; @@ -15485,6 +15517,14 @@ static int i40e_probe(struct pci_dev *pdev, const struct pci_device_id *ent)  	if (err)  		goto err_switch_setup; +	/* Reduce Tx and Rx pairs for kdump +	 * When MSI-X is enabled, it's not allowed to use more TC queue +	 * pairs than MSI-X vectors (pf->num_lan_msix) exist. Thus +	 * vsi->num_queue_pairs will be equal to pf->num_lan_msix, i.e., 1. +	 */ +	if (is_kdump_kernel()) +		pf->num_lan_msix = 1; +  	pf->udp_tunnel_nic.set_port = i40e_udp_tunnel_set_port;  	pf->udp_tunnel_nic.unset_port = i40e_udp_tunnel_unset_port;  	pf->udp_tunnel_nic.flags = UDP_TUNNEL_NIC_INFO_MAY_SLEEP; | 
