Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
[firefly-linux-kernel-4.4.55.git] / net / mac80211 / ieee80211_i.h
index 156e5835e37f4b140fb9261c2c1ed44f73cf8408..32e47853f329262eb46fbd57a81e492a1354d4bd 100644 (file)
@@ -280,23 +280,27 @@ struct probe_resp {
        u8 data[0];
 };
 
-struct ieee80211_if_ap {
-       struct beacon_data __rcu *beacon;
-       struct probe_resp __rcu *probe_resp;
-
-       struct list_head vlans;
-
+struct ps_data {
        /* yes, this looks ugly, but guarantees that we can later use
         * bitmap_empty :)
         * NB: don't touch this bitmap, use sta_info_{set,clear}_tim_bit */
        u8 tim[sizeof(unsigned long) * BITS_TO_LONGS(IEEE80211_MAX_AID + 1)];
-       struct sk_buff_head ps_bc_buf;
+       struct sk_buff_head bc_buf;
        atomic_t num_sta_ps; /* number of stations in PS mode */
-       atomic_t num_mcast_sta; /* number of stations receiving multicast */
        int dtim_count;
        bool dtim_bc_mc;
 };
 
+struct ieee80211_if_ap {
+       struct beacon_data __rcu *beacon;
+       struct probe_resp __rcu *probe_resp;
+
+       struct list_head vlans;
+
+       struct ps_data ps;
+       atomic_t num_mcast_sta; /* number of stations receiving multicast */
+};
+
 struct ieee80211_if_wds {
        struct sta_info *sta;
        u8 remote_addr[ETH_ALEN];
@@ -316,7 +320,6 @@ struct mesh_stats {
        __u32 dropped_frames_ttl;       /* Not transmitted since mesh_ttl == 0*/
        __u32 dropped_frames_no_route;  /* Not transmitted, no route found */
        __u32 dropped_frames_congestion;/* Not forwarded due to congestion */
-       atomic_t estab_plinks;
 };
 
 #define PREQ_Q_F_START         0x1
@@ -378,8 +381,9 @@ struct ieee80211_mgd_auth_data {
        u8 key_len, key_idx;
        bool done;
 
-       size_t ie_len;
-       u8 ie[];
+       u16 sae_trans, sae_status;
+       size_t data_len;
+       u8 data[];
 };
 
 struct ieee80211_mgd_assoc_data {
@@ -433,7 +437,6 @@ struct ieee80211_if_managed {
        bool powersave; /* powersave requested for this iface */
        bool broken_ap; /* AP is broken -- turn off powersave */
        enum ieee80211_smps_mode req_smps, /* requested smps mode */
-                                ap_smps, /* smps mode AP thinks we're in */
                                 driver_smps_mode; /* smps mode request */
 
        struct work_struct request_smps_work;
@@ -599,6 +602,7 @@ struct ieee80211_if_mesh {
        int preq_queue_len;
        struct mesh_stats mshstats;
        struct mesh_config mshcfg;
+       atomic_t estab_plinks;
        u32 mesh_seqnum;
        bool accepting_plinks;
        int num_gates;
@@ -610,7 +614,7 @@ struct ieee80211_if_mesh {
                IEEE80211_MESH_SEC_SECURED = 0x2,
        } security;
        /* Extensible Synchronization Framework */
-       struct ieee80211_mesh_sync_ops *sync_ops;
+       const struct ieee80211_mesh_sync_ops *sync_ops;
        s64 sync_offset_clockdrift_max;
        spinlock_t sync_offset_lock;
        bool adjusting_tbtt;
@@ -658,6 +662,30 @@ enum ieee80211_sdata_state_bits {
        SDATA_STATE_OFFCHANNEL,
 };
 
+/**
+ * enum ieee80211_chanctx_mode - channel context configuration mode
+ *
+ * @IEEE80211_CHANCTX_SHARED: channel context may be used by
+ *     multiple interfaces
+ * @IEEE80211_CHANCTX_EXCLUSIVE: channel context can be used
+ *     only by a single interface. This can be used for example for
+ *     non-fixed channel IBSS.
+ */
+enum ieee80211_chanctx_mode {
+       IEEE80211_CHANCTX_SHARED,
+       IEEE80211_CHANCTX_EXCLUSIVE
+};
+
+struct ieee80211_chanctx {
+       struct list_head list;
+       struct rcu_head rcu_head;
+
+       enum ieee80211_chanctx_mode mode;
+       int refcount;
+
+       struct ieee80211_chanctx_conf conf;
+};
+
 struct ieee80211_sub_if_data {
        struct list_head list;
 
@@ -704,11 +732,17 @@ struct ieee80211_sub_if_data {
 
        struct ieee80211_tx_queue_params tx_conf[IEEE80211_NUM_ACS];
 
+       /* used to reconfigure hardware SM PS */
+       struct work_struct recalc_smps;
+
        struct work_struct work;
        struct sk_buff_head skb_queue;
 
        bool arp_filter_state;
 
+       u8 needed_rx_chains;
+       enum ieee80211_smps_mode smps_mode;
+
        /*
         * AP this belongs to: self in AP mode and
         * corresponding AP in VLAN mode, NULL for
@@ -749,6 +783,21 @@ struct ieee80211_sub_if_data *vif_to_sdata(struct ieee80211_vif *p)
        return container_of(p, struct ieee80211_sub_if_data, vif);
 }
 
+static inline enum ieee80211_band
+ieee80211_get_sdata_band(struct ieee80211_sub_if_data *sdata)
+{
+       enum ieee80211_band band = IEEE80211_BAND_2GHZ;
+       struct ieee80211_chanctx_conf *chanctx_conf;
+
+       rcu_read_lock();
+       chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
+       if (!WARN_ON(!chanctx_conf))
+               band = chanctx_conf->channel->band;
+       rcu_read_unlock();
+
+       return band;
+}
+
 enum sdata_queue_type {
        IEEE80211_SDATA_QUEUE_TYPE_FRAME        = 0,
        IEEE80211_SDATA_QUEUE_AGG_START         = 1,
@@ -821,6 +870,7 @@ enum {
  * @SCAN_SUSPEND: Suspend the scan and go back to operating channel to
  *     send out data
  * @SCAN_RESUME: Resume the scan and scan the next channel
+ * @SCAN_ABORT: Abort the scan and go back to operating channel
  */
 enum mac80211_scan_state {
        SCAN_DECISION,
@@ -828,6 +878,7 @@ enum mac80211_scan_state {
        SCAN_SEND_PROBE,
        SCAN_SUSPEND,
        SCAN_RESUME,
+       SCAN_ABORT,
 };
 
 struct ieee80211_local {
@@ -858,15 +909,14 @@ struct ieee80211_local {
 
        bool wiphy_ciphers_allocated;
 
+       bool use_chanctx;
+
        /* protects the aggregated multicast list and filter calls */
        spinlock_t filter_lock;
 
        /* used for uploading changed mc list */
        struct work_struct reconfig_filter;
 
-       /* used to reconfigure hardware SM PS */
-       struct work_struct recalc_smps;
-
        /* aggregated multicast list */
        struct netdev_hw_addr_list mc_list;
 
@@ -903,6 +953,9 @@ struct ieee80211_local {
        /* wowlan is enabled -- don't reconfig on resume */
        bool wowlan;
 
+       /* number of RX chains the hardware has */
+       u8 rx_chains;
+
        int tx_headroom; /* required headroom for hardware/radiotap */
 
        /* Tasklet and skb queue to process calls from IRQ mode. All frames
@@ -980,13 +1033,19 @@ struct ieee80211_local {
        enum mac80211_scan_state next_scan_state;
        struct delayed_work scan_work;
        struct ieee80211_sub_if_data __rcu *scan_sdata;
+       struct ieee80211_channel *csa_channel;
+       /* For backward compatibility only -- do not use */
+       struct ieee80211_channel *_oper_channel;
        enum nl80211_channel_type _oper_channel_type;
-       struct ieee80211_channel *oper_channel, *csa_channel;
 
        /* Temporary remain-on-channel for off-channel operations */
        struct ieee80211_channel *tmp_channel;
        enum nl80211_channel_type tmp_channel_type;
 
+       /* channel contexts */
+       struct list_head chanctx_list;
+       struct mutex chanctx_mtx;
+
        /* SNMP counters */
        /* dot11CountersTable */
        u32 dot11TransmittedFragmentCount;
@@ -1091,6 +1150,8 @@ struct ieee80211_local {
 
        /* virtual monitor interface */
        struct ieee80211_sub_if_data __rcu *monitor_sdata;
+       struct ieee80211_channel *monitor_channel;
+       enum nl80211_channel_type monitor_channel_type;
 };
 
 static inline struct ieee80211_sub_if_data *
@@ -1133,6 +1194,8 @@ struct ieee802_11_elems {
        u8 *wmm_param;
        struct ieee80211_ht_cap *ht_cap_elem;
        struct ieee80211_ht_operation *ht_operation;
+       struct ieee80211_vht_cap *vht_cap_elem;
+       struct ieee80211_vht_operation *vht_operation;
        struct ieee80211_meshconf_ie *mesh_config;
        u8 *mesh_id;
        u8 *peering;
@@ -1361,6 +1424,13 @@ void ieee80211_ba_session_work(struct work_struct *work);
 void ieee80211_tx_ba_session_handle_start(struct sta_info *sta, int tid);
 void ieee80211_release_reorder_timeout(struct sta_info *sta, int tid);
 
+u8 ieee80211_mcs_to_chains(const struct ieee80211_mcs_info *mcs);
+
+/* VHT */
+void ieee80211_vht_cap_ie_to_sta_vht_cap(struct ieee80211_sub_if_data *sdata,
+                                        struct ieee80211_supported_band *sband,
+                                        struct ieee80211_vht_cap *vht_cap_ie,
+                                        struct ieee80211_sta_vht_cap *vht_cap);
 /* Spectrum management */
 void ieee80211_process_measurement_req(struct ieee80211_sub_if_data *sdata,
                                       struct ieee80211_mgmt *mgmt,
@@ -1395,11 +1465,42 @@ void mac80211_ev_michael_mic_failure(struct ieee80211_sub_if_data *sdata, int ke
                                     gfp_t gfp);
 void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata,
                               bool bss_notify);
-void ieee80211_xmit(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb);
+void ieee80211_xmit(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb,
+                   enum ieee80211_band band);
+
+void __ieee80211_tx_skb_tid_band(struct ieee80211_sub_if_data *sdata,
+                                struct sk_buff *skb, int tid,
+                                enum ieee80211_band band);
 
-void ieee80211_tx_skb_tid(struct ieee80211_sub_if_data *sdata,
-                         struct sk_buff *skb, int tid);
-static void inline ieee80211_tx_skb(struct ieee80211_sub_if_data *sdata,
+static inline void
+ieee80211_tx_skb_tid_band(struct ieee80211_sub_if_data *sdata,
+                         struct sk_buff *skb, int tid,
+                         enum ieee80211_band band)
+{
+       rcu_read_lock();
+       __ieee80211_tx_skb_tid_band(sdata, skb, tid, band);
+       rcu_read_unlock();
+}
+
+static inline void ieee80211_tx_skb_tid(struct ieee80211_sub_if_data *sdata,
+                                       struct sk_buff *skb, int tid)
+{
+       struct ieee80211_chanctx_conf *chanctx_conf;
+
+       rcu_read_lock();
+       chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
+       if (WARN_ON(!chanctx_conf)) {
+               rcu_read_unlock();
+               kfree_skb(skb);
+               return;
+       }
+
+       __ieee80211_tx_skb_tid_band(sdata, skb, tid,
+                                   chanctx_conf->channel->band);
+       rcu_read_unlock();
+}
+
+static inline void ieee80211_tx_skb(struct ieee80211_sub_if_data *sdata,
                                    struct sk_buff *skb)
 {
        /* Send all internal mgmt frames on VO. Accordingly set TID to 7. */
@@ -1446,7 +1547,7 @@ static inline void ieee80211_add_pending_skbs(struct ieee80211_local *local,
 }
 
 void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata,
-                        u16 transaction, u16 auth_alg,
+                        u16 transaction, u16 auth_alg, u16 status,
                         u8 *extra, size_t extra_len, const u8 *bssid,
                         const u8 *da, const u8 *key, u8 key_len, u8 key_idx);
 void ieee80211_send_deauth_disassoc(struct ieee80211_sub_if_data *sdata,
@@ -1466,7 +1567,7 @@ void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst,
                              const u8 *ssid, size_t ssid_len,
                              const u8 *ie, size_t ie_len,
                              u32 ratemask, bool directed, bool no_cck,
-                             struct ieee80211_channel *channel);
+                             struct ieee80211_channel *channel, bool scan);
 
 void ieee80211_sta_def_wmm_params(struct ieee80211_sub_if_data *sdata,
                                  const size_t supp_rates_len,
@@ -1476,7 +1577,7 @@ u32 ieee80211_sta_get_rates(struct ieee80211_local *local,
                            enum ieee80211_band band, u32 *basic_rates);
 int __ieee80211_request_smps(struct ieee80211_sub_if_data *sdata,
                             enum ieee80211_smps_mode smps_mode);
-void ieee80211_recalc_smps(struct ieee80211_local *local);
+void ieee80211_recalc_smps(struct ieee80211_sub_if_data *sdata);
 
 size_t ieee80211_ie_split(const u8 *ies, size_t ielen,
                          const u8 *ids, int n_ids, size_t offset);
@@ -1497,21 +1598,19 @@ int ieee80211_add_ext_srates_ie(struct ieee80211_sub_if_data *sdata,
                                enum ieee80211_band band);
 
 /* channel management */
-enum ieee80211_chan_mode {
-       CHAN_MODE_UNDEFINED,
-       CHAN_MODE_HOPPING,
-       CHAN_MODE_FIXED,
-};
-
-enum ieee80211_chan_mode
-ieee80211_get_channel_mode(struct ieee80211_local *local,
-                          struct ieee80211_sub_if_data *ignore);
-bool ieee80211_set_channel_type(struct ieee80211_local *local,
-                               struct ieee80211_sub_if_data *sdata,
-                               enum nl80211_channel_type chantype);
 enum nl80211_channel_type
 ieee80211_ht_oper_to_channel_type(struct ieee80211_ht_operation *ht_oper);
 
+int __must_check
+ieee80211_vif_use_channel(struct ieee80211_sub_if_data *sdata,
+                         struct ieee80211_channel *channel,
+                         enum nl80211_channel_type channel_type,
+                         enum ieee80211_chanctx_mode mode);
+void ieee80211_vif_release_channel(struct ieee80211_sub_if_data *sdata);
+
+void ieee80211_recalc_smps_chanctx(struct ieee80211_local *local,
+                                  struct ieee80211_chanctx *chanctx);
+
 #ifdef CONFIG_MAC80211_NOINLINE
 #define debug_noinline noinline
 #else