aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/intel
diff options
context:
space:
mode:
authorAvraham Stern <avraham.stern@intel.com>2018-03-20 11:05:06 -0400
committerLuca Coelho <luciano.coelho@intel.com>2018-08-31 04:38:17 -0400
commit2210f6959dfa754d2a191f3db6ac7592d1bebc9c (patch)
treec81d1e06361c5ee50273579f1525ffb2648ec431 /drivers/net/wireless/intel
parentdd2690579f5138e569440e5252e93d8634593190 (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.h2
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/tx.c24
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);