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


Jeff Kirsher says:

====================
100GbE Intel Wired LAN Driver Updates 2020-05-21

This series contains updates to ice driver only.  Several of the changes
are fixes, which could be backported to stable, of which, only one was
marked for stable because of the memory leak potential.

Jake exposes the information in the flash memory used for link
management, which is called the netlist module.

Henry and Tony add support for tunnel offloads.

Brett adds promiscuous support in VF's which is based on VF trust and
the new vf-true-promisc flag.

Avinash fixes an issue where a transmit timeout for a queue that belongs
to a PFC enabled TC is not a true transmit timeout, but because the PFC
is in action.

Dave fixes the check for contiguous TCs to allow for various UP2TC
mapping configurations.  Also fixed an issue when changing the pause
parameters would could multiple link drop/down's in succession, which in
turn caused the firmware to not generate a link interrupt for the driver
to respond to.

Anirudh (Ani) fixed a potential race condition in probe/open due to a
bit being cleared too early.

Lihong updates an error message to make it more meaningful instead of
just printing out the numerical value of the status/error code.  Also
fixed an incorrect return value if deleting a filter does not find a
match to delete or when adding a filter that already exists.

Karol fixes casting issues and precision loss in the driver.

Jesse make the sign usage more consistent in the driver by making sure
all instances of vf_id are unsigned, since it can never be negative.

Eric fixes a potential memory leak in ice_add_prof_id_vsig() where was
not cleaning up resources properly when an error occurs.

Michal to help organize the filtering code in the driver, refactor the
code into a separate file and add functions to prepare the filter
information.

Bruce cleaned up a conditional statement that always resulted in true
and provided a comment to make it more obvious.  Also cleaned up
redundant code checks.

Tony helps with potential namespace issues by renaming a 'ice' specific
function with the driver name prepended.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 4001f1f0 5757cc7c
Loading
Loading
Loading
Loading
+11 −0
Original line number Original line Diff line number Diff line
@@ -69,6 +69,17 @@ The ``ice`` driver reports the following versions
      - The version of the DDP package that is active in the device. Note
      - The version of the DDP package that is active in the device. Note
        that both the name (as reported by ``fw.app.name``) and version are
        that both the name (as reported by ``fw.app.name``) and version are
        required to uniquely identify the package.
        required to uniquely identify the package.
    * - ``fw.netlist``
      - running
      - 1.1.2000-6.7.0
      - The version of the netlist module. This module defines the device's
        Ethernet capabilities and default settings, and is used by the
        management firmware as part of managing link and device
        connectivity.
    * - ``fw.netlist.build``
      - running
      - 0xee16ced7
      - The first 4 bytes of the hash of the netlist module contents.


Regions
Regions
=======
=======
+1 −0
Original line number Original line Diff line number Diff line
@@ -17,6 +17,7 @@ ice-y := ice_main.o \
	 ice_lib.o	\
	 ice_lib.o	\
	 ice_txrx_lib.o	\
	 ice_txrx_lib.o	\
	 ice_txrx.o	\
	 ice_txrx.o	\
	 ice_fltr.o	\
	 ice_flex_pipe.o \
	 ice_flex_pipe.o \
	 ice_flow.o	\
	 ice_flow.o	\
	 ice_devlink.o	\
	 ice_devlink.o	\
+13 −6
Original line number Original line Diff line number Diff line
@@ -37,6 +37,10 @@
#include <net/devlink.h>
#include <net/devlink.h>
#include <net/ipv6.h>
#include <net/ipv6.h>
#include <net/xdp_sock.h>
#include <net/xdp_sock.h>
#include <net/geneve.h>
#include <net/gre.h>
#include <net/udp_tunnel.h>
#include <net/vxlan.h>
#include "ice_devids.h"
#include "ice_devids.h"
#include "ice_type.h"
#include "ice_type.h"
#include "ice_txrx.h"
#include "ice_txrx.h"
@@ -244,8 +248,8 @@ struct ice_vsi {
	u32 tx_busy;
	u32 tx_busy;
	u32 rx_buf_failed;
	u32 rx_buf_failed;
	u32 rx_page_failed;
	u32 rx_page_failed;
	int num_q_vectors;
	u16 num_q_vectors;
	int base_vector;		/* IRQ base for OS reserved vectors */
	u16 base_vector;		/* IRQ base for OS reserved vectors */
	enum ice_vsi_type type;
	enum ice_vsi_type type;
	u16 vsi_num;			/* HW (absolute) index of this VSI */
	u16 vsi_num;			/* HW (absolute) index of this VSI */
	u16 idx;			/* software index in pf->vsi[] */
	u16 idx;			/* software index in pf->vsi[] */
@@ -341,6 +345,7 @@ enum ice_pf_flags {
	ICE_FLAG_FW_LLDP_AGENT,
	ICE_FLAG_FW_LLDP_AGENT,
	ICE_FLAG_ETHTOOL_CTXT,		/* set when ethtool holds RTNL lock */
	ICE_FLAG_ETHTOOL_CTXT,		/* set when ethtool holds RTNL lock */
	ICE_FLAG_LEGACY_RX,
	ICE_FLAG_LEGACY_RX,
	ICE_FLAG_VF_TRUE_PROMISC_ENA,
	ICE_FLAG_MDD_AUTO_RESET_VF,
	ICE_FLAG_MDD_AUTO_RESET_VF,
	ICE_PF_FLAGS_NBITS		/* must be last */
	ICE_PF_FLAGS_NBITS		/* must be last */
};
};
@@ -366,7 +371,7 @@ struct ice_pf {
	struct ice_sw *first_sw;	/* first switch created by firmware */
	struct ice_sw *first_sw;	/* first switch created by firmware */
	/* Virtchnl/SR-IOV config info */
	/* Virtchnl/SR-IOV config info */
	struct ice_vf *vf;
	struct ice_vf *vf;
	int num_alloc_vfs;		/* actual number of VFs allocated */
	u16 num_alloc_vfs;		/* actual number of VFs allocated */
	u16 num_vfs_supported;		/* num VFs supported for this PF */
	u16 num_vfs_supported;		/* num VFs supported for this PF */
	u16 num_qps_per_vf;
	u16 num_qps_per_vf;
	u16 num_msix_per_vf;
	u16 num_msix_per_vf;
@@ -385,11 +390,11 @@ struct ice_pf {
	struct mutex tc_mutex;		/* lock to protect TC changes */
	struct mutex tc_mutex;		/* lock to protect TC changes */
	u32 msg_enable;
	u32 msg_enable;
	u32 hw_csum_rx_error;
	u32 hw_csum_rx_error;
	u32 oicr_idx;		/* Other interrupt cause MSIX vector index */
	u16 oicr_idx;		/* Other interrupt cause MSIX vector index */
	u32 num_avail_sw_msix;	/* remaining MSIX SW vectors left unclaimed */
	u16 num_avail_sw_msix;	/* remaining MSIX SW vectors left unclaimed */
	u16 max_pf_txqs;	/* Total Tx queues PF wide */
	u16 max_pf_txqs;	/* Total Tx queues PF wide */
	u16 max_pf_rxqs;	/* Total Rx queues PF wide */
	u16 max_pf_rxqs;	/* Total Rx queues PF wide */
	u32 num_lan_msix;	/* Total MSIX vectors for base driver */
	u16 num_lan_msix;	/* Total MSIX vectors for base driver */
	u16 num_lan_tx;		/* num LAN Tx queues setup */
	u16 num_lan_tx;		/* num LAN Tx queues setup */
	u16 num_lan_rx;		/* num LAN Rx queues setup */
	u16 num_lan_rx;		/* num LAN Rx queues setup */
	u16 next_vsi;		/* Next free slot in pf->vsi[] - 0-based! */
	u16 next_vsi;		/* Next free slot in pf->vsi[] - 0-based! */
@@ -523,6 +528,8 @@ int ice_get_rss(struct ice_vsi *vsi, u8 *seed, u8 *lut, u16 lut_size);
void ice_fill_rss_lut(u8 *lut, u16 rss_table_size, u16 rss_size);
void ice_fill_rss_lut(u8 *lut, u16 rss_table_size, u16 rss_size);
int ice_schedule_reset(struct ice_pf *pf, enum ice_reset_req reset);
int ice_schedule_reset(struct ice_pf *pf, enum ice_reset_req reset);
void ice_print_link_msg(struct ice_vsi *vsi, bool isup);
void ice_print_link_msg(struct ice_vsi *vsi, bool isup);
const char *ice_stat_str(enum ice_status stat_err);
const char *ice_aq_str(enum ice_aq_err aq_err);
int ice_open(struct net_device *netdev);
int ice_open(struct net_device *netdev);
int ice_stop(struct net_device *netdev);
int ice_stop(struct net_device *netdev);


+28 −1
Original line number Original line Diff line number Diff line
@@ -541,7 +541,7 @@ struct ice_sw_rule_lkup_rx_tx {
#define ICE_SINGLE_ACT_OTHER_ACTS		0x3
#define ICE_SINGLE_ACT_OTHER_ACTS		0x3
#define ICE_SINGLE_OTHER_ACT_IDENTIFIER_S	17
#define ICE_SINGLE_OTHER_ACT_IDENTIFIER_S	17
#define ICE_SINGLE_OTHER_ACT_IDENTIFIER_M	\
#define ICE_SINGLE_OTHER_ACT_IDENTIFIER_M	\
				(0x3 << \ ICE_SINGLE_OTHER_ACT_IDENTIFIER_S)
				(0x3 << ICE_SINGLE_OTHER_ACT_IDENTIFIER_S)


	/* Bit 17:18 - Defines other actions */
	/* Bit 17:18 - Defines other actions */
	/* Other action = 0 - Mirror VSI */
	/* Other action = 0 - Mirror VSI */
@@ -1264,6 +1264,33 @@ struct ice_aqc_nvm_checksum {
	u8 rsvd2[12];
	u8 rsvd2[12];
};
};


/* The result of netlist NVM read comes in a TLV format. The actual data
 * (netlist header) starts from word offset 1 (byte 2). The FW strips
 * out the type field from the TLV header so all the netlist fields
 * should adjust their offset value by 1 word (2 bytes) in order to map
 * their correct location.
 */
#define ICE_AQC_NVM_LINK_TOPO_NETLIST_MOD_ID		0x11B
#define ICE_AQC_NVM_LINK_TOPO_NETLIST_LEN_OFFSET	1
#define ICE_AQC_NVM_LINK_TOPO_NETLIST_LEN		2 /* In bytes */
#define ICE_AQC_NVM_NETLIST_NODE_COUNT_OFFSET		2
#define ICE_AQC_NVM_NETLIST_NODE_COUNT_LEN		2 /* In bytes */
#define ICE_AQC_NVM_NETLIST_NODE_COUNT_M		ICE_M(0x3FF, 0)
#define ICE_AQC_NVM_NETLIST_ID_BLK_START_OFFSET		5
#define ICE_AQC_NVM_NETLIST_ID_BLK_LEN			0x30 /* In words */

/* netlist ID block field offsets (word offsets) */
#define ICE_AQC_NVM_NETLIST_ID_BLK_MAJOR_VER_LOW	2
#define ICE_AQC_NVM_NETLIST_ID_BLK_MAJOR_VER_HIGH	3
#define ICE_AQC_NVM_NETLIST_ID_BLK_MINOR_VER_LOW	4
#define ICE_AQC_NVM_NETLIST_ID_BLK_MINOR_VER_HIGH	5
#define ICE_AQC_NVM_NETLIST_ID_BLK_TYPE_LOW		6
#define ICE_AQC_NVM_NETLIST_ID_BLK_TYPE_HIGH		7
#define ICE_AQC_NVM_NETLIST_ID_BLK_REV_LOW		8
#define ICE_AQC_NVM_NETLIST_ID_BLK_REV_HIGH		9
#define ICE_AQC_NVM_NETLIST_ID_BLK_SHA_HASH		0xA
#define ICE_AQC_NVM_NETLIST_ID_BLK_CUST_VER		0x2F

/**
/**
 * Send to PF command (indirect 0x0801) ID is only used by PF
 * Send to PF command (indirect 0x0801) ID is only used by PF
 *
 *
+18 −14
Original line number Original line Diff line number Diff line
@@ -24,7 +24,7 @@ static int __ice_vsi_get_qs_contig(struct ice_qs_cfg *qs_cfg)


	bitmap_set(qs_cfg->pf_map, offset, qs_cfg->q_count);
	bitmap_set(qs_cfg->pf_map, offset, qs_cfg->q_count);
	for (i = 0; i < qs_cfg->q_count; i++)
	for (i = 0; i < qs_cfg->q_count; i++)
		qs_cfg->vsi_map[i + qs_cfg->vsi_map_offset] = i + offset;
		qs_cfg->vsi_map[i + qs_cfg->vsi_map_offset] = (u16)(i + offset);
	mutex_unlock(qs_cfg->qs_mutex);
	mutex_unlock(qs_cfg->qs_mutex);


	return 0;
	return 0;
@@ -47,7 +47,7 @@ static int __ice_vsi_get_qs_sc(struct ice_qs_cfg *qs_cfg)
		if (index >= qs_cfg->pf_map_size)
		if (index >= qs_cfg->pf_map_size)
			goto err_scatter;
			goto err_scatter;
		set_bit(index, qs_cfg->pf_map);
		set_bit(index, qs_cfg->pf_map);
		qs_cfg->vsi_map[i + qs_cfg->vsi_map_offset] = index;
		qs_cfg->vsi_map[i + qs_cfg->vsi_map_offset] = (u16)index;
	}
	}
	mutex_unlock(qs_cfg->qs_mutex);
	mutex_unlock(qs_cfg->qs_mutex);


@@ -96,7 +96,7 @@ static int ice_pf_rxq_wait(struct ice_pf *pf, int pf_q, bool ena)
 * We allocate one q_vector and set default value for ITR setting associated
 * We allocate one q_vector and set default value for ITR setting associated
 * with this q_vector. If allocation fails we return -ENOMEM.
 * with this q_vector. If allocation fails we return -ENOMEM.
 */
 */
static int ice_vsi_alloc_q_vector(struct ice_vsi *vsi, int v_idx)
static int ice_vsi_alloc_q_vector(struct ice_vsi *vsi, u16 v_idx)
{
{
	struct ice_pf *pf = vsi->back;
	struct ice_pf *pf = vsi->back;
	struct ice_q_vector *q_vector;
	struct ice_q_vector *q_vector;
@@ -376,7 +376,7 @@ int ice_setup_rx_ctx(struct ice_ring *ring)
	/* Max packet size for this queue - must not be set to a larger value
	/* Max packet size for this queue - must not be set to a larger value
	 * than 5 x DBUF
	 * than 5 x DBUF
	 */
	 */
	rlan_ctx.rxmax = min_t(u16, vsi->max_frame,
	rlan_ctx.rxmax = min_t(u32, vsi->max_frame,
			       chain_len * ring->rx_buf_len);
			       chain_len * ring->rx_buf_len);


	/* Rx queue threshold in units of 64 */
	/* Rx queue threshold in units of 64 */
@@ -453,7 +453,7 @@ int __ice_vsi_get_qs(struct ice_qs_cfg *qs_cfg)
	if (ret) {
	if (ret) {
		/* contig failed, so try with scatter approach */
		/* contig failed, so try with scatter approach */
		qs_cfg->mapping_mode = ICE_VSI_MAP_SCATTER;
		qs_cfg->mapping_mode = ICE_VSI_MAP_SCATTER;
		qs_cfg->q_count = min_t(u16, qs_cfg->q_count,
		qs_cfg->q_count = min_t(unsigned int, qs_cfg->q_count,
					qs_cfg->scatter_count);
					qs_cfg->scatter_count);
		ret = __ice_vsi_get_qs_sc(qs_cfg);
		ret = __ice_vsi_get_qs_sc(qs_cfg);
	}
	}
@@ -526,7 +526,8 @@ int ice_vsi_wait_one_rx_ring(struct ice_vsi *vsi, bool ena, u16 rxq_idx)
int ice_vsi_alloc_q_vectors(struct ice_vsi *vsi)
int ice_vsi_alloc_q_vectors(struct ice_vsi *vsi)
{
{
	struct device *dev = ice_pf_to_dev(vsi->back);
	struct device *dev = ice_pf_to_dev(vsi->back);
	int v_idx, err;
	u16 v_idx;
	int err;


	if (vsi->q_vectors[0]) {
	if (vsi->q_vectors[0]) {
		dev_dbg(dev, "VSI %d has existing q_vectors\n", vsi->vsi_num);
		dev_dbg(dev, "VSI %d has existing q_vectors\n", vsi->vsi_num);
@@ -562,7 +563,7 @@ err_out:
void ice_vsi_map_rings_to_vectors(struct ice_vsi *vsi)
void ice_vsi_map_rings_to_vectors(struct ice_vsi *vsi)
{
{
	int q_vectors = vsi->num_q_vectors;
	int q_vectors = vsi->num_q_vectors;
	int tx_rings_rem, rx_rings_rem;
	u16 tx_rings_rem, rx_rings_rem;
	int v_id;
	int v_id;


	/* initially assigning remaining rings count to VSIs num queue value */
	/* initially assigning remaining rings count to VSIs num queue value */
@@ -571,10 +572,12 @@ void ice_vsi_map_rings_to_vectors(struct ice_vsi *vsi)


	for (v_id = 0; v_id < q_vectors; v_id++) {
	for (v_id = 0; v_id < q_vectors; v_id++) {
		struct ice_q_vector *q_vector = vsi->q_vectors[v_id];
		struct ice_q_vector *q_vector = vsi->q_vectors[v_id];
		int tx_rings_per_v, rx_rings_per_v, q_id, q_base;
		u8 tx_rings_per_v, rx_rings_per_v;
		u16 q_id, q_base;


		/* Tx rings mapping to vector */
		/* Tx rings mapping to vector */
		tx_rings_per_v = DIV_ROUND_UP(tx_rings_rem, q_vectors - v_id);
		tx_rings_per_v = (u8)DIV_ROUND_UP(tx_rings_rem,
						  q_vectors - v_id);
		q_vector->num_ring_tx = tx_rings_per_v;
		q_vector->num_ring_tx = tx_rings_per_v;
		q_vector->tx.ring = NULL;
		q_vector->tx.ring = NULL;
		q_vector->tx.itr_idx = ICE_TX_ITR;
		q_vector->tx.itr_idx = ICE_TX_ITR;
@@ -590,7 +593,8 @@ void ice_vsi_map_rings_to_vectors(struct ice_vsi *vsi)
		tx_rings_rem -= tx_rings_per_v;
		tx_rings_rem -= tx_rings_per_v;


		/* Rx rings mapping to vector */
		/* Rx rings mapping to vector */
		rx_rings_per_v = DIV_ROUND_UP(rx_rings_rem, q_vectors - v_id);
		rx_rings_per_v = (u8)DIV_ROUND_UP(rx_rings_rem,
						  q_vectors - v_id);
		q_vector->num_ring_rx = rx_rings_per_v;
		q_vector->num_ring_rx = rx_rings_per_v;
		q_vector->rx.ring = NULL;
		q_vector->rx.ring = NULL;
		q_vector->rx.itr_idx = ICE_RX_ITR;
		q_vector->rx.itr_idx = ICE_RX_ITR;
@@ -662,8 +666,8 @@ ice_vsi_cfg_txq(struct ice_vsi *vsi, struct ice_ring *ring,
	status = ice_ena_vsi_txq(vsi->port_info, vsi->idx, tc, ring->q_handle,
	status = ice_ena_vsi_txq(vsi->port_info, vsi->idx, tc, ring->q_handle,
				 1, qg_buf, buf_len, NULL);
				 1, qg_buf, buf_len, NULL);
	if (status) {
	if (status) {
		dev_err(ice_pf_to_dev(pf), "Failed to set LAN Tx queue context, error: %d\n",
		dev_err(ice_pf_to_dev(pf), "Failed to set LAN Tx queue context, error: %s\n",
			status);
			ice_stat_str(status));
		return -ENODEV;
		return -ENODEV;
	}
	}


@@ -832,8 +836,8 @@ ice_vsi_stop_tx_ring(struct ice_vsi *vsi, enum ice_disq_rst_src rst_src,
	} else if (status == ICE_ERR_DOES_NOT_EXIST) {
	} else if (status == ICE_ERR_DOES_NOT_EXIST) {
		dev_dbg(ice_pf_to_dev(vsi->back), "LAN Tx queues do not exist, nothing to disable\n");
		dev_dbg(ice_pf_to_dev(vsi->back), "LAN Tx queues do not exist, nothing to disable\n");
	} else if (status) {
	} else if (status) {
		dev_err(ice_pf_to_dev(vsi->back), "Failed to disable LAN Tx queues, error: %d\n",
		dev_err(ice_pf_to_dev(vsi->back), "Failed to disable LAN Tx queues, error: %s\n",
			status);
			ice_stat_str(status));
		return -ENODEV;
		return -ENODEV;
	}
	}


Loading