aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-rxon.c3
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-tx.c53
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.c23
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-dev.h11
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-helpers.h13
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-rx.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-trans-int-pcie.h14
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-trans-tx-pcie.c8
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-trans.c223
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-trans.h19
10 files changed, 201 insertions, 168 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c
index 7ce56ff4a525..b4d7460f05ca 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c
@@ -835,7 +835,8 @@ void iwlagn_bss_info_changed(struct ieee80211_hw *hw,
835 */ 835 */
836 if (ctx->last_tx_rejected) { 836 if (ctx->last_tx_rejected) {
837 ctx->last_tx_rejected = false; 837 ctx->last_tx_rejected = false;
838 iwl_wake_any_queue(priv, ctx); 838 iwl_trans_wake_any_queue(trans(priv),
839 ctx->ctxid);
839 } 840 }
840 ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK; 841 ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
841 842
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
index b02125a6a437..32e39059b9bf 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
@@ -278,14 +278,11 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
278 struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; 278 struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
279 struct iwl_device_cmd *dev_cmd = NULL; 279 struct iwl_device_cmd *dev_cmd = NULL;
280 struct iwl_tx_cmd *tx_cmd; 280 struct iwl_tx_cmd *tx_cmd;
281 int txq_id;
282 281
283 u16 seq_number = 0;
284 __le16 fc; 282 __le16 fc;
285 u8 hdr_len; 283 u8 hdr_len;
286 u16 len; 284 u16 len;
287 u8 sta_id; 285 u8 sta_id;
288 u8 tid = 0;
289 unsigned long flags; 286 unsigned long flags;
290 bool is_agg = false; 287 bool is_agg = false;
291 288
@@ -343,50 +340,9 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
343 iwl_sta_modify_sleep_tx_count(priv, sta_id, 1); 340 iwl_sta_modify_sleep_tx_count(priv, sta_id, 1);
344 } 341 }
345 342
346 /*
347 * Send this frame after DTIM -- there's a special queue
348 * reserved for this for contexts that support AP mode.
349 */
350 if (info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM) {
351 txq_id = ctx->mcast_queue;
352 /*
353 * The microcode will clear the more data
354 * bit in the last frame it transmits.
355 */
356 hdr->frame_control |=
357 cpu_to_le16(IEEE80211_FCTL_MOREDATA);
358 } else if (info->flags & IEEE80211_TX_CTL_TX_OFFCHAN)
359 txq_id = IWL_AUX_QUEUE;
360 else
361 txq_id = ctx->ac_to_queue[skb_get_queue_mapping(skb)];
362
363 /* irqs already disabled/saved above when locking priv->shrd->lock */ 343 /* irqs already disabled/saved above when locking priv->shrd->lock */
364 spin_lock(&priv->shrd->sta_lock); 344 spin_lock(&priv->shrd->sta_lock);
365 345
366 if (ieee80211_is_data_qos(fc)) {
367 u8 *qc = NULL;
368 struct iwl_tid_data *tid_data;
369 qc = ieee80211_get_qos_ctl(hdr);
370 tid = qc[0] & IEEE80211_QOS_CTL_TID_MASK;
371 tid_data = &priv->shrd->tid_data[sta_id][tid];
372
373 if (WARN_ON_ONCE(tid >= IWL_MAX_TID_COUNT))
374 goto drop_unlock_sta;
375
376 seq_number = tid_data->seq_number;
377 seq_number &= IEEE80211_SCTL_SEQ;
378 hdr->seq_ctrl = hdr->seq_ctrl &
379 cpu_to_le16(IEEE80211_SCTL_FRAG);
380 hdr->seq_ctrl |= cpu_to_le16(seq_number);
381 seq_number += 0x10;
382 /* aggregation is on for this <sta,tid> */
383 if (info->flags & IEEE80211_TX_CTL_AMPDU &&
384 tid_data->agg.state == IWL_AGG_ON) {
385 txq_id = tid_data->agg.txq_id;
386 is_agg = true;
387 }
388 }
389
390 dev_cmd = kmem_cache_alloc(priv->tx_cmd_pool, GFP_ATOMIC); 346 dev_cmd = kmem_cache_alloc(priv->tx_cmd_pool, GFP_ATOMIC);
391 347
392 if (unlikely(!dev_cmd)) 348 if (unlikely(!dev_cmd))
@@ -416,16 +372,9 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
416 info->driver_data[0] = ctx; 372 info->driver_data[0] = ctx;
417 info->driver_data[1] = dev_cmd; 373 info->driver_data[1] = dev_cmd;
418 374
419 if (iwl_trans_tx(trans(priv), skb, dev_cmd, txq_id, fc, is_agg)) 375 if (iwl_trans_tx(trans(priv), skb, dev_cmd, ctx->ctxid, sta_id))
420 goto drop_unlock_sta; 376 goto drop_unlock_sta;
421 377
422 if (ieee80211_is_data_qos(fc)) {
423 priv->shrd->tid_data[sta_id][tid].tfds_in_queue++;
424 if (!ieee80211_has_morefrags(fc))
425 priv->shrd->tid_data[sta_id][tid].seq_number =
426 seq_number;
427 }
428
429 spin_unlock(&priv->shrd->sta_lock); 378 spin_unlock(&priv->shrd->sta_lock);
430 spin_unlock_irqrestore(&priv->shrd->lock, flags); 379 spin_unlock_irqrestore(&priv->shrd->lock, flags);
431 380
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index cfb4a4ae52ce..60b964bd5cf8 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -617,24 +617,6 @@ static int iwl_alloc_fw_desc(struct iwl_priv *priv, struct fw_desc *desc,
617 617
618static void iwl_init_context(struct iwl_priv *priv, u32 ucode_flags) 618static void iwl_init_context(struct iwl_priv *priv, u32 ucode_flags)
619{ 619{
620 static const u8 iwlagn_bss_ac_to_fifo[] = {
621 IWL_TX_FIFO_VO,
622 IWL_TX_FIFO_VI,
623 IWL_TX_FIFO_BE,
624 IWL_TX_FIFO_BK,
625 };
626 static const u8 iwlagn_bss_ac_to_queue[] = {
627 0, 1, 2, 3,
628 };
629 static const u8 iwlagn_pan_ac_to_fifo[] = {
630 IWL_TX_FIFO_VO_IPAN,
631 IWL_TX_FIFO_VI_IPAN,
632 IWL_TX_FIFO_BE_IPAN,
633 IWL_TX_FIFO_BK_IPAN,
634 };
635 static const u8 iwlagn_pan_ac_to_queue[] = {
636 7, 6, 5, 4,
637 };
638 int i; 620 int i;
639 621
640 /* 622 /*
@@ -656,8 +638,6 @@ static void iwl_init_context(struct iwl_priv *priv, u32 ucode_flags)
656 priv->contexts[IWL_RXON_CTX_BSS].qos_cmd = REPLY_QOS_PARAM; 638 priv->contexts[IWL_RXON_CTX_BSS].qos_cmd = REPLY_QOS_PARAM;
657 priv->contexts[IWL_RXON_CTX_BSS].ap_sta_id = IWL_AP_ID; 639 priv->contexts[IWL_RXON_CTX_BSS].ap_sta_id = IWL_AP_ID;
658 priv->contexts[IWL_RXON_CTX_BSS].wep_key_cmd = REPLY_WEPKEY; 640 priv->contexts[IWL_RXON_CTX_BSS].wep_key_cmd = REPLY_WEPKEY;
659 priv->contexts[IWL_RXON_CTX_BSS].ac_to_fifo = iwlagn_bss_ac_to_fifo;
660 priv->contexts[IWL_RXON_CTX_BSS].ac_to_queue = iwlagn_bss_ac_to_queue;
661 priv->contexts[IWL_RXON_CTX_BSS].exclusive_interface_modes = 641 priv->contexts[IWL_RXON_CTX_BSS].exclusive_interface_modes =
662 BIT(NL80211_IFTYPE_ADHOC); 642 BIT(NL80211_IFTYPE_ADHOC);
663 priv->contexts[IWL_RXON_CTX_BSS].interface_modes = 643 priv->contexts[IWL_RXON_CTX_BSS].interface_modes =
@@ -677,9 +657,6 @@ static void iwl_init_context(struct iwl_priv *priv, u32 ucode_flags)
677 priv->contexts[IWL_RXON_CTX_PAN].wep_key_cmd = REPLY_WIPAN_WEPKEY; 657 priv->contexts[IWL_RXON_CTX_PAN].wep_key_cmd = REPLY_WIPAN_WEPKEY;
678 priv->contexts[IWL_RXON_CTX_PAN].bcast_sta_id = IWLAGN_PAN_BCAST_ID; 658 priv->contexts[IWL_RXON_CTX_PAN].bcast_sta_id = IWLAGN_PAN_BCAST_ID;
679 priv->contexts[IWL_RXON_CTX_PAN].station_flags = STA_FLG_PAN_STATION; 659 priv->contexts[IWL_RXON_CTX_PAN].station_flags = STA_FLG_PAN_STATION;
680 priv->contexts[IWL_RXON_CTX_PAN].ac_to_fifo = iwlagn_pan_ac_to_fifo;
681 priv->contexts[IWL_RXON_CTX_PAN].ac_to_queue = iwlagn_pan_ac_to_queue;
682 priv->contexts[IWL_RXON_CTX_PAN].mcast_queue = IWL_IPAN_MCAST_QUEUE;
683 priv->contexts[IWL_RXON_CTX_PAN].interface_modes = 660 priv->contexts[IWL_RXON_CTX_PAN].interface_modes =
684 BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_AP); 661 BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_AP);
685 662
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index 977015b47c64..2e75429f5ac6 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -244,13 +244,6 @@ struct iwl_channel_info {
244#define IWL_DEFAULT_CMD_QUEUE_NUM 4 244#define IWL_DEFAULT_CMD_QUEUE_NUM 4
245#define IWL_IPAN_CMD_QUEUE_NUM 9 245#define IWL_IPAN_CMD_QUEUE_NUM 9
246 246
247/*
248 * This queue number is required for proper operation
249 * because the ucode will stop/start the scheduler as
250 * required.
251 */
252#define IWL_IPAN_MCAST_QUEUE 8
253
254#define IEEE80211_DATA_LEN 2304 247#define IEEE80211_DATA_LEN 2304
255#define IEEE80211_4ADDR_LEN 30 248#define IEEE80211_4ADDR_LEN 30
256#define IEEE80211_HLEN (IEEE80211_4ADDR_LEN) 249#define IEEE80211_HLEN (IEEE80211_4ADDR_LEN)
@@ -965,10 +958,6 @@ struct iwl_notification_wait {
965struct iwl_rxon_context { 958struct iwl_rxon_context {
966 struct ieee80211_vif *vif; 959 struct ieee80211_vif *vif;
967 960
968 const u8 *ac_to_fifo;
969 const u8 *ac_to_queue;
970 u8 mcast_queue;
971
972 /* 961 /*
973 * We could use the vif to indicate active, but we 962 * We could use the vif to indicate active, but we
974 * also need it to be active during disabling when 963 * also need it to be active during disabling when
diff --git a/drivers/net/wireless/iwlwifi/iwl-helpers.h b/drivers/net/wireless/iwlwifi/iwl-helpers.h
index 8ca624d2a8b0..7f92d14083ca 100644
--- a/drivers/net/wireless/iwlwifi/iwl-helpers.h
+++ b/drivers/net/wireless/iwlwifi/iwl-helpers.h
@@ -113,19 +113,6 @@ static inline void iwl_stop_queue(struct iwl_priv *priv,
113 ieee80211_stop_queue(priv->hw, ac); 113 ieee80211_stop_queue(priv->hw, ac);
114} 114}
115 115
116static inline void iwl_wake_any_queue(struct iwl_priv *priv,
117 struct iwl_rxon_context *ctx)
118{
119 u8 ac;
120
121 for (ac = 0; ac < AC_NUM; ac++) {
122 IWL_DEBUG_INFO(priv, "Queue Status: Q[%d] %s\n",
123 ac, (atomic_read(&priv->queue_stop_count[ac]) > 0)
124 ? "stopped" : "awake");
125 iwl_wake_queue(priv, &priv->txq[ctx->ac_to_queue[ac]]);
126 }
127}
128
129#ifdef ieee80211_stop_queue 116#ifdef ieee80211_stop_queue
130#undef ieee80211_stop_queue 117#undef ieee80211_stop_queue
131#endif 118#endif
diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c
index 2c6659c82f92..8572548dd4a2 100644
--- a/drivers/net/wireless/iwlwifi/iwl-rx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-rx.c
@@ -699,7 +699,7 @@ static void iwl_pass_packet_to_mac80211(struct iwl_priv *priv,
699 ctx->active.bssid_addr)) 699 ctx->active.bssid_addr))
700 continue; 700 continue;
701 ctx->last_tx_rejected = false; 701 ctx->last_tx_rejected = false;
702 iwl_wake_any_queue(priv, ctx); 702 iwl_trans_wake_any_queue(trans(priv), ctx->ctxid);
703 } 703 }
704 } 704 }
705 705
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-int-pcie.h b/drivers/net/wireless/iwlwifi/iwl-trans-int-pcie.h
index f443c106291a..d73ebefa7d05 100644
--- a/drivers/net/wireless/iwlwifi/iwl-trans-int-pcie.h
+++ b/drivers/net/wireless/iwlwifi/iwl-trans-int-pcie.h
@@ -107,6 +107,13 @@ struct iwl_dma_ptr {
107 size_t size; 107 size_t size;
108}; 108};
109 109
110/*
111 * This queue number is required for proper operation
112 * because the ucode will stop/start the scheduler as
113 * required.
114 */
115#define IWL_IPAN_MCAST_QUEUE 8
116
110/** 117/**
111 * struct iwl_trans_pcie - PCIe transport specific data 118 * struct iwl_trans_pcie - PCIe transport specific data
112 * @rxq: all the RX queue data 119 * @rxq: all the RX queue data
@@ -115,6 +122,9 @@ struct iwl_dma_ptr {
115 * @scd_base_addr: scheduler sram base address in SRAM 122 * @scd_base_addr: scheduler sram base address in SRAM
116 * @scd_bc_tbls: pointer to the byte count table of the scheduler 123 * @scd_bc_tbls: pointer to the byte count table of the scheduler
117 * @kw: keep warm address 124 * @kw: keep warm address
125 * @ac_to_fifo: to what fifo is a specifc AC mapped ?
126 * @ac_to_queue: to what tx queue is a specifc AC mapped ?
127 * @mcast_queue:
118 */ 128 */
119struct iwl_trans_pcie { 129struct iwl_trans_pcie {
120 struct iwl_rx_queue rxq; 130 struct iwl_rx_queue rxq;
@@ -136,6 +146,10 @@ struct iwl_trans_pcie {
136 u32 scd_base_addr; 146 u32 scd_base_addr;
137 struct iwl_dma_ptr scd_bc_tbls; 147 struct iwl_dma_ptr scd_bc_tbls;
138 struct iwl_dma_ptr kw; 148 struct iwl_dma_ptr kw;
149
150 const u8 *ac_to_fifo[NUM_IWL_RXON_CTX];
151 const u8 *ac_to_queue[NUM_IWL_RXON_CTX];
152 u8 mcast_queue[NUM_IWL_RXON_CTX];
139}; 153};
140 154
141#define IWL_TRANS_GET_PCIE_TRANS(_iwl_trans) \ 155#define IWL_TRANS_GET_PCIE_TRANS(_iwl_trans) \
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-tx-pcie.c b/drivers/net/wireless/iwlwifi/iwl-trans-tx-pcie.c
index 96ad0afd185e..6af33104228a 100644
--- a/drivers/net/wireless/iwlwifi/iwl-trans-tx-pcie.c
+++ b/drivers/net/wireless/iwlwifi/iwl-trans-tx-pcie.c
@@ -424,10 +424,12 @@ void iwl_trans_tx_queue_set_status(struct iwl_priv *priv,
424 scd_retry ? "BA" : "AC/CMD", txq_id, tx_fifo_id); 424 scd_retry ? "BA" : "AC/CMD", txq_id, tx_fifo_id);
425} 425}
426 426
427static inline int get_fifo_from_tid(struct iwl_rxon_context *ctx, u16 tid) 427static inline int get_fifo_from_tid(struct iwl_trans_pcie *trans_pcie,
428 u8 ctx, u16 tid)
428{ 429{
430 const u8 *ac_to_fifo = trans_pcie->ac_to_fifo[ctx];
429 if (likely(tid < ARRAY_SIZE(tid_to_ac))) 431 if (likely(tid < ARRAY_SIZE(tid_to_ac)))
430 return ctx->ac_to_fifo[tid_to_ac[tid]]; 432 return ac_to_fifo[tid_to_ac[tid]];
431 433
432 /* no support for TIDs 8-15 yet */ 434 /* no support for TIDs 8-15 yet */
433 return -EINVAL; 435 return -EINVAL;
@@ -451,7 +453,7 @@ void iwl_trans_pcie_txq_agg_setup(struct iwl_priv *priv,
451 if (WARN_ON(tid >= IWL_MAX_TID_COUNT)) 453 if (WARN_ON(tid >= IWL_MAX_TID_COUNT))
452 return; 454 return;
453 455
454 tx_fifo = get_fifo_from_tid(&priv->contexts[ctx], tid); 456 tx_fifo = get_fifo_from_tid(trans_pcie, ctx, tid);
455 if (WARN_ON(tx_fifo < 0)) { 457 if (WARN_ON(tx_fifo < 0)) {
456 IWL_ERR(trans, "txq_agg_setup, bad fifo: %d\n", tx_fifo); 458 IWL_ERR(trans, "txq_agg_setup, bad fifo: %d\n", tx_fifo);
457 return; 459 return;
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.c b/drivers/net/wireless/iwlwifi/iwl-trans.c
index 7de042c6c258..133b227cb64d 100644
--- a/drivers/net/wireless/iwlwifi/iwl-trans.c
+++ b/drivers/net/wireless/iwlwifi/iwl-trans.c
@@ -714,12 +714,75 @@ static int iwl_trans_pcie_prepare_card_hw(struct iwl_trans *trans)
714 return ret; 714 return ret;
715} 715}
716 716
717#define IWL_AC_UNSET -1
718
719struct queue_to_fifo_ac {
720 s8 fifo, ac;
721};
722
723static const struct queue_to_fifo_ac iwlagn_default_queue_to_tx_fifo[] = {
724 { IWL_TX_FIFO_VO, IEEE80211_AC_VO, },
725 { IWL_TX_FIFO_VI, IEEE80211_AC_VI, },
726 { IWL_TX_FIFO_BE, IEEE80211_AC_BE, },
727 { IWL_TX_FIFO_BK, IEEE80211_AC_BK, },
728 { IWLAGN_CMD_FIFO_NUM, IWL_AC_UNSET, },
729 { IWL_TX_FIFO_UNUSED, IWL_AC_UNSET, },
730 { IWL_TX_FIFO_UNUSED, IWL_AC_UNSET, },
731 { IWL_TX_FIFO_UNUSED, IWL_AC_UNSET, },
732 { IWL_TX_FIFO_UNUSED, IWL_AC_UNSET, },
733 { IWL_TX_FIFO_UNUSED, IWL_AC_UNSET, },
734 { IWL_TX_FIFO_UNUSED, IWL_AC_UNSET, },
735};
736
737static const struct queue_to_fifo_ac iwlagn_ipan_queue_to_tx_fifo[] = {
738 { IWL_TX_FIFO_VO, IEEE80211_AC_VO, },
739 { IWL_TX_FIFO_VI, IEEE80211_AC_VI, },
740 { IWL_TX_FIFO_BE, IEEE80211_AC_BE, },
741 { IWL_TX_FIFO_BK, IEEE80211_AC_BK, },
742 { IWL_TX_FIFO_BK_IPAN, IEEE80211_AC_BK, },
743 { IWL_TX_FIFO_BE_IPAN, IEEE80211_AC_BE, },
744 { IWL_TX_FIFO_VI_IPAN, IEEE80211_AC_VI, },
745 { IWL_TX_FIFO_VO_IPAN, IEEE80211_AC_VO, },
746 { IWL_TX_FIFO_BE_IPAN, 2, },
747 { IWLAGN_CMD_FIFO_NUM, IWL_AC_UNSET, },
748 { IWL_TX_FIFO_AUX, IWL_AC_UNSET, },
749};
750
751static const u8 iwlagn_bss_ac_to_fifo[] = {
752 IWL_TX_FIFO_VO,
753 IWL_TX_FIFO_VI,
754 IWL_TX_FIFO_BE,
755 IWL_TX_FIFO_BK,
756};
757static const u8 iwlagn_bss_ac_to_queue[] = {
758 0, 1, 2, 3,
759};
760static const u8 iwlagn_pan_ac_to_fifo[] = {
761 IWL_TX_FIFO_VO_IPAN,
762 IWL_TX_FIFO_VI_IPAN,
763 IWL_TX_FIFO_BE_IPAN,
764 IWL_TX_FIFO_BK_IPAN,
765};
766static const u8 iwlagn_pan_ac_to_queue[] = {
767 7, 6, 5, 4,
768};
769
717static int iwl_trans_pcie_start_device(struct iwl_trans *trans) 770static int iwl_trans_pcie_start_device(struct iwl_trans *trans)
718{ 771{
719 int ret; 772 int ret;
720 struct iwl_priv *priv = priv(trans); 773 struct iwl_priv *priv = priv(trans);
774 struct iwl_trans_pcie *trans_pcie =
775 IWL_TRANS_GET_PCIE_TRANS(trans);
721 776
722 priv->shrd->ucode_owner = IWL_OWNERSHIP_DRIVER; 777 priv->shrd->ucode_owner = IWL_OWNERSHIP_DRIVER;
778 trans_pcie->ac_to_queue[IWL_RXON_CTX_BSS] = iwlagn_bss_ac_to_queue;
779 trans_pcie->ac_to_queue[IWL_RXON_CTX_PAN] = iwlagn_pan_ac_to_queue;
780
781 trans_pcie->ac_to_fifo[IWL_RXON_CTX_BSS] = iwlagn_bss_ac_to_fifo;
782 trans_pcie->ac_to_fifo[IWL_RXON_CTX_PAN] = iwlagn_pan_ac_to_fifo;
783
784 trans_pcie->mcast_queue[IWL_RXON_CTX_BSS] = 0;
785 trans_pcie->mcast_queue[IWL_RXON_CTX_PAN] = IWL_IPAN_MCAST_QUEUE;
723 786
724 if ((hw_params(priv).sku & EEPROM_SKU_CAP_AMT_ENABLE) && 787 if ((hw_params(priv).sku & EEPROM_SKU_CAP_AMT_ENABLE) &&
725 iwl_trans_pcie_prepare_card_hw(trans)) { 788 iwl_trans_pcie_prepare_card_hw(trans)) {
@@ -773,39 +836,6 @@ static void iwl_trans_txq_set_sched(struct iwl_trans *trans, u32 mask)
773 iwl_write_prph(bus(trans), SCD_TXFACT, mask); 836 iwl_write_prph(bus(trans), SCD_TXFACT, mask);
774} 837}
775 838
776#define IWL_AC_UNSET -1
777
778struct queue_to_fifo_ac {
779 s8 fifo, ac;
780};
781
782static const struct queue_to_fifo_ac iwlagn_default_queue_to_tx_fifo[] = {
783 { IWL_TX_FIFO_VO, IEEE80211_AC_VO, },
784 { IWL_TX_FIFO_VI, IEEE80211_AC_VI, },
785 { IWL_TX_FIFO_BE, IEEE80211_AC_BE, },
786 { IWL_TX_FIFO_BK, IEEE80211_AC_BK, },
787 { IWLAGN_CMD_FIFO_NUM, IWL_AC_UNSET, },
788 { IWL_TX_FIFO_UNUSED, IWL_AC_UNSET, },
789 { IWL_TX_FIFO_UNUSED, IWL_AC_UNSET, },
790 { IWL_TX_FIFO_UNUSED, IWL_AC_UNSET, },
791 { IWL_TX_FIFO_UNUSED, IWL_AC_UNSET, },
792 { IWL_TX_FIFO_UNUSED, IWL_AC_UNSET, },
793 { IWL_TX_FIFO_UNUSED, IWL_AC_UNSET, },
794};
795
796static const struct queue_to_fifo_ac iwlagn_ipan_queue_to_tx_fifo[] = {
797 { IWL_TX_FIFO_VO, IEEE80211_AC_VO, },
798 { IWL_TX_FIFO_VI, IEEE80211_AC_VI, },
799 { IWL_TX_FIFO_BE, IEEE80211_AC_BE, },
800 { IWL_TX_FIFO_BK, IEEE80211_AC_BK, },
801 { IWL_TX_FIFO_BK_IPAN, IEEE80211_AC_BK, },
802 { IWL_TX_FIFO_BE_IPAN, IEEE80211_AC_BE, },
803 { IWL_TX_FIFO_VI_IPAN, IEEE80211_AC_VI, },
804 { IWL_TX_FIFO_VO_IPAN, IEEE80211_AC_VO, },
805 { IWL_TX_FIFO_BE_IPAN, 2, },
806 { IWLAGN_CMD_FIFO_NUM, IWL_AC_UNSET, },
807 { IWL_TX_FIFO_AUX, IWL_AC_UNSET, },
808};
809static void iwl_trans_pcie_tx_start(struct iwl_trans *trans) 839static void iwl_trans_pcie_tx_start(struct iwl_trans *trans)
810{ 840{
811 const struct queue_to_fifo_ac *queue_to_fifo; 841 const struct queue_to_fifo_ac *queue_to_fifo;
@@ -1012,22 +1042,75 @@ static void iwl_trans_pcie_stop_device(struct iwl_trans *trans)
1012 iwl_apm_stop(priv(trans)); 1042 iwl_apm_stop(priv(trans));
1013} 1043}
1014 1044
1015static int iwl_trans_pcie_tx(struct iwl_priv *priv, struct sk_buff *skb, 1045static int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb,
1016 struct iwl_device_cmd *dev_cmd, int txq_id, 1046 struct iwl_device_cmd *dev_cmd, u8 ctx, u8 sta_id)
1017 __le16 fc, bool ampdu)
1018{ 1047{
1019 struct iwl_tx_queue *txq = &priv->txq[txq_id]; 1048 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
1020 struct iwl_queue *q = &txq->q; 1049 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
1050 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
1021 struct iwl_tx_cmd *tx_cmd = &dev_cmd->cmd.tx; 1051 struct iwl_tx_cmd *tx_cmd = &dev_cmd->cmd.tx;
1022 struct iwl_cmd_meta *out_meta; 1052 struct iwl_cmd_meta *out_meta;
1053 struct iwl_tx_queue *txq;
1054 struct iwl_queue *q;
1023 1055
1024 dma_addr_t phys_addr = 0; 1056 dma_addr_t phys_addr = 0;
1025 dma_addr_t txcmd_phys; 1057 dma_addr_t txcmd_phys;
1026 dma_addr_t scratch_phys; 1058 dma_addr_t scratch_phys;
1027 u16 len, firstlen, secondlen; 1059 u16 len, firstlen, secondlen;
1060 u16 seq_number = 0;
1028 u8 wait_write_ptr = 0; 1061 u8 wait_write_ptr = 0;
1062 u8 txq_id;
1063 u8 tid = 0;
1064 bool is_agg = false;
1065 __le16 fc = hdr->frame_control;
1029 u8 hdr_len = ieee80211_hdrlen(fc); 1066 u8 hdr_len = ieee80211_hdrlen(fc);
1030 1067
1068 /*
1069 * Send this frame after DTIM -- there's a special queue
1070 * reserved for this for contexts that support AP mode.
1071 */
1072 if (info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM) {
1073 txq_id = trans_pcie->mcast_queue[ctx];
1074
1075 /*
1076 * The microcode will clear the more data
1077 * bit in the last frame it transmits.
1078 */
1079 hdr->frame_control |=
1080 cpu_to_le16(IEEE80211_FCTL_MOREDATA);
1081 } else if (info->flags & IEEE80211_TX_CTL_TX_OFFCHAN)
1082 txq_id = IWL_AUX_QUEUE;
1083 else
1084 txq_id =
1085 trans_pcie->ac_to_queue[ctx][skb_get_queue_mapping(skb)];
1086
1087 if (ieee80211_is_data_qos(fc)) {
1088 u8 *qc = NULL;
1089 struct iwl_tid_data *tid_data;
1090 qc = ieee80211_get_qos_ctl(hdr);
1091 tid = qc[0] & IEEE80211_QOS_CTL_TID_MASK;
1092 tid_data = &trans->shrd->tid_data[sta_id][tid];
1093
1094 if (WARN_ON_ONCE(tid >= IWL_MAX_TID_COUNT))
1095 return -1;
1096
1097 seq_number = tid_data->seq_number;
1098 seq_number &= IEEE80211_SCTL_SEQ;
1099 hdr->seq_ctrl = hdr->seq_ctrl &
1100 cpu_to_le16(IEEE80211_SCTL_FRAG);
1101 hdr->seq_ctrl |= cpu_to_le16(seq_number);
1102 seq_number += 0x10;
1103 /* aggregation is on for this <sta,tid> */
1104 if (info->flags & IEEE80211_TX_CTL_AMPDU &&
1105 tid_data->agg.state == IWL_AGG_ON) {
1106 txq_id = tid_data->agg.txq_id;
1107 is_agg = true;
1108 }
1109 }
1110
1111 txq = &priv(trans)->txq[txq_id];
1112 q = &txq->q;
1113
1031 /* Set up driver data for this TFD */ 1114 /* Set up driver data for this TFD */
1032 txq->skbs[q->write_ptr] = skb; 1115 txq->skbs[q->write_ptr] = skb;
1033 txq->cmd[q->write_ptr] = dev_cmd; 1116 txq->cmd[q->write_ptr] = dev_cmd;
@@ -1058,10 +1141,10 @@ static int iwl_trans_pcie_tx(struct iwl_priv *priv, struct sk_buff *skb,
1058 1141
1059 /* Physical address of this Tx command's header (not MAC header!), 1142 /* Physical address of this Tx command's header (not MAC header!),
1060 * within command buffer array. */ 1143 * within command buffer array. */
1061 txcmd_phys = dma_map_single(priv->bus->dev, 1144 txcmd_phys = dma_map_single(bus(trans)->dev,
1062 &dev_cmd->hdr, firstlen, 1145 &dev_cmd->hdr, firstlen,
1063 DMA_BIDIRECTIONAL); 1146 DMA_BIDIRECTIONAL);
1064 if (unlikely(dma_mapping_error(priv->bus->dev, txcmd_phys))) 1147 if (unlikely(dma_mapping_error(bus(trans)->dev, txcmd_phys)))
1065 return -1; 1148 return -1;
1066 dma_unmap_addr_set(out_meta, mapping, txcmd_phys); 1149 dma_unmap_addr_set(out_meta, mapping, txcmd_phys);
1067 dma_unmap_len_set(out_meta, len, firstlen); 1150 dma_unmap_len_set(out_meta, len, firstlen);
@@ -1077,10 +1160,10 @@ static int iwl_trans_pcie_tx(struct iwl_priv *priv, struct sk_buff *skb,
1077 * if any (802.11 null frames have no payload). */ 1160 * if any (802.11 null frames have no payload). */
1078 secondlen = skb->len - hdr_len; 1161 secondlen = skb->len - hdr_len;
1079 if (secondlen > 0) { 1162 if (secondlen > 0) {
1080 phys_addr = dma_map_single(priv->bus->dev, skb->data + hdr_len, 1163 phys_addr = dma_map_single(bus(trans)->dev, skb->data + hdr_len,
1081 secondlen, DMA_TO_DEVICE); 1164 secondlen, DMA_TO_DEVICE);
1082 if (unlikely(dma_mapping_error(priv->bus->dev, phys_addr))) { 1165 if (unlikely(dma_mapping_error(bus(trans)->dev, phys_addr))) {
1083 dma_unmap_single(priv->bus->dev, 1166 dma_unmap_single(bus(trans)->dev,
1084 dma_unmap_addr(out_meta, mapping), 1167 dma_unmap_addr(out_meta, mapping),
1085 dma_unmap_len(out_meta, len), 1168 dma_unmap_len(out_meta, len),
1086 DMA_BIDIRECTIONAL); 1169 DMA_BIDIRECTIONAL);
@@ -1089,36 +1172,35 @@ static int iwl_trans_pcie_tx(struct iwl_priv *priv, struct sk_buff *skb,
1089 } 1172 }
1090 1173
1091 /* Attach buffers to TFD */ 1174 /* Attach buffers to TFD */
1092 iwlagn_txq_attach_buf_to_tfd(trans(priv), txq, txcmd_phys, 1175 iwlagn_txq_attach_buf_to_tfd(trans, txq, txcmd_phys, firstlen, 1);
1093 firstlen, 1);
1094 if (secondlen > 0) 1176 if (secondlen > 0)
1095 iwlagn_txq_attach_buf_to_tfd(trans(priv), txq, phys_addr, 1177 iwlagn_txq_attach_buf_to_tfd(trans, txq, phys_addr,
1096 secondlen, 0); 1178 secondlen, 0);
1097 1179
1098 scratch_phys = txcmd_phys + sizeof(struct iwl_cmd_header) + 1180 scratch_phys = txcmd_phys + sizeof(struct iwl_cmd_header) +
1099 offsetof(struct iwl_tx_cmd, scratch); 1181 offsetof(struct iwl_tx_cmd, scratch);
1100 1182
1101 /* take back ownership of DMA buffer to enable update */ 1183 /* take back ownership of DMA buffer to enable update */
1102 dma_sync_single_for_cpu(priv->bus->dev, txcmd_phys, firstlen, 1184 dma_sync_single_for_cpu(bus(trans)->dev, txcmd_phys, firstlen,
1103 DMA_BIDIRECTIONAL); 1185 DMA_BIDIRECTIONAL);
1104 tx_cmd->dram_lsb_ptr = cpu_to_le32(scratch_phys); 1186 tx_cmd->dram_lsb_ptr = cpu_to_le32(scratch_phys);
1105 tx_cmd->dram_msb_ptr = iwl_get_dma_hi_addr(scratch_phys); 1187 tx_cmd->dram_msb_ptr = iwl_get_dma_hi_addr(scratch_phys);
1106 1188
1107 IWL_DEBUG_TX(priv, "sequence nr = 0X%x\n", 1189 IWL_DEBUG_TX(trans, "sequence nr = 0X%x\n",
1108 le16_to_cpu(dev_cmd->hdr.sequence)); 1190 le16_to_cpu(dev_cmd->hdr.sequence));
1109 IWL_DEBUG_TX(priv, "tx_flags = 0X%x\n", le32_to_cpu(tx_cmd->tx_flags)); 1191 IWL_DEBUG_TX(trans, "tx_flags = 0X%x\n", le32_to_cpu(tx_cmd->tx_flags));
1110 iwl_print_hex_dump(priv, IWL_DL_TX, (u8 *)tx_cmd, sizeof(*tx_cmd)); 1192 iwl_print_hex_dump(trans, IWL_DL_TX, (u8 *)tx_cmd, sizeof(*tx_cmd));
1111 iwl_print_hex_dump(priv, IWL_DL_TX, (u8 *)tx_cmd->hdr, hdr_len); 1193 iwl_print_hex_dump(trans, IWL_DL_TX, (u8 *)tx_cmd->hdr, hdr_len);
1112 1194
1113 /* Set up entry for this TFD in Tx byte-count array */ 1195 /* Set up entry for this TFD in Tx byte-count array */
1114 if (ampdu) 1196 if (is_agg)
1115 iwl_trans_txq_update_byte_cnt_tbl(trans(priv), txq, 1197 iwl_trans_txq_update_byte_cnt_tbl(trans, txq,
1116 le16_to_cpu(tx_cmd->len)); 1198 le16_to_cpu(tx_cmd->len));
1117 1199
1118 dma_sync_single_for_device(priv->bus->dev, txcmd_phys, firstlen, 1200 dma_sync_single_for_device(bus(trans)->dev, txcmd_phys, firstlen,
1119 DMA_BIDIRECTIONAL); 1201 DMA_BIDIRECTIONAL);
1120 1202
1121 trace_iwlwifi_dev_tx(priv, 1203 trace_iwlwifi_dev_tx(priv(trans),
1122 &((struct iwl_tfd *)txq->tfds)[txq->q.write_ptr], 1204 &((struct iwl_tfd *)txq->tfds)[txq->q.write_ptr],
1123 sizeof(struct iwl_tfd), 1205 sizeof(struct iwl_tfd),
1124 &dev_cmd->hdr, firstlen, 1206 &dev_cmd->hdr, firstlen,
@@ -1126,7 +1208,14 @@ static int iwl_trans_pcie_tx(struct iwl_priv *priv, struct sk_buff *skb,
1126 1208
1127 /* Tell device the write index *just past* this latest filled TFD */ 1209 /* Tell device the write index *just past* this latest filled TFD */
1128 q->write_ptr = iwl_queue_inc_wrap(q->write_ptr, q->n_bd); 1210 q->write_ptr = iwl_queue_inc_wrap(q->write_ptr, q->n_bd);
1129 iwl_txq_update_write_ptr(trans(priv), txq); 1211 iwl_txq_update_write_ptr(trans, txq);
1212
1213 if (ieee80211_is_data_qos(fc)) {
1214 trans->shrd->tid_data[sta_id][tid].tfds_in_queue++;
1215 if (!ieee80211_has_morefrags(fc))
1216 trans->shrd->tid_data[sta_id][tid].seq_number =
1217 seq_number;
1218 }
1130 1219
1131 /* 1220 /*
1132 * At this point the frame is "transmitted" successfully 1221 * At this point the frame is "transmitted" successfully
@@ -1137,9 +1226,9 @@ static int iwl_trans_pcie_tx(struct iwl_priv *priv, struct sk_buff *skb,
1137 if (iwl_queue_space(q) < q->high_mark) { 1226 if (iwl_queue_space(q) < q->high_mark) {
1138 if (wait_write_ptr) { 1227 if (wait_write_ptr) {
1139 txq->need_update = 1; 1228 txq->need_update = 1;
1140 iwl_txq_update_write_ptr(trans(priv), txq); 1229 iwl_txq_update_write_ptr(trans, txq);
1141 } else { 1230 } else {
1142 iwl_stop_queue(priv, txq); 1231 iwl_stop_queue(priv(trans), txq);
1143 } 1232 }
1144 } 1233 }
1145 return 0; 1234 return 0;
@@ -1262,6 +1351,23 @@ static int iwl_trans_pcie_resume(struct iwl_trans *trans)
1262 1351
1263#endif /* CONFIG_PM */ 1352#endif /* CONFIG_PM */
1264 1353
1354static void iwl_trans_pcie_wake_any_queue(struct iwl_trans *trans,
1355 u8 ctx)
1356{
1357 u8 ac, txq_id;
1358 struct iwl_trans_pcie *trans_pcie =
1359 IWL_TRANS_GET_PCIE_TRANS(trans);
1360
1361 for (ac = 0; ac < AC_NUM; ac++) {
1362 txq_id = trans_pcie->ac_to_queue[ctx][ac];
1363 IWL_DEBUG_INFO(trans, "Queue Status: Q[%d] %s\n",
1364 ac,
1365 (atomic_read(&priv(trans)->queue_stop_count[ac]) > 0)
1366 ? "stopped" : "awake");
1367 iwl_wake_queue(priv(trans), &priv(trans)->txq[txq_id]);
1368 }
1369}
1370
1265const struct iwl_trans_ops trans_ops_pcie; 1371const struct iwl_trans_ops trans_ops_pcie;
1266 1372
1267static struct iwl_trans *iwl_trans_pcie_alloc(struct iwl_shared *shrd) 1373static struct iwl_trans *iwl_trans_pcie_alloc(struct iwl_shared *shrd)
@@ -1842,6 +1948,7 @@ const struct iwl_trans_ops trans_ops_pcie = {
1842 .stop_device = iwl_trans_pcie_stop_device, 1948 .stop_device = iwl_trans_pcie_stop_device,
1843 1949
1844 .tx_start = iwl_trans_pcie_tx_start, 1950 .tx_start = iwl_trans_pcie_tx_start,
1951 .wake_any_queue = iwl_trans_pcie_wake_any_queue,
1845 1952
1846 .send_cmd = iwl_trans_pcie_send_cmd, 1953 .send_cmd = iwl_trans_pcie_send_cmd,
1847 .send_cmd_pdu = iwl_trans_pcie_send_cmd_pdu, 1954 .send_cmd_pdu = iwl_trans_pcie_send_cmd_pdu,
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h
index 0691d39bce05..0fee8840c0aa 100644
--- a/drivers/net/wireless/iwlwifi/iwl-trans.h
+++ b/drivers/net/wireless/iwlwifi/iwl-trans.h
@@ -88,6 +88,7 @@ struct iwl_device_cmd;
88 * probe. 88 * probe.
89 * @tx_start: starts and configures all the Tx fifo - usually done once the fw 89 * @tx_start: starts and configures all the Tx fifo - usually done once the fw
90 * is alive. 90 * is alive.
91 * @wake_any_queue: wake all the queues of a specfic context IWL_RXON_CTX_*
91 * @stop_device:stops the whole device (embedded CPU put to reset) 92 * @stop_device:stops the whole device (embedded CPU put to reset)
92 * @send_cmd:send a host command 93 * @send_cmd:send a host command
93 * @send_cmd_pdu:send a host command: flags can be CMD_* 94 * @send_cmd_pdu:send a host command: flags can be CMD_*
@@ -113,13 +114,14 @@ struct iwl_trans_ops {
113 void (*stop_device)(struct iwl_trans *trans); 114 void (*stop_device)(struct iwl_trans *trans);
114 void (*tx_start)(struct iwl_trans *trans); 115 void (*tx_start)(struct iwl_trans *trans);
115 116
117 void (*wake_any_queue)(struct iwl_trans *trans, u8 ctx);
118
116 int (*send_cmd)(struct iwl_trans *trans, struct iwl_host_cmd *cmd); 119 int (*send_cmd)(struct iwl_trans *trans, struct iwl_host_cmd *cmd);
117 120
118 int (*send_cmd_pdu)(struct iwl_trans *trans, u8 id, u32 flags, u16 len, 121 int (*send_cmd_pdu)(struct iwl_trans *trans, u8 id, u32 flags, u16 len,
119 const void *data); 122 const void *data);
120 int (*tx)(struct iwl_priv *priv, struct sk_buff *skb, 123 int (*tx)(struct iwl_trans *trans, struct sk_buff *skb,
121 struct iwl_device_cmd *dev_cmd, 124 struct iwl_device_cmd *dev_cmd, u8 ctx, u8 sta_id);
122 int txq_id, __le16 fc, bool ampdu);
123 void (*reclaim)(struct iwl_trans *trans, int txq_id, int ssn, 125 void (*reclaim)(struct iwl_trans *trans, int txq_id, int ssn,
124 u32 status, struct sk_buff_head *skbs); 126 u32 status, struct sk_buff_head *skbs);
125 127
@@ -178,6 +180,12 @@ static inline void iwl_trans_tx_start(struct iwl_trans *trans)
178 trans->ops->tx_start(trans); 180 trans->ops->tx_start(trans);
179} 181}
180 182
183static inline void iwl_trans_wake_any_queue(struct iwl_trans *trans, u8 ctx)
184{
185 trans->ops->wake_any_queue(trans, ctx);
186}
187
188
181static inline int iwl_trans_send_cmd(struct iwl_trans *trans, 189static inline int iwl_trans_send_cmd(struct iwl_trans *trans,
182 struct iwl_host_cmd *cmd) 190 struct iwl_host_cmd *cmd)
183{ 191{
@@ -191,10 +199,9 @@ static inline int iwl_trans_send_cmd_pdu(struct iwl_trans *trans, u8 id,
191} 199}
192 200
193static inline int iwl_trans_tx(struct iwl_trans *trans, struct sk_buff *skb, 201static inline int iwl_trans_tx(struct iwl_trans *trans, struct sk_buff *skb,
194 struct iwl_device_cmd *dev_cmd, 202 struct iwl_device_cmd *dev_cmd, u8 ctx, u8 sta_id)
195 int txq_id, __le16 fc, bool ampdu)
196{ 203{
197 return trans->ops->tx(priv(trans), skb, dev_cmd, txq_id, fc, ampdu); 204 return trans->ops->tx(trans, skb, dev_cmd, ctx, sta_id);
198} 205}
199 206
200static inline void iwl_trans_reclaim(struct iwl_trans *trans, int txq_id, 207static inline void iwl_trans_reclaim(struct iwl_trans *trans, int txq_id,