aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/iwlwifi')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965.c20
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-5000.c35
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-dev.h12
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-prph.h14
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-tx.c105
5 files changed, 109 insertions, 77 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c
index 1bd2cd83602..644aacfbd7d 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965.c
+++ b/drivers/net/wireless/iwlwifi/iwl-4965.c
@@ -502,14 +502,14 @@ static void iwl4965_tx_queue_set_status(struct iwl_priv *priv,
502 scd_retry ? "BA" : "AC", txq_id, tx_fifo_id); 502 scd_retry ? "BA" : "AC", txq_id, tx_fifo_id);
503} 503}
504 504
505static const u16 default_queue_to_tx_fifo[] = { 505static const s8 default_queue_to_tx_fifo[] = {
506 IWL_TX_FIFO_AC3, 506 IWL_TX_FIFO_VO,
507 IWL_TX_FIFO_AC2, 507 IWL_TX_FIFO_VI,
508 IWL_TX_FIFO_AC1, 508 IWL_TX_FIFO_BE,
509 IWL_TX_FIFO_AC0, 509 IWL_TX_FIFO_BK,
510 IWL49_CMD_FIFO_NUM, 510 IWL49_CMD_FIFO_NUM,
511 IWL_TX_FIFO_HCCA_1, 511 IWL_TX_FIFO_UNUSED,
512 IWL_TX_FIFO_HCCA_2 512 IWL_TX_FIFO_UNUSED,
513}; 513};
514 514
515static int iwl4965_alive_notify(struct iwl_priv *priv) 515static int iwl4965_alive_notify(struct iwl_priv *priv)
@@ -589,9 +589,15 @@ static int iwl4965_alive_notify(struct iwl_priv *priv)
589 /* reset to 0 to enable all the queue first */ 589 /* reset to 0 to enable all the queue first */
590 priv->txq_ctx_active_msk = 0; 590 priv->txq_ctx_active_msk = 0;
591 /* Map each Tx/cmd queue to its corresponding fifo */ 591 /* Map each Tx/cmd queue to its corresponding fifo */
592 BUILD_BUG_ON(ARRAY_SIZE(default_queue_to_tx_fifo) != 7);
592 for (i = 0; i < ARRAY_SIZE(default_queue_to_tx_fifo); i++) { 593 for (i = 0; i < ARRAY_SIZE(default_queue_to_tx_fifo); i++) {
593 int ac = default_queue_to_tx_fifo[i]; 594 int ac = default_queue_to_tx_fifo[i];
595
594 iwl_txq_ctx_activate(priv, i); 596 iwl_txq_ctx_activate(priv, i);
597
598 if (ac == IWL_TX_FIFO_UNUSED)
599 continue;
600
595 iwl4965_tx_queue_set_status(priv, &priv->txq[i], ac, 0); 601 iwl4965_tx_queue_set_status(priv, &priv->txq[i], ac, 0);
596 } 602 }
597 603
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c
index 4c0ef013acb..37e1e77f513 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-5000.c
@@ -64,14 +64,17 @@
64#define _IWL5150_MODULE_FIRMWARE(api) IWL5150_FW_PRE #api ".ucode" 64#define _IWL5150_MODULE_FIRMWARE(api) IWL5150_FW_PRE #api ".ucode"
65#define IWL5150_MODULE_FIRMWARE(api) _IWL5150_MODULE_FIRMWARE(api) 65#define IWL5150_MODULE_FIRMWARE(api) _IWL5150_MODULE_FIRMWARE(api)
66 66
67static const u16 iwl5000_default_queue_to_tx_fifo[] = { 67static const s8 iwl5000_default_queue_to_tx_fifo[] = {
68 IWL_TX_FIFO_AC3, 68 IWL_TX_FIFO_VO,
69 IWL_TX_FIFO_AC2, 69 IWL_TX_FIFO_VI,
70 IWL_TX_FIFO_AC1, 70 IWL_TX_FIFO_BE,
71 IWL_TX_FIFO_AC0, 71 IWL_TX_FIFO_BK,
72 IWL50_CMD_FIFO_NUM, 72 IWL50_CMD_FIFO_NUM,
73 IWL_TX_FIFO_HCCA_1, 73 IWL_TX_FIFO_UNUSED,
74 IWL_TX_FIFO_HCCA_2 74 IWL_TX_FIFO_UNUSED,
75 IWL_TX_FIFO_UNUSED,
76 IWL_TX_FIFO_UNUSED,
77 IWL_TX_FIFO_UNUSED,
75}; 78};
76 79
77/* NIC configuration for 5000 series */ 80/* NIC configuration for 5000 series */
@@ -657,25 +660,21 @@ int iwl5000_alive_notify(struct iwl_priv *priv)
657 /* reset to 0 to enable all the queue first */ 660 /* reset to 0 to enable all the queue first */
658 priv->txq_ctx_active_msk = 0; 661 priv->txq_ctx_active_msk = 0;
659 /* map qos queues to fifos one-to-one */ 662 /* map qos queues to fifos one-to-one */
663 BUILD_BUG_ON(ARRAY_SIZE(iwl5000_default_queue_to_tx_fifo) != 10);
664
660 for (i = 0; i < ARRAY_SIZE(iwl5000_default_queue_to_tx_fifo); i++) { 665 for (i = 0; i < ARRAY_SIZE(iwl5000_default_queue_to_tx_fifo); i++) {
661 int ac = iwl5000_default_queue_to_tx_fifo[i]; 666 int ac = iwl5000_default_queue_to_tx_fifo[i];
667
662 iwl_txq_ctx_activate(priv, i); 668 iwl_txq_ctx_activate(priv, i);
669
670 if (ac == IWL_TX_FIFO_UNUSED)
671 continue;
672
663 iwl5000_tx_queue_set_status(priv, &priv->txq[i], ac, 0); 673 iwl5000_tx_queue_set_status(priv, &priv->txq[i], ac, 0);
664 } 674 }
665 675
666 /*
667 * TODO - need to initialize these queues and map them to FIFOs
668 * in the loop above, not only mark them as active. We do this
669 * because we want the first aggregation queue to be queue #10,
670 * but do not use 8 or 9 otherwise yet.
671 */
672 iwl_txq_ctx_activate(priv, 7);
673 iwl_txq_ctx_activate(priv, 8);
674 iwl_txq_ctx_activate(priv, 9);
675
676 spin_unlock_irqrestore(&priv->lock, flags); 676 spin_unlock_irqrestore(&priv->lock, flags);
677 677
678
679 iwl_send_wimax_coex(priv); 678 iwl_send_wimax_coex(priv);
680 679
681 iwl5000_set_Xtal_calib(priv); 680 iwl5000_set_Xtal_calib(priv);
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index bac8e7cc46c..2e4d47c7139 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -304,13 +304,11 @@ struct iwl_channel_info {
304 struct iwl3945_scan_power_info scan_pwr_info[IWL_NUM_SCAN_RATES]; 304 struct iwl3945_scan_power_info scan_pwr_info[IWL_NUM_SCAN_RATES];
305}; 305};
306 306
307#define IWL_TX_FIFO_AC0 0 307#define IWL_TX_FIFO_BK 0
308#define IWL_TX_FIFO_AC1 1 308#define IWL_TX_FIFO_BE 1
309#define IWL_TX_FIFO_AC2 2 309#define IWL_TX_FIFO_VI 2
310#define IWL_TX_FIFO_AC3 3 310#define IWL_TX_FIFO_VO 3
311#define IWL_TX_FIFO_HCCA_1 5 311#define IWL_TX_FIFO_UNUSED -1
312#define IWL_TX_FIFO_HCCA_2 6
313#define IWL_TX_FIFO_NONE 7
314 312
315/* Minimum number of queues. MAX_NUM is defined in hw specific files. 313/* Minimum number of queues. MAX_NUM is defined in hw specific files.
316 * Set the minimum to accommodate the 4 standard TX queues, 1 command 314 * Set the minimum to accommodate the 4 standard TX queues, 1 command
diff --git a/drivers/net/wireless/iwlwifi/iwl-prph.h b/drivers/net/wireless/iwlwifi/iwl-prph.h
index d2d2a917490..5944de7a98a 100644
--- a/drivers/net/wireless/iwlwifi/iwl-prph.h
+++ b/drivers/net/wireless/iwlwifi/iwl-prph.h
@@ -254,7 +254,7 @@
254 * device. A queue maps to only one (selectable by driver) Tx DMA channel, 254 * device. A queue maps to only one (selectable by driver) Tx DMA channel,
255 * but one DMA channel may take input from several queues. 255 * but one DMA channel may take input from several queues.
256 * 256 *
257 * Tx DMA channels have dedicated purposes. For 4965, they are used as follows 257 * Tx DMA FIFOs have dedicated purposes. For 4965, they are used as follows
258 * (cf. default_queue_to_tx_fifo in iwl-4965.c): 258 * (cf. default_queue_to_tx_fifo in iwl-4965.c):
259 * 259 *
260 * 0 -- EDCA BK (background) frames, lowest priority 260 * 0 -- EDCA BK (background) frames, lowest priority
@@ -262,20 +262,20 @@
262 * 2 -- EDCA VI (video) frames, higher priority 262 * 2 -- EDCA VI (video) frames, higher priority
263 * 3 -- EDCA VO (voice) and management frames, highest priority 263 * 3 -- EDCA VO (voice) and management frames, highest priority
264 * 4 -- Commands (e.g. RXON, etc.) 264 * 4 -- Commands (e.g. RXON, etc.)
265 * 5 -- HCCA short frames 265 * 5 -- unused (HCCA)
266 * 6 -- HCCA long frames 266 * 6 -- unused (HCCA)
267 * 7 -- not used by driver (device-internal only) 267 * 7 -- not used by driver (device-internal only)
268 * 268 *
269 * For 5000 series and up, they are used slightly differently 269 * For 5000 series and up, they are used differently
270 * (cf. iwl5000_default_queue_to_tx_fifo in iwl-5000.c): 270 * (cf. iwl5000_default_queue_to_tx_fifo in iwl-5000.c):
271 * 271 *
272 * 0 -- EDCA BK (background) frames, lowest priority 272 * 0 -- EDCA BK (background) frames, lowest priority
273 * 1 -- EDCA BE (best effort) frames, normal priority 273 * 1 -- EDCA BE (best effort) frames, normal priority
274 * 2 -- EDCA VI (video) frames, higher priority 274 * 2 -- EDCA VI (video) frames, higher priority
275 * 3 -- EDCA VO (voice) and management frames, highest priority 275 * 3 -- EDCA VO (voice) and management frames, highest priority
276 * 4 -- (TBD) 276 * 4 -- unused
277 * 5 -- HCCA short frames 277 * 5 -- unused
278 * 6 -- HCCA long frames 278 * 6 -- unused
279 * 7 -- Commands 279 * 7 -- Commands
280 * 280 *
281 * Driver should normally map queues 0-6 to Tx DMA/FIFO channels 0-6. 281 * Driver should normally map queues 0-6 to Tx DMA/FIFO channels 0-6.
diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c
index 08b33fcc079..045e4a67344 100644
--- a/drivers/net/wireless/iwlwifi/iwl-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-tx.c
@@ -37,26 +37,63 @@
37#include "iwl-io.h" 37#include "iwl-io.h"
38#include "iwl-helpers.h" 38#include "iwl-helpers.h"
39 39
40static const u16 default_tid_to_tx_fifo[] = { 40/*
41 IWL_TX_FIFO_AC1, 41 * mac80211 queues, ACs, hardware queues, FIFOs.
42 IWL_TX_FIFO_AC0, 42 *
43 IWL_TX_FIFO_AC0, 43 * Cf. http://wireless.kernel.org/en/developers/Documentation/mac80211/queues
44 IWL_TX_FIFO_AC1, 44 *
45 IWL_TX_FIFO_AC2, 45 * Mac80211 uses the following numbers, which we get as from it
46 IWL_TX_FIFO_AC2, 46 * by way of skb_get_queue_mapping(skb):
47 IWL_TX_FIFO_AC3, 47 *
48 IWL_TX_FIFO_AC3, 48 * VO 0
49 IWL_TX_FIFO_NONE, 49 * VI 1
50 IWL_TX_FIFO_NONE, 50 * BE 2
51 IWL_TX_FIFO_NONE, 51 * BK 3
52 IWL_TX_FIFO_NONE, 52 *
53 IWL_TX_FIFO_NONE, 53 *
54 IWL_TX_FIFO_NONE, 54 * Regular (not A-MPDU) frames are put into hardware queues corresponding
55 IWL_TX_FIFO_NONE, 55 * to the FIFOs, see comments in iwl-prph.h. Aggregated frames get their
56 IWL_TX_FIFO_NONE, 56 * own queue per aggregation session (RA/TID combination), such queues are
57 IWL_TX_FIFO_AC3 57 * set up to map into FIFOs too, for which we need an AC->FIFO mapping. In
58 * order to map frames to the right queue, we also need an AC->hw queue
59 * mapping. This is implemented here.
60 *
61 * Due to the way hw queues are set up (by the hw specific modules like
62 * iwl-4965.c, iwl-5000.c etc.), the AC->hw queue mapping is the identity
63 * mapping.
64 */
65
66static const u8 tid_to_ac[] = {
67 /* this matches the mac80211 numbers */
68 2, 3, 3, 2, 1, 1, 0, 0
69};
70
71static const u8 ac_to_fifo[] = {
72 IWL_TX_FIFO_VO,
73 IWL_TX_FIFO_VI,
74 IWL_TX_FIFO_BE,
75 IWL_TX_FIFO_BK,
58}; 76};
59 77
78static inline int get_fifo_from_ac(u8 ac)
79{
80 return ac_to_fifo[ac];
81}
82
83static inline int get_queue_from_ac(u16 ac)
84{
85 return ac;
86}
87
88static inline int get_fifo_from_tid(u16 tid)
89{
90 if (likely(tid < ARRAY_SIZE(tid_to_ac)))
91 return get_fifo_from_ac(tid_to_ac[tid]);
92
93 /* no support for TIDs 8-15 yet */
94 return -EINVAL;
95}
96
60static inline int iwl_alloc_dma_ptr(struct iwl_priv *priv, 97static inline int iwl_alloc_dma_ptr(struct iwl_priv *priv,
61 struct iwl_dma_ptr *ptr, size_t size) 98 struct iwl_dma_ptr *ptr, size_t size)
62{ 99{
@@ -591,13 +628,12 @@ static void iwl_tx_cmd_build_basic(struct iwl_priv *priv,
591 tx_cmd->next_frame_len = 0; 628 tx_cmd->next_frame_len = 0;
592} 629}
593 630
594#define RTS_HCCA_RETRY_LIMIT 3
595#define RTS_DFAULT_RETRY_LIMIT 60 631#define RTS_DFAULT_RETRY_LIMIT 60
596 632
597static void iwl_tx_cmd_build_rate(struct iwl_priv *priv, 633static void iwl_tx_cmd_build_rate(struct iwl_priv *priv,
598 struct iwl_tx_cmd *tx_cmd, 634 struct iwl_tx_cmd *tx_cmd,
599 struct ieee80211_tx_info *info, 635 struct ieee80211_tx_info *info,
600 __le16 fc, int is_hcca) 636 __le16 fc)
601{ 637{
602 u32 rate_flags; 638 u32 rate_flags;
603 int rate_idx; 639 int rate_idx;
@@ -613,8 +649,7 @@ static void iwl_tx_cmd_build_rate(struct iwl_priv *priv,
613 tx_cmd->data_retry_limit = data_retry_limit; 649 tx_cmd->data_retry_limit = data_retry_limit;
614 650
615 /* Set retry limit on RTS packets */ 651 /* Set retry limit on RTS packets */
616 rts_retry_limit = (is_hcca) ? RTS_HCCA_RETRY_LIMIT : 652 rts_retry_limit = RTS_DFAULT_RETRY_LIMIT;
617 RTS_DFAULT_RETRY_LIMIT;
618 if (data_retry_limit < rts_retry_limit) 653 if (data_retry_limit < rts_retry_limit)
619 rts_retry_limit = data_retry_limit; 654 rts_retry_limit = data_retry_limit;
620 tx_cmd->rts_retry_limit = rts_retry_limit; 655 tx_cmd->rts_retry_limit = rts_retry_limit;
@@ -794,7 +829,7 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
794 iwl_sta_modify_sleep_tx_count(priv, sta_id, 1); 829 iwl_sta_modify_sleep_tx_count(priv, sta_id, 1);
795 } 830 }
796 831
797 txq_id = skb_get_queue_mapping(skb); 832 txq_id = get_queue_from_ac(skb_get_queue_mapping(skb));
798 if (ieee80211_is_data_qos(fc)) { 833 if (ieee80211_is_data_qos(fc)) {
799 qc = ieee80211_get_qos_ctl(hdr); 834 qc = ieee80211_get_qos_ctl(hdr);
800 tid = qc[0] & IEEE80211_QOS_CTL_TID_MASK; 835 tid = qc[0] & IEEE80211_QOS_CTL_TID_MASK;
@@ -859,8 +894,7 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
859 iwl_tx_cmd_build_basic(priv, tx_cmd, info, hdr, sta_id); 894 iwl_tx_cmd_build_basic(priv, tx_cmd, info, hdr, sta_id);
860 iwl_dbg_log_tx_data_frame(priv, len, hdr); 895 iwl_dbg_log_tx_data_frame(priv, len, hdr);
861 896
862 /* set is_hcca to 0; it probably will never be implemented */ 897 iwl_tx_cmd_build_rate(priv, tx_cmd, info, fc);
863 iwl_tx_cmd_build_rate(priv, tx_cmd, info, fc, 0);
864 898
865 iwl_update_stats(priv, true, fc, len); 899 iwl_update_stats(priv, true, fc, len);
866 /* 900 /*
@@ -1260,7 +1294,7 @@ EXPORT_SYMBOL(iwl_tx_cmd_complete);
1260 * Find first available (lowest unused) Tx Queue, mark it "active". 1294 * Find first available (lowest unused) Tx Queue, mark it "active".
1261 * Called only when finding queue for aggregation. 1295 * Called only when finding queue for aggregation.
1262 * Should never return anything < 7, because they should already 1296 * Should never return anything < 7, because they should already
1263 * be in use as EDCA AC (0-3), Command (4), HCCA (5, 6). 1297 * be in use as EDCA AC (0-3), Command (4), reserved (5, 6)
1264 */ 1298 */
1265static int iwl_txq_ctx_activate_free(struct iwl_priv *priv) 1299static int iwl_txq_ctx_activate_free(struct iwl_priv *priv)
1266{ 1300{
@@ -1281,10 +1315,9 @@ int iwl_tx_agg_start(struct iwl_priv *priv, const u8 *ra, u16 tid, u16 *ssn)
1281 unsigned long flags; 1315 unsigned long flags;
1282 struct iwl_tid_data *tid_data; 1316 struct iwl_tid_data *tid_data;
1283 1317
1284 if (likely(tid < ARRAY_SIZE(default_tid_to_tx_fifo))) 1318 tx_fifo = get_fifo_from_tid(tid);
1285 tx_fifo = default_tid_to_tx_fifo[tid]; 1319 if (unlikely(tx_fifo < 0))
1286 else 1320 return tx_fifo;
1287 return -EINVAL;
1288 1321
1289 IWL_WARN(priv, "%s on ra = %pM tid = %d\n", 1322 IWL_WARN(priv, "%s on ra = %pM tid = %d\n",
1290 __func__, ra, tid); 1323 __func__, ra, tid);
@@ -1345,13 +1378,9 @@ int iwl_tx_agg_stop(struct iwl_priv *priv , const u8 *ra, u16 tid)
1345 return -EINVAL; 1378 return -EINVAL;
1346 } 1379 }
1347 1380
1348 if (unlikely(tid >= MAX_TID_COUNT)) 1381 tx_fifo_id = get_fifo_from_tid(tid);
1349 return -EINVAL; 1382 if (unlikely(tx_fifo_id < 0))
1350 1383 return tx_fifo_id;
1351 if (likely(tid < ARRAY_SIZE(default_tid_to_tx_fifo)))
1352 tx_fifo_id = default_tid_to_tx_fifo[tid];
1353 else
1354 return -EINVAL;
1355 1384
1356 sta_id = iwl_find_station(priv, ra); 1385 sta_id = iwl_find_station(priv, ra);
1357 1386
@@ -1419,7 +1448,7 @@ int iwl_txq_check_empty(struct iwl_priv *priv, int sta_id, u8 tid, int txq_id)
1419 if ((txq_id == tid_data->agg.txq_id) && 1448 if ((txq_id == tid_data->agg.txq_id) &&
1420 (q->read_ptr == q->write_ptr)) { 1449 (q->read_ptr == q->write_ptr)) {
1421 u16 ssn = SEQ_TO_SN(tid_data->seq_number); 1450 u16 ssn = SEQ_TO_SN(tid_data->seq_number);
1422 int tx_fifo = default_tid_to_tx_fifo[tid]; 1451 int tx_fifo = get_fifo_from_tid(tid);
1423 IWL_DEBUG_HT(priv, "HW queue empty: continue DELBA flow\n"); 1452 IWL_DEBUG_HT(priv, "HW queue empty: continue DELBA flow\n");
1424 priv->cfg->ops->lib->txq_agg_disable(priv, txq_id, 1453 priv->cfg->ops->lib->txq_agg_disable(priv, txq_id,
1425 ssn, tx_fifo); 1454 ssn, tx_fifo);