Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d5486377 authored by David S. Miller's avatar David S. Miller
Browse files


Jeff Kirsher says:

====================
100GbE Intel Wired LAN Driver Updates 2018-10-02

This series contains updates to ice driver only.

Anirudh expands the use of VSI handles across the rest of the driver,
which includes refactoring the code to correctly use VSI handles.  After
a reset, ensure that all configurations for a VSI get re-applied before
moving on to rebuilding the next VSI.

Dave fixed the driver to check the current link state after reset to
ensure that the correct link state of a port is reported.  Fixed an
issue where if the driver is unloaded when traffic is in progress,
errors are generated.

Preethi breaks up the IRQ tracker into a software and hardware IRQ
tracker, where the software IRQ tracker tracks only the PF's IRQ
requests and does not play any role in the VF initialization.  The
hardware IRQ tracker represents the device's interrupt space and will be
looked up to see if the device has run our of interrupts when a
interrupt has to be allocated in the device for either PF or VF.

Md Fahad adds support for enabling/disabling RSS via ethtool.

Brett aligns the ice_reset_req enum values to the values that the
hardware understands.  Also added initial support for dynamic interrupt
moderation in the ice driver.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents dd0bb7f9 81b23589
Loading
Loading
Loading
Loading
+19 −6
Original line number Diff line number Diff line
@@ -172,7 +172,8 @@ struct ice_vsi {
	u32 rx_buf_failed;
	u32 rx_page_failed;
	int num_q_vectors;
	int base_vector;
	int sw_base_vector;		/* Irq base for OS reserved vectors */
	int hw_base_vector;		/* HW (absolute) index of a vector */
	enum ice_vsi_type type;
	u16 vsi_num;			 /* HW (absolute) index of this VSI */
	u16 idx;			 /* software index in pf->vsi[] */
@@ -229,6 +230,10 @@ struct ice_q_vector {
	u8 num_ring_tx;			/* total number of tx rings in vector */
	u8 num_ring_rx;			/* total number of rx rings in vector */
	char name[ICE_INT_NAME_STR_LEN];
	/* in usecs, need to use ice_intrl_to_usecs_reg() before writing this
	 * value to the device
	 */
	u8 intrl;
} ____cacheline_internodealigned_in_smp;

enum ice_pf_flags {
@@ -240,8 +245,14 @@ enum ice_pf_flags {

struct ice_pf {
	struct pci_dev *pdev;

	/* OS reserved IRQ details */
	struct msix_entry *msix_entries;
	struct ice_res_tracker *irq_tracker;
	struct ice_res_tracker *sw_irq_tracker;

	/* HW reserved Interrupts for this PF */
	struct ice_res_tracker *hw_irq_tracker;

	struct ice_vsi **vsi;		/* VSIs created by the driver */
	struct ice_sw *first_sw;	/* first switch created by firmware */
	DECLARE_BITMAP(state, __ICE_STATE_NBITS);
@@ -256,9 +267,11 @@ struct ice_pf {
	struct mutex sw_mutex;		/* lock for protecting VSI alloc flow */
	u32 msg_enable;
	u32 hw_csum_rx_error;
	u32 oicr_idx;		/* Other interrupt cause vector index */
	u32 sw_oicr_idx;	/* Other interrupt cause SW vector index */
	u32 num_avail_sw_msix;	/* remaining MSIX SW vectors left unclaimed */
	u32 hw_oicr_idx;	/* Other interrupt cause vector HW index */
	u32 num_avail_hw_msix;	/* remaining HW MSIX vectors left unclaimed */
	u32 num_lan_msix;	/* Total MSIX vectors for base driver */
	u32 num_avail_msix;	/* remaining MSIX vectors left unclaimed */
	u16 num_lan_tx;		/* num lan tx queues setup */
	u16 num_lan_rx;		/* num lan rx queues setup */
	u16 q_left_tx;		/* remaining num tx queues left unclaimed */
@@ -293,8 +306,8 @@ struct ice_netdev_priv {
static inline void ice_irq_dynamic_ena(struct ice_hw *hw, struct ice_vsi *vsi,
				       struct ice_q_vector *q_vector)
{
	u32 vector = (vsi && q_vector) ? vsi->base_vector + q_vector->v_idx :
					((struct ice_pf *)hw->back)->oicr_idx;
	u32 vector = (vsi && q_vector) ? vsi->hw_base_vector + q_vector->v_idx :
				((struct ice_pf *)hw->back)->hw_oicr_idx;
	int itr = ICE_ITR_NONE;
	u32 val;

+147 −33
Original line number Diff line number Diff line
@@ -422,7 +422,7 @@ static void ice_cleanup_fltr_mgmt_struct(struct ice_hw *hw)
			devm_kfree(ice_hw_to_dev(hw), lst_itr);
		}
	}

	ice_rm_all_sw_replay_rule_info(hw);
	devm_kfree(ice_hw_to_dev(hw), sw->recp_list);
	devm_kfree(ice_hw_to_dev(hw), sw);
}
@@ -597,6 +597,39 @@ void ice_output_fw_log(struct ice_hw *hw, struct ice_aq_desc *desc, void *buf)
	ice_debug(hw, ICE_DBG_AQ_MSG, "[ FW Log Msg End ]\n");
}

/**
 * ice_get_itr_intrl_gran - determine int/intrl granularity
 * @hw: pointer to the hw struct
 *
 * Determines the itr/intrl granularities based on the maximum aggregate
 * bandwidth according to the device's configuration during power-on.
 */
static enum ice_status ice_get_itr_intrl_gran(struct ice_hw *hw)
{
	u8 max_agg_bw = (rd32(hw, GL_PWR_MODE_CTL) &
			 GL_PWR_MODE_CTL_CAR_MAX_BW_M) >>
			GL_PWR_MODE_CTL_CAR_MAX_BW_S;

	switch (max_agg_bw) {
	case ICE_MAX_AGG_BW_200G:
	case ICE_MAX_AGG_BW_100G:
	case ICE_MAX_AGG_BW_50G:
		hw->itr_gran = ICE_ITR_GRAN_ABOVE_25;
		hw->intrl_gran = ICE_INTRL_GRAN_ABOVE_25;
		break;
	case ICE_MAX_AGG_BW_25G:
		hw->itr_gran = ICE_ITR_GRAN_MAX_25;
		hw->intrl_gran = ICE_INTRL_GRAN_MAX_25;
		break;
	default:
		ice_debug(hw, ICE_DBG_INIT,
			  "Failed to determine itr/intrl granularity\n");
		return ICE_ERR_CFG;
	}

	return 0;
}

/**
 * ice_init_hw - main hardware initialization routine
 * @hw: pointer to the hardware structure
@@ -621,11 +654,9 @@ enum ice_status ice_init_hw(struct ice_hw *hw)
	if (status)
		return status;

	/* set these values to minimum allowed */
	hw->itr_gran_200 = ICE_ITR_GRAN_MIN_200;
	hw->itr_gran_100 = ICE_ITR_GRAN_MIN_100;
	hw->itr_gran_50 = ICE_ITR_GRAN_MIN_50;
	hw->itr_gran_25 = ICE_ITR_GRAN_MIN_25;
	status = ice_get_itr_intrl_gran(hw);
	if (status)
		return status;

	status = ice_init_all_ctrlq(hw);
	if (status)
@@ -1740,8 +1771,7 @@ ice_aq_set_phy_cfg(struct ice_hw *hw, u8 lport,
 * ice_update_link_info - update status of the HW network link
 * @pi: port info structure of the interested logical port
 */
static enum ice_status
ice_update_link_info(struct ice_port_info *pi)
enum ice_status ice_update_link_info(struct ice_port_info *pi)
{
	struct ice_aqc_get_phy_caps_data *pcaps;
	struct ice_phy_info *phy_info;
@@ -2055,7 +2085,7 @@ __ice_aq_get_set_rss_lut(struct ice_hw *hw, u16 vsi_id, u8 lut_type, u8 *lut,
/**
 * ice_aq_get_rss_lut
 * @hw: pointer to the hardware structure
 * @vsi_id: VSI FW index
 * @vsi_handle: software VSI handle
 * @lut_type: LUT table type
 * @lut: pointer to the LUT buffer provided by the caller
 * @lut_size: size of the LUT buffer
@@ -2063,17 +2093,20 @@ __ice_aq_get_set_rss_lut(struct ice_hw *hw, u16 vsi_id, u8 lut_type, u8 *lut,
 * get the RSS lookup table, PF or VSI type
 */
enum ice_status
ice_aq_get_rss_lut(struct ice_hw *hw, u16 vsi_id, u8 lut_type, u8 *lut,
		   u16 lut_size)
ice_aq_get_rss_lut(struct ice_hw *hw, u16 vsi_handle, u8 lut_type,
		   u8 *lut, u16 lut_size)
{
	return __ice_aq_get_set_rss_lut(hw, vsi_id, lut_type, lut, lut_size, 0,
					false);
	if (!ice_is_vsi_valid(hw, vsi_handle) || !lut)
		return ICE_ERR_PARAM;

	return __ice_aq_get_set_rss_lut(hw, ice_get_hw_vsi_num(hw, vsi_handle),
					lut_type, lut, lut_size, 0, false);
}

/**
 * ice_aq_set_rss_lut
 * @hw: pointer to the hardware structure
 * @vsi_id: VSI FW index
 * @vsi_handle: software VSI handle
 * @lut_type: LUT table type
 * @lut: pointer to the LUT buffer provided by the caller
 * @lut_size: size of the LUT buffer
@@ -2081,11 +2114,14 @@ ice_aq_get_rss_lut(struct ice_hw *hw, u16 vsi_id, u8 lut_type, u8 *lut,
 * set the RSS lookup table, PF or VSI type
 */
enum ice_status
ice_aq_set_rss_lut(struct ice_hw *hw, u16 vsi_id, u8 lut_type, u8 *lut,
		   u16 lut_size)
ice_aq_set_rss_lut(struct ice_hw *hw, u16 vsi_handle, u8 lut_type,
		   u8 *lut, u16 lut_size)
{
	return __ice_aq_get_set_rss_lut(hw, vsi_id, lut_type, lut, lut_size, 0,
					true);
	if (!ice_is_vsi_valid(hw, vsi_handle) || !lut)
		return ICE_ERR_PARAM;

	return __ice_aq_get_set_rss_lut(hw, ice_get_hw_vsi_num(hw, vsi_handle),
					lut_type, lut, lut_size, 0, true);
}

/**
@@ -2126,31 +2162,39 @@ ice_status __ice_aq_get_set_rss_key(struct ice_hw *hw, u16 vsi_id,
/**
 * ice_aq_get_rss_key
 * @hw: pointer to the hw struct
 * @vsi_id: VSI FW index
 * @vsi_handle: software VSI handle
 * @key: pointer to key info struct
 *
 * get the RSS key per VSI
 */
enum ice_status
ice_aq_get_rss_key(struct ice_hw *hw, u16 vsi_id,
ice_aq_get_rss_key(struct ice_hw *hw, u16 vsi_handle,
		   struct ice_aqc_get_set_rss_keys *key)
{
	return __ice_aq_get_set_rss_key(hw, vsi_id, key, false);
	if (!ice_is_vsi_valid(hw, vsi_handle) || !key)
		return ICE_ERR_PARAM;

	return __ice_aq_get_set_rss_key(hw, ice_get_hw_vsi_num(hw, vsi_handle),
					key, false);
}

/**
 * ice_aq_set_rss_key
 * @hw: pointer to the hw struct
 * @vsi_id: VSI FW index
 * @vsi_handle: software VSI handle
 * @keys: pointer to key info struct
 *
 * set the RSS key per VSI
 */
enum ice_status
ice_aq_set_rss_key(struct ice_hw *hw, u16 vsi_id,
ice_aq_set_rss_key(struct ice_hw *hw, u16 vsi_handle,
		   struct ice_aqc_get_set_rss_keys *keys)
{
	return __ice_aq_get_set_rss_key(hw, vsi_id, keys, true);
	if (!ice_is_vsi_valid(hw, vsi_handle) || !keys)
		return ICE_ERR_PARAM;

	return __ice_aq_get_set_rss_key(hw, ice_get_hw_vsi_num(hw, vsi_handle),
					keys, true);
}

/**
@@ -2489,7 +2533,7 @@ ice_set_ctx(u8 *src_ctx, u8 *dest_ctx, const struct ice_ctx_ele *ce_info)
/**
 * ice_ena_vsi_txq
 * @pi: port information structure
 * @vsi_id: VSI id
 * @vsi_handle: software VSI handle
 * @tc: tc number
 * @num_qgrps: Number of added queue groups
 * @buf: list of queue groups to be added
@@ -2499,7 +2543,7 @@ ice_set_ctx(u8 *src_ctx, u8 *dest_ctx, const struct ice_ctx_ele *ce_info)
 * This function adds one lan q
 */
enum ice_status
ice_ena_vsi_txq(struct ice_port_info *pi, u16 vsi_id, u8 tc, u8 num_qgrps,
ice_ena_vsi_txq(struct ice_port_info *pi, u16 vsi_handle, u8 tc, u8 num_qgrps,
		struct ice_aqc_add_tx_qgrp *buf, u16 buf_size,
		struct ice_sq_cd *cd)
{
@@ -2516,15 +2560,19 @@ ice_ena_vsi_txq(struct ice_port_info *pi, u16 vsi_id, u8 tc, u8 num_qgrps,

	hw = pi->hw;

	if (!ice_is_vsi_valid(hw, vsi_handle))
		return ICE_ERR_PARAM;

	mutex_lock(&pi->sched_lock);

	/* find a parent node */
	parent = ice_sched_get_free_qparent(pi, vsi_id, tc,
	parent = ice_sched_get_free_qparent(pi, vsi_handle, tc,
					    ICE_SCHED_NODE_OWNER_LAN);
	if (!parent) {
		status = ICE_ERR_PARAM;
		goto ena_txq_exit;
	}

	buf->parent_teid = parent->info.node_teid;
	node.parent_teid = parent->info.node_teid;
	/* Mark that the values in the "generic" section as valid. The default
@@ -2602,7 +2650,7 @@ ice_dis_vsi_txq(struct ice_port_info *pi, u8 num_queues, u16 *q_ids,
/**
 * ice_cfg_vsi_qs - configure the new/exisiting VSI queues
 * @pi: port information structure
 * @vsi_id: VSI Id
 * @vsi_handle: software VSI handle
 * @tc_bitmap: TC bitmap
 * @maxqs: max queues array per TC
 * @owner: lan or rdma
@@ -2610,7 +2658,7 @@ ice_dis_vsi_txq(struct ice_port_info *pi, u8 num_queues, u16 *q_ids,
 * This function adds/updates the VSI queues per TC.
 */
static enum ice_status
ice_cfg_vsi_qs(struct ice_port_info *pi, u16 vsi_id, u8 tc_bitmap,
ice_cfg_vsi_qs(struct ice_port_info *pi, u16 vsi_handle, u8 tc_bitmap,
	       u16 *maxqs, u8 owner)
{
	enum ice_status status = 0;
@@ -2619,6 +2667,9 @@ ice_cfg_vsi_qs(struct ice_port_info *pi, u16 vsi_id, u8 tc_bitmap,
	if (!pi || pi->port_state != ICE_SCHED_PORT_STATE_READY)
		return ICE_ERR_CFG;

	if (!ice_is_vsi_valid(pi->hw, vsi_handle))
		return ICE_ERR_PARAM;

	mutex_lock(&pi->sched_lock);

	for (i = 0; i < ICE_MAX_TRAFFIC_CLASS; i++) {
@@ -2626,7 +2677,7 @@ ice_cfg_vsi_qs(struct ice_port_info *pi, u16 vsi_id, u8 tc_bitmap,
		if (!ice_sched_get_tc_node(pi, i))
			continue;

		status = ice_sched_cfg_vsi(pi, vsi_id, i, maxqs[i], owner,
		status = ice_sched_cfg_vsi(pi, vsi_handle, i, maxqs[i], owner,
					   ice_is_tc_ena(tc_bitmap, i));
		if (status)
			break;
@@ -2639,20 +2690,83 @@ ice_cfg_vsi_qs(struct ice_port_info *pi, u16 vsi_id, u8 tc_bitmap,
/**
 * ice_cfg_vsi_lan - configure VSI lan queues
 * @pi: port information structure
 * @vsi_id: VSI Id
 * @vsi_handle: software VSI handle
 * @tc_bitmap: TC bitmap
 * @max_lanqs: max lan queues array per TC
 *
 * This function adds/updates the VSI lan queues per TC.
 */
enum ice_status
ice_cfg_vsi_lan(struct ice_port_info *pi, u16 vsi_id, u8 tc_bitmap,
ice_cfg_vsi_lan(struct ice_port_info *pi, u16 vsi_handle, u8 tc_bitmap,
		u16 *max_lanqs)
{
	return ice_cfg_vsi_qs(pi, vsi_id, tc_bitmap, max_lanqs,
	return ice_cfg_vsi_qs(pi, vsi_handle, tc_bitmap, max_lanqs,
			      ICE_SCHED_NODE_OWNER_LAN);
}

/**
 * ice_replay_pre_init - replay pre initialization
 * @hw: pointer to the hw struct
 *
 * Initializes required config data for VSI, FD, ACL, and RSS before replay.
 */
static enum ice_status ice_replay_pre_init(struct ice_hw *hw)
{
	struct ice_switch_info *sw = hw->switch_info;
	u8 i;

	/* Delete old entries from replay filter list head if there is any */
	ice_rm_all_sw_replay_rule_info(hw);
	/* In start of replay, move entries into replay_rules list, it
	 * will allow adding rules entries back to filt_rules list,
	 * which is operational list.
	 */
	for (i = 0; i < ICE_SW_LKUP_LAST; i++)
		list_replace_init(&sw->recp_list[i].filt_rules,
				  &sw->recp_list[i].filt_replay_rules);

	return 0;
}

/**
 * ice_replay_vsi - replay VSI configuration
 * @hw: pointer to the hw struct
 * @vsi_handle: driver VSI handle
 *
 * Restore all VSI configuration after reset. It is required to call this
 * function with main VSI first.
 */
enum ice_status ice_replay_vsi(struct ice_hw *hw, u16 vsi_handle)
{
	enum ice_status status;

	if (!ice_is_vsi_valid(hw, vsi_handle))
		return ICE_ERR_PARAM;

	/* Replay pre-initialization if there is any */
	if (vsi_handle == ICE_MAIN_VSI_HANDLE) {
		status = ice_replay_pre_init(hw);
		if (status)
			return status;
	}

	/* Replay per VSI all filters */
	status = ice_replay_vsi_all_fltr(hw, vsi_handle);
	return status;
}

/**
 * ice_replay_post - post replay configuration cleanup
 * @hw: pointer to the hw struct
 *
 * Post replay cleanup.
 */
void ice_replay_post(struct ice_hw *hw)
{
	/* Delete old entries from replay filter list head */
	ice_rm_all_sw_replay_rule_info(hw);
}

/**
 * ice_stat_update40 - read 40 bit stat from the chip and update stat values
 * @hw: ptr to the hardware info
+10 −6
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ ice_clean_rq_elem(struct ice_hw *hw, struct ice_ctl_q_info *cq,
		  struct ice_rq_event_info *e, u16 *pending);
enum ice_status
ice_get_link_status(struct ice_port_info *pi, bool *link_up);
enum ice_status ice_update_link_info(struct ice_port_info *pi);
enum ice_status
ice_acquire_res(struct ice_hw *hw, enum ice_aq_res_ids res,
		enum ice_aq_res_access_type access, u32 timeout);
@@ -37,17 +38,18 @@ ice_write_rxq_ctx(struct ice_hw *hw, struct ice_rlan_ctx *rlan_ctx,
		  u32 rxq_index);

enum ice_status
ice_aq_get_rss_lut(struct ice_hw *hw, u16 vsi_id, u8 lut_type, u8 *lut,
ice_aq_get_rss_lut(struct ice_hw *hw, u16 vsi_handle, u8 lut_type, u8 *lut,
		   u16 lut_size);
enum ice_status
ice_aq_set_rss_lut(struct ice_hw *hw, u16 vsi_id, u8 lut_type, u8 *lut,
ice_aq_set_rss_lut(struct ice_hw *hw, u16 vsi_handle, u8 lut_type, u8 *lut,
		   u16 lut_size);
enum ice_status
ice_aq_get_rss_key(struct ice_hw *hw, u16 vsi_id,
ice_aq_get_rss_key(struct ice_hw *hw, u16 vsi_handle,
		   struct ice_aqc_get_set_rss_keys *keys);
enum ice_status
ice_aq_set_rss_key(struct ice_hw *hw, u16 vsi_id,
ice_aq_set_rss_key(struct ice_hw *hw, u16 vsi_handle,
		   struct ice_aqc_get_set_rss_keys *keys);

bool ice_check_sq_alive(struct ice_hw *hw, struct ice_ctl_q_info *cq);
enum ice_status ice_aq_q_shutdown(struct ice_hw *hw, bool unloading);
void ice_fill_dflt_direct_cmd_desc(struct ice_aq_desc *desc, u16 opcode);
@@ -89,12 +91,14 @@ enum ice_status
ice_dis_vsi_txq(struct ice_port_info *pi, u8 num_queues, u16 *q_ids,
		u32 *q_teids, struct ice_sq_cd *cmd_details);
enum ice_status
ice_cfg_vsi_lan(struct ice_port_info *pi, u16 vsi_id, u8 tc_bitmap,
ice_cfg_vsi_lan(struct ice_port_info *pi, u16 vsi_handle, u8 tc_bitmap,
		u16 *max_lanqs);
enum ice_status
ice_ena_vsi_txq(struct ice_port_info *pi, u16 vsi_id, u8 tc, u8 num_qgrps,
ice_ena_vsi_txq(struct ice_port_info *pi, u16 vsi_handle, u8 tc, u8 num_qgrps,
		struct ice_aqc_add_tx_qgrp *buf, u16 buf_size,
		struct ice_sq_cd *cd);
enum ice_status ice_replay_vsi(struct ice_hw *hw, u16 vsi_handle);
void ice_replay_post(struct ice_hw *hw);
void ice_output_fw_log(struct ice_hw *hw, struct ice_aq_desc *desc, void *buf);
void ice_stat_update40(struct ice_hw *hw, u32 hireg, u32 loreg,
		       bool prev_stat_loaded, u64 *prev_stat, u64 *cur_stat);
+5 −0
Original line number Diff line number Diff line
@@ -88,6 +88,8 @@
#define GLINT_DYN_CTL_SW_ITR_INDX_M		ICE_M(0x3, 25)
#define GLINT_DYN_CTL_INTENA_MSK_M		BIT(31)
#define GLINT_ITR(_i, _INT)			(0x00154000 + ((_i) * 8192 + (_INT) * 4))
#define GLINT_RATE(_INT)			(0x0015A000 + ((_INT) * 4))
#define GLINT_RATE_INTRL_ENA_M			BIT(6)
#define PFINT_FW_CTL				0x0016C800
#define PFINT_FW_CTL_MSIX_INDX_M		ICE_M(0x7FF, 0)
#define PFINT_FW_CTL_ITR_INDX_S			11
@@ -173,6 +175,9 @@
#define PF_FUNC_RID				0x0009E880
#define PF_FUNC_RID_FUNC_NUM_S			0
#define PF_FUNC_RID_FUNC_NUM_M			ICE_M(0x7, 0)
#define GL_PWR_MODE_CTL				0x000B820C
#define GL_PWR_MODE_CTL_CAR_MAX_BW_S		30
#define GL_PWR_MODE_CTL_CAR_MAX_BW_M		ICE_M(0x3, 30)
#define GLPRT_BPRCH(_i)				(0x00381384 + ((_i) * 8))
#define GLPRT_BPRCL(_i)				(0x00381380 + ((_i) * 8))
#define GLPRT_BPTCH(_i)				(0x00381244 + ((_i) * 8))
+132 −50

File changed.

Preview size limit exceeded, changes collapsed.

Loading