Commit 13a6233b authored by Brett Creeley's avatar Brett Creeley Committed by Jeff Kirsher

ice: Add support to enable/disable all Rx queues before waiting

Currently when we enable/disable all Rx queues we do the following
sequence for each Rx queue and then move to the next queue.

1. Enable/Disable the Rx queue via register write.
2. Read the configuration register to determine if the Rx queue was
enabled/disabled successfully.

In some cases enabling/disabling queue 0 fails because of step 2 above.
Fix this by doing step 1 for all of the Rx queues and then step 2 for
all of the Rx queues.

Also, there are cases where we enable/disable a single queue (i.e.
SR-IOV and XDP) so add a new function that does step 1 and 2 above with
a read flush in between.

This change also required a single Rx queue to be enabled/disabled with
and without waiting for the change to propagate through hardware. Fix
this by adding a boolean wait flag to the necessary functions.

Also, add the keywords "one" and "all" to distinguish between
enabling/disabling a single Rx queue and all Rx queues respectively.
Signed-off-by: default avatarBrett Creeley <brett.creeley@intel.com>
Tested-by: default avatarAndrew Bowers <andrewx.bowers@intel.com>
Signed-off-by: default avatarJeff Kirsher <jeffrey.t.kirsher@intel.com>
parent 72634bc2
...@@ -459,17 +459,20 @@ int __ice_vsi_get_qs(struct ice_qs_cfg *qs_cfg) ...@@ -459,17 +459,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 +488,30 @@ int ice_vsi_ctrl_rx_ring(struct ice_vsi *vsi, bool ena, u16 rxq_idx) ...@@ -485,13 +488,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", ice_flush(hw);
vsi->idx, pf_q, (ena ? "en" : "dis")); return ice_pf_rxq_wait(pf, pf_q, ena);
}
return ret; /**
* 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 @@ ...@@ -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);
......
...@@ -462,7 +462,7 @@ static int ice_lbtest_prepare_rings(struct ice_vsi *vsi) ...@@ -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) ...@@ -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);
......
...@@ -26,16 +26,26 @@ const char *ice_vsi_type_str(enum ice_vsi_type type) ...@@ -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;
} }
...@@ -1682,25 +1692,25 @@ int ice_vsi_manage_vlan_stripping(struct ice_vsi *vsi, bool ena) ...@@ -1682,25 +1692,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);
} }
/** /**
......
...@@ -30,9 +30,9 @@ int ice_vsi_manage_vlan_insertion(struct ice_vsi *vsi); ...@@ -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,
......
...@@ -3968,7 +3968,7 @@ static int ice_up_complete(struct ice_vsi *vsi) ...@@ -3968,7 +3968,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;
...@@ -4347,7 +4347,7 @@ int ice_down(struct ice_vsi *vsi) ...@@ -4347,7 +4347,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);
......
...@@ -271,7 +271,7 @@ static void ice_dis_vf_qs(struct ice_vf *vf) ...@@ -271,7 +271,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);
} }
...@@ -2051,7 +2051,7 @@ static int ice_vc_ena_qs_msg(struct ice_vf *vf, u8 *msg) ...@@ -2051,7 +2051,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;
...@@ -2179,7 +2179,8 @@ static int ice_vc_dis_qs_msg(struct ice_vf *vf, u8 *msg) ...@@ -2179,7 +2179,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;
......
...@@ -183,7 +183,7 @@ static int ice_qp_dis(struct ice_vsi *vsi, u16 q_idx) ...@@ -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) ...@@ -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;
......
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