iwlwifi: don't rely on the wr / rd pointers in DELBA flow
In the same spirit as the previous patch. Eventually this will allow us to remove the tid_data knowledge from the transport layer. Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com> Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
This commit is contained in:
parent
1ba42da479
commit
1f40e145eb
2 changed files with 14 additions and 17 deletions
|
@ -599,10 +599,8 @@ int iwl_trans_pcie_tx_agg_disable(struct iwl_trans *trans,
|
||||||
enum iwl_rxon_context_id ctx, int sta_id,
|
enum iwl_rxon_context_id ctx, int sta_id,
|
||||||
int tid)
|
int tid)
|
||||||
{
|
{
|
||||||
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
|
|
||||||
unsigned long flags;
|
|
||||||
int read_ptr, write_ptr;
|
|
||||||
struct iwl_tid_data *tid_data;
|
struct iwl_tid_data *tid_data;
|
||||||
|
unsigned long flags;
|
||||||
int txq_id;
|
int txq_id;
|
||||||
|
|
||||||
spin_lock_irqsave(&trans->shrd->sta_lock, flags);
|
spin_lock_irqsave(&trans->shrd->sta_lock, flags);
|
||||||
|
@ -642,21 +640,22 @@ int iwl_trans_pcie_tx_agg_disable(struct iwl_trans *trans,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
write_ptr = trans_pcie->txq[txq_id].q.write_ptr;
|
tid_data->agg.ssn = SEQ_TO_SN(tid_data->seq_number);
|
||||||
read_ptr = trans_pcie->txq[txq_id].q.read_ptr;
|
|
||||||
|
|
||||||
/* The queue is not empty */
|
/* There are still packets for this RA / TID in the HW */
|
||||||
if (write_ptr != read_ptr) {
|
if (tid_data->agg.ssn != tid_data->next_reclaimed) {
|
||||||
IWL_DEBUG_TX_QUEUES(trans,
|
IWL_DEBUG_TX_QUEUES(trans, "Can't proceed: ssn %d, "
|
||||||
"Stopping a non empty AGG HW QUEUE\n");
|
"next_recl = %d",
|
||||||
|
tid_data->agg.ssn,
|
||||||
|
tid_data->next_reclaimed);
|
||||||
trans->shrd->tid_data[sta_id][tid].agg.state =
|
trans->shrd->tid_data[sta_id][tid].agg.state =
|
||||||
IWL_EMPTYING_HW_QUEUE_DELBA;
|
IWL_EMPTYING_HW_QUEUE_DELBA;
|
||||||
tid_data->agg.ssn = SEQ_TO_SN(tid_data->seq_number);
|
|
||||||
spin_unlock_irqrestore(&trans->shrd->sta_lock, flags);
|
spin_unlock_irqrestore(&trans->shrd->sta_lock, flags);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
IWL_DEBUG_TX_QUEUES(trans, "HW queue is empty\n");
|
IWL_DEBUG_TX_QUEUES(trans, "Can proceed: ssn = next_recl = %d",
|
||||||
|
tid_data->agg.ssn);
|
||||||
turn_off:
|
turn_off:
|
||||||
trans->shrd->tid_data[sta_id][tid].agg.state = IWL_AGG_OFF;
|
trans->shrd->tid_data[sta_id][tid].agg.state = IWL_AGG_OFF;
|
||||||
|
|
||||||
|
|
|
@ -1278,20 +1278,18 @@ static int iwl_trans_pcie_request_irq(struct iwl_trans *trans)
|
||||||
static int iwlagn_txq_check_empty(struct iwl_trans *trans,
|
static int iwlagn_txq_check_empty(struct iwl_trans *trans,
|
||||||
int sta_id, u8 tid, int txq_id)
|
int sta_id, u8 tid, int txq_id)
|
||||||
{
|
{
|
||||||
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
|
|
||||||
struct iwl_queue *q = &trans_pcie->txq[txq_id].q;
|
|
||||||
struct iwl_tid_data *tid_data = &trans->shrd->tid_data[sta_id][tid];
|
struct iwl_tid_data *tid_data = &trans->shrd->tid_data[sta_id][tid];
|
||||||
|
|
||||||
lockdep_assert_held(&trans->shrd->sta_lock);
|
lockdep_assert_held(&trans->shrd->sta_lock);
|
||||||
|
|
||||||
switch (trans->shrd->tid_data[sta_id][tid].agg.state) {
|
switch (trans->shrd->tid_data[sta_id][tid].agg.state) {
|
||||||
case IWL_EMPTYING_HW_QUEUE_DELBA:
|
case IWL_EMPTYING_HW_QUEUE_DELBA:
|
||||||
/* We are reclaiming the last packet of the */
|
/* There are no packets for this RA / TID in the HW any more */
|
||||||
/* aggregated HW queue */
|
|
||||||
if ((txq_id == tid_data->agg.txq_id) &&
|
if ((txq_id == tid_data->agg.txq_id) &&
|
||||||
(q->read_ptr == q->write_ptr)) {
|
(tid_data->agg.ssn == tid_data->next_reclaimed)) {
|
||||||
IWL_DEBUG_TX_QUEUES(trans,
|
IWL_DEBUG_TX_QUEUES(trans,
|
||||||
"HW queue empty: continue DELBA flow\n");
|
"Can continue DELBA flow ssn = next_recl ="
|
||||||
|
" %d", tid_data->next_reclaimed);
|
||||||
iwl_trans_pcie_txq_agg_disable(trans, txq_id);
|
iwl_trans_pcie_txq_agg_disable(trans, txq_id);
|
||||||
tid_data->agg.state = IWL_AGG_OFF;
|
tid_data->agg.state = IWL_AGG_OFF;
|
||||||
iwl_stop_tx_ba_trans_ready(priv(trans),
|
iwl_stop_tx_ba_trans_ready(priv(trans),
|
||||||
|
|
Reference in a new issue