|
@@ -1,7 +1,7 @@
|
|
|
/*******************************************************************************
|
|
|
*
|
|
|
* Intel Ethernet Controller XL710 Family Linux Driver
|
|
|
- * Copyright(c) 2013 - 2014 Intel Corporation.
|
|
|
+ * 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,
|
|
@@ -39,7 +39,7 @@ static const char i40e_driver_string[] =
|
|
|
|
|
|
#define DRV_VERSION_MAJOR 1
|
|
|
#define DRV_VERSION_MINOR 2
|
|
|
-#define DRV_VERSION_BUILD 8
|
|
|
+#define DRV_VERSION_BUILD 9
|
|
|
#define DRV_VERSION __stringify(DRV_VERSION_MAJOR) "." \
|
|
|
__stringify(DRV_VERSION_MINOR) "." \
|
|
|
__stringify(DRV_VERSION_BUILD) DRV_KERN
|
|
@@ -4835,11 +4835,7 @@ exit:
|
|
|
*
|
|
|
* Returns 0 on success, negative value on failure
|
|
|
**/
|
|
|
-#ifdef I40E_FCOE
|
|
|
int i40e_open(struct net_device *netdev)
|
|
|
-#else
|
|
|
-static int i40e_open(struct net_device *netdev)
|
|
|
-#endif
|
|
|
{
|
|
|
struct i40e_netdev_priv *np = netdev_priv(netdev);
|
|
|
struct i40e_vsi *vsi = np->vsi;
|
|
@@ -5875,6 +5871,26 @@ static void i40e_verify_eeprom(struct i40e_pf *pf)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * i40e_config_bridge_mode - Configure the HW bridge mode
|
|
|
+ * @veb: pointer to the bridge instance
|
|
|
+ *
|
|
|
+ * Configure the loop back mode for the LAN VSI that is downlink to the
|
|
|
+ * specified HW bridge instance. It is expected this function is called
|
|
|
+ * when a new HW bridge is instantiated.
|
|
|
+ **/
|
|
|
+static void i40e_config_bridge_mode(struct i40e_veb *veb)
|
|
|
+{
|
|
|
+ struct i40e_pf *pf = veb->pf;
|
|
|
+
|
|
|
+ dev_info(&pf->pdev->dev, "enabling bridge mode: %s\n",
|
|
|
+ veb->bridge_mode == BRIDGE_MODE_VEPA ? "VEPA" : "VEB");
|
|
|
+ if (veb->bridge_mode & BRIDGE_MODE_VEPA)
|
|
|
+ i40e_disable_pf_switch_lb(pf);
|
|
|
+ else
|
|
|
+ i40e_enable_pf_switch_lb(pf);
|
|
|
+}
|
|
|
+
|
|
|
/**
|
|
|
* i40e_reconstitute_veb - rebuild the VEB and anything connected to it
|
|
|
* @veb: pointer to the VEB instance
|
|
@@ -5921,8 +5937,7 @@ static int i40e_reconstitute_veb(struct i40e_veb *veb)
|
|
|
if (ret)
|
|
|
goto end_reconstitute;
|
|
|
|
|
|
- /* Enable LB mode for the main VSI now that it is on a VEB */
|
|
|
- i40e_enable_pf_switch_lb(pf);
|
|
|
+ i40e_config_bridge_mode(veb);
|
|
|
|
|
|
/* create the remaining VSIs attached to this VEB */
|
|
|
for (v = 0; v < pf->num_alloc_vsi; v++) {
|
|
@@ -7253,6 +7268,128 @@ int i40e_reconfig_rss_queues(struct i40e_pf *pf, int queue_count)
|
|
|
return pf->rss_size;
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * i40e_get_npar_bw_setting - Retrieve BW settings for this PF partition
|
|
|
+ * @pf: board private structure
|
|
|
+ **/
|
|
|
+i40e_status i40e_get_npar_bw_setting(struct i40e_pf *pf)
|
|
|
+{
|
|
|
+ i40e_status status;
|
|
|
+ bool min_valid, max_valid;
|
|
|
+ u32 max_bw, min_bw;
|
|
|
+
|
|
|
+ status = i40e_read_bw_from_alt_ram(&pf->hw, &max_bw, &min_bw,
|
|
|
+ &min_valid, &max_valid);
|
|
|
+
|
|
|
+ if (!status) {
|
|
|
+ if (min_valid)
|
|
|
+ pf->npar_min_bw = min_bw;
|
|
|
+ if (max_valid)
|
|
|
+ pf->npar_max_bw = max_bw;
|
|
|
+ }
|
|
|
+
|
|
|
+ return status;
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * i40e_set_npar_bw_setting - Set BW settings for this PF partition
|
|
|
+ * @pf: board private structure
|
|
|
+ **/
|
|
|
+i40e_status i40e_set_npar_bw_setting(struct i40e_pf *pf)
|
|
|
+{
|
|
|
+ struct i40e_aqc_configure_partition_bw_data bw_data;
|
|
|
+ i40e_status status;
|
|
|
+
|
|
|
+ /* Set the valid bit for this pf */
|
|
|
+ bw_data.pf_valid_bits = cpu_to_le16(1 << pf->hw.pf_id);
|
|
|
+ bw_data.max_bw[pf->hw.pf_id] = pf->npar_max_bw & I40E_ALT_BW_VALUE_MASK;
|
|
|
+ bw_data.min_bw[pf->hw.pf_id] = pf->npar_min_bw & I40E_ALT_BW_VALUE_MASK;
|
|
|
+
|
|
|
+ /* Set the new bandwidths */
|
|
|
+ status = i40e_aq_configure_partition_bw(&pf->hw, &bw_data, NULL);
|
|
|
+
|
|
|
+ return status;
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * i40e_commit_npar_bw_setting - Commit BW settings for this PF partition
|
|
|
+ * @pf: board private structure
|
|
|
+ **/
|
|
|
+i40e_status i40e_commit_npar_bw_setting(struct i40e_pf *pf)
|
|
|
+{
|
|
|
+ /* Commit temporary BW setting to permanent NVM image */
|
|
|
+ enum i40e_admin_queue_err last_aq_status;
|
|
|
+ i40e_status ret;
|
|
|
+ u16 nvm_word;
|
|
|
+
|
|
|
+ if (pf->hw.partition_id != 1) {
|
|
|
+ dev_info(&pf->pdev->dev,
|
|
|
+ "Commit BW only works on partition 1! This is partition %d",
|
|
|
+ pf->hw.partition_id);
|
|
|
+ ret = I40E_NOT_SUPPORTED;
|
|
|
+ goto bw_commit_out;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Acquire NVM for read access */
|
|
|
+ ret = i40e_acquire_nvm(&pf->hw, I40E_RESOURCE_READ);
|
|
|
+ last_aq_status = pf->hw.aq.asq_last_status;
|
|
|
+ if (ret) {
|
|
|
+ dev_info(&pf->pdev->dev,
|
|
|
+ "Cannot acquire NVM for read access, err %d: aq_err %d\n",
|
|
|
+ ret, last_aq_status);
|
|
|
+ goto bw_commit_out;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Read word 0x10 of NVM - SW compatibility word 1 */
|
|
|
+ ret = i40e_aq_read_nvm(&pf->hw,
|
|
|
+ I40E_SR_NVM_CONTROL_WORD,
|
|
|
+ 0x10, sizeof(nvm_word), &nvm_word,
|
|
|
+ false, NULL);
|
|
|
+ /* Save off last admin queue command status before releasing
|
|
|
+ * the NVM
|
|
|
+ */
|
|
|
+ last_aq_status = pf->hw.aq.asq_last_status;
|
|
|
+ i40e_release_nvm(&pf->hw);
|
|
|
+ if (ret) {
|
|
|
+ dev_info(&pf->pdev->dev, "NVM read error, err %d aq_err %d\n",
|
|
|
+ ret, last_aq_status);
|
|
|
+ goto bw_commit_out;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Wait a bit for NVM release to complete */
|
|
|
+ msleep(50);
|
|
|
+
|
|
|
+ /* Acquire NVM for write access */
|
|
|
+ ret = i40e_acquire_nvm(&pf->hw, I40E_RESOURCE_WRITE);
|
|
|
+ last_aq_status = pf->hw.aq.asq_last_status;
|
|
|
+ if (ret) {
|
|
|
+ dev_info(&pf->pdev->dev,
|
|
|
+ "Cannot acquire NVM for write access, err %d: aq_err %d\n",
|
|
|
+ ret, last_aq_status);
|
|
|
+ goto bw_commit_out;
|
|
|
+ }
|
|
|
+ /* Write it back out unchanged to initiate update NVM,
|
|
|
+ * which will force a write of the shadow (alt) RAM to
|
|
|
+ * the NVM - thus storing the bandwidth values permanently.
|
|
|
+ */
|
|
|
+ ret = i40e_aq_update_nvm(&pf->hw,
|
|
|
+ I40E_SR_NVM_CONTROL_WORD,
|
|
|
+ 0x10, sizeof(nvm_word),
|
|
|
+ &nvm_word, true, NULL);
|
|
|
+ /* Save off last admin queue command status before releasing
|
|
|
+ * the NVM
|
|
|
+ */
|
|
|
+ last_aq_status = pf->hw.aq.asq_last_status;
|
|
|
+ i40e_release_nvm(&pf->hw);
|
|
|
+ if (ret)
|
|
|
+ dev_info(&pf->pdev->dev,
|
|
|
+ "BW settings NOT SAVED, err %d aq_err %d\n",
|
|
|
+ ret, last_aq_status);
|
|
|
+bw_commit_out:
|
|
|
+
|
|
|
+ return ret;
|
|
|
+}
|
|
|
+
|
|
|
/**
|
|
|
* i40e_sw_init - Initialize general software structures (struct i40e_pf)
|
|
|
* @pf: board private structure to initialize
|
|
@@ -7279,8 +7416,12 @@ static int i40e_sw_init(struct i40e_pf *pf)
|
|
|
/* Set default capability flags */
|
|
|
pf->flags = I40E_FLAG_RX_CSUM_ENABLED |
|
|
|
I40E_FLAG_MSI_ENABLED |
|
|
|
- I40E_FLAG_MSIX_ENABLED |
|
|
|
- I40E_FLAG_RX_PS_ENABLED;
|
|
|
+ I40E_FLAG_MSIX_ENABLED;
|
|
|
+
|
|
|
+ if (iommu_present(&pci_bus_type))
|
|
|
+ pf->flags |= I40E_FLAG_RX_PS_ENABLED;
|
|
|
+ else
|
|
|
+ pf->flags |= I40E_FLAG_RX_1BUF_ENABLED;
|
|
|
|
|
|
/* Set default ITR */
|
|
|
pf->rx_itr_default = I40E_ITR_DYNAMIC | I40E_ITR_RX_DEF;
|
|
@@ -7302,6 +7443,13 @@ static int i40e_sw_init(struct i40e_pf *pf)
|
|
|
if (pf->hw.func_caps.npar_enable || pf->hw.func_caps.mfp_mode_1) {
|
|
|
pf->flags |= I40E_FLAG_MFP_ENABLED;
|
|
|
dev_info(&pf->pdev->dev, "MFP mode Enabled\n");
|
|
|
+ if (i40e_get_npar_bw_setting(pf))
|
|
|
+ dev_warn(&pf->pdev->dev,
|
|
|
+ "Could not get NPAR bw settings\n");
|
|
|
+ else
|
|
|
+ dev_info(&pf->pdev->dev,
|
|
|
+ "Min BW = %8.8x, Max BW = %8.8x\n",
|
|
|
+ pf->npar_min_bw, pf->npar_max_bw);
|
|
|
}
|
|
|
|
|
|
/* FW/NVM is not yet fixed in this regard */
|
|
@@ -7608,7 +7756,119 @@ static int i40e_ndo_fdb_add(struct ndmsg *ndm, struct nlattr *tb[],
|
|
|
return err;
|
|
|
}
|
|
|
|
|
|
-static const struct net_device_ops i40e_netdev_ops = {
|
|
|
+#ifdef HAVE_BRIDGE_ATTRIBS
|
|
|
+/**
|
|
|
+ * i40e_ndo_bridge_setlink - Set the hardware bridge mode
|
|
|
+ * @dev: the netdev being configured
|
|
|
+ * @nlh: RTNL message
|
|
|
+ *
|
|
|
+ * Inserts a new hardware bridge if not already created and
|
|
|
+ * enables the bridging mode requested (VEB or VEPA). If the
|
|
|
+ * hardware bridge has already been inserted and the request
|
|
|
+ * is to change the mode then that requires a PF reset to
|
|
|
+ * allow rebuild of the components with required hardware
|
|
|
+ * bridge mode enabled.
|
|
|
+ **/
|
|
|
+static int i40e_ndo_bridge_setlink(struct net_device *dev,
|
|
|
+ struct nlmsghdr *nlh)
|
|
|
+{
|
|
|
+ struct i40e_netdev_priv *np = netdev_priv(dev);
|
|
|
+ struct i40e_vsi *vsi = np->vsi;
|
|
|
+ struct i40e_pf *pf = vsi->back;
|
|
|
+ struct i40e_veb *veb = NULL;
|
|
|
+ struct nlattr *attr, *br_spec;
|
|
|
+ int i, rem;
|
|
|
+
|
|
|
+ /* Only for PF VSI for now */
|
|
|
+ if (vsi->seid != pf->vsi[pf->lan_vsi]->seid)
|
|
|
+ return -EOPNOTSUPP;
|
|
|
+
|
|
|
+ /* Find the HW bridge for PF VSI */
|
|
|
+ for (i = 0; i < I40E_MAX_VEB && !veb; i++) {
|
|
|
+ if (pf->veb[i] && pf->veb[i]->seid == vsi->uplink_seid)
|
|
|
+ veb = pf->veb[i];
|
|
|
+ }
|
|
|
+
|
|
|
+ br_spec = nlmsg_find_attr(nlh, sizeof(struct ifinfomsg), IFLA_AF_SPEC);
|
|
|
+
|
|
|
+ nla_for_each_nested(attr, br_spec, rem) {
|
|
|
+ __u16 mode;
|
|
|
+
|
|
|
+ if (nla_type(attr) != IFLA_BRIDGE_MODE)
|
|
|
+ continue;
|
|
|
+
|
|
|
+ mode = nla_get_u16(attr);
|
|
|
+ if ((mode != BRIDGE_MODE_VEPA) &&
|
|
|
+ (mode != BRIDGE_MODE_VEB))
|
|
|
+ return -EINVAL;
|
|
|
+
|
|
|
+ /* Insert a new HW bridge */
|
|
|
+ if (!veb) {
|
|
|
+ veb = i40e_veb_setup(pf, 0, vsi->uplink_seid, vsi->seid,
|
|
|
+ vsi->tc_config.enabled_tc);
|
|
|
+ if (veb) {
|
|
|
+ veb->bridge_mode = mode;
|
|
|
+ i40e_config_bridge_mode(veb);
|
|
|
+ } else {
|
|
|
+ /* No Bridge HW offload available */
|
|
|
+ return -ENOENT;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ } else if (mode != veb->bridge_mode) {
|
|
|
+ /* Existing HW bridge but different mode needs reset */
|
|
|
+ veb->bridge_mode = mode;
|
|
|
+ i40e_do_reset(pf, (1 << __I40E_PF_RESET_REQUESTED));
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * i40e_ndo_bridge_getlink - Get the hardware bridge mode
|
|
|
+ * @skb: skb buff
|
|
|
+ * @pid: process id
|
|
|
+ * @seq: RTNL message seq #
|
|
|
+ * @dev: the netdev being configured
|
|
|
+ * @filter_mask: unused
|
|
|
+ *
|
|
|
+ * Return the mode in which the hardware bridge is operating in
|
|
|
+ * i.e VEB or VEPA.
|
|
|
+ **/
|
|
|
+#ifdef HAVE_BRIDGE_FILTER
|
|
|
+static int i40e_ndo_bridge_getlink(struct sk_buff *skb, u32 pid, u32 seq,
|
|
|
+ struct net_device *dev,
|
|
|
+ u32 __always_unused filter_mask)
|
|
|
+#else
|
|
|
+static int i40e_ndo_bridge_getlink(struct sk_buff *skb, u32 pid, u32 seq,
|
|
|
+ struct net_device *dev)
|
|
|
+#endif /* HAVE_BRIDGE_FILTER */
|
|
|
+{
|
|
|
+ struct i40e_netdev_priv *np = netdev_priv(dev);
|
|
|
+ struct i40e_vsi *vsi = np->vsi;
|
|
|
+ struct i40e_pf *pf = vsi->back;
|
|
|
+ struct i40e_veb *veb = NULL;
|
|
|
+ int i;
|
|
|
+
|
|
|
+ /* Only for PF VSI for now */
|
|
|
+ if (vsi->seid != pf->vsi[pf->lan_vsi]->seid)
|
|
|
+ return -EOPNOTSUPP;
|
|
|
+
|
|
|
+ /* Find the HW bridge for the PF VSI */
|
|
|
+ for (i = 0; i < I40E_MAX_VEB && !veb; i++) {
|
|
|
+ if (pf->veb[i] && pf->veb[i]->seid == vsi->uplink_seid)
|
|
|
+ veb = pf->veb[i];
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!veb)
|
|
|
+ return 0;
|
|
|
+
|
|
|
+ return ndo_dflt_bridge_getlink(skb, pid, seq, dev, veb->bridge_mode);
|
|
|
+}
|
|
|
+#endif /* HAVE_BRIDGE_ATTRIBS */
|
|
|
+
|
|
|
+const struct net_device_ops i40e_netdev_ops = {
|
|
|
.ndo_open = i40e_open,
|
|
|
.ndo_stop = i40e_close,
|
|
|
.ndo_start_xmit = i40e_lan_xmit_frame,
|
|
@@ -7642,6 +7902,10 @@ static const struct net_device_ops i40e_netdev_ops = {
|
|
|
#endif
|
|
|
.ndo_get_phys_port_id = i40e_get_phys_port_id,
|
|
|
.ndo_fdb_add = i40e_ndo_fdb_add,
|
|
|
+#ifdef HAVE_BRIDGE_ATTRIBS
|
|
|
+ .ndo_bridge_getlink = i40e_ndo_bridge_getlink,
|
|
|
+ .ndo_bridge_setlink = i40e_ndo_bridge_setlink,
|
|
|
+#endif /* HAVE_BRIDGE_ATTRIBS */
|
|
|
};
|
|
|
|
|
|
/**
|
|
@@ -7753,6 +8017,30 @@ static void i40e_vsi_delete(struct i40e_vsi *vsi)
|
|
|
i40e_aq_delete_element(&vsi->back->hw, vsi->seid, NULL);
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * i40e_is_vsi_uplink_mode_veb - Check if the VSI's uplink bridge mode is VEB
|
|
|
+ * @vsi: the VSI being queried
|
|
|
+ *
|
|
|
+ * Returns 1 if HW bridge mode is VEB and return 0 in case of VEPA mode
|
|
|
+ **/
|
|
|
+int i40e_is_vsi_uplink_mode_veb(struct i40e_vsi *vsi)
|
|
|
+{
|
|
|
+ struct i40e_veb *veb;
|
|
|
+ struct i40e_pf *pf = vsi->back;
|
|
|
+
|
|
|
+ /* Uplink is not a bridge so default to VEB */
|
|
|
+ if (vsi->veb_idx == I40E_NO_VEB)
|
|
|
+ return 1;
|
|
|
+
|
|
|
+ veb = pf->veb[vsi->veb_idx];
|
|
|
+ /* Uplink is a bridge in VEPA mode */
|
|
|
+ if (veb && (veb->bridge_mode & BRIDGE_MODE_VEPA))
|
|
|
+ return 0;
|
|
|
+
|
|
|
+ /* Uplink is a bridge in VEB mode */
|
|
|
+ return 1;
|
|
|
+}
|
|
|
+
|
|
|
/**
|
|
|
* i40e_add_vsi - Add a VSI to the switch
|
|
|
* @vsi: the VSI being configured
|
|
@@ -7840,10 +8128,12 @@ static int i40e_add_vsi(struct i40e_vsi *vsi)
|
|
|
ctxt.uplink_seid = vsi->uplink_seid;
|
|
|
ctxt.connection_type = I40E_AQ_VSI_CONN_TYPE_NORMAL;
|
|
|
ctxt.flags = I40E_AQ_VSI_TYPE_PF;
|
|
|
- ctxt.info.valid_sections |=
|
|
|
+ if (i40e_is_vsi_uplink_mode_veb(vsi)) {
|
|
|
+ ctxt.info.valid_sections |=
|
|
|
cpu_to_le16(I40E_AQ_VSI_PROP_SWITCH_VALID);
|
|
|
- ctxt.info.switch_id =
|
|
|
+ ctxt.info.switch_id =
|
|
|
cpu_to_le16(I40E_AQ_VSI_SW_ID_FLAG_ALLOW_LB);
|
|
|
+ }
|
|
|
i40e_vsi_setup_queue_map(vsi, &ctxt, enabled_tc, true);
|
|
|
break;
|
|
|
|
|
@@ -7854,13 +8144,15 @@ static int i40e_add_vsi(struct i40e_vsi *vsi)
|
|
|
ctxt.connection_type = I40E_AQ_VSI_CONN_TYPE_NORMAL;
|
|
|
ctxt.flags = I40E_AQ_VSI_TYPE_VMDQ2;
|
|
|
|
|
|
- ctxt.info.valid_sections |= cpu_to_le16(I40E_AQ_VSI_PROP_SWITCH_VALID);
|
|
|
-
|
|
|
/* This VSI is connected to VEB so the switch_id
|
|
|
* should be set to zero by default.
|
|
|
*/
|
|
|
- ctxt.info.switch_id = 0;
|
|
|
- ctxt.info.switch_id |= cpu_to_le16(I40E_AQ_VSI_SW_ID_FLAG_ALLOW_LB);
|
|
|
+ if (i40e_is_vsi_uplink_mode_veb(vsi)) {
|
|
|
+ ctxt.info.valid_sections |=
|
|
|
+ cpu_to_le16(I40E_AQ_VSI_PROP_SWITCH_VALID);
|
|
|
+ ctxt.info.switch_id =
|
|
|
+ cpu_to_le16(I40E_AQ_VSI_SW_ID_FLAG_ALLOW_LB);
|
|
|
+ }
|
|
|
|
|
|
/* Setup the VSI tx/rx queue map for TC0 only for now */
|
|
|
i40e_vsi_setup_queue_map(vsi, &ctxt, enabled_tc, true);
|
|
@@ -7873,12 +8165,15 @@ static int i40e_add_vsi(struct i40e_vsi *vsi)
|
|
|
ctxt.connection_type = I40E_AQ_VSI_CONN_TYPE_NORMAL;
|
|
|
ctxt.flags = I40E_AQ_VSI_TYPE_VF;
|
|
|
|
|
|
- ctxt.info.valid_sections |= cpu_to_le16(I40E_AQ_VSI_PROP_SWITCH_VALID);
|
|
|
-
|
|
|
/* This VSI is connected to VEB so the switch_id
|
|
|
* should be set to zero by default.
|
|
|
*/
|
|
|
- ctxt.info.switch_id = cpu_to_le16(I40E_AQ_VSI_SW_ID_FLAG_ALLOW_LB);
|
|
|
+ if (i40e_is_vsi_uplink_mode_veb(vsi)) {
|
|
|
+ ctxt.info.valid_sections |=
|
|
|
+ cpu_to_le16(I40E_AQ_VSI_PROP_SWITCH_VALID);
|
|
|
+ ctxt.info.switch_id =
|
|
|
+ cpu_to_le16(I40E_AQ_VSI_SW_ID_FLAG_ALLOW_LB);
|
|
|
+ }
|
|
|
|
|
|
ctxt.info.valid_sections |= cpu_to_le16(I40E_AQ_VSI_PROP_VLAN_VALID);
|
|
|
ctxt.info.port_vlan_flags |= I40E_AQ_VSI_PVLAN_MODE_ALL;
|
|
@@ -8236,7 +8531,7 @@ struct i40e_vsi *i40e_vsi_setup(struct i40e_pf *pf, u8 type,
|
|
|
__func__);
|
|
|
return NULL;
|
|
|
}
|
|
|
- i40e_enable_pf_switch_lb(pf);
|
|
|
+ i40e_config_bridge_mode(veb);
|
|
|
}
|
|
|
for (i = 0; i < I40E_MAX_VEB && !veb; i++) {
|
|
|
if (pf->veb[i] && pf->veb[i]->seid == vsi->uplink_seid)
|
|
@@ -9061,8 +9356,10 @@ static void i40e_print_features(struct i40e_pf *pf)
|
|
|
#ifdef CONFIG_PCI_IOV
|
|
|
buf += sprintf(buf, "VFs: %d ", pf->num_req_vfs);
|
|
|
#endif
|
|
|
- buf += sprintf(buf, "VSIs: %d QP: %d ", pf->hw.func_caps.num_vsis,
|
|
|
- pf->vsi[pf->lan_vsi]->num_queue_pairs);
|
|
|
+ buf += sprintf(buf, "VSIs: %d QP: %d RX: %s ",
|
|
|
+ pf->hw.func_caps.num_vsis,
|
|
|
+ pf->vsi[pf->lan_vsi]->num_queue_pairs,
|
|
|
+ pf->flags & I40E_FLAG_RX_PS_ENABLED ? "PS" : "1BUF");
|
|
|
|
|
|
if (pf->flags & I40E_FLAG_RSS_ENABLED)
|
|
|
buf += sprintf(buf, "RSS ");
|
|
@@ -9099,6 +9396,7 @@ static void i40e_print_features(struct i40e_pf *pf)
|
|
|
**/
|
|
|
static int i40e_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
|
|
{
|
|
|
+ struct i40e_aq_get_phy_abilities_resp abilities;
|
|
|
struct i40e_pf *pf;
|
|
|
struct i40e_hw *hw;
|
|
|
static u16 pfs_found;
|
|
@@ -9454,6 +9752,13 @@ static int i40e_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
|
|
dev_warn(&pdev->dev, "Please move the device to a different PCI-e link with more lanes and/or higher transfer rate.\n");
|
|
|
}
|
|
|
|
|
|
+ /* get the requested speeds from the fw */
|
|
|
+ err = i40e_aq_get_phy_capabilities(hw, false, false, &abilities, NULL);
|
|
|
+ if (err)
|
|
|
+ dev_info(&pf->pdev->dev, "get phy abilities failed, aq_err %d, advertised speed settings may not be correct\n",
|
|
|
+ err);
|
|
|
+ pf->hw.phy.link_info.requested_speeds = abilities.link_speed;
|
|
|
+
|
|
|
/* print a string summarizing features */
|
|
|
i40e_print_features(pf);
|
|
|
|
|
@@ -9802,6 +10107,10 @@ static int __init i40e_init_module(void)
|
|
|
pr_info("%s: %s - version %s\n", i40e_driver_name,
|
|
|
i40e_driver_string, i40e_driver_version_str);
|
|
|
pr_info("%s: %s\n", i40e_driver_name, i40e_copyright);
|
|
|
+
|
|
|
+#if IS_ENABLED(CONFIG_CONFIGFS_FS)
|
|
|
+ i40e_configfs_init();
|
|
|
+#endif /* CONFIG_CONFIGFS_FS */
|
|
|
i40e_dbg_init();
|
|
|
return pci_register_driver(&i40e_driver);
|
|
|
}
|
|
@@ -9817,5 +10126,8 @@ static void __exit i40e_exit_module(void)
|
|
|
{
|
|
|
pci_unregister_driver(&i40e_driver);
|
|
|
i40e_dbg_exit();
|
|
|
+#if IS_ENABLED(CONFIG_CONFIGFS_FS)
|
|
|
+ i40e_configfs_exit();
|
|
|
+#endif /* CONFIG_CONFIGFS_FS */
|
|
|
}
|
|
|
module_exit(i40e_exit_module);
|