diff options
author | Jacob Keller <jacob.e.keller@intel.com> | 2017-04-13 04:45:47 -0400 |
---|---|---|
committer | Jeff Kirsher <jeffrey.t.kirsher@intel.com> | 2017-04-19 20:13:56 -0400 |
commit | c768e490640dbb928d1c8a5f7b437a334d0cde44 (patch) | |
tree | ac840a01f879402574d3c764219a113f2a60a48f /drivers/net/ethernet/intel/i40e/i40e_main.c | |
parent | 024b05f4246e281ef50e019eff0fc53aedf069ac (diff) |
i40e: factor out queue control from i40e_vsi_control_(tx|rx)
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.
Change-ID: Id923cbfa43127b1c24d8ed4f809b1012c736d9ac
Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
Tested-by: Andrew Bowers <andrewx.bowers@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Diffstat (limited to 'drivers/net/ethernet/intel/i40e/i40e_main.c')
-rw-r--r-- | drivers/net/ethernet/intel/i40e/i40e_main.c | 139 |
1 files 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 5c2ceb247959..2bf5bb1b4627 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) | |||
3919 | } | 3919 | } |
3920 | #endif | 3920 | #endif |
3921 | 3921 | ||
3922 | #define I40E_QTX_ENA_WAIT_COUNT 50 | ||
3923 | |||
3922 | /** | 3924 | /** |
3923 | * i40e_pf_txq_wait - Wait for a PF's Tx queue to be enabled or disabled | 3925 | * i40e_pf_txq_wait - Wait for a PF's Tx queue to be enabled or disabled |
3924 | * @pf: the PF being configured | 3926 | * @pf: the PF being configured |
@@ -3949,6 +3951,50 @@ static int i40e_pf_txq_wait(struct i40e_pf *pf, int pf_q, bool enable) | |||
3949 | } | 3951 | } |
3950 | 3952 | ||
3951 | /** | 3953 | /** |
3954 | * i40e_control_tx_q - Start or stop a particular Tx queue | ||
3955 | * @pf: the PF structure | ||
3956 | * @pf_q: the PF queue to configure | ||
3957 | * @enable: start or stop the queue | ||
3958 | * | ||
3959 | * This function enables or disables a single queue. Note that any delay | ||
3960 | * required after the operation is expected to be handled by the caller of | ||
3961 | * this function. | ||
3962 | **/ | ||
3963 | static void i40e_control_tx_q(struct i40e_pf *pf, int pf_q, bool enable) | ||
3964 | { | ||
3965 | struct i40e_hw *hw = &pf->hw; | ||
3966 | u32 tx_reg; | ||
3967 | int i; | ||
3968 | |||
3969 | /* warn the TX unit of coming changes */ | ||
3970 | i40e_pre_tx_queue_cfg(&pf->hw, pf_q, enable); | ||
3971 | if (!enable) | ||
3972 | usleep_range(10, 20); | ||
3973 | |||
3974 | for (i = 0; i < I40E_QTX_ENA_WAIT_COUNT; i++) { | ||
3975 | tx_reg = rd32(hw, I40E_QTX_ENA(pf_q)); | ||
3976 | if (((tx_reg >> I40E_QTX_ENA_QENA_REQ_SHIFT) & 1) == | ||
3977 | ((tx_reg >> I40E_QTX_ENA_QENA_STAT_SHIFT) & 1)) | ||
3978 | break; | ||
3979 | usleep_range(1000, 2000); | ||
3980 | } | ||
3981 | |||
3982 | /* Skip if the queue is already in the requested state */ | ||
3983 | if (enable == !!(tx_reg & I40E_QTX_ENA_QENA_STAT_MASK)) | ||
3984 | return; | ||
3985 | |||
3986 | /* turn on/off the queue */ | ||
3987 | if (enable) { | ||
3988 | wr32(hw, I40E_QTX_HEAD(pf_q), 0); | ||
3989 | tx_reg |= I40E_QTX_ENA_QENA_REQ_MASK; | ||
3990 | } else { | ||
3991 | tx_reg &= ~I40E_QTX_ENA_QENA_REQ_MASK; | ||
3992 | } | ||
3993 | |||
3994 | wr32(hw, I40E_QTX_ENA(pf_q), tx_reg); | ||
3995 | } | ||
3996 | |||
3997 | /** | ||
3952 | * i40e_vsi_control_tx - Start or stop a VSI's rings | 3998 | * i40e_vsi_control_tx - Start or stop a VSI's rings |
3953 | * @vsi: the VSI being configured | 3999 | * @vsi: the VSI being configured |
3954 | * @enable: start or stop the rings | 4000 | * @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) | |||
3956 | static int i40e_vsi_control_tx(struct i40e_vsi *vsi, bool enable) | 4002 | static int i40e_vsi_control_tx(struct i40e_vsi *vsi, bool enable) |
3957 | { | 4003 | { |
3958 | struct i40e_pf *pf = vsi->back; | 4004 | struct i40e_pf *pf = vsi->back; |
3959 | struct i40e_hw *hw = &pf->hw; | 4005 | int i, pf_q, ret = 0; |
3960 | int i, j, pf_q, ret = 0; | ||
3961 | u32 tx_reg; | ||
3962 | 4006 | ||
3963 | pf_q = vsi->base_queue; | 4007 | pf_q = vsi->base_queue; |
3964 | for (i = 0; i < vsi->num_queue_pairs; i++, pf_q++) { | 4008 | for (i = 0; i < vsi->num_queue_pairs; i++, pf_q++) { |
4009 | i40e_control_tx_q(pf, pf_q, enable); | ||
3965 | 4010 | ||
3966 | /* warn the TX unit of coming changes */ | 4011 | /* Don't wait to disable when port Tx is suspended */ |
3967 | i40e_pre_tx_queue_cfg(&pf->hw, pf_q, enable); | ||
3968 | if (!enable) | ||
3969 | usleep_range(10, 20); | ||
3970 | |||
3971 | for (j = 0; j < 50; j++) { | ||
3972 | tx_reg = rd32(hw, I40E_QTX_ENA(pf_q)); | ||
3973 | if (((tx_reg >> I40E_QTX_ENA_QENA_REQ_SHIFT) & 1) == | ||
3974 | ((tx_reg >> I40E_QTX_ENA_QENA_STAT_SHIFT) & 1)) | ||
3975 | break; | ||
3976 | usleep_range(1000, 2000); | ||
3977 | } | ||
3978 | /* Skip if the queue is already in the requested state */ | ||
3979 | if (enable == !!(tx_reg & I40E_QTX_ENA_QENA_STAT_MASK)) | ||
3980 | continue; | ||
3981 | |||
3982 | /* turn on/off the queue */ | ||
3983 | if (enable) { | ||
3984 | wr32(hw, I40E_QTX_HEAD(pf_q), 0); | ||
3985 | tx_reg |= I40E_QTX_ENA_QENA_REQ_MASK; | ||
3986 | } else { | ||
3987 | tx_reg &= ~I40E_QTX_ENA_QENA_REQ_MASK; | ||
3988 | } | ||
3989 | |||
3990 | wr32(hw, I40E_QTX_ENA(pf_q), tx_reg); | ||
3991 | /* No waiting for the Tx queue to disable */ | ||
3992 | if (!enable && test_bit(__I40E_PORT_TX_SUSPENDED, &pf->state)) | 4012 | if (!enable && test_bit(__I40E_PORT_TX_SUSPENDED, &pf->state)) |
3993 | continue; | 4013 | continue; |
3994 | 4014 | ||
@@ -4035,6 +4055,43 @@ static int i40e_pf_rxq_wait(struct i40e_pf *pf, int pf_q, bool enable) | |||
4035 | } | 4055 | } |
4036 | 4056 | ||
4037 | /** | 4057 | /** |
4058 | * i40e_control_rx_q - Start or stop a particular Rx queue | ||
4059 | * @pf: the PF structure | ||
4060 | * @pf_q: the PF queue to configure | ||
4061 | * @enable: start or stop the queue | ||
4062 | * | ||
4063 | * This function enables or disables a single queue. Note that any delay | ||
4064 | * required after the operation is expected to be handled by the caller of | ||
4065 | * this function. | ||
4066 | **/ | ||
4067 | static void i40e_control_rx_q(struct i40e_pf *pf, int pf_q, bool enable) | ||
4068 | { | ||
4069 | struct i40e_hw *hw = &pf->hw; | ||
4070 | u32 rx_reg; | ||
4071 | int i; | ||
4072 | |||
4073 | for (i = 0; i < I40E_QTX_ENA_WAIT_COUNT; i++) { | ||
4074 | rx_reg = rd32(hw, I40E_QRX_ENA(pf_q)); | ||
4075 | if (((rx_reg >> I40E_QRX_ENA_QENA_REQ_SHIFT) & 1) == | ||
4076 | ((rx_reg >> I40E_QRX_ENA_QENA_STAT_SHIFT) & 1)) | ||
4077 | break; | ||
4078 | usleep_range(1000, 2000); | ||
4079 | } | ||
4080 | |||
4081 | /* Skip if the queue is already in the requested state */ | ||
4082 | if (enable == !!(rx_reg & I40E_QRX_ENA_QENA_STAT_MASK)) | ||
4083 | return; | ||
4084 | |||
4085 | /* turn on/off the queue */ | ||
4086 | if (enable) | ||
4087 | rx_reg |= I40E_QRX_ENA_QENA_REQ_MASK; | ||
4088 | else | ||
4089 | rx_reg &= ~I40E_QRX_ENA_QENA_REQ_MASK; | ||
4090 | |||
4091 | wr32(hw, I40E_QRX_ENA(pf_q), rx_reg); | ||
4092 | } | ||
4093 | |||
4094 | /** | ||
4038 | * i40e_vsi_control_rx - Start or stop a VSI's rings | 4095 | * i40e_vsi_control_rx - Start or stop a VSI's rings |
4039 | * @vsi: the VSI being configured | 4096 | * @vsi: the VSI being configured |
4040 | * @enable: start or stop the rings | 4097 | * @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) | |||
4042 | static int i40e_vsi_control_rx(struct i40e_vsi *vsi, bool enable) | 4099 | static int i40e_vsi_control_rx(struct i40e_vsi *vsi, bool enable) |
4043 | { | 4100 | { |
4044 | struct i40e_pf *pf = vsi->back; | 4101 | struct i40e_pf *pf = vsi->back; |
4045 | struct i40e_hw *hw = &pf->hw; | 4102 | int i, pf_q, ret = 0; |
4046 | int i, j, pf_q, ret = 0; | ||
4047 | u32 rx_reg; | ||
4048 | 4103 | ||
4049 | pf_q = vsi->base_queue; | 4104 | pf_q = vsi->base_queue; |
4050 | for (i = 0; i < vsi->num_queue_pairs; i++, pf_q++) { | 4105 | for (i = 0; i < vsi->num_queue_pairs; i++, pf_q++) { |
4051 | for (j = 0; j < 50; j++) { | 4106 | i40e_control_rx_q(pf, pf_q, enable); |
4052 | rx_reg = rd32(hw, I40E_QRX_ENA(pf_q)); | ||
4053 | if (((rx_reg >> I40E_QRX_ENA_QENA_REQ_SHIFT) & 1) == | ||
4054 | ((rx_reg >> I40E_QRX_ENA_QENA_STAT_SHIFT) & 1)) | ||
4055 | break; | ||
4056 | usleep_range(1000, 2000); | ||
4057 | } | ||
4058 | 4107 | ||
4059 | /* Skip if the queue is already in the requested state */ | 4108 | /* Don't wait to disable when port Tx is suspended */ |
4060 | if (enable == !!(rx_reg & I40E_QRX_ENA_QENA_STAT_MASK)) | ||
4061 | continue; | ||
4062 | |||
4063 | /* turn on/off the queue */ | ||
4064 | if (enable) | ||
4065 | rx_reg |= I40E_QRX_ENA_QENA_REQ_MASK; | ||
4066 | else | ||
4067 | rx_reg &= ~I40E_QRX_ENA_QENA_REQ_MASK; | ||
4068 | wr32(hw, I40E_QRX_ENA(pf_q), rx_reg); | ||
4069 | /* No waiting for the Tx queue to disable */ | ||
4070 | if (!enable && test_bit(__I40E_PORT_TX_SUSPENDED, &pf->state)) | 4109 | if (!enable && test_bit(__I40E_PORT_TX_SUSPENDED, &pf->state)) |
4071 | continue; | 4110 | continue; |
4072 | 4111 | ||