diff options
author | Christian Lamparter <chunkeey@googlemail.com> | 2011-01-22 18:18:28 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2011-01-27 16:03:56 -0500 |
commit | aa32452dcff1f95976fb28b5a28ecc93f47d0472 (patch) | |
tree | d5f92b88218125acb51e17b21af489b9aee4bd2e /drivers/net/wireless/ath/carl9170 | |
parent | c42d6cf25d648d95387d8a881aa0cab657470726 (diff) |
carl9170: utilize fw seq counter for mgmt/non-QoS data frames
"mac80211 will properly assign sequence numbers to QoS-data
frames but cannot do so correctly for non-QoS-data and
management frames because beacons need them from that counter
as well and mac80211 cannot guarantee proper sequencing."
Signed-off-by: Christian Lamparter <chunkeey@googlemail.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/ath/carl9170')
-rw-r--r-- | drivers/net/wireless/ath/carl9170/carl9170.h | 1 | ||||
-rw-r--r-- | drivers/net/wireless/ath/carl9170/fw.c | 12 | ||||
-rw-r--r-- | drivers/net/wireless/ath/carl9170/main.c | 7 | ||||
-rw-r--r-- | drivers/net/wireless/ath/carl9170/tx.c | 3 |
4 files changed, 23 insertions, 0 deletions
diff --git a/drivers/net/wireless/ath/carl9170/carl9170.h b/drivers/net/wireless/ath/carl9170/carl9170.h index d07ff7f2fd92..420d437f9580 100644 --- a/drivers/net/wireless/ath/carl9170/carl9170.h +++ b/drivers/net/wireless/ath/carl9170/carl9170.h | |||
@@ -283,6 +283,7 @@ struct ar9170 { | |||
283 | unsigned int mem_blocks; | 283 | unsigned int mem_blocks; |
284 | unsigned int mem_block_size; | 284 | unsigned int mem_block_size; |
285 | unsigned int rx_size; | 285 | unsigned int rx_size; |
286 | unsigned int tx_seq_table; | ||
286 | } fw; | 287 | } fw; |
287 | 288 | ||
288 | /* reset / stuck frames/queue detection */ | 289 | /* reset / stuck frames/queue detection */ |
diff --git a/drivers/net/wireless/ath/carl9170/fw.c b/drivers/net/wireless/ath/carl9170/fw.c index a4e5b4458c00..9517ede9e2df 100644 --- a/drivers/net/wireless/ath/carl9170/fw.c +++ b/drivers/net/wireless/ath/carl9170/fw.c | |||
@@ -150,6 +150,7 @@ static int carl9170_fw(struct ar9170 *ar, const __u8 *data, size_t len) | |||
150 | const struct carl9170fw_otus_desc *otus_desc; | 150 | const struct carl9170fw_otus_desc *otus_desc; |
151 | const struct carl9170fw_chk_desc *chk_desc; | 151 | const struct carl9170fw_chk_desc *chk_desc; |
152 | const struct carl9170fw_last_desc *last_desc; | 152 | const struct carl9170fw_last_desc *last_desc; |
153 | const struct carl9170fw_txsq_desc *txsq_desc; | ||
153 | 154 | ||
154 | last_desc = carl9170_fw_find_desc(ar, LAST_MAGIC, | 155 | last_desc = carl9170_fw_find_desc(ar, LAST_MAGIC, |
155 | sizeof(*last_desc), CARL9170FW_LAST_DESC_CUR_VER); | 156 | sizeof(*last_desc), CARL9170FW_LAST_DESC_CUR_VER); |
@@ -299,6 +300,17 @@ static int carl9170_fw(struct ar9170 *ar, const __u8 *data, size_t len) | |||
299 | } | 300 | } |
300 | } | 301 | } |
301 | 302 | ||
303 | txsq_desc = carl9170_fw_find_desc(ar, TXSQ_MAGIC, | ||
304 | sizeof(*txsq_desc), CARL9170FW_TXSQ_DESC_CUR_VER); | ||
305 | |||
306 | if (txsq_desc) { | ||
307 | ar->fw.tx_seq_table = le32_to_cpu(txsq_desc->seq_table_addr); | ||
308 | if (!valid_cpu_addr(ar->fw.tx_seq_table)) | ||
309 | return -EINVAL; | ||
310 | } else { | ||
311 | ar->fw.tx_seq_table = 0; | ||
312 | } | ||
313 | |||
302 | #undef SUPPORTED | 314 | #undef SUPPORTED |
303 | return 0; | 315 | return 0; |
304 | } | 316 | } |
diff --git a/drivers/net/wireless/ath/carl9170/main.c b/drivers/net/wireless/ath/carl9170/main.c index ecfb80b059d1..ede3d7e5a048 100644 --- a/drivers/net/wireless/ath/carl9170/main.c +++ b/drivers/net/wireless/ath/carl9170/main.c | |||
@@ -662,6 +662,13 @@ init: | |||
662 | goto unlock; | 662 | goto unlock; |
663 | } | 663 | } |
664 | 664 | ||
665 | if (ar->fw.tx_seq_table) { | ||
666 | err = carl9170_write_reg(ar, ar->fw.tx_seq_table + vif_id * 4, | ||
667 | 0); | ||
668 | if (err) | ||
669 | goto unlock; | ||
670 | } | ||
671 | |||
665 | unlock: | 672 | unlock: |
666 | if (err && (vif_id >= 0)) { | 673 | if (err && (vif_id >= 0)) { |
667 | vif_priv->active = false; | 674 | vif_priv->active = false; |
diff --git a/drivers/net/wireless/ath/carl9170/tx.c b/drivers/net/wireless/ath/carl9170/tx.c index 6cc58e052d10..6f41e21d3a1c 100644 --- a/drivers/net/wireless/ath/carl9170/tx.c +++ b/drivers/net/wireless/ath/carl9170/tx.c | |||
@@ -862,6 +862,9 @@ static int carl9170_tx_prepare(struct ar9170 *ar, struct sk_buff *skb) | |||
862 | if (unlikely(info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM)) | 862 | if (unlikely(info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM)) |
863 | txc->s.misc |= CARL9170_TX_SUPER_MISC_CAB; | 863 | txc->s.misc |= CARL9170_TX_SUPER_MISC_CAB; |
864 | 864 | ||
865 | if (unlikely(info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ)) | ||
866 | txc->s.misc |= CARL9170_TX_SUPER_MISC_ASSIGN_SEQ; | ||
867 | |||
865 | if (unlikely(ieee80211_is_probe_resp(hdr->frame_control))) | 868 | if (unlikely(ieee80211_is_probe_resp(hdr->frame_control))) |
866 | txc->s.misc |= CARL9170_TX_SUPER_MISC_FILL_IN_TSF; | 869 | txc->s.misc |= CARL9170_TX_SUPER_MISC_FILL_IN_TSF; |
867 | 870 | ||