Skip to content

Commit

Permalink
iwlagn: queue frames according to context
Browse files Browse the repository at this point in the history
Frames for different contexts need to be put
on different queues, and multicast after DTIM
frames have a special queue yet which also
depends on the context, so put all this into
the context.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
  • Loading branch information
Johannes Berg authored and Wey-Yi Guy committed Aug 27, 2010
1 parent 60744f6 commit e72f368
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 23 deletions.
42 changes: 19 additions & 23 deletions drivers/net/wireless/iwlwifi/iwl-agn-tx.c
Original file line number Diff line number Diff line change
Expand Up @@ -71,18 +71,6 @@ static const u8 tid_to_ac[] = {
2, 3, 3, 2, 1, 1, 0, 0
};

static const u8 ac_to_fifo[] = {
IWL_TX_FIFO_VO,
IWL_TX_FIFO_VI,
IWL_TX_FIFO_BE,
IWL_TX_FIFO_BK,
};

static inline int get_fifo_from_ac(u8 ac)
{
return ac_to_fifo[ac];
}

static inline int get_ac_from_tid(u16 tid)
{
if (likely(tid < ARRAY_SIZE(tid_to_ac)))
Expand All @@ -92,10 +80,10 @@ static inline int get_ac_from_tid(u16 tid)
return -EINVAL;
}

static inline int get_fifo_from_tid(u16 tid)
static inline int get_fifo_from_tid(struct iwl_rxon_context *ctx, u16 tid)
{
if (likely(tid < ARRAY_SIZE(tid_to_ac)))
return get_fifo_from_ac(tid_to_ac[tid]);
return ctx->ac_to_fifo[tid_to_ac[tid]];

/* no support for TIDs 8-15 yet */
return -EINVAL;
Expand Down Expand Up @@ -333,11 +321,6 @@ void iwlagn_txq_set_sched(struct iwl_priv *priv, u32 mask)
iwl_write_prph(priv, IWLAGN_SCD_TXFACT, mask);
}

static inline int get_queue_from_ac(u16 ac)
{
return ac;
}

/*
* handle build REPLY_TX command notification.
*/
Expand Down Expand Up @@ -595,7 +578,20 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
iwl_sta_modify_sleep_tx_count(priv, sta_id, 1);
}

txq_id = get_queue_from_ac(skb_get_queue_mapping(skb));
/*
* Send this frame after DTIM -- there's a special queue
* reserved for this for contexts that support AP mode.
*/
if (info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM) {
txq_id = ctx->mcast_queue;
/*
* The microcode will clear the more data
* bit in the last frame it transmits.
*/
hdr->frame_control |=
cpu_to_le16(IEEE80211_FCTL_MOREDATA);
} else
txq_id = ctx->ac_to_queue[skb_get_queue_mapping(skb)];

/* irqs already disabled/saved above when locking priv->lock */
spin_lock(&priv->sta_lock);
Expand Down Expand Up @@ -984,7 +980,7 @@ int iwlagn_tx_agg_start(struct iwl_priv *priv, struct ieee80211_vif *vif,
unsigned long flags;
struct iwl_tid_data *tid_data;

tx_fifo = get_fifo_from_tid(tid);
tx_fifo = get_fifo_from_tid(iwl_rxon_ctx_from_vif(vif), tid);
if (unlikely(tx_fifo < 0))
return tx_fifo;

Expand Down Expand Up @@ -1045,7 +1041,7 @@ int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif,
int write_ptr, read_ptr;
unsigned long flags;

tx_fifo_id = get_fifo_from_tid(tid);
tx_fifo_id = get_fifo_from_tid(iwl_rxon_ctx_from_vif(vif), tid);
if (unlikely(tx_fifo_id < 0))
return tx_fifo_id;

Expand Down Expand Up @@ -1133,7 +1129,7 @@ int iwlagn_txq_check_empty(struct iwl_priv *priv,
if ((txq_id == tid_data->agg.txq_id) &&
(q->read_ptr == q->write_ptr)) {
u16 ssn = SEQ_TO_SN(tid_data->seq_number);
int tx_fifo = get_fifo_from_tid(tid);
int tx_fifo = get_fifo_from_tid(ctx, tid);
IWL_DEBUG_HT(priv, "HW queue empty: continue DELBA flow\n");
priv->cfg->ops->lib->txq_agg_disable(priv, txq_id,
ssn, tx_fifo);
Expand Down
27 changes: 27 additions & 0 deletions drivers/net/wireless/iwlwifi/iwl-agn.c
Original file line number Diff line number Diff line change
Expand Up @@ -4196,6 +4196,28 @@ static int iwl_set_hw_params(struct iwl_priv *priv)
return priv->cfg->ops->lib->set_hw_params(priv);
}

static const u8 iwlagn_bss_ac_to_fifo[] = {
IWL_TX_FIFO_VO,
IWL_TX_FIFO_VI,
IWL_TX_FIFO_BE,
IWL_TX_FIFO_BK,
};

static const u8 iwlagn_bss_ac_to_queue[] = {
0, 1, 2, 3,
};

static const u8 iwlagn_pan_ac_to_fifo[] = {
IWL_TX_FIFO_VO_IPAN,
IWL_TX_FIFO_VI_IPAN,
IWL_TX_FIFO_BE_IPAN,
IWL_TX_FIFO_BK_IPAN,
};

static const u8 iwlagn_pan_ac_to_queue[] = {
7, 6, 5, 4,
};

static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
{
int err = 0, i;
Expand Down Expand Up @@ -4242,6 +4264,8 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
priv->contexts[IWL_RXON_CTX_BSS].qos_cmd = REPLY_QOS_PARAM;
priv->contexts[IWL_RXON_CTX_BSS].ap_sta_id = IWL_AP_ID;
priv->contexts[IWL_RXON_CTX_BSS].wep_key_cmd = REPLY_WEPKEY;
priv->contexts[IWL_RXON_CTX_BSS].ac_to_fifo = iwlagn_bss_ac_to_fifo;
priv->contexts[IWL_RXON_CTX_BSS].ac_to_queue = iwlagn_bss_ac_to_queue;

priv->contexts[IWL_RXON_CTX_PAN].rxon_cmd = REPLY_WIPAN_RXON;
priv->contexts[IWL_RXON_CTX_PAN].rxon_timing_cmd = REPLY_WIPAN_RXON_TIMING;
Expand All @@ -4251,6 +4275,9 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
priv->contexts[IWL_RXON_CTX_PAN].wep_key_cmd = REPLY_WIPAN_WEPKEY;
priv->contexts[IWL_RXON_CTX_PAN].bcast_sta_id = IWLAGN_PAN_BCAST_ID;
priv->contexts[IWL_RXON_CTX_PAN].station_flags = STA_FLG_PAN_STATION;
priv->contexts[IWL_RXON_CTX_PAN].ac_to_fifo = iwlagn_pan_ac_to_fifo;
priv->contexts[IWL_RXON_CTX_PAN].ac_to_queue = iwlagn_pan_ac_to_queue;
priv->contexts[IWL_RXON_CTX_PAN].mcast_queue = IWL_IPAN_MCAST_QUEUE;

BUILD_BUG_ON(NUM_IWL_RXON_CTX != 2);

Expand Down
5 changes: 5 additions & 0 deletions drivers/net/wireless/iwlwifi/iwl-dev.h
Original file line number Diff line number Diff line change
Expand Up @@ -1111,6 +1111,11 @@ enum iwl_rxon_context_id {

struct iwl_rxon_context {
struct ieee80211_vif *vif;

const u8 *ac_to_fifo;
const u8 *ac_to_queue;
u8 mcast_queue;

enum iwl_rxon_context_id ctxid;
/*
* We declare this const so it can only be
Expand Down

0 comments on commit e72f368

Please sign in to comment.