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

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


Jeff Kirsher says:

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

This series contains updates to ice and virtchnl.

Yashaswini Raghuram adds a new virtchnl capability flag to support the
exchange of additional supported speeds.

Anirudh adds support for SR-IOV for the ice driver.  Added code to
initialize, configure and use mailbox queues for PF and VF
communication.  Updated the VSI and queue management to handle both PF
and VF VSI type.  Added "Adaptive Virtual Function (AVF)" support for
the ice PF driver by implementing virtchnl commands.  Extended the
malicious driver detection logic to include the VF driver as well.
Fixed the queue region size which needs to be log base 2 of the number
of queues in region.

Brett fixes an issue which was causing switch rules to be lost, by
making a call to ice_update_pkt_fwd_rule() with the necessary changes.
Fixed how the PF and VF assigned the ITR index by adding a struct member
itr_idx to be used to dynamically program the correct ITR index.

Dave fixed a potential NULL pointer dereference by adding checks in the
filter handling.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents db3408a1 5cc6c8b3
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -16,3 +16,4 @@ ice-y := ice_main.o \
	 ice_lib.o	\
	 ice_txrx.o	\
	 ice_ethtool.o
ice-$(CONFIG_PCI_IOV) += ice_virtchnl_pf.o ice_sriov.o
+34 −0
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@
#include <linux/ip.h>
#include <linux/ipv6.h>
#include <linux/if_bridge.h>
#include <linux/avf/virtchnl.h>
#include <net/ipv6.h>
#include "ice_devids.h"
#include "ice_type.h"
@@ -35,6 +36,8 @@
#include "ice_switch.h"
#include "ice_common.h"
#include "ice_sched.h"
#include "ice_virtchnl_pf.h"
#include "ice_sriov.h"

extern const char ice_drv_ver[];
#define ICE_BAR0		0
@@ -46,6 +49,7 @@ extern const char ice_drv_ver[];
#define ICE_INT_NAME_STR_LEN	(IFNAMSIZ + 16)
#define ICE_ETHTOOL_FWVER_LEN	32
#define ICE_AQ_LEN		64
#define ICE_MBXQ_LEN		64
#define ICE_MIN_MSIX		2
#define ICE_NO_VSI		0xffff
#define ICE_MAX_VSI_ALLOC	130
@@ -63,6 +67,14 @@ extern const char ice_drv_ver[];
#define ICE_RES_MISC_VEC_ID	(ICE_RES_VALID_BIT - 1)
#define ICE_INVAL_Q_INDEX	0xffff
#define ICE_INVAL_VFID		256
#define ICE_MAX_VF_COUNT	256
#define ICE_MAX_QS_PER_VF		256
#define ICE_MIN_QS_PER_VF		1
#define ICE_DFLT_QS_PER_VF		4
#define ICE_MAX_BASE_QS_PER_VF		16
#define ICE_MAX_INTR_PER_VF		65
#define ICE_MIN_INTR_PER_VF		(ICE_MIN_QS_PER_VF + 1)
#define ICE_DFLT_INTR_PER_VF		(ICE_DFLT_QS_PER_VF + 1)

#define ICE_VSIQF_HKEY_ARRAY_SIZE	((VSIQF_HKEY_MAX_INDEX + 1) *	4)

@@ -133,9 +145,21 @@ enum ice_state {
	__ICE_EMPR_RECV,		/* set by OICR handler */
	__ICE_SUSPENDED,		/* set on module remove path */
	__ICE_RESET_FAILED,		/* set by reset/rebuild */
	/* When checking for the PF to be in a nominal operating state, the
	 * bits that are grouped at the beginning of the list need to be
	 * checked.  Bits occurring before __ICE_STATE_NOMINAL_CHECK_BITS will
	 * be checked.  If you need to add a bit into consideration for nominal
	 * operating state, it must be added before
	 * __ICE_STATE_NOMINAL_CHECK_BITS.  Do not move this entry's position
	 * without appropriate consideration.
	 */
	__ICE_STATE_NOMINAL_CHECK_BITS,
	__ICE_ADMINQ_EVENT_PENDING,
	__ICE_MAILBOXQ_EVENT_PENDING,
	__ICE_MDD_EVENT_PENDING,
	__ICE_VFLR_EVENT_PENDING,
	__ICE_FLTR_OVERFLOW_PROMISC,
	__ICE_VF_DIS,
	__ICE_CFG_BUSY,
	__ICE_SERVICE_SCHED,
	__ICE_SERVICE_DIS,
@@ -181,6 +205,8 @@ struct ice_vsi {
	/* Interrupt thresholds */
	u16 work_lmt;

	s16 vf_id;			/* VF ID for SR-IOV VSIs */

	/* RSS config */
	u16 rss_table_size;	/* HW RSS table size */
	u16 rss_size;		/* Allocated RSS queues */
@@ -240,6 +266,8 @@ enum ice_pf_flags {
	ICE_FLAG_MSIX_ENA,
	ICE_FLAG_FLTR_SYNC,
	ICE_FLAG_RSS_ENA,
	ICE_FLAG_SRIOV_ENA,
	ICE_FLAG_SRIOV_CAPABLE,
	ICE_PF_FLAGS_NBITS		/* must be last */
};

@@ -255,6 +283,12 @@ struct ice_pf {

	struct ice_vsi **vsi;		/* VSIs created by the driver */
	struct ice_sw *first_sw;	/* first switch created by firmware */
	/* Virtchnl/SR-IOV config info */
	struct ice_vf *vf;
	int num_alloc_vfs;		/* actual number of VFs allocated */
	u16 num_vfs_supported;		/* num VFs supported for this PF */
	u16 num_vf_qps;			/* num queue pairs per VF */
	u16 num_vf_msix;		/* num vectors per VF */
	DECLARE_BITMAP(state, __ICE_STATE_NBITS);
	DECLARE_BITMAP(avail_txqs, ICE_MAX_TXQS);
	DECLARE_BITMAP(avail_rxqs, ICE_MAX_RXQS);
+20 −0
Original line number Diff line number Diff line
@@ -87,6 +87,8 @@ struct ice_aqc_list_caps {
/* Device/Function buffer entry, repeated per reported capability */
struct ice_aqc_list_caps_elem {
	__le16 cap;
#define ICE_AQC_CAPS_SRIOV				0x0012
#define ICE_AQC_CAPS_VF					0x0013
#define ICE_AQC_CAPS_VSI				0x0017
#define ICE_AQC_CAPS_RSS				0x0040
#define ICE_AQC_CAPS_RXQS				0x0041
@@ -1075,6 +1077,19 @@ struct ice_aqc_nvm {
	__le32 addr_low;
};

/**
 * Send to PF command (indirect 0x0801) id is only used by PF
 *
 * Send to VF command (indirect 0x0802) id is only used by PF
 *
 */
struct ice_aqc_pf_vf_msg {
	__le32 id;
	u32 reserved;
	__le32 addr_high;
	__le32 addr_low;
};

/* Get/Set RSS key (indirect 0x0B04/0x0B02) */
struct ice_aqc_get_set_rss_key {
#define ICE_AQC_GSET_RSS_KEY_VSI_VALID	BIT(15)
@@ -1332,6 +1347,7 @@ struct ice_aq_desc {
		struct ice_aqc_query_txsched_res query_sched_res;
		struct ice_aqc_add_move_delete_elem add_move_delete_elem;
		struct ice_aqc_nvm nvm;
		struct ice_aqc_pf_vf_msg virt;
		struct ice_aqc_get_set_rss_lut get_set_rss_lut;
		struct ice_aqc_get_set_rss_key get_set_rss_key;
		struct ice_aqc_add_txqs add_txqs;
@@ -1429,6 +1445,10 @@ enum ice_adminq_opc {
	/* NVM commands */
	ice_aqc_opc_nvm_read				= 0x0701,

	/* PF/VF mailbox commands */
	ice_mbx_opc_send_msg_to_pf			= 0x0801,
	ice_mbx_opc_send_msg_to_vf			= 0x0802,

	/* RSS commands */
	ice_aqc_opc_set_rss_key				= 0x0B02,
	ice_aqc_opc_set_rss_lut				= 0x0B03,
+74 −4
Original line number Diff line number Diff line
@@ -1406,6 +1406,28 @@ ice_parse_caps(struct ice_hw *hw, void *buf, u32 cap_count,
		u16 cap = le16_to_cpu(cap_resp->cap);

		switch (cap) {
		case ICE_AQC_CAPS_SRIOV:
			caps->sr_iov_1_1 = (number == 1);
			ice_debug(hw, ICE_DBG_INIT,
				  "HW caps: SR-IOV = %d\n", caps->sr_iov_1_1);
			break;
		case ICE_AQC_CAPS_VF:
			if (dev_p) {
				dev_p->num_vfs_exposed = number;
				ice_debug(hw, ICE_DBG_INIT,
					  "HW caps: VFs exposed = %d\n",
					  dev_p->num_vfs_exposed);
			} else if (func_p) {
				func_p->num_allocd_vfs = number;
				func_p->vf_base_id = logical_id;
				ice_debug(hw, ICE_DBG_INIT,
					  "HW caps: VFs allocated = %d\n",
					  func_p->num_allocd_vfs);
				ice_debug(hw, ICE_DBG_INIT,
					  "HW caps: VF base_id = %d\n",
					  func_p->vf_base_id);
			}
			break;
		case ICE_AQC_CAPS_VSI:
			if (dev_p) {
				dev_p->num_vsi_allocd_to_host = number;
@@ -2265,6 +2287,8 @@ ice_aq_add_lan_txq(struct ice_hw *hw, u8 num_qgrps,
 * @num_qgrps: number of groups in the list
 * @qg_list: the list of groups to disable
 * @buf_size: the total size of the qg_list buffer in bytes
 * @rst_src: if called due to reset, specifies the RST source
 * @vmvf_num: the relative VM or VF number that is undergoing the reset
 * @cd: pointer to command details structure or NULL
 *
 * Disable LAN Tx queue (0x0C31)
@@ -2272,6 +2296,7 @@ ice_aq_add_lan_txq(struct ice_hw *hw, u8 num_qgrps,
static enum ice_status
ice_aq_dis_lan_txq(struct ice_hw *hw, u8 num_qgrps,
		   struct ice_aqc_dis_txq_item *qg_list, u16 buf_size,
		   enum ice_disq_rst_src rst_src, u16 vmvf_num,
		   struct ice_sq_cd *cd)
{
	struct ice_aqc_dis_txqs *cmd;
@@ -2281,14 +2306,45 @@ ice_aq_dis_lan_txq(struct ice_hw *hw, u8 num_qgrps,
	cmd = &desc.params.dis_txqs;
	ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_dis_txqs);

	if (!qg_list)
	/* qg_list can be NULL only in VM/VF reset flow */
	if (!qg_list && !rst_src)
		return ICE_ERR_PARAM;

	if (num_qgrps > ICE_LAN_TXQ_MAX_QGRPS)
		return ICE_ERR_PARAM;
	desc.flags |= cpu_to_le16(ICE_AQ_FLAG_RD);

	cmd->num_entries = num_qgrps;

	cmd->vmvf_and_timeout = cpu_to_le16((5 << ICE_AQC_Q_DIS_TIMEOUT_S) &
					    ICE_AQC_Q_DIS_TIMEOUT_M);

	switch (rst_src) {
	case ICE_VM_RESET:
		cmd->cmd_type = ICE_AQC_Q_DIS_CMD_VM_RESET;
		cmd->vmvf_and_timeout |=
			cpu_to_le16(vmvf_num & ICE_AQC_Q_DIS_VMVF_NUM_M);
		break;
	case ICE_VF_RESET:
		cmd->cmd_type = ICE_AQC_Q_DIS_CMD_VF_RESET;
		/* In this case, FW expects vmvf_num to be absolute VF id */
		cmd->vmvf_and_timeout |=
			cpu_to_le16((vmvf_num + hw->func_caps.vf_base_id) &
				    ICE_AQC_Q_DIS_VMVF_NUM_M);
		break;
	case ICE_NO_RESET:
	default:
		break;
	}

	/* If no queue group info, we are in a reset flow. Issue the AQ */
	if (!qg_list)
		goto do_aq;

	/* set RD bit to indicate that command buffer is provided by the driver
	 * and it needs to be read by the firmware
	 */
	desc.flags |= cpu_to_le16(ICE_AQ_FLAG_RD);

	for (i = 0; i < num_qgrps; ++i) {
		/* Calculate the size taken up by the queue IDs in this group */
		sz += qg_list[i].num_qs * sizeof(qg_list[i].q_id);
@@ -2304,6 +2360,7 @@ ice_aq_dis_lan_txq(struct ice_hw *hw, u8 num_qgrps,
	if (buf_size != sz)
		return ICE_ERR_PARAM;

do_aq:
	return ice_aq_send_cmd(hw, &desc, qg_list, buf_size, cd);
}

@@ -2610,13 +2667,16 @@ ice_ena_vsi_txq(struct ice_port_info *pi, u16 vsi_handle, u8 tc, u8 num_qgrps,
 * @num_queues: number of queues
 * @q_ids: pointer to the q_id array
 * @q_teids: pointer to queue node teids
 * @rst_src: if called due to reset, specifies the RST source
 * @vmvf_num: the relative VM or VF number that is undergoing the reset
 * @cd: pointer to command details structure or NULL
 *
 * This function removes queues and their corresponding nodes in SW DB
 */
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 *cd)
		u32 *q_teids, enum ice_disq_rst_src rst_src, u16 vmvf_num,
		struct ice_sq_cd *cd)
{
	enum ice_status status = ICE_ERR_DOES_NOT_EXIST;
	struct ice_aqc_dis_txq_item qg_list;
@@ -2625,6 +2685,15 @@ ice_dis_vsi_txq(struct ice_port_info *pi, u8 num_queues, u16 *q_ids,
	if (!pi || pi->port_state != ICE_SCHED_PORT_STATE_READY)
		return ICE_ERR_CFG;

	/* if queue is disabled already yet the disable queue command has to be
	 * sent to complete the VF reset, then call ice_aq_dis_lan_txq without
	 * any queue information
	 */

	if (!num_queues && rst_src)
		return ice_aq_dis_lan_txq(pi->hw, 0, NULL, 0, rst_src, vmvf_num,
					  NULL);

	mutex_lock(&pi->sched_lock);

	for (i = 0; i < num_queues; i++) {
@@ -2637,7 +2706,8 @@ ice_dis_vsi_txq(struct ice_port_info *pi, u8 num_queues, u16 *q_ids,
		qg_list.num_qs = 1;
		qg_list.q_id[0] = cpu_to_le16(q_ids[i]);
		status = ice_aq_dis_lan_txq(pi->hw, 1, &qg_list,
					    sizeof(qg_list), cd);
					    sizeof(qg_list), rst_src, vmvf_num,
					    cd);

		if (status)
			break;
+3 −1
Original line number Diff line number Diff line
@@ -7,6 +7,7 @@
#include "ice.h"
#include "ice_type.h"
#include "ice_switch.h"
#include <linux/avf/virtchnl.h>

void ice_debug_cq(struct ice_hw *hw, u32 mask, void *desc, void *buf,
		  u16 buf_len);
@@ -89,7 +90,8 @@ ice_aq_set_event_mask(struct ice_hw *hw, u8 port_num, u16 mask,
		      struct ice_sq_cd *cd);
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);
		u32 *q_teids, enum ice_disq_rst_src rst_src, u16 vmvf_num,
		struct ice_sq_cd *cmd_details);
enum ice_status
ice_cfg_vsi_lan(struct ice_port_info *pi, u16 vsi_handle, u8 tc_bitmap,
		u16 *max_lanqs);
Loading