mediatek: backport the latest version of the mt7531 support patches
[openwrt/staging/rmilecki.git] / package / kernel / mac80211 / patches / subsys / 314-mac80211-rework-tx-encapsulation-offload-API.patch
1 From: Felix Fietkau <nbd@nbd.name>
2 Date: Thu, 13 Aug 2020 15:37:11 +0200
3 Subject: [PATCH] mac80211: rework tx encapsulation offload API
4
5 The current API (which lets the driver turn on/off per vif directly) has a
6 number of limitations:
7 - it does not deal with AP_VLAN
8 - conditions for enabling (no tkip, no monitor) are only checked at
9 add_interface time
10 - no way to indicate 4-addr support
11
12 In order to address this, store offload flags in struct ieee80211_vif
13 (easy to extend for decap offload later). mac80211 initially sets the enable
14 flag, but gives the driver a chance to modify it before its settings are
15 applied. In addition to the .add_interface op, a .update_vif_offload op is
16 introduced, which can be used for runtime changes.
17
18 If a driver can't disable encap offload at runtime, or if it has some extra
19 limitations, it can simply override the flags within those ops.
20
21 Support for encap offload with 4-address mode interfaces can be enabled
22 by setting a flag from .add_interface or .update_vif_offload.
23
24 Signed-off-by: Felix Fietkau <nbd@nbd.name>
25 ---
26
27 --- a/drivers/net/wireless/ath/ath11k/mac.c
28 +++ b/drivers/net/wireless/ath/ath11k/mac.c
29 @@ -4150,6 +4150,35 @@ static int ath11k_set_he_mu_sounding_mod
30 return ret;
31 }
32
33 +static void ath11k_mac_op_update_vif_offload(struct ieee80211_hw *hw,
34 + struct ieee80211_vif *vif)
35 +{
36 + struct ath11k *ar = hw->priv;
37 + struct ath11k_base *ab = ar->ab;
38 + struct ath11k_vif *arvif = ath11k_vif_to_arvif(vif);
39 + u32 param_id, param_value;
40 + int ret;
41 +
42 + param_id = WMI_VDEV_PARAM_TX_ENCAP_TYPE;
43 + if (ath11k_frame_mode != ATH11K_HW_TXRX_ETHERNET ||
44 + (vif->type != NL80211_IFTYPE_STATION &&
45 + vif->type != NL80211_IFTYPE_AP))
46 + vif->offload_flags &= ~IEEE80211_OFFLOAD_ENCAP_ENABLED;
47 +
48 + if (vif->offload_flags & IEEE80211_OFFLOAD_ENCAP_ENABLED)
49 + param_value = ATH11K_HW_TXRX_ETHERNET;
50 + else
51 + param_value = ATH11K_HW_TXRX_NATIVE_WIFI;
52 +
53 + ret = ath11k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id,
54 + param_id, param_value);
55 + if (ret) {
56 + ath11k_warn(ab, "failed to set vdev %d tx encap mode: %d\n",
57 + arvif->vdev_id, ret);
58 + vif->offload_flags &= ~IEEE80211_OFFLOAD_ENCAP_ENABLED;
59 + }
60 +}
61 +
62 static int ath11k_mac_op_add_interface(struct ieee80211_hw *hw,
63 struct ieee80211_vif *vif)
64 {
65 @@ -4159,7 +4188,6 @@ static int ath11k_mac_op_add_interface(s
66 struct vdev_create_params vdev_param = {0};
67 struct peer_create_params peer_param;
68 u32 param_id, param_value;
69 - int hw_encap = 0;
70 u16 nss;
71 int i;
72 int ret;
73 @@ -4253,30 +4281,7 @@ static int ath11k_mac_op_add_interface(s
74 list_add(&arvif->list, &ar->arvifs);
75 spin_unlock_bh(&ar->data_lock);
76
77 - param_id = WMI_VDEV_PARAM_TX_ENCAP_TYPE;
78 - if (ath11k_frame_mode == ATH11K_HW_TXRX_ETHERNET)
79 - switch (vif->type) {
80 - case NL80211_IFTYPE_STATION:
81 - case NL80211_IFTYPE_AP_VLAN:
82 - case NL80211_IFTYPE_AP:
83 - hw_encap = 1;
84 - break;
85 - default:
86 - break;
87 - }
88 -
89 - if (ieee80211_set_hw_80211_encap(vif, hw_encap))
90 - param_value = ATH11K_HW_TXRX_ETHERNET;
91 - else
92 - param_value = ATH11K_HW_TXRX_NATIVE_WIFI;
93 -
94 - ret = ath11k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id,
95 - param_id, param_value);
96 - if (ret) {
97 - ath11k_warn(ab, "failed to set vdev %d tx encap mode: %d\n",
98 - arvif->vdev_id, ret);
99 - goto err_vdev_del;
100 - }
101 + ath11k_mac_op_update_vif_offload(hw, vif);
102
103 nss = get_num_chains(ar->cfg_tx_chainmask) ? : 1;
104 ret = ath11k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id,
105 @@ -5599,6 +5604,7 @@ static const struct ieee80211_ops ath11k
106 .reconfig_complete = ath11k_mac_op_reconfig_complete,
107 .add_interface = ath11k_mac_op_add_interface,
108 .remove_interface = ath11k_mac_op_remove_interface,
109 + .update_vif_offload = ath11k_mac_op_update_vif_offload,
110 .config = ath11k_mac_op_config,
111 .bss_info_changed = ath11k_mac_op_bss_info_changed,
112 .configure_filter = ath11k_mac_op_configure_filter,
113 @@ -5852,6 +5858,7 @@ static int __ath11k_mac_register(struct
114 ieee80211_hw_set(ar->hw, QUEUE_CONTROL);
115 ieee80211_hw_set(ar->hw, SUPPORTS_TX_FRAG);
116 ieee80211_hw_set(ar->hw, REPORTS_LOW_ACK);
117 + ieee80211_hw_set(ar->hw, SUPPORTS_TX_ENCAP_OFFLOAD);
118 if (ht_cap & WMI_HT_CAP_ENABLED) {
119 ieee80211_hw_set(ar->hw, AMPDU_AGGREGATION);
120 ieee80211_hw_set(ar->hw, TX_AMPDU_SETUP_IN_HW);
121 --- a/include/net/mac80211.h
122 +++ b/include/net/mac80211.h
123 @@ -1603,6 +1603,21 @@ enum ieee80211_vif_flags {
124 IEEE80211_VIF_GET_NOA_UPDATE = BIT(3),
125 };
126
127 +
128 +/**
129 + * enum ieee80211_offload_flags - virtual interface offload flags
130 + *
131 + * @IEEE80211_OFFLOAD_ENCAP_ENABLED: tx encapsulation offload is enabled
132 + * The driver supports sending frames passed as 802.3 frames by mac80211.
133 + * It must also support sending 802.11 packets for the same interface.
134 + * @IEEE80211_OFFLOAD_ENCAP_4ADDR: support 4-address mode encapsulation offload
135 + */
136 +
137 +enum ieee80211_offload_flags {
138 + IEEE80211_OFFLOAD_ENCAP_ENABLED = BIT(0),
139 + IEEE80211_OFFLOAD_ENCAP_4ADDR = BIT(1),
140 +};
141 +
142 /**
143 * struct ieee80211_vif - per-interface data
144 *
145 @@ -1623,6 +1638,11 @@ enum ieee80211_vif_flags {
146 * these need to be set (or cleared) when the interface is added
147 * or, if supported by the driver, the interface type is changed
148 * at runtime, mac80211 will never touch this field
149 + * @offloaad_flags: hardware offload capabilities/flags for this interface.
150 + * These are initialized by mac80211 before calling .add_interface,
151 + * .change_interface or .update_vif_offload and updated by the driver
152 + * within these ops, based on supported features or runtime change
153 + * restrictions.
154 * @hw_queue: hardware queue for each AC
155 * @cab_queue: content-after-beacon (DTIM beacon really) queue, AP mode only
156 * @chanctx_conf: The channel context this interface is assigned to, or %NULL
157 @@ -1659,6 +1679,7 @@ struct ieee80211_vif {
158 struct ieee80211_chanctx_conf __rcu *chanctx_conf;
159
160 u32 driver_flags;
161 + u32 offload_flags;
162
163 #ifdef CPTCFG_MAC80211_DEBUGFS
164 struct dentry *debugfs_dir;
165 @@ -2325,6 +2346,9 @@ struct ieee80211_txq {
166 * aggregating MPDUs with the same keyid, allowing mac80211 to keep Tx
167 * A-MPDU sessions active while rekeying with Extended Key ID.
168 *
169 + * @IEEE80211_HW_SUPPORTS_TX_ENCAP_OFFLOAD: Hardware supports tx encapsulation
170 + * offload
171 + *
172 * @NUM_IEEE80211_HW_FLAGS: number of hardware flags, used for sizing arrays
173 */
174 enum ieee80211_hw_flags {
175 @@ -2377,6 +2401,7 @@ enum ieee80211_hw_flags {
176 IEEE80211_HW_SUPPORTS_MULTI_BSSID,
177 IEEE80211_HW_SUPPORTS_ONLY_HE_MULTI_BSSID,
178 IEEE80211_HW_AMPDU_KEYBORDER_SUPPORT,
179 + IEEE80211_HW_SUPPORTS_TX_ENCAP_OFFLOAD,
180
181 /* keep last, obviously */
182 NUM_IEEE80211_HW_FLAGS
183 @@ -3811,6 +3836,8 @@ enum ieee80211_reconfig_type {
184 * @set_tid_config: Apply TID specific configurations. This callback may sleep.
185 * @reset_tid_config: Reset TID specific configuration for the peer.
186 * This callback may sleep.
187 + * @update_vif_config: Update virtual interface offload flags
188 + * This callback may sleep.
189 */
190 struct ieee80211_ops {
191 void (*tx)(struct ieee80211_hw *hw,
192 @@ -4122,6 +4149,8 @@ struct ieee80211_ops {
193 int (*reset_tid_config)(struct ieee80211_hw *hw,
194 struct ieee80211_vif *vif,
195 struct ieee80211_sta *sta, u8 tids);
196 + void (*update_vif_offload)(struct ieee80211_hw *hw,
197 + struct ieee80211_vif *vif);
198 };
199
200 /**
201 --- a/net/mac80211/cfg.c
202 +++ b/net/mac80211/cfg.c
203 @@ -504,6 +504,7 @@ static int ieee80211_del_key(struct wiph
204 struct ieee80211_local *local = sdata->local;
205 struct sta_info *sta;
206 struct ieee80211_key *key = NULL;
207 + bool recalc_offload = false;
208 int ret;
209
210 mutex_lock(&local->sta_mtx);
211 @@ -528,6 +529,7 @@ static int ieee80211_del_key(struct wiph
212 goto out_unlock;
213 }
214
215 + recalc_offload = key->conf.cipher == WLAN_CIPHER_SUITE_TKIP;
216 ieee80211_key_free(key, sdata->vif.type == NL80211_IFTYPE_STATION);
217
218 ret = 0;
219 @@ -535,6 +537,9 @@ static int ieee80211_del_key(struct wiph
220 mutex_unlock(&local->key_mtx);
221 mutex_unlock(&local->sta_mtx);
222
223 + if (recalc_offload)
224 + ieee80211_recalc_offload(local);
225 +
226 return ret;
227 }
228
229 --- a/net/mac80211/debugfs.c
230 +++ b/net/mac80211/debugfs.c
231 @@ -408,6 +408,7 @@ static const char *hw_flag_names[] = {
232 FLAG(SUPPORTS_MULTI_BSSID),
233 FLAG(SUPPORTS_ONLY_HE_MULTI_BSSID),
234 FLAG(AMPDU_KEYBORDER_SUPPORT),
235 + FLAG(SUPPORTS_TX_ENCAP_OFFLOAD),
236 #undef FLAG
237 };
238
239 --- a/net/mac80211/driver-ops.h
240 +++ b/net/mac80211/driver-ops.h
241 @@ -1385,4 +1385,19 @@ static inline int drv_reset_tid_config(s
242
243 return ret;
244 }
245 +
246 +static inline void drv_update_vif_offload(struct ieee80211_local *local,
247 + struct ieee80211_sub_if_data *sdata)
248 +{
249 + might_sleep();
250 + check_sdata_in_driver(sdata);
251 +
252 + if (!local->ops->update_vif_offload)
253 + return;
254 +
255 + trace_drv_update_vif_offload(local, sdata);
256 + local->ops->update_vif_offload(&local->hw, &sdata->vif);
257 + trace_drv_return_void(local);
258 +}
259 +
260 #endif /* __MAC80211_DRIVER_OPS */
261 --- a/net/mac80211/ieee80211_i.h
262 +++ b/net/mac80211/ieee80211_i.h
263 @@ -990,8 +990,6 @@ struct ieee80211_sub_if_data {
264 } debugfs;
265 #endif
266
267 - bool hw_80211_encap;
268 -
269 /* must be last, dynamically sized area in this! */
270 struct ieee80211_vif vif;
271 };
272 @@ -1769,6 +1767,7 @@ void ieee80211_del_virtual_monitor(struc
273 bool __ieee80211_recalc_txpower(struct ieee80211_sub_if_data *sdata);
274 void ieee80211_recalc_txpower(struct ieee80211_sub_if_data *sdata,
275 bool update_bss);
276 +void ieee80211_recalc_offload(struct ieee80211_local *local);
277
278 static inline bool ieee80211_sdata_running(struct ieee80211_sub_if_data *sdata)
279 {
280 --- a/net/mac80211/iface.c
281 +++ b/net/mac80211/iface.c
282 @@ -43,6 +43,7 @@
283 */
284
285 static void ieee80211_iface_work(struct work_struct *work);
286 +static void ieee80211_set_vif_encap_ops(struct ieee80211_sub_if_data *sdata);
287
288 bool __ieee80211_recalc_txpower(struct ieee80211_sub_if_data *sdata)
289 {
290 @@ -348,6 +349,99 @@ static int ieee80211_check_queues(struct
291 return 0;
292 }
293
294 +static bool ieee80211_iftype_supports_encap_offload(enum nl80211_iftype iftype)
295 +{
296 + switch (iftype) {
297 + case NL80211_IFTYPE_AP:
298 + case NL80211_IFTYPE_P2P_GO:
299 + case NL80211_IFTYPE_P2P_CLIENT:
300 + case NL80211_IFTYPE_STATION:
301 + return true;
302 + default:
303 + return false;
304 + }
305 +}
306 +
307 +static bool ieee80211_set_sdata_offload_flags(struct ieee80211_sub_if_data *sdata)
308 +{
309 + struct ieee80211_local *local = sdata->local;
310 + struct ieee80211_key *key;
311 + u32 flags;
312 +
313 + flags = sdata->vif.offload_flags;
314 +
315 + if (ieee80211_hw_check(&local->hw, SUPPORTS_TX_ENCAP_OFFLOAD) &&
316 + ieee80211_iftype_supports_encap_offload(sdata->vif.type)) {
317 + flags |= IEEE80211_OFFLOAD_ENCAP_ENABLED;
318 + mutex_lock(&local->key_mtx);
319 + list_for_each_entry(key, &sdata->key_list, list) {
320 + if (key->conf.cipher == WLAN_CIPHER_SUITE_AES_CMAC ||
321 + key->conf.cipher == WLAN_CIPHER_SUITE_BIP_GMAC_128 ||
322 + key->conf.cipher == WLAN_CIPHER_SUITE_BIP_GMAC_256 ||
323 + key->conf.cipher == WLAN_CIPHER_SUITE_BIP_CMAC_256)
324 + continue;
325 + if (key->conf.cipher == WLAN_CIPHER_SUITE_TKIP ||
326 + !(key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE))
327 + flags &= ~IEEE80211_OFFLOAD_ENCAP_ENABLED;
328 + }
329 + mutex_unlock(&local->key_mtx);
330 +
331 + if (!ieee80211_hw_check(&local->hw, SUPPORTS_TX_FRAG) &&
332 + local->hw.wiphy->frag_threshold != (u32)-1)
333 + flags &= ~IEEE80211_OFFLOAD_ENCAP_ENABLED;
334 +
335 + if (local->monitors)
336 + flags &= ~IEEE80211_OFFLOAD_ENCAP_ENABLED;
337 + } else {
338 + flags &= ~IEEE80211_OFFLOAD_ENCAP_ENABLED;
339 + }
340 +
341 + if (sdata->vif.offload_flags == flags)
342 + return false;
343 +
344 + sdata->vif.offload_flags = flags;
345 + return true;
346 +}
347 +
348 +
349 +static void ieee80211_recalc_sdata_offload(struct ieee80211_sub_if_data *sdata)
350 +{
351 + struct ieee80211_local *local = sdata->local;
352 + struct ieee80211_sub_if_data *vsdata;
353 +
354 + if (ieee80211_set_sdata_offload_flags(sdata)) {
355 + drv_update_vif_offload(local, sdata);
356 + ieee80211_set_vif_encap_ops(sdata);
357 + }
358 +
359 + list_for_each_entry(vsdata, &local->interfaces, list) {
360 + if (vsdata->vif.type != NL80211_IFTYPE_AP_VLAN ||
361 + vsdata->bss != &sdata->u.ap)
362 + continue;
363 +
364 + ieee80211_set_vif_encap_ops(vsdata);
365 + }
366 +}
367 +
368 +void ieee80211_recalc_offload(struct ieee80211_local *local)
369 +{
370 + struct ieee80211_sub_if_data *sdata;
371 +
372 + if (!ieee80211_hw_check(&local->hw, SUPPORTS_TX_ENCAP_OFFLOAD))
373 + return;
374 +
375 + mutex_lock(&local->iflist_mtx);
376 +
377 + list_for_each_entry(sdata, &local->interfaces, list) {
378 + if (!ieee80211_sdata_running(sdata))
379 + continue;
380 +
381 + ieee80211_recalc_sdata_offload(sdata);
382 + }
383 +
384 + mutex_unlock(&local->iflist_mtx);
385 +}
386 +
387 void ieee80211_adjust_monitor_flags(struct ieee80211_sub_if_data *sdata,
388 const int offset)
389 {
390 @@ -587,6 +681,7 @@ int ieee80211_do_open(struct wireless_de
391 if (rtnl_dereference(sdata->bss->beacon)) {
392 ieee80211_vif_vlan_copy_chanctx(sdata);
393 netif_carrier_on(dev);
394 + ieee80211_set_vif_encap_ops(sdata);
395 } else {
396 netif_carrier_off(dev);
397 }
398 @@ -616,6 +711,7 @@ int ieee80211_do_open(struct wireless_de
399
400 ieee80211_adjust_monitor_flags(sdata, 1);
401 ieee80211_configure_filter(local);
402 + ieee80211_recalc_offload(local);
403 mutex_lock(&local->mtx);
404 ieee80211_recalc_idle(local);
405 mutex_unlock(&local->mtx);
406 @@ -625,10 +721,13 @@ int ieee80211_do_open(struct wireless_de
407 default:
408 if (coming_up) {
409 ieee80211_del_virtual_monitor(local);
410 + ieee80211_set_sdata_offload_flags(sdata);
411
412 res = drv_add_interface(local, sdata);
413 if (res)
414 goto err_stop;
415 +
416 + ieee80211_set_vif_encap_ops(sdata);
417 res = ieee80211_check_queues(sdata,
418 ieee80211_vif_type_p2p(&sdata->vif));
419 if (res)
420 @@ -1286,61 +1385,6 @@ static const struct net_device_ops ieee8
421
422 };
423
424 -static void __ieee80211_set_hw_80211_encap(struct ieee80211_sub_if_data *sdata,
425 - bool enable)
426 -{
427 - sdata->dev->netdev_ops = enable ? &ieee80211_dataif_8023_ops :
428 - &ieee80211_dataif_ops;
429 - sdata->hw_80211_encap = enable;
430 -}
431 -
432 -bool ieee80211_set_hw_80211_encap(struct ieee80211_vif *vif, bool enable)
433 -{
434 - struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
435 - struct ieee80211_local *local = sdata->local;
436 - struct ieee80211_sub_if_data *iter;
437 - struct ieee80211_key *key;
438 -
439 - mutex_lock(&local->iflist_mtx);
440 - list_for_each_entry(iter, &local->interfaces, list) {
441 - struct ieee80211_sub_if_data *disable = NULL;
442 -
443 - if (vif->type == NL80211_IFTYPE_MONITOR) {
444 - disable = iter;
445 - __ieee80211_set_hw_80211_encap(iter, false);
446 - } else if (iter->vif.type == NL80211_IFTYPE_MONITOR) {
447 - disable = sdata;
448 - enable = false;
449 - }
450 - if (disable)
451 - sdata_dbg(disable,
452 - "disable hw 80211 encap due to mon co-exist\n");
453 - }
454 - mutex_unlock(&local->iflist_mtx);
455 -
456 - if (enable == sdata->hw_80211_encap)
457 - return enable;
458 -
459 - if (!sdata->dev)
460 - return false;
461 -
462 - if (!ieee80211_hw_check(&local->hw, SUPPORTS_TX_FRAG) &&
463 - (local->hw.wiphy->frag_threshold != (u32)-1))
464 - enable = false;
465 -
466 - mutex_lock(&sdata->local->key_mtx);
467 - list_for_each_entry(key, &sdata->key_list, list) {
468 - if (key->conf.cipher == WLAN_CIPHER_SUITE_TKIP)
469 - enable = false;
470 - }
471 - mutex_unlock(&sdata->local->key_mtx);
472 -
473 - __ieee80211_set_hw_80211_encap(sdata, enable);
474 -
475 - return enable;
476 -}
477 -EXPORT_SYMBOL(ieee80211_set_hw_80211_encap);
478 -
479 static void ieee80211_if_free(struct net_device *dev)
480 {
481 free_percpu(netdev_tstats(dev));
482 @@ -1371,6 +1415,51 @@ static void ieee80211_if_setup_no_queue(
483 #endif
484 }
485
486 +static void ieee80211_set_vif_encap_ops(struct ieee80211_sub_if_data *sdata)
487 +{
488 + struct ieee80211_local *local = sdata->local;
489 + struct ieee80211_sub_if_data *bss = sdata;
490 + struct ieee80211_key *key;
491 + bool enabled;
492 +
493 + if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) {
494 + if (!sdata->bss)
495 + return;
496 +
497 + bss = container_of(sdata->bss, struct ieee80211_sub_if_data, u.ap);
498 + }
499 +
500 + if (!ieee80211_hw_check(&local->hw, SUPPORTS_TX_ENCAP_OFFLOAD) ||
501 + !ieee80211_iftype_supports_encap_offload(bss->vif.type))
502 + return;
503 +
504 + enabled = bss->vif.offload_flags & IEEE80211_OFFLOAD_ENCAP_ENABLED;
505 + if (sdata->wdev.use_4addr &&
506 + !(bss->vif.offload_flags & IEEE80211_OFFLOAD_ENCAP_4ADDR))
507 + enabled = false;
508 +
509 + /*
510 + * Encapsulation offload cannot be used with software crypto, and a per-VLAN
511 + * key may have been set
512 + */
513 + if (enabled && sdata->vif.type == NL80211_IFTYPE_AP_VLAN) {
514 + mutex_lock(&local->key_mtx);
515 + list_for_each_entry(key, &sdata->key_list, list) {
516 + if (key->conf.cipher == WLAN_CIPHER_SUITE_AES_CMAC ||
517 + key->conf.cipher == WLAN_CIPHER_SUITE_BIP_GMAC_128 ||
518 + key->conf.cipher == WLAN_CIPHER_SUITE_BIP_GMAC_256 ||
519 + key->conf.cipher == WLAN_CIPHER_SUITE_BIP_CMAC_256)
520 + continue;
521 + if (!(key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE))
522 + enabled = false;
523 + }
524 + mutex_unlock(&local->key_mtx);
525 + }
526 +
527 + sdata->dev->netdev_ops = enabled ? &ieee80211_dataif_8023_ops :
528 + &ieee80211_dataif_ops;
529 +}
530 +
531 static void ieee80211_iface_work(struct work_struct *work)
532 {
533 struct ieee80211_sub_if_data *sdata =
534 @@ -1553,7 +1642,6 @@ static void ieee80211_setup_sdata(struct
535 sdata->vif.bss_conf.txpower = INT_MIN; /* unset */
536
537 sdata->noack_map = 0;
538 - sdata->hw_80211_encap = false;
539
540 /* only monitor/p2p-device differ */
541 if (sdata->dev) {
542 @@ -1688,6 +1776,7 @@ static int ieee80211_runtime_change_ifty
543
544 ieee80211_teardown_sdata(sdata);
545
546 + ieee80211_set_sdata_offload_flags(sdata);
547 ret = drv_change_interface(local, sdata, internal_type, p2p);
548 if (ret)
549 type = ieee80211_vif_type_p2p(&sdata->vif);
550 @@ -1700,6 +1789,7 @@ static int ieee80211_runtime_change_ifty
551 ieee80211_check_queues(sdata, type);
552
553 ieee80211_setup_sdata(sdata, type);
554 + ieee80211_set_vif_encap_ops(sdata);
555
556 err = ieee80211_do_open(&sdata->wdev, false);
557 WARN(err, "type change: do_open returned %d", err);
558 --- a/net/mac80211/key.c
559 +++ b/net/mac80211/key.c
560 @@ -177,13 +177,6 @@ static int ieee80211_key_enable_hw_accel
561 }
562 }
563
564 - /* TKIP countermeasures don't work in encap offload mode */
565 - if (key->conf.cipher == WLAN_CIPHER_SUITE_TKIP &&
566 - sdata->hw_80211_encap) {
567 - sdata_dbg(sdata, "TKIP is not allowed in hw 80211 encap mode\n");
568 - return -EINVAL;
569 - }
570 -
571 ret = drv_set_key(key->local, SET_KEY, sdata,
572 sta ? &sta->sta : NULL, &key->conf);
573
574 @@ -219,14 +212,6 @@ static int ieee80211_key_enable_hw_accel
575 case WLAN_CIPHER_SUITE_CCMP_256:
576 case WLAN_CIPHER_SUITE_GCMP:
577 case WLAN_CIPHER_SUITE_GCMP_256:
578 - /* We cannot do software crypto of data frames with
579 - * encapsulation offload enabled. However for 802.11w to
580 - * function properly we need cmac/gmac keys.
581 - */
582 - if (sdata->hw_80211_encap)
583 - return -EINVAL;
584 - /* Fall through */
585 -
586 case WLAN_CIPHER_SUITE_AES_CMAC:
587 case WLAN_CIPHER_SUITE_BIP_CMAC_256:
588 case WLAN_CIPHER_SUITE_BIP_GMAC_128:
589 @@ -824,6 +809,7 @@ int ieee80211_key_link(struct ieee80211_
590 */
591 bool delay_tailroom = sdata->vif.type == NL80211_IFTYPE_STATION;
592 int ret = -EOPNOTSUPP;
593 + bool recalc_offload = false;
594
595 mutex_lock(&sdata->local->key_mtx);
596
597 @@ -864,11 +850,15 @@ int ieee80211_key_link(struct ieee80211_
598 key->local = sdata->local;
599 key->sdata = sdata;
600 key->sta = sta;
601 + recalc_offload = !old_key && key->conf.cipher == WLAN_CIPHER_SUITE_TKIP;
602
603 increment_tailroom_need_count(sdata);
604
605 ret = ieee80211_key_replace(sdata, sta, pairwise, old_key, key);
606
607 + if (!(key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE))
608 + recalc_offload = true;
609 +
610 if (!ret) {
611 ieee80211_debugfs_key_add(key);
612 ieee80211_key_destroy(old_key, delay_tailroom);
613 @@ -879,6 +869,9 @@ int ieee80211_key_link(struct ieee80211_
614 out:
615 mutex_unlock(&sdata->local->key_mtx);
616
617 + if (recalc_offload)
618 + ieee80211_recalc_offload(sdata->local);
619 +
620 return ret;
621 }
622
623 --- a/net/mac80211/trace.h
624 +++ b/net/mac80211/trace.h
625 @@ -2733,6 +2733,12 @@ TRACE_EVENT(drv_get_ftm_responder_stats,
626 )
627 );
628
629 +DEFINE_EVENT(local_sdata_addr_evt, drv_update_vif_offload,
630 + TP_PROTO(struct ieee80211_local *local,
631 + struct ieee80211_sub_if_data *sdata),
632 + TP_ARGS(local, sdata)
633 +);
634 +
635 #endif /* !__MAC80211_DRIVER_TRACE || TRACE_HEADER_MULTI_READ */
636
637 #undef TRACE_INCLUDE_PATH
638 --- a/net/mac80211/tx.c
639 +++ b/net/mac80211/tx.c
640 @@ -4264,11 +4264,6 @@ netdev_tx_t ieee80211_subif_start_xmit_8
641 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
642 struct sta_info *sta;
643
644 - if (WARN_ON(!sdata->hw_80211_encap)) {
645 - kfree_skb(skb);
646 - return NETDEV_TX_OK;
647 - }
648 -
649 if (unlikely(skb->len < ETH_HLEN)) {
650 kfree_skb(skb);
651 return NETDEV_TX_OK;