diff options
author | Avraham Stern <avraham.stern@intel.com> | 2018-03-20 11:05:06 -0400 |
---|---|---|
committer | Luca Coelho <luciano.coelho@intel.com> | 2018-08-31 04:38:17 -0400 |
commit | 2210f6959dfa754d2a191f3db6ac7592d1bebc9c (patch) | |
tree | c81d1e06361c5ee50273579f1525ffb2648ec431 /drivers/net/wireless/intel | |
parent | dd2690579f5138e569440e5252e93d8634593190 (diff) |
iwlwifi: set the tid for non-QOS frames to zero
The tid for Non-QOS frames is set to IWL_MAX_TID_COUNT. This value
is also used for configuring the queue for non-QOS data. However, this
tid is used by the FW for management queues. As a result, the FW
does not encrypt non-QOS data frames.
Fix this by setting the tid for non-QOS data frames to zero, which
is a valid value for data frames in the FW.
This also fixes a bug in sending multicast frames, where the queues
are allocated with tid == 0, but are sent with tid == 8, which may
lead to unexpected behavior.
Signed-off-by: Avraham Stern <avraham.stern@intel.com>
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
Diffstat (limited to 'drivers/net/wireless/intel')
-rw-r--r-- | drivers/net/wireless/intel/iwlwifi/fw/api/tx.h | 2 | ||||
-rw-r--r-- | drivers/net/wireless/intel/iwlwifi/mvm/tx.c | 24 |
2 files changed, 19 insertions, 7 deletions
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/tx.h b/drivers/net/wireless/intel/iwlwifi/fw/api/tx.h index 514b86123d3d..135135d80d4d 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/tx.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/tx.h | |||
@@ -186,7 +186,7 @@ enum iwl_tx_cmd_sec_ctrl { | |||
186 | /* | 186 | /* |
187 | * TID for non QoS frames - to be written in tid_tspec | 187 | * TID for non QoS frames - to be written in tid_tspec |
188 | */ | 188 | */ |
189 | #define IWL_TID_NON_QOS IWL_MAX_TID_COUNT | 189 | #define IWL_TID_NON_QOS 0 |
190 | 190 | ||
191 | /* | 191 | /* |
192 | * Limits on the retransmissions - to be written in {data,rts}_retry_limit | 192 | * Limits on the retransmissions - to be written in {data,rts}_retry_limit |
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c index ff193dca2020..83f3e74337db 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c | |||
@@ -8,6 +8,7 @@ | |||
8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
9 | * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH | 9 | * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH |
10 | * Copyright(c) 2016 - 2017 Intel Deutschland GmbH | 10 | * Copyright(c) 2016 - 2017 Intel Deutschland GmbH |
11 | * Copyright(c) 2018 Intel Corporation | ||
11 | * | 12 | * |
12 | * This program is free software; you can redistribute it and/or modify | 13 | * This program is free software; you can redistribute it and/or modify |
13 | * it under the terms of version 2 of the GNU General Public License as | 14 | * it under the terms of version 2 of the GNU General Public License as |
@@ -35,6 +36,7 @@ | |||
35 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. | 36 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
36 | * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH | 37 | * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH |
37 | * Copyright(c) 2016 - 2017 Intel Deutschland GmbH | 38 | * Copyright(c) 2016 - 2017 Intel Deutschland GmbH |
39 | * Copyright(c) 2018 Intel Corporation | ||
38 | * All rights reserved. | 40 | * All rights reserved. |
39 | * | 41 | * |
40 | * Redistribution and use in source and binary forms, with or without | 42 | * Redistribution and use in source and binary forms, with or without |
@@ -245,14 +247,18 @@ void iwl_mvm_set_tx_cmd(struct iwl_mvm *mvm, struct sk_buff *skb, | |||
245 | iwl_mvm_bar_check_trigger(mvm, bar->ra, tx_cmd->tid_tspec, | 247 | iwl_mvm_bar_check_trigger(mvm, bar->ra, tx_cmd->tid_tspec, |
246 | ssn); | 248 | ssn); |
247 | } else { | 249 | } else { |
248 | tx_cmd->tid_tspec = IWL_TID_NON_QOS; | 250 | if (ieee80211_is_data(fc)) |
251 | tx_cmd->tid_tspec = IWL_TID_NON_QOS; | ||
252 | else | ||
253 | tx_cmd->tid_tspec = IWL_MAX_TID_COUNT; | ||
254 | |||
249 | if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) | 255 | if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) |
250 | tx_flags |= TX_CMD_FLG_SEQ_CTL; | 256 | tx_flags |= TX_CMD_FLG_SEQ_CTL; |
251 | else | 257 | else |
252 | tx_flags &= ~TX_CMD_FLG_SEQ_CTL; | 258 | tx_flags &= ~TX_CMD_FLG_SEQ_CTL; |
253 | } | 259 | } |
254 | 260 | ||
255 | /* Default to 0 (BE) when tid_spec is set to IWL_TID_NON_QOS */ | 261 | /* Default to 0 (BE) when tid_spec is set to IWL_MAX_TID_COUNT */ |
256 | if (tx_cmd->tid_tspec < IWL_MAX_TID_COUNT) | 262 | if (tx_cmd->tid_tspec < IWL_MAX_TID_COUNT) |
257 | ac = tid_to_mac80211_ac[tx_cmd->tid_tspec]; | 263 | ac = tid_to_mac80211_ac[tx_cmd->tid_tspec]; |
258 | else | 264 | else |
@@ -1049,6 +1055,8 @@ static int iwl_mvm_tx_mpdu(struct iwl_mvm *mvm, struct sk_buff *skb, | |||
1049 | /* update the tx_cmd hdr as it was already copied */ | 1055 | /* update the tx_cmd hdr as it was already copied */ |
1050 | tx_cmd->hdr->seq_ctrl = hdr->seq_ctrl; | 1056 | tx_cmd->hdr->seq_ctrl = hdr->seq_ctrl; |
1051 | } | 1057 | } |
1058 | } else if (ieee80211_is_data(fc) && !ieee80211_is_data_qos(fc)) { | ||
1059 | tid = IWL_TID_NON_QOS; | ||
1052 | } | 1060 | } |
1053 | 1061 | ||
1054 | txq_id = mvmsta->tid_data[tid].txq_id; | 1062 | txq_id = mvmsta->tid_data[tid].txq_id; |
@@ -1525,7 +1533,7 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm, | |||
1525 | iwl_mvm_tx_airtime(mvm, mvmsta, | 1533 | iwl_mvm_tx_airtime(mvm, mvmsta, |
1526 | le16_to_cpu(tx_resp->wireless_media_time)); | 1534 | le16_to_cpu(tx_resp->wireless_media_time)); |
1527 | 1535 | ||
1528 | if (tid != IWL_TID_NON_QOS && tid != IWL_MGMT_TID) { | 1536 | if (sta->wme && tid != IWL_MGMT_TID) { |
1529 | struct iwl_mvm_tid_data *tid_data = | 1537 | struct iwl_mvm_tid_data *tid_data = |
1530 | &mvmsta->tid_data[tid]; | 1538 | &mvmsta->tid_data[tid]; |
1531 | bool send_eosp_ndp = false; | 1539 | bool send_eosp_ndp = false; |
@@ -1645,20 +1653,24 @@ static void iwl_mvm_rx_tx_cmd_agg(struct iwl_mvm *mvm, | |||
1645 | u16 sequence = le16_to_cpu(pkt->hdr.sequence); | 1653 | u16 sequence = le16_to_cpu(pkt->hdr.sequence); |
1646 | struct iwl_mvm_sta *mvmsta; | 1654 | struct iwl_mvm_sta *mvmsta; |
1647 | int queue = SEQ_TO_QUEUE(sequence); | 1655 | int queue = SEQ_TO_QUEUE(sequence); |
1656 | struct ieee80211_sta *sta; | ||
1648 | 1657 | ||
1649 | if (WARN_ON_ONCE(queue < IWL_MVM_DQA_MIN_DATA_QUEUE && | 1658 | if (WARN_ON_ONCE(queue < IWL_MVM_DQA_MIN_DATA_QUEUE && |
1650 | (queue != IWL_MVM_DQA_BSS_CLIENT_QUEUE))) | 1659 | (queue != IWL_MVM_DQA_BSS_CLIENT_QUEUE))) |
1651 | return; | 1660 | return; |
1652 | 1661 | ||
1653 | if (WARN_ON_ONCE(tid == IWL_TID_NON_QOS)) | ||
1654 | return; | ||
1655 | |||
1656 | iwl_mvm_rx_tx_cmd_agg_dbg(mvm, pkt); | 1662 | iwl_mvm_rx_tx_cmd_agg_dbg(mvm, pkt); |
1657 | 1663 | ||
1658 | rcu_read_lock(); | 1664 | rcu_read_lock(); |
1659 | 1665 | ||
1660 | mvmsta = iwl_mvm_sta_from_staid_rcu(mvm, sta_id); | 1666 | mvmsta = iwl_mvm_sta_from_staid_rcu(mvm, sta_id); |
1661 | 1667 | ||
1668 | sta = rcu_dereference(mvm->fw_id_to_mac_id[sta_id]); | ||
1669 | if (WARN_ON_ONCE(!sta || !sta->wme)) { | ||
1670 | rcu_read_unlock(); | ||
1671 | return; | ||
1672 | } | ||
1673 | |||
1662 | if (!WARN_ON_ONCE(!mvmsta)) { | 1674 | if (!WARN_ON_ONCE(!mvmsta)) { |
1663 | mvmsta->tid_data[tid].rate_n_flags = | 1675 | mvmsta->tid_data[tid].rate_n_flags = |
1664 | le32_to_cpu(tx_resp->initial_rate); | 1676 | le32_to_cpu(tx_resp->initial_rate); |