iwlagn: queue frames according to context
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>
This commit is contained in:
committed by
Wey-Yi Guy
parent
60744f6297
commit
e72f368be6
@@ -71,18 +71,6 @@ static const u8 tid_to_ac[] = {
|
|||||||
2, 3, 3, 2, 1, 1, 0, 0
|
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)
|
static inline int get_ac_from_tid(u16 tid)
|
||||||
{
|
{
|
||||||
if (likely(tid < ARRAY_SIZE(tid_to_ac)))
|
if (likely(tid < ARRAY_SIZE(tid_to_ac)))
|
||||||
@@ -92,10 +80,10 @@ static inline int get_ac_from_tid(u16 tid)
|
|||||||
return -EINVAL;
|
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)))
|
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 */
|
/* no support for TIDs 8-15 yet */
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
@@ -333,11 +321,6 @@ void iwlagn_txq_set_sched(struct iwl_priv *priv, u32 mask)
|
|||||||
iwl_write_prph(priv, IWLAGN_SCD_TXFACT, 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.
|
* handle build REPLY_TX command notification.
|
||||||
*/
|
*/
|
||||||
@@ -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);
|
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 */
|
/* irqs already disabled/saved above when locking priv->lock */
|
||||||
spin_lock(&priv->sta_lock);
|
spin_lock(&priv->sta_lock);
|
||||||
@@ -984,7 +980,7 @@ int iwlagn_tx_agg_start(struct iwl_priv *priv, struct ieee80211_vif *vif,
|
|||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
struct iwl_tid_data *tid_data;
|
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))
|
if (unlikely(tx_fifo < 0))
|
||||||
return tx_fifo;
|
return tx_fifo;
|
||||||
|
|
||||||
@@ -1045,7 +1041,7 @@ int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif,
|
|||||||
int write_ptr, read_ptr;
|
int write_ptr, read_ptr;
|
||||||
unsigned long flags;
|
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))
|
if (unlikely(tx_fifo_id < 0))
|
||||||
return tx_fifo_id;
|
return tx_fifo_id;
|
||||||
|
|
||||||
@@ -1133,7 +1129,7 @@ int iwlagn_txq_check_empty(struct iwl_priv *priv,
|
|||||||
if ((txq_id == tid_data->agg.txq_id) &&
|
if ((txq_id == tid_data->agg.txq_id) &&
|
||||||
(q->read_ptr == q->write_ptr)) {
|
(q->read_ptr == q->write_ptr)) {
|
||||||
u16 ssn = SEQ_TO_SN(tid_data->seq_number);
|
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");
|
IWL_DEBUG_HT(priv, "HW queue empty: continue DELBA flow\n");
|
||||||
priv->cfg->ops->lib->txq_agg_disable(priv, txq_id,
|
priv->cfg->ops->lib->txq_agg_disable(priv, txq_id,
|
||||||
ssn, tx_fifo);
|
ssn, tx_fifo);
|
||||||
|
@@ -4196,6 +4196,28 @@ static int iwl_set_hw_params(struct iwl_priv *priv)
|
|||||||
return priv->cfg->ops->lib->set_hw_params(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)
|
static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||||
{
|
{
|
||||||
int err = 0, i;
|
int err = 0, i;
|
||||||
@@ -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].qos_cmd = REPLY_QOS_PARAM;
|
||||||
priv->contexts[IWL_RXON_CTX_BSS].ap_sta_id = IWL_AP_ID;
|
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].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_cmd = REPLY_WIPAN_RXON;
|
||||||
priv->contexts[IWL_RXON_CTX_PAN].rxon_timing_cmd = REPLY_WIPAN_RXON_TIMING;
|
priv->contexts[IWL_RXON_CTX_PAN].rxon_timing_cmd = REPLY_WIPAN_RXON_TIMING;
|
||||||
@@ -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].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].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].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);
|
BUILD_BUG_ON(NUM_IWL_RXON_CTX != 2);
|
||||||
|
|
||||||
|
@@ -1111,6 +1111,11 @@ enum iwl_rxon_context_id {
|
|||||||
|
|
||||||
struct iwl_rxon_context {
|
struct iwl_rxon_context {
|
||||||
struct ieee80211_vif *vif;
|
struct ieee80211_vif *vif;
|
||||||
|
|
||||||
|
const u8 *ac_to_fifo;
|
||||||
|
const u8 *ac_to_queue;
|
||||||
|
u8 mcast_queue;
|
||||||
|
|
||||||
enum iwl_rxon_context_id ctxid;
|
enum iwl_rxon_context_id ctxid;
|
||||||
/*
|
/*
|
||||||
* We declare this const so it can only be
|
* We declare this const so it can only be
|
||||||
|
Reference in New Issue
Block a user