Merge ~canonical-hwe-team/ubuntu/+source/backport-iwlwifi-dkms/+git/backport-iwlwifi-dkms:vicamo/for-hwe/bug-1835858-fix-build-on-eoan into ~canonical-hwe-team/ubuntu/+source/backport-iwlwifi-dkms/+git/backport-iwlwifi-dkms:ubuntu/master

Proposed by You-Sheng Yang
Status: Merged
Approved by: You-Sheng Yang
Approved revision: 55790fad5390a07d821ead3ae9a2b3f6ffd34d5c
Merged at revision: 55790fad5390a07d821ead3ae9a2b3f6ffd34d5c
Proposed branch: ~canonical-hwe-team/ubuntu/+source/backport-iwlwifi-dkms/+git/backport-iwlwifi-dkms:vicamo/for-hwe/bug-1835858-fix-build-on-eoan
Merge into: ~canonical-hwe-team/ubuntu/+source/backport-iwlwifi-dkms/+git/backport-iwlwifi-dkms:ubuntu/master
Diff against target: 4542 lines (+1565/-737)
58 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 (+14/-0)
debian/gbp.conf (+1/-1)
debian/gitlab-ci.yml (+3/-3)
debian/patches/0002-fix-format-overflow-compile-error-in-kconf-confdata..patch (+28/-0)
debian/patches/0003-backport-apply-__copy-to-init_module-cleanup_module.patch (+44/-0)
debian/patches/0004-backport-fix-build-for-v5.2-kernel.patch (+38/-0)
debian/patches/0005-Makefile.kernel-pass-fno-stack-clash-protection-and-.patch (+22/-0)
debian/patches/series (+4/-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 Approve
Review via email: mp+370163@code.launchpad.net

Description of the change

* Fix build on Eoan. (LP: #1835858)
  - Fix build with gcc-9. (LP: #1830961)
  - Fix build against kernel v5.2.

To post a comment you must log in.
Revision history for this message
You-Sheng Yang (vicamo) wrote :
Revision history for this message
You-Sheng Yang (vicamo) wrote :

Tested on newly released 5.2.0-8-generic as well.

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

Subscribers

People subscribed via source and target branches