aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2010-08-23 04:46:51 -0400
committerWey-Yi Guy <wey-yi.w.guy@intel.com>2010-08-27 12:29:32 -0400
commite72f368be61d9835c98cd00ee1f330d28e2488ef (patch)
tree5f84437d3933928b367528e2d902d6cffb929243 /drivers
parent60744f62971cfa80cab36ab8c12afeae371fbe8b (diff)
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>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-tx.c42
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.c27
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-dev.h5
3 files changed, 51 insertions, 23 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
index 64daddd92279..5950184d9860 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
@@ -71,18 +71,6 @@ static const u8 tid_to_ac[] = {
71 2, 3, 3, 2, 1, 1, 0, 0 71 2, 3, 3, 2, 1, 1, 0, 0
72}; 72};
73 73
74static const u8 ac_to_fifo[] = {
75 IWL_TX_FIFO_VO,
76 IWL_TX_FIFO_VI,
77 IWL_TX_FIFO_BE,
78 IWL_TX_FIFO_BK,
79};
80
81static inline int get_fifo_from_ac(u8 ac)
82{
83 return ac_to_fifo[ac];
84}
85
86static inline int get_ac_from_tid(u16 tid) 74static inline int get_ac_from_tid(u16 tid)
87{ 75{
88 if (likely(tid < ARRAY_SIZE(tid_to_ac))) 76 if (likely(tid < ARRAY_SIZE(tid_to_ac)))
@@ -92,10 +80,10 @@ static inline int get_ac_from_tid(u16 tid)
92 return -EINVAL; 80 return -EINVAL;
93} 81}
94 82
95static inline int get_fifo_from_tid(u16 tid) 83static inline int get_fifo_from_tid(struct iwl_rxon_context *ctx, u16 tid)
96{ 84{
97 if (likely(tid < ARRAY_SIZE(tid_to_ac))) 85 if (likely(tid < ARRAY_SIZE(tid_to_ac)))
98 return get_fifo_from_ac(tid_to_ac[tid]); 86 return ctx->ac_to_fifo[tid_to_ac[tid]];
99 87
100 /* no support for TIDs 8-15 yet */ 88 /* no support for TIDs 8-15 yet */
101 return -EINVAL; 89 return -EINVAL;
@@ -333,11 +321,6 @@ void iwlagn_txq_set_sched(struct iwl_priv *priv, u32 mask)
333 iwl_write_prph(priv, IWLAGN_SCD_TXFACT, mask); 321 iwl_write_prph(priv, IWLAGN_SCD_TXFACT, mask);
334} 322}
335 323
336static inline int get_queue_from_ac(u16 ac)
337{
338 return ac;
339}
340
341/* 324/*
342 * handle build REPLY_TX command notification. 325 * handle build REPLY_TX command notification.
343 */ 326 */
@@ -595,7 +578,20 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
595 iwl_sta_modify_sleep_tx_count(priv, sta_id, 1); 578 iwl_sta_modify_sleep_tx_count(priv, sta_id, 1);
596 } 579 }
597 580
598 txq_id = get_queue_from_ac(skb_get_queue_mapping(skb)); 581 /*
582 * Send this frame after DTIM -- there's a special queue
583 * reserved for this for contexts that support AP mode.
584 */
585 if (info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM) {
586 txq_id = ctx->mcast_queue;
587 /*
588 * The microcode will clear the more data
589 * bit in the last frame it transmits.
590 */
591 hdr->frame_control |=
592 cpu_to_le16(IEEE80211_FCTL_MOREDATA);
593 } else
594 txq_id = ctx->ac_to_queue[skb_get_queue_mapping(skb)];
599 595
600 /* irqs already disabled/saved above when locking priv->lock */ 596 /* irqs already disabled/saved above when locking priv->lock */
601 spin_lock(&priv->sta_lock); 597 spin_lock(&priv->sta_lock);
@@ -984,7 +980,7 @@ int iwlagn_tx_agg_start(struct iwl_priv *priv, struct ieee80211_vif *vif,
984 unsigned long flags; 980 unsigned long flags;
985 struct iwl_tid_data *tid_data; 981 struct iwl_tid_data *tid_data;
986 982
987 tx_fifo = get_fifo_from_tid(tid); 983 tx_fifo = get_fifo_from_tid(iwl_rxon_ctx_from_vif(vif), tid);
988 if (unlikely(tx_fifo < 0)) 984 if (unlikely(tx_fifo < 0))
989 return tx_fifo; 985 return tx_fifo;
990 986
@@ -1045,7 +1041,7 @@ int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif,
1045 int write_ptr, read_ptr; 1041 int write_ptr, read_ptr;
1046 unsigned long flags; 1042 unsigned long flags;
1047 1043
1048 tx_fifo_id = get_fifo_from_tid(tid); 1044 tx_fifo_id = get_fifo_from_tid(iwl_rxon_ctx_from_vif(vif), tid);
1049 if (unlikely(tx_fifo_id < 0)) 1045 if (unlikely(tx_fifo_id < 0))
1050 return tx_fifo_id; 1046 return tx_fifo_id;
1051 1047
@@ -1133,7 +1129,7 @@ int iwlagn_txq_check_empty(struct iwl_priv *priv,
1133 if ((txq_id == tid_data->agg.txq_id) && 1129 if ((txq_id == tid_data->agg.txq_id) &&
1134 (q->read_ptr == q->write_ptr)) { 1130 (q->read_ptr == q->write_ptr)) {
1135 u16 ssn = SEQ_TO_SN(tid_data->seq_number); 1131 u16 ssn = SEQ_TO_SN(tid_data->seq_number);
1136 int tx_fifo = get_fifo_from_tid(tid); 1132 int tx_fifo = get_fifo_from_tid(ctx, tid);
1137 IWL_DEBUG_HT(priv, "HW queue empty: continue DELBA flow\n"); 1133 IWL_DEBUG_HT(priv, "HW queue empty: continue DELBA flow\n");
1138 priv->cfg->ops->lib->txq_agg_disable(priv, txq_id, 1134 priv->cfg->ops->lib->txq_agg_disable(priv, txq_id,
1139 ssn, tx_fifo); 1135 ssn, tx_fifo);
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index b07d397ed5a7..143c12a29fd8 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -4196,6 +4196,28 @@ static int iwl_set_hw_params(struct iwl_priv *priv)
4196 return priv->cfg->ops->lib->set_hw_params(priv); 4196 return priv->cfg->ops->lib->set_hw_params(priv);
4197} 4197}
4198 4198
4199static const u8 iwlagn_bss_ac_to_fifo[] = {
4200 IWL_TX_FIFO_VO,
4201 IWL_TX_FIFO_VI,
4202 IWL_TX_FIFO_BE,
4203 IWL_TX_FIFO_BK,
4204};
4205
4206static const u8 iwlagn_bss_ac_to_queue[] = {
4207 0, 1, 2, 3,
4208};
4209
4210static const u8 iwlagn_pan_ac_to_fifo[] = {
4211 IWL_TX_FIFO_VO_IPAN,
4212 IWL_TX_FIFO_VI_IPAN,
4213 IWL_TX_FIFO_BE_IPAN,
4214 IWL_TX_FIFO_BK_IPAN,
4215};
4216
4217static const u8 iwlagn_pan_ac_to_queue[] = {
4218 7, 6, 5, 4,
4219};
4220
4199static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) 4221static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
4200{ 4222{
4201 int err = 0, i; 4223 int err = 0, i;
@@ -4242,6 +4264,8 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
4242 priv->contexts[IWL_RXON_CTX_BSS].qos_cmd = REPLY_QOS_PARAM; 4264 priv->contexts[IWL_RXON_CTX_BSS].qos_cmd = REPLY_QOS_PARAM;
4243 priv->contexts[IWL_RXON_CTX_BSS].ap_sta_id = IWL_AP_ID; 4265 priv->contexts[IWL_RXON_CTX_BSS].ap_sta_id = IWL_AP_ID;
4244 priv->contexts[IWL_RXON_CTX_BSS].wep_key_cmd = REPLY_WEPKEY; 4266 priv->contexts[IWL_RXON_CTX_BSS].wep_key_cmd = REPLY_WEPKEY;
4267 priv->contexts[IWL_RXON_CTX_BSS].ac_to_fifo = iwlagn_bss_ac_to_fifo;
4268 priv->contexts[IWL_RXON_CTX_BSS].ac_to_queue = iwlagn_bss_ac_to_queue;
4245 4269
4246 priv->contexts[IWL_RXON_CTX_PAN].rxon_cmd = REPLY_WIPAN_RXON; 4270 priv->contexts[IWL_RXON_CTX_PAN].rxon_cmd = REPLY_WIPAN_RXON;
4247 priv->contexts[IWL_RXON_CTX_PAN].rxon_timing_cmd = REPLY_WIPAN_RXON_TIMING; 4271 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)
4251 priv->contexts[IWL_RXON_CTX_PAN].wep_key_cmd = REPLY_WIPAN_WEPKEY; 4275 priv->contexts[IWL_RXON_CTX_PAN].wep_key_cmd = REPLY_WIPAN_WEPKEY;
4252 priv->contexts[IWL_RXON_CTX_PAN].bcast_sta_id = IWLAGN_PAN_BCAST_ID; 4276 priv->contexts[IWL_RXON_CTX_PAN].bcast_sta_id = IWLAGN_PAN_BCAST_ID;
4253 priv->contexts[IWL_RXON_CTX_PAN].station_flags = STA_FLG_PAN_STATION; 4277 priv->contexts[IWL_RXON_CTX_PAN].station_flags = STA_FLG_PAN_STATION;
4278 priv->contexts[IWL_RXON_CTX_PAN].ac_to_fifo = iwlagn_pan_ac_to_fifo;
4279 priv->contexts[IWL_RXON_CTX_PAN].ac_to_queue = iwlagn_pan_ac_to_queue;
4280 priv->contexts[IWL_RXON_CTX_PAN].mcast_queue = IWL_IPAN_MCAST_QUEUE;
4254 4281
4255 BUILD_BUG_ON(NUM_IWL_RXON_CTX != 2); 4282 BUILD_BUG_ON(NUM_IWL_RXON_CTX != 2);
4256 4283
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index 99b6b81be7e2..422c71e122f7 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -1111,6 +1111,11 @@ enum iwl_rxon_context_id {
1111 1111
1112struct iwl_rxon_context { 1112struct iwl_rxon_context {
1113 struct ieee80211_vif *vif; 1113 struct ieee80211_vif *vif;
1114
1115 const u8 *ac_to_fifo;
1116 const u8 *ac_to_queue;
1117 u8 mcast_queue;
1118
1114 enum iwl_rxon_context_id ctxid; 1119 enum iwl_rxon_context_id ctxid;
1115 /* 1120 /*
1116 * We declare this const so it can only be 1121 * We declare this const so it can only be