aboutsummaryrefslogtreecommitdiffstats
path: root/package/kernel/mac80211/patches/subsys/327-mac80211-reorganize-code-to-remove-a-forward-declara.patch
diff options
context:
space:
mode:
Diffstat (limited to 'package/kernel/mac80211/patches/subsys/327-mac80211-reorganize-code-to-remove-a-forward-declara.patch')
-rw-r--r--package/kernel/mac80211/patches/subsys/327-mac80211-reorganize-code-to-remove-a-forward-declara.patch1124
1 files changed, 0 insertions, 1124 deletions
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
deleted file mode 100644
index 0bfb10cdb0..0000000000
--- a/package/kernel/mac80211/patches/subsys/327-mac80211-reorganize-code-to-remove-a-forward-declara.patch
+++ /dev/null
@@ -1,1124 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-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 <nbd@nbd.name>
----
-
---- 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,518 @@ 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);
-+ fallthrough;
-+ 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;
-+
-+ fallthrough;
-+ 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_tx_info *info = IEEE80211_SKB_CB(skb);
-+ struct ieee80211_hdr *hdr;
-+ int len_rthdr;
-+
-+ if (local->hw.queues < IEEE80211_NUM_ACS)
-+ return 0;
-+
-+ /* reset flags and info before parsing radiotap header */
-+ memset(info, 0, sizeof(*info));
-+
-+ if (!ieee80211_parse_tx_radiotap(skb, dev))
-+ return 0; /* doesn't matter, frame will be dropped */
-+
-+ len_rthdr = ieee80211_get_radiotap_len(skb->data);
-+ hdr = (struct ieee80211_hdr *)(skb->data + len_rthdr);
-+ if (skb->len < len_rthdr + 2 ||
-+ skb->len < len_rthdr + ieee80211_hdrlen(hdr->frame_control))
-+ return 0; /* doesn't matter, frame will be dropped */
-+
-+ 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 +900,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,518 +1402,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);
-- fallthrough;
-- 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;
--
-- fallthrough;
-- 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_tx_info *info = IEEE80211_SKB_CB(skb);
-- struct ieee80211_hdr *hdr;
-- int len_rthdr;
--
-- if (local->hw.queues < IEEE80211_NUM_ACS)
-- return 0;
--
-- /* reset flags and info before parsing radiotap header */
-- memset(info, 0, sizeof(*info));
--
-- if (!ieee80211_parse_tx_radiotap(skb, dev))
-- return 0; /* doesn't matter, frame will be dropped */
--
-- len_rthdr = ieee80211_get_radiotap_len(skb->data);
-- hdr = (struct ieee80211_hdr *)(skb->data + len_rthdr);
-- if (skb->len < len_rthdr + 2 ||
-- skb->len < len_rthdr + ieee80211_hdrlen(hdr->frame_control))
-- return 0; /* doesn't matter, frame will be dropped */
--
-- 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));
-@@ -1408,32 +1432,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 =