aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/mvm/sta.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-11-13 03:40:34 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2013-11-13 03:40:34 -0500
commit42a2d923cc349583ebf6fdd52a7d35e1c2f7e6bd (patch)
tree2b2b0c03b5389c1301800119333967efafd994ca /drivers/net/wireless/iwlwifi/mvm/sta.c
parent5cbb3d216e2041700231bcfc383ee5f8b7fc8b74 (diff)
parent75ecab1df14d90e86cebef9ec5c76befde46e65f (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next
Pull networking updates from David Miller: 1) The addition of nftables. No longer will we need protocol aware firewall filtering modules, it can all live in userspace. At the core of nftables is a, for lack of a better term, virtual machine that executes byte codes to inspect packet or metadata (arriving interface index, etc.) and make verdict decisions. Besides support for loading packet contents and comparing them, the interpreter supports lookups in various datastructures as fundamental operations. For example sets are supports, and therefore one could create a set of whitelist IP address entries which have ACCEPT verdicts attached to them, and use the appropriate byte codes to do such lookups. Since the interpreted code is composed in userspace, userspace can do things like optimize things before giving it to the kernel. Another major improvement is the capability of atomically updating portions of the ruleset. In the existing netfilter implementation, one has to update the entire rule set in order to make a change and this is very expensive. Userspace tools exist to create nftables rules using existing netfilter rule sets, but both kernel implementations will need to co-exist for quite some time as we transition from the old to the new stuff. Kudos to Patrick McHardy, Pablo Neira Ayuso, and others who have worked so hard on this. 2) Daniel Borkmann and Hannes Frederic Sowa made several improvements to our pseudo-random number generator, mostly used for things like UDP port randomization and netfitler, amongst other things. In particular the taus88 generater is updated to taus113, and test cases are added. 3) Support 64-bit rates in HTB and TBF schedulers, from Eric Dumazet and Yang Yingliang. 4) Add support for new 577xx tigon3 chips to tg3 driver, from Nithin Sujir. 5) Fix two fatal flaws in TCP dynamic right sizing, from Eric Dumazet, Neal Cardwell, and Yuchung Cheng. 6) Allow IP_TOS and IP_TTL to be specified in sendmsg() ancillary control message data, much like other socket option attributes. From Francesco Fusco. 7) Allow applications to specify a cap on the rate computed automatically by the kernel for pacing flows, via a new SO_MAX_PACING_RATE socket option. From Eric Dumazet. 8) Make the initial autotuned send buffer sizing in TCP more closely reflect actual needs, from Eric Dumazet. 9) Currently early socket demux only happens for TCP sockets, but we can do it for connected UDP sockets too. Implementation from Shawn Bohrer. 10) Refactor inet socket demux with the goal of improving hash demux performance for listening sockets. With the main goals being able to use RCU lookups on even request sockets, and eliminating the listening lock contention. From Eric Dumazet. 11) The bonding layer has many demuxes in it's fast path, and an RCU conversion was started back in 3.11, several changes here extend the RCU usage to even more locations. From Ding Tianhong and Wang Yufen, based upon suggestions by Nikolay Aleksandrov and Veaceslav Falico. 12) Allow stackability of segmentation offloads to, in particular, allow segmentation offloading over tunnels. From Eric Dumazet. 13) Significantly improve the handling of secret keys we input into the various hash functions in the inet hashtables, TCP fast open, as well as syncookies. From Hannes Frederic Sowa. The key fundamental operation is "net_get_random_once()" which uses static keys. Hannes even extended this to ipv4/ipv6 fragmentation handling and our generic flow dissector. 14) The generic driver layer takes care now to set the driver data to NULL on device removal, so it's no longer necessary for drivers to explicitly set it to NULL any more. Many drivers have been cleaned up in this way, from Jingoo Han. 15) Add a BPF based packet scheduler classifier, from Daniel Borkmann. 16) Improve CRC32 interfaces and generic SKB checksum iterators so that SCTP's checksumming can more cleanly be handled. Also from Daniel Borkmann. 17) Add a new PMTU discovery mode, IP_PMTUDISC_INTERFACE, which forces using the interface MTU value. This helps avoid PMTU attacks, particularly on DNS servers. From Hannes Frederic Sowa. 18) Use generic XPS for transmit queue steering rather than internal (re-)implementation in virtio-net. From Jason Wang. * git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next: (1622 commits) random32: add test cases for taus113 implementation random32: upgrade taus88 generator to taus113 from errata paper random32: move rnd_state to linux/random.h random32: add prandom_reseed_late() and call when nonblocking pool becomes initialized random32: add periodic reseeding random32: fix off-by-one in seeding requirement PHY: Add RTL8201CP phy_driver to realtek xtsonic: add missing platform_set_drvdata() in xtsonic_probe() macmace: add missing platform_set_drvdata() in mace_probe() ethernet/arc/arc_emac: add missing platform_set_drvdata() in arc_emac_probe() ipv6: protect for_each_sk_fl_rcu in mem_check with rcu_read_lock_bh vlan: Implement vlan_dev_get_egress_qos_mask as an inline. ixgbe: add warning when max_vfs is out of range. igb: Update link modes display in ethtool netfilter: push reasm skb through instead of original frag skbs ip6_output: fragment outgoing reassembled skb properly MAINTAINERS: mv643xx_eth: take over maintainership from Lennart net_sched: tbf: support of 64bit rates ixgbe: deleting dfwd stations out of order can cause null ptr deref ixgbe: fix build err, num_rx_queues is only available with CONFIG_RPS ...
Diffstat (limited to 'drivers/net/wireless/iwlwifi/mvm/sta.c')
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/sta.c206
1 files changed, 157 insertions, 49 deletions
diff --git a/drivers/net/wireless/iwlwifi/mvm/sta.c b/drivers/net/wireless/iwlwifi/mvm/sta.c
index 44add291531b..329952363a54 100644
--- a/drivers/net/wireless/iwlwifi/mvm/sta.c
+++ b/drivers/net/wireless/iwlwifi/mvm/sta.c
@@ -66,6 +66,115 @@
66#include "sta.h" 66#include "sta.h"
67#include "rs.h" 67#include "rs.h"
68 68
69static void iwl_mvm_add_sta_cmd_v6_to_v5(struct iwl_mvm_add_sta_cmd_v6 *cmd_v6,
70 struct iwl_mvm_add_sta_cmd_v5 *cmd_v5)
71{
72 memset(cmd_v5, 0, sizeof(*cmd_v5));
73
74 cmd_v5->add_modify = cmd_v6->add_modify;
75 cmd_v5->tid_disable_tx = cmd_v6->tid_disable_tx;
76 cmd_v5->mac_id_n_color = cmd_v6->mac_id_n_color;
77 memcpy(cmd_v5->addr, cmd_v6->addr, ETH_ALEN);
78 cmd_v5->sta_id = cmd_v6->sta_id;
79 cmd_v5->modify_mask = cmd_v6->modify_mask;
80 cmd_v5->station_flags = cmd_v6->station_flags;
81 cmd_v5->station_flags_msk = cmd_v6->station_flags_msk;
82 cmd_v5->add_immediate_ba_tid = cmd_v6->add_immediate_ba_tid;
83 cmd_v5->remove_immediate_ba_tid = cmd_v6->remove_immediate_ba_tid;
84 cmd_v5->add_immediate_ba_ssn = cmd_v6->add_immediate_ba_ssn;
85 cmd_v5->sleep_tx_count = cmd_v6->sleep_tx_count;
86 cmd_v5->sleep_state_flags = cmd_v6->sleep_state_flags;
87 cmd_v5->assoc_id = cmd_v6->assoc_id;
88 cmd_v5->beamform_flags = cmd_v6->beamform_flags;
89 cmd_v5->tfd_queue_msk = cmd_v6->tfd_queue_msk;
90}
91
92static void
93iwl_mvm_add_sta_key_to_add_sta_cmd_v5(struct iwl_mvm_add_sta_key_cmd *key_cmd,
94 struct iwl_mvm_add_sta_cmd_v5 *sta_cmd,
95 u32 mac_id_n_color)
96{
97 memset(sta_cmd, 0, sizeof(*sta_cmd));
98
99 sta_cmd->sta_id = key_cmd->sta_id;
100 sta_cmd->add_modify = STA_MODE_MODIFY;
101 sta_cmd->modify_mask = STA_MODIFY_KEY;
102 sta_cmd->mac_id_n_color = cpu_to_le32(mac_id_n_color);
103
104 sta_cmd->key.key_offset = key_cmd->key_offset;
105 sta_cmd->key.key_flags = key_cmd->key_flags;
106 memcpy(sta_cmd->key.key, key_cmd->key, sizeof(sta_cmd->key.key));
107 sta_cmd->key.tkip_rx_tsc_byte2 = key_cmd->tkip_rx_tsc_byte2;
108 memcpy(sta_cmd->key.tkip_rx_ttak, key_cmd->tkip_rx_ttak,
109 sizeof(sta_cmd->key.tkip_rx_ttak));
110}
111
112static int iwl_mvm_send_add_sta_cmd_status(struct iwl_mvm *mvm,
113 struct iwl_mvm_add_sta_cmd_v6 *cmd,
114 int *status)
115{
116 struct iwl_mvm_add_sta_cmd_v5 cmd_v5;
117
118 if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_STA_KEY_CMD)
119 return iwl_mvm_send_cmd_pdu_status(mvm, ADD_STA, sizeof(*cmd),
120 cmd, status);
121
122 iwl_mvm_add_sta_cmd_v6_to_v5(cmd, &cmd_v5);
123
124 return iwl_mvm_send_cmd_pdu_status(mvm, ADD_STA, sizeof(cmd_v5),
125 &cmd_v5, status);
126}
127
128static int iwl_mvm_send_add_sta_cmd(struct iwl_mvm *mvm, u32 flags,
129 struct iwl_mvm_add_sta_cmd_v6 *cmd)
130{
131 struct iwl_mvm_add_sta_cmd_v5 cmd_v5;
132
133 if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_STA_KEY_CMD)
134 return iwl_mvm_send_cmd_pdu(mvm, ADD_STA, flags,
135 sizeof(*cmd), cmd);
136
137 iwl_mvm_add_sta_cmd_v6_to_v5(cmd, &cmd_v5);
138
139 return iwl_mvm_send_cmd_pdu(mvm, ADD_STA, flags, sizeof(cmd_v5),
140 &cmd_v5);
141}
142
143static int
144iwl_mvm_send_add_sta_key_cmd_status(struct iwl_mvm *mvm,
145 struct iwl_mvm_add_sta_key_cmd *cmd,
146 u32 mac_id_n_color,
147 int *status)
148{
149 struct iwl_mvm_add_sta_cmd_v5 sta_cmd;
150
151 if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_STA_KEY_CMD)
152 return iwl_mvm_send_cmd_pdu_status(mvm, ADD_STA_KEY,
153 sizeof(*cmd), cmd, status);
154
155 iwl_mvm_add_sta_key_to_add_sta_cmd_v5(cmd, &sta_cmd, mac_id_n_color);
156
157 return iwl_mvm_send_cmd_pdu_status(mvm, ADD_STA, sizeof(sta_cmd),
158 &sta_cmd, status);
159}
160
161static int iwl_mvm_send_add_sta_key_cmd(struct iwl_mvm *mvm,
162 u32 flags,
163 struct iwl_mvm_add_sta_key_cmd *cmd,
164 u32 mac_id_n_color)
165{
166 struct iwl_mvm_add_sta_cmd_v5 sta_cmd;
167
168 if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_STA_KEY_CMD)
169 return iwl_mvm_send_cmd_pdu(mvm, ADD_STA_KEY, flags,
170 sizeof(*cmd), cmd);
171
172 iwl_mvm_add_sta_key_to_add_sta_cmd_v5(cmd, &sta_cmd, mac_id_n_color);
173
174 return iwl_mvm_send_cmd_pdu(mvm, ADD_STA, flags, sizeof(sta_cmd),
175 &sta_cmd);
176}
177
69static int iwl_mvm_find_free_sta_id(struct iwl_mvm *mvm) 178static int iwl_mvm_find_free_sta_id(struct iwl_mvm *mvm)
70{ 179{
71 int sta_id; 180 int sta_id;
@@ -87,7 +196,7 @@ int iwl_mvm_sta_send_to_fw(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
87 bool update) 196 bool update)
88{ 197{
89 struct iwl_mvm_sta *mvm_sta = (void *)sta->drv_priv; 198 struct iwl_mvm_sta *mvm_sta = (void *)sta->drv_priv;
90 struct iwl_mvm_add_sta_cmd add_sta_cmd; 199 struct iwl_mvm_add_sta_cmd_v6 add_sta_cmd;
91 int ret; 200 int ret;
92 u32 status; 201 u32 status;
93 u32 agg_size = 0, mpdu_dens = 0; 202 u32 agg_size = 0, mpdu_dens = 0;
@@ -175,8 +284,7 @@ int iwl_mvm_sta_send_to_fw(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
175 cpu_to_le32(mpdu_dens << STA_FLG_AGG_MPDU_DENS_SHIFT); 284 cpu_to_le32(mpdu_dens << STA_FLG_AGG_MPDU_DENS_SHIFT);
176 285
177 status = ADD_STA_SUCCESS; 286 status = ADD_STA_SUCCESS;
178 ret = iwl_mvm_send_cmd_pdu_status(mvm, ADD_STA, sizeof(add_sta_cmd), 287 ret = iwl_mvm_send_add_sta_cmd_status(mvm, &add_sta_cmd, &status);
179 &add_sta_cmd, &status);
180 if (ret) 288 if (ret)
181 return ret; 289 return ret;
182 290
@@ -229,8 +337,12 @@ int iwl_mvm_add_sta(struct iwl_mvm *mvm,
229 if (vif->hw_queue[i] != IEEE80211_INVAL_HW_QUEUE) 337 if (vif->hw_queue[i] != IEEE80211_INVAL_HW_QUEUE)
230 mvm_sta->tfd_queue_msk |= BIT(vif->hw_queue[i]); 338 mvm_sta->tfd_queue_msk |= BIT(vif->hw_queue[i]);
231 339
232 /* for HW restart - need to reset the seq_number etc... */ 340 /* for HW restart - reset everything but the sequence number */
233 memset(mvm_sta->tid_data, 0, sizeof(mvm_sta->tid_data)); 341 for (i = 0; i < IWL_MAX_TID_COUNT; i++) {
342 u16 seq = mvm_sta->tid_data[i].seq_number;
343 memset(&mvm_sta->tid_data[i], 0, sizeof(mvm_sta->tid_data[i]));
344 mvm_sta->tid_data[i].seq_number = seq;
345 }
234 346
235 ret = iwl_mvm_sta_send_to_fw(mvm, sta, false); 347 ret = iwl_mvm_sta_send_to_fw(mvm, sta, false);
236 if (ret) 348 if (ret)
@@ -256,7 +368,7 @@ int iwl_mvm_update_sta(struct iwl_mvm *mvm,
256int iwl_mvm_drain_sta(struct iwl_mvm *mvm, struct iwl_mvm_sta *mvmsta, 368int iwl_mvm_drain_sta(struct iwl_mvm *mvm, struct iwl_mvm_sta *mvmsta,
257 bool drain) 369 bool drain)
258{ 370{
259 struct iwl_mvm_add_sta_cmd cmd = {}; 371 struct iwl_mvm_add_sta_cmd_v6 cmd = {};
260 int ret; 372 int ret;
261 u32 status; 373 u32 status;
262 374
@@ -269,8 +381,7 @@ int iwl_mvm_drain_sta(struct iwl_mvm *mvm, struct iwl_mvm_sta *mvmsta,
269 cmd.station_flags_msk = cpu_to_le32(STA_FLG_DRAIN_FLOW); 381 cmd.station_flags_msk = cpu_to_le32(STA_FLG_DRAIN_FLOW);
270 382
271 status = ADD_STA_SUCCESS; 383 status = ADD_STA_SUCCESS;
272 ret = iwl_mvm_send_cmd_pdu_status(mvm, ADD_STA, sizeof(cmd), 384 ret = iwl_mvm_send_add_sta_cmd_status(mvm, &cmd, &status);
273 &cmd, &status);
274 if (ret) 385 if (ret)
275 return ret; 386 return ret;
276 387
@@ -469,13 +580,13 @@ static int iwl_mvm_add_int_sta_common(struct iwl_mvm *mvm,
469 const u8 *addr, 580 const u8 *addr,
470 u16 mac_id, u16 color) 581 u16 mac_id, u16 color)
471{ 582{
472 struct iwl_mvm_add_sta_cmd cmd; 583 struct iwl_mvm_add_sta_cmd_v6 cmd;
473 int ret; 584 int ret;
474 u32 status; 585 u32 status;
475 586
476 lockdep_assert_held(&mvm->mutex); 587 lockdep_assert_held(&mvm->mutex);
477 588
478 memset(&cmd, 0, sizeof(struct iwl_mvm_add_sta_cmd)); 589 memset(&cmd, 0, sizeof(struct iwl_mvm_add_sta_cmd_v6));
479 cmd.sta_id = sta->sta_id; 590 cmd.sta_id = sta->sta_id;
480 cmd.mac_id_n_color = cpu_to_le32(FW_CMD_ID_AND_COLOR(mac_id, 591 cmd.mac_id_n_color = cpu_to_le32(FW_CMD_ID_AND_COLOR(mac_id,
481 color)); 592 color));
@@ -485,8 +596,7 @@ static int iwl_mvm_add_int_sta_common(struct iwl_mvm *mvm,
485 if (addr) 596 if (addr)
486 memcpy(cmd.addr, addr, ETH_ALEN); 597 memcpy(cmd.addr, addr, ETH_ALEN);
487 598
488 ret = iwl_mvm_send_cmd_pdu_status(mvm, ADD_STA, sizeof(cmd), 599 ret = iwl_mvm_send_add_sta_cmd_status(mvm, &cmd, &status);
489 &cmd, &status);
490 if (ret) 600 if (ret)
491 return ret; 601 return ret;
492 602
@@ -534,10 +644,14 @@ int iwl_mvm_send_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
534 struct iwl_mvm_int_sta *bsta) 644 struct iwl_mvm_int_sta *bsta)
535{ 645{
536 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); 646 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
537 static const u8 baddr[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; 647 static const u8 _baddr[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
648 static const u8 *baddr = _baddr;
538 649
539 lockdep_assert_held(&mvm->mutex); 650 lockdep_assert_held(&mvm->mutex);
540 651
652 if (vif->type == NL80211_IFTYPE_ADHOC)
653 baddr = vif->bss_conf.bssid;
654
541 if (WARN_ON_ONCE(bsta->sta_id == IWL_MVM_STATION_COUNT)) 655 if (WARN_ON_ONCE(bsta->sta_id == IWL_MVM_STATION_COUNT))
542 return -ENOSPC; 656 return -ENOSPC;
543 657
@@ -614,7 +728,7 @@ int iwl_mvm_sta_rx_agg(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
614 int tid, u16 ssn, bool start) 728 int tid, u16 ssn, bool start)
615{ 729{
616 struct iwl_mvm_sta *mvm_sta = (void *)sta->drv_priv; 730 struct iwl_mvm_sta *mvm_sta = (void *)sta->drv_priv;
617 struct iwl_mvm_add_sta_cmd cmd = {}; 731 struct iwl_mvm_add_sta_cmd_v6 cmd = {};
618 int ret; 732 int ret;
619 u32 status; 733 u32 status;
620 734
@@ -638,8 +752,7 @@ int iwl_mvm_sta_rx_agg(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
638 STA_MODIFY_REMOVE_BA_TID; 752 STA_MODIFY_REMOVE_BA_TID;
639 753
640 status = ADD_STA_SUCCESS; 754 status = ADD_STA_SUCCESS;
641 ret = iwl_mvm_send_cmd_pdu_status(mvm, ADD_STA, sizeof(cmd), 755 ret = iwl_mvm_send_add_sta_cmd_status(mvm, &cmd, &status);
642 &cmd, &status);
643 if (ret) 756 if (ret)
644 return ret; 757 return ret;
645 758
@@ -674,7 +787,7 @@ static int iwl_mvm_sta_tx_agg(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
674 int tid, u8 queue, bool start) 787 int tid, u8 queue, bool start)
675{ 788{
676 struct iwl_mvm_sta *mvm_sta = (void *)sta->drv_priv; 789 struct iwl_mvm_sta *mvm_sta = (void *)sta->drv_priv;
677 struct iwl_mvm_add_sta_cmd cmd = {}; 790 struct iwl_mvm_add_sta_cmd_v6 cmd = {};
678 int ret; 791 int ret;
679 u32 status; 792 u32 status;
680 793
@@ -696,8 +809,7 @@ static int iwl_mvm_sta_tx_agg(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
696 cmd.tid_disable_tx = cpu_to_le16(mvm_sta->tid_disable_agg); 809 cmd.tid_disable_tx = cpu_to_le16(mvm_sta->tid_disable_agg);
697 810
698 status = ADD_STA_SUCCESS; 811 status = ADD_STA_SUCCESS;
699 ret = iwl_mvm_send_cmd_pdu_status(mvm, ADD_STA, sizeof(cmd), 812 ret = iwl_mvm_send_add_sta_cmd_status(mvm, &cmd, &status);
700 &cmd, &status);
701 if (ret) 813 if (ret)
702 return ret; 814 return ret;
703 815
@@ -743,13 +855,13 @@ int iwl_mvm_sta_tx_agg_start(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
743 855
744 lockdep_assert_held(&mvm->mutex); 856 lockdep_assert_held(&mvm->mutex);
745 857
746 for (txq_id = IWL_MVM_FIRST_AGG_QUEUE; 858 for (txq_id = mvm->first_agg_queue;
747 txq_id <= IWL_MVM_LAST_AGG_QUEUE; txq_id++) 859 txq_id <= mvm->last_agg_queue; txq_id++)
748 if (mvm->queue_to_mac80211[txq_id] == 860 if (mvm->queue_to_mac80211[txq_id] ==
749 IWL_INVALID_MAC80211_QUEUE) 861 IWL_INVALID_MAC80211_QUEUE)
750 break; 862 break;
751 863
752 if (txq_id > IWL_MVM_LAST_AGG_QUEUE) { 864 if (txq_id > mvm->last_agg_queue) {
753 IWL_ERR(mvm, "Failed to allocate agg queue\n"); 865 IWL_ERR(mvm, "Failed to allocate agg queue\n");
754 return -EIO; 866 return -EIO;
755 } 867 }
@@ -987,10 +1099,11 @@ static int iwl_mvm_send_sta_key(struct iwl_mvm *mvm,
987 u32 cmd_flags) 1099 u32 cmd_flags)
988{ 1100{
989 __le16 key_flags; 1101 __le16 key_flags;
990 struct iwl_mvm_add_sta_cmd cmd = {}; 1102 struct iwl_mvm_add_sta_key_cmd cmd = {};
991 int ret, status; 1103 int ret, status;
992 u16 keyidx; 1104 u16 keyidx;
993 int i; 1105 int i;
1106 u32 mac_id_n_color = mvm_sta->mac_id_n_color;
994 1107
995 keyidx = (keyconf->keyidx << STA_KEY_FLG_KEYID_POS) & 1108 keyidx = (keyconf->keyidx << STA_KEY_FLG_KEYID_POS) &
996 STA_KEY_FLG_KEYID_MSK; 1109 STA_KEY_FLG_KEYID_MSK;
@@ -1000,14 +1113,14 @@ static int iwl_mvm_send_sta_key(struct iwl_mvm *mvm,
1000 switch (keyconf->cipher) { 1113 switch (keyconf->cipher) {
1001 case WLAN_CIPHER_SUITE_TKIP: 1114 case WLAN_CIPHER_SUITE_TKIP:
1002 key_flags |= cpu_to_le16(STA_KEY_FLG_TKIP); 1115 key_flags |= cpu_to_le16(STA_KEY_FLG_TKIP);
1003 cmd.key.tkip_rx_tsc_byte2 = tkip_iv32; 1116 cmd.tkip_rx_tsc_byte2 = tkip_iv32;
1004 for (i = 0; i < 5; i++) 1117 for (i = 0; i < 5; i++)
1005 cmd.key.tkip_rx_ttak[i] = cpu_to_le16(tkip_p1k[i]); 1118 cmd.tkip_rx_ttak[i] = cpu_to_le16(tkip_p1k[i]);
1006 memcpy(cmd.key.key, keyconf->key, keyconf->keylen); 1119 memcpy(cmd.key, keyconf->key, keyconf->keylen);
1007 break; 1120 break;
1008 case WLAN_CIPHER_SUITE_CCMP: 1121 case WLAN_CIPHER_SUITE_CCMP:
1009 key_flags |= cpu_to_le16(STA_KEY_FLG_CCM); 1122 key_flags |= cpu_to_le16(STA_KEY_FLG_CCM);
1010 memcpy(cmd.key.key, keyconf->key, keyconf->keylen); 1123 memcpy(cmd.key, keyconf->key, keyconf->keylen);
1011 break; 1124 break;
1012 default: 1125 default:
1013 WARN_ON(1); 1126 WARN_ON(1);
@@ -1017,20 +1130,18 @@ static int iwl_mvm_send_sta_key(struct iwl_mvm *mvm,
1017 if (!(keyconf->flags & IEEE80211_KEY_FLAG_PAIRWISE)) 1130 if (!(keyconf->flags & IEEE80211_KEY_FLAG_PAIRWISE))
1018 key_flags |= cpu_to_le16(STA_KEY_MULTICAST); 1131 key_flags |= cpu_to_le16(STA_KEY_MULTICAST);
1019 1132
1020 cmd.mac_id_n_color = cpu_to_le32(mvm_sta->mac_id_n_color); 1133 cmd.key_offset = keyconf->hw_key_idx;
1021 cmd.key.key_offset = keyconf->hw_key_idx; 1134 cmd.key_flags = key_flags;
1022 cmd.key.key_flags = key_flags;
1023 cmd.add_modify = STA_MODE_MODIFY;
1024 cmd.modify_mask = STA_MODIFY_KEY;
1025 cmd.sta_id = sta_id; 1135 cmd.sta_id = sta_id;
1026 1136
1027 status = ADD_STA_SUCCESS; 1137 status = ADD_STA_SUCCESS;
1028 if (cmd_flags == CMD_SYNC) 1138 if (cmd_flags == CMD_SYNC)
1029 ret = iwl_mvm_send_cmd_pdu_status(mvm, ADD_STA, sizeof(cmd), 1139 ret = iwl_mvm_send_add_sta_key_cmd_status(mvm, &cmd,
1030 &cmd, &status); 1140 mac_id_n_color,
1141 &status);
1031 else 1142 else
1032 ret = iwl_mvm_send_cmd_pdu(mvm, ADD_STA, CMD_ASYNC, 1143 ret = iwl_mvm_send_add_sta_key_cmd(mvm, CMD_ASYNC, &cmd,
1033 sizeof(cmd), &cmd); 1144 mac_id_n_color);
1034 1145
1035 switch (status) { 1146 switch (status) {
1036 case ADD_STA_SUCCESS: 1147 case ADD_STA_SUCCESS:
@@ -1197,7 +1308,7 @@ int iwl_mvm_remove_sta_key(struct iwl_mvm *mvm,
1197 struct ieee80211_key_conf *keyconf) 1308 struct ieee80211_key_conf *keyconf)
1198{ 1309{
1199 struct iwl_mvm_sta *mvm_sta; 1310 struct iwl_mvm_sta *mvm_sta;
1200 struct iwl_mvm_add_sta_cmd cmd = {}; 1311 struct iwl_mvm_add_sta_key_cmd cmd = {};
1201 __le16 key_flags; 1312 __le16 key_flags;
1202 int ret, status; 1313 int ret, status;
1203 u8 sta_id; 1314 u8 sta_id;
@@ -1252,17 +1363,14 @@ int iwl_mvm_remove_sta_key(struct iwl_mvm *mvm,
1252 if (!(keyconf->flags & IEEE80211_KEY_FLAG_PAIRWISE)) 1363 if (!(keyconf->flags & IEEE80211_KEY_FLAG_PAIRWISE))
1253 key_flags |= cpu_to_le16(STA_KEY_MULTICAST); 1364 key_flags |= cpu_to_le16(STA_KEY_MULTICAST);
1254 1365
1255 cmd.mac_id_n_color = cpu_to_le32(mvm_sta->mac_id_n_color); 1366 cmd.key_flags = key_flags;
1256 cmd.key.key_flags = key_flags; 1367 cmd.key_offset = keyconf->hw_key_idx;
1257 cmd.key.key_offset = keyconf->hw_key_idx;
1258 cmd.sta_id = sta_id; 1368 cmd.sta_id = sta_id;
1259 1369
1260 cmd.modify_mask = STA_MODIFY_KEY;
1261 cmd.add_modify = STA_MODE_MODIFY;
1262
1263 status = ADD_STA_SUCCESS; 1370 status = ADD_STA_SUCCESS;
1264 ret = iwl_mvm_send_cmd_pdu_status(mvm, ADD_STA, sizeof(cmd), 1371 ret = iwl_mvm_send_add_sta_key_cmd_status(mvm, &cmd,
1265 &cmd, &status); 1372 mvm_sta->mac_id_n_color,
1373 &status);
1266 1374
1267 switch (status) { 1375 switch (status) {
1268 case ADD_STA_SUCCESS: 1376 case ADD_STA_SUCCESS:
@@ -1309,7 +1417,7 @@ void iwl_mvm_sta_modify_ps_wake(struct iwl_mvm *mvm,
1309 struct ieee80211_sta *sta) 1417 struct ieee80211_sta *sta)
1310{ 1418{
1311 struct iwl_mvm_sta *mvmsta = (void *)sta->drv_priv; 1419 struct iwl_mvm_sta *mvmsta = (void *)sta->drv_priv;
1312 struct iwl_mvm_add_sta_cmd cmd = { 1420 struct iwl_mvm_add_sta_cmd_v6 cmd = {
1313 .add_modify = STA_MODE_MODIFY, 1421 .add_modify = STA_MODE_MODIFY,
1314 .sta_id = mvmsta->sta_id, 1422 .sta_id = mvmsta->sta_id,
1315 .station_flags_msk = cpu_to_le32(STA_FLG_PS), 1423 .station_flags_msk = cpu_to_le32(STA_FLG_PS),
@@ -1317,7 +1425,7 @@ void iwl_mvm_sta_modify_ps_wake(struct iwl_mvm *mvm,
1317 }; 1425 };
1318 int ret; 1426 int ret;
1319 1427
1320 ret = iwl_mvm_send_cmd_pdu(mvm, ADD_STA, CMD_ASYNC, sizeof(cmd), &cmd); 1428 ret = iwl_mvm_send_add_sta_cmd(mvm, CMD_ASYNC, &cmd);
1321 if (ret) 1429 if (ret)
1322 IWL_ERR(mvm, "Failed to send ADD_STA command (%d)\n", ret); 1430 IWL_ERR(mvm, "Failed to send ADD_STA command (%d)\n", ret);
1323} 1431}
@@ -1331,7 +1439,7 @@ void iwl_mvm_sta_modify_sleep_tx_count(struct iwl_mvm *mvm,
1331 (reason == IEEE80211_FRAME_RELEASE_UAPSD) ? 1439 (reason == IEEE80211_FRAME_RELEASE_UAPSD) ?
1332 STA_SLEEP_STATE_UAPSD : STA_SLEEP_STATE_PS_POLL; 1440 STA_SLEEP_STATE_UAPSD : STA_SLEEP_STATE_PS_POLL;
1333 struct iwl_mvm_sta *mvmsta = (void *)sta->drv_priv; 1441 struct iwl_mvm_sta *mvmsta = (void *)sta->drv_priv;
1334 struct iwl_mvm_add_sta_cmd cmd = { 1442 struct iwl_mvm_add_sta_cmd_v6 cmd = {
1335 .add_modify = STA_MODE_MODIFY, 1443 .add_modify = STA_MODE_MODIFY,
1336 .sta_id = mvmsta->sta_id, 1444 .sta_id = mvmsta->sta_id,
1337 .modify_mask = STA_MODIFY_SLEEPING_STA_TX_COUNT, 1445 .modify_mask = STA_MODIFY_SLEEPING_STA_TX_COUNT,
@@ -1346,7 +1454,7 @@ void iwl_mvm_sta_modify_sleep_tx_count(struct iwl_mvm *mvm,
1346 int ret; 1454 int ret;
1347 1455
1348 /* TODO: somehow the fw doesn't seem to take PS_POLL into account */ 1456 /* TODO: somehow the fw doesn't seem to take PS_POLL into account */
1349 ret = iwl_mvm_send_cmd_pdu(mvm, ADD_STA, CMD_ASYNC, sizeof(cmd), &cmd); 1457 ret = iwl_mvm_send_add_sta_cmd(mvm, CMD_ASYNC, &cmd);
1350 if (ret) 1458 if (ret)
1351 IWL_ERR(mvm, "Failed to send ADD_STA command (%d)\n", ret); 1459 IWL_ERR(mvm, "Failed to send ADD_STA command (%d)\n", ret);
1352} 1460}