mac80211: avoid using synchronize_rcu in ieee80211_set_probe_resp
[firefly-linux-kernel-4.4.55.git] / net / mac80211 / ieee80211_i.h
index 3f3cd50fff16ec637b23f3a25bdf6ed4a8146296..e22aee83ba535e4af4976f80fbcd4f6d184de10b 100644 (file)
@@ -30,6 +30,7 @@
 #include <net/mac80211.h>
 #include "key.h"
 #include "sta_info.h"
+#include "debug.h"
 
 struct ieee80211_local;
 
@@ -55,11 +56,14 @@ struct ieee80211_local;
 #define TU_TO_JIFFIES(x)       (usecs_to_jiffies((x) * 1024))
 #define TU_TO_EXP_TIME(x)      (jiffies + TU_TO_JIFFIES(x))
 
+/*
+ * Some APs experience problems when working with U-APSD. Decrease the
+ * probability of that happening by using legacy mode for all ACs but VO.
+ * The AP that caused us trouble was a Cisco 4410N. It ignores our
+ * setting, and always treats non-VO ACs as legacy.
+ */
 #define IEEE80211_DEFAULT_UAPSD_QUEUES \
-       (IEEE80211_WMM_IE_STA_QOSINFO_AC_BK |   \
-        IEEE80211_WMM_IE_STA_QOSINFO_AC_BE |   \
-        IEEE80211_WMM_IE_STA_QOSINFO_AC_VI |   \
-        IEEE80211_WMM_IE_STA_QOSINFO_AC_VO)
+       IEEE80211_WMM_IE_STA_QOSINFO_AC_VO
 
 #define IEEE80211_DEFAULT_MAX_SP_LEN           \
        IEEE80211_WMM_IE_STA_QOSINFO_SP_ALL
@@ -81,6 +85,8 @@ struct ieee80211_bss {
        size_t ssid_len;
        u8 ssid[IEEE80211_MAX_SSID_LEN];
 
+       u32 device_ts;
+
        u8 dtim_period;
 
        bool wmm_used;
@@ -187,8 +193,6 @@ struct ieee80211_tx_data {
        struct sta_info *sta;
        struct ieee80211_key *key;
 
-       struct ieee80211_channel *channel;
-
        unsigned int flags;
 };
 
@@ -203,7 +207,6 @@ typedef unsigned __bitwise__ ieee80211_rx_result;
  * enum ieee80211_packet_rx_flags - packet RX flags
  * @IEEE80211_RX_RA_MATCH: frame is destined to interface currently processed
  *     (incl. multicast frames)
- * @IEEE80211_RX_IN_SCAN: received while scanning
  * @IEEE80211_RX_FRAGMENTED: fragmented frame
  * @IEEE80211_RX_AMSDU: a-MSDU packet
  * @IEEE80211_RX_MALFORMED_ACTION_FRM: action frame is malformed
@@ -213,7 +216,6 @@ typedef unsigned __bitwise__ ieee80211_rx_result;
  * @rx_flags field of &struct ieee80211_rx_status.
  */
 enum ieee80211_packet_rx_flags {
-       IEEE80211_RX_IN_SCAN                    = BIT(0),
        IEEE80211_RX_RA_MATCH                   = BIT(1),
        IEEE80211_RX_FRAGMENTED                 = BIT(2),
        IEEE80211_RX_AMSDU                      = BIT(3),
@@ -270,9 +272,15 @@ struct beacon_data {
        struct rcu_head rcu_head;
 };
 
+struct probe_resp {
+       struct rcu_head rcu_head;
+       int len;
+       u8 data[0];
+};
+
 struct ieee80211_if_ap {
        struct beacon_data __rcu *beacon;
-       struct sk_buff __rcu *probe_resp;
+       struct probe_resp __rcu *probe_resp;
 
        struct list_head vlans;
 
@@ -317,55 +325,30 @@ struct mesh_preq_queue {
        u8 flags;
 };
 
-enum ieee80211_work_type {
-       IEEE80211_WORK_ABORT,
-       IEEE80211_WORK_REMAIN_ON_CHANNEL,
-       IEEE80211_WORK_OFFCHANNEL_TX,
-};
-
-/**
- * enum work_done_result - indicates what to do after work was done
- *
- * @WORK_DONE_DESTROY: This work item is no longer needed, destroy.
- * @WORK_DONE_REQUEUE: This work item was reset to be reused, and
- *     should be requeued.
- */
-enum work_done_result {
-       WORK_DONE_DESTROY,
-       WORK_DONE_REQUEUE,
-};
+#if HZ/100 == 0
+#define IEEE80211_ROC_MIN_LEFT 1
+#else
+#define IEEE80211_ROC_MIN_LEFT (HZ/100)
+#endif
 
-struct ieee80211_work {
+struct ieee80211_roc_work {
        struct list_head list;
+       struct list_head dependents;
 
-       struct rcu_head rcu_head;
+       struct delayed_work work;
 
        struct ieee80211_sub_if_data *sdata;
 
-       enum work_done_result (*done)(struct ieee80211_work *wk,
-                                     struct sk_buff *skb);
-
        struct ieee80211_channel *chan;
        enum nl80211_channel_type chan_type;
 
-       unsigned long timeout;
-       enum ieee80211_work_type type;
+       bool started, abort, hw_begun, notified;
 
-       bool started;
+       unsigned long hw_start_time;
 
-       union {
-               struct {
-                       u32 duration;
-               } remain;
-               struct {
-                       struct sk_buff *frame;
-                       u32 wait;
-                       bool status;
-               } offchan_tx;
-       };
-
-       size_t data_len;
-       u8 data[];
+       u32 duration, req_duration;
+       struct sk_buff *frame;
+       u64 mgmt_tx_cookie;
 };
 
 /* flags used in struct ieee80211_if_managed.flags */
@@ -380,6 +363,7 @@ enum ieee80211_sta_flags {
        IEEE80211_STA_NULLFUNC_ACKED    = BIT(8),
        IEEE80211_STA_RESET_SIGNAL_AVE  = BIT(9),
        IEEE80211_STA_DISABLE_40MHZ     = BIT(10),
+       IEEE80211_STA_DISABLE_VHT       = BIT(11),
 };
 
 struct ieee80211_mgd_auth_data {
@@ -399,7 +383,6 @@ struct ieee80211_mgd_auth_data {
 struct ieee80211_mgd_assoc_data {
        struct cfg80211_bss *bss;
        const u8 *supp_rates;
-       const u8 *ht_operation_ie;
 
        unsigned long timeout;
        int tries;
@@ -414,6 +397,8 @@ struct ieee80211_mgd_assoc_data {
        bool sent_assoc;
        bool synced;
 
+       u8 ap_ht_param;
+
        size_t ie_len;
        u8 ie[];
 };
@@ -532,6 +517,7 @@ struct ieee80211_if_ibss {
        bool privacy;
 
        bool control_port;
+       unsigned int auth_frame_registrations;
 
        u8 bssid[ETH_ALEN] __aligned(2);
        u8 ssid[IEEE80211_MAX_SSID_LEN];
@@ -701,6 +687,9 @@ struct ieee80211_sub_if_data {
        /* TID bitmap for NoAck policy */
        u16 noack_map;
 
+       /* bit field of ACM bits (BIT(802.1D tag)) */
+       u8 wmm_acm;
+
        struct ieee80211_key __rcu *keys[NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS];
        struct ieee80211_key __rcu *default_unicast_key;
        struct ieee80211_key __rcu *default_multicast_key;
@@ -846,13 +835,6 @@ struct ieee80211_local {
 
        const struct ieee80211_ops *ops;
 
-       /*
-        * work stuff, potentially off-channel (in the future)
-        */
-       struct list_head work_list;
-       struct timer_list work_timer;
-       struct work_struct work_work;
-
        /*
         * private workqueue to mac80211. mac80211 makes this accessible
         * via ieee80211_queue_work()
@@ -912,6 +894,9 @@ struct ieee80211_local {
        /* device is started */
        bool started;
 
+       /* device is during a HW reconfig */
+       bool in_reconfig;
+
        /* wowlan is enabled -- don't reconfig on resume */
        bool wowlan;
 
@@ -985,14 +970,14 @@ struct ieee80211_local {
        int scan_channel_idx;
        int scan_ies_len;
 
-       bool sched_scanning;
        struct ieee80211_sched_scan_ies sched_scan_ies;
        struct work_struct sched_scan_stopped_work;
+       struct ieee80211_sub_if_data __rcu *sched_scan_sdata;
 
        unsigned long leave_oper_channel_time;
        enum mac80211_scan_state next_scan_state;
        struct delayed_work scan_work;
-       struct ieee80211_sub_if_data *scan_sdata;
+       struct ieee80211_sub_if_data __rcu *scan_sdata;
        enum nl80211_channel_type _oper_channel_type;
        struct ieee80211_channel *oper_channel, *csa_channel;
 
@@ -1034,7 +1019,6 @@ struct ieee80211_local {
        unsigned int rx_handlers_drop_nullfunc;
        unsigned int rx_handlers_drop_defrag;
        unsigned int rx_handlers_drop_short;
-       unsigned int rx_handlers_drop_passive_scan;
        unsigned int tx_expand_skb_head;
        unsigned int tx_expand_skb_head_cloned;
        unsigned int rx_expand_skb_head;
@@ -1050,7 +1034,6 @@ struct ieee80211_local {
        int total_ps_buffered; /* total number of all buffered unicast and
                                * multicast packets for power saving stations
                                */
-       unsigned int wmm_acm; /* bit field of ACM bits (BIT(802.1D tag)) */
 
        bool pspolling;
        bool offchannel_ps_enabled;
@@ -1087,14 +1070,12 @@ struct ieee80211_local {
        } debugfs;
 #endif
 
-       struct ieee80211_channel *hw_roc_channel;
-       struct net_device *hw_roc_dev;
-       struct sk_buff *hw_roc_skb, *hw_roc_skb_for_status;
+       /*
+        * Remain-on-channel support
+        */
+       struct list_head roc_list;
        struct work_struct hw_roc_start, hw_roc_done;
-       enum nl80211_channel_type hw_roc_channel_type;
-       unsigned int hw_roc_duration;
-       u32 hw_roc_cookie;
-       bool hw_roc_for_tx;
+       unsigned long hw_roc_start_time;
 
        struct idr ack_status_frames;
        spinlock_t ack_status_lock;
@@ -1114,6 +1095,12 @@ IEEE80211_DEV_TO_SUB_IF(struct net_device *dev)
        return netdev_priv(dev);
 }
 
+static inline struct ieee80211_sub_if_data *
+IEEE80211_WDEV_TO_SUB_IF(struct wireless_dev *wdev)
+{
+       return container_of(wdev, struct ieee80211_sub_if_data, wdev);
+}
+
 /* this struct represents 802.11n's RA/TID combination */
 struct ieee80211_ra_tid {
        u8 ra[ETH_ALEN];
@@ -1220,6 +1207,7 @@ int ieee80211_mgd_disassoc(struct ieee80211_sub_if_data *sdata,
 void ieee80211_send_pspoll(struct ieee80211_local *local,
                           struct ieee80211_sub_if_data *sdata);
 void ieee80211_recalc_ps(struct ieee80211_local *local, s32 latency);
+void ieee80211_recalc_ps_vif(struct ieee80211_sub_if_data *sdata);
 int ieee80211_max_network_latency(struct notifier_block *nb,
                                  unsigned long data, void *dummy);
 int ieee80211_set_arp_filter(struct ieee80211_sub_if_data *sdata);
@@ -1264,8 +1252,7 @@ int ieee80211_request_scan(struct ieee80211_sub_if_data *sdata,
                           struct cfg80211_scan_request *req);
 void ieee80211_scan_cancel(struct ieee80211_local *local);
 void ieee80211_run_deferred_scan(struct ieee80211_local *local);
-ieee80211_rx_result
-ieee80211_scan_rx(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb);
+void ieee80211_scan_rx(struct ieee80211_local *local, struct sk_buff *skb);
 
 void ieee80211_mlme_notify_scan_completed(struct ieee80211_local *local);
 struct ieee80211_bss *
@@ -1290,19 +1277,23 @@ void ieee80211_offchannel_stop_vifs(struct ieee80211_local *local,
                                    bool offchannel_ps_enable);
 void ieee80211_offchannel_return(struct ieee80211_local *local,
                                 bool offchannel_ps_disable);
-void ieee80211_hw_roc_setup(struct ieee80211_local *local);
+void ieee80211_roc_setup(struct ieee80211_local *local);
+void ieee80211_start_next_roc(struct ieee80211_local *local);
+void ieee80211_roc_purge(struct ieee80211_sub_if_data *sdata);
+void ieee80211_roc_notify_destroy(struct ieee80211_roc_work *roc);
+void ieee80211_sw_roc_work(struct work_struct *work);
+void ieee80211_handle_roc_started(struct ieee80211_roc_work *roc);
 
 /* interface handling */
 int ieee80211_iface_init(void);
 void ieee80211_iface_exit(void);
 int ieee80211_if_add(struct ieee80211_local *local, const char *name,
-                    struct net_device **new_dev, enum nl80211_iftype type,
+                    struct wireless_dev **new_wdev, enum nl80211_iftype type,
                     struct vif_params *params);
 int ieee80211_if_change_type(struct ieee80211_sub_if_data *sdata,
                             enum nl80211_iftype type);
 void ieee80211_if_remove(struct ieee80211_sub_if_data *sdata);
 void ieee80211_remove_interfaces(struct ieee80211_local *local);
-u32 __ieee80211_recalc_idle(struct ieee80211_local *local);
 void ieee80211_recalc_idle(struct ieee80211_local *local);
 void ieee80211_adjust_monitor_flags(struct ieee80211_sub_if_data *sdata,
                                    const int offset);
@@ -1472,6 +1463,7 @@ int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer,
                             u8 channel);
 struct sk_buff *ieee80211_build_probe_req(struct ieee80211_sub_if_data *sdata,
                                          u8 *dst, u32 ratemask,
+                                         struct ieee80211_channel *chan,
                                          const u8 *ssid, size_t ssid_len,
                                          const u8 *ie, size_t ie_len,
                                          bool directed);
@@ -1499,18 +1491,14 @@ u8 *ieee80211_ie_build_ht_oper(u8 *pos, struct ieee80211_sta_ht_cap *ht_cap,
                               struct ieee80211_channel *channel,
                               enum nl80211_channel_type channel_type,
                               u16 prot_mode);
-
-/* internal work items */
-void ieee80211_work_init(struct ieee80211_local *local);
-void ieee80211_add_work(struct ieee80211_work *wk);
-void free_work(struct ieee80211_work *wk);
-void ieee80211_work_purge(struct ieee80211_sub_if_data *sdata);
-int ieee80211_wk_remain_on_channel(struct ieee80211_sub_if_data *sdata,
-                                  struct ieee80211_channel *chan,
-                                  enum nl80211_channel_type channel_type,
-                                  unsigned int duration, u64 *cookie);
-int ieee80211_wk_cancel_remain_on_channel(
-       struct ieee80211_sub_if_data *sdata, u64 cookie);
+u8 *ieee80211_ie_build_vht_cap(u8 *pos, struct ieee80211_sta_vht_cap *vht_cap,
+                              u32 cap);
+int ieee80211_add_srates_ie(struct ieee80211_sub_if_data *sdata,
+                           struct sk_buff *skb, bool need_basic,
+                           enum ieee80211_band band);
+int ieee80211_add_ext_srates_ie(struct ieee80211_sub_if_data *sdata,
+                               struct sk_buff *skb, bool need_basic,
+                               enum ieee80211_band band);
 
 /* channel management */
 enum ieee80211_chan_mode {