Merge branch 'kvm-updates/3.3' of git://git.kernel.org/pub/scm/virt/kvm/kvm
[cascardo/linux.git] / net / mac80211 / ieee80211_i.h
index ea10a51..2f0642d 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/spinlock.h>
 #include <linux/etherdevice.h>
 #include <linux/leds.h>
+#include <linux/idr.h>
 #include <net/ieee80211_radiotap.h>
 #include <net/cfg80211.h>
 #include <net/mac80211.h>
@@ -141,6 +142,7 @@ typedef unsigned __bitwise__ ieee80211_tx_result;
 
 struct ieee80211_tx_data {
        struct sk_buff *skb;
+       struct sk_buff_head skbs;
        struct ieee80211_local *local;
        struct ieee80211_sub_if_data *sdata;
        struct sta_info *sta;
@@ -184,12 +186,15 @@ enum ieee80211_packet_rx_flags {
  * enum ieee80211_rx_flags - RX data flags
  *
  * @IEEE80211_RX_CMNTR: received on cooked monitor already
+ * @IEEE80211_RX_BEACON_REPORTED: This frame was already reported
+ *     to cfg80211_report_obss_beacon().
  *
  * These flags are used across handling multiple interfaces
  * for a single frame.
  */
 enum ieee80211_rx_flags {
        IEEE80211_RX_CMNTR              = BIT(0),
+       IEEE80211_RX_BEACON_REPORTED    = BIT(1),
 };
 
 struct ieee80211_rx_data {
@@ -228,6 +233,7 @@ struct beacon_data {
 
 struct ieee80211_if_ap {
        struct beacon_data __rcu *beacon;
+       struct sk_buff __rcu *probe_resp;
 
        struct list_head vlans;
 
@@ -237,6 +243,7 @@ struct ieee80211_if_ap {
        u8 tim[sizeof(unsigned long) * BITS_TO_LONGS(IEEE80211_MAX_AID + 1)];
        struct sk_buff_head ps_bc_buf;
        atomic_t num_sta_ps; /* number of stations in PS mode */
+       atomic_t num_sta_authorized; /* number of authorized stations */
        int dtim_count;
        bool dtim_bc_mc;
 };
@@ -443,6 +450,9 @@ struct ieee80211_if_managed {
         */
        int rssi_min_thold, rssi_max_thold;
        int last_ave_beacon_signal;
+
+       struct ieee80211_ht_cap ht_capa; /* configured ht-cap over-rides */
+       struct ieee80211_ht_cap ht_capa_mask; /* Valid parts of ht_capa */
 };
 
 struct ieee80211_if_ibss {
@@ -465,12 +475,16 @@ struct ieee80211_if_ibss {
        u8 ssid_len, ie_len;
        u8 *ie;
        struct ieee80211_channel *channel;
+       enum nl80211_channel_type channel_type;
 
        unsigned long ibss_join_req;
        /* probe response/beacon for IBSS */
        struct sk_buff __rcu *presp;
        struct sk_buff *skb;
 
+       spinlock_t incomplete_lock;
+       struct list_head incomplete_stations;
+
        enum {
                IEEE80211_IBSS_MLME_SEARCH,
                IEEE80211_IBSS_MLME_JOINED,
@@ -505,7 +519,9 @@ struct ieee80211_if_mesh {
        atomic_t mpaths;
        /* Timestamp of last SN update */
        unsigned long last_sn_update;
-       /* Timestamp of last SN sent */
+       /* Time when it's ok to send next PERR */
+       unsigned long next_perr;
+       /* Timestamp of last PREQ sent */
        unsigned long last_preq;
        struct mesh_rmc *rmc;
        spinlock_t mesh_preq_queue_lock;
@@ -543,6 +559,7 @@ struct ieee80211_if_mesh {
  *     associated stations and deliver multicast frames both
  *     back to wireless media and to the local net stack.
  * @IEEE80211_SDATA_DISCONNECT_RESUME: Disconnect after resume.
+ * @IEEE80211_SDATA_IN_DRIVER: indicates interface was added to driver
  */
 enum ieee80211_sub_if_data_flags {
        IEEE80211_SDATA_ALLMULTI                = BIT(0),
@@ -550,6 +567,7 @@ enum ieee80211_sub_if_data_flags {
        IEEE80211_SDATA_OPERATING_GMODE         = BIT(2),
        IEEE80211_SDATA_DONT_BRIDGE_PACKETS     = BIT(3),
        IEEE80211_SDATA_DISCONNECT_RESUME       = BIT(4),
+       IEEE80211_SDATA_IN_DRIVER               = BIT(5),
 };
 
 /**
@@ -600,6 +618,9 @@ struct ieee80211_sub_if_data {
        struct ieee80211_fragment_entry fragments[IEEE80211_FRAGMENT_MAX];
        unsigned int fragment_next;
 
+       /* TID bitmap for NoAck policy */
+       u16 noack_map;
+
        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;
@@ -722,17 +743,16 @@ enum {
  *     operating channel
  * @SCAN_SET_CHANNEL: Set the next channel to be scanned
  * @SCAN_SEND_PROBE: Send probe requests and wait for probe responses
- * @SCAN_LEAVE_OPER_CHANNEL: Leave the operating channel, notify the AP
- *     about us leaving the channel and stop all associated STA interfaces
- * @SCAN_ENTER_OPER_CHANNEL: Enter the operating channel again, notify the
- *     AP about us being back and restart all associated STA interfaces
+ * @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
  */
 enum mac80211_scan_state {
        SCAN_DECISION,
        SCAN_SET_CHANNEL,
        SCAN_SEND_PROBE,
-       SCAN_LEAVE_OPER_CHANNEL,
-       SCAN_ENTER_OPER_CHANNEL,
+       SCAN_SUSPEND,
+       SCAN_RESUME,
 };
 
 struct ieee80211_local {
@@ -835,18 +855,15 @@ struct ieee80211_local {
 
        /* Station data */
        /*
-        * The mutex only protects the list and counter,
-        * reads are done in RCU.
-        * Additionally, the lock protects the hash table,
-        * the pending list and each BSS's TIM bitmap.
+        * The mutex only protects the list, hash table and
+        * counter, reads are done with RCU.
         */
        struct mutex sta_mtx;
-       spinlock_t sta_lock;
+       spinlock_t tim_lock;
        unsigned long num_sta;
-       struct list_head sta_list, sta_pending_list;
+       struct list_head sta_list;
        struct sta_info __rcu *sta_hash[STA_HASH_SIZE];
        struct timer_list sta_cleanup;
-       struct work_struct sta_finish_work;
        int sta_generation;
 
        struct sk_buff_head pending[IEEE80211_MAX_QUEUES];
@@ -951,7 +968,6 @@ struct ieee80211_local {
        int total_ps_buffered; /* total number of all buffered unicast and
                                * multicast packets for power saving stations
                                */
-       int wifi_wme_noack_test;
        unsigned int wmm_acm; /* bit field of ACM bits (BIT(802.1D tag)) */
 
        /*
@@ -1012,6 +1028,9 @@ struct ieee80211_local {
        u32 hw_roc_cookie;
        bool hw_roc_for_tx;
 
+       struct idr ack_status_frames;
+       spinlock_t ack_status_lock;
+
        /* dummy netdev for use w/ NAPI */
        struct net_device napi_dev;
 
@@ -1030,6 +1049,69 @@ struct ieee80211_ra_tid {
        u16 tid;
 };
 
+/* Parsed Information Elements */
+struct ieee802_11_elems {
+       u8 *ie_start;
+       size_t total_len;
+
+       /* pointers to IEs */
+       u8 *ssid;
+       u8 *supp_rates;
+       u8 *fh_params;
+       u8 *ds_params;
+       u8 *cf_params;
+       struct ieee80211_tim_ie *tim;
+       u8 *ibss_params;
+       u8 *challenge;
+       u8 *wpa;
+       u8 *rsn;
+       u8 *erp_info;
+       u8 *ext_supp_rates;
+       u8 *wmm_info;
+       u8 *wmm_param;
+       struct ieee80211_ht_cap *ht_cap_elem;
+       struct ieee80211_ht_info *ht_info_elem;
+       struct ieee80211_meshconf_ie *mesh_config;
+       u8 *mesh_id;
+       u8 *peering;
+       u8 *preq;
+       u8 *prep;
+       u8 *perr;
+       struct ieee80211_rann_ie *rann;
+       u8 *ch_switch_elem;
+       u8 *country_elem;
+       u8 *pwr_constr_elem;
+       u8 *quiet_elem; /* first quite element */
+       u8 *timeout_int;
+
+       /* length of them, respectively */
+       u8 ssid_len;
+       u8 supp_rates_len;
+       u8 fh_params_len;
+       u8 ds_params_len;
+       u8 cf_params_len;
+       u8 tim_len;
+       u8 ibss_params_len;
+       u8 challenge_len;
+       u8 wpa_len;
+       u8 rsn_len;
+       u8 erp_info_len;
+       u8 ext_supp_rates_len;
+       u8 wmm_info_len;
+       u8 wmm_param_len;
+       u8 mesh_id_len;
+       u8 peering_len;
+       u8 preq_len;
+       u8 prep_len;
+       u8 perr_len;
+       u8 ch_switch_elem_len;
+       u8 country_elem_len;
+       u8 pwr_constr_elem_len;
+       u8 quiet_elem_len;
+       u8 num_of_quiet_elem;   /* can be more the one */
+       u8 timeout_int_len;
+};
+
 static inline struct ieee80211_local *hw_to_local(
        struct ieee80211_hw *hw)
 {
@@ -1090,9 +1172,8 @@ void ieee80211_sta_reset_conn_monitor(struct ieee80211_sub_if_data *sdata);
 /* IBSS code */
 void ieee80211_ibss_notify_scan_completed(struct ieee80211_local *local);
 void ieee80211_ibss_setup_sdata(struct ieee80211_sub_if_data *sdata);
-struct sta_info *ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata,
-                                       u8 *bssid, u8 *addr, u32 supp_rates,
-                                       gfp_t gfp);
+void ieee80211_ibss_rx_no_sta(struct ieee80211_sub_if_data *sdata,
+                             const u8 *bssid, const u8 *addr, u32 supp_rates);
 int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata,
                        struct cfg80211_ibss_params *params);
 int ieee80211_ibss_leave(struct ieee80211_sub_if_data *sdata);
@@ -1140,13 +1221,9 @@ int ieee80211_request_sched_scan_stop(struct ieee80211_sub_if_data *sdata);
 void ieee80211_sched_scan_stopped_work(struct work_struct *work);
 
 /* off-channel helpers */
-bool ieee80211_cfg_on_oper_channel(struct ieee80211_local *local);
-void ieee80211_offchannel_enable_all_ps(struct ieee80211_local *local,
-                                       bool tell_ap);
 void ieee80211_offchannel_stop_vifs(struct ieee80211_local *local,
                                    bool offchannel_ps_enable);
 void ieee80211_offchannel_return(struct ieee80211_local *local,
-                                bool enable_beaconing,
                                 bool offchannel_ps_disable);
 void ieee80211_hw_roc_setup(struct ieee80211_local *local);
 
@@ -1179,7 +1256,11 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
                                       struct net_device *dev);
 
 /* HT */
-void ieee80211_ht_cap_ie_to_sta_ht_cap(struct ieee80211_supported_band *sband,
+bool ieee80111_cfg_override_disables_ht40(struct ieee80211_sub_if_data *sdata);
+void ieee80211_apply_htcap_overrides(struct ieee80211_sub_if_data *sdata,
+                                    struct ieee80211_sta_ht_cap *ht_cap);
+void ieee80211_ht_cap_ie_to_sta_ht_cap(struct ieee80211_sub_if_data *sdata,
+                                      struct ieee80211_supported_band *sband,
                                       struct ieee80211_ht_cap *ht_cap_ie,
                                       struct ieee80211_sta_ht_cap *ht_cap);
 void ieee80211_send_delba(struct ieee80211_sub_if_data *sdata,
@@ -1266,7 +1347,16 @@ 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);
 void ieee80211_xmit(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb);
-void ieee80211_tx_skb(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb);
+
+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,
+                                   struct sk_buff *skb)
+{
+       /* Send all internal mgmt frames on VO. Accordingly set TID to 7. */
+       ieee80211_tx_skb_tid(sdata, skb, 7);
+}
+
 void ieee802_11_parse_elems(u8 *start, size_t len,
                            struct ieee802_11_elems *elems);
 u32 ieee802_11_parse_elems_crc(u8 *start, size_t len,
@@ -1334,6 +1424,12 @@ void ieee80211_recalc_smps(struct ieee80211_local *local);
 size_t ieee80211_ie_split(const u8 *ies, size_t ielen,
                          const u8 *ids, int n_ids, size_t offset);
 size_t ieee80211_ie_split_vendor(const u8 *ies, size_t ielen, size_t offset);
+u8 *ieee80211_ie_build_ht_cap(u8 *pos, struct ieee80211_sta_ht_cap *ht_cap,
+                             u16 cap);
+u8 *ieee80211_ie_build_ht_info(u8 *pos,
+                               struct ieee80211_sta_ht_cap *ht_cap,
+                               struct ieee80211_channel *channel,
+                               enum nl80211_channel_type channel_type);
 
 /* internal work items */
 void ieee80211_work_init(struct ieee80211_local *local);
@@ -1362,6 +1458,8 @@ ieee80211_get_channel_mode(struct ieee80211_local *local,
 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_info_to_channel_type(struct ieee80211_ht_info *ht_info);
 
 #ifdef CONFIG_MAC80211_NOINLINE
 #define debug_noinline noinline