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

Commit e3219ce6 authored by Anjali Singhai Jain's avatar Anjali Singhai Jain Committed by Doug Ledford
Browse files

i40e: Add support for client interface for IWARP driver



This patch adds a Client interface for i40iw driver
support. Also expands the Virtchannel to support messages
from i40evf driver on behalf of i40iwvf driver.

This client API is used by the i40iw and i40iwvf driver
to access the core driver resources brokered by the i40e driver.

Signed-off-by: default avatarAnjali Singhai Jain <anjali.singhai@intel.com>
Signed-off-by: default avatarDoug Ledford <dledford@redhat.com>
parent fc77dbd3
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -41,6 +41,7 @@ i40e-objs := i40e_main.o \
	i40e_diag.o	\
	i40e_txrx.o	\
	i40e_ptp.o	\
	i40e_client.o   \
	i40e_virtchnl_pf.o

i40e-$(CONFIG_I40E_DCB) += i40e_dcb.o i40e_dcb_nl.o
+22 −0
Original line number Diff line number Diff line
@@ -58,6 +58,7 @@
#ifdef I40E_FCOE
#include "i40e_fcoe.h"
#endif
#include "i40e_client.h"
#include "i40e_virtchnl.h"
#include "i40e_virtchnl_pf.h"
#include "i40e_txrx.h"
@@ -178,6 +179,7 @@ struct i40e_lump_tracking {
	u16 search_hint;
	u16 list[0];
#define I40E_PILE_VALID_BIT  0x8000
#define I40E_IWARP_IRQ_PILE_ID  (I40E_PILE_VALID_BIT - 2)
};

#define I40E_DEFAULT_ATR_SAMPLE_RATE	20
@@ -270,6 +272,8 @@ struct i40e_pf {
#endif /* I40E_FCOE */
	u16 num_lan_qps;           /* num lan queues this PF has set up */
	u16 num_lan_msix;          /* num queue vectors for the base PF vsi */
	u16 num_iwarp_msix;        /* num of iwarp vectors for this PF */
	int iwarp_base_vector;
	int queues_left;           /* queues left unclaimed */
	u16 alloc_rss_size;        /* allocated RSS queues */
	u16 rss_size_max;          /* HW defined max RSS queues */
@@ -317,6 +321,7 @@ struct i40e_pf {
#define I40E_FLAG_16BYTE_RX_DESC_ENABLED	BIT_ULL(13)
#define I40E_FLAG_CLEAN_ADMINQ			BIT_ULL(14)
#define I40E_FLAG_FILTER_SYNC			BIT_ULL(15)
#define I40E_FLAG_SERVICE_CLIENT_REQUESTED	BIT_ULL(16)
#define I40E_FLAG_PROCESS_MDD_EVENT		BIT_ULL(17)
#define I40E_FLAG_PROCESS_VFLR_EVENT		BIT_ULL(18)
#define I40E_FLAG_SRIOV_ENABLED			BIT_ULL(19)
@@ -557,6 +562,8 @@ struct i40e_vsi {
	struct kobject *kobj;  /* sysfs object */
	bool current_isup;     /* Sync 'link up' logging */

	void *priv;	/* client driver data reference. */

	/* VSI specific handlers */
	irqreturn_t (*irq_handler)(int irq, void *data);

@@ -714,6 +721,10 @@ void i40e_vsi_setup_queue_map(struct i40e_vsi *vsi,
			      struct i40e_vsi_context *ctxt,
			      u8 enabled_tc, bool is_add);
#endif
void i40e_service_event_schedule(struct i40e_pf *pf);
void i40e_notify_client_of_vf_msg(struct i40e_vsi *vsi, u32 vf_id,
				  u8 *msg, u16 len);

int i40e_vsi_control_rings(struct i40e_vsi *vsi, bool enable);
int i40e_reconfig_rss_queues(struct i40e_pf *pf, int queue_count);
struct i40e_veb *i40e_veb_setup(struct i40e_pf *pf, u16 flags, u16 uplink_seid,
@@ -736,6 +747,17 @@ static inline void i40e_dbg_pf_exit(struct i40e_pf *pf) {}
static inline void i40e_dbg_init(void) {}
static inline void i40e_dbg_exit(void) {}
#endif /* CONFIG_DEBUG_FS*/
/* needed by client drivers */
int i40e_lan_add_device(struct i40e_pf *pf);
int i40e_lan_del_device(struct i40e_pf *pf);
void i40e_client_subtask(struct i40e_pf *pf);
void i40e_notify_client_of_l2_param_changes(struct i40e_vsi *vsi);
void i40e_notify_client_of_netdev_open(struct i40e_vsi *vsi);
void i40e_notify_client_of_netdev_close(struct i40e_vsi *vsi, bool reset);
void i40e_notify_client_of_vf_enable(struct i40e_pf *pf, u32 num_vfs);
void i40e_notify_client_of_vf_reset(struct i40e_pf *pf, u32 vf_id);
int i40e_vf_client_capable(struct i40e_pf *pf, u32 vf_id,
			   enum i40e_client_type type);
/**
 * i40e_irq_dynamic_enable - Enable default interrupt generation settings
 * @vsi: pointer to a vsi
+1012 −0

File added.

Preview size limit exceeded, changes collapsed.

+232 −0
Original line number Diff line number Diff line
/*******************************************************************************
 *
 * Intel Ethernet Controller XL710 Family Linux Driver
 * Copyright(c) 2013 - 2015 Intel Corporation.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms and conditions of the GNU General Public License,
 * version 2, as published by the Free Software Foundation.
 *
 * This program is distributed in the hope it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 * more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 * The full GNU General Public License is included in this distribution in
 * the file called "COPYING".
 *
 * Contact Information:
 * e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
 *
 ******************************************************************************/

#ifndef _I40E_CLIENT_H_
#define _I40E_CLIENT_H_

#define I40E_CLIENT_STR_LENGTH 10

/* Client interface version should be updated anytime there is a change in the
 * existing APIs or data structures.
 */
#define I40E_CLIENT_VERSION_MAJOR 0
#define I40E_CLIENT_VERSION_MINOR 01
#define I40E_CLIENT_VERSION_BUILD 00
#define I40E_CLIENT_VERSION_STR     \
	XSTRINGIFY(I40E_CLIENT_VERSION_MAJOR) "." \
	XSTRINGIFY(I40E_CLIENT_VERSION_MINOR) "." \
	XSTRINGIFY(I40E_CLIENT_VERSION_BUILD)

struct i40e_client_version {
	u8 major;
	u8 minor;
	u8 build;
	u8 rsvd;
};

enum i40e_client_state {
	__I40E_CLIENT_NULL,
	__I40E_CLIENT_REGISTERED
};

enum i40e_client_instance_state {
	__I40E_CLIENT_INSTANCE_NONE,
	__I40E_CLIENT_INSTANCE_OPENED,
};

enum i40e_client_type {
	I40E_CLIENT_IWARP,
	I40E_CLIENT_VMDQ2
};

struct i40e_ops;
struct i40e_client;

/* HW does not define a type value for AEQ; only for RX/TX and CEQ.
 * In order for us to keep the interface simple, SW will define a
 * unique type value for AEQ.
 */
#define I40E_QUEUE_TYPE_PE_AEQ  0x80
#define I40E_QUEUE_INVALID_IDX	0xFFFF

struct i40e_qv_info {
	u32 v_idx; /* msix_vector */
	u16 ceq_idx;
	u16 aeq_idx;
	u8 itr_idx;
};

struct i40e_qvlist_info {
	u32 num_vectors;
	struct i40e_qv_info qv_info[1];
};

#define I40E_CLIENT_MSIX_ALL 0xFFFFFFFF

/* set of LAN parameters useful for clients managed by LAN */

/* Struct to hold per priority info */
struct i40e_prio_qos_params {
	u16 qs_handle; /* qs handle for prio */
	u8 tc; /* TC mapped to prio */
	u8 reserved;
};

#define I40E_CLIENT_MAX_USER_PRIORITY        8
/* Struct to hold Client QoS */
struct i40e_qos_params {
	struct i40e_prio_qos_params prio_qos[I40E_CLIENT_MAX_USER_PRIORITY];
};

struct i40e_params {
	struct i40e_qos_params qos;
	u16 mtu;
};

/* Structure to hold Lan device info for a client device */
struct i40e_info {
	struct i40e_client_version version;
	u8 lanmac[6];
	struct net_device *netdev;
	struct pci_dev *pcidev;
	u8 __iomem *hw_addr;
	u8 fid;	/* function id, PF id or VF id */
#define I40E_CLIENT_FTYPE_PF 0
#define I40E_CLIENT_FTYPE_VF 1
	u8 ftype; /* function type, PF or VF */
	void *pf;

	/* All L2 params that could change during the life span of the PF
	 * and needs to be communicated to the client when they change
	 */
	struct i40e_qvlist_info *qvlist_info;
	struct i40e_params params;
	struct i40e_ops *ops;

	u16 msix_count;	 /* number of msix vectors*/
	/* Array down below will be dynamically allocated based on msix_count */
	struct msix_entry *msix_entries;
	u16 itr_index; /* Which ITR index the PE driver is suppose to use */
	u16 fw_maj_ver;                 /* firmware major version */
	u16 fw_min_ver;                 /* firmware minor version */
	u32 fw_build;                   /* firmware build number */
};

#define I40E_CLIENT_RESET_LEVEL_PF   1
#define I40E_CLIENT_RESET_LEVEL_CORE 2
#define I40E_CLIENT_VSI_FLAG_TCP_PACKET_ENABLE  BIT(1)

struct i40e_ops {
	/* setup_q_vector_list enables queues with a particular vector */
	int (*setup_qvlist)(struct i40e_info *ldev, struct i40e_client *client,
			    struct i40e_qvlist_info *qv_info);

	int (*virtchnl_send)(struct i40e_info *ldev, struct i40e_client *client,
			     u32 vf_id, u8 *msg, u16 len);

	/* If the PE Engine is unresponsive, RDMA driver can request a reset.
	 * The level helps determine the level of reset being requested.
	 */
	void (*request_reset)(struct i40e_info *ldev,
			      struct i40e_client *client, u32 level);

	/* API for the RDMA driver to set certain VSI flags that control
	 * PE Engine.
	 */
	int (*update_vsi_ctxt)(struct i40e_info *ldev,
			       struct i40e_client *client,
			       bool is_vf, u32 vf_id,
			       u32 flag, u32 valid_flag);
};

struct i40e_client_ops {
	/* Should be called from register_client() or whenever PF is ready
	 * to create a specific client instance.
	 */
	int (*open)(struct i40e_info *ldev, struct i40e_client *client);

	/* Should be called when netdev is unavailable or when unregister
	 * call comes in. If the close is happenening due to a reset being
	 * triggered set the reset bit to true.
	 */
	void (*close)(struct i40e_info *ldev, struct i40e_client *client,
		      bool reset);

	/* called when some l2 managed parameters changes - mtu */
	void (*l2_param_change)(struct i40e_info *ldev,
				struct i40e_client *client,
				struct i40e_params *params);

	int (*virtchnl_receive)(struct i40e_info *ldev,
				struct i40e_client *client, u32 vf_id,
				u8 *msg, u16 len);

	/* called when a VF is reset by the PF */
	void (*vf_reset)(struct i40e_info *ldev,
			 struct i40e_client *client, u32 vf_id);

	/* called when the number of VFs changes */
	void (*vf_enable)(struct i40e_info *ldev,
			  struct i40e_client *client, u32 num_vfs);

	/* returns true if VF is capable of specified offload */
	int (*vf_capable)(struct i40e_info *ldev,
			  struct i40e_client *client, u32 vf_id);
};

/* Client device */
struct i40e_client_instance {
	struct list_head list;
	struct i40e_info lan_info;
	struct i40e_client *client;
	unsigned long  state;
	/* A count of all the in-progress calls to the client */
	atomic_t ref_cnt;
};

struct i40e_client {
	struct list_head list;		/* list of registered clients */
	char name[I40E_CLIENT_STR_LENGTH];
	struct i40e_client_version version;
	unsigned long state;		/* client state */
	atomic_t ref_cnt;  /* Count of all the client devices of this kind */
	u32 flags;
#define I40E_CLIENT_FLAGS_LAUNCH_ON_PROBE	BIT(0)
#define I40E_TX_FLAGS_NOTIFY_OTHER_EVENTS	BIT(2)
	enum i40e_client_type type;
	struct i40e_client_ops *ops;	/* client ops provided by the client */
};

static inline bool i40e_client_is_registered(struct i40e_client *client)
{
	return test_bit(__I40E_CLIENT_REGISTERED, &client->state);
}

/* used by clients */
int i40e_register_client(struct i40e_client *client);
int i40e_unregister_client(struct i40e_client *client);

#endif /* _I40E_CLIENT_H_ */
+108 −7
Original line number Diff line number Diff line
@@ -290,7 +290,7 @@ struct i40e_vsi *i40e_find_vsi_from_id(struct i40e_pf *pf, u16 id)
 *
 * If not already scheduled, this puts the task into the work queue
 **/
static void i40e_service_event_schedule(struct i40e_pf *pf)
void i40e_service_event_schedule(struct i40e_pf *pf)
{
	if (!test_bit(__I40E_DOWN, &pf->state) &&
	    !test_bit(__I40E_RESET_RECOVERY_PENDING, &pf->state) &&
@@ -2212,7 +2212,7 @@ static int i40e_change_mtu(struct net_device *netdev, int new_mtu)
	netdev->mtu = new_mtu;
	if (netif_running(netdev))
		i40e_vsi_reinit_locked(vsi);

	i40e_notify_client_of_l2_param_changes(vsi);
	return 0;
}

@@ -4166,6 +4166,9 @@ static void i40e_clear_interrupt_scheme(struct i40e_pf *pf)
		free_irq(pf->msix_entries[0].vector, pf);
	}

	i40e_put_lump(pf->irq_pile, pf->iwarp_base_vector,
		      I40E_IWARP_IRQ_PILE_ID);

	i40e_put_lump(pf->irq_pile, 0, I40E_PILE_VALID_BIT-1);
	for (i = 0; i < pf->num_alloc_vsi; i++)
		if (pf->vsi[i])
@@ -4209,12 +4212,17 @@ static void i40e_napi_disable_all(struct i40e_vsi *vsi)
 **/
static void i40e_vsi_close(struct i40e_vsi *vsi)
{
	bool reset = false;

	if (!test_and_set_bit(__I40E_DOWN, &vsi->state))
		i40e_down(vsi);
	i40e_vsi_free_irq(vsi);
	i40e_vsi_free_tx_resources(vsi);
	i40e_vsi_free_rx_resources(vsi);
	vsi->current_netdev_flags = 0;
	if (test_bit(__I40E_RESET_RECOVERY_PENDING, &vsi->back->state))
		reset = true;
	i40e_notify_client_of_netdev_close(vsi, reset);
}

/**
@@ -4831,6 +4839,12 @@ static int i40e_vsi_config_tc(struct i40e_vsi *vsi, u8 enabled_tc)
	ctxt.info = vsi->info;
	i40e_vsi_setup_queue_map(vsi, &ctxt, enabled_tc, false);

	if (vsi->back->flags & I40E_FLAG_IWARP_ENABLED) {
		ctxt.info.valid_sections |=
				cpu_to_le16(I40E_AQ_VSI_PROP_QUEUE_OPT_VALID);
		ctxt.info.queueing_opt_flags |= I40E_AQ_VSI_QUE_OPT_TCP_ENA;
	}

	/* Update the VSI after updating the VSI queue-mapping information */
	ret = i40e_aq_update_vsi_params(&vsi->back->hw, &ctxt, NULL);
	if (ret) {
@@ -4974,6 +4988,7 @@ static void i40e_dcb_reconfigure(struct i40e_pf *pf)
			if (pf->vsi[v]->netdev)
				i40e_dcbnl_set_all(pf->vsi[v]);
		}
		i40e_notify_client_of_l2_param_changes(pf->vsi[v]);
	}
}

@@ -5173,6 +5188,11 @@ static int i40e_up_complete(struct i40e_vsi *vsi)
		}
		i40e_fdir_filter_restore(vsi);
	}

	/* On the next run of the service_task, notify any clients of the new
	 * opened netdev
	 */
	pf->flags |= I40E_FLAG_SERVICE_CLIENT_REQUESTED;
	i40e_service_event_schedule(pf);

	return 0;
@@ -5351,6 +5371,8 @@ int i40e_open(struct net_device *netdev)
	geneve_get_rx_port(netdev);
#endif

	i40e_notify_client_of_netdev_open(vsi);

	return 0;
}

@@ -6015,6 +6037,7 @@ static void i40e_vsi_link_event(struct i40e_vsi *vsi, bool link_up)
	case I40E_VSI_SRIOV:
	case I40E_VSI_VMDQ2:
	case I40E_VSI_CTRL:
	case I40E_VSI_IWARP:
	case I40E_VSI_MIRROR:
	default:
		/* there is no notification for other VSIs */
@@ -7116,6 +7139,7 @@ static void i40e_service_task(struct work_struct *work)
	i40e_vc_process_vflr_event(pf);
	i40e_watchdog_subtask(pf);
	i40e_fdir_reinit_subtask(pf);
	i40e_client_subtask(pf);
	i40e_sync_filters_subtask(pf);
	i40e_sync_udp_filters_subtask(pf);
	i40e_clean_adminq_subtask(pf);
@@ -7520,6 +7544,7 @@ static int i40e_init_msix(struct i40e_pf *pf)
	int vectors_left;
	int v_budget, i;
	int v_actual;
	int iwarp_requested = 0;

	if (!(pf->flags & I40E_FLAG_MSIX_ENABLED))
		return -ENODEV;
@@ -7533,6 +7558,7 @@ static int i40e_init_msix(struct i40e_pf *pf)
	 *		is governed by number of cpus in the system.
	 *	- assumes symmetric Tx/Rx pairing
	 *   - The number of VMDq pairs
	 *   - The CPU count within the NUMA node if iWARP is enabled
#ifdef I40E_FCOE
	 *   - The number of FCOE qps.
#endif
@@ -7579,6 +7605,16 @@ static int i40e_init_msix(struct i40e_pf *pf)
	}

#endif
	/* can we reserve enough for iWARP? */
	if (pf->flags & I40E_FLAG_IWARP_ENABLED) {
		if (!vectors_left)
			pf->num_iwarp_msix = 0;
		else if (vectors_left < pf->num_iwarp_msix)
			pf->num_iwarp_msix = 1;
		v_budget += pf->num_iwarp_msix;
		vectors_left -= pf->num_iwarp_msix;
	}

	/* any vectors left over go for VMDq support */
	if (pf->flags & I40E_FLAG_VMDQ_ENABLED) {
		int vmdq_vecs_wanted = pf->num_vmdq_vsis * pf->num_vmdq_qps;
@@ -7613,6 +7649,8 @@ static int i40e_init_msix(struct i40e_pf *pf)
		 * of these features based on the policy and at the end disable
		 * the features that did not get any vectors.
		 */
		iwarp_requested = pf->num_iwarp_msix;
		pf->num_iwarp_msix = 0;
#ifdef I40E_FCOE
		pf->num_fcoe_qps = 0;
		pf->num_fcoe_msix = 0;
@@ -7651,17 +7689,33 @@ static int i40e_init_msix(struct i40e_pf *pf)
			pf->num_lan_msix = 1;
			break;
		case 3:
			if (pf->flags & I40E_FLAG_IWARP_ENABLED) {
				pf->num_lan_msix = 1;
				pf->num_iwarp_msix = 1;
			} else {
				pf->num_lan_msix = 2;
			}
#ifdef I40E_FCOE
			/* give one vector to FCoE */
			if (pf->flags & I40E_FLAG_FCOE_ENABLED) {
				pf->num_lan_msix = 1;
				pf->num_fcoe_msix = 1;
			}
#else
			pf->num_lan_msix = 2;
#endif
			break;
		default:
			if (pf->flags & I40E_FLAG_IWARP_ENABLED) {
				pf->num_iwarp_msix = min_t(int, (vec / 3),
						 iwarp_requested);
				pf->num_vmdq_vsis = min_t(int, (vec / 3),
						  I40E_DEFAULT_NUM_VMDQ_VSI);
			} else {
				pf->num_vmdq_vsis = min_t(int, (vec / 2),
						  I40E_DEFAULT_NUM_VMDQ_VSI);
			}
			pf->num_lan_msix = min_t(int,
			       (vec - (pf->num_iwarp_msix + pf->num_vmdq_vsis)),
							      pf->num_lan_msix);
#ifdef I40E_FCOE
			/* give one vector to FCoE */
			if (pf->flags & I40E_FLAG_FCOE_ENABLED) {
@@ -7669,8 +7723,6 @@ static int i40e_init_msix(struct i40e_pf *pf)
				vec--;
			}
#endif
			/* give the rest to the PF */
			pf->num_lan_msix = min_t(int, vec, pf->num_lan_qps);
			break;
		}
	}
@@ -7680,6 +7732,12 @@ static int i40e_init_msix(struct i40e_pf *pf)
		dev_info(&pf->pdev->dev, "VMDq disabled, not enough MSI-X vectors\n");
		pf->flags &= ~I40E_FLAG_VMDQ_ENABLED;
	}

	if ((pf->flags & I40E_FLAG_IWARP_ENABLED) &&
	    (pf->num_iwarp_msix == 0)) {
		dev_info(&pf->pdev->dev, "IWARP disabled, not enough MSI-X vectors\n");
		pf->flags &= ~I40E_FLAG_IWARP_ENABLED;
	}
#ifdef I40E_FCOE

	if ((pf->flags & I40E_FLAG_FCOE_ENABLED) && (pf->num_fcoe_msix == 0)) {
@@ -7771,6 +7829,7 @@ static int i40e_init_interrupt_scheme(struct i40e_pf *pf)
		vectors = i40e_init_msix(pf);
		if (vectors < 0) {
			pf->flags &= ~(I40E_FLAG_MSIX_ENABLED	|
				       I40E_FLAG_IWARP_ENABLED	|
#ifdef I40E_FCOE
				       I40E_FLAG_FCOE_ENABLED	|
#endif
@@ -8373,6 +8432,12 @@ static int i40e_sw_init(struct i40e_pf *pf)
		pf->num_vmdq_qps = i40e_default_queues_per_vmdq(pf);
	}

	if (pf->hw.func_caps.iwarp) {
		pf->flags |= I40E_FLAG_IWARP_ENABLED;
		/* IWARP needs one extra vector for CQP just like MISC.*/
		pf->num_iwarp_msix = (int)num_online_cpus() + 1;
	}

#ifdef I40E_FCOE
	i40e_init_pf_fcoe(pf);

@@ -9216,6 +9281,13 @@ static int i40e_add_vsi(struct i40e_vsi *vsi)
				cpu_to_le16(I40E_AQ_VSI_SW_ID_FLAG_ALLOW_LB);
		}

		if (vsi->back->flags & I40E_FLAG_IWARP_ENABLED) {
			ctxt.info.valid_sections |=
				cpu_to_le16(I40E_AQ_VSI_PROP_QUEUE_OPT_VALID);
			ctxt.info.queueing_opt_flags |=
						I40E_AQ_VSI_QUE_OPT_TCP_ENA;
		}

		ctxt.info.valid_sections |= cpu_to_le16(I40E_AQ_VSI_PROP_VLAN_VALID);
		ctxt.info.port_vlan_flags |= I40E_AQ_VSI_PVLAN_MODE_ALL;
		if (pf->vf[vsi->vf_id].spoofchk) {
@@ -9239,6 +9311,10 @@ static int i40e_add_vsi(struct i40e_vsi *vsi)
		break;

#endif /* I40E_FCOE */
	case I40E_VSI_IWARP:
		/* send down message to iWARP */
		break;

	default:
		return -ENODEV;
	}
@@ -10350,6 +10426,7 @@ static void i40e_determine_queue_usage(struct i40e_pf *pf)

		/* make sure all the fancies are disabled */
		pf->flags &= ~(I40E_FLAG_RSS_ENABLED	|
			       I40E_FLAG_IWARP_ENABLED	|
#ifdef I40E_FCOE
			       I40E_FLAG_FCOE_ENABLED	|
#endif
@@ -10367,6 +10444,7 @@ static void i40e_determine_queue_usage(struct i40e_pf *pf)
		queues_left -= pf->num_lan_qps;

		pf->flags &= ~(I40E_FLAG_RSS_ENABLED	|
			       I40E_FLAG_IWARP_ENABLED	|
#ifdef I40E_FCOE
			       I40E_FLAG_FCOE_ENABLED	|
#endif
@@ -10959,7 +11037,17 @@ static int i40e_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
	}
#endif /* CONFIG_PCI_IOV */

	pfs_found++;
	if (pf->flags & I40E_FLAG_IWARP_ENABLED) {
		pf->iwarp_base_vector = i40e_get_lump(pf, pf->irq_pile,
						      pf->num_iwarp_msix,
						      I40E_IWARP_IRQ_PILE_ID);
		if (pf->iwarp_base_vector < 0) {
			dev_info(&pdev->dev,
				 "failed to get tracking for %d vectors for IWARP err=%d\n",
				 pf->num_iwarp_msix, pf->iwarp_base_vector);
			pf->flags &= ~I40E_FLAG_IWARP_ENABLED;
		}
	}

	i40e_dbg_pf_init(pf);

@@ -10970,6 +11058,12 @@ static int i40e_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
	mod_timer(&pf->service_timer,
		  round_jiffies(jiffies + pf->service_timer_period));

	/* add this PF to client device list and launch a client service task */
	err = i40e_lan_add_device(pf);
	if (err)
		dev_info(&pdev->dev, "Failed to add PF to client API service list: %d\n",
			 err);

#ifdef I40E_FCOE
	/* create FCoE interface */
	i40e_fcoe_vsi_setup(pf);
@@ -11140,6 +11234,13 @@ static void i40e_remove(struct pci_dev *pdev)
	if (pf->vsi[pf->lan_vsi])
		i40e_vsi_release(pf->vsi[pf->lan_vsi]);

	/* remove attached clients */
	ret_code = i40e_lan_del_device(pf);
	if (ret_code) {
		dev_warn(&pdev->dev, "Failed to delete client device: %d\n",
			 ret_code);
	}

	/* shutdown and destroy the HMC */
	if (pf->hw.hmc.hmc_obj) {
		ret_code = i40e_shutdown_lan_hmc(&pf->hw);
Loading