From mboxrd@z Thu Jan 1 00:00:00 1970 From: Keller, Jacob E Date: Thu, 13 Apr 2017 17:22:38 +0000 Subject: [Intel-wired-lan] [next PATCH S70 04/12] i40e: factor out queue control from i40e_vsi_control_(tx|rx) In-Reply-To: <20170413084555.6962-4-alice.michael@intel.com> References: <20170413084555.6962-1-alice.michael@intel.com> <20170413084555.6962-4-alice.michael@intel.com> Message-ID: <02874ECE860811409154E81DA85FBB5857E014FE@ORSMSX115.amr.corp.intel.com> MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit To: intel-wired-lan@osuosl.org List-ID: ACK Thanks, Jake > -----Original Message----- > From: Michael, Alice > Sent: Thursday, April 13, 2017 1:46 AM > To: Michael, Alice ; intel-wired-lan at lists.osuosl.org > Cc: Keller, Jacob E > Subject: [next PATCH S70 04/12] i40e: factor out queue control from > i40e_vsi_control_(tx|rx) > > From: Jacob Keller > > A future patch will need to be able to handle controlling queues without > waiting until all VSIs are handled. Factor out the direct queue > modification so that we can easily re-use this code. The result is also > a bit easier to read since we don't embed multiple single-letter loop > counters. > > Signed-off-by: Jacob Keller > Change-ID: Id923cbfa43127b1c24d8ed4f809b1012c736d9ac > --- > drivers/net/ethernet/intel/i40e/i40e_main.c | 139 ++++++++++++++++++------- > --- > 1 file changed, 89 insertions(+), 50 deletions(-) > > diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c > b/drivers/net/ethernet/intel/i40e/i40e_main.c > index 1c06693..ebf2ad4 100644 > --- a/drivers/net/ethernet/intel/i40e/i40e_main.c > +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c > @@ -3919,6 +3919,8 @@ static void i40e_netpoll(struct net_device *netdev) > } > #endif > > +#define I40E_QTX_ENA_WAIT_COUNT 50 > + > /** > * i40e_pf_txq_wait - Wait for a PF's Tx queue to be enabled or disabled > * @pf: the PF being configured > @@ -3949,6 +3951,50 @@ static int i40e_pf_txq_wait(struct i40e_pf *pf, int pf_q, > bool enable) > } > > /** > + * i40e_control_tx_q - Start or stop a particular Tx queue > + * @pf: the PF structure > + * @pf_q: the PF queue to configure > + * @enable: start or stop the queue > + * > + * This function enables or disables a single queue. Note that any delay > + * required after the operation is expected to be handled by the caller of > + * this function. > + **/ > +static void i40e_control_tx_q(struct i40e_pf *pf, int pf_q, bool enable) > +{ > + struct i40e_hw *hw = &pf->hw; > + u32 tx_reg; > + int i; > + > + /* warn the TX unit of coming changes */ > + i40e_pre_tx_queue_cfg(&pf->hw, pf_q, enable); > + if (!enable) > + usleep_range(10, 20); > + > + for (i = 0; i < I40E_QTX_ENA_WAIT_COUNT; i++) { > + tx_reg = rd32(hw, I40E_QTX_ENA(pf_q)); > + if (((tx_reg >> I40E_QTX_ENA_QENA_REQ_SHIFT) & 1) == > + ((tx_reg >> I40E_QTX_ENA_QENA_STAT_SHIFT) & 1)) > + break; > + usleep_range(1000, 2000); > + } > + > + /* Skip if the queue is already in the requested state */ > + if (enable == !!(tx_reg & I40E_QTX_ENA_QENA_STAT_MASK)) > + return; > + > + /* turn on/off the queue */ > + if (enable) { > + wr32(hw, I40E_QTX_HEAD(pf_q), 0); > + tx_reg |= I40E_QTX_ENA_QENA_REQ_MASK; > + } else { > + tx_reg &= ~I40E_QTX_ENA_QENA_REQ_MASK; > + } > + > + wr32(hw, I40E_QTX_ENA(pf_q), tx_reg); > +} > + > +/** > * i40e_vsi_control_tx - Start or stop a VSI's rings > * @vsi: the VSI being configured > * @enable: start or stop the rings > @@ -3956,39 +4002,13 @@ static int i40e_pf_txq_wait(struct i40e_pf *pf, int > pf_q, bool enable) > static int i40e_vsi_control_tx(struct i40e_vsi *vsi, bool enable) > { > struct i40e_pf *pf = vsi->back; > - struct i40e_hw *hw = &pf->hw; > - int i, j, pf_q, ret = 0; > - u32 tx_reg; > + int i, pf_q, ret = 0; > > pf_q = vsi->base_queue; > for (i = 0; i < vsi->num_queue_pairs; i++, pf_q++) { > + i40e_control_tx_q(pf, pf_q, enable); > > - /* warn the TX unit of coming changes */ > - i40e_pre_tx_queue_cfg(&pf->hw, pf_q, enable); > - if (!enable) > - usleep_range(10, 20); > - > - for (j = 0; j < 50; j++) { > - tx_reg = rd32(hw, I40E_QTX_ENA(pf_q)); > - if (((tx_reg >> I40E_QTX_ENA_QENA_REQ_SHIFT) & 1) == > - ((tx_reg >> I40E_QTX_ENA_QENA_STAT_SHIFT) & 1)) > - break; > - usleep_range(1000, 2000); > - } > - /* Skip if the queue is already in the requested state */ > - if (enable == !!(tx_reg & I40E_QTX_ENA_QENA_STAT_MASK)) > - continue; > - > - /* turn on/off the queue */ > - if (enable) { > - wr32(hw, I40E_QTX_HEAD(pf_q), 0); > - tx_reg |= I40E_QTX_ENA_QENA_REQ_MASK; > - } else { > - tx_reg &= ~I40E_QTX_ENA_QENA_REQ_MASK; > - } > - > - wr32(hw, I40E_QTX_ENA(pf_q), tx_reg); > - /* No waiting for the Tx queue to disable */ > + /* Don't wait to disable when port Tx is suspended */ > if (!enable && test_bit(__I40E_PORT_TX_SUSPENDED, &pf- > >state)) > continue; > > @@ -4035,6 +4055,43 @@ static int i40e_pf_rxq_wait(struct i40e_pf *pf, int pf_q, > bool enable) > } > > /** > + * i40e_control_rx_q - Start or stop a particular Rx queue > + * @pf: the PF structure > + * @pf_q: the PF queue to configure > + * @enable: start or stop the queue > + * > + * This function enables or disables a single queue. Note that any delay > + * required after the operation is expected to be handled by the caller of > + * this function. > + **/ > +static void i40e_control_rx_q(struct i40e_pf *pf, int pf_q, bool enable) > +{ > + struct i40e_hw *hw = &pf->hw; > + u32 rx_reg; > + int i; > + > + for (i = 0; i < I40E_QTX_ENA_WAIT_COUNT; i++) { > + rx_reg = rd32(hw, I40E_QRX_ENA(pf_q)); > + if (((rx_reg >> I40E_QRX_ENA_QENA_REQ_SHIFT) & 1) == > + ((rx_reg >> I40E_QRX_ENA_QENA_STAT_SHIFT) & 1)) > + break; > + usleep_range(1000, 2000); > + } > + > + /* Skip if the queue is already in the requested state */ > + if (enable == !!(rx_reg & I40E_QRX_ENA_QENA_STAT_MASK)) > + return; > + > + /* turn on/off the queue */ > + if (enable) > + rx_reg |= I40E_QRX_ENA_QENA_REQ_MASK; > + else > + rx_reg &= ~I40E_QRX_ENA_QENA_REQ_MASK; > + > + wr32(hw, I40E_QRX_ENA(pf_q), rx_reg); > +} > + > +/** > * i40e_vsi_control_rx - Start or stop a VSI's rings > * @vsi: the VSI being configured > * @enable: start or stop the rings > @@ -4042,31 +4099,13 @@ static int i40e_pf_rxq_wait(struct i40e_pf *pf, int > pf_q, bool enable) > static int i40e_vsi_control_rx(struct i40e_vsi *vsi, bool enable) > { > struct i40e_pf *pf = vsi->back; > - struct i40e_hw *hw = &pf->hw; > - int i, j, pf_q, ret = 0; > - u32 rx_reg; > + int i, pf_q, ret = 0; > > pf_q = vsi->base_queue; > for (i = 0; i < vsi->num_queue_pairs; i++, pf_q++) { > - for (j = 0; j < 50; j++) { > - rx_reg = rd32(hw, I40E_QRX_ENA(pf_q)); > - if (((rx_reg >> I40E_QRX_ENA_QENA_REQ_SHIFT) & 1) == > - ((rx_reg >> I40E_QRX_ENA_QENA_STAT_SHIFT) & 1)) > - break; > - usleep_range(1000, 2000); > - } > + i40e_control_rx_q(pf, pf_q, enable); > > - /* Skip if the queue is already in the requested state */ > - if (enable == !!(rx_reg & I40E_QRX_ENA_QENA_STAT_MASK)) > - continue; > - > - /* turn on/off the queue */ > - if (enable) > - rx_reg |= I40E_QRX_ENA_QENA_REQ_MASK; > - else > - rx_reg &= ~I40E_QRX_ENA_QENA_REQ_MASK; > - wr32(hw, I40E_QRX_ENA(pf_q), rx_reg); > - /* No waiting for the Tx queue to disable */ > + /* Don't wait to disable when port Tx is suspended */ > if (!enable && test_bit(__I40E_PORT_TX_SUSPENDED, &pf- > >state)) > continue; > > -- > 2.9.3