From d717343c85f6c305b6896e4d3aa93f9cd67e9d22 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Tue, 8 Sep 2020 14:22:28 +0200 Subject: [PATCH] mac80211: update encap offload patches to the latest version Minor cleanup and code reorganization, along with a change to not disable offload anymore when a tkip or sw crypto key is added Signed-off-by: Felix Fietkau --- ...ing-queue-hash-initialization-to-80.patch} | 4 +- ...d-refresh-aggregation-session-in-en.patch} | 4 +- ...ap-offload-for-tx-multicast-control.patch} | 26 +- ...-control.hw_key-for-encap-offload-p.patch} | 2 +- ...rework-tx-encapsulation-offload-API.patch} | 180 ++- ...-duplication-in-tx-status-functions.patch} | 0 ...x-status-call-to-ieee80211_sta_regi.patch} | 0 ...optimize-station-connection-monitor.patch} | 0 ...D_TXPROCESSING-and-HW_80211_ENCAP-t.patch} | 8 +- ...2.3-offload-and-802.11-tx-status-co.patch} | 0 ...using-ieee80211_tx_status_ext-to-fr.patch} | 0 ...eee80211_tx_status_ext-to-support-b.patch} | 4 +- ...he-driver-when-a-sta-uses-4-address.patch} | 2 +- ...ize-code-to-remove-a-forward-declara.patch | 1110 +++++++++++++++++ ...QL-aggregation-estimation-to-HE-and.patch} | 0 ...add-AQL-support-for-VHT160-tx-rates.patch} | 0 .../500-mac80211_configure_antenna_gain.patch | 8 +- 17 files changed, 1199 insertions(+), 149 deletions(-) rename package/kernel/mac80211/patches/subsys/{320-mac80211-add-missing-queue-hash-initialization-to-80.patch => 314-mac80211-add-missing-queue-hash-initialization-to-80.patch} (97%) rename package/kernel/mac80211/patches/subsys/{321-mac80211-check-and-refresh-aggregation-session-in-en.patch => 315-mac80211-check-and-refresh-aggregation-session-in-en.patch} (98%) rename package/kernel/mac80211/patches/subsys/{325-mac80211-skip-encap-offload-for-tx-multicast-control.patch => 316-mac80211-skip-encap-offload-for-tx-multicast-control.patch} (77%) rename package/kernel/mac80211/patches/subsys/{326-mac80211-set-info-control.hw_key-for-encap-offload-p.patch => 317-mac80211-set-info-control.hw_key-for-encap-offload-p.patch} (93%) rename package/kernel/mac80211/patches/subsys/{314-mac80211-rework-tx-encapsulation-offload-API.patch => 318-mac80211-rework-tx-encapsulation-offload-API.patch} (82%) rename package/kernel/mac80211/patches/subsys/{315-mac80211-reduce-duplication-in-tx-status-functions.patch => 319-mac80211-reduce-duplication-in-tx-status-functions.patch} (100%) rename package/kernel/mac80211/patches/subsys/{316-mac80211-remove-tx-status-call-to-ieee80211_sta_regi.patch => 320-mac80211-remove-tx-status-call-to-ieee80211_sta_regi.patch} (100%) rename package/kernel/mac80211/patches/subsys/{317-mac80211-optimize-station-connection-monitor.patch => 321-mac80211-optimize-station-connection-monitor.patch} (100%) rename package/kernel/mac80211/patches/subsys/{318-mac80211-swap-NEED_TXPROCESSING-and-HW_80211_ENCAP-t.patch => 322-mac80211-swap-NEED_TXPROCESSING-and-HW_80211_ENCAP-t.patch} (97%) rename package/kernel/mac80211/patches/subsys/{319-mac80211-unify-802.3-offload-and-802.11-tx-status-co.patch => 323-mac80211-unify-802.3-offload-and-802.11-tx-status-co.patch} (100%) rename package/kernel/mac80211/patches/subsys/{322-mac80211-support-using-ieee80211_tx_status_ext-to-fr.patch => 324-mac80211-support-using-ieee80211_tx_status_ext-to-fr.patch} (100%) rename package/kernel/mac80211/patches/subsys/{323-mac80211-extend-ieee80211_tx_status_ext-to-support-b.patch => 325-mac80211-extend-ieee80211_tx_status_ext-to-support-b.patch} (98%) rename package/kernel/mac80211/patches/subsys/{324-mac80211-notify-the-driver-when-a-sta-uses-4-address.patch => 326-mac80211-notify-the-driver-when-a-sta-uses-4-address.patch} (97%) create mode 100644 package/kernel/mac80211/patches/subsys/327-mac80211-reorganize-code-to-remove-a-forward-declara.patch rename package/kernel/mac80211/patches/subsys/{327-mac80211-extend-AQL-aggregation-estimation-to-HE-and.patch => 328-mac80211-extend-AQL-aggregation-estimation-to-HE-and.patch} (100%) rename package/kernel/mac80211/patches/subsys/{328-mac80211-add-AQL-support-for-VHT160-tx-rates.patch => 329-mac80211-add-AQL-support-for-VHT160-tx-rates.patch} (100%) diff --git a/package/kernel/mac80211/patches/subsys/320-mac80211-add-missing-queue-hash-initialization-to-80.patch b/package/kernel/mac80211/patches/subsys/314-mac80211-add-missing-queue-hash-initialization-to-80.patch similarity index 97% rename from package/kernel/mac80211/patches/subsys/320-mac80211-add-missing-queue-hash-initialization-to-80.patch rename to package/kernel/mac80211/patches/subsys/314-mac80211-add-missing-queue-hash-initialization-to-80.patch index d9d3fded75..eb56a2cac5 100644 --- a/package/kernel/mac80211/patches/subsys/320-mac80211-add-missing-queue-hash-initialization-to-80.patch +++ b/package/kernel/mac80211/patches/subsys/314-mac80211-add-missing-queue-hash-initialization-to-80.patch @@ -1,7 +1,7 @@ From: Felix Fietkau Date: Mon, 17 Aug 2020 13:55:56 +0200 -Subject: [PATCH] mac80211: add missing queue/hash initialization to 802.3 - xmit +Subject: [PATCH] mac80211: add missing queue/hash initialization to + 802.3 xmit Fixes AQL for encap-offloaded tx diff --git a/package/kernel/mac80211/patches/subsys/321-mac80211-check-and-refresh-aggregation-session-in-en.patch b/package/kernel/mac80211/patches/subsys/315-mac80211-check-and-refresh-aggregation-session-in-en.patch similarity index 98% rename from package/kernel/mac80211/patches/subsys/321-mac80211-check-and-refresh-aggregation-session-in-en.patch rename to package/kernel/mac80211/patches/subsys/315-mac80211-check-and-refresh-aggregation-session-in-en.patch index 0188e19b71..e411d59722 100644 --- a/package/kernel/mac80211/patches/subsys/321-mac80211-check-and-refresh-aggregation-session-in-en.patch +++ b/package/kernel/mac80211/patches/subsys/315-mac80211-check-and-refresh-aggregation-session-in-en.patch @@ -1,7 +1,7 @@ From: Felix Fietkau Date: Mon, 17 Aug 2020 21:11:25 +0200 -Subject: [PATCH] mac80211: check and refresh aggregation session in encap - offload tx +Subject: [PATCH] mac80211: check and refresh aggregation session in + encap offload tx Update the last_tx timestamp to avoid tearing down the aggregation session early. Fall back to the slow path if the session setup is still running diff --git a/package/kernel/mac80211/patches/subsys/325-mac80211-skip-encap-offload-for-tx-multicast-control.patch b/package/kernel/mac80211/patches/subsys/316-mac80211-skip-encap-offload-for-tx-multicast-control.patch similarity index 77% rename from package/kernel/mac80211/patches/subsys/325-mac80211-skip-encap-offload-for-tx-multicast-control.patch rename to package/kernel/mac80211/patches/subsys/316-mac80211-skip-encap-offload-for-tx-multicast-control.patch index a32075768a..6dce21db1e 100644 --- a/package/kernel/mac80211/patches/subsys/325-mac80211-skip-encap-offload-for-tx-multicast-control.patch +++ b/package/kernel/mac80211/patches/subsys/316-mac80211-skip-encap-offload-for-tx-multicast-control.patch @@ -10,28 +10,6 @@ using an AP_VLAN. Signed-off-by: Felix Fietkau --- ---- a/net/mac80211/iface.c -+++ b/net/mac80211/iface.c -@@ -378,7 +378,8 @@ static bool ieee80211_set_sdata_offload_ - if (key->conf.cipher == WLAN_CIPHER_SUITE_AES_CMAC || - key->conf.cipher == WLAN_CIPHER_SUITE_BIP_GMAC_128 || - key->conf.cipher == WLAN_CIPHER_SUITE_BIP_GMAC_256 || -- key->conf.cipher == WLAN_CIPHER_SUITE_BIP_CMAC_256) -+ key->conf.cipher == WLAN_CIPHER_SUITE_BIP_CMAC_256 || -+ !(key->conf.flags & IEEE80211_KEY_FLAG_PAIRWISE)) - continue; - if (key->conf.cipher == WLAN_CIPHER_SUITE_TKIP || - !(key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE)) -@@ -1448,7 +1449,8 @@ static void ieee80211_set_vif_encap_ops( - if (key->conf.cipher == WLAN_CIPHER_SUITE_AES_CMAC || - key->conf.cipher == WLAN_CIPHER_SUITE_BIP_GMAC_128 || - key->conf.cipher == WLAN_CIPHER_SUITE_BIP_GMAC_256 || -- key->conf.cipher == WLAN_CIPHER_SUITE_BIP_CMAC_256) -+ key->conf.cipher == WLAN_CIPHER_SUITE_BIP_CMAC_256 || -+ !(key->conf.flags & IEEE80211_KEY_FLAG_PAIRWISE)) - continue; - if (!(key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE)) - enabled = false; --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c @@ -4184,88 +4184,47 @@ static void ieee80211_8023_xmit(struct i @@ -144,8 +122,8 @@ Signed-off-by: Felix Fietkau + struct ethhdr *ehdr = (struct ethhdr *)skb->data; struct sta_info *sta; - if (unlikely(skb->len < ETH_HLEN)) { -@@ -4297,6 +4257,10 @@ netdev_tx_t ieee80211_subif_start_xmit_8 + if (WARN_ON(!sdata->hw_80211_encap)) { +@@ -4302,6 +4262,10 @@ netdev_tx_t ieee80211_subif_start_xmit_8 if (ieee80211_lookup_ra_sta(sdata, skb, &sta)) kfree_skb(skb); diff --git a/package/kernel/mac80211/patches/subsys/326-mac80211-set-info-control.hw_key-for-encap-offload-p.patch b/package/kernel/mac80211/patches/subsys/317-mac80211-set-info-control.hw_key-for-encap-offload-p.patch similarity index 93% rename from package/kernel/mac80211/patches/subsys/326-mac80211-set-info-control.hw_key-for-encap-offload-p.patch rename to package/kernel/mac80211/patches/subsys/317-mac80211-set-info-control.hw_key-for-encap-offload-p.patch index 421d18f2c2..cb5a986312 100644 --- a/package/kernel/mac80211/patches/subsys/326-mac80211-set-info-control.hw_key-for-encap-offload-p.patch +++ b/package/kernel/mac80211/patches/subsys/317-mac80211-set-info-control.hw_key-for-encap-offload-p.patch @@ -19,7 +19,7 @@ Signed-off-by: Felix Fietkau u8 tid; @@ -4233,6 +4234,10 @@ static void ieee80211_8023_xmit(struct i - info->flags |= IEEE80211_TX_CTL_HW_80211_ENCAP; + info->control.flags |= IEEE80211_TX_CTRL_HW_80211_ENCAP; info->control.vif = &sdata->vif; + key = rcu_dereference(sta->ptk[sta->ptk_idx]); diff --git a/package/kernel/mac80211/patches/subsys/314-mac80211-rework-tx-encapsulation-offload-API.patch b/package/kernel/mac80211/patches/subsys/318-mac80211-rework-tx-encapsulation-offload-API.patch similarity index 82% rename from package/kernel/mac80211/patches/subsys/314-mac80211-rework-tx-encapsulation-offload-API.patch rename to package/kernel/mac80211/patches/subsys/318-mac80211-rework-tx-encapsulation-offload-API.patch index 4f0d264947..7593c41da0 100644 --- a/package/kernel/mac80211/patches/subsys/314-mac80211-rework-tx-encapsulation-offload-API.patch +++ b/package/kernel/mac80211/patches/subsys/318-mac80211-rework-tx-encapsulation-offload-API.patch @@ -198,34 +198,6 @@ Signed-off-by: Felix Fietkau }; /** ---- a/net/mac80211/cfg.c -+++ b/net/mac80211/cfg.c -@@ -504,6 +504,7 @@ static int ieee80211_del_key(struct wiph - struct ieee80211_local *local = sdata->local; - struct sta_info *sta; - struct ieee80211_key *key = NULL; -+ bool recalc_offload = false; - int ret; - - mutex_lock(&local->sta_mtx); -@@ -528,6 +529,7 @@ static int ieee80211_del_key(struct wiph - goto out_unlock; - } - -+ recalc_offload = key->conf.cipher == WLAN_CIPHER_SUITE_TKIP; - ieee80211_key_free(key, sdata->vif.type == NL80211_IFTYPE_STATION); - - ret = 0; -@@ -535,6 +537,9 @@ static int ieee80211_del_key(struct wiph - mutex_unlock(&local->key_mtx); - mutex_unlock(&local->sta_mtx); - -+ if (recalc_offload) -+ ieee80211_recalc_offload(local); -+ - return ret; - } - --- a/net/mac80211/debugfs.c +++ b/net/mac80211/debugfs.c @@ -408,6 +408,7 @@ static const char *hw_flag_names[] = { @@ -287,16 +259,15 @@ Signed-off-by: Felix Fietkau bool __ieee80211_recalc_txpower(struct ieee80211_sub_if_data *sdata) { -@@ -348,6 +349,99 @@ static int ieee80211_check_queues(struct +@@ -348,6 +349,85 @@ static int ieee80211_check_queues(struct return 0; } +static bool ieee80211_iftype_supports_encap_offload(enum nl80211_iftype iftype) +{ + switch (iftype) { ++ /* P2P GO and client are mapped to AP/STATION types */ + case NL80211_IFTYPE_AP: -+ case NL80211_IFTYPE_P2P_GO: -+ case NL80211_IFTYPE_P2P_CLIENT: + case NL80211_IFTYPE_STATION: + return true; + default: @@ -307,7 +278,6 @@ Signed-off-by: Felix Fietkau +static bool ieee80211_set_sdata_offload_flags(struct ieee80211_sub_if_data *sdata) +{ + struct ieee80211_local *local = sdata->local; -+ struct ieee80211_key *key; + u32 flags; + + flags = sdata->vif.offload_flags; @@ -315,18 +285,6 @@ Signed-off-by: Felix Fietkau + if (ieee80211_hw_check(&local->hw, SUPPORTS_TX_ENCAP_OFFLOAD) && + ieee80211_iftype_supports_encap_offload(sdata->vif.type)) { + flags |= IEEE80211_OFFLOAD_ENCAP_ENABLED; -+ mutex_lock(&local->key_mtx); -+ list_for_each_entry(key, &sdata->key_list, list) { -+ if (key->conf.cipher == WLAN_CIPHER_SUITE_AES_CMAC || -+ key->conf.cipher == WLAN_CIPHER_SUITE_BIP_GMAC_128 || -+ key->conf.cipher == WLAN_CIPHER_SUITE_BIP_GMAC_256 || -+ key->conf.cipher == WLAN_CIPHER_SUITE_BIP_CMAC_256) -+ continue; -+ if (key->conf.cipher == WLAN_CIPHER_SUITE_TKIP || -+ !(key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE)) -+ flags &= ~IEEE80211_OFFLOAD_ENCAP_ENABLED; -+ } -+ mutex_unlock(&local->key_mtx); + + if (!ieee80211_hw_check(&local->hw, SUPPORTS_TX_FRAG) && + local->hw.wiphy->frag_threshold != (u32)-1) @@ -387,7 +345,7 @@ Signed-off-by: Felix Fietkau void ieee80211_adjust_monitor_flags(struct ieee80211_sub_if_data *sdata, const int offset) { -@@ -587,6 +681,7 @@ int ieee80211_do_open(struct wireless_de +@@ -587,6 +667,7 @@ int ieee80211_do_open(struct wireless_de if (rtnl_dereference(sdata->bss->beacon)) { ieee80211_vif_vlan_copy_chanctx(sdata); netif_carrier_on(dev); @@ -395,7 +353,7 @@ Signed-off-by: Felix Fietkau } else { netif_carrier_off(dev); } -@@ -616,6 +711,7 @@ int ieee80211_do_open(struct wireless_de +@@ -616,6 +697,7 @@ int ieee80211_do_open(struct wireless_de ieee80211_adjust_monitor_flags(sdata, 1); ieee80211_configure_filter(local); @@ -403,7 +361,7 @@ Signed-off-by: Felix Fietkau mutex_lock(&local->mtx); ieee80211_recalc_idle(local); mutex_unlock(&local->mtx); -@@ -625,10 +721,13 @@ int ieee80211_do_open(struct wireless_de +@@ -625,10 +707,13 @@ int ieee80211_do_open(struct wireless_de default: if (coming_up) { ieee80211_del_virtual_monitor(local); @@ -417,7 +375,7 @@ Signed-off-by: Felix Fietkau res = ieee80211_check_queues(sdata, ieee80211_vif_type_p2p(&sdata->vif)); if (res) -@@ -1286,61 +1385,6 @@ static const struct net_device_ops ieee8 +@@ -1286,61 +1371,6 @@ static const struct net_device_ops ieee8 }; @@ -479,7 +437,7 @@ Signed-off-by: Felix Fietkau static void ieee80211_if_free(struct net_device *dev) { free_percpu(netdev_tstats(dev)); -@@ -1371,6 +1415,51 @@ static void ieee80211_if_setup_no_queue( +@@ -1371,6 +1401,32 @@ static void ieee80211_if_setup_no_queue( #endif } @@ -487,7 +445,6 @@ Signed-off-by: Felix Fietkau +{ + struct ieee80211_local *local = sdata->local; + struct ieee80211_sub_if_data *bss = sdata; -+ struct ieee80211_key *key; + bool enabled; + + if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) { @@ -506,24 +463,6 @@ Signed-off-by: Felix Fietkau + !(bss->vif.offload_flags & IEEE80211_OFFLOAD_ENCAP_4ADDR)) + enabled = false; + -+ /* -+ * Encapsulation offload cannot be used with software crypto, and a per-VLAN -+ * key may have been set -+ */ -+ if (enabled && sdata->vif.type == NL80211_IFTYPE_AP_VLAN) { -+ mutex_lock(&local->key_mtx); -+ list_for_each_entry(key, &sdata->key_list, list) { -+ if (key->conf.cipher == WLAN_CIPHER_SUITE_AES_CMAC || -+ key->conf.cipher == WLAN_CIPHER_SUITE_BIP_GMAC_128 || -+ key->conf.cipher == WLAN_CIPHER_SUITE_BIP_GMAC_256 || -+ key->conf.cipher == WLAN_CIPHER_SUITE_BIP_CMAC_256) -+ continue; -+ if (!(key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE)) -+ enabled = false; -+ } -+ mutex_unlock(&local->key_mtx); -+ } -+ + sdata->dev->netdev_ops = enabled ? &ieee80211_dataif_8023_ops : + &ieee80211_dataif_ops; +} @@ -531,7 +470,7 @@ Signed-off-by: Felix Fietkau static void ieee80211_iface_work(struct work_struct *work) { struct ieee80211_sub_if_data *sdata = -@@ -1553,7 +1642,6 @@ static void ieee80211_setup_sdata(struct +@@ -1553,7 +1609,6 @@ static void ieee80211_setup_sdata(struct sdata->vif.bss_conf.txpower = INT_MIN; /* unset */ sdata->noack_map = 0; @@ -539,7 +478,7 @@ Signed-off-by: Felix Fietkau /* only monitor/p2p-device differ */ if (sdata->dev) { -@@ -1688,6 +1776,7 @@ static int ieee80211_runtime_change_ifty +@@ -1688,6 +1743,7 @@ static int ieee80211_runtime_change_ifty ieee80211_teardown_sdata(sdata); @@ -547,7 +486,7 @@ Signed-off-by: Felix Fietkau ret = drv_change_interface(local, sdata, internal_type, p2p); if (ret) type = ieee80211_vif_type_p2p(&sdata->vif); -@@ -1700,6 +1789,7 @@ static int ieee80211_runtime_change_ifty +@@ -1700,6 +1756,7 @@ static int ieee80211_runtime_change_ifty ieee80211_check_queues(sdata, type); ieee80211_setup_sdata(sdata, type); @@ -586,40 +525,6 @@ Signed-off-by: Felix Fietkau case WLAN_CIPHER_SUITE_AES_CMAC: case WLAN_CIPHER_SUITE_BIP_CMAC_256: case WLAN_CIPHER_SUITE_BIP_GMAC_128: -@@ -824,6 +809,7 @@ int ieee80211_key_link(struct ieee80211_ - */ - bool delay_tailroom = sdata->vif.type == NL80211_IFTYPE_STATION; - int ret = -EOPNOTSUPP; -+ bool recalc_offload = false; - - mutex_lock(&sdata->local->key_mtx); - -@@ -864,11 +850,15 @@ int ieee80211_key_link(struct ieee80211_ - key->local = sdata->local; - key->sdata = sdata; - key->sta = sta; -+ recalc_offload = !old_key && key->conf.cipher == WLAN_CIPHER_SUITE_TKIP; - - increment_tailroom_need_count(sdata); - - ret = ieee80211_key_replace(sdata, sta, pairwise, old_key, key); - -+ if (!(key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE)) -+ recalc_offload = true; -+ - if (!ret) { - ieee80211_debugfs_key_add(key); - ieee80211_key_destroy(old_key, delay_tailroom); -@@ -879,6 +869,9 @@ int ieee80211_key_link(struct ieee80211_ - out: - mutex_unlock(&sdata->local->key_mtx); - -+ if (recalc_offload) -+ ieee80211_recalc_offload(sdata->local); -+ - return ret; - } - --- a/net/mac80211/trace.h +++ b/net/mac80211/trace.h @@ -2733,6 +2733,12 @@ TRACE_EVENT(drv_get_ftm_responder_stats, @@ -637,15 +542,72 @@ Signed-off-by: Felix Fietkau #undef TRACE_INCLUDE_PATH --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c -@@ -4264,11 +4264,6 @@ netdev_tx_t ieee80211_subif_start_xmit_8 +@@ -4181,11 +4181,10 @@ static bool ieee80211_tx_8023(struct iee + + static void ieee80211_8023_xmit(struct ieee80211_sub_if_data *sdata, + struct net_device *dev, struct sta_info *sta, +- struct sk_buff *skb) ++ struct ieee80211_key *key, struct sk_buff *skb) + { + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); + struct ieee80211_local *local = sdata->local; +- struct ieee80211_key *key; + struct tid_ampdu_tx *tid_tx; + u8 tid; + +@@ -4234,7 +4233,6 @@ static void ieee80211_8023_xmit(struct i + info->control.flags |= IEEE80211_TX_CTRL_HW_80211_ENCAP; + info->control.vif = &sdata->vif; + +- key = rcu_dereference(sta->ptk[sta->ptk_idx]); + if (key) + info->control.hw_key = &key->conf; + +@@ -4251,12 +4249,9 @@ netdev_tx_t ieee80211_subif_start_xmit_8 + { struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); + struct ethhdr *ehdr = (struct ethhdr *)skb->data; ++ struct ieee80211_key *key; struct sta_info *sta; - +- - if (WARN_ON(!sdata->hw_80211_encap)) { - kfree_skb(skb); - return NETDEV_TX_OK; - } -- ++ bool offload = true; + if (unlikely(skb->len < ETH_HLEN)) { kfree_skb(skb); - return NETDEV_TX_OK; +@@ -4265,15 +4260,26 @@ netdev_tx_t ieee80211_subif_start_xmit_8 + + rcu_read_lock(); + +- if (ieee80211_lookup_ra_sta(sdata, skb, &sta)) ++ if (ieee80211_lookup_ra_sta(sdata, skb, &sta)) { + kfree_skb(skb); +- else if (unlikely(IS_ERR_OR_NULL(sta) || !sta->uploaded || +- !test_sta_flag(sta, WLAN_STA_AUTHORIZED) || +- sdata->control_port_protocol == ehdr->h_proto)) +- ieee80211_subif_start_xmit(skb, dev); ++ goto out; ++ } ++ ++ if (unlikely(IS_ERR_OR_NULL(sta) || !sta->uploaded || ++ !test_sta_flag(sta, WLAN_STA_AUTHORIZED) || ++ sdata->control_port_protocol == ehdr->h_proto)) ++ offload = false; ++ else if ((key = rcu_dereference(sta->ptk[sta->ptk_idx])) && ++ (!(key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) || ++ key->conf.cipher == WLAN_CIPHER_SUITE_TKIP)) ++ offload = false; ++ ++ if (offload) ++ ieee80211_8023_xmit(sdata, dev, sta, key, skb); + else +- ieee80211_8023_xmit(sdata, dev, sta, skb); ++ ieee80211_subif_start_xmit(skb, dev); + ++out: + rcu_read_unlock(); + + return NETDEV_TX_OK; diff --git a/package/kernel/mac80211/patches/subsys/315-mac80211-reduce-duplication-in-tx-status-functions.patch b/package/kernel/mac80211/patches/subsys/319-mac80211-reduce-duplication-in-tx-status-functions.patch similarity index 100% rename from package/kernel/mac80211/patches/subsys/315-mac80211-reduce-duplication-in-tx-status-functions.patch rename to package/kernel/mac80211/patches/subsys/319-mac80211-reduce-duplication-in-tx-status-functions.patch diff --git a/package/kernel/mac80211/patches/subsys/316-mac80211-remove-tx-status-call-to-ieee80211_sta_regi.patch b/package/kernel/mac80211/patches/subsys/320-mac80211-remove-tx-status-call-to-ieee80211_sta_regi.patch similarity index 100% rename from package/kernel/mac80211/patches/subsys/316-mac80211-remove-tx-status-call-to-ieee80211_sta_regi.patch rename to package/kernel/mac80211/patches/subsys/320-mac80211-remove-tx-status-call-to-ieee80211_sta_regi.patch diff --git a/package/kernel/mac80211/patches/subsys/317-mac80211-optimize-station-connection-monitor.patch b/package/kernel/mac80211/patches/subsys/321-mac80211-optimize-station-connection-monitor.patch similarity index 100% rename from package/kernel/mac80211/patches/subsys/317-mac80211-optimize-station-connection-monitor.patch rename to package/kernel/mac80211/patches/subsys/321-mac80211-optimize-station-connection-monitor.patch diff --git a/package/kernel/mac80211/patches/subsys/318-mac80211-swap-NEED_TXPROCESSING-and-HW_80211_ENCAP-t.patch b/package/kernel/mac80211/patches/subsys/322-mac80211-swap-NEED_TXPROCESSING-and-HW_80211_ENCAP-t.patch similarity index 97% rename from package/kernel/mac80211/patches/subsys/318-mac80211-swap-NEED_TXPROCESSING-and-HW_80211_ENCAP-t.patch rename to package/kernel/mac80211/patches/subsys/322-mac80211-swap-NEED_TXPROCESSING-and-HW_80211_ENCAP-t.patch index 85287a6ef1..b9069ef9b8 100644 --- a/package/kernel/mac80211/patches/subsys/318-mac80211-swap-NEED_TXPROCESSING-and-HW_80211_ENCAP-t.patch +++ b/package/kernel/mac80211/patches/subsys/322-mac80211-swap-NEED_TXPROCESSING-and-HW_80211_ENCAP-t.patch @@ -198,7 +198,7 @@ Signed-off-by: Felix Fietkau goto encap_out; if (info->control.flags & IEEE80211_TX_CTRL_FAST_XMIT) { -@@ -4247,7 +4247,7 @@ static void ieee80211_8023_xmit(struct i +@@ -4230,7 +4230,7 @@ static void ieee80211_8023_xmit(struct i sdata = container_of(sdata->bss, struct ieee80211_sub_if_data, u.ap); @@ -206,8 +206,8 @@ Signed-off-by: Felix Fietkau + info->flags |= IEEE80211_TX_CTL_HW_80211_ENCAP; info->control.vif = &sdata->vif; - ieee80211_tx_8023(sdata, skb, skb->len, sta, false); -@@ -4351,7 +4351,7 @@ static bool ieee80211_tx_pending_skb(str + if (key) +@@ -4355,7 +4355,7 @@ static bool ieee80211_tx_pending_skb(str sdata = vif_to_sdata(info->control.vif); @@ -216,7 +216,7 @@ Signed-off-by: Felix Fietkau chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); if (unlikely(!chanctx_conf)) { dev_kfree_skb(skb); -@@ -4359,7 +4359,7 @@ static bool ieee80211_tx_pending_skb(str +@@ -4363,7 +4363,7 @@ static bool ieee80211_tx_pending_skb(str } info->band = chanctx_conf->def.chan->band; result = ieee80211_tx(sdata, NULL, skb, true, 0); diff --git a/package/kernel/mac80211/patches/subsys/319-mac80211-unify-802.3-offload-and-802.11-tx-status-co.patch b/package/kernel/mac80211/patches/subsys/323-mac80211-unify-802.3-offload-and-802.11-tx-status-co.patch similarity index 100% rename from package/kernel/mac80211/patches/subsys/319-mac80211-unify-802.3-offload-and-802.11-tx-status-co.patch rename to package/kernel/mac80211/patches/subsys/323-mac80211-unify-802.3-offload-and-802.11-tx-status-co.patch diff --git a/package/kernel/mac80211/patches/subsys/322-mac80211-support-using-ieee80211_tx_status_ext-to-fr.patch b/package/kernel/mac80211/patches/subsys/324-mac80211-support-using-ieee80211_tx_status_ext-to-fr.patch similarity index 100% rename from package/kernel/mac80211/patches/subsys/322-mac80211-support-using-ieee80211_tx_status_ext-to-fr.patch rename to package/kernel/mac80211/patches/subsys/324-mac80211-support-using-ieee80211_tx_status_ext-to-fr.patch diff --git a/package/kernel/mac80211/patches/subsys/323-mac80211-extend-ieee80211_tx_status_ext-to-support-b.patch b/package/kernel/mac80211/patches/subsys/325-mac80211-extend-ieee80211_tx_status_ext-to-support-b.patch similarity index 98% rename from package/kernel/mac80211/patches/subsys/323-mac80211-extend-ieee80211_tx_status_ext-to-support-b.patch rename to package/kernel/mac80211/patches/subsys/325-mac80211-extend-ieee80211_tx_status_ext-to-support-b.patch index c0f2b7b10a..e8b29bb4c5 100644 --- a/package/kernel/mac80211/patches/subsys/323-mac80211-extend-ieee80211_tx_status_ext-to-support-b.patch +++ b/package/kernel/mac80211/patches/subsys/325-mac80211-extend-ieee80211_tx_status_ext-to-support-b.patch @@ -1,7 +1,7 @@ From: Felix Fietkau Date: Fri, 21 Aug 2020 05:49:07 +0200 -Subject: [PATCH] mac80211: extend ieee80211_tx_status_ext to support bulk - free +Subject: [PATCH] mac80211: extend ieee80211_tx_status_ext to support + bulk free Store processed skbs ready to be freed in a list so the driver bulk free them diff --git a/package/kernel/mac80211/patches/subsys/324-mac80211-notify-the-driver-when-a-sta-uses-4-address.patch b/package/kernel/mac80211/patches/subsys/326-mac80211-notify-the-driver-when-a-sta-uses-4-address.patch similarity index 97% rename from package/kernel/mac80211/patches/subsys/324-mac80211-notify-the-driver-when-a-sta-uses-4-address.patch rename to package/kernel/mac80211/patches/subsys/326-mac80211-notify-the-driver-when-a-sta-uses-4-address.patch index abfb5b76d0..5ad5ac6a78 100644 --- a/package/kernel/mac80211/patches/subsys/324-mac80211-notify-the-driver-when-a-sta-uses-4-address.patch +++ b/package/kernel/mac80211/patches/subsys/326-mac80211-notify-the-driver-when-a-sta-uses-4-address.patch @@ -30,7 +30,7 @@ Signed-off-by: Felix Fietkau /** --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c -@@ -1698,6 +1698,7 @@ static int ieee80211_change_station(stru +@@ -1693,6 +1693,7 @@ static int ieee80211_change_station(stru rcu_assign_pointer(vlansdata->u.vlan.sta, sta); __ieee80211_check_fast_rx_iface(vlansdata); diff --git a/package/kernel/mac80211/patches/subsys/327-mac80211-reorganize-code-to-remove-a-forward-declara.patch b/package/kernel/mac80211/patches/subsys/327-mac80211-reorganize-code-to-remove-a-forward-declara.patch new file mode 100644 index 0000000000..a3d600152c --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/327-mac80211-reorganize-code-to-remove-a-forward-declara.patch @@ -0,0 +1,1110 @@ +From: Felix Fietkau +Date: Tue, 8 Sep 2020 12:16:26 +0200 +Subject: [PATCH] mac80211: reorganize code to remove a forward + declaration + +Remove the newly added ieee80211_set_vif_encap_ops declaration. +No further code changes + +Signed-off-by: Felix Fietkau +--- + +--- a/net/mac80211/iface.c ++++ b/net/mac80211/iface.c +@@ -43,7 +43,6 @@ + */ + + static void ieee80211_iface_work(struct work_struct *work); +-static void ieee80211_set_vif_encap_ops(struct ieee80211_sub_if_data *sdata); + + bool __ieee80211_recalc_txpower(struct ieee80211_sub_if_data *sdata) + { +@@ -349,6 +348,511 @@ static int ieee80211_check_queues(struct + return 0; + } + ++static int ieee80211_open(struct net_device *dev) ++{ ++ struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); ++ int err; ++ ++ /* fail early if user set an invalid address */ ++ if (!is_valid_ether_addr(dev->dev_addr)) ++ return -EADDRNOTAVAIL; ++ ++ err = ieee80211_check_concurrent_iface(sdata, sdata->vif.type); ++ if (err) ++ return err; ++ ++ return ieee80211_do_open(&sdata->wdev, true); ++} ++ ++static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, ++ bool going_down) ++{ ++ struct ieee80211_local *local = sdata->local; ++ unsigned long flags; ++ struct sk_buff *skb, *tmp; ++ u32 hw_reconf_flags = 0; ++ int i, flushed; ++ struct ps_data *ps; ++ struct cfg80211_chan_def chandef; ++ bool cancel_scan; ++ struct cfg80211_nan_func *func; ++ ++ clear_bit(SDATA_STATE_RUNNING, &sdata->state); ++ ++ cancel_scan = rcu_access_pointer(local->scan_sdata) == sdata; ++ if (cancel_scan) ++ ieee80211_scan_cancel(local); ++ ++ /* ++ * Stop TX on this interface first. ++ */ ++ if (sdata->dev) ++ netif_tx_stop_all_queues(sdata->dev); ++ ++ ieee80211_roc_purge(local, sdata); ++ ++ switch (sdata->vif.type) { ++ case NL80211_IFTYPE_STATION: ++ ieee80211_mgd_stop(sdata); ++ break; ++ case NL80211_IFTYPE_ADHOC: ++ ieee80211_ibss_stop(sdata); ++ break; ++ case NL80211_IFTYPE_MONITOR: ++ if (sdata->u.mntr.flags & MONITOR_FLAG_COOK_FRAMES) ++ break; ++ list_del_rcu(&sdata->u.mntr.list); ++ break; ++ default: ++ break; ++ } ++ ++ /* ++ * Remove all stations associated with this interface. ++ * ++ * This must be done before calling ops->remove_interface() ++ * because otherwise we can later invoke ops->sta_notify() ++ * whenever the STAs are removed, and that invalidates driver ++ * assumptions about always getting a vif pointer that is valid ++ * (because if we remove a STA after ops->remove_interface() ++ * the driver will have removed the vif info already!) ++ * ++ * In WDS mode a station must exist here and be flushed, for ++ * AP_VLANs stations may exist since there's nothing else that ++ * would have removed them, but in other modes there shouldn't ++ * be any stations. ++ */ ++ flushed = sta_info_flush(sdata); ++ WARN_ON_ONCE(sdata->vif.type != NL80211_IFTYPE_AP_VLAN && ++ ((sdata->vif.type != NL80211_IFTYPE_WDS && flushed > 0) || ++ (sdata->vif.type == NL80211_IFTYPE_WDS && flushed != 1))); ++ ++ /* don't count this interface for allmulti while it is down */ ++ if (sdata->flags & IEEE80211_SDATA_ALLMULTI) ++ atomic_dec(&local->iff_allmultis); ++ ++ if (sdata->vif.type == NL80211_IFTYPE_AP) { ++ local->fif_pspoll--; ++ local->fif_probe_req--; ++ } else if (sdata->vif.type == NL80211_IFTYPE_ADHOC) { ++ local->fif_probe_req--; ++ } ++ ++ if (sdata->dev) { ++ netif_addr_lock_bh(sdata->dev); ++ spin_lock_bh(&local->filter_lock); ++ __hw_addr_unsync(&local->mc_list, &sdata->dev->mc, ++ sdata->dev->addr_len); ++ spin_unlock_bh(&local->filter_lock); ++ netif_addr_unlock_bh(sdata->dev); ++ } ++ ++ del_timer_sync(&local->dynamic_ps_timer); ++ cancel_work_sync(&local->dynamic_ps_enable_work); ++ ++ cancel_work_sync(&sdata->recalc_smps); ++ sdata_lock(sdata); ++ mutex_lock(&local->mtx); ++ sdata->vif.csa_active = false; ++ if (sdata->vif.type == NL80211_IFTYPE_STATION) ++ sdata->u.mgd.csa_waiting_bcn = false; ++ if (sdata->csa_block_tx) { ++ ieee80211_wake_vif_queues(local, sdata, ++ IEEE80211_QUEUE_STOP_REASON_CSA); ++ sdata->csa_block_tx = false; ++ } ++ mutex_unlock(&local->mtx); ++ sdata_unlock(sdata); ++ ++ cancel_work_sync(&sdata->csa_finalize_work); ++ ++ cancel_delayed_work_sync(&sdata->dfs_cac_timer_work); ++ ++ if (sdata->wdev.cac_started) { ++ chandef = sdata->vif.bss_conf.chandef; ++ WARN_ON(local->suspended); ++ mutex_lock(&local->mtx); ++ ieee80211_vif_release_channel(sdata); ++ mutex_unlock(&local->mtx); ++ cfg80211_cac_event(sdata->dev, &chandef, ++ NL80211_RADAR_CAC_ABORTED, ++ GFP_KERNEL); ++ } ++ ++ /* APs need special treatment */ ++ if (sdata->vif.type == NL80211_IFTYPE_AP) { ++ struct ieee80211_sub_if_data *vlan, *tmpsdata; ++ ++ /* down all dependent devices, that is VLANs */ ++ list_for_each_entry_safe(vlan, tmpsdata, &sdata->u.ap.vlans, ++ u.vlan.list) ++ dev_close(vlan->dev); ++ WARN_ON(!list_empty(&sdata->u.ap.vlans)); ++ } else if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) { ++ /* remove all packets in parent bc_buf pointing to this dev */ ++ ps = &sdata->bss->ps; ++ ++ spin_lock_irqsave(&ps->bc_buf.lock, flags); ++ skb_queue_walk_safe(&ps->bc_buf, skb, tmp) { ++ if (skb->dev == sdata->dev) { ++ __skb_unlink(skb, &ps->bc_buf); ++ local->total_ps_buffered--; ++ ieee80211_free_txskb(&local->hw, skb); ++ } ++ } ++ spin_unlock_irqrestore(&ps->bc_buf.lock, flags); ++ } ++ ++ if (going_down) ++ local->open_count--; ++ ++ switch (sdata->vif.type) { ++ case NL80211_IFTYPE_AP_VLAN: ++ mutex_lock(&local->mtx); ++ list_del(&sdata->u.vlan.list); ++ mutex_unlock(&local->mtx); ++ RCU_INIT_POINTER(sdata->vif.chanctx_conf, NULL); ++ /* see comment in the default case below */ ++ ieee80211_free_keys(sdata, true); ++ /* no need to tell driver */ ++ break; ++ case NL80211_IFTYPE_MONITOR: ++ if (sdata->u.mntr.flags & MONITOR_FLAG_COOK_FRAMES) { ++ local->cooked_mntrs--; ++ break; ++ } ++ ++ local->monitors--; ++ if (local->monitors == 0) { ++ local->hw.conf.flags &= ~IEEE80211_CONF_MONITOR; ++ hw_reconf_flags |= IEEE80211_CONF_CHANGE_MONITOR; ++ } ++ ++ ieee80211_adjust_monitor_flags(sdata, -1); ++ break; ++ case NL80211_IFTYPE_NAN: ++ /* clean all the functions */ ++ spin_lock_bh(&sdata->u.nan.func_lock); ++ ++ idr_for_each_entry(&sdata->u.nan.function_inst_ids, func, i) { ++ idr_remove(&sdata->u.nan.function_inst_ids, i); ++ cfg80211_free_nan_func(func); ++ } ++ idr_destroy(&sdata->u.nan.function_inst_ids); ++ ++ spin_unlock_bh(&sdata->u.nan.func_lock); ++ break; ++ case NL80211_IFTYPE_P2P_DEVICE: ++ /* relies on synchronize_rcu() below */ ++ RCU_INIT_POINTER(local->p2p_sdata, NULL); ++ /* fall through */ ++ default: ++ cancel_work_sync(&sdata->work); ++ /* ++ * When we get here, the interface is marked down. ++ * Free the remaining keys, if there are any ++ * (which can happen in AP mode if userspace sets ++ * keys before the interface is operating, and maybe ++ * also in WDS mode) ++ * ++ * Force the key freeing to always synchronize_net() ++ * to wait for the RX path in case it is using this ++ * interface enqueuing frames at this very time on ++ * another CPU. ++ */ ++ ieee80211_free_keys(sdata, true); ++ skb_queue_purge(&sdata->skb_queue); ++ } ++ ++ spin_lock_irqsave(&local->queue_stop_reason_lock, flags); ++ for (i = 0; i < IEEE80211_MAX_QUEUES; i++) { ++ skb_queue_walk_safe(&local->pending[i], skb, tmp) { ++ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); ++ if (info->control.vif == &sdata->vif) { ++ __skb_unlink(skb, &local->pending[i]); ++ ieee80211_free_txskb(&local->hw, skb); ++ } ++ } ++ } ++ spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); ++ ++ if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) ++ ieee80211_txq_remove_vlan(local, sdata); ++ ++ sdata->bss = NULL; ++ ++ if (local->open_count == 0) ++ ieee80211_clear_tx_pending(local); ++ ++ sdata->vif.bss_conf.beacon_int = 0; ++ ++ /* ++ * If the interface goes down while suspended, presumably because ++ * the device was unplugged and that happens before our resume, ++ * then the driver is already unconfigured and the remainder of ++ * this function isn't needed. ++ * XXX: what about WoWLAN? If the device has software state, e.g. ++ * memory allocated, it might expect teardown commands from ++ * mac80211 here? ++ */ ++ if (local->suspended) { ++ WARN_ON(local->wowlan); ++ WARN_ON(rtnl_dereference(local->monitor_sdata)); ++ return; ++ } ++ ++ switch (sdata->vif.type) { ++ case NL80211_IFTYPE_AP_VLAN: ++ break; ++ case NL80211_IFTYPE_MONITOR: ++ if (local->monitors == 0) ++ ieee80211_del_virtual_monitor(local); ++ ++ mutex_lock(&local->mtx); ++ ieee80211_recalc_idle(local); ++ mutex_unlock(&local->mtx); ++ ++ if (!(sdata->u.mntr.flags & MONITOR_FLAG_ACTIVE)) ++ break; ++ ++ /* fall through */ ++ default: ++ if (going_down) ++ drv_remove_interface(local, sdata); ++ } ++ ++ ieee80211_recalc_ps(local); ++ ++ if (cancel_scan) ++ flush_delayed_work(&local->scan_work); ++ ++ if (local->open_count == 0) { ++ ieee80211_stop_device(local); ++ ++ /* no reconfiguring after stop! */ ++ return; ++ } ++ ++ /* do after stop to avoid reconfiguring when we stop anyway */ ++ ieee80211_configure_filter(local); ++ ieee80211_hw_config(local, hw_reconf_flags); ++ ++ if (local->monitors == local->open_count) ++ ieee80211_add_virtual_monitor(local); ++} ++ ++static int ieee80211_stop(struct net_device *dev) ++{ ++ struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); ++ ++ ieee80211_do_stop(sdata, true); ++ ++ return 0; ++} ++ ++static void ieee80211_set_multicast_list(struct net_device *dev) ++{ ++ struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); ++ struct ieee80211_local *local = sdata->local; ++ int allmulti, sdata_allmulti; ++ ++ allmulti = !!(dev->flags & IFF_ALLMULTI); ++ sdata_allmulti = !!(sdata->flags & IEEE80211_SDATA_ALLMULTI); ++ ++ if (allmulti != sdata_allmulti) { ++ if (dev->flags & IFF_ALLMULTI) ++ atomic_inc(&local->iff_allmultis); ++ else ++ atomic_dec(&local->iff_allmultis); ++ sdata->flags ^= IEEE80211_SDATA_ALLMULTI; ++ } ++ ++ spin_lock_bh(&local->filter_lock); ++ __hw_addr_sync(&local->mc_list, &dev->mc, dev->addr_len); ++ spin_unlock_bh(&local->filter_lock); ++ ieee80211_queue_work(&local->hw, &local->reconfig_filter); ++} ++ ++/* ++ * Called when the netdev is removed or, by the code below, before ++ * the interface type changes. ++ */ ++static void ieee80211_teardown_sdata(struct ieee80211_sub_if_data *sdata) ++{ ++ int i; ++ ++ /* free extra data */ ++ ieee80211_free_keys(sdata, false); ++ ++ ieee80211_debugfs_remove_netdev(sdata); ++ ++ for (i = 0; i < IEEE80211_FRAGMENT_MAX; i++) ++ __skb_queue_purge(&sdata->fragments[i].skb_list); ++ sdata->fragment_next = 0; ++ ++ if (ieee80211_vif_is_mesh(&sdata->vif)) ++ ieee80211_mesh_teardown_sdata(sdata); ++} ++ ++static void ieee80211_uninit(struct net_device *dev) ++{ ++ ieee80211_teardown_sdata(IEEE80211_DEV_TO_SUB_IF(dev)); ++} ++ ++#if LINUX_VERSION_IS_GEQ(5,2,0) ++static u16 ieee80211_netdev_select_queue(struct net_device *dev, ++ struct sk_buff *skb, ++ struct net_device *sb_dev) ++#elif LINUX_VERSION_IS_GEQ(4,19,0) ++static u16 ieee80211_netdev_select_queue(struct net_device *dev, ++ struct sk_buff *skb, ++ struct net_device *sb_dev, ++ select_queue_fallback_t fallback) ++#elif LINUX_VERSION_IS_GEQ(3,14,0) || \ ++ (LINUX_VERSION_CODE == KERNEL_VERSION(3,13,11) && UTS_UBUNTU_RELEASE_ABI > 30) ++static u16 ieee80211_netdev_select_queue(struct net_device *dev, ++ struct sk_buff *skb, ++ void *accel_priv, ++ select_queue_fallback_t fallback) ++#elif LINUX_VERSION_IS_GEQ(3,13,0) ++static u16 ieee80211_netdev_select_queue(struct net_device *dev, ++ struct sk_buff *skb, ++ void *accel_priv) ++#else ++static u16 ieee80211_netdev_select_queue(struct net_device *dev, ++ struct sk_buff *skb) ++#endif ++{ ++ return ieee80211_select_queue(IEEE80211_DEV_TO_SUB_IF(dev), skb); ++} ++ ++static void ++ieee80211_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats) ++{ ++ int i; ++ ++ for_each_possible_cpu(i) { ++ const struct pcpu_sw_netstats *tstats; ++ u64 rx_packets, rx_bytes, tx_packets, tx_bytes; ++ unsigned int start; ++ ++ tstats = per_cpu_ptr(netdev_tstats(dev), i); ++ ++ do { ++ start = u64_stats_fetch_begin_irq(&tstats->syncp); ++ rx_packets = tstats->rx_packets; ++ tx_packets = tstats->tx_packets; ++ rx_bytes = tstats->rx_bytes; ++ tx_bytes = tstats->tx_bytes; ++ } while (u64_stats_fetch_retry_irq(&tstats->syncp, start)); ++ ++ stats->rx_packets += rx_packets; ++ stats->tx_packets += tx_packets; ++ stats->rx_bytes += rx_bytes; ++ stats->tx_bytes += tx_bytes; ++ } ++} ++#if LINUX_VERSION_IS_LESS(4,11,0) ++/* Just declare it here to keep sparse happy */ ++struct rtnl_link_stats64 *bp_ieee80211_get_stats64(struct net_device *dev, ++ struct rtnl_link_stats64 *stats); ++struct rtnl_link_stats64 * ++bp_ieee80211_get_stats64(struct net_device *dev, ++ struct rtnl_link_stats64 *stats){ ++ ieee80211_get_stats64(dev, stats); ++ return stats; ++} ++#endif ++ ++static const struct net_device_ops ieee80211_dataif_ops = { ++ .ndo_open = ieee80211_open, ++ .ndo_stop = ieee80211_stop, ++ .ndo_uninit = ieee80211_uninit, ++ .ndo_start_xmit = ieee80211_subif_start_xmit, ++ .ndo_set_rx_mode = ieee80211_set_multicast_list, ++ .ndo_set_mac_address = ieee80211_change_mac, ++ .ndo_select_queue = ieee80211_netdev_select_queue, ++#if LINUX_VERSION_IS_GEQ(4,11,0) ++ .ndo_get_stats64 = ieee80211_get_stats64, ++#else ++ .ndo_get_stats64 = bp_ieee80211_get_stats64, ++#endif ++ ++}; ++ ++#if LINUX_VERSION_IS_GEQ(5,2,0) ++static u16 ieee80211_monitor_select_queue(struct net_device *dev, ++ struct sk_buff *skb, ++ struct net_device *sb_dev) ++#elif LINUX_VERSION_IS_GEQ(4,19,0) ++static u16 ieee80211_monitor_select_queue(struct net_device *dev, ++ struct sk_buff *skb, ++ struct net_device *sb_dev, ++ select_queue_fallback_t fallback) ++#elif LINUX_VERSION_IS_GEQ(3,14,0) || \ ++ (LINUX_VERSION_CODE == KERNEL_VERSION(3,13,11) && UTS_UBUNTU_RELEASE_ABI > 30) ++static u16 ieee80211_monitor_select_queue(struct net_device *dev, ++ struct sk_buff *skb, ++ void *accel_priv, ++ select_queue_fallback_t fallback) ++#elif LINUX_VERSION_IS_GEQ(3,13,0) ++static u16 ieee80211_monitor_select_queue(struct net_device *dev, ++ struct sk_buff *skb, ++ void *accel_priv) ++#else ++static u16 ieee80211_monitor_select_queue(struct net_device *dev, ++ struct sk_buff *skb) ++#endif ++{ ++ struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); ++ struct ieee80211_local *local = sdata->local; ++ struct ieee80211_hdr *hdr; ++ struct ieee80211_radiotap_header *rtap = (void *)skb->data; ++ ++ if (local->hw.queues < IEEE80211_NUM_ACS) ++ return 0; ++ ++ if (skb->len < 4 || ++ skb->len < le16_to_cpu(rtap->it_len) + 2 /* frame control */) ++ return 0; /* doesn't matter, frame will be dropped */ ++ ++ hdr = (void *)((u8 *)skb->data + le16_to_cpu(rtap->it_len)); ++ ++ return ieee80211_select_queue_80211(sdata, skb, hdr); ++} ++ ++static const struct net_device_ops ieee80211_monitorif_ops = { ++ .ndo_open = ieee80211_open, ++ .ndo_stop = ieee80211_stop, ++ .ndo_uninit = ieee80211_uninit, ++ .ndo_start_xmit = ieee80211_monitor_start_xmit, ++ .ndo_set_rx_mode = ieee80211_set_multicast_list, ++ .ndo_set_mac_address = ieee80211_change_mac, ++ .ndo_select_queue = ieee80211_monitor_select_queue, ++#if LINUX_VERSION_IS_GEQ(4,11,0) ++ .ndo_get_stats64 = ieee80211_get_stats64, ++#else ++ .ndo_get_stats64 = bp_ieee80211_get_stats64, ++#endif ++ ++}; ++ ++static const struct net_device_ops ieee80211_dataif_8023_ops = { ++ .ndo_open = ieee80211_open, ++ .ndo_stop = ieee80211_stop, ++ .ndo_uninit = ieee80211_uninit, ++ .ndo_start_xmit = ieee80211_subif_start_xmit_8023, ++ .ndo_set_rx_mode = ieee80211_set_multicast_list, ++ .ndo_set_mac_address = ieee80211_change_mac, ++ .ndo_select_queue = ieee80211_netdev_select_queue, ++#if LINUX_VERSION_IS_GEQ(4,11,0) ++ .ndo_get_stats64 = ieee80211_get_stats64, ++#else ++ .ndo_get_stats64 = bp_ieee80211_get_stats64, ++#endif ++ ++}; ++ + static bool ieee80211_iftype_supports_encap_offload(enum nl80211_iftype iftype) + { + switch (iftype) { +@@ -389,6 +893,31 @@ static bool ieee80211_set_sdata_offload_ + return true; + } + ++static void ieee80211_set_vif_encap_ops(struct ieee80211_sub_if_data *sdata) ++{ ++ struct ieee80211_local *local = sdata->local; ++ struct ieee80211_sub_if_data *bss = sdata; ++ bool enabled; ++ ++ if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) { ++ if (!sdata->bss) ++ return; ++ ++ bss = container_of(sdata->bss, struct ieee80211_sub_if_data, u.ap); ++ } ++ ++ if (!ieee80211_hw_check(&local->hw, SUPPORTS_TX_ENCAP_OFFLOAD) || ++ !ieee80211_iftype_supports_encap_offload(bss->vif.type)) ++ return; ++ ++ enabled = bss->vif.offload_flags & IEEE80211_OFFLOAD_ENCAP_ENABLED; ++ if (sdata->wdev.use_4addr && ++ !(bss->vif.offload_flags & IEEE80211_OFFLOAD_ENCAP_4ADDR)) ++ enabled = false; ++ ++ sdata->dev->netdev_ops = enabled ? &ieee80211_dataif_8023_ops : ++ &ieee80211_dataif_ops; ++} + + static void ieee80211_recalc_sdata_offload(struct ieee80211_sub_if_data *sdata) + { +@@ -866,511 +1395,6 @@ int ieee80211_do_open(struct wireless_de + return res; + } + +-static int ieee80211_open(struct net_device *dev) +-{ +- struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); +- int err; +- +- /* fail early if user set an invalid address */ +- if (!is_valid_ether_addr(dev->dev_addr)) +- return -EADDRNOTAVAIL; +- +- err = ieee80211_check_concurrent_iface(sdata, sdata->vif.type); +- if (err) +- return err; +- +- return ieee80211_do_open(&sdata->wdev, true); +-} +- +-static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, +- bool going_down) +-{ +- struct ieee80211_local *local = sdata->local; +- unsigned long flags; +- struct sk_buff *skb, *tmp; +- u32 hw_reconf_flags = 0; +- int i, flushed; +- struct ps_data *ps; +- struct cfg80211_chan_def chandef; +- bool cancel_scan; +- struct cfg80211_nan_func *func; +- +- clear_bit(SDATA_STATE_RUNNING, &sdata->state); +- +- cancel_scan = rcu_access_pointer(local->scan_sdata) == sdata; +- if (cancel_scan) +- ieee80211_scan_cancel(local); +- +- /* +- * Stop TX on this interface first. +- */ +- if (sdata->dev) +- netif_tx_stop_all_queues(sdata->dev); +- +- ieee80211_roc_purge(local, sdata); +- +- switch (sdata->vif.type) { +- case NL80211_IFTYPE_STATION: +- ieee80211_mgd_stop(sdata); +- break; +- case NL80211_IFTYPE_ADHOC: +- ieee80211_ibss_stop(sdata); +- break; +- case NL80211_IFTYPE_MONITOR: +- if (sdata->u.mntr.flags & MONITOR_FLAG_COOK_FRAMES) +- break; +- list_del_rcu(&sdata->u.mntr.list); +- break; +- default: +- break; +- } +- +- /* +- * Remove all stations associated with this interface. +- * +- * This must be done before calling ops->remove_interface() +- * because otherwise we can later invoke ops->sta_notify() +- * whenever the STAs are removed, and that invalidates driver +- * assumptions about always getting a vif pointer that is valid +- * (because if we remove a STA after ops->remove_interface() +- * the driver will have removed the vif info already!) +- * +- * In WDS mode a station must exist here and be flushed, for +- * AP_VLANs stations may exist since there's nothing else that +- * would have removed them, but in other modes there shouldn't +- * be any stations. +- */ +- flushed = sta_info_flush(sdata); +- WARN_ON_ONCE(sdata->vif.type != NL80211_IFTYPE_AP_VLAN && +- ((sdata->vif.type != NL80211_IFTYPE_WDS && flushed > 0) || +- (sdata->vif.type == NL80211_IFTYPE_WDS && flushed != 1))); +- +- /* don't count this interface for allmulti while it is down */ +- if (sdata->flags & IEEE80211_SDATA_ALLMULTI) +- atomic_dec(&local->iff_allmultis); +- +- if (sdata->vif.type == NL80211_IFTYPE_AP) { +- local->fif_pspoll--; +- local->fif_probe_req--; +- } else if (sdata->vif.type == NL80211_IFTYPE_ADHOC) { +- local->fif_probe_req--; +- } +- +- if (sdata->dev) { +- netif_addr_lock_bh(sdata->dev); +- spin_lock_bh(&local->filter_lock); +- __hw_addr_unsync(&local->mc_list, &sdata->dev->mc, +- sdata->dev->addr_len); +- spin_unlock_bh(&local->filter_lock); +- netif_addr_unlock_bh(sdata->dev); +- } +- +- del_timer_sync(&local->dynamic_ps_timer); +- cancel_work_sync(&local->dynamic_ps_enable_work); +- +- cancel_work_sync(&sdata->recalc_smps); +- sdata_lock(sdata); +- mutex_lock(&local->mtx); +- sdata->vif.csa_active = false; +- if (sdata->vif.type == NL80211_IFTYPE_STATION) +- sdata->u.mgd.csa_waiting_bcn = false; +- if (sdata->csa_block_tx) { +- ieee80211_wake_vif_queues(local, sdata, +- IEEE80211_QUEUE_STOP_REASON_CSA); +- sdata->csa_block_tx = false; +- } +- mutex_unlock(&local->mtx); +- sdata_unlock(sdata); +- +- cancel_work_sync(&sdata->csa_finalize_work); +- +- cancel_delayed_work_sync(&sdata->dfs_cac_timer_work); +- +- if (sdata->wdev.cac_started) { +- chandef = sdata->vif.bss_conf.chandef; +- WARN_ON(local->suspended); +- mutex_lock(&local->mtx); +- ieee80211_vif_release_channel(sdata); +- mutex_unlock(&local->mtx); +- cfg80211_cac_event(sdata->dev, &chandef, +- NL80211_RADAR_CAC_ABORTED, +- GFP_KERNEL); +- } +- +- /* APs need special treatment */ +- if (sdata->vif.type == NL80211_IFTYPE_AP) { +- struct ieee80211_sub_if_data *vlan, *tmpsdata; +- +- /* down all dependent devices, that is VLANs */ +- list_for_each_entry_safe(vlan, tmpsdata, &sdata->u.ap.vlans, +- u.vlan.list) +- dev_close(vlan->dev); +- WARN_ON(!list_empty(&sdata->u.ap.vlans)); +- } else if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) { +- /* remove all packets in parent bc_buf pointing to this dev */ +- ps = &sdata->bss->ps; +- +- spin_lock_irqsave(&ps->bc_buf.lock, flags); +- skb_queue_walk_safe(&ps->bc_buf, skb, tmp) { +- if (skb->dev == sdata->dev) { +- __skb_unlink(skb, &ps->bc_buf); +- local->total_ps_buffered--; +- ieee80211_free_txskb(&local->hw, skb); +- } +- } +- spin_unlock_irqrestore(&ps->bc_buf.lock, flags); +- } +- +- if (going_down) +- local->open_count--; +- +- switch (sdata->vif.type) { +- case NL80211_IFTYPE_AP_VLAN: +- mutex_lock(&local->mtx); +- list_del(&sdata->u.vlan.list); +- mutex_unlock(&local->mtx); +- RCU_INIT_POINTER(sdata->vif.chanctx_conf, NULL); +- /* see comment in the default case below */ +- ieee80211_free_keys(sdata, true); +- /* no need to tell driver */ +- break; +- case NL80211_IFTYPE_MONITOR: +- if (sdata->u.mntr.flags & MONITOR_FLAG_COOK_FRAMES) { +- local->cooked_mntrs--; +- break; +- } +- +- local->monitors--; +- if (local->monitors == 0) { +- local->hw.conf.flags &= ~IEEE80211_CONF_MONITOR; +- hw_reconf_flags |= IEEE80211_CONF_CHANGE_MONITOR; +- } +- +- ieee80211_adjust_monitor_flags(sdata, -1); +- break; +- case NL80211_IFTYPE_NAN: +- /* clean all the functions */ +- spin_lock_bh(&sdata->u.nan.func_lock); +- +- idr_for_each_entry(&sdata->u.nan.function_inst_ids, func, i) { +- idr_remove(&sdata->u.nan.function_inst_ids, i); +- cfg80211_free_nan_func(func); +- } +- idr_destroy(&sdata->u.nan.function_inst_ids); +- +- spin_unlock_bh(&sdata->u.nan.func_lock); +- break; +- case NL80211_IFTYPE_P2P_DEVICE: +- /* relies on synchronize_rcu() below */ +- RCU_INIT_POINTER(local->p2p_sdata, NULL); +- /* fall through */ +- default: +- cancel_work_sync(&sdata->work); +- /* +- * When we get here, the interface is marked down. +- * Free the remaining keys, if there are any +- * (which can happen in AP mode if userspace sets +- * keys before the interface is operating, and maybe +- * also in WDS mode) +- * +- * Force the key freeing to always synchronize_net() +- * to wait for the RX path in case it is using this +- * interface enqueuing frames at this very time on +- * another CPU. +- */ +- ieee80211_free_keys(sdata, true); +- skb_queue_purge(&sdata->skb_queue); +- } +- +- spin_lock_irqsave(&local->queue_stop_reason_lock, flags); +- for (i = 0; i < IEEE80211_MAX_QUEUES; i++) { +- skb_queue_walk_safe(&local->pending[i], skb, tmp) { +- struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); +- if (info->control.vif == &sdata->vif) { +- __skb_unlink(skb, &local->pending[i]); +- ieee80211_free_txskb(&local->hw, skb); +- } +- } +- } +- spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); +- +- if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) +- ieee80211_txq_remove_vlan(local, sdata); +- +- sdata->bss = NULL; +- +- if (local->open_count == 0) +- ieee80211_clear_tx_pending(local); +- +- sdata->vif.bss_conf.beacon_int = 0; +- +- /* +- * If the interface goes down while suspended, presumably because +- * the device was unplugged and that happens before our resume, +- * then the driver is already unconfigured and the remainder of +- * this function isn't needed. +- * XXX: what about WoWLAN? If the device has software state, e.g. +- * memory allocated, it might expect teardown commands from +- * mac80211 here? +- */ +- if (local->suspended) { +- WARN_ON(local->wowlan); +- WARN_ON(rtnl_dereference(local->monitor_sdata)); +- return; +- } +- +- switch (sdata->vif.type) { +- case NL80211_IFTYPE_AP_VLAN: +- break; +- case NL80211_IFTYPE_MONITOR: +- if (local->monitors == 0) +- ieee80211_del_virtual_monitor(local); +- +- mutex_lock(&local->mtx); +- ieee80211_recalc_idle(local); +- mutex_unlock(&local->mtx); +- +- if (!(sdata->u.mntr.flags & MONITOR_FLAG_ACTIVE)) +- break; +- +- /* fall through */ +- default: +- if (going_down) +- drv_remove_interface(local, sdata); +- } +- +- ieee80211_recalc_ps(local); +- +- if (cancel_scan) +- flush_delayed_work(&local->scan_work); +- +- if (local->open_count == 0) { +- ieee80211_stop_device(local); +- +- /* no reconfiguring after stop! */ +- return; +- } +- +- /* do after stop to avoid reconfiguring when we stop anyway */ +- ieee80211_configure_filter(local); +- ieee80211_hw_config(local, hw_reconf_flags); +- +- if (local->monitors == local->open_count) +- ieee80211_add_virtual_monitor(local); +-} +- +-static int ieee80211_stop(struct net_device *dev) +-{ +- struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); +- +- ieee80211_do_stop(sdata, true); +- +- return 0; +-} +- +-static void ieee80211_set_multicast_list(struct net_device *dev) +-{ +- struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); +- struct ieee80211_local *local = sdata->local; +- int allmulti, sdata_allmulti; +- +- allmulti = !!(dev->flags & IFF_ALLMULTI); +- sdata_allmulti = !!(sdata->flags & IEEE80211_SDATA_ALLMULTI); +- +- if (allmulti != sdata_allmulti) { +- if (dev->flags & IFF_ALLMULTI) +- atomic_inc(&local->iff_allmultis); +- else +- atomic_dec(&local->iff_allmultis); +- sdata->flags ^= IEEE80211_SDATA_ALLMULTI; +- } +- +- spin_lock_bh(&local->filter_lock); +- __hw_addr_sync(&local->mc_list, &dev->mc, dev->addr_len); +- spin_unlock_bh(&local->filter_lock); +- ieee80211_queue_work(&local->hw, &local->reconfig_filter); +-} +- +-/* +- * Called when the netdev is removed or, by the code below, before +- * the interface type changes. +- */ +-static void ieee80211_teardown_sdata(struct ieee80211_sub_if_data *sdata) +-{ +- int i; +- +- /* free extra data */ +- ieee80211_free_keys(sdata, false); +- +- ieee80211_debugfs_remove_netdev(sdata); +- +- for (i = 0; i < IEEE80211_FRAGMENT_MAX; i++) +- __skb_queue_purge(&sdata->fragments[i].skb_list); +- sdata->fragment_next = 0; +- +- if (ieee80211_vif_is_mesh(&sdata->vif)) +- ieee80211_mesh_teardown_sdata(sdata); +-} +- +-static void ieee80211_uninit(struct net_device *dev) +-{ +- ieee80211_teardown_sdata(IEEE80211_DEV_TO_SUB_IF(dev)); +-} +- +-#if LINUX_VERSION_IS_GEQ(5,2,0) +-static u16 ieee80211_netdev_select_queue(struct net_device *dev, +- struct sk_buff *skb, +- struct net_device *sb_dev) +-#elif LINUX_VERSION_IS_GEQ(4,19,0) +-static u16 ieee80211_netdev_select_queue(struct net_device *dev, +- struct sk_buff *skb, +- struct net_device *sb_dev, +- select_queue_fallback_t fallback) +-#elif LINUX_VERSION_IS_GEQ(3,14,0) || \ +- (LINUX_VERSION_CODE == KERNEL_VERSION(3,13,11) && UTS_UBUNTU_RELEASE_ABI > 30) +-static u16 ieee80211_netdev_select_queue(struct net_device *dev, +- struct sk_buff *skb, +- void *accel_priv, +- select_queue_fallback_t fallback) +-#elif LINUX_VERSION_IS_GEQ(3,13,0) +-static u16 ieee80211_netdev_select_queue(struct net_device *dev, +- struct sk_buff *skb, +- void *accel_priv) +-#else +-static u16 ieee80211_netdev_select_queue(struct net_device *dev, +- struct sk_buff *skb) +-#endif +-{ +- return ieee80211_select_queue(IEEE80211_DEV_TO_SUB_IF(dev), skb); +-} +- +-static void +-ieee80211_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats) +-{ +- int i; +- +- for_each_possible_cpu(i) { +- const struct pcpu_sw_netstats *tstats; +- u64 rx_packets, rx_bytes, tx_packets, tx_bytes; +- unsigned int start; +- +- tstats = per_cpu_ptr(netdev_tstats(dev), i); +- +- do { +- start = u64_stats_fetch_begin_irq(&tstats->syncp); +- rx_packets = tstats->rx_packets; +- tx_packets = tstats->tx_packets; +- rx_bytes = tstats->rx_bytes; +- tx_bytes = tstats->tx_bytes; +- } while (u64_stats_fetch_retry_irq(&tstats->syncp, start)); +- +- stats->rx_packets += rx_packets; +- stats->tx_packets += tx_packets; +- stats->rx_bytes += rx_bytes; +- stats->tx_bytes += tx_bytes; +- } +-} +-#if LINUX_VERSION_IS_LESS(4,11,0) +-/* Just declare it here to keep sparse happy */ +-struct rtnl_link_stats64 *bp_ieee80211_get_stats64(struct net_device *dev, +- struct rtnl_link_stats64 *stats); +-struct rtnl_link_stats64 * +-bp_ieee80211_get_stats64(struct net_device *dev, +- struct rtnl_link_stats64 *stats){ +- ieee80211_get_stats64(dev, stats); +- return stats; +-} +-#endif +- +-static const struct net_device_ops ieee80211_dataif_ops = { +- .ndo_open = ieee80211_open, +- .ndo_stop = ieee80211_stop, +- .ndo_uninit = ieee80211_uninit, +- .ndo_start_xmit = ieee80211_subif_start_xmit, +- .ndo_set_rx_mode = ieee80211_set_multicast_list, +- .ndo_set_mac_address = ieee80211_change_mac, +- .ndo_select_queue = ieee80211_netdev_select_queue, +-#if LINUX_VERSION_IS_GEQ(4,11,0) +- .ndo_get_stats64 = ieee80211_get_stats64, +-#else +- .ndo_get_stats64 = bp_ieee80211_get_stats64, +-#endif +- +-}; +- +-#if LINUX_VERSION_IS_GEQ(5,2,0) +-static u16 ieee80211_monitor_select_queue(struct net_device *dev, +- struct sk_buff *skb, +- struct net_device *sb_dev) +-#elif LINUX_VERSION_IS_GEQ(4,19,0) +-static u16 ieee80211_monitor_select_queue(struct net_device *dev, +- struct sk_buff *skb, +- struct net_device *sb_dev, +- select_queue_fallback_t fallback) +-#elif LINUX_VERSION_IS_GEQ(3,14,0) || \ +- (LINUX_VERSION_CODE == KERNEL_VERSION(3,13,11) && UTS_UBUNTU_RELEASE_ABI > 30) +-static u16 ieee80211_monitor_select_queue(struct net_device *dev, +- struct sk_buff *skb, +- void *accel_priv, +- select_queue_fallback_t fallback) +-#elif LINUX_VERSION_IS_GEQ(3,13,0) +-static u16 ieee80211_monitor_select_queue(struct net_device *dev, +- struct sk_buff *skb, +- void *accel_priv) +-#else +-static u16 ieee80211_monitor_select_queue(struct net_device *dev, +- struct sk_buff *skb) +-#endif +-{ +- struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); +- struct ieee80211_local *local = sdata->local; +- struct ieee80211_hdr *hdr; +- struct ieee80211_radiotap_header *rtap = (void *)skb->data; +- +- if (local->hw.queues < IEEE80211_NUM_ACS) +- return 0; +- +- if (skb->len < 4 || +- skb->len < le16_to_cpu(rtap->it_len) + 2 /* frame control */) +- return 0; /* doesn't matter, frame will be dropped */ +- +- hdr = (void *)((u8 *)skb->data + le16_to_cpu(rtap->it_len)); +- +- return ieee80211_select_queue_80211(sdata, skb, hdr); +-} +- +-static const struct net_device_ops ieee80211_monitorif_ops = { +- .ndo_open = ieee80211_open, +- .ndo_stop = ieee80211_stop, +- .ndo_uninit = ieee80211_uninit, +- .ndo_start_xmit = ieee80211_monitor_start_xmit, +- .ndo_set_rx_mode = ieee80211_set_multicast_list, +- .ndo_set_mac_address = ieee80211_change_mac, +- .ndo_select_queue = ieee80211_monitor_select_queue, +-#if LINUX_VERSION_IS_GEQ(4,11,0) +- .ndo_get_stats64 = ieee80211_get_stats64, +-#else +- .ndo_get_stats64 = bp_ieee80211_get_stats64, +-#endif +- +-}; +- +-static const struct net_device_ops ieee80211_dataif_8023_ops = { +- .ndo_open = ieee80211_open, +- .ndo_stop = ieee80211_stop, +- .ndo_uninit = ieee80211_uninit, +- .ndo_start_xmit = ieee80211_subif_start_xmit_8023, +- .ndo_set_rx_mode = ieee80211_set_multicast_list, +- .ndo_set_mac_address = ieee80211_change_mac, +- .ndo_select_queue = ieee80211_netdev_select_queue, +-#if LINUX_VERSION_IS_GEQ(4,11,0) +- .ndo_get_stats64 = ieee80211_get_stats64, +-#else +- .ndo_get_stats64 = bp_ieee80211_get_stats64, +-#endif +- +-}; +- + static void ieee80211_if_free(struct net_device *dev) + { + free_percpu(netdev_tstats(dev)); +@@ -1401,32 +1425,6 @@ static void ieee80211_if_setup_no_queue( + #endif + } + +-static void ieee80211_set_vif_encap_ops(struct ieee80211_sub_if_data *sdata) +-{ +- struct ieee80211_local *local = sdata->local; +- struct ieee80211_sub_if_data *bss = sdata; +- bool enabled; +- +- if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) { +- if (!sdata->bss) +- return; +- +- bss = container_of(sdata->bss, struct ieee80211_sub_if_data, u.ap); +- } +- +- if (!ieee80211_hw_check(&local->hw, SUPPORTS_TX_ENCAP_OFFLOAD) || +- !ieee80211_iftype_supports_encap_offload(bss->vif.type)) +- return; +- +- enabled = bss->vif.offload_flags & IEEE80211_OFFLOAD_ENCAP_ENABLED; +- if (sdata->wdev.use_4addr && +- !(bss->vif.offload_flags & IEEE80211_OFFLOAD_ENCAP_4ADDR)) +- enabled = false; +- +- sdata->dev->netdev_ops = enabled ? &ieee80211_dataif_8023_ops : +- &ieee80211_dataif_ops; +-} +- + static void ieee80211_iface_work(struct work_struct *work) + { + struct ieee80211_sub_if_data *sdata = diff --git a/package/kernel/mac80211/patches/subsys/327-mac80211-extend-AQL-aggregation-estimation-to-HE-and.patch b/package/kernel/mac80211/patches/subsys/328-mac80211-extend-AQL-aggregation-estimation-to-HE-and.patch similarity index 100% rename from package/kernel/mac80211/patches/subsys/327-mac80211-extend-AQL-aggregation-estimation-to-HE-and.patch rename to package/kernel/mac80211/patches/subsys/328-mac80211-extend-AQL-aggregation-estimation-to-HE-and.patch diff --git a/package/kernel/mac80211/patches/subsys/328-mac80211-add-AQL-support-for-VHT160-tx-rates.patch b/package/kernel/mac80211/patches/subsys/329-mac80211-add-AQL-support-for-VHT160-tx-rates.patch similarity index 100% rename from package/kernel/mac80211/patches/subsys/328-mac80211-add-AQL-support-for-VHT160-tx-rates.patch rename to package/kernel/mac80211/patches/subsys/329-mac80211-add-AQL-support-for-VHT160-tx-rates.patch diff --git a/package/kernel/mac80211/patches/subsys/500-mac80211_configure_antenna_gain.patch b/package/kernel/mac80211/patches/subsys/500-mac80211_configure_antenna_gain.patch index 1487e10f42..8db3a758a1 100644 --- a/package/kernel/mac80211/patches/subsys/500-mac80211_configure_antenna_gain.patch +++ b/package/kernel/mac80211/patches/subsys/500-mac80211_configure_antenna_gain.patch @@ -18,7 +18,7 @@ const u8 *addr); --- a/include/net/mac80211.h +++ b/include/net/mac80211.h -@@ -1519,6 +1519,7 @@ enum ieee80211_smps_mode { +@@ -1521,6 +1521,7 @@ enum ieee80211_smps_mode { * * @power_level: requested transmit power (in dBm), backward compatibility * value only that is set to the minimum of all interfaces @@ -26,7 +26,7 @@ * * @chandef: the channel definition to tune to * @radar_enabled: whether radar detection is enabled -@@ -1539,6 +1540,7 @@ enum ieee80211_smps_mode { +@@ -1541,6 +1542,7 @@ enum ieee80211_smps_mode { struct ieee80211_conf { u32 flags; int power_level, dynamic_ps_timeout; @@ -57,7 +57,7 @@ __NL80211_ATTR_AFTER_LAST, --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c -@@ -2615,6 +2615,19 @@ static int ieee80211_get_tx_power(struct +@@ -2611,6 +2611,19 @@ static int ieee80211_get_tx_power(struct return 0; } @@ -77,7 +77,7 @@ static int ieee80211_set_wds_peer(struct wiphy *wiphy, struct net_device *dev, const u8 *addr) { -@@ -4045,6 +4058,7 @@ const struct cfg80211_ops mac80211_confi +@@ -4041,6 +4054,7 @@ const struct cfg80211_ops mac80211_confi .set_wiphy_params = ieee80211_set_wiphy_params, .set_tx_power = ieee80211_set_tx_power, .get_tx_power = ieee80211_get_tx_power, -- 2.30.2