Skip to content

Commit

Permalink
iwlagn: move tx queues to transport layer
Browse files Browse the repository at this point in the history
This finalizes the move of the data path to the transport layer.

Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
  • Loading branch information
Emmanuel Grumbach authored and John W. Linville committed Aug 29, 2011
1 parent e20d434 commit 8ad71be
Show file tree
Hide file tree
Showing 6 changed files with 136 additions and 139 deletions.
23 changes: 2 additions & 21 deletions drivers/net/wireless/iwlwifi/iwl-agn-tx.c
Original file line number Diff line number Diff line change
Expand Up @@ -742,7 +742,6 @@ void iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
u16 sequence = le16_to_cpu(pkt->hdr.sequence);
int txq_id = SEQ_TO_QUEUE(sequence);
int cmd_index = SEQ_TO_INDEX(sequence);
struct iwl_tx_queue *txq = &priv->txq[txq_id];
struct iwlagn_tx_resp *tx_resp = (void *)&pkt->u.raw[0];
struct ieee80211_hdr *hdr;
u32 status = le16_to_cpu(tx_resp->status.status);
Expand All @@ -755,17 +754,7 @@ void iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
struct sk_buff_head skbs;
struct sk_buff *skb;
struct iwl_rxon_context *ctx;

if ((cmd_index >= txq->q.n_bd) ||
(iwl_queue_used(&txq->q, cmd_index) == 0)) {
IWL_ERR(priv, "%s: Read index for DMA queue txq_id (%d) "
"cmd_index %d is out of range [0-%d] %d %d\n",
__func__, txq_id, cmd_index, txq->q.n_bd,
txq->q.write_ptr, txq->q.read_ptr);
return;
}

txq->time_stamp = jiffies;
bool is_agg = (txq_id >= IWLAGN_FIRST_AMPDU_QUEUE);

tid = (tx_resp->ra_tid & IWLAGN_TX_RES_TID_MSK) >>
IWLAGN_TX_RES_TID_POS;
Expand All @@ -774,12 +763,10 @@ void iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)

spin_lock_irqsave(&priv->shrd->sta_lock, flags);

if (txq->sched_retry)
if (is_agg)
iwl_rx_reply_tx_agg(priv, tx_resp);

if (tx_resp->frame_count == 1) {
bool is_agg = (txq_id >= IWLAGN_FIRST_AMPDU_QUEUE);

__skb_queue_head_init(&skbs);
/*we can free until ssn % q.n_bd not inclusive */
iwl_trans_reclaim(trans(priv), sta_id, tid, txq_id,
Expand Down Expand Up @@ -850,14 +837,12 @@ void iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv,
{
struct iwl_rx_packet *pkt = rxb_addr(rxb);
struct iwl_compressed_ba_resp *ba_resp = &pkt->u.compressed_ba;
struct iwl_tx_queue *txq = NULL;
struct iwl_ht_agg *agg;
struct sk_buff_head reclaimed_skbs;
struct ieee80211_tx_info *info;
struct ieee80211_hdr *hdr;
struct sk_buff *skb;
unsigned long flags;
int index;
int sta_id;
int tid;
int freed;
Expand All @@ -875,14 +860,10 @@ void iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv,
return;
}

txq = &priv->txq[scd_flow];
sta_id = ba_resp->sta_id;
tid = ba_resp->tid;
agg = &priv->shrd->tid_data[sta_id][tid].agg;

/* Find index of block-ack window */
index = ba_resp_scd_ssn & (txq->q.n_bd - 1);

spin_lock_irqsave(&priv->shrd->sta_lock, flags);

if (unlikely(agg->txq_id != scd_flow)) {
Expand Down
42 changes: 0 additions & 42 deletions drivers/net/wireless/iwlwifi/iwl-dev.h
Original file line number Diff line number Diff line change
Expand Up @@ -574,19 +574,6 @@ struct iwl_sensitivity_ranges {
****************************************************************************/
extern void iwl_update_chain_flags(struct iwl_priv *priv);
extern const u8 iwl_bcast_addr[ETH_ALEN];
extern int iwl_queue_space(const struct iwl_queue *q);
static inline int iwl_queue_used(const struct iwl_queue *q, int i)
{
return q->write_ptr >= q->read_ptr ?
(i >= q->read_ptr && i < q->write_ptr) :
!(i < q->read_ptr && i >= q->write_ptr);
}


static inline u8 get_cmd_index(struct iwl_queue *q, u32 index)
{
return index & (q->n_window - 1);
}

#define IWL_OPERATION_MODE_AUTO 0
#define IWL_OPERATION_MODE_HT_ONLY 1
Expand Down Expand Up @@ -1156,10 +1143,6 @@ struct iwl_priv {

int activity_timer_active;

/* Tx DMA processing queues */
struct iwl_tx_queue *txq;
unsigned long txq_ctx_active_msk;

/* counts mgmt, ctl, and data packets */
struct traffic_stats tx_stats;
struct traffic_stats rx_stats;
Expand All @@ -1172,12 +1155,6 @@ struct iwl_priv {
struct iwl_station_entry stations[IWLAGN_STATION_COUNT];
unsigned long ucode_key_table;

/* queue refcounts */
#define IWL_MAX_HW_QUEUES 32
unsigned long queue_stopped[BITS_TO_LONGS(IWL_MAX_HW_QUEUES)];
/* for each AC */
atomic_t queue_stop_count[4];

/* Indication if ieee80211_ops->open has been called */
u8 is_open;

Expand Down Expand Up @@ -1334,27 +1311,8 @@ struct iwl_priv {
bool have_rekey_data;
}; /*iwl_priv */

static inline void iwl_txq_ctx_activate(struct iwl_priv *priv, int txq_id)
{
set_bit(txq_id, &priv->txq_ctx_active_msk);
}

static inline void iwl_txq_ctx_deactivate(struct iwl_priv *priv, int txq_id)
{
clear_bit(txq_id, &priv->txq_ctx_active_msk);
}

extern struct iwl_mod_params iwlagn_mod_params;

static inline struct ieee80211_hdr *iwl_tx_queue_get_hdr(struct iwl_priv *priv,
int txq_id, int idx)
{
if (priv->txq[txq_id].skbs[idx])
return (struct ieee80211_hdr *)priv->txq[txq_id].
skbs[idx]->data;
return NULL;
}

static inline struct iwl_rxon_context *
iwl_rxon_ctx_from_vif(struct ieee80211_vif *vif)
{
Expand Down
50 changes: 46 additions & 4 deletions drivers/net/wireless/iwlwifi/iwl-trans-int-pcie.h
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,10 @@ struct iwl_dma_ptr {
* @ac_to_fifo: to what fifo is a specifc AC mapped ?
* @ac_to_queue: to what tx queue is a specifc AC mapped ?
* @mcast_queue:
* @txq: Tx DMA processing queues
* @txq_ctx_active_msk: what queue is active
* queue_stopped: tracks what queue is stopped
* queue_stop_count: tracks what SW queue is stopped
*/
struct iwl_trans_pcie {
struct iwl_rx_queue rxq;
Expand All @@ -150,6 +154,12 @@ struct iwl_trans_pcie {
const u8 *ac_to_fifo[NUM_IWL_RXON_CTX];
const u8 *ac_to_queue[NUM_IWL_RXON_CTX];
u8 mcast_queue[NUM_IWL_RXON_CTX];

struct iwl_tx_queue *txq;
unsigned long txq_ctx_active_msk;
#define IWL_MAX_HW_QUEUES 32
unsigned long queue_stopped[BITS_TO_LONGS(IWL_MAX_HW_QUEUES)];
atomic_t queue_stop_count[4];
};

#define IWL_TRANS_GET_PCIE_TRANS(_iwl_trans) \
Expand Down Expand Up @@ -207,6 +217,7 @@ void iwlagn_txq_free_tfd(struct iwl_trans *trans, struct iwl_tx_queue *txq,
int index);
int iwl_tx_queue_reclaim(struct iwl_trans *trans, int txq_id, int index,
struct sk_buff_head *skbs);
int iwl_queue_space(const struct iwl_queue *q);

/*****************************************************
* Error handling
Expand All @@ -216,6 +227,9 @@ int iwl_dump_nic_event_log(struct iwl_trans *trans, bool full_log,
int iwl_dump_fh(struct iwl_trans *trans, char **buf, bool display);
void iwl_dump_csr(struct iwl_trans *trans);

/*****************************************************
* Helpers
******************************************************/
static inline void iwl_disable_interrupts(struct iwl_trans *trans)
{
clear_bit(STATUS_INT_ENABLED, &trans->shrd->status);
Expand Down Expand Up @@ -265,12 +279,14 @@ static inline void iwl_wake_queue(struct iwl_trans *trans,
u8 queue = txq->swq_id;
u8 ac = queue & 3;
u8 hwq = (queue >> 2) & 0x1f;
struct iwl_trans_pcie *trans_pcie =
IWL_TRANS_GET_PCIE_TRANS(trans);

if (unlikely(!trans->shrd->mac80211_registered))
return;

if (test_and_clear_bit(hwq, priv(trans)->queue_stopped))
if (atomic_dec_return(&priv(trans)->queue_stop_count[ac]) <= 0)
if (test_and_clear_bit(hwq, trans_pcie->queue_stopped))
if (atomic_dec_return(&trans_pcie->queue_stop_count[ac]) <= 0)
ieee80211_wake_queue(trans->shrd->hw, ac);
}

Expand All @@ -280,12 +296,14 @@ static inline void iwl_stop_queue(struct iwl_trans *trans,
u8 queue = txq->swq_id;
u8 ac = queue & 3;
u8 hwq = (queue >> 2) & 0x1f;
struct iwl_trans_pcie *trans_pcie =
IWL_TRANS_GET_PCIE_TRANS(trans);

if (unlikely(!trans->shrd->mac80211_registered))
return;

if (!test_and_set_bit(hwq, priv(trans)->queue_stopped))
if (atomic_inc_return(&priv(trans)->queue_stop_count[ac]) > 0)
if (!test_and_set_bit(hwq, trans_pcie->queue_stopped))
if (atomic_inc_return(&trans_pcie->queue_stop_count[ac]) > 0)
ieee80211_stop_queue(trans->shrd->hw, ac);
}

Expand All @@ -301,4 +319,28 @@ static inline void iwl_stop_queue(struct iwl_trans *trans,

#define ieee80211_wake_queue DO_NOT_USE_ieee80211_wake_queue

static inline void iwl_txq_ctx_activate(struct iwl_trans_pcie *trans_pcie,
int txq_id)
{
set_bit(txq_id, &trans_pcie->txq_ctx_active_msk);
}

static inline void iwl_txq_ctx_deactivate(struct iwl_trans_pcie *trans_pcie,
int txq_id)
{
clear_bit(txq_id, &trans_pcie->txq_ctx_active_msk);
}

static inline int iwl_queue_used(const struct iwl_queue *q, int i)
{
return q->write_ptr >= q->read_ptr ?
(i >= q->read_ptr && i < q->write_ptr) :
!(i < q->read_ptr && i >= q->write_ptr);
}

static inline u8 get_cmd_index(struct iwl_queue *q, u32 index)
{
return index & (q->n_window - 1);
}

#endif /* __iwl_trans_int_pcie_h__ */
2 changes: 1 addition & 1 deletion drivers/net/wireless/iwlwifi/iwl-trans-rx-pcie.c
Original file line number Diff line number Diff line change
Expand Up @@ -1032,7 +1032,7 @@ void iwl_irq_tasklet(struct iwl_trans *trans)
iwl_rx_queue_update_write_ptr(trans, &trans_pcie->rxq);
for (i = 0; i < hw_params(trans).max_txq_num; i++)
iwl_txq_update_write_ptr(trans,
&priv(trans)->txq[i]);
&trans_pcie->txq[i]);

isr_stats->wakeup++;

Expand Down
Loading

0 comments on commit 8ad71be

Please sign in to comment.