Commit fd0d192b authored by David S. Miller's avatar David S. Miller

Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/jkirsher/net-next

Jeff Kirsher says:

====================
Intel Wired LAN Driver Updates

This series contains updates to i40e and i40evf.

Greg provides two patches for i40e, the first adds the netdev ops to support
the addition of static FDB entries in the physical function (PF) MAC/VLAN
filter table so that the virtual functions (VFs) can communicate with
bridged virtual Ethernet ports such as those provided by the virtio
driver.  The second is to fix an issue where the assignment of a port
VLAN after it is already up and running requires the VF driver to be
reloaded, so print a message warning the host administrator about the
need to reload the VF driver.  In addition, knock the VF offline so that
it does not continue to receive traffic not on the port VLAN assigned to
it.

Jesse provides a patch for i40e and i40evf to unhide and enable the
PREFENA field in the receive host memory cache (RX-HMC) for best
performance.

Mitch provides a i40e patch to implement the net device op for Tx
bandwidth setting.

Catherine removes a firmware workaround that is no longer needed with
the latest firmware for i40e.  She also provides some minor cleanups
as well bumps the driver versions.

Anjali provides a fix for i40e displaying IPv4 flow director filters
which needed additional information to be communicated up above in
order for it to be displayed correctly.

Shannon adds tracking of the NVM busy state so that the driver won't
allow a new NVM update command until a completion event is received
from the current update.  Updates the admin queue API to reflect
recent changes in the firmware.  Also rearranges the "if netdev" logic
to prepare for handling non-netdev VSIs.  Lastly rework the fdir
setup and tear down to use the newly created i40e_vsi_open() and
i40e_vsi_close(), which also fixes a memory leak of the FDIR queue
buffer info structs across a reset.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents a29b694a b98d1df2
...@@ -32,6 +32,16 @@ ...@@ -32,6 +32,16 @@
static void i40e_resume_aq(struct i40e_hw *hw); static void i40e_resume_aq(struct i40e_hw *hw);
/**
* i40e_is_nvm_update_op - return true if this is an NVM update operation
* @desc: API request descriptor
**/
static inline bool i40e_is_nvm_update_op(struct i40e_aq_desc *desc)
{
return (desc->opcode == i40e_aqc_opc_nvm_erase) ||
(desc->opcode == i40e_aqc_opc_nvm_update);
}
/** /**
* i40e_adminq_init_regs - Initialize AdminQ registers * i40e_adminq_init_regs - Initialize AdminQ registers
* @hw: pointer to the hardware structure * @hw: pointer to the hardware structure
...@@ -585,6 +595,7 @@ i40e_status i40e_init_adminq(struct i40e_hw *hw) ...@@ -585,6 +595,7 @@ i40e_status i40e_init_adminq(struct i40e_hw *hw)
/* pre-emptive resource lock release */ /* pre-emptive resource lock release */
i40e_aq_release_resource(hw, I40E_NVM_RESOURCE_ID, 0, NULL); i40e_aq_release_resource(hw, I40E_NVM_RESOURCE_ID, 0, NULL);
hw->aq.nvm_busy = false;
ret_code = i40e_aq_set_hmc_resource_profile(hw, ret_code = i40e_aq_set_hmc_resource_profile(hw,
I40E_HMC_PROFILE_DEFAULT, I40E_HMC_PROFILE_DEFAULT,
...@@ -708,6 +719,12 @@ i40e_status i40e_asq_send_command(struct i40e_hw *hw, ...@@ -708,6 +719,12 @@ i40e_status i40e_asq_send_command(struct i40e_hw *hw,
goto asq_send_command_exit; goto asq_send_command_exit;
} }
if (i40e_is_nvm_update_op(desc) && hw->aq.nvm_busy) {
i40e_debug(hw, I40E_DEBUG_AQ_MESSAGE, "AQTX: NVM busy.\n");
status = I40E_ERR_NVM;
goto asq_send_command_exit;
}
details = I40E_ADMINQ_DETAILS(hw->aq.asq, hw->aq.asq.next_to_use); details = I40E_ADMINQ_DETAILS(hw->aq.asq, hw->aq.asq.next_to_use);
if (cmd_details) { if (cmd_details) {
*details = *cmd_details; *details = *cmd_details;
...@@ -835,6 +852,9 @@ i40e_status i40e_asq_send_command(struct i40e_hw *hw, ...@@ -835,6 +852,9 @@ i40e_status i40e_asq_send_command(struct i40e_hw *hw,
hw->aq.asq_last_status = (enum i40e_admin_queue_err)retval; hw->aq.asq_last_status = (enum i40e_admin_queue_err)retval;
} }
if (i40e_is_nvm_update_op(desc))
hw->aq.nvm_busy = true;
/* update the error if time out occurred */ /* update the error if time out occurred */
if ((!cmd_completed) && if ((!cmd_completed) &&
(!details->async && !details->postpone)) { (!details->async && !details->postpone)) {
...@@ -929,6 +949,9 @@ i40e_status i40e_clean_arq_element(struct i40e_hw *hw, ...@@ -929,6 +949,9 @@ i40e_status i40e_clean_arq_element(struct i40e_hw *hw,
e->msg_size); e->msg_size);
} }
if (i40e_is_nvm_update_op(&e->desc))
hw->aq.nvm_busy = false;
/* Restore the original datalen and buffer address in the desc, /* Restore the original datalen and buffer address in the desc,
* FW updates datalen to indicate the event message * FW updates datalen to indicate the event message
* size * size
......
...@@ -90,6 +90,7 @@ struct i40e_adminq_info { ...@@ -90,6 +90,7 @@ struct i40e_adminq_info {
u16 fw_min_ver; /* firmware minor version */ u16 fw_min_ver; /* firmware minor version */
u16 api_maj_ver; /* api major version */ u16 api_maj_ver; /* api major version */
u16 api_min_ver; /* api minor version */ u16 api_min_ver; /* api minor version */
bool nvm_busy;
struct mutex asq_mutex; /* Send queue lock */ struct mutex asq_mutex; /* Send queue lock */
struct mutex arq_mutex; /* Receive queue lock */ struct mutex arq_mutex; /* Receive queue lock */
......
...@@ -182,9 +182,6 @@ enum i40e_admin_queue_opc { ...@@ -182,9 +182,6 @@ enum i40e_admin_queue_opc {
i40e_aqc_opc_add_mirror_rule = 0x0260, i40e_aqc_opc_add_mirror_rule = 0x0260,
i40e_aqc_opc_delete_mirror_rule = 0x0261, i40e_aqc_opc_delete_mirror_rule = 0x0261,
i40e_aqc_opc_set_storm_control_config = 0x0280,
i40e_aqc_opc_get_storm_control_config = 0x0281,
/* DCB commands */ /* DCB commands */
i40e_aqc_opc_dcb_ignore_pfc = 0x0301, i40e_aqc_opc_dcb_ignore_pfc = 0x0301,
i40e_aqc_opc_dcb_updated = 0x0302, i40e_aqc_opc_dcb_updated = 0x0302,
...@@ -207,6 +204,7 @@ enum i40e_admin_queue_opc { ...@@ -207,6 +204,7 @@ enum i40e_admin_queue_opc {
i40e_aqc_opc_query_switching_comp_bw_config = 0x041A, i40e_aqc_opc_query_switching_comp_bw_config = 0x041A,
i40e_aqc_opc_suspend_port_tx = 0x041B, i40e_aqc_opc_suspend_port_tx = 0x041B,
i40e_aqc_opc_resume_port_tx = 0x041C, i40e_aqc_opc_resume_port_tx = 0x041C,
i40e_aqc_opc_configure_partition_bw = 0x041D,
/* hmc */ /* hmc */
i40e_aqc_opc_query_hmc_resource_profile = 0x0500, i40e_aqc_opc_query_hmc_resource_profile = 0x0500,
...@@ -1289,27 +1287,6 @@ struct i40e_aqc_add_delete_mirror_rule_completion { ...@@ -1289,27 +1287,6 @@ struct i40e_aqc_add_delete_mirror_rule_completion {
I40E_CHECK_CMD_LENGTH(i40e_aqc_add_delete_mirror_rule_completion); I40E_CHECK_CMD_LENGTH(i40e_aqc_add_delete_mirror_rule_completion);
/* Set Storm Control Configuration (direct 0x0280)
* Get Storm Control Configuration (direct 0x0281)
* the command and response use the same descriptor structure
*/
struct i40e_aqc_set_get_storm_control_config {
__le32 broadcast_threshold;
__le32 multicast_threshold;
__le32 control_flags;
#define I40E_AQC_STORM_CONTROL_MDIPW 0x01
#define I40E_AQC_STORM_CONTROL_MDICW 0x02
#define I40E_AQC_STORM_CONTROL_BDIPW 0x04
#define I40E_AQC_STORM_CONTROL_BDICW 0x08
#define I40E_AQC_STORM_CONTROL_BIDU 0x10
#define I40E_AQC_STORM_CONTROL_INTERVAL_SHIFT 8
#define I40E_AQC_STORM_CONTROL_INTERVAL_MASK (0x3FF << \
I40E_AQC_STORM_CONTROL_INTERVAL_SHIFT)
u8 reserved[4];
};
I40E_CHECK_CMD_LENGTH(i40e_aqc_set_get_storm_control_config);
/* DCB 0x03xx*/ /* DCB 0x03xx*/
/* PFC Ignore (direct 0x0301) /* PFC Ignore (direct 0x0301)
...@@ -1499,6 +1476,15 @@ struct i40e_aqc_query_switching_comp_bw_config_resp { ...@@ -1499,6 +1476,15 @@ struct i40e_aqc_query_switching_comp_bw_config_resp {
* (direct 0x041B and 0x041C) uses the generic SEID struct * (direct 0x041B and 0x041C) uses the generic SEID struct
*/ */
/* Configure partition BW
* (indirect 0x041D)
*/
struct i40e_aqc_configure_partition_bw_data {
__le16 pf_valid_bits;
u8 min_bw[16]; /* guaranteed bandwidth */
u8 max_bw[16]; /* bandwidth limit */
};
/* Get and set the active HMC resource profile and status. /* Get and set the active HMC resource profile and status.
* (direct 0x0500) and (direct 0x0501) * (direct 0x0500) and (direct 0x0501)
*/ */
...@@ -1583,11 +1569,8 @@ struct i40e_aq_get_phy_abilities_resp { ...@@ -1583,11 +1569,8 @@ struct i40e_aq_get_phy_abilities_resp {
#define I40E_AQ_PHY_FLAG_PAUSE_TX 0x01 #define I40E_AQ_PHY_FLAG_PAUSE_TX 0x01
#define I40E_AQ_PHY_FLAG_PAUSE_RX 0x02 #define I40E_AQ_PHY_FLAG_PAUSE_RX 0x02
#define I40E_AQ_PHY_FLAG_LOW_POWER 0x04 #define I40E_AQ_PHY_FLAG_LOW_POWER 0x04
#define I40E_AQ_PHY_FLAG_AN_SHIFT 3 #define I40E_AQ_PHY_LINK_ENABLED 0x08
#define I40E_AQ_PHY_FLAG_AN_MASK (0x3 << I40E_AQ_PHY_FLAG_AN_SHIFT) #define I40E_AQ_PHY_AN_ENABLED 0x10
#define I40E_AQ_PHY_FLAG_AN_OFF 0x00 /* link forced on */
#define I40E_AQ_PHY_FLAG_AN_OFF_LINK_DOWN 0x01
#define I40E_AQ_PHY_FLAG_AN_ON 0x02
#define I40E_AQ_PHY_FLAG_MODULE_QUAL 0x20 #define I40E_AQ_PHY_FLAG_MODULE_QUAL 0x20
__le16 eee_capability; __le16 eee_capability;
#define I40E_AQ_EEE_100BASE_TX 0x0002 #define I40E_AQ_EEE_100BASE_TX 0x0002
......
...@@ -2252,6 +2252,35 @@ static i40e_status i40e_aq_tx_sched_cmd(struct i40e_hw *hw, u16 seid, ...@@ -2252,6 +2252,35 @@ static i40e_status i40e_aq_tx_sched_cmd(struct i40e_hw *hw, u16 seid,
return status; return status;
} }
/**
* i40e_aq_config_vsi_bw_limit - Configure VSI BW Limit
* @hw: pointer to the hw struct
* @seid: VSI seid
* @credit: BW limit credits (0 = disabled)
* @max_credit: Max BW limit credits
* @cmd_details: pointer to command details structure or NULL
**/
i40e_status i40e_aq_config_vsi_bw_limit(struct i40e_hw *hw,
u16 seid, u16 credit, u8 max_credit,
struct i40e_asq_cmd_details *cmd_details)
{
struct i40e_aq_desc desc;
struct i40e_aqc_configure_vsi_bw_limit *cmd =
(struct i40e_aqc_configure_vsi_bw_limit *)&desc.params.raw;
i40e_status status;
i40e_fill_default_direct_cmd_desc(&desc,
i40e_aqc_opc_configure_vsi_bw_limit);
cmd->vsi_seid = cpu_to_le16(seid);
cmd->credit = cpu_to_le16(credit);
cmd->max_credit = max_credit;
status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
return status;
}
/** /**
* i40e_aq_config_vsi_tc_bw - Config VSI BW Allocation per TC * i40e_aq_config_vsi_tc_bw - Config VSI BW Allocation per TC
* @hw: pointer to the hw struct * @hw: pointer to the hw struct
......
...@@ -649,7 +649,7 @@ static void i40e_get_ethtool_stats(struct net_device *netdev, ...@@ -649,7 +649,7 @@ static void i40e_get_ethtool_stats(struct net_device *netdev,
sizeof(u64)) ? *(u64 *)p : *(u32 *)p; sizeof(u64)) ? *(u64 *)p : *(u32 *)p;
} }
rcu_read_lock(); rcu_read_lock();
for (j = 0; j < vsi->num_queue_pairs; j++, i += 4) { for (j = 0; j < vsi->num_queue_pairs; j++) {
struct i40e_ring *tx_ring = ACCESS_ONCE(vsi->tx_rings[j]); struct i40e_ring *tx_ring = ACCESS_ONCE(vsi->tx_rings[j]);
struct i40e_ring *rx_ring; struct i40e_ring *rx_ring;
...@@ -662,14 +662,16 @@ static void i40e_get_ethtool_stats(struct net_device *netdev, ...@@ -662,14 +662,16 @@ static void i40e_get_ethtool_stats(struct net_device *netdev,
data[i] = tx_ring->stats.packets; data[i] = tx_ring->stats.packets;
data[i + 1] = tx_ring->stats.bytes; data[i + 1] = tx_ring->stats.bytes;
} while (u64_stats_fetch_retry_irq(&tx_ring->syncp, start)); } while (u64_stats_fetch_retry_irq(&tx_ring->syncp, start));
i += 2;
/* Rx ring is the 2nd half of the queue pair */ /* Rx ring is the 2nd half of the queue pair */
rx_ring = &tx_ring[1]; rx_ring = &tx_ring[1];
do { do {
start = u64_stats_fetch_begin_irq(&rx_ring->syncp); start = u64_stats_fetch_begin_irq(&rx_ring->syncp);
data[i + 2] = rx_ring->stats.packets; data[i] = rx_ring->stats.packets;
data[i + 3] = rx_ring->stats.bytes; data[i + 1] = rx_ring->stats.bytes;
} while (u64_stats_fetch_retry_irq(&rx_ring->syncp, start)); } while (u64_stats_fetch_retry_irq(&rx_ring->syncp, start));
i += 2;
} }
rcu_read_unlock(); rcu_read_unlock();
if (vsi == pf->vsi[pf->lan_vsi]) { if (vsi == pf->vsi[pf->lan_vsi]) {
...@@ -1189,6 +1191,12 @@ static int i40e_get_ethtool_fdir_entry(struct i40e_pf *pf, ...@@ -1189,6 +1191,12 @@ static int i40e_get_ethtool_fdir_entry(struct i40e_pf *pf,
return -EINVAL; return -EINVAL;
fsp->flow_type = rule->flow_type; fsp->flow_type = rule->flow_type;
if (fsp->flow_type == IP_USER_FLOW) {
fsp->h_u.usr_ip4_spec.ip_ver = ETH_RX_NFC_IP4;
fsp->h_u.usr_ip4_spec.proto = 0;
fsp->m_u.usr_ip4_spec.proto = 0;
}
fsp->h_u.tcp_ip4_spec.psrc = rule->src_port; fsp->h_u.tcp_ip4_spec.psrc = rule->src_port;
fsp->h_u.tcp_ip4_spec.pdst = rule->dst_port; fsp->h_u.tcp_ip4_spec.pdst = rule->dst_port;
fsp->h_u.tcp_ip4_spec.ip4src = rule->src_ip[0]; fsp->h_u.tcp_ip4_spec.ip4src = rule->src_ip[0];
......
...@@ -747,6 +747,7 @@ static struct i40e_context_ele i40e_hmc_rxq_ce_info[] = { ...@@ -747,6 +747,7 @@ static struct i40e_context_ele i40e_hmc_rxq_ce_info[] = {
{ I40E_HMC_STORE(i40e_hmc_obj_rxq, tphdata_ena), 1, 195 }, { I40E_HMC_STORE(i40e_hmc_obj_rxq, tphdata_ena), 1, 195 },
{ I40E_HMC_STORE(i40e_hmc_obj_rxq, tphhead_ena), 1, 196 }, { I40E_HMC_STORE(i40e_hmc_obj_rxq, tphhead_ena), 1, 196 },
{ I40E_HMC_STORE(i40e_hmc_obj_rxq, lrxqthresh), 3, 198 }, { I40E_HMC_STORE(i40e_hmc_obj_rxq, lrxqthresh), 3, 198 },
{ I40E_HMC_STORE(i40e_hmc_obj_rxq, prefena), 1, 201 },
{ 0 } { 0 }
}; };
......
...@@ -56,6 +56,7 @@ struct i40e_hmc_obj_rxq { ...@@ -56,6 +56,7 @@ struct i40e_hmc_obj_rxq {
u8 tphdata_ena; u8 tphdata_ena;
u8 tphhead_ena; u8 tphhead_ena;
u8 lrxqthresh; u8 lrxqthresh;
u8 prefena; /* NOTE: normally must be set to 1 at init */
}; };
/* Tx queue context data */ /* Tx queue context data */
......
This diff is collapsed.
...@@ -167,6 +167,9 @@ i40e_status i40e_aq_delete_element(struct i40e_hw *hw, u16 seid, ...@@ -167,6 +167,9 @@ i40e_status i40e_aq_delete_element(struct i40e_hw *hw, u16 seid,
i40e_status i40e_aq_mac_address_write(struct i40e_hw *hw, i40e_status i40e_aq_mac_address_write(struct i40e_hw *hw,
u16 flags, u8 *mac_addr, u16 flags, u8 *mac_addr,
struct i40e_asq_cmd_details *cmd_details); struct i40e_asq_cmd_details *cmd_details);
i40e_status i40e_aq_config_vsi_bw_limit(struct i40e_hw *hw,
u16 seid, u16 credit, u8 max_credit,
struct i40e_asq_cmd_details *cmd_details);
i40e_status i40e_aq_dcb_updated(struct i40e_hw *hw, i40e_status i40e_aq_dcb_updated(struct i40e_hw *hw,
struct i40e_asq_cmd_details *cmd_details); struct i40e_asq_cmd_details *cmd_details);
i40e_status i40e_aq_set_hmc_resource_profile(struct i40e_hw *hw, i40e_status i40e_aq_set_hmc_resource_profile(struct i40e_hw *hw,
......
...@@ -28,6 +28,24 @@ ...@@ -28,6 +28,24 @@
/***********************misc routines*****************************/ /***********************misc routines*****************************/
/**
* i40e_vc_disable_vf
* @pf: pointer to the pf info
* @vf: pointer to the vf info
*
* Disable the VF through a SW reset
**/
static inline void i40e_vc_disable_vf(struct i40e_pf *pf, struct i40e_vf *vf)
{
struct i40e_hw *hw = &pf->hw;
u32 reg;
reg = rd32(hw, I40E_VPGEN_VFRTRIG(vf->vf_id));
reg |= I40E_VPGEN_VFRTRIG_VFSWR_MASK;
wr32(hw, I40E_VPGEN_VFRTRIG(vf->vf_id), reg);
i40e_flush(hw);
}
/** /**
* i40e_vc_isvalid_vsi_id * i40e_vc_isvalid_vsi_id
* @vf: pointer to the vf info * @vf: pointer to the vf info
...@@ -416,6 +434,15 @@ static int i40e_alloc_vsi_res(struct i40e_vf *vf, enum i40e_vsi_type type) ...@@ -416,6 +434,15 @@ static int i40e_alloc_vsi_res(struct i40e_vf *vf, enum i40e_vsi_type type)
if (ret) if (ret)
dev_err(&pf->pdev->dev, "Unable to program ucast filters\n"); dev_err(&pf->pdev->dev, "Unable to program ucast filters\n");
/* Set VF bandwidth if specified */
if (vf->tx_rate) {
ret = i40e_aq_config_vsi_bw_limit(&pf->hw, vsi->seid,
vf->tx_rate / 50, 0, NULL);
if (ret)
dev_err(&pf->pdev->dev, "Unable to set tx rate, VF %d, error code %d.\n",
vf->vf_id, ret);
}
error_alloc_vsi_res: error_alloc_vsi_res:
return ret; return ret;
} }
...@@ -2088,10 +2115,16 @@ int i40e_ndo_set_vf_port_vlan(struct net_device *netdev, ...@@ -2088,10 +2115,16 @@ int i40e_ndo_set_vf_port_vlan(struct net_device *netdev,
goto error_pvid; goto error_pvid;
} }
if (vsi->info.pvid == 0 && i40e_is_vsi_in_vlan(vsi)) if (vsi->info.pvid == 0 && i40e_is_vsi_in_vlan(vsi)) {
dev_err(&pf->pdev->dev, dev_err(&pf->pdev->dev,
"VF %d has already configured VLAN filters and the administrator is requesting a port VLAN override.\nPlease unload and reload the VF driver for this change to take effect.\n", "VF %d has already configured VLAN filters and the administrator is requesting a port VLAN override.\nPlease unload and reload the VF driver for this change to take effect.\n",
vf_id); vf_id);
/* Administrator Error - knock the VF offline until he does
* the right thing by reconfiguring his network correctly
* and then reloading the VF driver.
*/
i40e_vc_disable_vf(pf, vf);
}
/* Check for condition where there was already a port VLAN ID /* Check for condition where there was already a port VLAN ID
* filter set and now it is being deleted by setting it to zero. * filter set and now it is being deleted by setting it to zero.
...@@ -2160,7 +2193,61 @@ int i40e_ndo_set_vf_port_vlan(struct net_device *netdev, ...@@ -2160,7 +2193,61 @@ int i40e_ndo_set_vf_port_vlan(struct net_device *netdev,
**/ **/
int i40e_ndo_set_vf_bw(struct net_device *netdev, int vf_id, int tx_rate) int i40e_ndo_set_vf_bw(struct net_device *netdev, int vf_id, int tx_rate)
{ {
return -EOPNOTSUPP; struct i40e_netdev_priv *np = netdev_priv(netdev);
struct i40e_pf *pf = np->vsi->back;
struct i40e_vsi *vsi;
struct i40e_vf *vf;
int speed = 0;
int ret = 0;
/* validate the request */
if (vf_id >= pf->num_alloc_vfs) {
dev_err(&pf->pdev->dev, "Invalid VF Identifier %d.\n", vf_id);
ret = -EINVAL;
goto error;
}
vf = &(pf->vf[vf_id]);
vsi = pf->vsi[vf->lan_vsi_index];
if (!test_bit(I40E_VF_STAT_INIT, &vf->vf_states)) {
dev_err(&pf->pdev->dev, "Uninitialized VF %d.\n", vf_id);
ret = -EINVAL;
goto error;
}
switch (pf->hw.phy.link_info.link_speed) {
case I40E_LINK_SPEED_40GB:
speed = 40000;
break;
case I40E_LINK_SPEED_10GB:
speed = 10000;
break;
case I40E_LINK_SPEED_1GB:
speed = 1000;
break;
default:
break;
}
if (tx_rate > speed) {
dev_err(&pf->pdev->dev, "Invalid tx rate %d specified for vf %d.",
tx_rate, vf->vf_id);
ret = -EINVAL;
goto error;
}
/* Tx rate credits are in values of 50Mbps, 0 is disabled*/
ret = i40e_aq_config_vsi_bw_limit(&pf->hw, vsi->seid, tx_rate / 50, 0,
NULL);
if (ret) {
dev_err(&pf->pdev->dev, "Unable to set tx rate, error code %d.\n",
ret);
ret = -EIO;
goto error;
}
vf->tx_rate = tx_rate;
error:
return ret;
} }
/** /**
...@@ -2200,7 +2287,7 @@ int i40e_ndo_get_vf_config(struct net_device *netdev, ...@@ -2200,7 +2287,7 @@ int i40e_ndo_get_vf_config(struct net_device *netdev,
memcpy(&ivi->mac, vf->default_lan_addr.addr, ETH_ALEN); memcpy(&ivi->mac, vf->default_lan_addr.addr, ETH_ALEN);
ivi->tx_rate = 0; ivi->tx_rate = vf->tx_rate;
ivi->vlan = le16_to_cpu(vsi->info.pvid) & I40E_VLAN_MASK; ivi->vlan = le16_to_cpu(vsi->info.pvid) & I40E_VLAN_MASK;
ivi->qos = (le16_to_cpu(vsi->info.pvid) & I40E_PRIORITY_MASK) >> ivi->qos = (le16_to_cpu(vsi->info.pvid) & I40E_PRIORITY_MASK) >>
I40E_VLAN_PRIORITY_SHIFT; I40E_VLAN_PRIORITY_SHIFT;
......
...@@ -98,6 +98,7 @@ struct i40e_vf { ...@@ -98,6 +98,7 @@ struct i40e_vf {
unsigned long vf_caps; /* vf's adv. capabilities */ unsigned long vf_caps; /* vf's adv. capabilities */
unsigned long vf_states; /* vf's runtime states */ unsigned long vf_states; /* vf's runtime states */
unsigned int tx_rate; /* Tx bandwidth limit in Mbps */
bool link_forced; bool link_forced;
bool link_up; /* only valid if vf link is forced */ bool link_up; /* only valid if vf link is forced */
}; };
......
...@@ -27,6 +27,16 @@ ...@@ -27,6 +27,16 @@
#include "i40e_adminq.h" #include "i40e_adminq.h"
#include "i40e_prototype.h" #include "i40e_prototype.h"
/**
* i40e_is_nvm_update_op - return true if this is an NVM update operation
* @desc: API request descriptor
**/
static inline bool i40e_is_nvm_update_op(struct i40e_aq_desc *desc)
{
return (desc->opcode == i40e_aqc_opc_nvm_erase) ||
(desc->opcode == i40e_aqc_opc_nvm_update);
}
/** /**
* i40e_adminq_init_regs - Initialize AdminQ registers * i40e_adminq_init_regs - Initialize AdminQ registers
* @hw: pointer to the hardware structure * @hw: pointer to the hardware structure
...@@ -659,6 +669,12 @@ i40e_status i40evf_asq_send_command(struct i40e_hw *hw, ...@@ -659,6 +669,12 @@ i40e_status i40evf_asq_send_command(struct i40e_hw *hw,
goto asq_send_command_exit; goto asq_send_command_exit;
} }
if (i40e_is_nvm_update_op(desc) && hw->aq.nvm_busy) {
i40e_debug(hw, I40E_DEBUG_AQ_MESSAGE, "AQTX: NVM busy.\n");
status = I40E_ERR_NVM;
goto asq_send_command_exit;
}
details = I40E_ADMINQ_DETAILS(hw->aq.asq, hw->aq.asq.next_to_use); details = I40E_ADMINQ_DETAILS(hw->aq.asq, hw->aq.asq.next_to_use);
if (cmd_details) { if (cmd_details) {
*details = *cmd_details; *details = *cmd_details;
...@@ -786,6 +802,9 @@ i40e_status i40evf_asq_send_command(struct i40e_hw *hw, ...@@ -786,6 +802,9 @@ i40e_status i40evf_asq_send_command(struct i40e_hw *hw,
hw->aq.asq_last_status = (enum i40e_admin_queue_err)retval; hw->aq.asq_last_status = (enum i40e_admin_queue_err)retval;
} }
if (i40e_is_nvm_update_op(desc))
hw->aq.nvm_busy = true;
/* update the error if time out occurred */ /* update the error if time out occurred */
if ((!cmd_completed) && if ((!cmd_completed) &&
(!details->async && !details->postpone)) { (!details->async && !details->postpone)) {
...@@ -880,6 +899,9 @@ i40e_status i40evf_clean_arq_element(struct i40e_hw *hw, ...@@ -880,6 +899,9 @@ i40e_status i40evf_clean_arq_element(struct i40e_hw *hw,
e->msg_size); e->msg_size);
} }
if (i40e_is_nvm_update_op(&e->desc))
hw->aq.nvm_busy = false;
/* Restore the original datalen and buffer address in the desc, /* Restore the original datalen and buffer address in the desc,
* FW updates datalen to indicate the event message * FW updates datalen to indicate the event message
* size * size
......
...@@ -87,6 +87,7 @@ struct i40e_adminq_info { ...@@ -87,6 +87,7 @@ struct i40e_adminq_info {
u16 fw_min_ver; /* firmware minor version */ u16 fw_min_ver; /* firmware minor version */
u16 api_maj_ver; /* api major version */ u16 api_maj_ver; /* api major version */
u16 api_min_ver; /* api minor version */ u16 api_min_ver; /* api minor version */
bool nvm_busy;
struct mutex asq_mutex; /* Send queue lock */ struct mutex asq_mutex; /* Send queue lock */
struct mutex arq_mutex; /* Receive queue lock */ struct mutex arq_mutex; /* Receive queue lock */
......
...@@ -180,9 +180,6 @@ enum i40e_admin_queue_opc { ...@@ -180,9 +180,6 @@ enum i40e_admin_queue_opc {
i40e_aqc_opc_add_mirror_rule = 0x0260, i40e_aqc_opc_add_mirror_rule = 0x0260,
i40e_aqc_opc_delete_mirror_rule = 0x0261, i40e_aqc_opc_delete_mirror_rule = 0x0261,
i40e_aqc_opc_set_storm_control_config = 0x0280,
i40e_aqc_opc_get_storm_control_config = 0x0281,
/* DCB commands */ /* DCB commands */
i40e_aqc_opc_dcb_ignore_pfc = 0x0301, i40e_aqc_opc_dcb_ignore_pfc = 0x0301,
i40e_aqc_opc_dcb_updated = 0x0302, i40e_aqc_opc_dcb_updated = 0x0302,
...@@ -205,6 +202,7 @@ enum i40e_admin_queue_opc { ...@@ -205,6 +202,7 @@ enum i40e_admin_queue_opc {
i40e_aqc_opc_query_switching_comp_bw_config = 0x041A, i40e_aqc_opc_query_switching_comp_bw_config = 0x041A,
i40e_aqc_opc_suspend_port_tx = 0x041B, i40e_aqc_opc_suspend_port_tx = 0x041B,
i40e_aqc_opc_resume_port_tx = 0x041C, i40e_aqc_opc_resume_port_tx = 0x041C,
i40e_aqc_opc_configure_partition_bw = 0x041D,
/* hmc */ /* hmc */
i40e_aqc_opc_query_hmc_resource_profile = 0x0500, i40e_aqc_opc_query_hmc_resource_profile = 0x0500,
...@@ -1289,27 +1287,6 @@ struct i40e_aqc_add_delete_mirror_rule_completion { ...@@ -1289,27 +1287,6 @@ struct i40e_aqc_add_delete_mirror_rule_completion {
I40E_CHECK_CMD_LENGTH(i40e_aqc_add_delete_mirror_rule_completion); I40E_CHECK_CMD_LENGTH(i40e_aqc_add_delete_mirror_rule_completion);
/* Set Storm Control Configuration (direct 0x0280)
* Get Storm Control Configuration (direct 0x0281)
* the command and response use the same descriptor structure
*/
struct i40e_aqc_set_get_storm_control_config {
__le32 broadcast_threshold;
__le32 multicast_threshold;
__le32 control_flags;
#define I40E_AQC_STORM_CONTROL_MDIPW 0x01
#define I40E_AQC_STORM_CONTROL_MDICW 0x02
#define I40E_AQC_STORM_CONTROL_BDIPW 0x04
#define I40E_AQC_STORM_CONTROL_BDICW 0x08
#define I40E_AQC_STORM_CONTROL_BIDU 0x10
#define I40E_AQC_STORM_CONTROL_INTERVAL_SHIFT 8
#define I40E_AQC_STORM_CONTROL_INTERVAL_MASK (0x3FF << \
I40E_AQC_STORM_CONTROL_INTERVAL_SHIFT)
u8 reserved[4];
};
I40E_CHECK_CMD_LENGTH(i40e_aqc_set_get_storm_control_config);
/* DCB 0x03xx*/ /* DCB 0x03xx*/
/* PFC Ignore (direct 0x0301) /* PFC Ignore (direct 0x0301)
...@@ -1499,6 +1476,15 @@ struct i40e_aqc_query_switching_comp_bw_config_resp { ...@@ -1499,6 +1476,15 @@ struct i40e_aqc_query_switching_comp_bw_config_resp {
* (direct 0x041B and 0x041C) uses the generic SEID struct * (direct 0x041B and 0x041C) uses the generic SEID struct
*/ */
/* Configure partition BW
* (indirect 0x041D)
*/
struct i40e_aqc_configure_partition_bw_data {
__le16 pf_valid_bits;
u8 min_bw[16]; /* guaranteed bandwidth */
u8 max_bw[16]; /* bandwidth limit */
};
/* Get and set the active HMC resource profile and status. /* Get and set the active HMC resource profile and status.
* (direct 0x0500) and (direct 0x0501) * (direct 0x0500) and (direct 0x0501)
*/ */
...@@ -1583,11 +1569,8 @@ struct i40e_aq_get_phy_abilities_resp { ...@@ -1583,11 +1569,8 @@ struct i40e_aq_get_phy_abilities_resp {
#define I40E_AQ_PHY_FLAG_PAUSE_TX 0x01 #define I40E_AQ_PHY_FLAG_PAUSE_TX 0x01
#define I40E_AQ_PHY_FLAG_PAUSE_RX 0x02 #define I40E_AQ_PHY_FLAG_PAUSE_RX 0x02
#define I40E_AQ_PHY_FLAG_LOW_POWER 0x04 #define I40E_AQ_PHY_FLAG_LOW_POWER 0x04
#define I40E_AQ_PHY_FLAG_AN_SHIFT 3 #define I40E_AQ_PHY_LINK_ENABLED 0x08
#define I40E_AQ_PHY_FLAG_AN_MASK (0x3 << I40E_AQ_PHY_FLAG_AN_SHIFT) #define I40E_AQ_PHY_AN_ENABLED 0x10
#define I40E_AQ_PHY_FLAG_AN_OFF 0x00 /* link forced on */
#define I40E_AQ_PHY_FLAG_AN_OFF_LINK_DOWN 0x01
#define I40E_AQ_PHY_FLAG_AN_ON 0x02
#define I40E_AQ_PHY_FLAG_MODULE_QUAL 0x20 #define I40E_AQ_PHY_FLAG_MODULE_QUAL 0x20
__le16 eee_capability; __le16 eee_capability;
#define I40E_AQ_EEE_100BASE_TX 0x0002 #define I40E_AQ_EEE_100BASE_TX 0x0002
......
...@@ -53,6 +53,7 @@ struct i40e_hmc_obj_rxq { ...@@ -53,6 +53,7 @@ struct i40e_hmc_obj_rxq {
u8 tphdata_ena; u8 tphdata_ena;
u8 tphhead_ena; u8 tphhead_ena;
u8 lrxqthresh; u8 lrxqthresh;
u8 prefena; /* NOTE: normally must be set to 1 at init */
}; };
/* Tx queue context data */ /* Tx queue context data */
......
...@@ -31,7 +31,7 @@ char i40evf_driver_name[] = "i40evf"; ...@@ -31,7 +31,7 @@ char i40evf_driver_name[] = "i40evf";
static const char i40evf_driver_string[] = static const char i40evf_driver_string[] =
"Intel(R) XL710 X710 Virtual Function Network Driver"; "Intel(R) XL710 X710 Virtual Function Network Driver";
#define DRV_VERSION "0.9.16" #define DRV_VERSION "0.9.21"
const char i40evf_driver_version[] = DRV_VERSION; const char i40evf_driver_version[] = DRV_VERSION;
static const char i40evf_copyright[] = static const char i40evf_copyright[] =
"Copyright (c) 2013 - 2014 Intel Corporation."; "Copyright (c) 2013 - 2014 Intel Corporation.";
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment