Merge ~canonical-hwe-team/+git/backport-iwlwifi-dkms:vicamo/for-hwe/sync-debian-7906 into ~canonical-hwe-team/+git/backport-iwlwifi-dkms:ubuntu/master

Proposed by You-Sheng Yang on 2019-07-09
Status: Merged
Approved by: You-Sheng Yang on 2019-07-17
Approved revision: 7a7c921e3ef0534469277d77219db5e8e144c15a
Merged at revision: 7a7c921e3ef0534469277d77219db5e8e144c15a
Proposed branch: ~canonical-hwe-team/+git/backport-iwlwifi-dkms:vicamo/for-hwe/sync-debian-7906
Merge into: ~canonical-hwe-team/+git/backport-iwlwifi-dkms:ubuntu/master
Diff against target: 4344 lines (+1417/-733)
51 files modified
backport-include/linux/skbuff.h (+5/-5)
backport-include/net/genetlink.h (+2/-1)
backport-include/net/netlink.h (+13/-5)
compat/Makefile (+1/-1)
compat/backport-4.20.c (+7/-1)
compat/backport-genetlink.c (+1/-1)
compat/verification/pkcs7_verify.c (+0/-1)
debian/backport-iwlwifi-dkms.modaliases (+2/-0)
debian/changelog (+6/-0)
drivers/net/wireless/intel/iwlwifi/cfg/22000.c (+55/-6)
drivers/net/wireless/intel/iwlwifi/fw/acpi.h (+12/-0)
drivers/net/wireless/intel/iwlwifi/fw/api/dbg-tlv.h (+2/-0)
drivers/net/wireless/intel/iwlwifi/fw/api/location.h (+2/-2)
drivers/net/wireless/intel/iwlwifi/fw/api/phy.h (+7/-0)
drivers/net/wireless/intel/iwlwifi/fw/api/power.h (+12/-0)
drivers/net/wireless/intel/iwlwifi/fw/api/rx.h (+2/-1)
drivers/net/wireless/intel/iwlwifi/fw/dbg.c (+30/-26)
drivers/net/wireless/intel/iwlwifi/fw/file.h (+1/-0)
drivers/net/wireless/intel/iwlwifi/fw/img.h (+0/-9)
drivers/net/wireless/intel/iwlwifi/iwl-config.h (+7/-0)
drivers/net/wireless/intel/iwlwifi/iwl-csr.h (+1/-0)
drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c (+44/-109)
drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.h (+10/-14)
drivers/net/wireless/intel/iwlwifi/iwl-drv.c (+4/-8)
drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c (+0/-14)
drivers/net/wireless/intel/iwlwifi/iwl-tm-gnl.c (+11/-6)
drivers/net/wireless/intel/iwlwifi/iwl-trans.h (+3/-1)
drivers/net/wireless/intel/iwlwifi/mvm/d3.c (+3/-0)
drivers/net/wireless/intel/iwlwifi/mvm/fw.c (+141/-7)
drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c (+3/-1)
drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c (+79/-44)
drivers/net/wireless/intel/iwlwifi/mvm/mvm.h (+7/-4)
drivers/net/wireless/intel/iwlwifi/mvm/nvm.c (+1/-1)
drivers/net/wireless/intel/iwlwifi/mvm/ops.c (+15/-14)
drivers/net/wireless/intel/iwlwifi/mvm/rs.c (+268/-251)
drivers/net/wireless/intel/iwlwifi/mvm/rs.h (+2/-1)
drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c (+134/-51)
drivers/net/wireless/intel/iwlwifi/mvm/sta.c (+4/-2)
drivers/net/wireless/intel/iwlwifi/mvm/sta.h (+10/-2)
drivers/net/wireless/intel/iwlwifi/mvm/utils.c (+2/-2)
drivers/net/wireless/intel/iwlwifi/pcie/drv.c (+23/-0)
drivers/net/wireless/intel/iwlwifi/pcie/trans.c (+4/-5)
drivers/net/wireless/mac80211_hwsim.c (+25/-6)
net/mac80211/ibss.c (+7/-3)
net/mac80211/ieee80211_i.h (+1/-1)
net/mac80211/main.c (+13/-0)
net/mac80211/mlme.c (+4/-4)
net/mac80211/scan.c (+2/-3)
net/mac80211/util.c (+6/-5)
net/wireless/nl80211.c (+422/-114)
versions (+1/-1)
Reviewer Review Type Date Requested Status
Anthony Wong 2019-07-09 Approve on 2019-07-16
Canonical Hardware Enablement 2019-07-15 Pending
Review via email: mp+369867@code.launchpad.net

Description of the change

Sync with debian 7906-1.

To post a comment you must log in.
You-Sheng Yang (vicamo) wrote :

Successfully built. Checked built blobs works on 4.15.0-1045-oem as well as 5.0.0-1011-oem-osp1 with Intel Wireless-AC 9560.

You-Sheng Yang (vicamo) wrote :

> Successfully built. Checked built blobs works on 4.15.0-1045-oem as well as
> 5.0.0-1011-oem-osp1 with Intel Wireless-AC 9560.

On IceLake platform, of course.

You-Sheng Yang (vicamo) wrote :

Verified same thing with 9462 on ICL.

Anthony Wong (anthonywong) wrote :

Is this just to merge upstream's code at 7906?

review: Needs Information
You-Sheng Yang (vicamo) wrote :

@anthonywong, yes, and update modaliases since 7906 includes support to new device models.

Anthony Wong (anthonywong) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/backport-include/linux/skbuff.h b/backport-include/linux/skbuff.h
2index 4d37569..c60cbcc 100644
3--- a/backport-include/linux/skbuff.h
4+++ b/backport-include/linux/skbuff.h
5@@ -200,14 +200,14 @@ static inline struct sk_buff *__pskb_copy_fclone(struct sk_buff *skb,
6 struct sk_buff *skb_clone_sk(struct sk_buff *skb);
7 #endif
8
9-static inline bool skb_xmit_more(struct sk_buff *skb)
10-{
11+
12 #if LINUX_VERSION_IS_LESS(3,18,0)
13- return false;
14+#define skb_xmit_more(skb) false
15+#elif LINUX_VERSION_IS_LESS(5,2,0)
16+#define skb_xmit_more(skb) ((skb)->xmit_more)
17 #else
18- return skb->xmit_more;
19+#define skb_xmit_more(skb) netdev_xmit_more()
20 #endif
21-}
22
23 #if LINUX_VERSION_IS_LESS(3,19,0)
24 /**
25diff --git a/backport-include/net/genetlink.h b/backport-include/net/genetlink.h
26index 844ed2a..59611a8 100644
27--- a/backport-include/net/genetlink.h
28+++ b/backport-include/net/genetlink.h
29@@ -93,7 +93,7 @@ void backport_genl_dump_check_consistent(struct netlink_callback *cb,
30 #endif
31 #endif /* LINUX_VERSION_IS_LESS(4,15,0) */
32
33-#if LINUX_VERSION_IS_LESS(4,20,0)
34+#if LINUX_VERSION_IS_LESS(5,2,0)
35 static inline int
36 __real_backport_genl_register_family(struct genl_family *family)
37 {
38@@ -117,6 +117,7 @@ struct backport_genl_family {
39 unsigned int maxattr;
40 bool netnsok;
41 bool parallel_ops;
42+ const struct nla_policy *policy;
43 int (*pre_doit)(__genl_const struct genl_ops *ops,
44 struct sk_buff *skb,
45 struct genl_info *info);
46diff --git a/backport-include/net/netlink.h b/backport-include/net/netlink.h
47index 8b58301..87c30cc 100644
48--- a/backport-include/net/netlink.h
49+++ b/backport-include/net/netlink.h
50@@ -4,6 +4,19 @@
51 #include <linux/version.h>
52 #include <linux/in6.h>
53
54+#if LINUX_VERSION_IS_LESS(5,1,0)
55+#undef NLA_POLICY_NESTED
56+#undef NLA_POLICY_NESTED_ARRAY
57+#define _NLA_POLICY_NESTED(maxattr, policy) \
58+ { .type = NLA_NESTED, .validation_data = policy, .len = maxattr }
59+#define _NLA_POLICY_NESTED_ARRAY(maxattr, policy) \
60+ { .type = NLA_NESTED_ARRAY, .validation_data = policy, .len = maxattr }
61+#define NLA_POLICY_NESTED(policy) \
62+ _NLA_POLICY_NESTED(ARRAY_SIZE(policy) - 1, policy)
63+#define NLA_POLICY_NESTED_ARRAY(policy) \
64+ _NLA_POLICY_NESTED_ARRAY(ARRAY_SIZE(policy) - 1, policy)
65+#endif /* < 5.1 */
66+
67 #if LINUX_VERSION_IS_LESS(4,20,0)
68 /* can't backport using the enum - need to override */
69 #define NLA_UNSPEC 0
70@@ -59,11 +72,6 @@ struct backport_nla_policy {
71 #define NLA_POLICY_ETH_ADDR NLA_POLICY_EXACT_LEN(ETH_ALEN)
72 #define NLA_POLICY_ETH_ADDR_COMPAT NLA_POLICY_EXACT_LEN_WARN(ETH_ALEN)
73
74-#define NLA_POLICY_NESTED(maxattr, policy) \
75- { .type = NLA_NESTED, .validation_data = policy, .len = maxattr }
76-#define NLA_POLICY_NESTED_ARRAY(maxattr, policy) \
77- { .type = NLA_NESTED_ARRAY, .validation_data = policy, .len = maxattr }
78-
79 #define __NLA_ENSURE(condition) (sizeof(char[1 - 2*!(condition)]) - 1)
80 #define NLA_ENSURE_INT_TYPE(tp) \
81 (__NLA_ENSURE(tp == NLA_S8 || tp == NLA_U8 || \
82diff --git a/compat/Makefile b/compat/Makefile
83index 7d2278b..1f62e4f 100644
84--- a/compat/Makefile
85+++ b/compat/Makefile
86@@ -39,7 +39,7 @@ compat-$(CPTCFG_KERNEL_4_10) += backport-4.10.o
87 compat-$(CPTCFG_KERNEL_4_18) += backport-4.18.o
88 compat-$(CPTCFG_KERNEL_4_20) += backport-4.20.o
89
90-compat-$(CPTCFG_KERNEL_4_20) += backport-genetlink.o
91+compat-$(CPTCFG_KERNEL_5_2) += backport-genetlink.o
92
93 compat-$(CPTCFG_BPAUTO_BUILD_SYSTEM_DATA_VERIFICATION) += verification/verify.o
94 compat-$(CPTCFG_BPAUTO_BUILD_SYSTEM_DATA_VERIFICATION) += verification/pkcs7.asn1.o
95diff --git a/compat/backport-4.20.c b/compat/backport-4.20.c
96index e26f3b5..a75657f 100644
97--- a/compat/backport-4.20.c
98+++ b/compat/backport-4.20.c
99@@ -1,5 +1,5 @@
100 /*
101- * Copyright (C) 2018 Intel Corporation
102+ * Copyright (C) 2018 - 2019 Intel Corporation
103 *
104 * Backport functionality introduced in Linux 4.20.
105 * This is basically upstream lib/nlattr.c.
106@@ -158,6 +158,9 @@ static int validate_nla(const struct nlattr *nla, int maxtype,
107 if (type <= 0 || type > maxtype)
108 return 0;
109
110+ if (WARN_ON(!policy))
111+ return -EINVAL;
112+
113 pt = &policy[type];
114
115 BUG_ON(pt->type > NLA_TYPE_MAX);
116@@ -316,6 +319,9 @@ int backport_nla_validate(const struct nlattr *head, int len, int maxtype,
117 const struct nlattr *nla;
118 int rem;
119
120+ if (!policy)
121+ return 0;
122+
123 nla_for_each_attr(nla, head, len, rem) {
124 int err = validate_nla(nla, maxtype, policy, extack);
125
126diff --git a/compat/backport-genetlink.c b/compat/backport-genetlink.c
127index fb559d2..f9e307b 100644
128--- a/compat/backport-genetlink.c
129+++ b/compat/backport-genetlink.c
130@@ -169,7 +169,7 @@ static int backport_pre_doit(__genl_const struct genl_ops *ops,
131 #endif
132
133 err = nlmsg_validate(info->nlhdr, GENL_HDRLEN + family->hdrsize,
134- family->maxattr, ops->policy, extack);
135+ family->maxattr, family->policy, extack);
136 if (!err && family->pre_doit)
137 err = family->pre_doit(ops, skb, info);
138
139diff --git a/compat/verification/pkcs7_verify.c b/compat/verification/pkcs7_verify.c
140index 97c77f6..f7b0980 100644
141--- a/compat/verification/pkcs7_verify.c
142+++ b/compat/verification/pkcs7_verify.c
143@@ -56,7 +56,6 @@ static int pkcs7_digest(struct pkcs7_message *pkcs7,
144 goto error_no_desc;
145
146 desc->tfm = tfm;
147- desc->flags = CRYPTO_TFM_REQ_MAY_SLEEP;
148
149 /* Digest the message [RFC2315 9.3] */
150 ret = crypto_shash_digest(desc, pkcs7->data, pkcs7->data_len,
151diff --git a/debian/backport-iwlwifi-dkms.modaliases b/debian/backport-iwlwifi-dkms.modaliases
152index 4ac4b99..9e7706a 100644
153--- a/debian/backport-iwlwifi-dkms.modaliases
154+++ b/debian/backport-iwlwifi-dkms.modaliases
155@@ -2,6 +2,7 @@ alias net-pf-16-proto-16-family-nl80211 cfg80211
156 alias pci:v00008086d00007AF0sv*sd00000A10bc*sc*i* iwlwifi
157 alias pci:v00008086d00007AF0sv*sd00000510bc*sc*i* iwlwifi
158 alias pci:v00008086d00007AF0sv*sd00000310bc*sc*i* iwlwifi
159+alias pci:v00008086d00007AF0sv*sd00000090bc*sc*i* iwlwifi
160 alias pci:v00008086d00007A70sv*sd00000A10bc*sc*i* iwlwifi
161 alias pci:v00008086d00007A70sv*sd00000510bc*sc*i* iwlwifi
162 alias pci:v00008086d00007A70sv*sd00000310bc*sc*i* iwlwifi
163@@ -366,6 +367,7 @@ alias pci:v00008086d0000271Bsv*sd00000010bc*sc*i* iwlwifi
164 alias pci:v00008086d00002526sv*sd0000A014bc*sc*i* iwlwifi
165 alias pci:v00008086d00002526sv*sd00008010bc*sc*i* iwlwifi
166 alias pci:v00008086d00002526sv*sd00008014bc*sc*i* iwlwifi
167+alias pci:v00008086d00002526sv*sd00006014bc*sc*i* iwlwifi
168 alias pci:v00008086d00002526sv*sd000042A4bc*sc*i* iwlwifi
169 alias pci:v00008086d00002526sv*sd00004234bc*sc*i* iwlwifi
170 alias pci:v00008086d00002526sv*sd000040A4bc*sc*i* iwlwifi
171diff --git a/debian/changelog b/debian/changelog
172index d70c99a..75ea7c7 100644
173--- a/debian/changelog
174+++ b/debian/changelog
175@@ -1,3 +1,9 @@
176+backport-iwlwifi-dkms (7906-ubuntu1) UNRELEASED; urgency=low
177+
178+ * Sync with debian 7906-1.
179+
180+ -- You-Sheng Yang <vicamo@gmail.com> Tue, 9 Jul 2019 16:35:22 +0800
181+
182 backport-iwlwifi-dkms (7858-ubuntu2) UNRELEASED; urgency=low
183
184 * Fix build on recent kernel that removes *.lex.c and *.tab.c at clean
185diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/22000.c b/drivers/net/wireless/intel/iwlwifi/cfg/22000.c
186index c5a0b6f..351f2c0 100644
187--- a/drivers/net/wireless/intel/iwlwifi/cfg/22000.c
188+++ b/drivers/net/wireless/intel/iwlwifi/cfg/22000.c
189@@ -56,7 +56,7 @@
190 #include "iwl-config.h"
191
192 /* Highest firmware API version supported */
193-#define IWL_22000_UCODE_API_MAX 50
194+#define IWL_22000_UCODE_API_MAX 51
195
196 /* Lowest firmware API version supported */
197 #define IWL_22000_UCODE_API_MIN 39
198@@ -76,11 +76,12 @@
199 #define IWL_22000_HR_FW_PRE "iwlwifi-Qu-a0-hr-a0-"
200 #define IWL_22000_HR_CDB_FW_PRE "iwlwifi-QuIcp-z0-hrcdb-a0-"
201 #define IWL_22000_HR_A_F0_FW_PRE "iwlwifi-QuQnj-f0-hr-a0-"
202-#define IWL_22000_HR_B_F0_FW_PRE "iwlwifi-Qu-b0-hr-b0-"
203 #define IWL_22000_QU_B_HR_B_FW_PRE "iwlwifi-Qu-b0-hr-b0-"
204 #define IWL_22000_HR_B_FW_PRE "iwlwifi-QuQnj-b0-hr-b0-"
205 #define IWL_22000_HR_A0_FW_PRE "iwlwifi-QuQnj-a0-hr-a0-"
206+#define IWL_QU_C_HR_B_FW_PRE "iwlwifi-Qu-c0-hr-b0-"
207 #define IWL_QU_B_JF_B_FW_PRE "iwlwifi-Qu-b0-jf-b0-"
208+#define IWL_QU_C_JF_B_FW_PRE "iwlwifi-Qu-c0-jf-b0-"
209 #define IWL_QUZ_A_HR_B_FW_PRE "iwlwifi-QuZ-a0-hr-b0-"
210 #define IWL_QUZ_A_JF_B_FW_PRE "iwlwifi-QuZ-a0-jf-b0-"
211 #define IWL_QNJ_B_JF_B_FW_PRE "iwlwifi-QuQnj-b0-jf-b0-"
212@@ -97,8 +98,6 @@
213 IWL_22000_JF_FW_PRE __stringify(api) ".ucode"
214 #define IWL_22000_HR_A_F0_QNJ_MODULE_FIRMWARE(api) \
215 IWL_22000_HR_A_F0_FW_PRE __stringify(api) ".ucode"
216-#define IWL_22000_HR_B_F0_QNJ_MODULE_FIRMWARE(api) \
217- IWL_22000_HR_B_F0_FW_PRE __stringify(api) ".ucode"
218 #define IWL_22000_QU_B_HR_B_MODULE_FIRMWARE(api) \
219 IWL_22000_QU_B_HR_B_FW_PRE __stringify(api) ".ucode"
220 #define IWL_22000_HR_B_QNJ_MODULE_FIRMWARE(api) \
221@@ -109,6 +108,8 @@
222 IWL_QUZ_A_HR_B_FW_PRE __stringify(api) ".ucode"
223 #define IWL_QUZ_A_JF_B_MODULE_FIRMWARE(api) \
224 IWL_QUZ_A_JF_B_FW_PRE __stringify(api) ".ucode"
225+#define IWL_QU_C_HR_B_MODULE_FIRMWARE(api) \
226+ IWL_QU_C_HR_B_FW_PRE __stringify(api) ".ucode"
227 #define IWL_QU_B_JF_B_MODULE_FIRMWARE(api) \
228 IWL_QU_B_JF_B_FW_PRE __stringify(api) ".ucode"
229 #define IWL_QNJ_B_JF_B_MODULE_FIRMWARE(api) \
230@@ -256,6 +257,30 @@ const struct iwl_cfg iwl_ax201_cfg_qu_hr = {
231 .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT,
232 };
233
234+const struct iwl_cfg iwl_ax101_cfg_qu_c0_hr_b0 = {
235+ .name = "Intel(R) Wi-Fi 6 AX101",
236+ .fw_name_pre = IWL_QU_C_HR_B_FW_PRE,
237+ IWL_DEVICE_22500,
238+ /*
239+ * This device doesn't support receiving BlockAck with a large bitmap
240+ * so we need to restrict the size of transmitted aggregation to the
241+ * HT size; mac80211 would otherwise pick the HE max (256) by default.
242+ */
243+ .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT,
244+};
245+
246+const struct iwl_cfg iwl_ax201_cfg_qu_c0_hr_b0 = {
247+ .name = "Intel(R) Wi-Fi 6 AX201 160MHz",
248+ .fw_name_pre = IWL_QU_C_HR_B_FW_PRE,
249+ IWL_DEVICE_22500,
250+ /*
251+ * This device doesn't support receiving BlockAck with a large bitmap
252+ * so we need to restrict the size of transmitted aggregation to the
253+ * HT size; mac80211 would otherwise pick the HE max (256) by default.
254+ */
255+ .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT,
256+};
257+
258 const struct iwl_cfg iwl_ax101_cfg_quz_hr = {
259 .name = "Intel(R) Wi-Fi 6 AX101",
260 .fw_name_pre = IWL_QUZ_A_HR_B_FW_PRE,
261@@ -372,6 +397,30 @@ const struct iwl_cfg iwl9560_2ac_160_cfg_qu_b0_jf_b0 = {
262 IWL_DEVICE_22500,
263 };
264
265+const struct iwl_cfg iwl9461_2ac_cfg_qu_c0_jf_b0 = {
266+ .name = "Intel(R) Wireless-AC 9461",
267+ .fw_name_pre = IWL_QU_C_JF_B_FW_PRE,
268+ IWL_DEVICE_22500,
269+};
270+
271+const struct iwl_cfg iwl9462_2ac_cfg_qu_c0_jf_b0 = {
272+ .name = "Intel(R) Wireless-AC 9462",
273+ .fw_name_pre = IWL_QU_C_JF_B_FW_PRE,
274+ IWL_DEVICE_22500,
275+};
276+
277+const struct iwl_cfg iwl9560_2ac_cfg_qu_c0_jf_b0 = {
278+ .name = "Intel(R) Wireless-AC 9560",
279+ .fw_name_pre = IWL_QU_C_JF_B_FW_PRE,
280+ IWL_DEVICE_22500,
281+};
282+
283+const struct iwl_cfg iwl9560_2ac_160_cfg_qu_c0_jf_b0 = {
284+ .name = "Intel(R) Wireless-AC 9560 160MHz",
285+ .fw_name_pre = IWL_QU_C_JF_B_FW_PRE,
286+ IWL_DEVICE_22500,
287+};
288+
289 const struct iwl_cfg iwl9560_2ac_cfg_qnj_jf_b0 = {
290 .name = "Intel(R) Wireless-AC 9560 160MHz",
291 .fw_name_pre = IWL_QNJ_B_JF_B_FW_PRE,
292@@ -530,7 +579,7 @@ const struct iwl_cfg iwl22000_2ax_cfg_qnj_hr_a0_f0 = {
293
294 const struct iwl_cfg iwl22000_2ax_cfg_qnj_hr_b0_f0 = {
295 .name = "Intel(R) Dual Band Wireless AX 22000",
296- .fw_name_pre = IWL_22000_HR_B_F0_FW_PRE,
297+ .fw_name_pre = IWL_22000_QU_B_HR_B_FW_PRE,
298 IWL_DEVICE_22500,
299 /*
300 * This device doesn't support receiving BlockAck with a large bitmap
301@@ -599,9 +648,9 @@ const struct iwl_cfg iwlax411_2ax_cfg_so_gf4_a0 = {
302 MODULE_FIRMWARE(IWL_22000_HR_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX));
303 MODULE_FIRMWARE(IWL_22000_JF_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX));
304 MODULE_FIRMWARE(IWL_22000_HR_A_F0_QNJ_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX));
305-MODULE_FIRMWARE(IWL_22000_HR_B_F0_QNJ_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX));
306 MODULE_FIRMWARE(IWL_22000_HR_B_QNJ_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX));
307 MODULE_FIRMWARE(IWL_22000_HR_A0_QNJ_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX));
308+MODULE_FIRMWARE(IWL_QU_C_HR_B_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX));
309 MODULE_FIRMWARE(IWL_QU_B_JF_B_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX));
310 MODULE_FIRMWARE(IWL_QUZ_A_HR_B_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX));
311 MODULE_FIRMWARE(IWL_QUZ_A_JF_B_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX));
312diff --git a/drivers/net/wireless/intel/iwlwifi/fw/acpi.h b/drivers/net/wireless/intel/iwlwifi/fw/acpi.h
313index 991a234..6cb2d1f 100644
314--- a/drivers/net/wireless/intel/iwlwifi/fw/acpi.h
315+++ b/drivers/net/wireless/intel/iwlwifi/fw/acpi.h
316@@ -68,6 +68,7 @@
317 #define ACPI_WRDD_METHOD "WRDD"
318 #define ACPI_SPLC_METHOD "SPLC"
319 #define ACPI_ECKV_METHOD "ECKV"
320+#define ACPI_PPAG_METHOD "PPAG"
321
322 #define ACPI_WIFI_DOMAIN (0x07)
323
324@@ -92,6 +93,17 @@
325 #define ACPI_WGDS_NUM_BANDS 2
326 #define ACPI_WGDS_TABLE_SIZE 3
327
328+#define ACPI_PPAG_NUM_CHAINS 2
329+#define ACPI_PPAG_NUM_SUB_BANDS 5
330+#define ACPI_PPAG_WIFI_DATA_SIZE ((ACPI_PPAG_NUM_CHAINS * \
331+ ACPI_PPAG_NUM_SUB_BANDS) + 3)
332+
333+/* PPAG gain value bounds in 1/8 dBm */
334+#define ACPI_PPAG_MIN_LB -16
335+#define ACPI_PPAG_MAX_LB 24
336+#define ACPI_PPAG_MIN_HB -16
337+#define ACPI_PPAG_MAX_HB 40
338+
339 #ifdef CONFIG_ACPI
340
341 void *iwl_acpi_get_object(struct device *dev, acpi_string method);
342diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/dbg-tlv.h b/drivers/net/wireless/intel/iwlwifi/fw/api/dbg-tlv.h
343index aaf3974..e02e289 100644
344--- a/drivers/net/wireless/intel/iwlwifi/fw/api/dbg-tlv.h
345+++ b/drivers/net/wireless/intel/iwlwifi/fw/api/dbg-tlv.h
346@@ -439,6 +439,7 @@ enum iwl_fw_ini_apply_point {
347 * @IWL_FW_INI_ALLOCATION_ID_SDFX: for SDFX module
348 * @IWL_FW_INI_ALLOCATION_ID_FW_DUMP: used for crash and runtime dumps
349 * @IWL_FW_INI_ALLOCATION_ID_USER_DEFINED: for future user scenarios
350+ * @IWL_FW_INI_ALLOCATION_NUM: number of allocation ids
351 */
352 enum iwl_fw_ini_allocation_id {
353 IWL_FW_INI_ALLOCATION_INVALID,
354@@ -448,6 +449,7 @@ enum iwl_fw_ini_allocation_id {
355 IWL_FW_INI_ALLOCATION_ID_SDFX,
356 IWL_FW_INI_ALLOCATION_ID_FW_DUMP,
357 IWL_FW_INI_ALLOCATION_ID_USER_DEFINED,
358+ IWL_FW_INI_ALLOCATION_NUM,
359 }; /* FW_DEBUG_TLV_ALLOCATION_ID_E_VER_1 */
360
361 /**
362diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/location.h b/drivers/net/wireless/intel/iwlwifi/fw/api/location.h
363index ec864c7..7a0fe5a 100644
364--- a/drivers/net/wireless/intel/iwlwifi/fw/api/location.h
365+++ b/drivers/net/wireless/intel/iwlwifi/fw/api/location.h
366@@ -82,7 +82,7 @@ enum iwl_location_subcmd_ids {
367 TOF_RANGE_ABORT_CMD = 0x2,
368 /**
369 * @TOF_RANGE_REQ_EXT_CMD: TOF extended ranging config,
370- * uses &struct iwl_tof_range_request_ext_cmd
371+ * uses &struct iwl_tof_range_req_ext_cmd
372 */
373 TOF_RANGE_REQ_EXT_CMD = 0x3,
374 /**
375@@ -292,7 +292,7 @@ struct iwl_tof_responder_dyn_config_cmd {
376 } __packed; /* TOF_RESPONDER_DYN_CONFIG_CMD_API_S_VER_2 */
377
378 /**
379- * struct iwl_tof_range_request_ext_cmd - extended range req for WLS
380+ * struct iwl_tof_range_req_ext_cmd - extended range req for WLS
381 * @tsf_timer_offset_msec: the recommended time offset (mSec) from the AP's TSF
382 * @reserved: reserved
383 * @min_delta_ftm: Minimal time between two consecutive measurements,
384diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/phy.h b/drivers/net/wireless/intel/iwlwifi/fw/api/phy.h
385index 9cc59e0..8991ddf 100644
386--- a/drivers/net/wireless/intel/iwlwifi/fw/api/phy.h
387+++ b/drivers/net/wireless/intel/iwlwifi/fw/api/phy.h
388@@ -8,6 +8,7 @@
389 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
390 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
391 * Copyright(c) 2016 - 2017 Intel Deutschland GmbH
392+ * Copyright(c) 2019 Intel Corporation
393 *
394 * This program is free software; you can redistribute it and/or modify
395 * it under the terms of version 2 of the GNU General Public License as
396@@ -30,6 +31,7 @@
397 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
398 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
399 * Copyright(c) 2016 - 2017 Intel Deutschland GmbH
400+ * Copyright(c) 2019 Intel Corporation
401 * All rights reserved.
402 *
403 * Redistribution and use in source and binary forms, with or without
404@@ -90,6 +92,11 @@ enum iwl_phy_ops_subcmd_ids {
405 GEO_TX_POWER_LIMIT = 0x05,
406
407 /**
408+ * @PER_PLATFORM_ANT_GAIN_CMD: &struct iwl_ppag_table_cmd
409+ */
410+ PER_PLATFORM_ANT_GAIN_CMD = 0x07,
411+
412+ /**
413 * @CT_KILL_NOTIFICATION: &struct ct_kill_notif
414 */
415 CT_KILL_NOTIFICATION = 0xFE,
416diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/power.h b/drivers/net/wireless/intel/iwlwifi/fw/api/power.h
417index f195db3..6e1b9b2 100644
418--- a/drivers/net/wireless/intel/iwlwifi/fw/api/power.h
419+++ b/drivers/net/wireless/intel/iwlwifi/fw/api/power.h
420@@ -450,6 +450,18 @@ struct iwl_geo_tx_power_profiles_resp {
421 } __packed; /* GEO_TX_POWER_LIMIT_RESP */
422
423 /**
424+ * struct iwl_ppag_table_cmd - struct for PER_PLATFORM_ANT_GAIN_CMD cmd.
425+ * @enabled: 1 if PPAG is enabled, 0 otherwise
426+ * @gain: table of antenna gain values per chain and sub-band
427+ * @reserved: reserved
428+ */
429+struct iwl_ppag_table_cmd {
430+ __le32 enabled;
431+ s8 gain[IWL_NUM_CHAIN_LIMITS][IWL_NUM_SUB_BANDS];
432+ s8 reserved[2];
433+} __packed; /* PER_PLATFORM_ANT_GAIN_CMD */
434+
435+/**
436 * struct iwl_beacon_filter_cmd
437 * REPLY_BEACON_FILTERING_CMD = 0xd2 (command)
438 * @bf_energy_delta: Used for RSSI filtering, if in 'normal' state. Send beacon
439diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/rx.h b/drivers/net/wireless/intel/iwlwifi/fw/api/rx.h
440index 4a96090..2920a11 100644
441--- a/drivers/net/wireless/intel/iwlwifi/fw/api/rx.h
442+++ b/drivers/net/wireless/intel/iwlwifi/fw/api/rx.h
443@@ -777,7 +777,6 @@ struct iwl_rss_config_cmd {
444 u8 indirection_table[IWL_RSS_INDIRECTION_TABLE_SIZE];
445 } __packed; /* RSS_CONFIG_CMD_API_S_VER_1 */
446
447-#define IWL_MULTI_QUEUE_SYNC_MSG_MAX_SIZE 128
448 #define IWL_MULTI_QUEUE_SYNC_SENDER_POS 0
449 #define IWL_MULTI_QUEUE_SYNC_SENDER_MSK 0xf
450
451@@ -813,10 +812,12 @@ struct iwl_rxq_sync_notification {
452 *
453 * @IWL_MVM_RXQ_EMPTY: empty sync notification
454 * @IWL_MVM_RXQ_NOTIF_DEL_BA: notify RSS queues of delBA
455+ * @IWL_MVM_RXQ_NSSN_SYNC: notify all the RSS queues with the new NSSN
456 */
457 enum iwl_mvm_rxq_notif_type {
458 IWL_MVM_RXQ_EMPTY,
459 IWL_MVM_RXQ_NOTIF_DEL_BA,
460+ IWL_MVM_RXQ_NSSN_SYNC,
461 };
462
463 /**
464diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c
465index d5a595a..d243f71 100644
466--- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c
467+++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c
468@@ -468,6 +468,9 @@ static const struct iwl_prph_range iwl_prph_dump_addr_9000[] = {
469 { .start = 0x00a05400, .end = 0x00a056e8 },
470 { .start = 0x00a08000, .end = 0x00a098bc },
471 { .start = 0x00a02400, .end = 0x00a02758 },
472+ { .start = 0x00a04764, .end = 0x00a0476c },
473+ { .start = 0x00a04770, .end = 0x00a04774 },
474+ { .start = 0x00a04620, .end = 0x00a04624 },
475 };
476
477 static const struct iwl_prph_range iwl_prph_dump_addr_22000[] = {
478@@ -1905,8 +1908,6 @@ static void iwl_fw_ini_dump_trigger(struct iwl_fw_runtime *fwrt,
479 iwl_dump_ini_mem(fwrt, data, reg, &ops);
480 break;
481 case IWL_FW_INI_REGION_PERIPHERY_MAC:
482- case IWL_FW_INI_REGION_PERIPHERY_PHY:
483- case IWL_FW_INI_REGION_PERIPHERY_AUX:
484 ops.get_num_of_ranges = iwl_dump_ini_mem_ranges;
485 ops.get_size = iwl_dump_ini_mem_get_size;
486 ops.fill_mem_hdr = iwl_dump_ini_mem_fill_header;
487@@ -1971,6 +1972,8 @@ static void iwl_fw_ini_dump_trigger(struct iwl_fw_runtime *fwrt,
488 ops.fill_range = iwl_dump_ini_csr_iter;
489 iwl_dump_ini_mem(fwrt, data, reg, &ops);
490 break;
491+ case IWL_FW_INI_REGION_PERIPHERY_PHY:
492+ case IWL_FW_INI_REGION_PERIPHERY_AUX:
493 case IWL_FW_INI_REGION_DRAM_IMR:
494 /* This is undefined yet */
495 default:
496@@ -2481,8 +2484,7 @@ iwl_fw_dbg_buffer_allocation(struct iwl_fw_runtime *fwrt, u32 size)
497
498 virtual_addr =
499 dma_alloc_coherent(fwrt->trans->dev, size, &phys_addr,
500- GFP_KERNEL | __GFP_NOWARN | __GFP_ZERO |
501- __GFP_COMP);
502+ GFP_KERNEL | __GFP_NOWARN);
503
504 /* TODO: alloc fragments if needed */
505 if (!virtual_addr)
506@@ -2499,7 +2501,7 @@ iwl_fw_dbg_buffer_allocation(struct iwl_fw_runtime *fwrt, u32 size)
507 }
508
509 static void iwl_fw_dbg_buffer_apply(struct iwl_fw_runtime *fwrt,
510- struct iwl_fw_ini_allocation_data *alloc,
511+ struct iwl_fw_ini_allocation_tlv *alloc,
512 enum iwl_fw_ini_apply_point pnt)
513 {
514 struct iwl_trans *trans = fwrt->trans;
515@@ -2514,7 +2516,14 @@ static void iwl_fw_dbg_buffer_apply(struct iwl_fw_runtime *fwrt,
516 .len[0] = sizeof(ldbg_cmd),
517 };
518 int block_idx = trans->dbg.num_blocks;
519- u32 buf_location = le32_to_cpu(alloc->tlv.buffer_location);
520+ u32 buf_location = le32_to_cpu(alloc->buffer_location);
521+ u32 alloc_id = le32_to_cpu(alloc->allocation_id);
522+
523+ if (alloc_id <= IWL_FW_INI_ALLOCATION_INVALID ||
524+ alloc_id >= IWL_FW_INI_ALLOCATION_NUM) {
525+ IWL_ERR(fwrt, "WRT: Invalid allocation id %d\n", alloc_id);
526+ return;
527+ }
528
529 if (fwrt->trans->dbg.ini_dest == IWL_FW_INI_LOCATION_INVALID)
530 fwrt->trans->dbg.ini_dest = buf_location;
531@@ -2539,12 +2548,11 @@ static void iwl_fw_dbg_buffer_apply(struct iwl_fw_runtime *fwrt,
532 if (buf_location != IWL_FW_INI_LOCATION_DRAM_PATH)
533 return;
534
535- if (!alloc->is_alloc) {
536- iwl_fw_dbg_buffer_allocation(fwrt,
537- le32_to_cpu(alloc->tlv.size));
538+ if (!(BIT(alloc_id) & fwrt->trans->dbg.is_alloc)) {
539+ iwl_fw_dbg_buffer_allocation(fwrt, le32_to_cpu(alloc->size));
540 if (block_idx == trans->dbg.num_blocks)
541 return;
542- alloc->is_alloc = 1;
543+ fwrt->trans->dbg.is_alloc |= BIT(alloc_id);
544 }
545
546 /* First block is assigned via registers / context info */
547@@ -2557,9 +2565,9 @@ static void iwl_fw_dbg_buffer_apply(struct iwl_fw_runtime *fwrt,
548 cmd->num_frags = cpu_to_le32(1);
549 cmd->fragments[0].address =
550 cpu_to_le64(trans->dbg.fw_mon[block_idx].physical);
551- cmd->fragments[0].size = alloc->tlv.size;
552- cmd->allocation_id = alloc->tlv.allocation_id;
553- cmd->buffer_location = alloc->tlv.buffer_location;
554+ cmd->fragments[0].size = alloc->size;
555+ cmd->allocation_id = alloc->allocation_id;
556+ cmd->buffer_location = alloc->buffer_location;
557
558 iwl_trans_send_cmd(trans, &hcmd);
559 }
560@@ -2773,10 +2781,13 @@ static void _iwl_fw_dbg_apply_point(struct iwl_fw_runtime *fwrt,
561 enum iwl_fw_ini_apply_point pnt,
562 bool ext)
563 {
564- void *iter = data->data;
565+ struct iwl_apply_point_data *iter;
566+
567+ if (!data->list.next)
568+ return;
569
570- while (iter && iter < data->data + data->size) {
571- struct iwl_ucode_tlv *tlv = iter;
572+ list_for_each_entry(iter, &data->list, list) {
573+ struct iwl_ucode_tlv *tlv = &iter->tlv;
574 void *ini_tlv = (void *)tlv->data;
575 u32 type = le32_to_cpu(tlv->type);
576 const char invalid_ap_str[] =
577@@ -2786,24 +2797,19 @@ static void _iwl_fw_dbg_apply_point(struct iwl_fw_runtime *fwrt,
578 case IWL_UCODE_TLV_TYPE_DEBUG_INFO:
579 iwl_fw_dbg_info_apply(fwrt, ini_tlv, ext, pnt);
580 break;
581- case IWL_UCODE_TLV_TYPE_BUFFER_ALLOCATION: {
582- struct iwl_fw_ini_allocation_data *buf_alloc = ini_tlv;
583-
584+ case IWL_UCODE_TLV_TYPE_BUFFER_ALLOCATION:
585 if (pnt != IWL_FW_INI_APPLY_EARLY) {
586 IWL_ERR(fwrt, invalid_ap_str, ext, pnt,
587 "buffer allocation");
588- goto next;
589+ break;
590 }
591-
592 iwl_fw_dbg_buffer_apply(fwrt, ini_tlv, pnt);
593- iter += sizeof(buf_alloc->is_alloc);
594 break;
595- }
596 case IWL_UCODE_TLV_TYPE_HCMD:
597 if (pnt < IWL_FW_INI_APPLY_AFTER_ALIVE) {
598 IWL_ERR(fwrt, invalid_ap_str, ext, pnt,
599 "host command");
600- goto next;
601+ break;
602 }
603 iwl_fw_dbg_send_hcmd(fwrt, tlv, ext);
604 break;
605@@ -2821,8 +2827,6 @@ static void _iwl_fw_dbg_apply_point(struct iwl_fw_runtime *fwrt,
606 ext, type);
607 break;
608 }
609-next:
610- iter += sizeof(*tlv) + le32_to_cpu(tlv->length);
611 }
612 }
613
614diff --git a/drivers/net/wireless/intel/iwlwifi/fw/file.h b/drivers/net/wireless/intel/iwlwifi/fw/file.h
615index a2b9299..d2b162f 100644
616--- a/drivers/net/wireless/intel/iwlwifi/fw/file.h
617+++ b/drivers/net/wireless/intel/iwlwifi/fw/file.h
618@@ -476,6 +476,7 @@ enum iwl_ucode_tlv_capa {
619 IWL_UCODE_TLV_CAPA_ULTRA_HB_CHANNELS = (__force iwl_ucode_tlv_capa_t)48,
620 IWL_UCODE_TLV_CAPA_CS_MODIFY = (__force iwl_ucode_tlv_capa_t)49,
621 IWL_UCODE_TLV_CAPA_SET_LTR_GEN2 = (__force iwl_ucode_tlv_capa_t)50,
622+ IWL_UCODE_TLV_CAPA_SET_PPAG = (__force iwl_ucode_tlv_capa_t)52,
623
624 /* set 2 */
625 IWL_UCODE_TLV_CAPA_EXTENDED_DTS_MEASURE = (__force iwl_ucode_tlv_capa_t)64,
626diff --git a/drivers/net/wireless/intel/iwlwifi/fw/img.h b/drivers/net/wireless/intel/iwlwifi/fw/img.h
627index 18ca5f1..039576d 100644
628--- a/drivers/net/wireless/intel/iwlwifi/fw/img.h
629+++ b/drivers/net/wireless/intel/iwlwifi/fw/img.h
630@@ -228,15 +228,6 @@ struct iwl_fw_dbg {
631 };
632
633 /**
634- * @tlv: the buffer allocation tlv
635- * @is_alloc: indicates if the buffer was already allocated
636- */
637-struct iwl_fw_ini_allocation_data {
638- struct iwl_fw_ini_allocation_tlv tlv;
639- u32 is_alloc;
640-} __packed;
641-
642-/**
643 * struct iwl_fw_ini_active_triggers
644 * @active: is this trigger active
645 * @size: allocated memory size of the trigger
646diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-config.h b/drivers/net/wireless/intel/iwlwifi/iwl-config.h
647index 286bc0c..2cc02f0 100644
648--- a/drivers/net/wireless/intel/iwlwifi/iwl-config.h
649+++ b/drivers/net/wireless/intel/iwlwifi/iwl-config.h
650@@ -523,10 +523,13 @@ extern const struct iwl_cfg iwl22000_2ac_cfg_hr;
651 extern const struct iwl_cfg iwl22000_2ac_cfg_hr_cdb;
652 extern const struct iwl_cfg iwl22000_2ac_cfg_jf;
653 extern const struct iwl_cfg iwl_ax101_cfg_qu_hr;
654+extern const struct iwl_cfg iwl_ax101_cfg_qu_c0_hr_b0;
655 extern const struct iwl_cfg iwl_ax101_cfg_quz_hr;
656 extern const struct iwl_cfg iwl22000_2ax_cfg_hr;
657 extern const struct iwl_cfg iwl_ax200_cfg_cc;
658 extern const struct iwl_cfg iwl_ax201_cfg_qu_hr;
659+extern const struct iwl_cfg iwl_ax201_cfg_qu_hr;
660+extern const struct iwl_cfg iwl_ax201_cfg_qu_c0_hr_b0;
661 extern const struct iwl_cfg iwl_ax201_cfg_quz_hr;
662 extern const struct iwl_cfg iwl_ax1650i_cfg_quz_hr;
663 extern const struct iwl_cfg iwl_ax1650s_cfg_quz_hr;
664@@ -538,6 +541,10 @@ extern const struct iwl_cfg iwl9461_2ac_cfg_qu_b0_jf_b0;
665 extern const struct iwl_cfg iwl9462_2ac_cfg_qu_b0_jf_b0;
666 extern const struct iwl_cfg iwl9560_2ac_cfg_qu_b0_jf_b0;
667 extern const struct iwl_cfg iwl9560_2ac_160_cfg_qu_b0_jf_b0;
668+extern const struct iwl_cfg iwl9461_2ac_cfg_qu_c0_jf_b0;
669+extern const struct iwl_cfg iwl9462_2ac_cfg_qu_c0_jf_b0;
670+extern const struct iwl_cfg iwl9560_2ac_cfg_qu_c0_jf_b0;
671+extern const struct iwl_cfg iwl9560_2ac_160_cfg_qu_c0_jf_b0;
672 extern const struct iwl_cfg killer1550i_2ac_cfg_qu_b0_jf_b0;
673 extern const struct iwl_cfg killer1550s_2ac_cfg_qu_b0_jf_b0;
674 extern const struct iwl_cfg iwl22000_2ax_cfg_jf;
675diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-csr.h b/drivers/net/wireless/intel/iwlwifi/iwl-csr.h
676index 1c867ce..cb4c551 100644
677--- a/drivers/net/wireless/intel/iwlwifi/iwl-csr.h
678+++ b/drivers/net/wireless/intel/iwlwifi/iwl-csr.h
679@@ -329,6 +329,7 @@ enum {
680 #define CSR_HW_REV_TYPE_QNJ (0x0000360)
681 #define CSR_HW_REV_TYPE_QNJ_B0 (0x0000364)
682 #define CSR_HW_REV_TYPE_QU_B0 (0x0000334)
683+#define CSR_HW_REV_TYPE_QU_C0 (0x0000338)
684 #define CSR_HW_REV_TYPE_QUZ (0x0000354)
685 #define CSR_HW_REV_TYPE_HR_CDB (0x0000340)
686 #define CSR_HW_REV_TYPE_SO (0x0000370)
687diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c b/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c
688index c4481aa..3029236 100644
689--- a/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c
690+++ b/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c
691@@ -60,143 +60,79 @@
692 #include "iwl-trans.h"
693 #include "iwl-dbg-tlv.h"
694
695-void iwl_fw_dbg_copy_tlv(struct iwl_trans *trans, struct iwl_ucode_tlv *tlv,
696- bool ext)
697+void iwl_dbg_tlv_copy(struct iwl_trans *trans, struct iwl_ucode_tlv *tlv,
698+ bool ext)
699 {
700- struct iwl_apply_point_data *data;
701+ struct iwl_apply_point_data *dbg_cfg, *tlv_copy;
702 struct iwl_fw_ini_header *header = (void *)&tlv->data[0];
703+ u32 tlv_type = le32_to_cpu(tlv->type);
704+ u32 len = le32_to_cpu(tlv->length);
705 u32 apply_point = le32_to_cpu(header->apply_point);
706
707- int copy_size = le32_to_cpu(tlv->length) + sizeof(*tlv);
708- int offset_size = copy_size;
709-
710 if (le32_to_cpu(header->tlv_version) != 1)
711 return;
712
713 if (WARN_ONCE(apply_point >= IWL_FW_INI_APPLY_NUM,
714- "Invalid apply point id %d\n", apply_point))
715+ "Invalid apply point %d\n", apply_point))
716 return;
717
718+ IWL_DEBUG_FW(trans, "WRT: read TLV 0x%x, apply point %d\n",
719+ tlv_type, apply_point);
720+
721 if (ext)
722- data = &trans->dbg.apply_points_ext[apply_point];
723+ dbg_cfg = &trans->dbg.apply_points_ext[apply_point];
724 else
725- data = &trans->dbg.apply_points[apply_point];
726-
727- /* add room for is_alloc field in &iwl_fw_ini_allocation_data struct */
728- if (le32_to_cpu(tlv->type) == IWL_UCODE_TLV_TYPE_BUFFER_ALLOCATION) {
729- struct iwl_fw_ini_allocation_data *buf_alloc =
730- (void *)tlv->data;
731-
732- offset_size += sizeof(buf_alloc->is_alloc);
733- }
734+ dbg_cfg = &trans->dbg.apply_points[apply_point];
735
736- /*
737- * Make sure we still have room to copy this TLV. Offset points to the
738- * location the last copy ended.
739- */
740- if (WARN_ONCE(data->offset + offset_size > data->size,
741- "Not enough memory for apply point %d\n",
742- apply_point))
743+ tlv_copy = kzalloc(sizeof(*tlv_copy) + len, GFP_KERNEL);
744+ if (!tlv_copy) {
745+ IWL_ERR(trans, "WRT: No memory for TLV 0x%x, apply point %d\n",
746+ tlv_type, apply_point);
747 return;
748-
749- memcpy(data->data + data->offset, (void *)tlv, copy_size);
750- data->offset += offset_size;
751-}
752-
753-void iwl_alloc_dbg_tlv(struct iwl_trans *trans, size_t len, const u8 *data,
754- bool ext)
755-{
756- struct iwl_ucode_tlv *tlv;
757- u32 size[IWL_FW_INI_APPLY_NUM] = {0};
758- int i;
759-
760- while (len >= sizeof(*tlv)) {
761- u32 tlv_len, tlv_type, apply;
762- struct iwl_fw_ini_header *hdr;
763-
764- len -= sizeof(*tlv);
765- tlv = (void *)data;
766-
767- tlv_len = le32_to_cpu(tlv->length);
768- tlv_type = le32_to_cpu(tlv->type);
769-
770- if (len < tlv_len)
771- return;
772-
773- len -= ALIGN(tlv_len, 4);
774- data += sizeof(*tlv) + ALIGN(tlv_len, 4);
775-
776- if (tlv_type < IWL_UCODE_TLV_DEBUG_BASE ||
777- tlv_type > IWL_UCODE_TLV_DEBUG_MAX)
778- continue;
779-
780- hdr = (void *)&tlv->data[0];
781- apply = le32_to_cpu(hdr->apply_point);
782-
783- if (le32_to_cpu(hdr->tlv_version) != 1)
784- continue;
785-
786- IWL_DEBUG_FW(trans, "WRT: read TLV 0x%x, apply point %d\n",
787- le32_to_cpu(tlv->type), apply);
788-
789- if (WARN_ON(apply >= IWL_FW_INI_APPLY_NUM))
790- continue;
791-
792- /* add room for is_alloc field in &iwl_fw_ini_allocation_data
793- * struct
794- */
795- if (tlv_type == IWL_UCODE_TLV_TYPE_BUFFER_ALLOCATION) {
796- struct iwl_fw_ini_allocation_data *buf_alloc =
797- (void *)tlv->data;
798-
799- size[apply] += sizeof(buf_alloc->is_alloc);
800- }
801-
802- size[apply] += sizeof(*tlv) + tlv_len;
803 }
804
805- for (i = 0; i < ARRAY_SIZE(size); i++) {
806- void *mem;
807+ INIT_LIST_HEAD(&tlv_copy->list);
808+ memcpy(&tlv_copy->tlv, tlv, sizeof(*tlv) + len);
809
810- if (!size[i])
811- continue;
812+ if (!dbg_cfg->list.next)
813+ INIT_LIST_HEAD(&dbg_cfg->list);
814
815- mem = kzalloc(size[i], GFP_KERNEL);
816+ list_add_tail(&tlv_copy->list, &dbg_cfg->list);
817
818- if (!mem) {
819- IWL_ERR(trans, "No memory for apply point %d\n", i);
820- return;
821- }
822+ trans->dbg.ini_valid = true;
823+}
824
825- if (ext) {
826- trans->dbg.apply_points_ext[i].data = mem;
827- trans->dbg.apply_points_ext[i].size = size[i];
828- } else {
829- trans->dbg.apply_points[i].data = mem;
830- trans->dbg.apply_points[i].size = size[i];
831- }
832+static void iwl_dbg_tlv_free_list(struct list_head *list)
833+{
834+ if (!list || !list->next)
835+ return;
836
837- trans->dbg.ini_valid = true;
838+ while (!list_empty(list)) {
839+ struct iwl_apply_point_data *node =
840+ list_entry(list->next, typeof(*node), list);
841+
842+ list_del(&node->list);
843+ kfree(node);
844 }
845 }
846
847-void iwl_fw_dbg_free(struct iwl_trans *trans)
848+void iwl_dbg_tlv_free(struct iwl_trans *trans)
849 {
850 int i;
851
852 for (i = 0; i < ARRAY_SIZE(trans->dbg.apply_points); i++) {
853- kfree(trans->dbg.apply_points[i].data);
854- trans->dbg.apply_points[i].size = 0;
855- trans->dbg.apply_points[i].offset = 0;
856+ struct iwl_apply_point_data *data;
857+
858+ data = &trans->dbg.apply_points[i];
859+ iwl_dbg_tlv_free_list(&data->list);
860
861- kfree(trans->dbg.apply_points_ext[i].data);
862- trans->dbg.apply_points_ext[i].size = 0;
863- trans->dbg.apply_points_ext[i].offset = 0;
864+ data = &trans->dbg.apply_points_ext[i];
865+ iwl_dbg_tlv_free_list(&data->list);
866 }
867 }
868
869-static int iwl_parse_fw_dbg_tlv(struct iwl_trans *trans, const u8 *data,
870- size_t len)
871+static int iwl_dbg_tlv_parse_bin(struct iwl_trans *trans, const u8 *data,
872+ size_t len)
873 {
874 struct iwl_ucode_tlv *tlv;
875 enum iwl_ucode_tlv_type tlv_type;
876@@ -224,7 +160,7 @@ static int iwl_parse_fw_dbg_tlv(struct iwl_trans *trans, const u8 *data,
877 case IWL_UCODE_TLV_TYPE_REGIONS:
878 case IWL_UCODE_TLV_TYPE_TRIGGERS:
879 case IWL_UCODE_TLV_TYPE_DEBUG_FLOW:
880- iwl_fw_dbg_copy_tlv(trans, tlv, true);
881+ iwl_dbg_tlv_copy(trans, tlv, true);
882 break;
883 default:
884 WARN_ONCE(1, "Invalid TLV %x\n", tlv_type);
885@@ -235,7 +171,7 @@ static int iwl_parse_fw_dbg_tlv(struct iwl_trans *trans, const u8 *data,
886 return 0;
887 }
888
889-void iwl_load_fw_dbg_tlv(struct device *dev, struct iwl_trans *trans)
890+void iwl_dbg_tlv_load_bin(struct device *dev, struct iwl_trans *trans)
891 {
892 const struct firmware *fw;
893 int res;
894@@ -247,8 +183,7 @@ void iwl_load_fw_dbg_tlv(struct device *dev, struct iwl_trans *trans)
895 if (res)
896 return;
897
898- iwl_alloc_dbg_tlv(trans, fw->size, fw->data, true);
899- iwl_parse_fw_dbg_tlv(trans, fw->data, fw->size);
900+ iwl_dbg_tlv_parse_bin(trans, fw->data, fw->size);
901
902 trans->dbg.external_ini_loaded = true;
903 release_firmware(fw);
904diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.h b/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.h
905index ee416f4..20c60a9 100644
906--- a/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.h
907+++ b/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.h
908@@ -5,7 +5,7 @@
909 *
910 * GPL LICENSE SUMMARY
911 *
912- * Copyright (C) 2018 Intel Corporation
913+ * Copyright (C) 2018 - 2019 Intel Corporation
914 *
915 * This program is free software; you can redistribute it and/or modify
916 * it under the terms of version 2 of the GNU General Public License as
917@@ -25,7 +25,7 @@
918 *
919 * BSD LICENSE
920 *
921- * Copyright (C) 2018 Intel Corporation
922+ * Copyright (C) 2018 - 2019 Intel Corporation
923 * All rights reserved.
924 *
925 * Redistribution and use in source and binary forms, with or without
926@@ -63,22 +63,18 @@
927
928 /**
929 * struct iwl_apply_point_data
930- * @data: start address of this apply point data
931- * @size total size of the data
932- * @offset: current offset of the copied data
933+ * @list: list to go through the TLVs of the apply point
934+ * @tlv: a debug TLV
935 */
936 struct iwl_apply_point_data {
937- void *data;
938- int size;
939- int offset;
940+ struct list_head list;
941+ struct iwl_ucode_tlv tlv;
942 };
943
944 struct iwl_trans;
945-void iwl_load_fw_dbg_tlv(struct device *dev, struct iwl_trans *trans);
946-void iwl_fw_dbg_free(struct iwl_trans *trans);
947-void iwl_fw_dbg_copy_tlv(struct iwl_trans *trans, struct iwl_ucode_tlv *tlv,
948- bool ext);
949-void iwl_alloc_dbg_tlv(struct iwl_trans *trans, size_t len, const u8 *data,
950- bool ext);
951+void iwl_dbg_tlv_load_bin(struct device *dev, struct iwl_trans *trans);
952+void iwl_dbg_tlv_free(struct iwl_trans *trans);
953+void iwl_dbg_tlv_copy(struct iwl_trans *trans, struct iwl_ucode_tlv *tlv,
954+ bool ext);
955
956 #endif /* __iwl_dbg_tlv_h__*/
957diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-drv.c b/drivers/net/wireless/intel/iwlwifi/iwl-drv.c
958index c4bfbb8..f70a749 100644
959--- a/drivers/net/wireless/intel/iwlwifi/iwl-drv.c
960+++ b/drivers/net/wireless/intel/iwlwifi/iwl-drv.c
961@@ -897,9 +897,6 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv,
962 fw_dbg_conf:
963 #endif
964
965- if (iwlwifi_mod_params.enable_ini)
966- iwl_alloc_dbg_tlv(drv->trans, len, data, false);
967-
968 while (len >= sizeof(*tlv)) {
969 len -= sizeof(*tlv);
970 tlv = (void *)data;
971@@ -1437,7 +1434,7 @@ fw_dbg_conf:
972 case IWL_UCODE_TLV_TYPE_TRIGGERS:
973 case IWL_UCODE_TLV_TYPE_DEBUG_FLOW:
974 if (iwlwifi_mod_params.enable_ini)
975- iwl_fw_dbg_copy_tlv(drv->trans, tlv, false);
976+ iwl_dbg_tlv_copy(drv->trans, tlv, false);
977 break;
978 case IWL_UCODE_TLV_CMD_VERSIONS:
979 if (tlv_len % sizeof(struct iwl_fw_cmd_version)) {
980@@ -1956,9 +1953,8 @@ struct iwl_drv *iwl_drv_start(struct iwl_trans *trans)
981 #ifdef CPTCFG_IWLWIFI_SUPPORT_DEBUG_OVERRIDES
982 trans->dbg_cfg = current_dbg_config;
983 iwl_dbg_cfg_load_ini(drv->trans->dev, &drv->trans->dbg_cfg);
984-
985- iwl_load_fw_dbg_tlv(drv->trans->dev, drv->trans);
986 #endif
987+ iwl_dbg_tlv_load_bin(drv->trans->dev, drv->trans);
988
989 #ifdef CPTCFG_IWLWIFI_DEBUGFS
990 /* Create the device debugfs entries. */
991@@ -1995,8 +1991,8 @@ err_fw:
992 #endif
993 #ifdef CPTCFG_IWLWIFI_DEBUGFS
994 debugfs_remove_recursive(drv->dbgfs_drv);
995- iwl_fw_dbg_free(drv->trans);
996 #endif
997+ iwl_dbg_tlv_free(drv->trans);
998 kfree(drv);
999 err:
1000 return ERR_PTR(ret);
1001@@ -2029,7 +2025,7 @@ void iwl_drv_stop(struct iwl_drv *drv)
1002 #ifdef CPTCFG_IWLWIFI_SUPPORT_DEBUG_OVERRIDES
1003 iwl_dbg_cfg_free(&drv->trans->dbg_cfg);
1004 #endif
1005- iwl_fw_dbg_free(drv->trans);
1006+ iwl_dbg_tlv_free(drv->trans);
1007
1008 #if IS_ENABLED(CPTCFG_IWLXVT)
1009 iwl_remove_sysfs_file(drv);
1010diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c b/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c
1011index 1b26b5d..c83de0e 100644
1012--- a/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c
1013+++ b/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c
1014@@ -1232,11 +1232,6 @@ static u32 iwl_nvm_get_regdom_bw_flags(const u16 *nvm_chan,
1015 return flags;
1016 }
1017
1018-struct regdb_ptrs {
1019- struct ieee80211_wmm_rule *rule;
1020- u32 token;
1021-};
1022-
1023 struct ieee80211_regdomain *
1024 iwl_parse_nvm_mcc_info(struct device *dev, const struct iwl_cfg *cfg,
1025 int num_of_ch, __le32 *channels, u16 fw_mcc,
1026@@ -1248,7 +1243,6 @@ iwl_parse_nvm_mcc_info(struct device *dev, const struct iwl_cfg *cfg,
1027 const u16 *nvm_chan;
1028 struct ieee80211_regdomain *regd, *copy_rd;
1029 struct ieee80211_reg_rule *rule;
1030- struct regdb_ptrs *regdb_ptrs;
1031 enum nl80211_band band;
1032 int center_freq, prev_center_freq = 0;
1033 int valid_rules = 0;
1034@@ -1280,12 +1274,6 @@ iwl_parse_nvm_mcc_info(struct device *dev, const struct iwl_cfg *cfg,
1035 if (!regd)
1036 return ERR_PTR(-ENOMEM);
1037
1038- regdb_ptrs = kcalloc(num_of_ch, sizeof(*regdb_ptrs), GFP_KERNEL);
1039- if (!regdb_ptrs) {
1040- copy_rd = ERR_PTR(-ENOMEM);
1041- goto out;
1042- }
1043-
1044 /* set alpha2 from FW. */
1045 regd->alpha2[0] = fw_mcc >> 8;
1046 regd->alpha2[1] = fw_mcc & 0xff;
1047@@ -1357,8 +1345,6 @@ iwl_parse_nvm_mcc_info(struct device *dev, const struct iwl_cfg *cfg,
1048 if (!copy_rd)
1049 copy_rd = ERR_PTR(-ENOMEM);
1050
1051-out:
1052- kfree(regdb_ptrs);
1053 kfree(regd);
1054 return copy_rd;
1055 }
1056diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-tm-gnl.c b/drivers/net/wireless/intel/iwlwifi/iwl-tm-gnl.c
1057index 79be4e6..55358f5 100644
1058--- a/drivers/net/wireless/intel/iwlwifi/iwl-tm-gnl.c
1059+++ b/drivers/net/wireless/intel/iwlwifi/iwl-tm-gnl.c
1060@@ -5,10 +5,9 @@
1061 *
1062 * GPL LICENSE SUMMARY
1063 *
1064- * Copyright(c) 2010 - 2014 Intel Corporation. All rights reserved.
1065+ * Copyright(c) 2010 - 2014, 2018 - 2019 Intel Corporation
1066 * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
1067 * Copyright(c) 2016 - 2017 Intel Deutschland GmbH
1068- * Copyright(c) 2018 Intel Corporation
1069 *
1070 * This program is free software; you can redistribute it and/or modify
1071 * it under the terms of version 2 of the GNU General Public License as
1072@@ -28,10 +27,9 @@
1073 *
1074 * BSD LICENSE
1075 *
1076- * Copyright(c) 2010 - 2014 Intel Corporation. All rights reserved.
1077+ * Copyright(c) 2010 - 2014, 2018 - 2019 Intel Corporation
1078 * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
1079 * Copyright(c) 2016 - 2017 Intel Deutschland GmbH
1080- * Copyright(c) 2018 Intel Corporation
1081 * All rights reserved.
1082 *
1083 * Redistribution and use in source and binary forms, with or without
1084@@ -1081,14 +1079,20 @@ static int iwl_tm_gnl_cmd_subscribe(struct sk_buff *skb, struct genl_info *info)
1085 static __genl_const struct genl_ops iwl_tm_gnl_ops[] = {
1086 {
1087 .cmd = IWL_TM_GNL_CMD_EXECUTE,
1088- .policy = iwl_tm_gnl_msg_policy,
1089+#if LINUX_VERSION_IS_GEQ(5,2,0)
1090+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
1091+#endif
1092+
1093 .doit = iwl_tm_gnl_cmd_do,
1094 .dumpit = iwl_tm_gnl_dump,
1095 .done = iwl_tm_gnl_done,
1096 },
1097 {
1098 .cmd = IWL_TM_GNL_CMD_SUBSCRIBE_EVENTS,
1099- .policy = iwl_tm_gnl_msg_policy,
1100+#if LINUX_VERSION_IS_GEQ(5,2,0)
1101+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
1102+#endif
1103+
1104 .doit = iwl_tm_gnl_cmd_subscribe,
1105 },
1106 };
1107@@ -1098,6 +1102,7 @@ static struct genl_family iwl_tm_gnl_family __genl_ro_after_init = {
1108 .name = IWL_TM_GNL_FAMILY_NAME,
1109 .version = IWL_TM_GNL_VERSION_NR,
1110 .maxattr = IWL_TM_GNL_MSG_ATTR_MAX,
1111+ .policy = iwl_tm_gnl_msg_policy,
1112 .module = THIS_MODULE,
1113 .ops = iwl_tm_gnl_ops,
1114 .n_ops = ARRAY_SIZE(iwl_tm_gnl_ops),
1115diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-trans.h b/drivers/net/wireless/intel/iwlwifi/iwl-trans.h
1116index 6d156ee..6d0403a 100644
1117--- a/drivers/net/wireless/intel/iwlwifi/iwl-trans.h
1118+++ b/drivers/net/wireless/intel/iwlwifi/iwl-trans.h
1119@@ -708,6 +708,7 @@ struct iwl_self_init_dram {
1120 * @ini_valid: indicates if debug ini mode is on
1121 * @num_blocks: number of blocks in fw_mon
1122 * @fw_mon: address of the buffers for firmware monitor
1123+ * @is_alloc: bit i is set if buffer i was allocated
1124 * @hw_error: equals true if hw error interrupt was received from the FW
1125 * @ini_dest: debug monitor destination uses &enum iwl_fw_ini_buffer_location
1126 */
1127@@ -730,7 +731,8 @@ struct iwl_trans_debug {
1128 struct iwl_apply_point_data apply_points_ext[IWL_FW_INI_APPLY_NUM];
1129
1130 int num_blocks;
1131- struct iwl_dram_data fw_mon[IWL_FW_INI_APPLY_NUM];
1132+ struct iwl_dram_data fw_mon[IWL_FW_INI_ALLOCATION_NUM];
1133+ u32 is_alloc;
1134
1135 bool hw_error;
1136 enum iwl_fw_ini_buffer_location ini_dest;
1137diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c
1138index 5e6cd75..dfc553e 100644
1139--- a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c
1140+++ b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c
1141@@ -1965,6 +1965,9 @@ static int __iwl_mvm_resume(struct iwl_mvm *mvm, bool test)
1142 */
1143 iwl_mvm_update_changed_regdom(mvm);
1144
1145+ /* Re-configure PPAG settings */
1146+ iwl_mvm_ppag_send_cmd(mvm);
1147+
1148 if (!unified_image)
1149 /* Re-configure default SAR profile */
1150 iwl_mvm_sar_select_profile(mvm, 1, 1);
1151diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
1152index bb2ad8b..e413f0a 100644
1153--- a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
1154+++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
1155@@ -987,6 +987,17 @@ int iwl_mvm_sar_select_profile(struct iwl_mvm *mvm, int prof_a, int prof_b)
1156 return iwl_mvm_send_cmd_pdu(mvm, REDUCE_TX_POWER_CMD, 0, len, &cmd);
1157 }
1158
1159+static bool iwl_mvm_sar_geo_support(struct iwl_mvm *mvm)
1160+{
1161+ /*
1162+ * The GEO_TX_POWER_LIMIT command is not supported on earlier
1163+ * firmware versions. Unfortunately, we don't have a TLV API
1164+ * flag to rely on, so rely on the major version which is in
1165+ * the first byte of ucode_ver.
1166+ */
1167+ return IWL_UCODE_SERIAL(mvm->fw->ucode_ver) >= 41;
1168+}
1169+
1170 int iwl_mvm_get_sar_geo_profile(struct iwl_mvm *mvm)
1171 {
1172 struct iwl_geo_tx_power_profiles_resp *resp;
1173@@ -1016,6 +1027,9 @@ int iwl_mvm_get_sar_geo_profile(struct iwl_mvm *mvm)
1174 .data = { data },
1175 };
1176
1177+ if (!iwl_mvm_sar_geo_support(mvm))
1178+ return -EOPNOTSUPP;
1179+
1180 ret = iwl_mvm_send_cmd(mvm, &cmd);
1181 if (ret) {
1182 IWL_ERR(mvm, "Failed to get geographic profile info %d\n", ret);
1183@@ -1041,13 +1055,7 @@ static int iwl_mvm_sar_geo_init(struct iwl_mvm *mvm)
1184 int ret, i, j;
1185 u16 cmd_wide_id = WIDE_ID(PHY_OPS_GROUP, GEO_TX_POWER_LIMIT);
1186
1187- /*
1188- * This command is not supported on earlier firmware versions.
1189- * Unfortunately, we don't have a TLV API flag to rely on, so
1190- * rely on the major version which is in the first byte of
1191- * ucode_ver.
1192- */
1193- if (IWL_UCODE_SERIAL(mvm->fw->ucode_ver) < 41)
1194+ if (!iwl_mvm_sar_geo_support(mvm))
1195 return 0;
1196
1197 ret = iwl_mvm_sar_get_wgds_table(mvm);
1198@@ -1096,6 +1104,113 @@ static int iwl_mvm_sar_geo_init(struct iwl_mvm *mvm)
1199 return iwl_mvm_send_cmd_pdu(mvm, cmd_wide_id, 0, sizeof(cmd), &cmd);
1200 }
1201
1202+static int iwl_mvm_get_ppag_table(struct iwl_mvm *mvm)
1203+{
1204+ union acpi_object *wifi_pkg, *data, *enabled;
1205+ int i, j, ret, tbl_rev;
1206+ int idx = 2;
1207+
1208+ mvm->ppag_table.enabled = cpu_to_le32(0);
1209+ data = iwl_acpi_get_object(mvm->dev, ACPI_PPAG_METHOD);
1210+ if (IS_ERR(data))
1211+ return PTR_ERR(data);
1212+
1213+ wifi_pkg = iwl_acpi_get_wifi_pkg(mvm->dev, data,
1214+ ACPI_PPAG_WIFI_DATA_SIZE, &tbl_rev);
1215+
1216+ if (IS_ERR(wifi_pkg) || tbl_rev != 0) {
1217+ ret = PTR_ERR(wifi_pkg);
1218+ goto out_free;
1219+ }
1220+
1221+ enabled = &wifi_pkg->package.elements[1];
1222+ if (enabled->type != ACPI_TYPE_INTEGER ||
1223+ (enabled->integer.value != 0 && enabled->integer.value != 1)) {
1224+ ret = -EINVAL;
1225+ goto out_free;
1226+ }
1227+
1228+ mvm->ppag_table.enabled = cpu_to_le32(enabled->integer.value);
1229+ if (!mvm->ppag_table.enabled) {
1230+ ret = 0;
1231+ goto out_free;
1232+ }
1233+
1234+ /*
1235+ * read, verify gain values and save them into the PPAG table.
1236+ * first sub-band (j=0) corresponds to Low-Band (2.4GHz), and the
1237+ * following sub-bands to High-Band (5GHz).
1238+ */
1239+ for (i = 0; i < ACPI_PPAG_NUM_CHAINS; i++) {
1240+ for (j = 0; j < ACPI_PPAG_NUM_SUB_BANDS; j++) {
1241+ union acpi_object *ent;
1242+
1243+ ent = &wifi_pkg->package.elements[idx++];
1244+ if (ent->type != ACPI_TYPE_INTEGER ||
1245+ (j == 0 && ent->integer.value > ACPI_PPAG_MAX_LB) ||
1246+ (j == 0 && ent->integer.value < ACPI_PPAG_MIN_LB) ||
1247+ (j != 0 && ent->integer.value > ACPI_PPAG_MAX_HB) ||
1248+ (j != 0 && ent->integer.value < ACPI_PPAG_MIN_HB)) {
1249+ mvm->ppag_table.enabled = cpu_to_le32(0);
1250+ ret = -EINVAL;
1251+ goto out_free;
1252+ }
1253+ mvm->ppag_table.gain[i][j] = ent->integer.value;
1254+ }
1255+ }
1256+ ret = 0;
1257+out_free:
1258+ kfree(data);
1259+ return ret;
1260+}
1261+
1262+int iwl_mvm_ppag_send_cmd(struct iwl_mvm *mvm)
1263+{
1264+ int i, j, ret;
1265+
1266+ if (!fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_SET_PPAG)) {
1267+ IWL_DEBUG_RADIO(mvm,
1268+ "PPAG capability not supported by FW, command not sent.\n");
1269+ return 0;
1270+ }
1271+
1272+ IWL_DEBUG_RADIO(mvm, "Sending PER_PLATFORM_ANT_GAIN_CMD\n");
1273+ IWL_DEBUG_RADIO(mvm, "PPAG is %s\n",
1274+ mvm->ppag_table.enabled ? "enabled" : "disabled");
1275+
1276+ for (i = 0; i < ACPI_PPAG_NUM_CHAINS; i++) {
1277+ for (j = 0; j < ACPI_PPAG_NUM_SUB_BANDS; j++) {
1278+ IWL_DEBUG_RADIO(mvm,
1279+ "PPAG table: chain[%d] band[%d]: gain = %d\n",
1280+ i, j, mvm->ppag_table.gain[i][j]);
1281+ }
1282+ }
1283+
1284+ ret = iwl_mvm_send_cmd_pdu(mvm, WIDE_ID(PHY_OPS_GROUP,
1285+ PER_PLATFORM_ANT_GAIN_CMD),
1286+ 0, sizeof(mvm->ppag_table),
1287+ &mvm->ppag_table);
1288+ if (ret < 0)
1289+ IWL_ERR(mvm, "failed to send PER_PLATFORM_ANT_GAIN_CMD (%d)\n",
1290+ ret);
1291+
1292+ return ret;
1293+}
1294+
1295+static int iwl_mvm_ppag_init(struct iwl_mvm *mvm)
1296+{
1297+ int ret;
1298+
1299+ ret = iwl_mvm_get_ppag_table(mvm);
1300+ if (ret < 0) {
1301+ IWL_DEBUG_RADIO(mvm,
1302+ "PPAG BIOS table invalid or unavailable. (%d)\n",
1303+ ret);
1304+ return 0;
1305+ }
1306+ return iwl_mvm_ppag_send_cmd(mvm);
1307+}
1308+
1309 #else /* CONFIG_ACPI */
1310 static int iwl_mvm_sar_get_wrds_table(struct iwl_mvm *mvm)
1311 {
1312@@ -1127,6 +1242,21 @@ int iwl_mvm_get_sar_geo_profile(struct iwl_mvm *mvm)
1313 {
1314 return -ENOENT;
1315 }
1316+
1317+static int iwl_mvm_get_ppag_table(struct iwl_mvm *mvm)
1318+{
1319+ return -ENOENT;
1320+}
1321+
1322+static int iwl_mvm_ppag_send_cmd(struct iwl_mvm *mvm)
1323+{
1324+ return -ENOENT;
1325+}
1326+
1327+static int iwl_mvm_ppag_init(struct iwl_mvm *mvm)
1328+{
1329+ return -ENOENT;
1330+}
1331 #endif /* CONFIG_ACPI */
1332
1333 void iwl_mvm_send_recovery_cmd(struct iwl_mvm *mvm, u32 flags)
1334@@ -1497,6 +1627,10 @@ int iwl_mvm_up(struct iwl_mvm *mvm)
1335 if (iwl_acpi_get_eckv(mvm->dev, &mvm->ext_clock_valid))
1336 IWL_DEBUG_INFO(mvm, "ECKV table doesn't exist in BIOS\n");
1337
1338+ ret = iwl_mvm_ppag_init(mvm);
1339+ if (ret)
1340+ goto error;
1341+
1342 ret = iwl_mvm_sar_init(mvm);
1343 if (ret == 0) {
1344 ret = iwl_mvm_sar_geo_init(mvm);
1345diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c
1346index ebcacd1..69dc7d1 100644
1347--- a/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c
1348+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c
1349@@ -1623,7 +1623,9 @@ void iwl_mvm_channel_switch_noa_notif(struct iwl_mvm *mvm,
1350 RCU_INIT_POINTER(mvm->csa_vif, NULL);
1351 return;
1352 case NL80211_IFTYPE_STATION:
1353- iwl_mvm_csa_client_absent(mvm, vif);
1354+ if (!fw_has_capa(&mvm->fw->ucode_capa,
1355+ IWL_UCODE_TLV_CAPA_CHANNEL_SWITCH_CMD))
1356+ iwl_mvm_csa_client_absent(mvm, vif);
1357 cancel_delayed_work(&mvmvif->csa_work);
1358 ieee80211_chswitch_done(vif, true);
1359 break;
1360diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
1361index c610056..3ab1876 100644
1362--- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
1363+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
1364@@ -246,11 +246,11 @@ static const struct cfg80211_pmsr_capabilities iwl_mvm_pmsr_capa = {
1365 },
1366 };
1367
1368-static int iwl_mvm_mac_set_key(struct ieee80211_hw *hw,
1369- enum set_key_cmd cmd,
1370- struct ieee80211_vif *vif,
1371- struct ieee80211_sta *sta,
1372- struct ieee80211_key_conf *key);
1373+static int __iwl_mvm_mac_set_key(struct ieee80211_hw *hw,
1374+ enum set_key_cmd cmd,
1375+ struct ieee80211_vif *vif,
1376+ struct ieee80211_sta *sta,
1377+ struct ieee80211_key_conf *key);
1378
1379 static void iwl_mvm_reset_phy_ctxts(struct iwl_mvm *mvm)
1380 {
1381@@ -1401,15 +1401,20 @@ static int iwl_mvm_post_channel_switch(struct ieee80211_hw *hw,
1382 goto out_unlock;
1383 }
1384
1385- iwl_mvm_sta_modify_disable_tx(mvm, mvmsta, false);
1386+ if (!fw_has_capa(&mvm->fw->ucode_capa,
1387+ IWL_UCODE_TLV_CAPA_CHANNEL_SWITCH_CMD))
1388+ iwl_mvm_sta_modify_disable_tx(mvm, mvmsta, false);
1389
1390 iwl_mvm_mac_ctxt_changed(mvm, vif, false, NULL);
1391
1392- ret = iwl_mvm_enable_beacon_filter(mvm, vif, 0);
1393- if (ret)
1394- goto out_unlock;
1395+ if (!fw_has_capa(&mvm->fw->ucode_capa,
1396+ IWL_UCODE_TLV_CAPA_CHANNEL_SWITCH_CMD)) {
1397+ ret = iwl_mvm_enable_beacon_filter(mvm, vif, 0);
1398+ if (ret)
1399+ goto out_unlock;
1400
1401- iwl_mvm_stop_session_protection(mvm, vif);
1402+ iwl_mvm_stop_session_protection(mvm, vif);
1403+ }
1404 }
1405
1406 mvmvif->ps_disabled = false;
1407@@ -2640,7 +2645,7 @@ static int iwl_mvm_start_ap_ibss(struct ieee80211_hw *hw,
1408
1409 mvmvif->ap_early_keys[i] = NULL;
1410
1411- ret = iwl_mvm_mac_set_key(hw, SET_KEY, vif, NULL, key);
1412+ ret = __iwl_mvm_mac_set_key(hw, SET_KEY, vif, NULL, key);
1413 if (ret)
1414 goto out_quota_failed;
1415 }
1416@@ -3445,11 +3450,11 @@ static int iwl_mvm_mac_sched_scan_stop(struct ieee80211_hw *hw,
1417 return ret;
1418 }
1419
1420-static int iwl_mvm_mac_set_key(struct ieee80211_hw *hw,
1421- enum set_key_cmd cmd,
1422- struct ieee80211_vif *vif,
1423- struct ieee80211_sta *sta,
1424- struct ieee80211_key_conf *key)
1425+static int __iwl_mvm_mac_set_key(struct ieee80211_hw *hw,
1426+ enum set_key_cmd cmd,
1427+ struct ieee80211_vif *vif,
1428+ struct ieee80211_sta *sta,
1429+ struct ieee80211_key_conf *key)
1430 {
1431 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
1432 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
1433@@ -3504,8 +3509,6 @@ static int iwl_mvm_mac_set_key(struct ieee80211_hw *hw,
1434 return -EOPNOTSUPP;
1435 }
1436
1437- mutex_lock(&mvm->mutex);
1438-
1439 switch (cmd) {
1440 case SET_KEY:
1441 if ((vif->type == NL80211_IFTYPE_ADHOC ||
1442@@ -3651,7 +3654,22 @@ static int iwl_mvm_mac_set_key(struct ieee80211_hw *hw,
1443 ret = -EINVAL;
1444 }
1445
1446+ return ret;
1447+}
1448+
1449+static int iwl_mvm_mac_set_key(struct ieee80211_hw *hw,
1450+ enum set_key_cmd cmd,
1451+ struct ieee80211_vif *vif,
1452+ struct ieee80211_sta *sta,
1453+ struct ieee80211_key_conf *key)
1454+{
1455+ struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
1456+ int ret;
1457+
1458+ mutex_lock(&mvm->mutex);
1459+ ret = __iwl_mvm_mac_set_key(hw, cmd, vif, sta, key);
1460 mutex_unlock(&mvm->mutex);
1461+
1462 return ret;
1463 }
1464
1465@@ -4554,6 +4572,42 @@ static int iwl_mvm_schedule_client_csa(struct iwl_mvm *mvm,
1466 0, sizeof(cmd), &cmd);
1467 }
1468
1469+static int iwl_mvm_old_pre_chan_sw_sta(struct iwl_mvm *mvm,
1470+ struct ieee80211_vif *vif,
1471+ struct ieee80211_channel_switch *chsw)
1472+{
1473+ struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
1474+ u32 apply_time;
1475+
1476+ /* Schedule the time event to a bit before beacon 1,
1477+ * to make sure we're in the new channel when the
1478+ * GO/AP arrives. In case count <= 1 immediately schedule the
1479+ * TE (this might result with some packet loss or connection
1480+ * loss).
1481+ */
1482+ if (chsw->count <= 1)
1483+ apply_time = 0;
1484+ else
1485+ apply_time = chsw->device_timestamp +
1486+ ((vif->bss_conf.beacon_int * (chsw->count - 1) -
1487+ IWL_MVM_CHANNEL_SWITCH_TIME_CLIENT) * 1024);
1488+
1489+ if (chsw->block_tx)
1490+ iwl_mvm_csa_client_absent(mvm, vif);
1491+
1492+ if (mvmvif->bf_data.bf_enabled) {
1493+ int ret = iwl_mvm_disable_beacon_filter(mvm, vif, 0);
1494+
1495+ if (ret)
1496+ return ret;
1497+ }
1498+
1499+ iwl_mvm_schedule_csa_period(mvm, vif, vif->bss_conf.beacon_int,
1500+ apply_time);
1501+
1502+ return 0;
1503+}
1504+
1505 #define IWL_MAX_CSA_BLOCK_TX 1500
1506 static int iwl_mvm_pre_channel_switch(struct ieee80211_hw *hw,
1507 struct ieee80211_vif *vif,
1508@@ -4562,7 +4616,6 @@ static int iwl_mvm_pre_channel_switch(struct ieee80211_hw *hw,
1509 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
1510 struct ieee80211_vif *csa_vif;
1511 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
1512- u32 apply_time;
1513 int ret;
1514
1515 mutex_lock(&mvm->mutex);
1516@@ -4606,21 +4659,7 @@ static int iwl_mvm_pre_channel_switch(struct ieee80211_hw *hw,
1517
1518 break;
1519 case NL80211_IFTYPE_STATION:
1520- /* Schedule the time event to a bit before beacon 1,
1521- * to make sure we're in the new channel when the
1522- * GO/AP arrives. In case count <= 1 immediately schedule the
1523- * TE (this might result with some packet loss or connection
1524- * loss).
1525- */
1526- if (chsw->count <= 1)
1527- apply_time = 0;
1528- else
1529- apply_time = chsw->device_timestamp +
1530- ((vif->bss_conf.beacon_int * (chsw->count - 1) -
1531- IWL_MVM_CHANNEL_SWITCH_TIME_CLIENT) * 1024);
1532-
1533 if (chsw->block_tx) {
1534- iwl_mvm_csa_client_absent(mvm, vif);
1535 /*
1536 * In case of undetermined / long time with immediate
1537 * quiet monitor status to gracefully disconnect
1538@@ -4632,19 +4671,14 @@ static int iwl_mvm_pre_channel_switch(struct ieee80211_hw *hw,
1539 msecs_to_jiffies(IWL_MAX_CSA_BLOCK_TX));
1540 }
1541
1542- if (mvmvif->bf_data.bf_enabled) {
1543- ret = iwl_mvm_disable_beacon_filter(mvm, vif, 0);
1544+ if (!fw_has_capa(&mvm->fw->ucode_capa,
1545+ IWL_UCODE_TLV_CAPA_CHANNEL_SWITCH_CMD)) {
1546+ ret = iwl_mvm_old_pre_chan_sw_sta(mvm, vif, chsw);
1547 if (ret)
1548 goto out_unlock;
1549- }
1550-
1551- if (fw_has_capa(&mvm->fw->ucode_capa,
1552- IWL_UCODE_TLV_CAPA_CHANNEL_SWITCH_CMD))
1553+ } else {
1554 iwl_mvm_schedule_client_csa(mvm, vif, chsw);
1555- else
1556- iwl_mvm_schedule_csa_period(mvm, vif,
1557- vif->bss_conf.beacon_int,
1558- apply_time);
1559+ }
1560
1561 mvmvif->csa_count = chsw->count;
1562 mvmvif->csa_misbehave = false;
1563@@ -5246,7 +5280,8 @@ void iwl_mvm_sync_rx_queues_internal(struct iwl_mvm *mvm,
1564 atomic_set(&mvm->queue_sync_counter,
1565 mvm->trans->num_rx_queues);
1566
1567- ret = iwl_mvm_notify_rx_queue(mvm, qmask, (u8 *)notif, size);
1568+ ret = iwl_mvm_notify_rx_queue(mvm, qmask, (u8 *)notif,
1569+ size, !notif->sync);
1570 if (ret) {
1571 IWL_ERR(mvm, "Failed to trigger RX queues sync (%d)\n", ret);
1572 goto out;
1573diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
1574index e140a1f..c9f8c5d 100644
1575--- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
1576+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
1577@@ -1227,6 +1227,8 @@ struct iwl_mvm {
1578 #endif
1579 struct iwl_mvm_geo_profile geo_profiles[ACPI_NUM_GEO_PROFILES];
1580 u32 geo_rev;
1581+ struct iwl_ppag_table_cmd ppag_table;
1582+ u32 ppag_rev;
1583 #endif
1584
1585 };
1586@@ -1698,9 +1700,9 @@ void iwl_mvm_rx_monitor_no_data(struct iwl_mvm *mvm, struct napi_struct *napi,
1587 void iwl_mvm_rx_frame_release(struct iwl_mvm *mvm, struct napi_struct *napi,
1588 struct iwl_rx_cmd_buffer *rxb, int queue);
1589 int iwl_mvm_notify_rx_queue(struct iwl_mvm *mvm, u32 rxq_mask,
1590- const u8 *data, u32 count);
1591-void iwl_mvm_rx_queue_notif(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
1592- int queue);
1593+ const u8 *data, u32 count, bool async);
1594+void iwl_mvm_rx_queue_notif(struct iwl_mvm *mvm, struct napi_struct *napi,
1595+ struct iwl_rx_cmd_buffer *rxb, int queue);
1596 void iwl_mvm_rx_tx_cmd(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb);
1597 void iwl_mvm_mfu_assert_dump_notif(struct iwl_mvm *mvm,
1598 struct iwl_rx_cmd_buffer *rxb);
1599@@ -1847,7 +1849,7 @@ iwl_mvm_vif_dbgfs_clean(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
1600 #endif /* CPTCFG_IWLWIFI_DEBUGFS */
1601
1602 /* rate scaling */
1603-int iwl_mvm_send_lq_cmd(struct iwl_mvm *mvm, struct iwl_lq_cmd *lq, bool sync);
1604+int iwl_mvm_send_lq_cmd(struct iwl_mvm *mvm, struct iwl_lq_cmd *lq);
1605 void iwl_mvm_update_frame_stats(struct iwl_mvm *mvm, u32 rate, bool agg);
1606 int rs_pretty_print_rate(char *buf, int bufsz, const u32 rate);
1607 void rs_update_last_rssi(struct iwl_mvm *mvm,
1608@@ -2199,6 +2201,7 @@ int iwl_mvm_nan_config_nan_faw_cmd(struct iwl_mvm *mvm,
1609
1610 int iwl_mvm_sar_select_profile(struct iwl_mvm *mvm, int prof_a, int prof_b);
1611 int iwl_mvm_get_sar_geo_profile(struct iwl_mvm *mvm);
1612+int iwl_mvm_ppag_send_cmd(struct iwl_mvm *mvm);
1613 #ifdef CPTCFG_IWLWIFI_DEBUGFS
1614 void iwl_mvm_sta_add_debugfs(struct ieee80211_hw *hw,
1615 struct ieee80211_vif *vif,
1616diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/nvm.c b/drivers/net/wireless/intel/iwlwifi/mvm/nvm.c
1617index 5a81722..cd3b5d6 100644
1618--- a/drivers/net/wireless/intel/iwlwifi/mvm/nvm.c
1619+++ b/drivers/net/wireless/intel/iwlwifi/mvm/nvm.c
1620@@ -620,7 +620,7 @@ void iwl_mvm_rx_chub_update_mcc(struct iwl_mvm *mvm,
1621 enum iwl_mcc_source src;
1622 char mcc[3];
1623 struct ieee80211_regdomain *regd;
1624- u32 wgds_tbl_idx;
1625+ int wgds_tbl_idx;
1626
1627 lockdep_assert_held(&mvm->mutex);
1628
1629diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
1630index ca25c5c..7ef326e 100644
1631--- a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
1632+++ b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
1633@@ -1260,7 +1260,7 @@ static void iwl_mvm_rx_mq(struct iwl_op_mode *op_mode,
1634 iwl_mvm_rx_mpdu_mq(mvm, napi, rxb, 0);
1635 else if (unlikely(cmd == WIDE_ID(DATA_PATH_GROUP,
1636 RX_QUEUES_NOTIFICATION)))
1637- iwl_mvm_rx_queue_notif(mvm, rxb, 0);
1638+ iwl_mvm_rx_queue_notif(mvm, napi, rxb, 0);
1639 else if (cmd == WIDE_ID(LEGACY_GROUP, FRAME_RELEASE))
1640 iwl_mvm_rx_frame_release(mvm, napi, rxb, 0);
1641 else if (cmd == WIDE_ID(DATA_PATH_GROUP, RX_NO_DATA_NOTIF))
1642@@ -1489,18 +1489,19 @@ void iwl_mvm_nic_restart(struct iwl_mvm *mvm, bool fw_error)
1643 IWL_ERR(mvm, "HW restart already requested, but not started\n");
1644 } else if (mvm->fwrt.cur_fw_img == IWL_UCODE_REGULAR &&
1645 mvm->hw_registered &&
1646- !test_bit(STATUS_TRANS_DEAD, &mvm->trans->status) &&
1647- mvm->fw->ucode_capa.error_log_size) {
1648- u32 src_size = mvm->fw->ucode_capa.error_log_size;
1649- u32 src_addr = mvm->fw->ucode_capa.error_log_addr;
1650- u8 *recover_buf = kzalloc(src_size, GFP_ATOMIC);
1651-
1652- if (recover_buf) {
1653- mvm->error_recovery_buf = recover_buf;
1654- iwl_trans_read_mem_bytes(mvm->trans,
1655- src_addr,
1656- recover_buf,
1657- src_size);
1658+ !test_bit(STATUS_TRANS_DEAD, &mvm->trans->status)) {
1659+ if (mvm->fw->ucode_capa.error_log_size) {
1660+ u32 src_size = mvm->fw->ucode_capa.error_log_size;
1661+ u32 src_addr = mvm->fw->ucode_capa.error_log_addr;
1662+ u8 *recover_buf = kzalloc(src_size, GFP_ATOMIC);
1663+
1664+ if (recover_buf) {
1665+ mvm->error_recovery_buf = recover_buf;
1666+ iwl_trans_read_mem_bytes(mvm->trans,
1667+ src_addr,
1668+ recover_buf,
1669+ src_size);
1670+ }
1671 }
1672
1673 iwl_fw_error_collect(&mvm->fwrt);
1674@@ -1574,7 +1575,7 @@ static void iwl_mvm_rx_mq_rss(struct iwl_op_mode *op_mode,
1675 iwl_mvm_rx_frame_release(mvm, napi, rxb, queue);
1676 else if (unlikely(cmd == WIDE_ID(DATA_PATH_GROUP,
1677 RX_QUEUES_NOTIFICATION)))
1678- iwl_mvm_rx_queue_notif(mvm, rxb, queue);
1679+ iwl_mvm_rx_queue_notif(mvm, napi, rxb, queue);
1680 else if (likely(cmd == WIDE_ID(LEGACY_GROUP, REPLY_RX_MPDU_CMD)))
1681 iwl_mvm_rx_mpdu_mq(mvm, napi, rxb, queue);
1682 }
1683diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rs.c b/drivers/net/wireless/intel/iwlwifi/mvm/rs.c
1684index 190c514..8cb07f4 100644
1685--- a/drivers/net/wireless/intel/iwlwifi/mvm/rs.c
1686+++ b/drivers/net/wireless/intel/iwlwifi/mvm/rs.c
1687@@ -1208,240 +1208,6 @@ static u8 rs_get_tid(struct ieee80211_hdr *hdr)
1688 return tid;
1689 }
1690
1691-void iwl_mvm_rs_tx_status(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
1692- int tid, struct ieee80211_tx_info *info, bool ndp)
1693-{
1694- int legacy_success;
1695- int retries;
1696- int i;
1697- struct iwl_lq_cmd *table;
1698- u32 lq_hwrate;
1699- struct rs_rate lq_rate, tx_resp_rate;
1700- struct iwl_scale_tbl_info *curr_tbl, *other_tbl, *tmp_tbl;
1701- u32 tlc_info = (uintptr_t)info->status.status_driver_data[0];
1702- u8 reduced_txp = tlc_info & RS_DRV_DATA_TXP_MSK;
1703- u8 lq_color = RS_DRV_DATA_LQ_COLOR_GET(tlc_info);
1704- u32 tx_resp_hwrate = (uintptr_t)info->status.status_driver_data[1];
1705- struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
1706- struct iwl_lq_sta *lq_sta = &mvmsta->lq_sta.rs_drv;
1707-
1708- /* Treat uninitialized rate scaling data same as non-existing. */
1709- if (!lq_sta) {
1710- IWL_DEBUG_RATE(mvm, "Station rate scaling not created yet.\n");
1711- return;
1712- } else if (!lq_sta->pers.drv) {
1713- IWL_DEBUG_RATE(mvm, "Rate scaling not initialized yet.\n");
1714- return;
1715- }
1716-
1717- /* This packet was aggregated but doesn't carry status info */
1718- if ((info->flags & IEEE80211_TX_CTL_AMPDU) &&
1719- !(info->flags & IEEE80211_TX_STAT_AMPDU))
1720- return;
1721-
1722- if (rs_rate_from_ucode_rate(tx_resp_hwrate, info->band,
1723- &tx_resp_rate)) {
1724- WARN_ON_ONCE(1);
1725- return;
1726- }
1727-
1728-#ifdef CPTCFG_MAC80211_DEBUGFS
1729- /* Disable last tx check if we are debugging with fixed rate but
1730- * update tx stats */
1731- if (lq_sta->pers.dbg_fixed_rate) {
1732- int index = tx_resp_rate.index;
1733- enum rs_column column;
1734- int attempts, success;
1735-
1736- column = rs_get_column_from_rate(&tx_resp_rate);
1737- if (WARN_ONCE(column == RS_COLUMN_INVALID,
1738- "Can't map rate 0x%x to column",
1739- tx_resp_hwrate))
1740- return;
1741-
1742- if (info->flags & IEEE80211_TX_STAT_AMPDU) {
1743- attempts = info->status.ampdu_len;
1744- success = info->status.ampdu_ack_len;
1745- } else {
1746- attempts = info->status.rates[0].count;
1747- success = !!(info->flags & IEEE80211_TX_STAT_ACK);
1748- }
1749-
1750- lq_sta->pers.tx_stats[column][index].total += attempts;
1751- lq_sta->pers.tx_stats[column][index].success += success;
1752-
1753- IWL_DEBUG_RATE(mvm, "Fixed rate 0x%x success %d attempts %d\n",
1754- tx_resp_hwrate, success, attempts);
1755- return;
1756- }
1757-#endif
1758-
1759- if (time_after(jiffies,
1760- (unsigned long)(lq_sta->last_tx +
1761- (IWL_MVM_RS_IDLE_TIMEOUT * HZ)))) {
1762- IWL_DEBUG_RATE(mvm, "Tx idle for too long. reinit rs\n");
1763- iwl_mvm_rs_rate_init(mvm, sta, info->band, true);
1764- return;
1765- }
1766- lq_sta->last_tx = jiffies;
1767-
1768- /* Ignore this Tx frame response if its initial rate doesn't match
1769- * that of latest Link Quality command. There may be stragglers
1770- * from a previous Link Quality command, but we're no longer interested
1771- * in those; they're either from the "active" mode while we're trying
1772- * to check "search" mode, or a prior "search" mode after we've moved
1773- * to a new "search" mode (which might become the new "active" mode).
1774- */
1775- table = &lq_sta->lq;
1776- lq_hwrate = le32_to_cpu(table->rs_table[0]);
1777- if (rs_rate_from_ucode_rate(lq_hwrate, info->band, &lq_rate)) {
1778- WARN_ON_ONCE(1);
1779- return;
1780- }
1781-
1782- /* Here we actually compare this rate to the latest LQ command */
1783- if (lq_color != LQ_FLAG_COLOR_GET(table->flags)) {
1784- IWL_DEBUG_RATE(mvm,
1785- "tx resp color 0x%x does not match 0x%x\n",
1786- lq_color, LQ_FLAG_COLOR_GET(table->flags));
1787-
1788- /*
1789- * Since rates mis-match, the last LQ command may have failed.
1790- * After IWL_MISSED_RATE_MAX mis-matches, resync the uCode with
1791- * ... driver.
1792- */
1793- lq_sta->missed_rate_counter++;
1794- if (lq_sta->missed_rate_counter > IWL_MVM_RS_MISSED_RATE_MAX) {
1795- lq_sta->missed_rate_counter = 0;
1796- IWL_DEBUG_RATE(mvm,
1797- "Too many rates mismatch. Send sync LQ. rs_state %d\n",
1798- lq_sta->rs_state);
1799- iwl_mvm_send_lq_cmd(mvm, &lq_sta->lq, false);
1800- }
1801- /* Regardless, ignore this status info for outdated rate */
1802- return;
1803- } else
1804- /* Rate did match, so reset the missed_rate_counter */
1805- lq_sta->missed_rate_counter = 0;
1806-
1807- if (!lq_sta->search_better_tbl) {
1808- curr_tbl = &(lq_sta->lq_info[lq_sta->active_tbl]);
1809- other_tbl = &(lq_sta->lq_info[1 - lq_sta->active_tbl]);
1810- } else {
1811- curr_tbl = &(lq_sta->lq_info[1 - lq_sta->active_tbl]);
1812- other_tbl = &(lq_sta->lq_info[lq_sta->active_tbl]);
1813- }
1814-
1815- if (WARN_ON_ONCE(!rs_rate_column_match(&lq_rate, &curr_tbl->rate))) {
1816- IWL_DEBUG_RATE(mvm,
1817- "Neither active nor search matches tx rate\n");
1818- tmp_tbl = &(lq_sta->lq_info[lq_sta->active_tbl]);
1819- rs_dump_rate(mvm, &tmp_tbl->rate, "ACTIVE");
1820- tmp_tbl = &(lq_sta->lq_info[1 - lq_sta->active_tbl]);
1821- rs_dump_rate(mvm, &tmp_tbl->rate, "SEARCH");
1822- rs_dump_rate(mvm, &lq_rate, "ACTUAL");
1823-
1824- /*
1825- * no matching table found, let's by-pass the data collection
1826- * and continue to perform rate scale to find the rate table
1827- */
1828- rs_stay_in_table(lq_sta, true);
1829- goto done;
1830- }
1831-
1832- /*
1833- * Updating the frame history depends on whether packets were
1834- * aggregated.
1835- *
1836- * For aggregation, all packets were transmitted at the same rate, the
1837- * first index into rate scale table.
1838- */
1839- if (info->flags & IEEE80211_TX_STAT_AMPDU) {
1840- rs_collect_tpc_data(mvm, lq_sta, curr_tbl, tx_resp_rate.index,
1841- info->status.ampdu_len,
1842- info->status.ampdu_ack_len,
1843- reduced_txp);
1844-
1845- /* ampdu_ack_len = 0 marks no BA was received. For TLC, treat
1846- * it as a single frame loss as we don't want the success ratio
1847- * to dip too quickly because a BA wasn't received.
1848- * For TPC, there's no need for this optimisation since we want
1849- * to recover very quickly from a bad power reduction and,
1850- * therefore we'd like the success ratio to get an immediate hit
1851- * when failing to get a BA, so we'd switch back to a lower or
1852- * zero power reduction. When FW transmits agg with a rate
1853- * different from the initial rate, it will not use reduced txp
1854- * and will send BA notification twice (one empty with reduced
1855- * txp equal to the value from LQ and one with reduced txp 0).
1856- * We need to update counters for each txp level accordingly.
1857- */
1858- if (info->status.ampdu_ack_len == 0)
1859- info->status.ampdu_len = 1;
1860-
1861- rs_collect_tlc_data(mvm, mvmsta, tid, curr_tbl,
1862- tx_resp_rate.index,
1863- info->status.ampdu_len,
1864- info->status.ampdu_ack_len);
1865-
1866- /* Update success/fail counts if not searching for new mode */
1867- if (lq_sta->rs_state == RS_STATE_STAY_IN_COLUMN) {
1868- lq_sta->total_success += info->status.ampdu_ack_len;
1869- lq_sta->total_failed += (info->status.ampdu_len -
1870- info->status.ampdu_ack_len);
1871- }
1872- } else {
1873- /* For legacy, update frame history with for each Tx retry. */
1874- retries = info->status.rates[0].count - 1;
1875- /* HW doesn't send more than 15 retries */
1876- retries = min(retries, 15);
1877-
1878- /* The last transmission may have been successful */
1879- legacy_success = !!(info->flags & IEEE80211_TX_STAT_ACK);
1880- /* Collect data for each rate used during failed TX attempts */
1881- for (i = 0; i <= retries; ++i) {
1882- lq_hwrate = le32_to_cpu(table->rs_table[i]);
1883- if (rs_rate_from_ucode_rate(lq_hwrate, info->band,
1884- &lq_rate)) {
1885- WARN_ON_ONCE(1);
1886- return;
1887- }
1888-
1889- /*
1890- * Only collect stats if retried rate is in the same RS
1891- * table as active/search.
1892- */
1893- if (rs_rate_column_match(&lq_rate, &curr_tbl->rate))
1894- tmp_tbl = curr_tbl;
1895- else if (rs_rate_column_match(&lq_rate,
1896- &other_tbl->rate))
1897- tmp_tbl = other_tbl;
1898- else
1899- continue;
1900-
1901- rs_collect_tpc_data(mvm, lq_sta, tmp_tbl,
1902- tx_resp_rate.index, 1,
1903- i < retries ? 0 : legacy_success,
1904- reduced_txp);
1905- rs_collect_tlc_data(mvm, mvmsta, tid, tmp_tbl,
1906- tx_resp_rate.index, 1,
1907- i < retries ? 0 : legacy_success);
1908- }
1909-
1910- /* Update success/fail counts if not searching for new mode */
1911- if (lq_sta->rs_state == RS_STATE_STAY_IN_COLUMN) {
1912- lq_sta->total_success += legacy_success;
1913- lq_sta->total_failed += retries + (1 - legacy_success);
1914- }
1915- }
1916- /* The last TX rate is cached in lq_sta; it's set in if/else above */
1917- lq_sta->last_rate_n_flags = lq_hwrate;
1918- IWL_DEBUG_RATE(mvm, "reduced txpower: %d\n", reduced_txp);
1919-done:
1920- /* See if there's a better rate or modulation mode to try. */
1921- if (sta->supp_rates[info->band])
1922- rs_rate_scale_perform(mvm, sta, lq_sta, tid, ndp);
1923-}
1924-
1925 /*
1926 * mac80211 sends us Tx status
1927 */
1928@@ -1454,8 +1220,9 @@ static void rs_drv_mac80211_tx_status(void *mvm_r,
1929 struct iwl_op_mode *op_mode = mvm_r;
1930 struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode);
1931 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
1932+ struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
1933
1934- if (!iwl_mvm_sta_from_mac80211(sta)->vif)
1935+ if (!mvmsta->vif)
1936 return;
1937
1938 if (!ieee80211_is_data(hdr->frame_control) ||
1939@@ -1806,7 +1573,7 @@ static void rs_update_rate_tbl(struct iwl_mvm *mvm,
1940 struct iwl_scale_tbl_info *tbl)
1941 {
1942 rs_fill_lq_cmd(mvm, sta, lq_sta, &tbl->rate);
1943- iwl_mvm_send_lq_cmd(mvm, &lq_sta->lq, false);
1944+ iwl_mvm_send_lq_cmd(mvm, &lq_sta->lq);
1945 }
1946
1947 static bool rs_tweak_rate_tbl(struct iwl_mvm *mvm,
1948@@ -2908,7 +2675,7 @@ void rs_update_last_rssi(struct iwl_mvm *mvm,
1949 static void rs_initialize_lq(struct iwl_mvm *mvm,
1950 struct ieee80211_sta *sta,
1951 struct iwl_lq_sta *lq_sta,
1952- enum nl80211_band band, bool update)
1953+ enum nl80211_band band)
1954 {
1955 struct iwl_scale_tbl_info *tbl;
1956 struct rs_rate *rate;
1957@@ -2938,7 +2705,7 @@ static void rs_initialize_lq(struct iwl_mvm *mvm,
1958 rs_set_expected_tpt_table(lq_sta, tbl);
1959 rs_fill_lq_cmd(mvm, sta, lq_sta, rate);
1960 /* TODO restore station should remember the lq cmd */
1961- iwl_mvm_send_lq_cmd(mvm, &lq_sta->lq, !update);
1962+ iwl_mvm_send_lq_cmd(mvm, &lq_sta->lq);
1963 }
1964
1965 static void rs_drv_get_rate(void *mvm_r, struct ieee80211_sta *sta,
1966@@ -3187,7 +2954,7 @@ void iwl_mvm_update_frame_stats(struct iwl_mvm *mvm, u32 rate, bool agg)
1967 * Called after adding a new station to initialize rate scaling
1968 */
1969 static void rs_drv_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
1970- enum nl80211_band band, bool update)
1971+ enum nl80211_band band)
1972 {
1973 int i, j;
1974 struct ieee80211_hw *hw = mvm->hw;
1975@@ -3198,6 +2965,8 @@ static void rs_drv_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
1976 struct ieee80211_supported_band *sband;
1977 unsigned long supp; /* must be unsigned long for for_each_set_bit */
1978
1979+ lockdep_assert_held(&mvmsta->lq_sta.rs_drv.pers.lock);
1980+
1981 /* clear all non-persistent lq data */
1982 memset(lq_sta, 0, offsetof(typeof(*lq_sta), pers));
1983
1984@@ -3267,7 +3036,7 @@ static void rs_drv_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
1985 #ifdef CPTCFG_IWLWIFI_DEBUGFS
1986 iwl_mvm_reset_frame_stats(mvm);
1987 #endif
1988- rs_initialize_lq(mvm, sta, lq_sta, band, update);
1989+ rs_initialize_lq(mvm, sta, lq_sta, band);
1990 }
1991
1992 static void rs_drv_rate_update(void *mvm_r,
1993@@ -3290,6 +3059,254 @@ static void rs_drv_rate_update(void *mvm_r,
1994 iwl_mvm_rs_rate_init(mvm, sta, sband->band, true);
1995 }
1996
1997+static void __iwl_mvm_rs_tx_status(struct iwl_mvm *mvm,
1998+ struct ieee80211_sta *sta,
1999+ int tid, struct ieee80211_tx_info *info,
2000+ bool ndp)
2001+{
2002+ int legacy_success;
2003+ int retries;
2004+ int i;
2005+ struct iwl_lq_cmd *table;
2006+ u32 lq_hwrate;
2007+ struct rs_rate lq_rate, tx_resp_rate;
2008+ struct iwl_scale_tbl_info *curr_tbl, *other_tbl, *tmp_tbl;
2009+ u32 tlc_info = (uintptr_t)info->status.status_driver_data[0];
2010+ u8 reduced_txp = tlc_info & RS_DRV_DATA_TXP_MSK;
2011+ u8 lq_color = RS_DRV_DATA_LQ_COLOR_GET(tlc_info);
2012+ u32 tx_resp_hwrate = (uintptr_t)info->status.status_driver_data[1];
2013+ struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
2014+ struct iwl_lq_sta *lq_sta = &mvmsta->lq_sta.rs_drv;
2015+
2016+ if (!lq_sta->pers.drv) {
2017+ IWL_DEBUG_RATE(mvm, "Rate scaling not initialized yet.\n");
2018+ return;
2019+ }
2020+
2021+ /* This packet was aggregated but doesn't carry status info */
2022+ if ((info->flags & IEEE80211_TX_CTL_AMPDU) &&
2023+ !(info->flags & IEEE80211_TX_STAT_AMPDU))
2024+ return;
2025+
2026+ if (rs_rate_from_ucode_rate(tx_resp_hwrate, info->band,
2027+ &tx_resp_rate)) {
2028+ WARN_ON_ONCE(1);
2029+ return;
2030+ }
2031+
2032+#ifdef CPTCFG_MAC80211_DEBUGFS
2033+ /* Disable last tx check if we are debugging with fixed rate but
2034+ * update tx stats
2035+ */
2036+ if (lq_sta->pers.dbg_fixed_rate) {
2037+ int index = tx_resp_rate.index;
2038+ enum rs_column column;
2039+ int attempts, success;
2040+
2041+ column = rs_get_column_from_rate(&tx_resp_rate);
2042+ if (WARN_ONCE(column == RS_COLUMN_INVALID,
2043+ "Can't map rate 0x%x to column",
2044+ tx_resp_hwrate))
2045+ return;
2046+
2047+ if (info->flags & IEEE80211_TX_STAT_AMPDU) {
2048+ attempts = info->status.ampdu_len;
2049+ success = info->status.ampdu_ack_len;
2050+ } else {
2051+ attempts = info->status.rates[0].count;
2052+ success = !!(info->flags & IEEE80211_TX_STAT_ACK);
2053+ }
2054+
2055+ lq_sta->pers.tx_stats[column][index].total += attempts;
2056+ lq_sta->pers.tx_stats[column][index].success += success;
2057+
2058+ IWL_DEBUG_RATE(mvm, "Fixed rate 0x%x success %d attempts %d\n",
2059+ tx_resp_hwrate, success, attempts);
2060+ return;
2061+ }
2062+#endif
2063+
2064+ if (time_after(jiffies,
2065+ (unsigned long)(lq_sta->last_tx +
2066+ (IWL_MVM_RS_IDLE_TIMEOUT * HZ)))) {
2067+ IWL_DEBUG_RATE(mvm, "Tx idle for too long. reinit rs\n");
2068+ /* reach here only in case of driver RS, call directly
2069+ * the unlocked version
2070+ */
2071+ rs_drv_rate_init(mvm, sta, info->band);
2072+ return;
2073+ }
2074+ lq_sta->last_tx = jiffies;
2075+
2076+ /* Ignore this Tx frame response if its initial rate doesn't match
2077+ * that of latest Link Quality command. There may be stragglers
2078+ * from a previous Link Quality command, but we're no longer interested
2079+ * in those; they're either from the "active" mode while we're trying
2080+ * to check "search" mode, or a prior "search" mode after we've moved
2081+ * to a new "search" mode (which might become the new "active" mode).
2082+ */
2083+ table = &lq_sta->lq;
2084+ lq_hwrate = le32_to_cpu(table->rs_table[0]);
2085+ if (rs_rate_from_ucode_rate(lq_hwrate, info->band, &lq_rate)) {
2086+ WARN_ON_ONCE(1);
2087+ return;
2088+ }
2089+
2090+ /* Here we actually compare this rate to the latest LQ command */
2091+ if (lq_color != LQ_FLAG_COLOR_GET(table->flags)) {
2092+ IWL_DEBUG_RATE(mvm,
2093+ "tx resp color 0x%x does not match 0x%x\n",
2094+ lq_color, LQ_FLAG_COLOR_GET(table->flags));
2095+
2096+ /* Since rates mis-match, the last LQ command may have failed.
2097+ * After IWL_MISSED_RATE_MAX mis-matches, resync the uCode with
2098+ * ... driver.
2099+ */
2100+ lq_sta->missed_rate_counter++;
2101+ if (lq_sta->missed_rate_counter > IWL_MVM_RS_MISSED_RATE_MAX) {
2102+ lq_sta->missed_rate_counter = 0;
2103+ IWL_DEBUG_RATE(mvm,
2104+ "Too many rates mismatch. Send sync LQ. rs_state %d\n",
2105+ lq_sta->rs_state);
2106+ iwl_mvm_send_lq_cmd(mvm, &lq_sta->lq);
2107+ }
2108+ /* Regardless, ignore this status info for outdated rate */
2109+ return;
2110+ }
2111+
2112+ /* Rate did match, so reset the missed_rate_counter */
2113+ lq_sta->missed_rate_counter = 0;
2114+
2115+ if (!lq_sta->search_better_tbl) {
2116+ curr_tbl = &lq_sta->lq_info[lq_sta->active_tbl];
2117+ other_tbl = &lq_sta->lq_info[1 - lq_sta->active_tbl];
2118+ } else {
2119+ curr_tbl = &lq_sta->lq_info[1 - lq_sta->active_tbl];
2120+ other_tbl = &lq_sta->lq_info[lq_sta->active_tbl];
2121+ }
2122+
2123+ if (WARN_ON_ONCE(!rs_rate_column_match(&lq_rate, &curr_tbl->rate))) {
2124+ IWL_DEBUG_RATE(mvm,
2125+ "Neither active nor search matches tx rate\n");
2126+ tmp_tbl = &lq_sta->lq_info[lq_sta->active_tbl];
2127+ rs_dump_rate(mvm, &tmp_tbl->rate, "ACTIVE");
2128+ tmp_tbl = &lq_sta->lq_info[1 - lq_sta->active_tbl];
2129+ rs_dump_rate(mvm, &tmp_tbl->rate, "SEARCH");
2130+ rs_dump_rate(mvm, &lq_rate, "ACTUAL");
2131+
2132+ /* no matching table found, let's by-pass the data collection
2133+ * and continue to perform rate scale to find the rate table
2134+ */
2135+ rs_stay_in_table(lq_sta, true);
2136+ goto done;
2137+ }
2138+
2139+ /* Updating the frame history depends on whether packets were
2140+ * aggregated.
2141+ *
2142+ * For aggregation, all packets were transmitted at the same rate, the
2143+ * first index into rate scale table.
2144+ */
2145+ if (info->flags & IEEE80211_TX_STAT_AMPDU) {
2146+ rs_collect_tpc_data(mvm, lq_sta, curr_tbl, tx_resp_rate.index,
2147+ info->status.ampdu_len,
2148+ info->status.ampdu_ack_len,
2149+ reduced_txp);
2150+
2151+ /* ampdu_ack_len = 0 marks no BA was received. For TLC, treat
2152+ * it as a single frame loss as we don't want the success ratio
2153+ * to dip too quickly because a BA wasn't received.
2154+ * For TPC, there's no need for this optimisation since we want
2155+ * to recover very quickly from a bad power reduction and,
2156+ * therefore we'd like the success ratio to get an immediate hit
2157+ * when failing to get a BA, so we'd switch back to a lower or
2158+ * zero power reduction. When FW transmits agg with a rate
2159+ * different from the initial rate, it will not use reduced txp
2160+ * and will send BA notification twice (one empty with reduced
2161+ * txp equal to the value from LQ and one with reduced txp 0).
2162+ * We need to update counters for each txp level accordingly.
2163+ */
2164+ if (info->status.ampdu_ack_len == 0)
2165+ info->status.ampdu_len = 1;
2166+
2167+ rs_collect_tlc_data(mvm, mvmsta, tid, curr_tbl,
2168+ tx_resp_rate.index,
2169+ info->status.ampdu_len,
2170+ info->status.ampdu_ack_len);
2171+
2172+ /* Update success/fail counts if not searching for new mode */
2173+ if (lq_sta->rs_state == RS_STATE_STAY_IN_COLUMN) {
2174+ lq_sta->total_success += info->status.ampdu_ack_len;
2175+ lq_sta->total_failed += (info->status.ampdu_len -
2176+ info->status.ampdu_ack_len);
2177+ }
2178+ } else {
2179+ /* For legacy, update frame history with for each Tx retry. */
2180+ retries = info->status.rates[0].count - 1;
2181+ /* HW doesn't send more than 15 retries */
2182+ retries = min(retries, 15);
2183+
2184+ /* The last transmission may have been successful */
2185+ legacy_success = !!(info->flags & IEEE80211_TX_STAT_ACK);
2186+ /* Collect data for each rate used during failed TX attempts */
2187+ for (i = 0; i <= retries; ++i) {
2188+ lq_hwrate = le32_to_cpu(table->rs_table[i]);
2189+ if (rs_rate_from_ucode_rate(lq_hwrate, info->band,
2190+ &lq_rate)) {
2191+ WARN_ON_ONCE(1);
2192+ return;
2193+ }
2194+
2195+ /* Only collect stats if retried rate is in the same RS
2196+ * table as active/search.
2197+ */
2198+ if (rs_rate_column_match(&lq_rate, &curr_tbl->rate))
2199+ tmp_tbl = curr_tbl;
2200+ else if (rs_rate_column_match(&lq_rate,
2201+ &other_tbl->rate))
2202+ tmp_tbl = other_tbl;
2203+ else
2204+ continue;
2205+
2206+ rs_collect_tpc_data(mvm, lq_sta, tmp_tbl,
2207+ tx_resp_rate.index, 1,
2208+ i < retries ? 0 : legacy_success,
2209+ reduced_txp);
2210+ rs_collect_tlc_data(mvm, mvmsta, tid, tmp_tbl,
2211+ tx_resp_rate.index, 1,
2212+ i < retries ? 0 : legacy_success);
2213+ }
2214+
2215+ /* Update success/fail counts if not searching for new mode */
2216+ if (lq_sta->rs_state == RS_STATE_STAY_IN_COLUMN) {
2217+ lq_sta->total_success += legacy_success;
2218+ lq_sta->total_failed += retries + (1 - legacy_success);
2219+ }
2220+ }
2221+ /* The last TX rate is cached in lq_sta; it's set in if/else above */
2222+ lq_sta->last_rate_n_flags = lq_hwrate;
2223+ IWL_DEBUG_RATE(mvm, "reduced txpower: %d\n", reduced_txp);
2224+done:
2225+ /* See if there's a better rate or modulation mode to try. */
2226+ if (sta->supp_rates[info->band])
2227+ rs_rate_scale_perform(mvm, sta, lq_sta, tid, ndp);
2228+}
2229+
2230+void iwl_mvm_rs_tx_status(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
2231+ int tid, struct ieee80211_tx_info *info, bool ndp)
2232+{
2233+ struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
2234+
2235+ /* If it's locked we are in middle of init flow
2236+ * just wait for next tx status to update the lq_sta data
2237+ */
2238+ if (!spin_trylock(&mvmsta->lq_sta.rs_drv.pers.lock))
2239+ return;
2240+
2241+ __iwl_mvm_rs_tx_status(mvm, sta, tid, info, ndp);
2242+ spin_unlock(&mvmsta->lq_sta.rs_drv.pers.lock);
2243+}
2244+
2245 #ifdef CPTCFG_MAC80211_DEBUGFS
2246 static void rs_build_rates_table_from_fixed(struct iwl_mvm *mvm,
2247 struct iwl_lq_cmd *lq_cmd,
2248@@ -3581,7 +3598,7 @@ static void rs_set_lq_ss_params(struct iwl_mvm *mvm,
2249
2250 bfersta_ss_params &= ~LQ_SS_BFER_ALLOWED;
2251 bfersta_lq_cmd->ss_params = cpu_to_le32(bfersta_ss_params);
2252- iwl_mvm_send_lq_cmd(mvm, bfersta_lq_cmd, false);
2253+ iwl_mvm_send_lq_cmd(mvm, bfersta_lq_cmd);
2254
2255 ss_params |= LQ_SS_BFER_ALLOWED;
2256 IWL_DEBUG_RATE(mvm,
2257@@ -3747,7 +3764,7 @@ static void rs_program_fix_rate(struct iwl_mvm *mvm,
2258
2259 if (lq_sta->pers.dbg_fixed_rate) {
2260 rs_fill_lq_cmd(mvm, NULL, lq_sta, NULL);
2261- iwl_mvm_send_lq_cmd(lq_sta->pers.drv, &lq_sta->lq, false);
2262+ iwl_mvm_send_lq_cmd(lq_sta->pers.drv, &lq_sta->lq);
2263 }
2264 }
2265
2266@@ -4105,10 +4122,6 @@ static void rs_drv_add_sta_debugfs(void *mvm, void *priv_sta,
2267
2268 MVM_DEBUGFS_ADD_FILE_RS(ss_force, dir, 0600);
2269 }
2270-
2271-void rs_remove_sta_debugfs(void *mvm, void *mvm_sta)
2272-{
2273-}
2274 #endif
2275
2276 /*
2277@@ -4136,7 +4149,6 @@ static const struct rate_control_ops rs_mvm_ops_drv = {
2278 .rate_update = rs_drv_rate_update,
2279 #ifdef CPTCFG_MAC80211_DEBUGFS
2280 .add_sta_debugfs = rs_drv_add_sta_debugfs,
2281- .remove_sta_debugfs = rs_remove_sta_debugfs,
2282 #endif
2283 .capa = RATE_CTRL_CAPA_VHT_EXT_NSS_BW,
2284 };
2285@@ -4144,10 +4156,15 @@ static const struct rate_control_ops rs_mvm_ops_drv = {
2286 void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
2287 enum nl80211_band band, bool update)
2288 {
2289- if (iwl_mvm_has_tlc_offload(mvm))
2290+ if (iwl_mvm_has_tlc_offload(mvm)) {
2291 rs_fw_rate_init(mvm, sta, band, update);
2292- else
2293- rs_drv_rate_init(mvm, sta, band, update);
2294+ } else {
2295+ struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
2296+
2297+ spin_lock(&mvmsta->lq_sta.rs_drv.pers.lock);
2298+ rs_drv_rate_init(mvm, sta, band);
2299+ spin_unlock(&mvmsta->lq_sta.rs_drv.pers.lock);
2300+ }
2301 }
2302
2303 int iwl_mvm_rate_control_register(void)
2304@@ -4177,7 +4194,7 @@ static int rs_drv_tx_protection(struct iwl_mvm *mvm, struct iwl_mvm_sta *mvmsta,
2305 lq->flags &= ~LQ_FLAG_USE_RTS_MSK;
2306 }
2307
2308- return iwl_mvm_send_lq_cmd(mvm, lq, false);
2309+ return iwl_mvm_send_lq_cmd(mvm, lq);
2310 }
2311
2312 /**
2313diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rs.h b/drivers/net/wireless/intel/iwlwifi/mvm/rs.h
2314index b80eebc..b199b43 100644
2315--- a/drivers/net/wireless/intel/iwlwifi/mvm/rs.h
2316+++ b/drivers/net/wireless/intel/iwlwifi/mvm/rs.h
2317@@ -3,7 +3,7 @@
2318 * Copyright(c) 2003 - 2014 Intel Corporation. All rights reserved.
2319 * Copyright(c) 2015 Intel Mobile Communications GmbH
2320 * Copyright(c) 2017 Intel Deutschland GmbH
2321- * Copyright(c) 2018 Intel Corporation
2322+ * Copyright(c) 2018 - 2019 Intel Corporation
2323 *
2324 * This program is free software; you can redistribute it and/or modify it
2325 * under the terms of version 2 of the GNU General Public License as
2326@@ -396,6 +396,7 @@ struct iwl_lq_sta {
2327 s8 last_rssi;
2328 struct rs_rate_stats tx_stats[RS_COLUMN_COUNT][IWL_RATE_COUNT];
2329 struct iwl_mvm *drv;
2330+ spinlock_t lock; /* for races in reinit/update table */
2331 } pers;
2332 };
2333
2334diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c
2335index c35c3dd..6eadeb7 100644
2336--- a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c
2337+++ b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c
2338@@ -462,20 +462,22 @@ static bool iwl_mvm_is_dup(struct ieee80211_sta *sta, int queue,
2339 }
2340
2341 int iwl_mvm_notify_rx_queue(struct iwl_mvm *mvm, u32 rxq_mask,
2342- const u8 *data, u32 count)
2343+ const u8 *data, u32 count, bool async)
2344 {
2345- struct iwl_rxq_sync_cmd *cmd;
2346+ u8 buf[sizeof(struct iwl_rxq_sync_cmd) +
2347+ sizeof(struct iwl_mvm_rss_sync_notif)];
2348+ struct iwl_rxq_sync_cmd *cmd = (void *)buf;
2349 u32 data_size = sizeof(*cmd) + count;
2350 int ret;
2351
2352- /* should be DWORD aligned */
2353- if (WARN_ON(count & 3 || count > IWL_MULTI_QUEUE_SYNC_MSG_MAX_SIZE))
2354+ /*
2355+ * size must be a multiple of DWORD
2356+ * Ensure we don't overflow buf
2357+ */
2358+ if (WARN_ON(count & 3 ||
2359+ count > sizeof(struct iwl_mvm_rss_sync_notif)))
2360 return -EINVAL;
2361
2362- cmd = kzalloc(data_size, GFP_KERNEL);
2363- if (!cmd)
2364- return -ENOMEM;
2365-
2366 cmd->rxq_mask = cpu_to_le32(rxq_mask);
2367 cmd->count = cpu_to_le32(count);
2368 cmd->flags = 0;
2369@@ -484,9 +486,8 @@ int iwl_mvm_notify_rx_queue(struct iwl_mvm *mvm, u32 rxq_mask,
2370 ret = iwl_mvm_send_cmd_pdu(mvm,
2371 WIDE_ID(DATA_PATH_GROUP,
2372 TRIGGER_RX_QUEUES_NOTIF_CMD),
2373- 0, data_size, cmd);
2374+ async ? CMD_ASYNC : 0, data_size, cmd);
2375
2376- kfree(cmd);
2377 return ret;
2378 }
2379
2380@@ -502,14 +503,31 @@ static bool iwl_mvm_is_sn_less(u16 sn1, u16 sn2, u16 buffer_size)
2381 !ieee80211_sn_less(sn1, sn2 - buffer_size);
2382 }
2383
2384+static void iwl_mvm_sync_nssn(struct iwl_mvm *mvm, u8 baid, u16 nssn)
2385+{
2386+ struct iwl_mvm_rss_sync_notif notif = {
2387+ .metadata.type = IWL_MVM_RXQ_NSSN_SYNC,
2388+ .metadata.sync = 0,
2389+ .nssn_sync.baid = baid,
2390+ .nssn_sync.nssn = nssn,
2391+ };
2392+
2393+ iwl_mvm_sync_rx_queues_internal(mvm, (void *)&notif, sizeof(notif));
2394+}
2395+
2396 #define RX_REORDER_BUF_TIMEOUT_MQ (HZ / 10)
2397
2398+enum iwl_mvm_release_flags {
2399+ IWL_MVM_RELEASE_SEND_RSS_SYNC = BIT(0),
2400+ IWL_MVM_RELEASE_FROM_RSS_SYNC = BIT(1),
2401+};
2402+
2403 static void iwl_mvm_release_frames(struct iwl_mvm *mvm,
2404 struct ieee80211_sta *sta,
2405 struct napi_struct *napi,
2406 struct iwl_mvm_baid_data *baid_data,
2407 struct iwl_mvm_reorder_buffer *reorder_buf,
2408- u16 nssn)
2409+ u16 nssn, u32 flags)
2410 {
2411 struct iwl_mvm_reorder_buf_entry *entries =
2412 &baid_data->entries[reorder_buf->queue *
2413@@ -518,6 +536,18 @@ static void iwl_mvm_release_frames(struct iwl_mvm *mvm,
2414
2415 lockdep_assert_held(&reorder_buf->lock);
2416
2417+ /*
2418+ * We keep the NSSN not too far behind, if we are sync'ing it and it
2419+ * is more than 2048 ahead of us, it must be behind us. Discard it.
2420+ * This can happen if the queue that hit the 0 / 2048 seqno was lagging
2421+ * behind and this queue already processed packets. The next if
2422+ * would have caught cases where this queue would have processed less
2423+ * than 64 packets, but it may have processed more than 64 packets.
2424+ */
2425+ if ((flags & IWL_MVM_RELEASE_FROM_RSS_SYNC) &&
2426+ ieee80211_sn_less(nssn, ssn))
2427+ goto set_timer;
2428+
2429 /* ignore nssn smaller than head sn - this can happen due to timeout */
2430 if (iwl_mvm_is_sn_less(nssn, ssn, reorder_buf->buf_size))
2431 goto set_timer;
2432@@ -528,6 +558,9 @@ static void iwl_mvm_release_frames(struct iwl_mvm *mvm,
2433 struct sk_buff *skb;
2434
2435 ssn = ieee80211_sn_inc(ssn);
2436+ if ((flags & IWL_MVM_RELEASE_SEND_RSS_SYNC) &&
2437+ (ssn == 2048 || ssn == 0))
2438+ iwl_mvm_sync_nssn(mvm, baid_data->baid, ssn);
2439
2440 /*
2441 * Empty the list. Will have more than one frame for A-MSDU.
2442@@ -614,7 +647,8 @@ void iwl_mvm_reorder_timer_expired(struct timer_list *t)
2443 sta_id, sn);
2444 iwl_mvm_event_frame_timeout_callback(buf->mvm, mvmsta->vif,
2445 sta, baid_data->tid);
2446- iwl_mvm_release_frames(buf->mvm, sta, NULL, baid_data, buf, sn);
2447+ iwl_mvm_release_frames(buf->mvm, sta, NULL, baid_data,
2448+ buf, sn, IWL_MVM_RELEASE_SEND_RSS_SYNC);
2449 rcu_read_unlock();
2450 } else {
2451 /*
2452@@ -656,7 +690,8 @@ static void iwl_mvm_del_ba(struct iwl_mvm *mvm, int queue,
2453 spin_lock_bh(&reorder_buf->lock);
2454 iwl_mvm_release_frames(mvm, sta, NULL, ba_data, reorder_buf,
2455 ieee80211_sn_add(reorder_buf->head_sn,
2456- reorder_buf->buf_size));
2457+ reorder_buf->buf_size),
2458+ 0);
2459 spin_unlock_bh(&reorder_buf->lock);
2460 del_timer_sync(&reorder_buf->reorder_timer);
2461
2462@@ -664,8 +699,54 @@ out:
2463 rcu_read_unlock();
2464 }
2465
2466-void iwl_mvm_rx_queue_notif(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
2467- int queue)
2468+static void iwl_mvm_release_frames_from_notif(struct iwl_mvm *mvm,
2469+ struct napi_struct *napi,
2470+ u8 baid, u16 nssn, int queue,
2471+ u32 flags)
2472+{
2473+ struct ieee80211_sta *sta;
2474+ struct iwl_mvm_reorder_buffer *reorder_buf;
2475+ struct iwl_mvm_baid_data *ba_data;
2476+
2477+ IWL_DEBUG_HT(mvm, "Frame release notification for BAID %u, NSSN %d\n",
2478+ baid, nssn);
2479+
2480+ if (WARN_ON_ONCE(baid == IWL_RX_REORDER_DATA_INVALID_BAID ||
2481+ baid >= ARRAY_SIZE(mvm->baid_map)))
2482+ return;
2483+
2484+ rcu_read_lock();
2485+
2486+ ba_data = rcu_dereference(mvm->baid_map[baid]);
2487+ if (WARN_ON_ONCE(!ba_data))
2488+ goto out;
2489+
2490+ sta = rcu_dereference(mvm->fw_id_to_mac_id[ba_data->sta_id]);
2491+ if (WARN_ON_ONCE(IS_ERR_OR_NULL(sta)))
2492+ goto out;
2493+
2494+ reorder_buf = &ba_data->reorder_buf[queue];
2495+
2496+ spin_lock_bh(&reorder_buf->lock);
2497+ iwl_mvm_release_frames(mvm, sta, napi, ba_data,
2498+ reorder_buf, nssn, flags);
2499+ spin_unlock_bh(&reorder_buf->lock);
2500+
2501+out:
2502+ rcu_read_unlock();
2503+}
2504+
2505+static void iwl_mvm_nssn_sync(struct iwl_mvm *mvm,
2506+ struct napi_struct *napi, int queue,
2507+ const struct iwl_mvm_nssn_sync_data *data)
2508+{
2509+ iwl_mvm_release_frames_from_notif(mvm, napi, data->baid,
2510+ data->nssn, queue,
2511+ IWL_MVM_RELEASE_FROM_RSS_SYNC);
2512+}
2513+
2514+void iwl_mvm_rx_queue_notif(struct iwl_mvm *mvm, struct napi_struct *napi,
2515+ struct iwl_rx_cmd_buffer *rxb, int queue)
2516 {
2517 struct iwl_rx_packet *pkt = rxb_addr(rxb);
2518 struct iwl_rxq_sync_notification *notif;
2519@@ -686,6 +767,10 @@ void iwl_mvm_rx_queue_notif(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
2520 case IWL_MVM_RXQ_NOTIF_DEL_BA:
2521 iwl_mvm_del_ba(mvm, queue, (void *)internal_notif->data);
2522 break;
2523+ case IWL_MVM_RXQ_NSSN_SYNC:
2524+ iwl_mvm_nssn_sync(mvm, napi, queue,
2525+ (void *)internal_notif->data);
2526+ break;
2527 default:
2528 WARN_ONCE(1, "Invalid identifier %d", internal_notif->type);
2529 }
2530@@ -784,7 +869,8 @@ static bool iwl_mvm_reorder(struct iwl_mvm *mvm,
2531 }
2532
2533 if (ieee80211_is_back_req(hdr->frame_control)) {
2534- iwl_mvm_release_frames(mvm, sta, napi, baid_data, buffer, nssn);
2535+ iwl_mvm_release_frames(mvm, sta, napi, baid_data,
2536+ buffer, nssn, 0);
2537 goto drop;
2538 }
2539
2540@@ -793,7 +879,10 @@ static bool iwl_mvm_reorder(struct iwl_mvm *mvm,
2541 * If the SN is smaller than the NSSN it might need to first go into
2542 * the reorder buffer, in which case we just release up to it and the
2543 * rest of the function will take care of storing it and releasing up to
2544- * the nssn
2545+ * the nssn.
2546+ * This should not happen. This queue has been lagging and it should
2547+ * have been updated by a IWL_MVM_RXQ_NSSN_SYNC notification. Be nice
2548+ * and update the other queues.
2549 */
2550 if (!iwl_mvm_is_sn_less(nssn, buffer->head_sn + buffer->buf_size,
2551 buffer->buf_size) ||
2552@@ -801,7 +890,7 @@ static bool iwl_mvm_reorder(struct iwl_mvm *mvm,
2553 u16 min_sn = ieee80211_sn_less(sn, nssn) ? sn : nssn;
2554
2555 iwl_mvm_release_frames(mvm, sta, napi, baid_data, buffer,
2556- min_sn);
2557+ min_sn, IWL_MVM_RELEASE_SEND_RSS_SYNC);
2558 }
2559
2560 /* drop any oudated packets */
2561@@ -812,8 +901,23 @@ static bool iwl_mvm_reorder(struct iwl_mvm *mvm,
2562 if (!buffer->num_stored && ieee80211_sn_less(sn, nssn)) {
2563 if (iwl_mvm_is_sn_less(buffer->head_sn, nssn,
2564 buffer->buf_size) &&
2565- (!amsdu || last_subframe))
2566+ (!amsdu || last_subframe)) {
2567+ /*
2568+ * If we crossed the 2048 or 0 SN, notify all the
2569+ * queues. This is done in order to avoid having a
2570+ * head_sn that lags behind for too long. When that
2571+ * happens, we can get to a situation where the head_sn
2572+ * is within the interval [nssn - buf_size : nssn]
2573+ * which will make us think that the nssn is a packet
2574+ * that we already freed because of the reordering
2575+ * buffer and we will ignore it. So maintain the
2576+ * head_sn somewhat updated across all the queues:
2577+ * when it crosses 0 and 2048.
2578+ */
2579+ if (sn == 2048 || sn == 0)
2580+ iwl_mvm_sync_nssn(mvm, baid, sn);
2581 buffer->head_sn = nssn;
2582+ }
2583 /* No need to update AMSDU last SN - we are moving the head */
2584 spin_unlock_bh(&buffer->lock);
2585 return false;
2586@@ -828,8 +932,11 @@ static bool iwl_mvm_reorder(struct iwl_mvm *mvm,
2587 * while technically there is no hole and we can move forward.
2588 */
2589 if (!buffer->num_stored && sn == buffer->head_sn) {
2590- if (!amsdu || last_subframe)
2591+ if (!amsdu || last_subframe) {
2592+ if (sn == 2048 || sn == 0)
2593+ iwl_mvm_sync_nssn(mvm, baid, sn);
2594 buffer->head_sn = ieee80211_sn_inc(buffer->head_sn);
2595+ }
2596 /* No need to update AMSDU last SN - we are moving the head */
2597 spin_unlock_bh(&buffer->lock);
2598 return false;
2599@@ -874,7 +981,9 @@ static bool iwl_mvm_reorder(struct iwl_mvm *mvm,
2600 * release notification with up to date NSSN.
2601 */
2602 if (!amsdu || last_subframe)
2603- iwl_mvm_release_frames(mvm, sta, napi, baid_data, buffer, nssn);
2604+ iwl_mvm_release_frames(mvm, sta, napi, baid_data,
2605+ buffer, nssn,
2606+ IWL_MVM_RELEASE_SEND_RSS_SYNC);
2607
2608 spin_unlock_bh(&buffer->lock);
2609 return true;
2610@@ -1843,40 +1952,14 @@ void iwl_mvm_rx_monitor_no_data(struct iwl_mvm *mvm, struct napi_struct *napi,
2611 out:
2612 rcu_read_unlock();
2613 }
2614+
2615 void iwl_mvm_rx_frame_release(struct iwl_mvm *mvm, struct napi_struct *napi,
2616 struct iwl_rx_cmd_buffer *rxb, int queue)
2617 {
2618 struct iwl_rx_packet *pkt = rxb_addr(rxb);
2619 struct iwl_frame_release *release = (void *)pkt->data;
2620- struct ieee80211_sta *sta;
2621- struct iwl_mvm_reorder_buffer *reorder_buf;
2622- struct iwl_mvm_baid_data *ba_data;
2623-
2624- int baid = release->baid;
2625-
2626- IWL_DEBUG_HT(mvm, "Frame release notification for BAID %u, NSSN %d\n",
2627- release->baid, le16_to_cpu(release->nssn));
2628
2629- if (WARN_ON_ONCE(baid == IWL_RX_REORDER_DATA_INVALID_BAID))
2630- return;
2631-
2632- rcu_read_lock();
2633-
2634- ba_data = rcu_dereference(mvm->baid_map[baid]);
2635- if (WARN_ON_ONCE(!ba_data))
2636- goto out;
2637-
2638- sta = rcu_dereference(mvm->fw_id_to_mac_id[ba_data->sta_id]);
2639- if (WARN_ON_ONCE(IS_ERR_OR_NULL(sta)))
2640- goto out;
2641-
2642- reorder_buf = &ba_data->reorder_buf[queue];
2643-
2644- spin_lock_bh(&reorder_buf->lock);
2645- iwl_mvm_release_frames(mvm, sta, napi, ba_data, reorder_buf,
2646- le16_to_cpu(release->nssn));
2647- spin_unlock_bh(&reorder_buf->lock);
2648-
2649-out:
2650- rcu_read_unlock();
2651+ iwl_mvm_release_frames_from_notif(mvm, napi, release->baid,
2652+ le16_to_cpu(release->nssn),
2653+ queue, 0);
2654 }
2655diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
2656index 7d667f3..1cdfebc 100644
2657--- a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
2658+++ b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
2659@@ -1678,6 +1678,8 @@ int iwl_mvm_add_sta(struct iwl_mvm *mvm,
2660 */
2661 if (iwl_mvm_has_tlc_offload(mvm))
2662 iwl_mvm_rs_add_sta(mvm, mvm_sta);
2663+ else
2664+ spin_lock_init(&mvm_sta->lq_sta.rs_drv.pers.lock);
2665
2666 iwl_mvm_toggle_tx_ant(mvm, &mvm_sta->tx_ant);
2667
2668@@ -2411,7 +2413,7 @@ int iwl_mvm_rm_mcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
2669
2670 static void iwl_mvm_sync_rxq_del_ba(struct iwl_mvm *mvm, u8 baid)
2671 {
2672- struct iwl_mvm_delba_notif notif = {
2673+ struct iwl_mvm_rss_sync_notif notif = {
2674 .metadata.type = IWL_MVM_RXQ_NOTIF_DEL_BA,
2675 .metadata.sync = 1,
2676 .delba.baid = baid,
2677@@ -2955,7 +2957,7 @@ out:
2678 IWL_DEBUG_HT(mvm, "Tx aggregation enabled on ra = %pM tid = %d\n",
2679 sta->addr, tid);
2680
2681- return iwl_mvm_send_lq_cmd(mvm, &mvmsta->lq_sta.rs_drv.lq, false);
2682+ return iwl_mvm_send_lq_cmd(mvm, &mvmsta->lq_sta.rs_drv.lq);
2683 }
2684
2685 static void iwl_mvm_unreserve_agg_queue(struct iwl_mvm *mvm,
2686diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/sta.h b/drivers/net/wireless/intel/iwlwifi/mvm/sta.h
2687index 4487cc3..8d70093 100644
2688--- a/drivers/net/wireless/intel/iwlwifi/mvm/sta.h
2689+++ b/drivers/net/wireless/intel/iwlwifi/mvm/sta.h
2690@@ -343,9 +343,17 @@ struct iwl_mvm_delba_data {
2691 u32 baid;
2692 } __packed;
2693
2694-struct iwl_mvm_delba_notif {
2695+struct iwl_mvm_nssn_sync_data {
2696+ u32 baid;
2697+ u32 nssn;
2698+} __packed;
2699+
2700+struct iwl_mvm_rss_sync_notif {
2701 struct iwl_mvm_internal_rxq_notif metadata;
2702- struct iwl_mvm_delba_data delba;
2703+ union {
2704+ struct iwl_mvm_delba_data delba;
2705+ struct iwl_mvm_nssn_sync_data nssn_sync;
2706+ };
2707 } __packed;
2708
2709 /**
2710diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/utils.c b/drivers/net/wireless/intel/iwlwifi/mvm/utils.c
2711index dd65970..99f02f8 100644
2712--- a/drivers/net/wireless/intel/iwlwifi/mvm/utils.c
2713+++ b/drivers/net/wireless/intel/iwlwifi/mvm/utils.c
2714@@ -647,12 +647,12 @@ int iwl_mvm_reconfig_scd(struct iwl_mvm *mvm, int queue, int fifo, int sta_id,
2715 * this case to clear the state indicating that station creation is in
2716 * progress.
2717 */
2718-int iwl_mvm_send_lq_cmd(struct iwl_mvm *mvm, struct iwl_lq_cmd *lq, bool sync)
2719+int iwl_mvm_send_lq_cmd(struct iwl_mvm *mvm, struct iwl_lq_cmd *lq)
2720 {
2721 struct iwl_host_cmd cmd = {
2722 .id = LQ_CMD,
2723 .len = { sizeof(struct iwl_lq_cmd), },
2724- .flags = sync ? 0 : CMD_ASYNC,
2725+ .flags = CMD_ASYNC,
2726 .data = { lq, },
2727 };
2728
2729diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c
2730index fee789b..1324f23 100644
2731--- a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c
2732+++ b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c
2733@@ -417,6 +417,7 @@ static const struct pci_device_id iwl_hw_card_ids[] = {
2734 {IWL_PCI_DEVICE(0x2526, 0x40A4, iwl9460_2ac_cfg)},
2735 {IWL_PCI_DEVICE(0x2526, 0x4234, iwl9560_2ac_cfg_soc)},
2736 {IWL_PCI_DEVICE(0x2526, 0x42A4, iwl9462_2ac_cfg_soc)},
2737+ {IWL_PCI_DEVICE(0x2526, 0x6014, iwl9260_2ac_160_cfg)},
2738 {IWL_PCI_DEVICE(0x2526, 0x8014, iwl9260_2ac_160_cfg)},
2739 {IWL_PCI_DEVICE(0x2526, 0x8010, iwl9260_2ac_160_cfg)},
2740 {IWL_PCI_DEVICE(0x2526, 0xA014, iwl9260_2ac_160_cfg)},
2741@@ -789,6 +790,7 @@ static const struct pci_device_id iwl_hw_card_ids[] = {
2742 {IWL_PCI_DEVICE(0x7A70, 0x0310, iwlax211_2ax_cfg_so_gf_a0)},
2743 {IWL_PCI_DEVICE(0x7A70, 0x0510, iwlax211_2ax_cfg_so_gf_a0)},
2744 {IWL_PCI_DEVICE(0x7A70, 0x0A10, iwlax211_2ax_cfg_so_gf_a0)},
2745+ {IWL_PCI_DEVICE(0x7AF0, 0x0090, iwlax211_2ax_cfg_so_gf_a0)},
2746 {IWL_PCI_DEVICE(0x7AF0, 0x0310, iwlax211_2ax_cfg_so_gf_a0)},
2747 {IWL_PCI_DEVICE(0x7AF0, 0x0510, iwlax211_2ax_cfg_so_gf_a0)},
2748 {IWL_PCI_DEVICE(0x7AF0, 0x0A10, iwlax211_2ax_cfg_so_gf_a0)},
2749@@ -861,6 +863,27 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
2750 }
2751 iwl_trans->cfg = cfg;
2752 }
2753+
2754+ /*
2755+ * This is a hack to switch from Qu B0 to Qu C0. We need to
2756+ * do this for all cfgs that use Qu B0. All this code is in
2757+ * urgent need for a refactor, but for now this is the easiest
2758+ * thing to do to support Qu C-step.
2759+ */
2760+ if (iwl_trans->hw_rev == CSR_HW_REV_TYPE_QU_C0) {
2761+ if (iwl_trans->cfg == &iwl_ax101_cfg_qu_hr)
2762+ iwl_trans->cfg = &iwl_ax101_cfg_qu_c0_hr_b0;
2763+ else if (iwl_trans->cfg == &iwl_ax201_cfg_qu_hr)
2764+ iwl_trans->cfg = &iwl_ax201_cfg_qu_c0_hr_b0;
2765+ else if (iwl_trans->cfg == &iwl9461_2ac_cfg_qu_b0_jf_b0)
2766+ iwl_trans->cfg = &iwl9461_2ac_cfg_qu_c0_jf_b0;
2767+ else if (iwl_trans->cfg == &iwl9462_2ac_cfg_qu_b0_jf_b0)
2768+ iwl_trans->cfg = &iwl9462_2ac_cfg_qu_c0_jf_b0;
2769+ else if (iwl_trans->cfg == &iwl9560_2ac_cfg_qu_b0_jf_b0)
2770+ iwl_trans->cfg = &iwl9560_2ac_cfg_qu_c0_jf_b0;
2771+ else if (iwl_trans->cfg == &iwl9560_2ac_160_cfg_qu_b0_jf_b0)
2772+ iwl_trans->cfg = &iwl9560_2ac_160_cfg_qu_c0_jf_b0;
2773+ }
2774 #endif
2775
2776 pci_set_drvdata(pdev, iwl_trans);
2777diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
2778index 1e63a59..519a421 100644
2779--- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
2780+++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
2781@@ -218,8 +218,7 @@ static void iwl_pcie_alloc_fw_monitor_block(struct iwl_trans *trans,
2782 for (power = max_power; power >= min_power; power--) {
2783 size = BIT(power);
2784 cpu_addr = dma_alloc_coherent(trans->dev, size, &phys,
2785- GFP_KERNEL | __GFP_NOWARN |
2786- __GFP_ZERO | __GFP_COMP);
2787+ GFP_KERNEL | __GFP_NOWARN);
2788 if (!cpu_addr)
2789 continue;
2790
2791@@ -2140,7 +2139,6 @@ static void iwl_trans_pcie_release_nic_access(struct iwl_trans *trans,
2792 * MAC_ACCESS_REQ bit to be performed before any other writes
2793 * scheduled on different CPUs (after we drop reg_lock).
2794 */
2795- mmiowb();
2796 out:
2797 spin_unlock_irqrestore(&trans_pcie->reg_lock, *flags);
2798 }
2799@@ -3615,8 +3613,9 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev,
2800 } else if (CSR_HW_RF_ID_TYPE_CHIP_ID(trans->hw_rf_id) ==
2801 CSR_HW_RF_ID_TYPE_CHIP_ID(CSR_HW_RF_ID_TYPE_HR) &&
2802 ((trans->cfg != &iwl_ax200_cfg_cc &&
2803- trans->cfg != &killer1650x_2ax_cfg &&
2804- trans->cfg != &killer1650w_2ax_cfg) ||
2805+ trans->cfg != &killer1650x_2ax_cfg &&
2806+ trans->cfg != &killer1650w_2ax_cfg &&
2807+ trans->cfg != &iwl_ax201_cfg_quz_hr) ||
2808 trans->hw_rev == CSR_HW_REV_TYPE_QNJ_B0)) {
2809 u32 hw_status;
2810
2811diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
2812index 26e4405..880445d 100644
2813--- a/drivers/net/wireless/mac80211_hwsim.c
2814+++ b/drivers/net/wireless/mac80211_hwsim.c
2815@@ -3654,35 +3654,53 @@ done:
2816 static __genl_const struct genl_ops hwsim_ops[] = {
2817 {
2818 .cmd = HWSIM_CMD_REGISTER,
2819- .policy = hwsim_genl_policy,
2820+#if LINUX_VERSION_IS_GEQ(5,2,0)
2821+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
2822+#endif
2823+
2824 .doit = hwsim_register_received_nl,
2825 .flags = GENL_UNS_ADMIN_PERM,
2826 },
2827 {
2828 .cmd = HWSIM_CMD_FRAME,
2829- .policy = hwsim_genl_policy,
2830+#if LINUX_VERSION_IS_GEQ(5,2,0)
2831+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
2832+#endif
2833+
2834 .doit = hwsim_cloned_frame_received_nl,
2835 },
2836 {
2837 .cmd = HWSIM_CMD_TX_INFO_FRAME,
2838- .policy = hwsim_genl_policy,
2839+#if LINUX_VERSION_IS_GEQ(5,2,0)
2840+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
2841+#endif
2842+
2843 .doit = hwsim_tx_info_frame_received_nl,
2844 },
2845 {
2846 .cmd = HWSIM_CMD_NEW_RADIO,
2847- .policy = hwsim_genl_policy,
2848+#if LINUX_VERSION_IS_GEQ(5,2,0)
2849+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
2850+#endif
2851+
2852 .doit = hwsim_new_radio_nl,
2853 .flags = GENL_UNS_ADMIN_PERM,
2854 },
2855 {
2856 .cmd = HWSIM_CMD_DEL_RADIO,
2857- .policy = hwsim_genl_policy,
2858+#if LINUX_VERSION_IS_GEQ(5,2,0)
2859+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
2860+#endif
2861+
2862 .doit = hwsim_del_radio_nl,
2863 .flags = GENL_UNS_ADMIN_PERM,
2864 },
2865 {
2866 .cmd = HWSIM_CMD_GET_RADIO,
2867- .policy = hwsim_genl_policy,
2868+#if LINUX_VERSION_IS_GEQ(5,2,0)
2869+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
2870+#endif
2871+
2872 .doit = hwsim_get_radio_nl,
2873 .dumpit = hwsim_dump_radio_nl,
2874 },
2875@@ -3692,6 +3710,7 @@ static struct genl_family hwsim_genl_family __genl_ro_after_init = {
2876 .name = "MAC80211_HWSIM",
2877 .version = 1,
2878 .maxattr = HWSIM_ATTR_MAX,
2879+ .policy = hwsim_genl_policy,
2880 .netnsok = true,
2881 .module = THIS_MODULE,
2882 .ops = hwsim_ops,
2883diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c
2884index fc29f99..ba2d64a 100644
2885--- a/net/mac80211/ibss.c
2886+++ b/net/mac80211/ibss.c
2887@@ -1193,6 +1193,7 @@ void ieee80211_ibss_rx_no_sta(struct ieee80211_sub_if_data *sdata,
2888 {
2889 struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
2890 struct ieee80211_chanctx_conf *chanctx_conf;
2891+ struct sk_buff *skb;
2892
2893 if (ifibss->state == IEEE80211_IBSS_MLME_SEARCH)
2894 return;
2895@@ -1207,9 +1208,12 @@ void ieee80211_ibss_rx_no_sta(struct ieee80211_sub_if_data *sdata,
2896 return;
2897 }
2898
2899- ieee80211_mlme_send_probe_req(sdata, sdata->vif.addr, addr,
2900- sdata->u.ibss.ssid, sdata->u.ibss.ssid_len,
2901- chanctx_conf->def.chan);
2902+ skb = ieee80211_build_probe_req(sdata, sdata->vif.addr, addr, bssid,
2903+ (u32)-1, chanctx_conf->def.chan,
2904+ ifibss->ssid, ifibss->ssid_len, NULL, 0,
2905+ IEEE80211_PROBE_FLAG_DIRECTED);
2906+ if (skb)
2907+ ieee80211_tx_skb(sdata, skb);
2908 rcu_read_unlock();
2909 }
2910
2911diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
2912index fca3b96..1c659c7 100644
2913--- a/net/mac80211/ieee80211_i.h
2914+++ b/net/mac80211/ieee80211_i.h
2915@@ -2212,7 +2212,7 @@ int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer,
2916 u32 flags);
2917 struct sk_buff *ieee80211_build_probe_req(struct ieee80211_sub_if_data *sdata,
2918 const u8 *src, const u8 *dst,
2919- u32 ratemask,
2920+ const u8 *bssid, u32 ratemask,
2921 struct ieee80211_channel *chan,
2922 const u8 *ssid, size_t ssid_len,
2923 const u8 *ie, size_t ie_len,
2924diff --git a/net/mac80211/main.c b/net/mac80211/main.c
2925index e470b33..e6f291e 100644
2926--- a/net/mac80211/main.c
2927+++ b/net/mac80211/main.c
2928@@ -422,7 +422,20 @@ ieee80211_default_mgmt_stypes[NUM_NL80211_IFTYPES] = {
2929 },
2930 [NL80211_IFTYPE_STATION] = {
2931 .tx = 0xffff,
2932+ /*
2933+ * To support Pre Association Security Negotiation (PASN) while
2934+ * already associated to one AP, allow user space to register to
2935+ * Rx authentication frames, so that the user space logic would
2936+ * be able to receive/handle authentication frames from a
2937+ * different AP as part of PASN.
2938+ * It is expected that user space would intelligently register
2939+ * for Rx authentication frames, i.e., only when PASN is used
2940+ * and configure a match filter only for PASN authentication
2941+ * algorithm, as otherwise the MLME functionality of mac80211
2942+ * would be broken.
2943+ */
2944 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
2945+ BIT(IEEE80211_STYPE_AUTH >> 4) |
2946 BIT(IEEE80211_STYPE_PROBE_REQ >> 4),
2947 },
2948 [NL80211_IFTYPE_AP] = {
2949diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
2950index 7791e4d..b929cb4 100644
2951--- a/net/mac80211/mlme.c
2952+++ b/net/mac80211/mlme.c
2953@@ -2480,8 +2480,8 @@ void ieee80211_mlme_send_probe_req(struct ieee80211_sub_if_data *sdata,
2954 {
2955 struct sk_buff *skb;
2956
2957- skb = ieee80211_build_probe_req(sdata, src, dst, (u32)-1, channel,
2958- ssid, ssid_len, NULL, 0,
2959+ skb = ieee80211_build_probe_req(sdata, src, dst, dst, (u32)-1,
2960+ channel, ssid, ssid_len, NULL, 0,
2961 IEEE80211_PROBE_FLAG_DIRECTED);
2962 if (skb)
2963 ieee80211_tx_skb(sdata, skb);
2964@@ -2635,7 +2635,7 @@ struct sk_buff *ieee80211_ap_probereq_get(struct ieee80211_hw *hw,
2965 ssid_len = ssid[1];
2966
2967 skb = ieee80211_build_probe_req(sdata, sdata->vif.addr, cbss->bssid,
2968- (u32) -1, cbss->channel,
2969+ cbss->bssid, (u32)-1, cbss->channel,
2970 ssid + 2, ssid_len,
2971 NULL, 0, IEEE80211_PROBE_FLAG_DIRECTED);
2972 rcu_read_unlock();
2973@@ -5308,7 +5308,7 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
2974 ifmgd->flags |= IEEE80211_STA_DISABLE_VHT;
2975 ifmgd->flags |= IEEE80211_STA_DISABLE_HE;
2976 netdev_info(sdata->dev,
2977- "disabling HE/HT/VHT due to WEP/TKIP use\n");
2978+ "disabling HT/VHT/HE due to WEP/TKIP use\n");
2979 }
2980 }
2981
2982diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
2983index 565bc1e..57ba759 100644
2984--- a/net/mac80211/scan.c
2985+++ b/net/mac80211/scan.c
2986@@ -565,9 +565,8 @@ static void ieee80211_send_scan_probe_req(struct ieee80211_sub_if_data *sdata,
2987 struct sk_buff *skb;
2988 u32 txdata_flags = 0;
2989
2990- skb = ieee80211_build_probe_req(sdata, src, dst, ratemask, channel,
2991- ssid, ssid_len,
2992- ie, ie_len, flags);
2993+ skb = ieee80211_build_probe_req(sdata, src, dst, dst, ratemask, channel,
2994+ ssid, ssid_len, ie, ie_len, flags);
2995
2996 if (skb) {
2997 if (flags & IEEE80211_PROBE_FLAG_RANDOM_SN) {
2998diff --git a/net/mac80211/util.c b/net/mac80211/util.c
2999index c8f6405..2a4515c 100644
3000--- a/net/mac80211/util.c
3001+++ b/net/mac80211/util.c
3002@@ -1857,7 +1857,7 @@ int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer,
3003
3004 struct sk_buff *ieee80211_build_probe_req(struct ieee80211_sub_if_data *sdata,
3005 const u8 *src, const u8 *dst,
3006- u32 ratemask,
3007+ const u8 *bssid, u32 ratemask,
3008 struct ieee80211_channel *chan,
3009 const u8 *ssid, size_t ssid_len,
3010 const u8 *ie, size_t ie_len,
3011@@ -1894,11 +1894,12 @@ struct sk_buff *ieee80211_build_probe_req(struct ieee80211_sub_if_data *sdata,
3012 rate_masks, &chandef, flags);
3013 skb_put(skb, ies_len);
3014
3015- if (dst) {
3016- mgmt = (struct ieee80211_mgmt *) skb->data;
3017+ mgmt = (void *)skb->data;
3018+ if (dst)
3019 memcpy(mgmt->da, dst, ETH_ALEN);
3020- memcpy(mgmt->bssid, dst, ETH_ALEN);
3021- }
3022+
3023+ if (bssid)
3024+ memcpy(mgmt->bssid, bssid, ETH_ALEN);
3025
3026 IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT;
3027
3028diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
3029index a3547aa..98b8f96 100644
3030--- a/net/wireless/nl80211.c
3031+++ b/net/wireless/nl80211.c
3032@@ -248,15 +248,13 @@ nl80211_pmsr_ftm_req_attr_policy[NL80211_PMSR_FTM_REQ_ATTR_MAX + 1] = {
3033 static const struct nla_policy
3034 nl80211_pmsr_req_data_policy[NL80211_PMSR_TYPE_MAX + 1] = {
3035 [NL80211_PMSR_TYPE_FTM] =
3036- NLA_POLICY_NESTED(NL80211_PMSR_FTM_REQ_ATTR_MAX,
3037- nl80211_pmsr_ftm_req_attr_policy),
3038+ NLA_POLICY_NESTED(nl80211_pmsr_ftm_req_attr_policy),
3039 };
3040
3041 static const struct nla_policy
3042 nl80211_pmsr_req_attr_policy[NL80211_PMSR_REQ_ATTR_MAX + 1] = {
3043 [NL80211_PMSR_REQ_ATTR_DATA] =
3044- NLA_POLICY_NESTED(NL80211_PMSR_TYPE_MAX,
3045- nl80211_pmsr_req_data_policy),
3046+ NLA_POLICY_NESTED(nl80211_pmsr_req_data_policy),
3047 [NL80211_PMSR_REQ_ATTR_GET_AP_TSF] = { .type = NLA_FLAG },
3048 };
3049
3050@@ -269,8 +267,7 @@ nl80211_psmr_peer_attr_policy[NL80211_PMSR_PEER_ATTR_MAX + 1] = {
3051 */
3052 [NL80211_PMSR_PEER_ATTR_CHAN] = { .type = NLA_NESTED },
3053 [NL80211_PMSR_PEER_ATTR_REQ] =
3054- NLA_POLICY_NESTED(NL80211_PMSR_REQ_ATTR_MAX,
3055- nl80211_pmsr_req_attr_policy),
3056+ NLA_POLICY_NESTED(nl80211_pmsr_req_attr_policy),
3057 [NL80211_PMSR_PEER_ATTR_RESP] = { .type = NLA_REJECT },
3058 };
3059
3060@@ -281,8 +278,7 @@ nl80211_pmsr_attr_policy[NL80211_PMSR_ATTR_MAX + 1] = {
3061 [NL80211_PMSR_ATTR_RANDOMIZE_MAC_ADDR] = { .type = NLA_REJECT },
3062 [NL80211_PMSR_ATTR_TYPE_CAPA] = { .type = NLA_REJECT },
3063 [NL80211_PMSR_ATTR_PEERS] =
3064- NLA_POLICY_NESTED_ARRAY(NL80211_PMSR_PEER_ATTR_MAX,
3065- nl80211_psmr_peer_attr_policy),
3066+ NLA_POLICY_NESTED_ARRAY(nl80211_psmr_peer_attr_policy),
3067 };
3068
3069 const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
3070@@ -543,8 +539,7 @@ const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
3071 },
3072 [NL80211_ATTR_TIMEOUT] = NLA_POLICY_MIN(NLA_U32, 1),
3073 [NL80211_ATTR_PEER_MEASUREMENTS] =
3074- NLA_POLICY_NESTED(NL80211_PMSR_FTM_REQ_ATTR_MAX,
3075- nl80211_pmsr_attr_policy),
3076+ NLA_POLICY_NESTED(nl80211_pmsr_attr_policy),
3077
3078 [NL80211_ATTR_NAN_CDW_2G] = { .type = NLA_U8 },
3079 [NL80211_ATTR_NAN_CDW_5G] = { .type = NLA_U8 },
3080@@ -13645,66 +13640,90 @@ static void nl80211_post_doit(__genl_const struct genl_ops *ops,
3081 static __genl_const struct genl_ops nl80211_ops[] = {
3082 {
3083 .cmd = NL80211_CMD_GET_WIPHY,
3084+#if LINUX_VERSION_IS_GEQ(5,2,0)
3085+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
3086+#endif
3087+
3088 .doit = nl80211_get_wiphy,
3089 .dumpit = nl80211_dump_wiphy,
3090 .done = nl80211_dump_wiphy_done,
3091- .policy = nl80211_policy,
3092 /* can be retrieved by unprivileged users */
3093 .internal_flags = NL80211_FLAG_NEED_WIPHY |
3094 NL80211_FLAG_NEED_RTNL,
3095 },
3096 {
3097 .cmd = NL80211_CMD_SET_WIPHY,
3098+#if LINUX_VERSION_IS_GEQ(5,2,0)
3099+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
3100+#endif
3101+
3102 .doit = nl80211_set_wiphy,
3103- .policy = nl80211_policy,
3104 .flags = GENL_UNS_ADMIN_PERM,
3105 .internal_flags = NL80211_FLAG_NEED_RTNL,
3106 },
3107 {
3108 .cmd = NL80211_CMD_GET_INTERFACE,
3109+#if LINUX_VERSION_IS_GEQ(5,2,0)
3110+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
3111+#endif
3112+
3113 .doit = nl80211_get_interface,
3114 .dumpit = nl80211_dump_interface,
3115- .policy = nl80211_policy,
3116 /* can be retrieved by unprivileged users */
3117 .internal_flags = NL80211_FLAG_NEED_WDEV |
3118 NL80211_FLAG_NEED_RTNL,
3119 },
3120 {
3121 .cmd = NL80211_CMD_SET_INTERFACE,
3122+#if LINUX_VERSION_IS_GEQ(5,2,0)
3123+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
3124+#endif
3125+
3126 .doit = nl80211_set_interface,
3127- .policy = nl80211_policy,
3128 .flags = GENL_UNS_ADMIN_PERM,
3129 .internal_flags = NL80211_FLAG_NEED_NETDEV |
3130 NL80211_FLAG_NEED_RTNL,
3131 },
3132 {
3133 .cmd = NL80211_CMD_NEW_INTERFACE,
3134+#if LINUX_VERSION_IS_GEQ(5,2,0)
3135+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
3136+#endif
3137+
3138 .doit = nl80211_new_interface,
3139- .policy = nl80211_policy,
3140 .flags = GENL_UNS_ADMIN_PERM,
3141 .internal_flags = NL80211_FLAG_NEED_WIPHY |
3142 NL80211_FLAG_NEED_RTNL,
3143 },
3144 {
3145 .cmd = NL80211_CMD_DEL_INTERFACE,
3146+#if LINUX_VERSION_IS_GEQ(5,2,0)
3147+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
3148+#endif
3149+
3150 .doit = nl80211_del_interface,
3151- .policy = nl80211_policy,
3152 .flags = GENL_UNS_ADMIN_PERM,
3153 .internal_flags = NL80211_FLAG_NEED_WDEV |
3154 NL80211_FLAG_NEED_RTNL,
3155 },
3156 {
3157 .cmd = NL80211_CMD_GET_KEY,
3158+#if LINUX_VERSION_IS_GEQ(5,2,0)
3159+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
3160+#endif
3161+
3162 .doit = nl80211_get_key,
3163- .policy = nl80211_policy,
3164 .flags = GENL_UNS_ADMIN_PERM,
3165 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
3166 NL80211_FLAG_NEED_RTNL,
3167 },
3168 {
3169 .cmd = NL80211_CMD_SET_KEY,
3170+#if LINUX_VERSION_IS_GEQ(5,2,0)
3171+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
3172+#endif
3173+
3174 .doit = nl80211_set_key,
3175- .policy = nl80211_policy,
3176 .flags = GENL_UNS_ADMIN_PERM,
3177 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
3178 NL80211_FLAG_NEED_RTNL |
3179@@ -13712,8 +13731,11 @@ static __genl_const struct genl_ops nl80211_ops[] = {
3180 },
3181 {
3182 .cmd = NL80211_CMD_NEW_KEY,
3183+#if LINUX_VERSION_IS_GEQ(5,2,0)
3184+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
3185+#endif
3186+
3187 .doit = nl80211_new_key,
3188- .policy = nl80211_policy,
3189 .flags = GENL_UNS_ADMIN_PERM,
3190 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
3191 NL80211_FLAG_NEED_RTNL |
3192@@ -13721,15 +13743,21 @@ static __genl_const struct genl_ops nl80211_ops[] = {
3193 },
3194 {
3195 .cmd = NL80211_CMD_DEL_KEY,
3196+#if LINUX_VERSION_IS_GEQ(5,2,0)
3197+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
3198+#endif
3199+
3200 .doit = nl80211_del_key,
3201- .policy = nl80211_policy,
3202 .flags = GENL_UNS_ADMIN_PERM,
3203 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
3204 NL80211_FLAG_NEED_RTNL,
3205 },
3206 {
3207 .cmd = NL80211_CMD_SET_BEACON,
3208- .policy = nl80211_policy,
3209+#if LINUX_VERSION_IS_GEQ(5,2,0)
3210+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
3211+#endif
3212+
3213 .flags = GENL_UNS_ADMIN_PERM,
3214 .doit = nl80211_set_beacon,
3215 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
3216@@ -13737,7 +13765,10 @@ static __genl_const struct genl_ops nl80211_ops[] = {
3217 },
3218 {
3219 .cmd = NL80211_CMD_START_AP,
3220- .policy = nl80211_policy,
3221+#if LINUX_VERSION_IS_GEQ(5,2,0)
3222+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
3223+#endif
3224+
3225 .flags = GENL_UNS_ADMIN_PERM,
3226 .doit = nl80211_start_ap,
3227 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
3228@@ -13745,7 +13776,10 @@ static __genl_const struct genl_ops nl80211_ops[] = {
3229 },
3230 {
3231 .cmd = NL80211_CMD_STOP_AP,
3232- .policy = nl80211_policy,
3233+#if LINUX_VERSION_IS_GEQ(5,2,0)
3234+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
3235+#endif
3236+
3237 .flags = GENL_UNS_ADMIN_PERM,
3238 .doit = nl80211_stop_ap,
3239 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
3240@@ -13753,172 +13787,238 @@ static __genl_const struct genl_ops nl80211_ops[] = {
3241 },
3242 {
3243 .cmd = NL80211_CMD_GET_STATION,
3244+#if LINUX_VERSION_IS_GEQ(5,2,0)
3245+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
3246+#endif
3247+
3248 .doit = nl80211_get_station,
3249 .dumpit = nl80211_dump_station,
3250- .policy = nl80211_policy,
3251 .internal_flags = NL80211_FLAG_NEED_NETDEV |
3252 NL80211_FLAG_NEED_RTNL,
3253 },
3254 {
3255 .cmd = NL80211_CMD_SET_STATION,
3256+#if LINUX_VERSION_IS_GEQ(5,2,0)
3257+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
3258+#endif
3259+
3260 .doit = nl80211_set_station,
3261- .policy = nl80211_policy,
3262 .flags = GENL_UNS_ADMIN_PERM,
3263 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
3264 NL80211_FLAG_NEED_RTNL,
3265 },
3266 {
3267 .cmd = NL80211_CMD_NEW_STATION,
3268+#if LINUX_VERSION_IS_GEQ(5,2,0)
3269+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
3270+#endif
3271+
3272 .doit = nl80211_new_station,
3273- .policy = nl80211_policy,
3274 .flags = GENL_UNS_ADMIN_PERM,
3275 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
3276 NL80211_FLAG_NEED_RTNL,
3277 },
3278 {
3279 .cmd = NL80211_CMD_DEL_STATION,
3280+#if LINUX_VERSION_IS_GEQ(5,2,0)
3281+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
3282+#endif
3283+
3284 .doit = nl80211_del_station,
3285- .policy = nl80211_policy,
3286 .flags = GENL_UNS_ADMIN_PERM,
3287 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
3288 NL80211_FLAG_NEED_RTNL,
3289 },
3290 {
3291 .cmd = NL80211_CMD_GET_MPATH,
3292+#if LINUX_VERSION_IS_GEQ(5,2,0)
3293+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
3294+#endif
3295+
3296 .doit = nl80211_get_mpath,
3297 .dumpit = nl80211_dump_mpath,
3298- .policy = nl80211_policy,
3299 .flags = GENL_UNS_ADMIN_PERM,
3300 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
3301 NL80211_FLAG_NEED_RTNL,
3302 },
3303 {
3304 .cmd = NL80211_CMD_GET_MPP,
3305+#if LINUX_VERSION_IS_GEQ(5,2,0)
3306+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
3307+#endif
3308+
3309 .doit = nl80211_get_mpp,
3310 .dumpit = nl80211_dump_mpp,
3311- .policy = nl80211_policy,
3312 .flags = GENL_UNS_ADMIN_PERM,
3313 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
3314 NL80211_FLAG_NEED_RTNL,
3315 },
3316 {
3317 .cmd = NL80211_CMD_SET_MPATH,
3318+#if LINUX_VERSION_IS_GEQ(5,2,0)
3319+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
3320+#endif
3321+
3322 .doit = nl80211_set_mpath,
3323- .policy = nl80211_policy,
3324 .flags = GENL_UNS_ADMIN_PERM,
3325 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
3326 NL80211_FLAG_NEED_RTNL,
3327 },
3328 {
3329 .cmd = NL80211_CMD_NEW_MPATH,
3330+#if LINUX_VERSION_IS_GEQ(5,2,0)
3331+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
3332+#endif
3333+
3334 .doit = nl80211_new_mpath,
3335- .policy = nl80211_policy,
3336 .flags = GENL_UNS_ADMIN_PERM,
3337 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
3338 NL80211_FLAG_NEED_RTNL,
3339 },
3340 {
3341 .cmd = NL80211_CMD_DEL_MPATH,
3342+#if LINUX_VERSION_IS_GEQ(5,2,0)
3343+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
3344+#endif
3345+
3346 .doit = nl80211_del_mpath,
3347- .policy = nl80211_policy,
3348 .flags = GENL_UNS_ADMIN_PERM,
3349 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
3350 NL80211_FLAG_NEED_RTNL,
3351 },
3352 {
3353 .cmd = NL80211_CMD_SET_BSS,
3354+#if LINUX_VERSION_IS_GEQ(5,2,0)
3355+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
3356+#endif
3357+
3358 .doit = nl80211_set_bss,
3359- .policy = nl80211_policy,
3360 .flags = GENL_UNS_ADMIN_PERM,
3361 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
3362 NL80211_FLAG_NEED_RTNL,
3363 },
3364 {
3365 .cmd = NL80211_CMD_GET_REG,
3366+#if LINUX_VERSION_IS_GEQ(5,2,0)
3367+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
3368+#endif
3369+
3370 .doit = nl80211_get_reg_do,
3371 .dumpit = nl80211_get_reg_dump,
3372- .policy = nl80211_policy,
3373 .internal_flags = NL80211_FLAG_NEED_RTNL,
3374 /* can be retrieved by unprivileged users */
3375 },
3376 #ifdef CPTCFG_CFG80211_CRDA_SUPPORT
3377 {
3378 .cmd = NL80211_CMD_SET_REG,
3379+#if LINUX_VERSION_IS_GEQ(5,2,0)
3380+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
3381+#endif
3382+
3383 .doit = nl80211_set_reg,
3384- .policy = nl80211_policy,
3385 .flags = GENL_ADMIN_PERM,
3386 .internal_flags = NL80211_FLAG_NEED_RTNL,
3387 },
3388 #endif
3389 {
3390 .cmd = NL80211_CMD_REQ_SET_REG,
3391+#if LINUX_VERSION_IS_GEQ(5,2,0)
3392+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
3393+#endif
3394+
3395 .doit = nl80211_req_set_reg,
3396- .policy = nl80211_policy,
3397 .flags = GENL_ADMIN_PERM,
3398 },
3399 {
3400 .cmd = NL80211_CMD_RELOAD_REGDB,
3401+#if LINUX_VERSION_IS_GEQ(5,2,0)
3402+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
3403+#endif
3404+
3405 .doit = nl80211_reload_regdb,
3406- .policy = nl80211_policy,
3407 .flags = GENL_ADMIN_PERM,
3408 },
3409 {
3410 .cmd = NL80211_CMD_GET_MESH_CONFIG,
3411+#if LINUX_VERSION_IS_GEQ(5,2,0)
3412+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
3413+#endif
3414+
3415 .doit = nl80211_get_mesh_config,
3416- .policy = nl80211_policy,
3417 /* can be retrieved by unprivileged users */
3418 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
3419 NL80211_FLAG_NEED_RTNL,
3420 },
3421 {
3422 .cmd = NL80211_CMD_SET_MESH_CONFIG,
3423+#if LINUX_VERSION_IS_GEQ(5,2,0)
3424+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
3425+#endif
3426+
3427 .doit = nl80211_update_mesh_config,
3428- .policy = nl80211_policy,
3429 .flags = GENL_UNS_ADMIN_PERM,
3430 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
3431 NL80211_FLAG_NEED_RTNL,
3432 },
3433 {
3434 .cmd = NL80211_CMD_TRIGGER_SCAN,
3435+#if LINUX_VERSION_IS_GEQ(5,2,0)
3436+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
3437+#endif
3438+
3439 .doit = nl80211_trigger_scan,
3440- .policy = nl80211_policy,
3441 .flags = GENL_UNS_ADMIN_PERM,
3442 .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
3443 NL80211_FLAG_NEED_RTNL,
3444 },
3445 {
3446 .cmd = NL80211_CMD_ABORT_SCAN,
3447+#if LINUX_VERSION_IS_GEQ(5,2,0)
3448+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
3449+#endif
3450+
3451 .doit = nl80211_abort_scan,
3452- .policy = nl80211_policy,
3453 .flags = GENL_UNS_ADMIN_PERM,
3454 .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
3455 NL80211_FLAG_NEED_RTNL,
3456 },
3457 {
3458 .cmd = NL80211_CMD_GET_SCAN,
3459- .policy = nl80211_policy,
3460+#if LINUX_VERSION_IS_GEQ(5,2,0)
3461+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
3462+#endif
3463+
3464 .dumpit = nl80211_dump_scan,
3465 },
3466 {
3467 .cmd = NL80211_CMD_START_SCHED_SCAN,
3468+#if LINUX_VERSION_IS_GEQ(5,2,0)
3469+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
3470+#endif
3471+
3472 .doit = nl80211_start_sched_scan,
3473- .policy = nl80211_policy,
3474 .flags = GENL_UNS_ADMIN_PERM,
3475 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
3476 NL80211_FLAG_NEED_RTNL,
3477 },
3478 {
3479 .cmd = NL80211_CMD_STOP_SCHED_SCAN,
3480+#if LINUX_VERSION_IS_GEQ(5,2,0)
3481+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
3482+#endif
3483+
3484 .doit = nl80211_stop_sched_scan,
3485- .policy = nl80211_policy,
3486 .flags = GENL_UNS_ADMIN_PERM,
3487 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
3488 NL80211_FLAG_NEED_RTNL,
3489 },
3490 {
3491 .cmd = NL80211_CMD_AUTHENTICATE,
3492+#if LINUX_VERSION_IS_GEQ(5,2,0)
3493+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
3494+#endif
3495+
3496 .doit = nl80211_authenticate,
3497- .policy = nl80211_policy,
3498 .flags = GENL_UNS_ADMIN_PERM,
3499 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
3500 NL80211_FLAG_NEED_RTNL |
3501@@ -13926,40 +14026,55 @@ static __genl_const struct genl_ops nl80211_ops[] = {
3502 },
3503 {
3504 .cmd = NL80211_CMD_ASSOCIATE,
3505+#if LINUX_VERSION_IS_GEQ(5,2,0)
3506+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
3507+#endif
3508+
3509 .doit = nl80211_associate,
3510- .policy = nl80211_policy,
3511 .flags = GENL_UNS_ADMIN_PERM,
3512 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
3513 NL80211_FLAG_NEED_RTNL,
3514 },
3515 {
3516 .cmd = NL80211_CMD_DEAUTHENTICATE,
3517+#if LINUX_VERSION_IS_GEQ(5,2,0)
3518+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
3519+#endif
3520+
3521 .doit = nl80211_deauthenticate,
3522- .policy = nl80211_policy,
3523 .flags = GENL_UNS_ADMIN_PERM,
3524 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
3525 NL80211_FLAG_NEED_RTNL,
3526 },
3527 {
3528 .cmd = NL80211_CMD_DISASSOCIATE,
3529+#if LINUX_VERSION_IS_GEQ(5,2,0)
3530+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
3531+#endif
3532+
3533 .doit = nl80211_disassociate,
3534- .policy = nl80211_policy,
3535 .flags = GENL_UNS_ADMIN_PERM,
3536 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
3537 NL80211_FLAG_NEED_RTNL,
3538 },
3539 {
3540 .cmd = NL80211_CMD_JOIN_IBSS,
3541+#if LINUX_VERSION_IS_GEQ(5,2,0)
3542+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
3543+#endif
3544+
3545 .doit = nl80211_join_ibss,
3546- .policy = nl80211_policy,
3547 .flags = GENL_UNS_ADMIN_PERM,
3548 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
3549 NL80211_FLAG_NEED_RTNL,
3550 },
3551 {
3552 .cmd = NL80211_CMD_LEAVE_IBSS,
3553+#if LINUX_VERSION_IS_GEQ(5,2,0)
3554+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
3555+#endif
3556+
3557 .doit = nl80211_leave_ibss,
3558- .policy = nl80211_policy,
3559 .flags = GENL_UNS_ADMIN_PERM,
3560 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
3561 NL80211_FLAG_NEED_RTNL,
3562@@ -13967,9 +14082,12 @@ static __genl_const struct genl_ops nl80211_ops[] = {
3563 #ifdef CPTCFG_NL80211_TESTMODE
3564 {
3565 .cmd = NL80211_CMD_TESTMODE,
3566+#if LINUX_VERSION_IS_GEQ(5,2,0)
3567+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
3568+#endif
3569+
3570 .doit = nl80211_testmode_do,
3571 .dumpit = nl80211_testmode_dump,
3572- .policy = nl80211_policy,
3573 .flags = GENL_UNS_ADMIN_PERM,
3574 .internal_flags = NL80211_FLAG_NEED_WIPHY |
3575 NL80211_FLAG_NEED_RTNL,
3576@@ -13977,181 +14095,250 @@ static __genl_const struct genl_ops nl80211_ops[] = {
3577 #endif
3578 {
3579 .cmd = NL80211_CMD_CONNECT,
3580+#if LINUX_VERSION_IS_GEQ(5,2,0)
3581+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
3582+#endif
3583+
3584 .doit = nl80211_connect,
3585- .policy = nl80211_policy,
3586 .flags = GENL_UNS_ADMIN_PERM,
3587 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
3588 NL80211_FLAG_NEED_RTNL,
3589 },
3590 {
3591 .cmd = NL80211_CMD_UPDATE_CONNECT_PARAMS,
3592+#if LINUX_VERSION_IS_GEQ(5,2,0)
3593+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
3594+#endif
3595+
3596 .doit = nl80211_update_connect_params,
3597- .policy = nl80211_policy,
3598 .flags = GENL_ADMIN_PERM,
3599 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
3600 NL80211_FLAG_NEED_RTNL,
3601 },
3602 {
3603 .cmd = NL80211_CMD_DISCONNECT,
3604+#if LINUX_VERSION_IS_GEQ(5,2,0)
3605+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
3606+#endif
3607+
3608 .doit = nl80211_disconnect,
3609- .policy = nl80211_policy,
3610 .flags = GENL_UNS_ADMIN_PERM,
3611 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
3612 NL80211_FLAG_NEED_RTNL,
3613 },
3614 {
3615 .cmd = NL80211_CMD_SET_WIPHY_NETNS,
3616+#if LINUX_VERSION_IS_GEQ(5,2,0)
3617+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
3618+#endif
3619+
3620 .doit = nl80211_wiphy_netns,
3621- .policy = nl80211_policy,
3622 .flags = GENL_UNS_ADMIN_PERM,
3623 .internal_flags = NL80211_FLAG_NEED_WIPHY |
3624 NL80211_FLAG_NEED_RTNL,
3625 },
3626 {
3627 .cmd = NL80211_CMD_GET_SURVEY,
3628- .policy = nl80211_policy,
3629+#if LINUX_VERSION_IS_GEQ(5,2,0)
3630+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
3631+#endif
3632+
3633 .dumpit = nl80211_dump_survey,
3634 },
3635 {
3636 .cmd = NL80211_CMD_SET_PMKSA,
3637+#if LINUX_VERSION_IS_GEQ(5,2,0)
3638+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
3639+#endif
3640+
3641 .doit = nl80211_setdel_pmksa,
3642- .policy = nl80211_policy,
3643 .flags = GENL_UNS_ADMIN_PERM,
3644 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
3645 NL80211_FLAG_NEED_RTNL,
3646 },
3647 {
3648 .cmd = NL80211_CMD_DEL_PMKSA,
3649+#if LINUX_VERSION_IS_GEQ(5,2,0)
3650+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
3651+#endif
3652+
3653 .doit = nl80211_setdel_pmksa,
3654- .policy = nl80211_policy,
3655 .flags = GENL_UNS_ADMIN_PERM,
3656 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
3657 NL80211_FLAG_NEED_RTNL,
3658 },
3659 {
3660 .cmd = NL80211_CMD_FLUSH_PMKSA,
3661+#if LINUX_VERSION_IS_GEQ(5,2,0)
3662+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
3663+#endif
3664+
3665 .doit = nl80211_flush_pmksa,
3666- .policy = nl80211_policy,
3667 .flags = GENL_UNS_ADMIN_PERM,
3668 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
3669 NL80211_FLAG_NEED_RTNL,
3670 },
3671 {
3672 .cmd = NL80211_CMD_REMAIN_ON_CHANNEL,
3673+#if LINUX_VERSION_IS_GEQ(5,2,0)
3674+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
3675+#endif
3676+
3677 .doit = nl80211_remain_on_channel,
3678- .policy = nl80211_policy,
3679 .flags = GENL_UNS_ADMIN_PERM,
3680 .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
3681 NL80211_FLAG_NEED_RTNL,
3682 },
3683 {
3684 .cmd = NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL,
3685+#if LINUX_VERSION_IS_GEQ(5,2,0)
3686+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
3687+#endif
3688+
3689 .doit = nl80211_cancel_remain_on_channel,
3690- .policy = nl80211_policy,
3691 .flags = GENL_UNS_ADMIN_PERM,
3692 .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
3693 NL80211_FLAG_NEED_RTNL,
3694 },
3695 {
3696 .cmd = NL80211_CMD_SET_TX_BITRATE_MASK,
3697+#if LINUX_VERSION_IS_GEQ(5,2,0)
3698+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
3699+#endif
3700+
3701 .doit = nl80211_set_tx_bitrate_mask,
3702- .policy = nl80211_policy,
3703 .flags = GENL_UNS_ADMIN_PERM,
3704 .internal_flags = NL80211_FLAG_NEED_NETDEV |
3705 NL80211_FLAG_NEED_RTNL,
3706 },
3707 {
3708 .cmd = NL80211_CMD_REGISTER_FRAME,
3709+#if LINUX_VERSION_IS_GEQ(5,2,0)
3710+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
3711+#endif
3712+
3713 .doit = nl80211_register_mgmt,
3714- .policy = nl80211_policy,
3715 .flags = GENL_UNS_ADMIN_PERM,
3716 .internal_flags = NL80211_FLAG_NEED_WDEV |
3717 NL80211_FLAG_NEED_RTNL,
3718 },
3719 {
3720 .cmd = NL80211_CMD_FRAME,
3721+#if LINUX_VERSION_IS_GEQ(5,2,0)
3722+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
3723+#endif
3724+
3725 .doit = nl80211_tx_mgmt,
3726- .policy = nl80211_policy,
3727 .flags = GENL_UNS_ADMIN_PERM,
3728 .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
3729 NL80211_FLAG_NEED_RTNL,
3730 },
3731 {
3732 .cmd = NL80211_CMD_FRAME_WAIT_CANCEL,
3733+#if LINUX_VERSION_IS_GEQ(5,2,0)
3734+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
3735+#endif
3736+
3737 .doit = nl80211_tx_mgmt_cancel_wait,
3738- .policy = nl80211_policy,
3739 .flags = GENL_UNS_ADMIN_PERM,
3740 .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
3741 NL80211_FLAG_NEED_RTNL,
3742 },
3743 {
3744 .cmd = NL80211_CMD_SET_POWER_SAVE,
3745+#if LINUX_VERSION_IS_GEQ(5,2,0)
3746+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
3747+#endif
3748+
3749 .doit = nl80211_set_power_save,
3750- .policy = nl80211_policy,
3751 .flags = GENL_UNS_ADMIN_PERM,
3752 .internal_flags = NL80211_FLAG_NEED_NETDEV |
3753 NL80211_FLAG_NEED_RTNL,
3754 },
3755 {
3756 .cmd = NL80211_CMD_GET_POWER_SAVE,
3757+#if LINUX_VERSION_IS_GEQ(5,2,0)
3758+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
3759+#endif
3760+
3761 .doit = nl80211_get_power_save,
3762- .policy = nl80211_policy,
3763 /* can be retrieved by unprivileged users */
3764 .internal_flags = NL80211_FLAG_NEED_NETDEV |
3765 NL80211_FLAG_NEED_RTNL,
3766 },
3767 {
3768 .cmd = NL80211_CMD_SET_CQM,
3769+#if LINUX_VERSION_IS_GEQ(5,2,0)
3770+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
3771+#endif
3772+
3773 .doit = nl80211_set_cqm,
3774- .policy = nl80211_policy,
3775 .flags = GENL_UNS_ADMIN_PERM,
3776 .internal_flags = NL80211_FLAG_NEED_NETDEV |
3777 NL80211_FLAG_NEED_RTNL,
3778 },
3779 {
3780 .cmd = NL80211_CMD_SET_CHANNEL,
3781+#if LINUX_VERSION_IS_GEQ(5,2,0)
3782+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
3783+#endif
3784+
3785 .doit = nl80211_set_channel,
3786- .policy = nl80211_policy,
3787 .flags = GENL_UNS_ADMIN_PERM,
3788 .internal_flags = NL80211_FLAG_NEED_NETDEV |
3789 NL80211_FLAG_NEED_RTNL,
3790 },
3791 {
3792 .cmd = NL80211_CMD_SET_WDS_PEER,
3793+#if LINUX_VERSION_IS_GEQ(5,2,0)
3794+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
3795+#endif
3796+
3797 .doit = nl80211_set_wds_peer,
3798- .policy = nl80211_policy,
3799 .flags = GENL_UNS_ADMIN_PERM,
3800 .internal_flags = NL80211_FLAG_NEED_NETDEV |
3801 NL80211_FLAG_NEED_RTNL,
3802 },
3803 {
3804 .cmd = NL80211_CMD_JOIN_MESH,
3805+#if LINUX_VERSION_IS_GEQ(5,2,0)
3806+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
3807+#endif
3808+
3809 .doit = nl80211_join_mesh,
3810- .policy = nl80211_policy,
3811 .flags = GENL_UNS_ADMIN_PERM,
3812 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
3813 NL80211_FLAG_NEED_RTNL,
3814 },
3815 {
3816 .cmd = NL80211_CMD_LEAVE_MESH,
3817+#if LINUX_VERSION_IS_GEQ(5,2,0)
3818+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
3819+#endif
3820+
3821 .doit = nl80211_leave_mesh,
3822- .policy = nl80211_policy,
3823 .flags = GENL_UNS_ADMIN_PERM,
3824 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
3825 NL80211_FLAG_NEED_RTNL,
3826 },
3827 {
3828 .cmd = NL80211_CMD_JOIN_OCB,
3829+#if LINUX_VERSION_IS_GEQ(5,2,0)
3830+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
3831+#endif
3832+
3833 .doit = nl80211_join_ocb,
3834- .policy = nl80211_policy,
3835 .flags = GENL_UNS_ADMIN_PERM,
3836 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
3837 NL80211_FLAG_NEED_RTNL,
3838 },
3839 {
3840 .cmd = NL80211_CMD_LEAVE_OCB,
3841+#if LINUX_VERSION_IS_GEQ(5,2,0)
3842+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
3843+#endif
3844+
3845 .doit = nl80211_leave_ocb,
3846- .policy = nl80211_policy,
3847 .flags = GENL_UNS_ADMIN_PERM,
3848 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
3849 NL80211_FLAG_NEED_RTNL,
3850@@ -14159,16 +14346,22 @@ static __genl_const struct genl_ops nl80211_ops[] = {
3851 #ifdef CONFIG_PM
3852 {
3853 .cmd = NL80211_CMD_GET_WOWLAN,
3854+#if LINUX_VERSION_IS_GEQ(5,2,0)
3855+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
3856+#endif
3857+
3858 .doit = nl80211_get_wowlan,
3859- .policy = nl80211_policy,
3860 /* can be retrieved by unprivileged users */
3861 .internal_flags = NL80211_FLAG_NEED_WIPHY |
3862 NL80211_FLAG_NEED_RTNL,
3863 },
3864 {
3865 .cmd = NL80211_CMD_SET_WOWLAN,
3866+#if LINUX_VERSION_IS_GEQ(5,2,0)
3867+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
3868+#endif
3869+
3870 .doit = nl80211_set_wowlan,
3871- .policy = nl80211_policy,
3872 .flags = GENL_UNS_ADMIN_PERM,
3873 .internal_flags = NL80211_FLAG_NEED_WIPHY |
3874 NL80211_FLAG_NEED_RTNL,
3875@@ -14176,8 +14369,11 @@ static __genl_const struct genl_ops nl80211_ops[] = {
3876 #endif
3877 {
3878 .cmd = NL80211_CMD_SET_REKEY_OFFLOAD,
3879+#if LINUX_VERSION_IS_GEQ(5,2,0)
3880+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
3881+#endif
3882+
3883 .doit = nl80211_set_rekey_data,
3884- .policy = nl80211_policy,
3885 .flags = GENL_UNS_ADMIN_PERM,
3886 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
3887 NL80211_FLAG_NEED_RTNL |
3888@@ -14185,290 +14381,401 @@ static __genl_const struct genl_ops nl80211_ops[] = {
3889 },
3890 {
3891 .cmd = NL80211_CMD_TDLS_MGMT,
3892+#if LINUX_VERSION_IS_GEQ(5,2,0)
3893+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
3894+#endif
3895+
3896 .doit = nl80211_tdls_mgmt,
3897- .policy = nl80211_policy,
3898 .flags = GENL_UNS_ADMIN_PERM,
3899 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
3900 NL80211_FLAG_NEED_RTNL,
3901 },
3902 {
3903 .cmd = NL80211_CMD_TDLS_OPER,
3904+#if LINUX_VERSION_IS_GEQ(5,2,0)
3905+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
3906+#endif
3907+
3908 .doit = nl80211_tdls_oper,
3909- .policy = nl80211_policy,
3910 .flags = GENL_UNS_ADMIN_PERM,
3911 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
3912 NL80211_FLAG_NEED_RTNL,
3913 },
3914 {
3915 .cmd = NL80211_CMD_UNEXPECTED_FRAME,
3916+#if LINUX_VERSION_IS_GEQ(5,2,0)
3917+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
3918+#endif
3919+
3920 .doit = nl80211_register_unexpected_frame,
3921- .policy = nl80211_policy,
3922 .flags = GENL_UNS_ADMIN_PERM,
3923 .internal_flags = NL80211_FLAG_NEED_NETDEV |
3924 NL80211_FLAG_NEED_RTNL,
3925 },
3926 {
3927 .cmd = NL80211_CMD_PROBE_CLIENT,
3928+#if LINUX_VERSION_IS_GEQ(5,2,0)
3929+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
3930+#endif
3931+
3932 .doit = nl80211_probe_client,
3933- .policy = nl80211_policy,
3934 .flags = GENL_UNS_ADMIN_PERM,
3935 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
3936 NL80211_FLAG_NEED_RTNL,
3937 },
3938 {
3939 .cmd = NL80211_CMD_REGISTER_BEACONS,
3940+#if LINUX_VERSION_IS_GEQ(5,2,0)
3941+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
3942+#endif
3943+
3944 .doit = nl80211_register_beacons,
3945- .policy = nl80211_policy,
3946 .flags = GENL_UNS_ADMIN_PERM,
3947 .internal_flags = NL80211_FLAG_NEED_WIPHY |
3948 NL80211_FLAG_NEED_RTNL,
3949 },
3950 {
3951 .cmd = NL80211_CMD_SET_NOACK_MAP,
3952+#if LINUX_VERSION_IS_GEQ(5,2,0)
3953+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
3954+#endif
3955+
3956 .doit = nl80211_set_noack_map,
3957- .policy = nl80211_policy,
3958 .flags = GENL_UNS_ADMIN_PERM,
3959 .internal_flags = NL80211_FLAG_NEED_NETDEV |
3960 NL80211_FLAG_NEED_RTNL,
3961 },
3962 {
3963 .cmd = NL80211_CMD_START_P2P_DEVICE,
3964+#if LINUX_VERSION_IS_GEQ(5,2,0)
3965+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
3966+#endif
3967+
3968 .doit = nl80211_start_p2p_device,
3969- .policy = nl80211_policy,
3970 .flags = GENL_UNS_ADMIN_PERM,
3971 .internal_flags = NL80211_FLAG_NEED_WDEV |
3972 NL80211_FLAG_NEED_RTNL,
3973 },
3974 {
3975 .cmd = NL80211_CMD_STOP_P2P_DEVICE,
3976+#if LINUX_VERSION_IS_GEQ(5,2,0)
3977+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
3978+#endif
3979+
3980 .doit = nl80211_stop_p2p_device,
3981- .policy = nl80211_policy,
3982 .flags = GENL_UNS_ADMIN_PERM,
3983 .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
3984 NL80211_FLAG_NEED_RTNL,
3985 },
3986 {
3987 .cmd = NL80211_CMD_START_NAN,
3988+#if LINUX_VERSION_IS_GEQ(5,2,0)
3989+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
3990+#endif
3991+
3992 .doit = nl80211_start_nan,
3993- .policy = nl80211_policy,
3994 .flags = GENL_ADMIN_PERM,
3995 .internal_flags = NL80211_FLAG_NEED_WDEV |
3996 NL80211_FLAG_NEED_RTNL,
3997 },
3998 {
3999 .cmd = NL80211_CMD_STOP_NAN,
4000+#if LINUX_VERSION_IS_GEQ(5,2,0)
4001+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
4002+#endif
4003+
4004 .doit = nl80211_stop_nan,
4005- .policy = nl80211_policy,
4006 .flags = GENL_ADMIN_PERM,
4007 .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
4008 NL80211_FLAG_NEED_RTNL,
4009 },
4010 {
4011 .cmd = NL80211_CMD_ADD_NAN_FUNCTION,
4012+#if LINUX_VERSION_IS_GEQ(5,2,0)
4013+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
4014+#endif
4015+
4016 .doit = nl80211_nan_add_func,
4017- .policy = nl80211_policy,
4018 .flags = GENL_ADMIN_PERM,
4019 .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
4020 NL80211_FLAG_NEED_RTNL,
4021 },
4022 {
4023 .cmd = NL80211_CMD_DEL_NAN_FUNCTION,
4024+#if LINUX_VERSION_IS_GEQ(5,2,0)
4025+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
4026+#endif
4027+
4028 .doit = nl80211_nan_del_func,
4029- .policy = nl80211_policy,
4030 .flags = GENL_ADMIN_PERM,
4031 .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
4032 NL80211_FLAG_NEED_RTNL,
4033 },
4034 {
4035 .cmd = NL80211_CMD_CHANGE_NAN_CONFIG,
4036+#if LINUX_VERSION_IS_GEQ(5,2,0)
4037+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
4038+#endif
4039+
4040 .doit = nl80211_nan_change_config,
4041- .policy = nl80211_policy,
4042 .flags = GENL_ADMIN_PERM,
4043 .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
4044 NL80211_FLAG_NEED_RTNL,
4045 },
4046 {
4047 .cmd = NL80211_CMD_SET_MCAST_RATE,
4048+#if LINUX_VERSION_IS_GEQ(5,2,0)
4049+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
4050+#endif
4051+
4052 .doit = nl80211_set_mcast_rate,
4053- .policy = nl80211_policy,
4054 .flags = GENL_UNS_ADMIN_PERM,
4055 .internal_flags = NL80211_FLAG_NEED_NETDEV |
4056 NL80211_FLAG_NEED_RTNL,
4057 },
4058 {
4059 .cmd = NL80211_CMD_SET_MAC_ACL,
4060+#if LINUX_VERSION_IS_GEQ(5,2,0)
4061+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
4062+#endif
4063+
4064 .doit = nl80211_set_mac_acl,
4065- .policy = nl80211_policy,
4066 .flags = GENL_UNS_ADMIN_PERM,
4067 .internal_flags = NL80211_FLAG_NEED_NETDEV |
4068 NL80211_FLAG_NEED_RTNL,
4069 },
4070 {
4071 .cmd = NL80211_CMD_RADAR_DETECT,
4072+#if LINUX_VERSION_IS_GEQ(5,2,0)
4073+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
4074+#endif
4075+
4076 .doit = nl80211_start_radar_detection,
4077- .policy = nl80211_policy,
4078 .flags = GENL_UNS_ADMIN_PERM,
4079 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4080 NL80211_FLAG_NEED_RTNL,
4081 },
4082 {
4083 .cmd = NL80211_CMD_GET_PROTOCOL_FEATURES,
4084+#if LINUX_VERSION_IS_GEQ(5,2,0)
4085+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
4086+#endif
4087+
4088 .doit = nl80211_get_protocol_features,
4089- .policy = nl80211_policy,
4090 },
4091 {
4092 .cmd = NL80211_CMD_UPDATE_FT_IES,
4093+#if LINUX_VERSION_IS_GEQ(5,2,0)
4094+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
4095+#endif
4096+
4097 .doit = nl80211_update_ft_ies,
4098- .policy = nl80211_policy,
4099 .flags = GENL_UNS_ADMIN_PERM,
4100 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4101 NL80211_FLAG_NEED_RTNL,
4102 },
4103 {
4104 .cmd = NL80211_CMD_CRIT_PROTOCOL_START,
4105+#if LINUX_VERSION_IS_GEQ(5,2,0)
4106+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
4107+#endif
4108+
4109 .doit = nl80211_crit_protocol_start,
4110- .policy = nl80211_policy,
4111 .flags = GENL_UNS_ADMIN_PERM,
4112 .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
4113 NL80211_FLAG_NEED_RTNL,
4114 },
4115 {
4116 .cmd = NL80211_CMD_CRIT_PROTOCOL_STOP,
4117+#if LINUX_VERSION_IS_GEQ(5,2,0)
4118+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
4119+#endif
4120+
4121 .doit = nl80211_crit_protocol_stop,
4122- .policy = nl80211_policy,
4123 .flags = GENL_UNS_ADMIN_PERM,
4124 .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
4125 NL80211_FLAG_NEED_RTNL,
4126 },
4127 {
4128 .cmd = NL80211_CMD_GET_COALESCE,
4129+#if LINUX_VERSION_IS_GEQ(5,2,0)
4130+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
4131+#endif
4132+
4133 .doit = nl80211_get_coalesce,
4134- .policy = nl80211_policy,
4135 .internal_flags = NL80211_FLAG_NEED_WIPHY |
4136 NL80211_FLAG_NEED_RTNL,
4137 },
4138 {
4139 .cmd = NL80211_CMD_SET_COALESCE,
4140+#if LINUX_VERSION_IS_GEQ(5,2,0)
4141+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
4142+#endif
4143+
4144 .doit = nl80211_set_coalesce,
4145- .policy = nl80211_policy,
4146 .flags = GENL_UNS_ADMIN_PERM,
4147 .internal_flags = NL80211_FLAG_NEED_WIPHY |
4148 NL80211_FLAG_NEED_RTNL,
4149 },
4150 {
4151 .cmd = NL80211_CMD_CHANNEL_SWITCH,
4152+#if LINUX_VERSION_IS_GEQ(5,2,0)
4153+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
4154+#endif
4155+
4156 .doit = nl80211_channel_switch,
4157- .policy = nl80211_policy,
4158 .flags = GENL_UNS_ADMIN_PERM,
4159 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4160 NL80211_FLAG_NEED_RTNL,
4161 },
4162 {
4163 .cmd = NL80211_CMD_VENDOR,
4164+#if LINUX_VERSION_IS_GEQ(5,2,0)
4165+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
4166+#endif
4167+
4168 .doit = nl80211_vendor_cmd,
4169 .dumpit = nl80211_vendor_cmd_dump,
4170- .policy = nl80211_policy,
4171 .flags = GENL_UNS_ADMIN_PERM,
4172 .internal_flags = NL80211_FLAG_NEED_WIPHY |
4173 NL80211_FLAG_NEED_RTNL,
4174 },
4175 {
4176 .cmd = NL80211_CMD_SET_QOS_MAP,
4177+#if LINUX_VERSION_IS_GEQ(5,2,0)
4178+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
4179+#endif
4180+
4181 .doit = nl80211_set_qos_map,
4182- .policy = nl80211_policy,
4183 .flags = GENL_UNS_ADMIN_PERM,
4184 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4185 NL80211_FLAG_NEED_RTNL,
4186 },
4187 {
4188 .cmd = NL80211_CMD_ADD_TX_TS,
4189+#if LINUX_VERSION_IS_GEQ(5,2,0)
4190+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
4191+#endif
4192+
4193 .doit = nl80211_add_tx_ts,
4194- .policy = nl80211_policy,
4195 .flags = GENL_UNS_ADMIN_PERM,
4196 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4197 NL80211_FLAG_NEED_RTNL,
4198 },
4199 {
4200 .cmd = NL80211_CMD_DEL_TX_TS,
4201+#if LINUX_VERSION_IS_GEQ(5,2,0)
4202+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
4203+#endif
4204+
4205 .doit = nl80211_del_tx_ts,
4206- .policy = nl80211_policy,
4207 .flags = GENL_UNS_ADMIN_PERM,
4208 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4209 NL80211_FLAG_NEED_RTNL,
4210 },
4211 {
4212 .cmd = NL80211_CMD_TDLS_CHANNEL_SWITCH,
4213+#if LINUX_VERSION_IS_GEQ(5,2,0)
4214+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
4215+#endif
4216+
4217 .doit = nl80211_tdls_channel_switch,
4218- .policy = nl80211_policy,
4219 .flags = GENL_UNS_ADMIN_PERM,
4220 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4221 NL80211_FLAG_NEED_RTNL,
4222 },
4223 {
4224 .cmd = NL80211_CMD_TDLS_CANCEL_CHANNEL_SWITCH,
4225+#if LINUX_VERSION_IS_GEQ(5,2,0)
4226+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
4227+#endif
4228+
4229 .doit = nl80211_tdls_cancel_channel_switch,
4230- .policy = nl80211_policy,
4231 .flags = GENL_UNS_ADMIN_PERM,
4232 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4233 NL80211_FLAG_NEED_RTNL,
4234 },
4235 {
4236 .cmd = NL80211_CMD_SET_MULTICAST_TO_UNICAST,
4237+#if LINUX_VERSION_IS_GEQ(5,2,0)
4238+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
4239+#endif
4240+
4241 .doit = nl80211_set_multicast_to_unicast,
4242- .policy = nl80211_policy,
4243 .flags = GENL_UNS_ADMIN_PERM,
4244 .internal_flags = NL80211_FLAG_NEED_NETDEV |
4245 NL80211_FLAG_NEED_RTNL,
4246 },
4247 {
4248 .cmd = NL80211_CMD_SET_PMK,
4249+#if LINUX_VERSION_IS_GEQ(5,2,0)
4250+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
4251+#endif
4252+
4253 .doit = nl80211_set_pmk,
4254- .policy = nl80211_policy,
4255 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4256 NL80211_FLAG_NEED_RTNL,
4257 },
4258 {
4259 .cmd = NL80211_CMD_DEL_PMK,
4260+#if LINUX_VERSION_IS_GEQ(5,2,0)
4261+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
4262+#endif
4263+
4264 .doit = nl80211_del_pmk,
4265- .policy = nl80211_policy,
4266 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4267 NL80211_FLAG_NEED_RTNL,
4268 },
4269 {
4270 .cmd = NL80211_CMD_EXTERNAL_AUTH,
4271+#if LINUX_VERSION_IS_GEQ(5,2,0)
4272+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
4273+#endif
4274+
4275 .doit = nl80211_external_auth,
4276- .policy = nl80211_policy,
4277 .flags = GENL_ADMIN_PERM,
4278 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4279 NL80211_FLAG_NEED_RTNL,
4280 },
4281 {
4282 .cmd = NL80211_CMD_CONTROL_PORT_FRAME,
4283+#if LINUX_VERSION_IS_GEQ(5,2,0)
4284+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
4285+#endif
4286+
4287 .doit = nl80211_tx_control_port,
4288- .policy = nl80211_policy,
4289 .flags = GENL_UNS_ADMIN_PERM,
4290 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4291 NL80211_FLAG_NEED_RTNL,
4292 },
4293 {
4294 .cmd = NL80211_CMD_GET_FTM_RESPONDER_STATS,
4295+#if LINUX_VERSION_IS_GEQ(5,2,0)
4296+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
4297+#endif
4298+
4299 .doit = nl80211_get_ftm_responder_stats,
4300- .policy = nl80211_policy,
4301 .internal_flags = NL80211_FLAG_NEED_NETDEV |
4302 NL80211_FLAG_NEED_RTNL,
4303 },
4304 {
4305 .cmd = NL80211_CMD_PEER_MEASUREMENT_START,
4306+#if LINUX_VERSION_IS_GEQ(5,2,0)
4307+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
4308+#endif
4309+
4310 .doit = nl80211_pmsr_start,
4311- .policy = nl80211_policy,
4312 .flags = GENL_UNS_ADMIN_PERM,
4313 .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
4314 NL80211_FLAG_NEED_RTNL,
4315 },
4316 {
4317 .cmd = NL80211_CMD_NOTIFY_RADAR,
4318+#if LINUX_VERSION_IS_GEQ(5,2,0)
4319+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
4320+#endif
4321+
4322 .doit = nl80211_notify_radar_detection,
4323- .policy = nl80211_policy,
4324 .flags = GENL_UNS_ADMIN_PERM,
4325 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4326 NL80211_FLAG_NEED_RTNL,
4327@@ -14480,6 +14787,7 @@ static struct genl_family nl80211_fam __genl_ro_after_init = {
4328 .hdrsize = 0, /* no private header */
4329 .version = 1, /* no particular meaning now */
4330 .maxattr = NL80211_ATTR_MAX,
4331+ .policy = nl80211_policy,
4332 .netnsok = true,
4333 .pre_doit = nl80211_pre_doit,
4334 .post_doit = nl80211_post_doit,
4335diff --git a/versions b/versions
4336index a2de5cc..95f63c9 100644
4337--- a/versions
4338+++ b/versions
4339@@ -2,4 +2,4 @@ BACKPORTS_VERSION="(see git)"
4340 BACKPORTED_KERNEL_VERSION="(see git)"
4341 BACKPORTED_KERNEL_NAME="iwlwifi"
4342 BACKPORTS_BUILD_TSTAMP=__DATE__ \" \" __TIME__
4343-BACKPORTS_GIT_TRACKED="iwlwifi-stack-public:master:7858:cb17257d"
4344+BACKPORTS_GIT_TRACKED="iwlwifi-stack-public:master:7906:7773a757"

Subscribers

People subscribed via source and target branches