mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-26 10:49:33 +00:00
Merge branch '100GbE' of git://git.kernel.org/pub/scm/linux/kernel/git/jkirsher/next-queue
Jeff Kirsher says: ==================== 100GbE Intel Wired LAN Driver Updates 2020-02-15 This series contains updates to ice driver only. Brett adds support for "Queue in Queue" (QinQ) support, by supporting S-tag & C-tag VLAN traffic by disabling pruning when there are no 0x8100 VLAN interfaces currently on top of the PF. Also refactored the port VLAN configuration to re-use the common code for enabling and disabling a port VLAN in single function. Added a helper function to determine if the VF link is up. Fixed how the port VLAN configures the priority bits for a VF interface. Fixed the port VLAN to only see its own broadcast and multicast traffic. Added support to enable and disable all receive queues, by refactoring adding a new function to do the necessary steps to enable/disable a queue with the necessary read flush. Fixed how we set the mapping mode for transmit and receive queues. Added support for VF queues to handle LAN overflow events. Fixed and refactored how receive queues get disabled for VFs, which was being handled one queue at at time, so improve it to handle when the VF is requesting more than one queue to be disabled. Fixed how the virtchnl_queue_select bitmap is validated. Finally a patch not authored by Brett, Bruce cleans up "fallthrough" comments which are unnecessary. Also replaces the "fallthough" comments with the GCC reserved word fallthrough, along with other GCC compiler fixes. Add missing function header comment regarding a function argument that was missing. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
27aa6228d6
15 changed files with 385 additions and 198 deletions
|
@ -1661,6 +1661,13 @@ struct ice_aqc_get_pkg_info_resp {
|
||||||
struct ice_aqc_get_pkg_info pkg_info[1];
|
struct ice_aqc_get_pkg_info pkg_info[1];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Lan Queue Overflow Event (direct, 0x1001) */
|
||||||
|
struct ice_aqc_event_lan_overflow {
|
||||||
|
__le32 prtdcb_ruptq;
|
||||||
|
__le32 qtx_ctl;
|
||||||
|
u8 reserved[8];
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* struct ice_aq_desc - Admin Queue (AQ) descriptor
|
* struct ice_aq_desc - Admin Queue (AQ) descriptor
|
||||||
* @flags: ICE_AQ_FLAG_* flags
|
* @flags: ICE_AQ_FLAG_* flags
|
||||||
|
@ -1730,6 +1737,7 @@ struct ice_aq_desc {
|
||||||
struct ice_aqc_alloc_free_res_cmd sw_res_ctrl;
|
struct ice_aqc_alloc_free_res_cmd sw_res_ctrl;
|
||||||
struct ice_aqc_set_event_mask set_event_mask;
|
struct ice_aqc_set_event_mask set_event_mask;
|
||||||
struct ice_aqc_get_link_status get_link_status;
|
struct ice_aqc_get_link_status get_link_status;
|
||||||
|
struct ice_aqc_event_lan_overflow lan_overflow;
|
||||||
} params;
|
} params;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1860,6 +1868,9 @@ enum ice_adminq_opc {
|
||||||
ice_aqc_opc_update_pkg = 0x0C42,
|
ice_aqc_opc_update_pkg = 0x0C42,
|
||||||
ice_aqc_opc_get_pkg_info_list = 0x0C43,
|
ice_aqc_opc_get_pkg_info_list = 0x0C43,
|
||||||
|
|
||||||
|
/* Standalone Commands/Events */
|
||||||
|
ice_aqc_opc_event_lan_overflow = 0x1001,
|
||||||
|
|
||||||
/* debug commands */
|
/* debug commands */
|
||||||
ice_aqc_opc_fw_logging = 0xFF09,
|
ice_aqc_opc_fw_logging = 0xFF09,
|
||||||
ice_aqc_opc_fw_logging_info = 0xFF10,
|
ice_aqc_opc_fw_logging_info = 0xFF10,
|
||||||
|
|
|
@ -247,7 +247,6 @@ ice_setup_tx_ctx(struct ice_ring *ring, struct ice_tlan_ctx *tlan_ctx, u16 pf_q)
|
||||||
*/
|
*/
|
||||||
switch (vsi->type) {
|
switch (vsi->type) {
|
||||||
case ICE_VSI_LB:
|
case ICE_VSI_LB:
|
||||||
/* fall through */
|
|
||||||
case ICE_VSI_PF:
|
case ICE_VSI_PF:
|
||||||
tlan_ctx->vmvf_type = ICE_TLAN_CTX_VMVF_TYPE_PF;
|
tlan_ctx->vmvf_type = ICE_TLAN_CTX_VMVF_TYPE_PF;
|
||||||
break;
|
break;
|
||||||
|
@ -459,17 +458,20 @@ int __ice_vsi_get_qs(struct ice_qs_cfg *qs_cfg)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ice_vsi_ctrl_rx_ring - Start or stop a VSI's Rx ring
|
* ice_vsi_ctrl_one_rx_ring - start/stop VSI's Rx ring with no busy wait
|
||||||
* @vsi: the VSI being configured
|
* @vsi: the VSI being configured
|
||||||
* @ena: start or stop the Rx rings
|
* @ena: start or stop the Rx ring
|
||||||
* @rxq_idx: Rx queue index
|
* @rxq_idx: 0-based Rx queue index for the VSI passed in
|
||||||
|
* @wait: wait or don't wait for configuration to finish in hardware
|
||||||
|
*
|
||||||
|
* Return 0 on success and negative on error.
|
||||||
*/
|
*/
|
||||||
int ice_vsi_ctrl_rx_ring(struct ice_vsi *vsi, bool ena, u16 rxq_idx)
|
int
|
||||||
|
ice_vsi_ctrl_one_rx_ring(struct ice_vsi *vsi, bool ena, u16 rxq_idx, bool wait)
|
||||||
{
|
{
|
||||||
int pf_q = vsi->rxq_map[rxq_idx];
|
int pf_q = vsi->rxq_map[rxq_idx];
|
||||||
struct ice_pf *pf = vsi->back;
|
struct ice_pf *pf = vsi->back;
|
||||||
struct ice_hw *hw = &pf->hw;
|
struct ice_hw *hw = &pf->hw;
|
||||||
int ret = 0;
|
|
||||||
u32 rx_reg;
|
u32 rx_reg;
|
||||||
|
|
||||||
rx_reg = rd32(hw, QRX_CTRL(pf_q));
|
rx_reg = rd32(hw, QRX_CTRL(pf_q));
|
||||||
|
@ -485,13 +487,30 @@ int ice_vsi_ctrl_rx_ring(struct ice_vsi *vsi, bool ena, u16 rxq_idx)
|
||||||
rx_reg &= ~QRX_CTRL_QENA_REQ_M;
|
rx_reg &= ~QRX_CTRL_QENA_REQ_M;
|
||||||
wr32(hw, QRX_CTRL(pf_q), rx_reg);
|
wr32(hw, QRX_CTRL(pf_q), rx_reg);
|
||||||
|
|
||||||
/* wait for the change to finish */
|
if (!wait)
|
||||||
ret = ice_pf_rxq_wait(pf, pf_q, ena);
|
return 0;
|
||||||
if (ret)
|
|
||||||
dev_err(ice_pf_to_dev(pf), "VSI idx %d Rx ring %d %sable timeout\n",
|
|
||||||
vsi->idx, pf_q, (ena ? "en" : "dis"));
|
|
||||||
|
|
||||||
return ret;
|
ice_flush(hw);
|
||||||
|
return ice_pf_rxq_wait(pf, pf_q, ena);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ice_vsi_wait_one_rx_ring - wait for a VSI's Rx ring to be stopped/started
|
||||||
|
* @vsi: the VSI being configured
|
||||||
|
* @ena: true/false to verify Rx ring has been enabled/disabled respectively
|
||||||
|
* @rxq_idx: 0-based Rx queue index for the VSI passed in
|
||||||
|
*
|
||||||
|
* This routine will wait for the given Rx queue of the VSI to reach the
|
||||||
|
* enabled or disabled state. Returns -ETIMEDOUT in case of failing to reach
|
||||||
|
* the requested state after multiple retries; else will return 0 in case of
|
||||||
|
* success.
|
||||||
|
*/
|
||||||
|
int ice_vsi_wait_one_rx_ring(struct ice_vsi *vsi, bool ena, u16 rxq_idx)
|
||||||
|
{
|
||||||
|
int pf_q = vsi->rxq_map[rxq_idx];
|
||||||
|
struct ice_pf *pf = vsi->back;
|
||||||
|
|
||||||
|
return ice_pf_rxq_wait(pf, pf_q, ena);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -8,7 +8,9 @@
|
||||||
|
|
||||||
int ice_setup_rx_ctx(struct ice_ring *ring);
|
int ice_setup_rx_ctx(struct ice_ring *ring);
|
||||||
int __ice_vsi_get_qs(struct ice_qs_cfg *qs_cfg);
|
int __ice_vsi_get_qs(struct ice_qs_cfg *qs_cfg);
|
||||||
int ice_vsi_ctrl_rx_ring(struct ice_vsi *vsi, bool ena, u16 rxq_idx);
|
int
|
||||||
|
ice_vsi_ctrl_one_rx_ring(struct ice_vsi *vsi, bool ena, u16 rxq_idx, bool wait);
|
||||||
|
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);
|
||||||
void ice_vsi_map_rings_to_vectors(struct ice_vsi *vsi);
|
void ice_vsi_map_rings_to_vectors(struct ice_vsi *vsi);
|
||||||
void ice_vsi_free_q_vectors(struct ice_vsi *vsi);
|
void ice_vsi_free_q_vectors(struct ice_vsi *vsi);
|
||||||
|
|
|
@ -1181,7 +1181,7 @@ ice_aq_send_cmd(struct ice_hw *hw, struct ice_aq_desc *desc, void *buf,
|
||||||
case ice_aqc_opc_release_res:
|
case ice_aqc_opc_release_res:
|
||||||
if (le16_to_cpu(cmd->res_id) == ICE_AQC_RES_ID_GLBL_LOCK)
|
if (le16_to_cpu(cmd->res_id) == ICE_AQC_RES_ID_GLBL_LOCK)
|
||||||
break;
|
break;
|
||||||
/* fall-through */
|
fallthrough;
|
||||||
default:
|
default:
|
||||||
mutex_lock(&ice_global_cfg_lock_sw);
|
mutex_lock(&ice_global_cfg_lock_sw);
|
||||||
lock_acquired = true;
|
lock_acquired = true;
|
||||||
|
@ -2703,7 +2703,7 @@ __ice_aq_get_set_rss_lut(struct ice_hw *hw, u16 vsi_id, u8 lut_type, u8 *lut,
|
||||||
ICE_AQC_GSET_RSS_LUT_TABLE_SIZE_M;
|
ICE_AQC_GSET_RSS_LUT_TABLE_SIZE_M;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/* fall-through */
|
fallthrough;
|
||||||
default:
|
default:
|
||||||
status = ICE_ERR_PARAM;
|
status = ICE_ERR_PARAM;
|
||||||
goto ice_aq_get_set_rss_lut_exit;
|
goto ice_aq_get_set_rss_lut_exit;
|
||||||
|
|
|
@ -462,7 +462,7 @@ static int ice_lbtest_prepare_rings(struct ice_vsi *vsi)
|
||||||
if (status)
|
if (status)
|
||||||
goto err_setup_rx_ring;
|
goto err_setup_rx_ring;
|
||||||
|
|
||||||
status = ice_vsi_start_rx_rings(vsi);
|
status = ice_vsi_start_all_rx_rings(vsi);
|
||||||
if (status)
|
if (status)
|
||||||
goto err_start_rx_ring;
|
goto err_start_rx_ring;
|
||||||
|
|
||||||
|
@ -494,7 +494,7 @@ static int ice_lbtest_disable_rings(struct ice_vsi *vsi)
|
||||||
netdev_err(vsi->netdev, "Failed to stop Tx rings, VSI %d error %d\n",
|
netdev_err(vsi->netdev, "Failed to stop Tx rings, VSI %d error %d\n",
|
||||||
vsi->vsi_num, status);
|
vsi->vsi_num, status);
|
||||||
|
|
||||||
status = ice_vsi_stop_rx_rings(vsi);
|
status = ice_vsi_stop_all_rx_rings(vsi);
|
||||||
if (status)
|
if (status)
|
||||||
netdev_err(vsi->netdev, "Failed to stop Rx rings, VSI %d error %d\n",
|
netdev_err(vsi->netdev, "Failed to stop Rx rings, VSI %d error %d\n",
|
||||||
vsi->vsi_num, status);
|
vsi->vsi_num, status);
|
||||||
|
@ -1091,7 +1091,6 @@ ice_get_fecparam(struct net_device *netdev, struct ethtool_fecparam *fecparam)
|
||||||
fecparam->active_fec = ETHTOOL_FEC_BASER;
|
fecparam->active_fec = ETHTOOL_FEC_BASER;
|
||||||
break;
|
break;
|
||||||
case ICE_AQ_LINK_25G_RS_528_FEC_EN:
|
case ICE_AQ_LINK_25G_RS_528_FEC_EN:
|
||||||
/* fall through */
|
|
||||||
case ICE_AQ_LINK_25G_RS_544_FEC_EN:
|
case ICE_AQ_LINK_25G_RS_544_FEC_EN:
|
||||||
fecparam->active_fec = ETHTOOL_FEC_RS;
|
fecparam->active_fec = ETHTOOL_FEC_RS;
|
||||||
break;
|
break;
|
||||||
|
@ -1781,7 +1780,6 @@ ice_get_settings_link_up(struct ethtool_link_ksettings *ks,
|
||||||
Asym_Pause);
|
Asym_Pause);
|
||||||
break;
|
break;
|
||||||
case ICE_FC_PFC:
|
case ICE_FC_PFC:
|
||||||
/* fall through */
|
|
||||||
default:
|
default:
|
||||||
ethtool_link_ksettings_del_link_mode(ks, lp_advertising, Pause);
|
ethtool_link_ksettings_del_link_mode(ks, lp_advertising, Pause);
|
||||||
ethtool_link_ksettings_del_link_mode(ks, lp_advertising,
|
ethtool_link_ksettings_del_link_mode(ks, lp_advertising,
|
||||||
|
|
|
@ -286,6 +286,8 @@
|
||||||
#define GL_PWR_MODE_CTL 0x000B820C
|
#define GL_PWR_MODE_CTL 0x000B820C
|
||||||
#define GL_PWR_MODE_CTL_CAR_MAX_BW_S 30
|
#define GL_PWR_MODE_CTL_CAR_MAX_BW_S 30
|
||||||
#define GL_PWR_MODE_CTL_CAR_MAX_BW_M ICE_M(0x3, 30)
|
#define GL_PWR_MODE_CTL_CAR_MAX_BW_M ICE_M(0x3, 30)
|
||||||
|
#define GLDCB_RTCTQ_RXQNUM_S 0
|
||||||
|
#define GLDCB_RTCTQ_RXQNUM_M ICE_M(0x7FF, 0)
|
||||||
#define GLPRT_BPRCL(_i) (0x00381380 + ((_i) * 8))
|
#define GLPRT_BPRCL(_i) (0x00381380 + ((_i) * 8))
|
||||||
#define GLPRT_BPTCL(_i) (0x00381240 + ((_i) * 8))
|
#define GLPRT_BPTCL(_i) (0x00381240 + ((_i) * 8))
|
||||||
#define GLPRT_CRCERRS(_i) (0x00380100 + ((_i) * 8))
|
#define GLPRT_CRCERRS(_i) (0x00380100 + ((_i) * 8))
|
||||||
|
|
|
@ -26,16 +26,26 @@ const char *ice_vsi_type_str(enum ice_vsi_type type)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ice_vsi_ctrl_rx_rings - Start or stop a VSI's Rx rings
|
* ice_vsi_ctrl_all_rx_rings - Start or stop a VSI's Rx rings
|
||||||
* @vsi: the VSI being configured
|
* @vsi: the VSI being configured
|
||||||
* @ena: start or stop the Rx rings
|
* @ena: start or stop the Rx rings
|
||||||
|
*
|
||||||
|
* First enable/disable all of the Rx rings, flush any remaining writes, and
|
||||||
|
* then verify that they have all been enabled/disabled successfully. This will
|
||||||
|
* let all of the register writes complete when enabling/disabling the Rx rings
|
||||||
|
* before waiting for the change in hardware to complete.
|
||||||
*/
|
*/
|
||||||
static int ice_vsi_ctrl_rx_rings(struct ice_vsi *vsi, bool ena)
|
static int ice_vsi_ctrl_all_rx_rings(struct ice_vsi *vsi, bool ena)
|
||||||
{
|
{
|
||||||
int i, ret = 0;
|
int i, ret = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < vsi->num_rxq; i++)
|
||||||
|
ice_vsi_ctrl_one_rx_ring(vsi, ena, i, false);
|
||||||
|
|
||||||
|
ice_flush(&vsi->back->hw);
|
||||||
|
|
||||||
for (i = 0; i < vsi->num_rxq; i++) {
|
for (i = 0; i < vsi->num_rxq; i++) {
|
||||||
ret = ice_vsi_ctrl_rx_ring(vsi, ena, i);
|
ret = ice_vsi_wait_one_rx_ring(vsi, ena, i);
|
||||||
if (ret)
|
if (ret)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -111,7 +121,6 @@ static void ice_vsi_set_num_desc(struct ice_vsi *vsi)
|
||||||
{
|
{
|
||||||
switch (vsi->type) {
|
switch (vsi->type) {
|
||||||
case ICE_VSI_PF:
|
case ICE_VSI_PF:
|
||||||
/* fall through */
|
|
||||||
case ICE_VSI_LB:
|
case ICE_VSI_LB:
|
||||||
vsi->num_rx_desc = ICE_DFLT_NUM_RX_DESC;
|
vsi->num_rx_desc = ICE_DFLT_NUM_RX_DESC;
|
||||||
vsi->num_tx_desc = ICE_DFLT_NUM_TX_DESC;
|
vsi->num_tx_desc = ICE_DFLT_NUM_TX_DESC;
|
||||||
|
@ -433,7 +442,7 @@ static int ice_vsi_get_qs(struct ice_vsi *vsi)
|
||||||
.scatter_count = ICE_MAX_SCATTER_TXQS,
|
.scatter_count = ICE_MAX_SCATTER_TXQS,
|
||||||
.vsi_map = vsi->txq_map,
|
.vsi_map = vsi->txq_map,
|
||||||
.vsi_map_offset = 0,
|
.vsi_map_offset = 0,
|
||||||
.mapping_mode = vsi->tx_mapping_mode
|
.mapping_mode = ICE_VSI_MAP_CONTIG
|
||||||
};
|
};
|
||||||
struct ice_qs_cfg rx_qs_cfg = {
|
struct ice_qs_cfg rx_qs_cfg = {
|
||||||
.qs_mutex = &pf->avail_q_mutex,
|
.qs_mutex = &pf->avail_q_mutex,
|
||||||
|
@ -443,18 +452,21 @@ static int ice_vsi_get_qs(struct ice_vsi *vsi)
|
||||||
.scatter_count = ICE_MAX_SCATTER_RXQS,
|
.scatter_count = ICE_MAX_SCATTER_RXQS,
|
||||||
.vsi_map = vsi->rxq_map,
|
.vsi_map = vsi->rxq_map,
|
||||||
.vsi_map_offset = 0,
|
.vsi_map_offset = 0,
|
||||||
.mapping_mode = vsi->rx_mapping_mode
|
.mapping_mode = ICE_VSI_MAP_CONTIG
|
||||||
};
|
};
|
||||||
int ret = 0;
|
int ret;
|
||||||
|
|
||||||
vsi->tx_mapping_mode = ICE_VSI_MAP_CONTIG;
|
|
||||||
vsi->rx_mapping_mode = ICE_VSI_MAP_CONTIG;
|
|
||||||
|
|
||||||
ret = __ice_vsi_get_qs(&tx_qs_cfg);
|
ret = __ice_vsi_get_qs(&tx_qs_cfg);
|
||||||
if (!ret)
|
if (ret)
|
||||||
ret = __ice_vsi_get_qs(&rx_qs_cfg);
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
vsi->tx_mapping_mode = tx_qs_cfg.mapping_mode;
|
||||||
|
|
||||||
|
ret = __ice_vsi_get_qs(&rx_qs_cfg);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
vsi->rx_mapping_mode = rx_qs_cfg.mapping_mode;
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -804,7 +816,6 @@ static int ice_vsi_init(struct ice_vsi *vsi, bool init_vsi)
|
||||||
ctxt->info = vsi->info;
|
ctxt->info = vsi->info;
|
||||||
switch (vsi->type) {
|
switch (vsi->type) {
|
||||||
case ICE_VSI_LB:
|
case ICE_VSI_LB:
|
||||||
/* fall through */
|
|
||||||
case ICE_VSI_PF:
|
case ICE_VSI_PF:
|
||||||
ctxt->flags = ICE_AQ_VSI_TYPE_PF;
|
ctxt->flags = ICE_AQ_VSI_TYPE_PF;
|
||||||
break;
|
break;
|
||||||
|
@ -1348,7 +1359,9 @@ int ice_vsi_add_vlan(struct ice_vsi *vsi, u16 vid)
|
||||||
list_add(&tmp->list_entry, &tmp_add_list);
|
list_add(&tmp->list_entry, &tmp_add_list);
|
||||||
|
|
||||||
status = ice_add_vlan(&pf->hw, &tmp_add_list);
|
status = ice_add_vlan(&pf->hw, &tmp_add_list);
|
||||||
if (status) {
|
if (!status) {
|
||||||
|
vsi->num_vlan++;
|
||||||
|
} else {
|
||||||
err = -ENODEV;
|
err = -ENODEV;
|
||||||
dev_err(dev, "Failure Adding VLAN %d on VSI %i\n", vid,
|
dev_err(dev, "Failure Adding VLAN %d on VSI %i\n", vid,
|
||||||
vsi->vsi_num);
|
vsi->vsi_num);
|
||||||
|
@ -1390,10 +1403,12 @@ int ice_vsi_kill_vlan(struct ice_vsi *vsi, u16 vid)
|
||||||
list_add(&list->list_entry, &tmp_add_list);
|
list_add(&list->list_entry, &tmp_add_list);
|
||||||
|
|
||||||
status = ice_remove_vlan(&pf->hw, &tmp_add_list);
|
status = ice_remove_vlan(&pf->hw, &tmp_add_list);
|
||||||
if (status == ICE_ERR_DOES_NOT_EXIST) {
|
if (!status) {
|
||||||
|
vsi->num_vlan--;
|
||||||
|
} else if (status == ICE_ERR_DOES_NOT_EXIST) {
|
||||||
dev_dbg(dev, "Failed to remove VLAN %d on VSI %i, it does not exist, status: %d\n",
|
dev_dbg(dev, "Failed to remove VLAN %d on VSI %i, it does not exist, status: %d\n",
|
||||||
vid, vsi->vsi_num, status);
|
vid, vsi->vsi_num, status);
|
||||||
} else if (status) {
|
} else {
|
||||||
dev_err(dev, "Error removing VLAN %d on vsi %i error: %d\n",
|
dev_err(dev, "Error removing VLAN %d on vsi %i error: %d\n",
|
||||||
vid, vsi->vsi_num, status);
|
vid, vsi->vsi_num, status);
|
||||||
err = -EIO;
|
err = -EIO;
|
||||||
|
@ -1678,25 +1693,25 @@ int ice_vsi_manage_vlan_stripping(struct ice_vsi *vsi, bool ena)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ice_vsi_start_rx_rings - start VSI's Rx rings
|
* ice_vsi_start_all_rx_rings - start/enable all of a VSI's Rx rings
|
||||||
* @vsi: the VSI whose rings are to be started
|
* @vsi: the VSI whose rings are to be enabled
|
||||||
*
|
*
|
||||||
* Returns 0 on success and a negative value on error
|
* Returns 0 on success and a negative value on error
|
||||||
*/
|
*/
|
||||||
int ice_vsi_start_rx_rings(struct ice_vsi *vsi)
|
int ice_vsi_start_all_rx_rings(struct ice_vsi *vsi)
|
||||||
{
|
{
|
||||||
return ice_vsi_ctrl_rx_rings(vsi, true);
|
return ice_vsi_ctrl_all_rx_rings(vsi, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ice_vsi_stop_rx_rings - stop VSI's Rx rings
|
* ice_vsi_stop_all_rx_rings - stop/disable all of a VSI's Rx rings
|
||||||
* @vsi: the VSI
|
* @vsi: the VSI whose rings are to be disabled
|
||||||
*
|
*
|
||||||
* Returns 0 on success and a negative value on error
|
* Returns 0 on success and a negative value on error
|
||||||
*/
|
*/
|
||||||
int ice_vsi_stop_rx_rings(struct ice_vsi *vsi)
|
int ice_vsi_stop_all_rx_rings(struct ice_vsi *vsi)
|
||||||
{
|
{
|
||||||
return ice_vsi_ctrl_rx_rings(vsi, false);
|
return ice_vsi_ctrl_all_rx_rings(vsi, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1755,6 +1770,26 @@ int ice_vsi_stop_xdp_tx_rings(struct ice_vsi *vsi)
|
||||||
return ice_vsi_stop_tx_rings(vsi, ICE_NO_RESET, 0, vsi->xdp_rings);
|
return ice_vsi_stop_tx_rings(vsi, ICE_NO_RESET, 0, vsi->xdp_rings);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ice_vsi_is_vlan_pruning_ena - check if VLAN pruning is enabled or not
|
||||||
|
* @vsi: VSI to check whether or not VLAN pruning is enabled.
|
||||||
|
*
|
||||||
|
* returns true if Rx VLAN pruning and Tx VLAN anti-spoof is enabled and false
|
||||||
|
* otherwise.
|
||||||
|
*/
|
||||||
|
bool ice_vsi_is_vlan_pruning_ena(struct ice_vsi *vsi)
|
||||||
|
{
|
||||||
|
u8 rx_pruning = ICE_AQ_VSI_SW_FLAG_RX_VLAN_PRUNE_ENA;
|
||||||
|
u8 tx_pruning = ICE_AQ_VSI_SEC_TX_VLAN_PRUNE_ENA <<
|
||||||
|
ICE_AQ_VSI_SEC_TX_PRUNE_ENA_S;
|
||||||
|
|
||||||
|
if (!vsi)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return ((vsi->info.sw_flags2 & rx_pruning) &&
|
||||||
|
(vsi->info.sec_flags & tx_pruning));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ice_cfg_vlan_pruning - enable or disable VLAN pruning on the VSI
|
* ice_cfg_vlan_pruning - enable or disable VLAN pruning on the VSI
|
||||||
* @vsi: VSI to enable or disable VLAN pruning on
|
* @vsi: VSI to enable or disable VLAN pruning on
|
||||||
|
@ -2025,6 +2060,17 @@ ice_vsi_setup(struct ice_pf *pf, struct ice_port_info *pi,
|
||||||
if (ret)
|
if (ret)
|
||||||
goto unroll_vector_base;
|
goto unroll_vector_base;
|
||||||
|
|
||||||
|
/* Always add VLAN ID 0 switch rule by default. This is needed
|
||||||
|
* in order to allow all untagged and 0 tagged priority traffic
|
||||||
|
* if Rx VLAN pruning is enabled. Also there are cases where we
|
||||||
|
* don't get the call to add VLAN 0 via ice_vlan_rx_add_vid()
|
||||||
|
* so this handles those cases (i.e. adding the PF to a bridge
|
||||||
|
* without the 8021q module loaded).
|
||||||
|
*/
|
||||||
|
ret = ice_vsi_add_vlan(vsi, 0);
|
||||||
|
if (ret)
|
||||||
|
goto unroll_clear_rings;
|
||||||
|
|
||||||
ice_vsi_map_rings_to_vectors(vsi);
|
ice_vsi_map_rings_to_vectors(vsi);
|
||||||
|
|
||||||
/* Do not exit if configuring RSS had an issue, at least
|
/* Do not exit if configuring RSS had an issue, at least
|
||||||
|
@ -2104,6 +2150,8 @@ ice_vsi_setup(struct ice_pf *pf, struct ice_port_info *pi,
|
||||||
|
|
||||||
return vsi;
|
return vsi;
|
||||||
|
|
||||||
|
unroll_clear_rings:
|
||||||
|
ice_vsi_clear_rings(vsi);
|
||||||
unroll_vector_base:
|
unroll_vector_base:
|
||||||
/* reclaim SW interrupts back to the common pool */
|
/* reclaim SW interrupts back to the common pool */
|
||||||
ice_free_res(pf->irq_tracker, vsi->base_vector, vsi->idx);
|
ice_free_res(pf->irq_tracker, vsi->base_vector, vsi->idx);
|
||||||
|
|
|
@ -30,9 +30,9 @@ int ice_vsi_manage_vlan_insertion(struct ice_vsi *vsi);
|
||||||
|
|
||||||
int ice_vsi_manage_vlan_stripping(struct ice_vsi *vsi, bool ena);
|
int ice_vsi_manage_vlan_stripping(struct ice_vsi *vsi, bool ena);
|
||||||
|
|
||||||
int ice_vsi_start_rx_rings(struct ice_vsi *vsi);
|
int ice_vsi_start_all_rx_rings(struct ice_vsi *vsi);
|
||||||
|
|
||||||
int ice_vsi_stop_rx_rings(struct ice_vsi *vsi);
|
int ice_vsi_stop_all_rx_rings(struct ice_vsi *vsi);
|
||||||
|
|
||||||
int
|
int
|
||||||
ice_vsi_stop_lan_tx_rings(struct ice_vsi *vsi, enum ice_disq_rst_src rst_src,
|
ice_vsi_stop_lan_tx_rings(struct ice_vsi *vsi, enum ice_disq_rst_src rst_src,
|
||||||
|
@ -42,6 +42,8 @@ int ice_vsi_cfg_xdp_txqs(struct ice_vsi *vsi);
|
||||||
|
|
||||||
int ice_vsi_stop_xdp_tx_rings(struct ice_vsi *vsi);
|
int ice_vsi_stop_xdp_tx_rings(struct ice_vsi *vsi);
|
||||||
|
|
||||||
|
bool ice_vsi_is_vlan_pruning_ena(struct ice_vsi *vsi);
|
||||||
|
|
||||||
int ice_cfg_vlan_pruning(struct ice_vsi *vsi, bool ena, bool vlan_promisc);
|
int ice_cfg_vlan_pruning(struct ice_vsi *vsi, bool ena, bool vlan_promisc);
|
||||||
|
|
||||||
void ice_cfg_sw_lldp(struct ice_vsi *vsi, bool tx, bool create);
|
void ice_cfg_sw_lldp(struct ice_vsi *vsi, bool tx, bool create);
|
||||||
|
|
|
@ -706,7 +706,6 @@ void ice_print_link_msg(struct ice_vsi *vsi, bool isup)
|
||||||
/* Get FEC mode based on negotiated link info */
|
/* Get FEC mode based on negotiated link info */
|
||||||
switch (vsi->port_info->phy.link_info.fec_info) {
|
switch (vsi->port_info->phy.link_info.fec_info) {
|
||||||
case ICE_AQ_LINK_25G_RS_528_FEC_EN:
|
case ICE_AQ_LINK_25G_RS_528_FEC_EN:
|
||||||
/* fall through */
|
|
||||||
case ICE_AQ_LINK_25G_RS_544_FEC_EN:
|
case ICE_AQ_LINK_25G_RS_544_FEC_EN:
|
||||||
fec = "RS-FEC";
|
fec = "RS-FEC";
|
||||||
break;
|
break;
|
||||||
|
@ -1029,6 +1028,9 @@ static int __ice_clean_ctrlq(struct ice_pf *pf, enum ice_ctl_q q_type)
|
||||||
if (ice_handle_link_event(pf, &event))
|
if (ice_handle_link_event(pf, &event))
|
||||||
dev_err(dev, "Could not handle link event\n");
|
dev_err(dev, "Could not handle link event\n");
|
||||||
break;
|
break;
|
||||||
|
case ice_aqc_opc_event_lan_overflow:
|
||||||
|
ice_vf_lan_overflow_event(pf, &event);
|
||||||
|
break;
|
||||||
case ice_mbx_opc_send_msg_to_pf:
|
case ice_mbx_opc_send_msg_to_pf:
|
||||||
ice_vc_process_vf_msg(pf, &event);
|
ice_vc_process_vf_msg(pf, &event);
|
||||||
break;
|
break;
|
||||||
|
@ -2461,16 +2463,19 @@ ice_vlan_rx_add_vid(struct net_device *netdev, __always_unused __be16 proto,
|
||||||
if (vsi->info.pvid)
|
if (vsi->info.pvid)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
/* Enable VLAN pruning when VLAN 0 is added */
|
/* VLAN 0 is added by default during load/reset */
|
||||||
if (unlikely(!vid)) {
|
if (!vid)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* Enable VLAN pruning when a VLAN other than 0 is added */
|
||||||
|
if (!ice_vsi_is_vlan_pruning_ena(vsi)) {
|
||||||
ret = ice_cfg_vlan_pruning(vsi, true, false);
|
ret = ice_cfg_vlan_pruning(vsi, true, false);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Add all VLAN IDs including 0 to the switch filter. VLAN ID 0 is
|
/* Add a switch rule for this VLAN ID so its corresponding VLAN tagged
|
||||||
* needed to continue allowing all untagged packets since VLAN prune
|
* packets aren't pruned by the device's internal switch on Rx
|
||||||
* list is applied to all packets by the switch
|
|
||||||
*/
|
*/
|
||||||
ret = ice_vsi_add_vlan(vsi, vid);
|
ret = ice_vsi_add_vlan(vsi, vid);
|
||||||
if (!ret) {
|
if (!ret) {
|
||||||
|
@ -2500,6 +2505,10 @@ ice_vlan_rx_kill_vid(struct net_device *netdev, __always_unused __be16 proto,
|
||||||
if (vsi->info.pvid)
|
if (vsi->info.pvid)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
|
/* don't allow removal of VLAN 0 */
|
||||||
|
if (!vid)
|
||||||
|
return 0;
|
||||||
|
|
||||||
/* Make sure ice_vsi_kill_vlan is successful before updating VLAN
|
/* Make sure ice_vsi_kill_vlan is successful before updating VLAN
|
||||||
* information
|
* information
|
||||||
*/
|
*/
|
||||||
|
@ -2507,8 +2516,8 @@ ice_vlan_rx_kill_vid(struct net_device *netdev, __always_unused __be16 proto,
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
/* Disable VLAN pruning when VLAN 0 is removed */
|
/* Disable pruning when VLAN 0 is the only VLAN rule */
|
||||||
if (unlikely(!vid))
|
if (vsi->num_vlan == 1 && ice_vsi_is_vlan_pruning_ena(vsi))
|
||||||
ret = ice_cfg_vlan_pruning(vsi, false, false);
|
ret = ice_cfg_vlan_pruning(vsi, false, false);
|
||||||
|
|
||||||
vsi->vlan_ena = false;
|
vsi->vlan_ena = false;
|
||||||
|
@ -2945,7 +2954,6 @@ ice_log_pkg_init(struct ice_hw *hw, enum ice_status *status)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ICE_ERR_BUF_TOO_SHORT:
|
case ICE_ERR_BUF_TOO_SHORT:
|
||||||
/* fall-through */
|
|
||||||
case ICE_ERR_CFG:
|
case ICE_ERR_CFG:
|
||||||
dev_err(dev, "The DDP package file is invalid. Entering Safe Mode.\n");
|
dev_err(dev, "The DDP package file is invalid. Entering Safe Mode.\n");
|
||||||
break;
|
break;
|
||||||
|
@ -2977,7 +2985,7 @@ ice_log_pkg_init(struct ice_hw *hw, enum ice_status *status)
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/* fall-through */
|
fallthrough;
|
||||||
default:
|
default:
|
||||||
dev_err(dev, "An unknown error (%d) occurred when loading the DDP package. Entering Safe Mode.\n",
|
dev_err(dev, "An unknown error (%d) occurred when loading the DDP package. Entering Safe Mode.\n",
|
||||||
*status);
|
*status);
|
||||||
|
@ -3961,7 +3969,7 @@ static int ice_up_complete(struct ice_vsi *vsi)
|
||||||
* Tx queue group list was configured and the context bits were
|
* Tx queue group list was configured and the context bits were
|
||||||
* programmed using ice_vsi_cfg_txqs
|
* programmed using ice_vsi_cfg_txqs
|
||||||
*/
|
*/
|
||||||
err = ice_vsi_start_rx_rings(vsi);
|
err = ice_vsi_start_all_rx_rings(vsi);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
|
@ -4340,7 +4348,7 @@ int ice_down(struct ice_vsi *vsi)
|
||||||
vsi->vsi_num, tx_err);
|
vsi->vsi_num, tx_err);
|
||||||
}
|
}
|
||||||
|
|
||||||
rx_err = ice_vsi_stop_rx_rings(vsi);
|
rx_err = ice_vsi_stop_all_rx_rings(vsi);
|
||||||
if (rx_err)
|
if (rx_err)
|
||||||
netdev_err(vsi->netdev, "Failed stop Rx rings, VSI %d error %d\n",
|
netdev_err(vsi->netdev, "Failed stop Rx rings, VSI %d error %d\n",
|
||||||
vsi->vsi_num, rx_err);
|
vsi->vsi_num, rx_err);
|
||||||
|
@ -5027,6 +5035,7 @@ ice_bridge_setlink(struct net_device *dev, struct nlmsghdr *nlh,
|
||||||
/**
|
/**
|
||||||
* ice_tx_timeout - Respond to a Tx Hang
|
* ice_tx_timeout - Respond to a Tx Hang
|
||||||
* @netdev: network interface device structure
|
* @netdev: network interface device structure
|
||||||
|
* @txqueue: Tx queue
|
||||||
*/
|
*/
|
||||||
static void ice_tx_timeout(struct net_device *netdev, unsigned int txqueue)
|
static void ice_tx_timeout(struct net_device *netdev, unsigned int txqueue)
|
||||||
{
|
{
|
||||||
|
|
|
@ -121,9 +121,7 @@ u32 ice_conv_link_speed_to_virtchnl(bool adv_link_support, u16 link_speed)
|
||||||
speed = (u32)VIRTCHNL_LINK_SPEED_25GB;
|
speed = (u32)VIRTCHNL_LINK_SPEED_25GB;
|
||||||
break;
|
break;
|
||||||
case ICE_AQ_LINK_SPEED_40GB:
|
case ICE_AQ_LINK_SPEED_40GB:
|
||||||
/* fall through */
|
|
||||||
case ICE_AQ_LINK_SPEED_50GB:
|
case ICE_AQ_LINK_SPEED_50GB:
|
||||||
/* fall through */
|
|
||||||
case ICE_AQ_LINK_SPEED_100GB:
|
case ICE_AQ_LINK_SPEED_100GB:
|
||||||
speed = (u32)VIRTCHNL_LINK_SPEED_40GB;
|
speed = (u32)VIRTCHNL_LINK_SPEED_40GB;
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -760,7 +760,7 @@ ice_fill_sw_rule(struct ice_hw *hw, struct ice_fltr_info *f_info,
|
||||||
break;
|
break;
|
||||||
case ICE_SW_LKUP_ETHERTYPE_MAC:
|
case ICE_SW_LKUP_ETHERTYPE_MAC:
|
||||||
daddr = f_info->l_data.ethertype_mac.mac_addr;
|
daddr = f_info->l_data.ethertype_mac.mac_addr;
|
||||||
/* fall-through */
|
fallthrough;
|
||||||
case ICE_SW_LKUP_ETHERTYPE:
|
case ICE_SW_LKUP_ETHERTYPE:
|
||||||
off = (__force __be16 *)(eth_hdr + ICE_ETH_ETHTYPE_OFFSET);
|
off = (__force __be16 *)(eth_hdr + ICE_ETH_ETHTYPE_OFFSET);
|
||||||
*off = cpu_to_be16(f_info->l_data.ethertype_mac.ethertype);
|
*off = cpu_to_be16(f_info->l_data.ethertype_mac.ethertype);
|
||||||
|
@ -771,7 +771,7 @@ ice_fill_sw_rule(struct ice_hw *hw, struct ice_fltr_info *f_info,
|
||||||
break;
|
break;
|
||||||
case ICE_SW_LKUP_PROMISC_VLAN:
|
case ICE_SW_LKUP_PROMISC_VLAN:
|
||||||
vlan_id = f_info->l_data.mac_vlan.vlan_id;
|
vlan_id = f_info->l_data.mac_vlan.vlan_id;
|
||||||
/* fall-through */
|
fallthrough;
|
||||||
case ICE_SW_LKUP_PROMISC:
|
case ICE_SW_LKUP_PROMISC:
|
||||||
daddr = f_info->l_data.mac_vlan.mac_addr;
|
daddr = f_info->l_data.mac_vlan.mac_addr;
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -453,10 +453,10 @@ ice_run_xdp(struct ice_ring *rx_ring, struct xdp_buff *xdp,
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
bpf_warn_invalid_xdp_action(act);
|
bpf_warn_invalid_xdp_action(act);
|
||||||
/* fallthrough -- not supported action */
|
fallthrough;
|
||||||
case XDP_ABORTED:
|
case XDP_ABORTED:
|
||||||
trace_xdp_exception(rx_ring->netdev, xdp_prog, act);
|
trace_xdp_exception(rx_ring->netdev, xdp_prog, act);
|
||||||
/* fallthrough -- handle aborts by dropping frame */
|
fallthrough;
|
||||||
case XDP_DROP:
|
case XDP_DROP:
|
||||||
result = ICE_XDP_CONSUMED;
|
result = ICE_XDP_CONSUMED;
|
||||||
break;
|
break;
|
||||||
|
@ -1188,7 +1188,6 @@ ice_adjust_itr_by_size_and_speed(struct ice_port_info *port_info,
|
||||||
avg_pkt_size + 640);
|
avg_pkt_size + 640);
|
||||||
break;
|
break;
|
||||||
case ICE_AQ_LINK_SPEED_10GB:
|
case ICE_AQ_LINK_SPEED_10GB:
|
||||||
/* fall through */
|
|
||||||
default:
|
default:
|
||||||
itr += DIV_ROUND_UP(170 * (avg_pkt_size + 24),
|
itr += DIV_ROUND_UP(170 * (avg_pkt_size + 24),
|
||||||
avg_pkt_size + 640);
|
avg_pkt_size + 640);
|
||||||
|
|
|
@ -90,6 +90,39 @@ ice_set_pfe_link(struct ice_vf *vf, struct virtchnl_pf_event *pfe,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ice_vf_has_no_qs_ena - check if the VF has any Rx or Tx queues enabled
|
||||||
|
* @vf: the VF to check
|
||||||
|
*
|
||||||
|
* Returns true if the VF has no Rx and no Tx queues enabled and returns false
|
||||||
|
* otherwise
|
||||||
|
*/
|
||||||
|
static bool ice_vf_has_no_qs_ena(struct ice_vf *vf)
|
||||||
|
{
|
||||||
|
return (!bitmap_weight(vf->rxq_ena, ICE_MAX_BASE_QS_PER_VF) &&
|
||||||
|
!bitmap_weight(vf->txq_ena, ICE_MAX_BASE_QS_PER_VF));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ice_is_vf_link_up - check if the VF's link is up
|
||||||
|
* @vf: VF to check if link is up
|
||||||
|
*/
|
||||||
|
static bool ice_is_vf_link_up(struct ice_vf *vf)
|
||||||
|
{
|
||||||
|
struct ice_pf *pf = vf->pf;
|
||||||
|
|
||||||
|
if (ice_check_vf_init(pf, vf))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (ice_vf_has_no_qs_ena(vf))
|
||||||
|
return false;
|
||||||
|
else if (vf->link_forced)
|
||||||
|
return vf->link_up;
|
||||||
|
else
|
||||||
|
return pf->hw.port_info->phy.link_info.link_info &
|
||||||
|
ICE_AQ_LINK_UP;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ice_vc_notify_vf_link_state - Inform a VF of link status
|
* ice_vc_notify_vf_link_state - Inform a VF of link status
|
||||||
* @vf: pointer to the VF structure
|
* @vf: pointer to the VF structure
|
||||||
|
@ -99,28 +132,16 @@ ice_set_pfe_link(struct ice_vf *vf, struct virtchnl_pf_event *pfe,
|
||||||
static void ice_vc_notify_vf_link_state(struct ice_vf *vf)
|
static void ice_vc_notify_vf_link_state(struct ice_vf *vf)
|
||||||
{
|
{
|
||||||
struct virtchnl_pf_event pfe = { 0 };
|
struct virtchnl_pf_event pfe = { 0 };
|
||||||
struct ice_link_status *ls;
|
struct ice_hw *hw = &vf->pf->hw;
|
||||||
struct ice_pf *pf = vf->pf;
|
|
||||||
struct ice_hw *hw;
|
|
||||||
|
|
||||||
hw = &pf->hw;
|
|
||||||
ls = &hw->port_info->phy.link_info;
|
|
||||||
|
|
||||||
pfe.event = VIRTCHNL_EVENT_LINK_CHANGE;
|
pfe.event = VIRTCHNL_EVENT_LINK_CHANGE;
|
||||||
pfe.severity = PF_EVENT_SEVERITY_INFO;
|
pfe.severity = PF_EVENT_SEVERITY_INFO;
|
||||||
|
|
||||||
/* Always report link is down if the VF queues aren't enabled */
|
if (ice_is_vf_link_up(vf))
|
||||||
if (!vf->num_qs_ena) {
|
ice_set_pfe_link(vf, &pfe,
|
||||||
|
hw->port_info->phy.link_info.link_speed, true);
|
||||||
|
else
|
||||||
ice_set_pfe_link(vf, &pfe, ICE_AQ_LINK_SPEED_UNKNOWN, false);
|
ice_set_pfe_link(vf, &pfe, ICE_AQ_LINK_SPEED_UNKNOWN, false);
|
||||||
} else if (vf->link_forced) {
|
|
||||||
u16 link_speed = vf->link_up ?
|
|
||||||
ls->link_speed : ICE_AQ_LINK_SPEED_UNKNOWN;
|
|
||||||
|
|
||||||
ice_set_pfe_link(vf, &pfe, link_speed, vf->link_up);
|
|
||||||
} else {
|
|
||||||
ice_set_pfe_link(vf, &pfe, ls->link_speed,
|
|
||||||
ls->link_info & ICE_AQ_LINK_UP);
|
|
||||||
}
|
|
||||||
|
|
||||||
ice_aq_send_msg_to_vf(hw, vf->vf_id, VIRTCHNL_OP_EVENT,
|
ice_aq_send_msg_to_vf(hw, vf->vf_id, VIRTCHNL_OP_EVENT,
|
||||||
VIRTCHNL_STATUS_SUCCESS, (u8 *)&pfe,
|
VIRTCHNL_STATUS_SUCCESS, (u8 *)&pfe,
|
||||||
|
@ -247,7 +268,6 @@ void ice_set_vf_state_qs_dis(struct ice_vf *vf)
|
||||||
/* Clear Rx/Tx enabled queues flag */
|
/* Clear Rx/Tx enabled queues flag */
|
||||||
bitmap_zero(vf->txq_ena, ICE_MAX_BASE_QS_PER_VF);
|
bitmap_zero(vf->txq_ena, ICE_MAX_BASE_QS_PER_VF);
|
||||||
bitmap_zero(vf->rxq_ena, ICE_MAX_BASE_QS_PER_VF);
|
bitmap_zero(vf->rxq_ena, ICE_MAX_BASE_QS_PER_VF);
|
||||||
vf->num_qs_ena = 0;
|
|
||||||
clear_bit(ICE_VF_STATE_QS_ENA, vf->vf_states);
|
clear_bit(ICE_VF_STATE_QS_ENA, vf->vf_states);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -263,7 +283,7 @@ static void ice_dis_vf_qs(struct ice_vf *vf)
|
||||||
vsi = pf->vsi[vf->lan_vsi_idx];
|
vsi = pf->vsi[vf->lan_vsi_idx];
|
||||||
|
|
||||||
ice_vsi_stop_lan_tx_rings(vsi, ICE_NO_RESET, vf->vf_id);
|
ice_vsi_stop_lan_tx_rings(vsi, ICE_NO_RESET, vf->vf_id);
|
||||||
ice_vsi_stop_rx_rings(vsi);
|
ice_vsi_stop_all_rx_rings(vsi);
|
||||||
ice_set_vf_state_qs_dis(vf);
|
ice_set_vf_state_qs_dis(vf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -406,44 +426,16 @@ static void ice_trigger_vf_reset(struct ice_vf *vf, bool is_vflr, bool is_pfr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* ice_vsi_set_pvid_fill_ctxt - Set VSI ctxt for add PVID
|
|
||||||
* @ctxt: the VSI ctxt to fill
|
|
||||||
* @vid: the VLAN ID to set as a PVID
|
|
||||||
*/
|
|
||||||
static void ice_vsi_set_pvid_fill_ctxt(struct ice_vsi_ctx *ctxt, u16 vid)
|
|
||||||
{
|
|
||||||
ctxt->info.vlan_flags = (ICE_AQ_VSI_VLAN_MODE_UNTAGGED |
|
|
||||||
ICE_AQ_VSI_PVLAN_INSERT_PVID |
|
|
||||||
ICE_AQ_VSI_VLAN_EMOD_STR);
|
|
||||||
ctxt->info.pvid = cpu_to_le16(vid);
|
|
||||||
ctxt->info.sw_flags2 |= ICE_AQ_VSI_SW_FLAG_RX_VLAN_PRUNE_ENA;
|
|
||||||
ctxt->info.valid_sections = cpu_to_le16(ICE_AQ_VSI_PROP_VLAN_VALID |
|
|
||||||
ICE_AQ_VSI_PROP_SW_VALID);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* ice_vsi_kill_pvid_fill_ctxt - Set VSI ctx for remove PVID
|
|
||||||
* @ctxt: the VSI ctxt to fill
|
|
||||||
*/
|
|
||||||
static void ice_vsi_kill_pvid_fill_ctxt(struct ice_vsi_ctx *ctxt)
|
|
||||||
{
|
|
||||||
ctxt->info.vlan_flags = ICE_AQ_VSI_VLAN_EMOD_NOTHING;
|
|
||||||
ctxt->info.vlan_flags |= ICE_AQ_VSI_VLAN_MODE_ALL;
|
|
||||||
ctxt->info.sw_flags2 &= ~ICE_AQ_VSI_SW_FLAG_RX_VLAN_PRUNE_ENA;
|
|
||||||
ctxt->info.valid_sections = cpu_to_le16(ICE_AQ_VSI_PROP_VLAN_VALID |
|
|
||||||
ICE_AQ_VSI_PROP_SW_VALID);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ice_vsi_manage_pvid - Enable or disable port VLAN for VSI
|
* ice_vsi_manage_pvid - Enable or disable port VLAN for VSI
|
||||||
* @vsi: the VSI to update
|
* @vsi: the VSI to update
|
||||||
* @vid: the VLAN ID to set as a PVID
|
* @pvid_info: VLAN ID and QoS used to set the PVID VSI context field
|
||||||
* @enable: true for enable PVID false for disable
|
* @enable: true for enable PVID false for disable
|
||||||
*/
|
*/
|
||||||
static int ice_vsi_manage_pvid(struct ice_vsi *vsi, u16 vid, bool enable)
|
static int ice_vsi_manage_pvid(struct ice_vsi *vsi, u16 pvid_info, bool enable)
|
||||||
{
|
{
|
||||||
struct ice_hw *hw = &vsi->back->hw;
|
struct ice_hw *hw = &vsi->back->hw;
|
||||||
|
struct ice_aqc_vsi_props *info;
|
||||||
struct ice_vsi_ctx *ctxt;
|
struct ice_vsi_ctx *ctxt;
|
||||||
enum ice_status status;
|
enum ice_status status;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
@ -453,20 +445,33 @@ static int ice_vsi_manage_pvid(struct ice_vsi *vsi, u16 vid, bool enable)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
ctxt->info = vsi->info;
|
ctxt->info = vsi->info;
|
||||||
if (enable)
|
info = &ctxt->info;
|
||||||
ice_vsi_set_pvid_fill_ctxt(ctxt, vid);
|
if (enable) {
|
||||||
else
|
info->vlan_flags = ICE_AQ_VSI_VLAN_MODE_UNTAGGED |
|
||||||
ice_vsi_kill_pvid_fill_ctxt(ctxt);
|
ICE_AQ_VSI_PVLAN_INSERT_PVID |
|
||||||
|
ICE_AQ_VSI_VLAN_EMOD_STR;
|
||||||
|
info->sw_flags2 |= ICE_AQ_VSI_SW_FLAG_RX_VLAN_PRUNE_ENA;
|
||||||
|
} else {
|
||||||
|
info->vlan_flags = ICE_AQ_VSI_VLAN_EMOD_NOTHING |
|
||||||
|
ICE_AQ_VSI_VLAN_MODE_ALL;
|
||||||
|
info->sw_flags2 &= ~ICE_AQ_VSI_SW_FLAG_RX_VLAN_PRUNE_ENA;
|
||||||
|
}
|
||||||
|
|
||||||
|
info->pvid = cpu_to_le16(pvid_info);
|
||||||
|
info->valid_sections = cpu_to_le16(ICE_AQ_VSI_PROP_VLAN_VALID |
|
||||||
|
ICE_AQ_VSI_PROP_SW_VALID);
|
||||||
|
|
||||||
status = ice_update_vsi(hw, vsi->idx, ctxt, NULL);
|
status = ice_update_vsi(hw, vsi->idx, ctxt, NULL);
|
||||||
if (status) {
|
if (status) {
|
||||||
dev_info(ice_pf_to_dev(vsi->back), "update VSI for port VLAN failed, err %d aq_err %d\n",
|
dev_info(ice_hw_to_dev(hw), "update VSI for port VLAN failed, err %d aq_err %d\n",
|
||||||
status, hw->adminq.sq_last_status);
|
status, hw->adminq.sq_last_status);
|
||||||
ret = -EIO;
|
ret = -EIO;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
vsi->info = ctxt->info;
|
vsi->info.vlan_flags = info->vlan_flags;
|
||||||
|
vsi->info.sw_flags2 = info->sw_flags2;
|
||||||
|
vsi->info.pvid = info->pvid;
|
||||||
out:
|
out:
|
||||||
kfree(ctxt);
|
kfree(ctxt);
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -533,9 +538,20 @@ static int ice_alloc_vsi_res(struct ice_vf *vf)
|
||||||
vf->lan_vsi_num = vsi->vsi_num;
|
vf->lan_vsi_num = vsi->vsi_num;
|
||||||
|
|
||||||
/* Check if port VLAN exist before, and restore it accordingly */
|
/* Check if port VLAN exist before, and restore it accordingly */
|
||||||
if (vf->port_vlan_id) {
|
if (vf->port_vlan_info) {
|
||||||
ice_vsi_manage_pvid(vsi, vf->port_vlan_id, true);
|
ice_vsi_manage_pvid(vsi, vf->port_vlan_info, true);
|
||||||
ice_vsi_add_vlan(vsi, vf->port_vlan_id & ICE_VLAN_M);
|
if (ice_vsi_add_vlan(vsi, vf->port_vlan_info & VLAN_VID_MASK))
|
||||||
|
dev_warn(ice_pf_to_dev(pf), "Failed to add Port VLAN %d filter for VF %d\n",
|
||||||
|
vf->port_vlan_info & VLAN_VID_MASK, vf->vf_id);
|
||||||
|
} else {
|
||||||
|
/* set VLAN 0 filter by default when no port VLAN is
|
||||||
|
* enabled. If a port VLAN is enabled we don't want
|
||||||
|
* untagged broadcast/multicast traffic seen on the VF
|
||||||
|
* interface.
|
||||||
|
*/
|
||||||
|
if (ice_vsi_add_vlan(vsi, 0))
|
||||||
|
dev_warn(ice_pf_to_dev(pf), "Failed to add VLAN 0 filter for VF %d, MDD events will trigger. Reset the VF, disable spoofchk, or enable 8021q module on the guest\n",
|
||||||
|
vf->vf_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
eth_broadcast_addr(broadcast);
|
eth_broadcast_addr(broadcast);
|
||||||
|
@ -943,17 +959,9 @@ static void ice_cleanup_and_realloc_vf(struct ice_vf *vf)
|
||||||
|
|
||||||
/* reallocate VF resources to finish resetting the VSI state */
|
/* reallocate VF resources to finish resetting the VSI state */
|
||||||
if (!ice_alloc_vf_res(vf)) {
|
if (!ice_alloc_vf_res(vf)) {
|
||||||
struct ice_vsi *vsi;
|
|
||||||
|
|
||||||
ice_ena_vf_mappings(vf);
|
ice_ena_vf_mappings(vf);
|
||||||
set_bit(ICE_VF_STATE_ACTIVE, vf->vf_states);
|
set_bit(ICE_VF_STATE_ACTIVE, vf->vf_states);
|
||||||
clear_bit(ICE_VF_STATE_DIS, vf->vf_states);
|
clear_bit(ICE_VF_STATE_DIS, vf->vf_states);
|
||||||
|
|
||||||
vsi = pf->vsi[vf->lan_vsi_idx];
|
|
||||||
if (ice_vsi_add_vlan(vsi, 0))
|
|
||||||
dev_warn(ice_pf_to_dev(pf),
|
|
||||||
"Failed to add VLAN 0 filter for VF %d, MDD events will trigger. Reset the VF, disable spoofchk, or enable 8021q module on the guest",
|
|
||||||
vf->vf_id);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Tell the VF driver the reset is done. This needs to be done only
|
/* Tell the VF driver the reset is done. This needs to be done only
|
||||||
|
@ -985,13 +993,13 @@ ice_vf_set_vsi_promisc(struct ice_vf *vf, struct ice_vsi *vsi, u8 promisc_m,
|
||||||
if (vsi->num_vlan) {
|
if (vsi->num_vlan) {
|
||||||
status = ice_set_vlan_vsi_promisc(hw, vsi->idx, promisc_m,
|
status = ice_set_vlan_vsi_promisc(hw, vsi->idx, promisc_m,
|
||||||
rm_promisc);
|
rm_promisc);
|
||||||
} else if (vf->port_vlan_id) {
|
} else if (vf->port_vlan_info) {
|
||||||
if (rm_promisc)
|
if (rm_promisc)
|
||||||
status = ice_clear_vsi_promisc(hw, vsi->idx, promisc_m,
|
status = ice_clear_vsi_promisc(hw, vsi->idx, promisc_m,
|
||||||
vf->port_vlan_id);
|
vf->port_vlan_info);
|
||||||
else
|
else
|
||||||
status = ice_set_vsi_promisc(hw, vsi->idx, promisc_m,
|
status = ice_set_vsi_promisc(hw, vsi->idx, promisc_m,
|
||||||
vf->port_vlan_id);
|
vf->port_vlan_info);
|
||||||
} else {
|
} else {
|
||||||
if (rm_promisc)
|
if (rm_promisc)
|
||||||
status = ice_clear_vsi_promisc(hw, vsi->idx, promisc_m,
|
status = ice_clear_vsi_promisc(hw, vsi->idx, promisc_m,
|
||||||
|
@ -1231,7 +1239,7 @@ static bool ice_reset_vf(struct ice_vf *vf, bool is_vflr)
|
||||||
*/
|
*/
|
||||||
if (test_bit(ICE_VF_STATE_UC_PROMISC, vf->vf_states) ||
|
if (test_bit(ICE_VF_STATE_UC_PROMISC, vf->vf_states) ||
|
||||||
test_bit(ICE_VF_STATE_MC_PROMISC, vf->vf_states)) {
|
test_bit(ICE_VF_STATE_MC_PROMISC, vf->vf_states)) {
|
||||||
if (vf->port_vlan_id || vsi->num_vlan)
|
if (vf->port_vlan_info || vsi->num_vlan)
|
||||||
promisc_m = ICE_UCAST_VLAN_PROMISC_BITS;
|
promisc_m = ICE_UCAST_VLAN_PROMISC_BITS;
|
||||||
else
|
else
|
||||||
promisc_m = ICE_UCAST_PROMISC_BITS;
|
promisc_m = ICE_UCAST_PROMISC_BITS;
|
||||||
|
@ -1517,6 +1525,72 @@ static void ice_vc_reset_vf(struct ice_vf *vf)
|
||||||
ice_reset_vf(vf, false);
|
ice_reset_vf(vf, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ice_get_vf_from_pfq - get the VF who owns the PF space queue passed in
|
||||||
|
* @pf: PF used to index all VFs
|
||||||
|
* @pfq: queue index relative to the PF's function space
|
||||||
|
*
|
||||||
|
* If no VF is found who owns the pfq then return NULL, otherwise return a
|
||||||
|
* pointer to the VF who owns the pfq
|
||||||
|
*/
|
||||||
|
static struct ice_vf *ice_get_vf_from_pfq(struct ice_pf *pf, u16 pfq)
|
||||||
|
{
|
||||||
|
int vf_id;
|
||||||
|
|
||||||
|
ice_for_each_vf(pf, vf_id) {
|
||||||
|
struct ice_vf *vf = &pf->vf[vf_id];
|
||||||
|
struct ice_vsi *vsi;
|
||||||
|
u16 rxq_idx;
|
||||||
|
|
||||||
|
vsi = pf->vsi[vf->lan_vsi_idx];
|
||||||
|
|
||||||
|
ice_for_each_rxq(vsi, rxq_idx)
|
||||||
|
if (vsi->rxq_map[rxq_idx] == pfq)
|
||||||
|
return vf;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ice_globalq_to_pfq - convert from global queue index to PF space queue index
|
||||||
|
* @pf: PF used for conversion
|
||||||
|
* @globalq: global queue index used to convert to PF space queue index
|
||||||
|
*/
|
||||||
|
static u32 ice_globalq_to_pfq(struct ice_pf *pf, u32 globalq)
|
||||||
|
{
|
||||||
|
return globalq - pf->hw.func_caps.common_cap.rxq_first_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ice_vf_lan_overflow_event - handle LAN overflow event for a VF
|
||||||
|
* @pf: PF that the LAN overflow event happened on
|
||||||
|
* @event: structure holding the event information for the LAN overflow event
|
||||||
|
*
|
||||||
|
* Determine if the LAN overflow event was caused by a VF queue. If it was not
|
||||||
|
* caused by a VF, do nothing. If a VF caused this LAN overflow event trigger a
|
||||||
|
* reset on the offending VF.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
ice_vf_lan_overflow_event(struct ice_pf *pf, struct ice_rq_event_info *event)
|
||||||
|
{
|
||||||
|
u32 gldcb_rtctq, queue;
|
||||||
|
struct ice_vf *vf;
|
||||||
|
|
||||||
|
gldcb_rtctq = le32_to_cpu(event->desc.params.lan_overflow.prtdcb_ruptq);
|
||||||
|
dev_dbg(ice_pf_to_dev(pf), "GLDCB_RTCTQ: 0x%08x\n", gldcb_rtctq);
|
||||||
|
|
||||||
|
/* event returns device global Rx queue number */
|
||||||
|
queue = (gldcb_rtctq & GLDCB_RTCTQ_RXQNUM_M) >>
|
||||||
|
GLDCB_RTCTQ_RXQNUM_S;
|
||||||
|
|
||||||
|
vf = ice_get_vf_from_pfq(pf, ice_globalq_to_pfq(pf, queue));
|
||||||
|
if (!vf)
|
||||||
|
return;
|
||||||
|
|
||||||
|
ice_vc_reset_vf(vf);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ice_vc_send_msg_to_vf - Send message to VF
|
* ice_vc_send_msg_to_vf - Send message to VF
|
||||||
* @vf: pointer to the VF info
|
* @vf: pointer to the VF info
|
||||||
|
@ -1996,6 +2070,22 @@ static int ice_vc_get_stats_msg(struct ice_vf *vf, u8 *msg)
|
||||||
(u8 *)&stats, sizeof(stats));
|
(u8 *)&stats, sizeof(stats));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ice_vc_validate_vqs_bitmaps - validate Rx/Tx queue bitmaps from VIRTCHNL
|
||||||
|
* @vqs: virtchnl_queue_select structure containing bitmaps to validate
|
||||||
|
*
|
||||||
|
* Return true on successful validation, else false
|
||||||
|
*/
|
||||||
|
static bool ice_vc_validate_vqs_bitmaps(struct virtchnl_queue_select *vqs)
|
||||||
|
{
|
||||||
|
if ((!vqs->rx_queues && !vqs->tx_queues) ||
|
||||||
|
vqs->rx_queues >= BIT(ICE_MAX_BASE_QS_PER_VF) ||
|
||||||
|
vqs->tx_queues >= BIT(ICE_MAX_BASE_QS_PER_VF))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ice_vc_ena_qs_msg
|
* ice_vc_ena_qs_msg
|
||||||
* @vf: pointer to the VF info
|
* @vf: pointer to the VF info
|
||||||
|
@ -2023,13 +2113,7 @@ static int ice_vc_ena_qs_msg(struct ice_vf *vf, u8 *msg)
|
||||||
goto error_param;
|
goto error_param;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!vqs->rx_queues && !vqs->tx_queues) {
|
if (!ice_vc_validate_vqs_bitmaps(vqs)) {
|
||||||
v_ret = VIRTCHNL_STATUS_ERR_PARAM;
|
|
||||||
goto error_param;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (vqs->rx_queues > ICE_MAX_BASE_QS_PER_VF ||
|
|
||||||
vqs->tx_queues > ICE_MAX_BASE_QS_PER_VF) {
|
|
||||||
v_ret = VIRTCHNL_STATUS_ERR_PARAM;
|
v_ret = VIRTCHNL_STATUS_ERR_PARAM;
|
||||||
goto error_param;
|
goto error_param;
|
||||||
}
|
}
|
||||||
|
@ -2055,7 +2139,7 @@ static int ice_vc_ena_qs_msg(struct ice_vf *vf, u8 *msg)
|
||||||
if (test_bit(vf_q_id, vf->rxq_ena))
|
if (test_bit(vf_q_id, vf->rxq_ena))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (ice_vsi_ctrl_rx_ring(vsi, true, vf_q_id)) {
|
if (ice_vsi_ctrl_one_rx_ring(vsi, true, vf_q_id, true)) {
|
||||||
dev_err(ice_pf_to_dev(vsi->back), "Failed to enable Rx ring %d on VSI %d\n",
|
dev_err(ice_pf_to_dev(vsi->back), "Failed to enable Rx ring %d on VSI %d\n",
|
||||||
vf_q_id, vsi->vsi_num);
|
vf_q_id, vsi->vsi_num);
|
||||||
v_ret = VIRTCHNL_STATUS_ERR_PARAM;
|
v_ret = VIRTCHNL_STATUS_ERR_PARAM;
|
||||||
|
@ -2063,7 +2147,6 @@ static int ice_vc_ena_qs_msg(struct ice_vf *vf, u8 *msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
set_bit(vf_q_id, vf->rxq_ena);
|
set_bit(vf_q_id, vf->rxq_ena);
|
||||||
vf->num_qs_ena++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
vsi = pf->vsi[vf->lan_vsi_idx];
|
vsi = pf->vsi[vf->lan_vsi_idx];
|
||||||
|
@ -2079,7 +2162,6 @@ static int ice_vc_ena_qs_msg(struct ice_vf *vf, u8 *msg)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
set_bit(vf_q_id, vf->txq_ena);
|
set_bit(vf_q_id, vf->txq_ena);
|
||||||
vf->num_qs_ena++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set flag to indicate that queues are enabled */
|
/* Set flag to indicate that queues are enabled */
|
||||||
|
@ -2121,7 +2203,7 @@ static int ice_vc_dis_qs_msg(struct ice_vf *vf, u8 *msg)
|
||||||
goto error_param;
|
goto error_param;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!vqs->rx_queues && !vqs->tx_queues) {
|
if (!ice_vc_validate_vqs_bitmaps(vqs)) {
|
||||||
v_ret = VIRTCHNL_STATUS_ERR_PARAM;
|
v_ret = VIRTCHNL_STATUS_ERR_PARAM;
|
||||||
goto error_param;
|
goto error_param;
|
||||||
}
|
}
|
||||||
|
@ -2166,13 +2248,22 @@ static int ice_vc_dis_qs_msg(struct ice_vf *vf, u8 *msg)
|
||||||
|
|
||||||
/* Clear enabled queues flag */
|
/* Clear enabled queues flag */
|
||||||
clear_bit(vf_q_id, vf->txq_ena);
|
clear_bit(vf_q_id, vf->txq_ena);
|
||||||
vf->num_qs_ena--;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (vqs->rx_queues) {
|
|
||||||
q_map = vqs->rx_queues;
|
q_map = vqs->rx_queues;
|
||||||
|
/* speed up Rx queue disable by batching them if possible */
|
||||||
|
if (q_map &&
|
||||||
|
bitmap_equal(&q_map, vf->rxq_ena, ICE_MAX_BASE_QS_PER_VF)) {
|
||||||
|
if (ice_vsi_stop_all_rx_rings(vsi)) {
|
||||||
|
dev_err(ice_pf_to_dev(vsi->back), "Failed to stop all Rx rings on VSI %d\n",
|
||||||
|
vsi->vsi_num);
|
||||||
|
v_ret = VIRTCHNL_STATUS_ERR_PARAM;
|
||||||
|
goto error_param;
|
||||||
|
}
|
||||||
|
|
||||||
|
bitmap_zero(vf->rxq_ena, ICE_MAX_BASE_QS_PER_VF);
|
||||||
|
} else if (q_map) {
|
||||||
for_each_set_bit(vf_q_id, &q_map, ICE_MAX_BASE_QS_PER_VF) {
|
for_each_set_bit(vf_q_id, &q_map, ICE_MAX_BASE_QS_PER_VF) {
|
||||||
if (!ice_vc_isvalid_q_id(vf, vqs->vsi_id, vf_q_id)) {
|
if (!ice_vc_isvalid_q_id(vf, vqs->vsi_id, vf_q_id)) {
|
||||||
v_ret = VIRTCHNL_STATUS_ERR_PARAM;
|
v_ret = VIRTCHNL_STATUS_ERR_PARAM;
|
||||||
|
@ -2183,7 +2274,8 @@ static int ice_vc_dis_qs_msg(struct ice_vf *vf, u8 *msg)
|
||||||
if (!test_bit(vf_q_id, vf->rxq_ena))
|
if (!test_bit(vf_q_id, vf->rxq_ena))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (ice_vsi_ctrl_rx_ring(vsi, false, vf_q_id)) {
|
if (ice_vsi_ctrl_one_rx_ring(vsi, false, vf_q_id,
|
||||||
|
true)) {
|
||||||
dev_err(ice_pf_to_dev(vsi->back), "Failed to stop Rx ring %d on VSI %d\n",
|
dev_err(ice_pf_to_dev(vsi->back), "Failed to stop Rx ring %d on VSI %d\n",
|
||||||
vf_q_id, vsi->vsi_num);
|
vf_q_id, vsi->vsi_num);
|
||||||
v_ret = VIRTCHNL_STATUS_ERR_PARAM;
|
v_ret = VIRTCHNL_STATUS_ERR_PARAM;
|
||||||
|
@ -2192,12 +2284,11 @@ static int ice_vc_dis_qs_msg(struct ice_vf *vf, u8 *msg)
|
||||||
|
|
||||||
/* Clear enabled queues flag */
|
/* Clear enabled queues flag */
|
||||||
clear_bit(vf_q_id, vf->rxq_ena);
|
clear_bit(vf_q_id, vf->rxq_ena);
|
||||||
vf->num_qs_ena--;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Clear enabled queues flag */
|
/* Clear enabled queues flag */
|
||||||
if (v_ret == VIRTCHNL_STATUS_SUCCESS && !vf->num_qs_ena)
|
if (v_ret == VIRTCHNL_STATUS_SUCCESS && ice_vf_has_no_qs_ena(vf))
|
||||||
clear_bit(ICE_VF_STATE_QS_ENA, vf->vf_states);
|
clear_bit(ICE_VF_STATE_QS_ENA, vf->vf_states);
|
||||||
|
|
||||||
error_param:
|
error_param:
|
||||||
|
@ -2691,19 +2782,20 @@ int
|
||||||
ice_set_vf_port_vlan(struct net_device *netdev, int vf_id, u16 vlan_id, u8 qos,
|
ice_set_vf_port_vlan(struct net_device *netdev, int vf_id, u16 vlan_id, u8 qos,
|
||||||
__be16 vlan_proto)
|
__be16 vlan_proto)
|
||||||
{
|
{
|
||||||
u16 vlanprio = vlan_id | (qos << ICE_VLAN_PRIORITY_S);
|
|
||||||
struct ice_pf *pf = ice_netdev_to_pf(netdev);
|
struct ice_pf *pf = ice_netdev_to_pf(netdev);
|
||||||
struct ice_vsi *vsi;
|
struct ice_vsi *vsi;
|
||||||
struct device *dev;
|
struct device *dev;
|
||||||
struct ice_vf *vf;
|
struct ice_vf *vf;
|
||||||
|
u16 vlanprio;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
dev = ice_pf_to_dev(pf);
|
dev = ice_pf_to_dev(pf);
|
||||||
if (ice_validate_vf_id(pf, vf_id))
|
if (ice_validate_vf_id(pf, vf_id))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
if (vlan_id > ICE_MAX_VLANID || qos > 7) {
|
if (vlan_id >= VLAN_N_VID || qos > 7) {
|
||||||
dev_err(dev, "Invalid VF Parameters\n");
|
dev_err(dev, "Invalid Port VLAN parameters for VF %d, ID %d, QoS %d\n",
|
||||||
|
vf_id, vlan_id, qos);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2717,42 +2809,54 @@ ice_set_vf_port_vlan(struct net_device *netdev, int vf_id, u16 vlan_id, u8 qos,
|
||||||
if (ice_check_vf_init(pf, vf))
|
if (ice_check_vf_init(pf, vf))
|
||||||
return -EBUSY;
|
return -EBUSY;
|
||||||
|
|
||||||
if (le16_to_cpu(vsi->info.pvid) == vlanprio) {
|
vlanprio = vlan_id | (qos << VLAN_PRIO_SHIFT);
|
||||||
|
|
||||||
|
if (vf->port_vlan_info == vlanprio) {
|
||||||
/* duplicate request, so just return success */
|
/* duplicate request, so just return success */
|
||||||
dev_dbg(dev, "Duplicate pvid %d request\n", vlanprio);
|
dev_dbg(dev, "Duplicate pvid %d request\n", vlanprio);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If PVID, then remove all filters on the old VLAN */
|
|
||||||
if (vsi->info.pvid)
|
|
||||||
ice_vsi_kill_vlan(vsi, (le16_to_cpu(vsi->info.pvid) &
|
|
||||||
VLAN_VID_MASK));
|
|
||||||
|
|
||||||
if (vlan_id || qos) {
|
if (vlan_id || qos) {
|
||||||
|
/* remove VLAN 0 filter set by default when transitioning from
|
||||||
|
* no port VLAN to a port VLAN. No change to old port VLAN on
|
||||||
|
* failure.
|
||||||
|
*/
|
||||||
|
ret = ice_vsi_kill_vlan(vsi, 0);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
ret = ice_vsi_manage_pvid(vsi, vlanprio, true);
|
ret = ice_vsi_manage_pvid(vsi, vlanprio, true);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto error_set_pvid;
|
return ret;
|
||||||
} else {
|
} else {
|
||||||
ice_vsi_manage_pvid(vsi, 0, false);
|
/* add VLAN 0 filter back when transitioning from port VLAN to
|
||||||
vsi->info.pvid = 0;
|
* no port VLAN. No change to old port VLAN on failure.
|
||||||
|
*/
|
||||||
|
ret = ice_vsi_add_vlan(vsi, 0);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
ret = ice_vsi_manage_pvid(vsi, 0, false);
|
||||||
|
if (ret)
|
||||||
|
goto error_manage_pvid;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (vlan_id) {
|
if (vlan_id) {
|
||||||
dev_info(dev, "Setting VLAN %d, QoS 0x%x on VF %d\n",
|
dev_info(dev, "Setting VLAN %d, QoS 0x%x on VF %d\n",
|
||||||
vlan_id, qos, vf_id);
|
vlan_id, qos, vf_id);
|
||||||
|
|
||||||
/* add new VLAN filter for each MAC */
|
/* add VLAN filter for the port VLAN */
|
||||||
ret = ice_vsi_add_vlan(vsi, vlan_id);
|
ret = ice_vsi_add_vlan(vsi, vlan_id);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto error_set_pvid;
|
goto error_manage_pvid;
|
||||||
}
|
}
|
||||||
|
/* remove old port VLAN filter with valid VLAN ID or QoS fields */
|
||||||
|
if (vf->port_vlan_info)
|
||||||
|
ice_vsi_kill_vlan(vsi, vf->port_vlan_info & VLAN_VID_MASK);
|
||||||
|
|
||||||
/* The Port VLAN needs to be saved across resets the same as the
|
/* keep port VLAN information persistent on resets */
|
||||||
* default LAN MAC address.
|
vf->port_vlan_info = le16_to_cpu(vsi->info.pvid);
|
||||||
*/
|
|
||||||
vf->port_vlan_id = le16_to_cpu(vsi->info.pvid);
|
|
||||||
|
|
||||||
error_set_pvid:
|
error_manage_pvid:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2806,7 +2910,7 @@ static int ice_vc_process_vlan_msg(struct ice_vf *vf, u8 *msg, bool add_v)
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < vfl->num_elements; i++) {
|
for (i = 0; i < vfl->num_elements; i++) {
|
||||||
if (vfl->vlan_id[i] > ICE_MAX_VLANID) {
|
if (vfl->vlan_id[i] >= VLAN_N_VID) {
|
||||||
v_ret = VIRTCHNL_STATUS_ERR_PARAM;
|
v_ret = VIRTCHNL_STATUS_ERR_PARAM;
|
||||||
dev_err(dev, "invalid VF VLAN id %d\n",
|
dev_err(dev, "invalid VF VLAN id %d\n",
|
||||||
vfl->vlan_id[i]);
|
vfl->vlan_id[i]);
|
||||||
|
@ -2868,9 +2972,9 @@ static int ice_vc_process_vlan_msg(struct ice_vf *vf, u8 *msg, bool add_v)
|
||||||
goto error_param;
|
goto error_param;
|
||||||
}
|
}
|
||||||
|
|
||||||
vsi->num_vlan++;
|
/* Enable VLAN pruning when non-zero VLAN is added */
|
||||||
/* Enable VLAN pruning when VLAN is added */
|
if (!vlan_promisc && vid &&
|
||||||
if (!vlan_promisc) {
|
!ice_vsi_is_vlan_pruning_ena(vsi)) {
|
||||||
status = ice_cfg_vlan_pruning(vsi, true, false);
|
status = ice_cfg_vlan_pruning(vsi, true, false);
|
||||||
if (status) {
|
if (status) {
|
||||||
v_ret = VIRTCHNL_STATUS_ERR_PARAM;
|
v_ret = VIRTCHNL_STATUS_ERR_PARAM;
|
||||||
|
@ -2878,7 +2982,7 @@ static int ice_vc_process_vlan_msg(struct ice_vf *vf, u8 *msg, bool add_v)
|
||||||
vid, status);
|
vid, status);
|
||||||
goto error_param;
|
goto error_param;
|
||||||
}
|
}
|
||||||
} else {
|
} else if (vlan_promisc) {
|
||||||
/* Enable Ucast/Mcast VLAN promiscuous mode */
|
/* Enable Ucast/Mcast VLAN promiscuous mode */
|
||||||
promisc_m = ICE_PROMISC_VLAN_TX |
|
promisc_m = ICE_PROMISC_VLAN_TX |
|
||||||
ICE_PROMISC_VLAN_RX;
|
ICE_PROMISC_VLAN_RX;
|
||||||
|
@ -2922,9 +3026,9 @@ static int ice_vc_process_vlan_msg(struct ice_vf *vf, u8 *msg, bool add_v)
|
||||||
goto error_param;
|
goto error_param;
|
||||||
}
|
}
|
||||||
|
|
||||||
vsi->num_vlan--;
|
/* Disable VLAN pruning when only VLAN 0 is left */
|
||||||
/* Disable VLAN pruning when the last VLAN is removed */
|
if (vsi->num_vlan == 1 &&
|
||||||
if (!vsi->num_vlan)
|
ice_vsi_is_vlan_pruning_ena(vsi))
|
||||||
ice_cfg_vlan_pruning(vsi, false, false);
|
ice_cfg_vlan_pruning(vsi, false, false);
|
||||||
|
|
||||||
/* Disable Unicast/Multicast VLAN promiscuous mode */
|
/* Disable Unicast/Multicast VLAN promiscuous mode */
|
||||||
|
@ -3203,14 +3307,12 @@ int
|
||||||
ice_get_vf_cfg(struct net_device *netdev, int vf_id, struct ifla_vf_info *ivi)
|
ice_get_vf_cfg(struct net_device *netdev, int vf_id, struct ifla_vf_info *ivi)
|
||||||
{
|
{
|
||||||
struct ice_pf *pf = ice_netdev_to_pf(netdev);
|
struct ice_pf *pf = ice_netdev_to_pf(netdev);
|
||||||
struct ice_vsi *vsi;
|
|
||||||
struct ice_vf *vf;
|
struct ice_vf *vf;
|
||||||
|
|
||||||
if (ice_validate_vf_id(pf, vf_id))
|
if (ice_validate_vf_id(pf, vf_id))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
vf = &pf->vf[vf_id];
|
vf = &pf->vf[vf_id];
|
||||||
vsi = pf->vsi[vf->lan_vsi_idx];
|
|
||||||
|
|
||||||
if (ice_check_vf_init(pf, vf))
|
if (ice_check_vf_init(pf, vf))
|
||||||
return -EBUSY;
|
return -EBUSY;
|
||||||
|
@ -3219,9 +3321,8 @@ ice_get_vf_cfg(struct net_device *netdev, int vf_id, struct ifla_vf_info *ivi)
|
||||||
ether_addr_copy(ivi->mac, vf->dflt_lan_addr.addr);
|
ether_addr_copy(ivi->mac, vf->dflt_lan_addr.addr);
|
||||||
|
|
||||||
/* VF configuration for VLAN and applicable QoS */
|
/* VF configuration for VLAN and applicable QoS */
|
||||||
ivi->vlan = le16_to_cpu(vsi->info.pvid) & ICE_VLAN_M;
|
ivi->vlan = vf->port_vlan_info & VLAN_VID_MASK;
|
||||||
ivi->qos = (le16_to_cpu(vsi->info.pvid) & ICE_PRIORITY_M) >>
|
ivi->qos = (vf->port_vlan_info & VLAN_PRIO_MASK) >> VLAN_PRIO_SHIFT;
|
||||||
ICE_VLAN_PRIORITY_S;
|
|
||||||
|
|
||||||
ivi->trusted = vf->trusted;
|
ivi->trusted = vf->trusted;
|
||||||
ivi->spoofchk = vf->spoofchk;
|
ivi->spoofchk = vf->spoofchk;
|
||||||
|
|
|
@ -5,11 +5,6 @@
|
||||||
#define _ICE_VIRTCHNL_PF_H_
|
#define _ICE_VIRTCHNL_PF_H_
|
||||||
#include "ice.h"
|
#include "ice.h"
|
||||||
|
|
||||||
#define ICE_MAX_VLANID 4095
|
|
||||||
#define ICE_VLAN_PRIORITY_S 12
|
|
||||||
#define ICE_VLAN_M 0xFFF
|
|
||||||
#define ICE_PRIORITY_M 0x7000
|
|
||||||
|
|
||||||
/* Restrict number of MAC Addr and VLAN that non-trusted VF can programmed */
|
/* Restrict number of MAC Addr and VLAN that non-trusted VF can programmed */
|
||||||
#define ICE_MAX_VLAN_PER_VF 8
|
#define ICE_MAX_VLAN_PER_VF 8
|
||||||
#define ICE_MAX_MACADDR_PER_VF 12
|
#define ICE_MAX_MACADDR_PER_VF 12
|
||||||
|
@ -74,7 +69,7 @@ struct ice_vf {
|
||||||
struct virtchnl_ether_addr dflt_lan_addr;
|
struct virtchnl_ether_addr dflt_lan_addr;
|
||||||
DECLARE_BITMAP(txq_ena, ICE_MAX_BASE_QS_PER_VF);
|
DECLARE_BITMAP(txq_ena, ICE_MAX_BASE_QS_PER_VF);
|
||||||
DECLARE_BITMAP(rxq_ena, ICE_MAX_BASE_QS_PER_VF);
|
DECLARE_BITMAP(rxq_ena, ICE_MAX_BASE_QS_PER_VF);
|
||||||
u16 port_vlan_id;
|
u16 port_vlan_info; /* Port VLAN ID and QoS */
|
||||||
u8 pf_set_mac:1; /* VF MAC address set by VMM admin */
|
u8 pf_set_mac:1; /* VF MAC address set by VMM admin */
|
||||||
u8 trusted:1;
|
u8 trusted:1;
|
||||||
u8 spoofchk:1;
|
u8 spoofchk:1;
|
||||||
|
@ -95,7 +90,6 @@ struct ice_vf {
|
||||||
u8 num_req_qs; /* num of queue pairs requested by VF */
|
u8 num_req_qs; /* num of queue pairs requested by VF */
|
||||||
u16 num_mac;
|
u16 num_mac;
|
||||||
u16 num_vf_qs; /* num of queue configured per VF */
|
u16 num_vf_qs; /* num of queue configured per VF */
|
||||||
u16 num_qs_ena; /* total num of Tx/Rx queue enabled */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef CONFIG_PCI_IOV
|
#ifdef CONFIG_PCI_IOV
|
||||||
|
@ -127,6 +121,9 @@ void ice_set_vf_state_qs_dis(struct ice_vf *vf);
|
||||||
int
|
int
|
||||||
ice_get_vf_stats(struct net_device *netdev, int vf_id,
|
ice_get_vf_stats(struct net_device *netdev, int vf_id,
|
||||||
struct ifla_vf_stats *vf_stats);
|
struct ifla_vf_stats *vf_stats);
|
||||||
|
void
|
||||||
|
ice_vf_lan_overflow_event(struct ice_pf *pf, struct ice_rq_event_info *event);
|
||||||
|
|
||||||
#else /* CONFIG_PCI_IOV */
|
#else /* CONFIG_PCI_IOV */
|
||||||
#define ice_process_vflr_event(pf) do {} while (0)
|
#define ice_process_vflr_event(pf) do {} while (0)
|
||||||
#define ice_free_vfs(pf) do {} while (0)
|
#define ice_free_vfs(pf) do {} while (0)
|
||||||
|
@ -134,6 +131,7 @@ ice_get_vf_stats(struct net_device *netdev, int vf_id,
|
||||||
#define ice_vc_notify_link_state(pf) do {} while (0)
|
#define ice_vc_notify_link_state(pf) do {} while (0)
|
||||||
#define ice_vc_notify_reset(pf) do {} while (0)
|
#define ice_vc_notify_reset(pf) do {} while (0)
|
||||||
#define ice_set_vf_state_qs_dis(vf) do {} while (0)
|
#define ice_set_vf_state_qs_dis(vf) do {} while (0)
|
||||||
|
#define ice_vf_lan_overflow_event(pf, event) do {} while (0)
|
||||||
|
|
||||||
static inline bool
|
static inline bool
|
||||||
ice_reset_all_vfs(struct ice_pf __always_unused *pf,
|
ice_reset_all_vfs(struct ice_pf __always_unused *pf,
|
||||||
|
|
|
@ -183,7 +183,7 @@ static int ice_qp_dis(struct ice_vsi *vsi, u16 q_idx)
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
err = ice_vsi_ctrl_rx_ring(vsi, false, q_idx);
|
err = ice_vsi_ctrl_one_rx_ring(vsi, false, q_idx, true);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
|
@ -243,7 +243,7 @@ static int ice_qp_ena(struct ice_vsi *vsi, u16 q_idx)
|
||||||
|
|
||||||
ice_qvec_cfg_msix(vsi, q_vector);
|
ice_qvec_cfg_msix(vsi, q_vector);
|
||||||
|
|
||||||
err = ice_vsi_ctrl_rx_ring(vsi, true, q_idx);
|
err = ice_vsi_ctrl_one_rx_ring(vsi, true, q_idx, true);
|
||||||
if (err)
|
if (err)
|
||||||
goto free_buf;
|
goto free_buf;
|
||||||
|
|
||||||
|
@ -609,7 +609,7 @@ ice_alloc_buf_slow_zc(struct ice_ring *rx_ring, struct ice_rx_buf *rx_buf)
|
||||||
*/
|
*/
|
||||||
static bool
|
static bool
|
||||||
ice_alloc_rx_bufs_zc(struct ice_ring *rx_ring, int count,
|
ice_alloc_rx_bufs_zc(struct ice_ring *rx_ring, int count,
|
||||||
bool alloc(struct ice_ring *, struct ice_rx_buf *))
|
bool (*alloc)(struct ice_ring *, struct ice_rx_buf *))
|
||||||
{
|
{
|
||||||
union ice_32b_rx_flex_desc *rx_desc;
|
union ice_32b_rx_flex_desc *rx_desc;
|
||||||
u16 ntu = rx_ring->next_to_use;
|
u16 ntu = rx_ring->next_to_use;
|
||||||
|
@ -816,10 +816,10 @@ ice_run_xdp_zc(struct ice_ring *rx_ring, struct xdp_buff *xdp)
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
bpf_warn_invalid_xdp_action(act);
|
bpf_warn_invalid_xdp_action(act);
|
||||||
/* fallthrough -- not supported action */
|
fallthrough;
|
||||||
case XDP_ABORTED:
|
case XDP_ABORTED:
|
||||||
trace_xdp_exception(rx_ring->netdev, xdp_prog, act);
|
trace_xdp_exception(rx_ring->netdev, xdp_prog, act);
|
||||||
/* fallthrough -- handle aborts by dropping frame */
|
fallthrough;
|
||||||
case XDP_DROP:
|
case XDP_DROP:
|
||||||
result = ICE_XDP_CONSUMED;
|
result = ICE_XDP_CONSUMED;
|
||||||
break;
|
break;
|
||||||
|
@ -841,8 +841,8 @@ int ice_clean_rx_irq_zc(struct ice_ring *rx_ring, int budget)
|
||||||
unsigned int total_rx_bytes = 0, total_rx_packets = 0;
|
unsigned int total_rx_bytes = 0, total_rx_packets = 0;
|
||||||
u16 cleaned_count = ICE_DESC_UNUSED(rx_ring);
|
u16 cleaned_count = ICE_DESC_UNUSED(rx_ring);
|
||||||
unsigned int xdp_xmit = 0;
|
unsigned int xdp_xmit = 0;
|
||||||
|
bool failure = false;
|
||||||
struct xdp_buff xdp;
|
struct xdp_buff xdp;
|
||||||
bool failure = 0;
|
|
||||||
|
|
||||||
xdp.rxq = &rx_ring->xdp_rxq;
|
xdp.rxq = &rx_ring->xdp_rxq;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue