]> bbs.cooldavid.org Git - net-next-2.6.git/blobdiff - net/mac80211/ieee80211_i.h
mac80211: add probe request filter flag
[net-next-2.6.git] / net / mac80211 / ieee80211_i.h
index ec3e5c3e27bd880ec7f222c2c2bf6fc32c25ef71..b80c386899276dd436ebc93caab1957622389be5 100644 (file)
@@ -50,12 +50,6 @@ struct ieee80211_local;
  * increased memory use (about 2 kB of RAM per entry). */
 #define IEEE80211_FRAGMENT_MAX 4
 
-/*
- * Time after which we ignore scan results and no longer report/use
- * them in any way.
- */
-#define IEEE80211_SCAN_RESULT_EXPIRE (10 * HZ)
-
 #define TU_TO_EXP_TIME(x)      (jiffies + usecs_to_jiffies((x) * 1024))
 
 #define IEEE80211_DEFAULT_UAPSD_QUEUES \
@@ -165,12 +159,37 @@ typedef unsigned __bitwise__ ieee80211_rx_result;
 #define RX_DROP_MONITOR                ((__force ieee80211_rx_result) 2u)
 #define RX_QUEUED              ((__force ieee80211_rx_result) 3u)
 
-#define IEEE80211_RX_IN_SCAN           BIT(0)
-/* frame is destined to interface currently processed (incl. multicast frames) */
-#define IEEE80211_RX_RA_MATCH          BIT(1)
-#define IEEE80211_RX_AMSDU             BIT(2)
-#define IEEE80211_RX_FRAGMENTED                BIT(3)
-/* only add flags here that do not change with subframes of an aMPDU */
+/**
+ * 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
+ *
+ * These are per-frame flags that are attached to a frame in the
+ * @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),
+       IEEE80211_RX_MALFORMED_ACTION_FRM       = BIT(4),
+};
+
+/**
+ * enum ieee80211_rx_flags - RX data flags
+ *
+ * @IEEE80211_RX_CMNTR: received on cooked monitor already
+ *
+ * These flags are used across handling multiple interfaces
+ * for a single frame.
+ */
+enum ieee80211_rx_flags {
+       IEEE80211_RX_CMNTR              = BIT(0),
+};
 
 struct ieee80211_rx_data {
        struct sk_buff *skb;
@@ -238,6 +257,7 @@ enum ieee80211_work_type {
        IEEE80211_WORK_ABORT,
        IEEE80211_WORK_DIRECT_PROBE,
        IEEE80211_WORK_AUTH,
+       IEEE80211_WORK_ASSOC_BEACON_WAIT,
        IEEE80211_WORK_ASSOC,
        IEEE80211_WORK_REMAIN_ON_CHANNEL,
 };
@@ -325,7 +345,6 @@ struct ieee80211_if_managed {
        struct timer_list conn_mon_timer;
        struct timer_list bcn_mon_timer;
        struct timer_list chswitch_timer;
-       struct work_struct work;
        struct work_struct monitor_work;
        struct work_struct chswitch_work;
        struct work_struct beacon_connection_loss_work;
@@ -340,15 +359,17 @@ struct ieee80211_if_managed {
 
        u16 aid;
 
-       struct sk_buff_head skb_queue;
-
        unsigned long timers_running; /* used for quiesce/restart */
        bool powersave; /* powersave requested for this iface */
        enum ieee80211_smps_mode req_smps, /* requested smps mode */
-                                ap_smps; /* smps mode AP thinks we're in */
+                                ap_smps, /* smps mode AP thinks we're in */
+                                driver_smps_mode; /* smps mode request */
+
+       struct work_struct request_smps_work;
 
        unsigned int flags;
 
+       bool beacon_crc_valid;
        u32 beacon_crc;
 
        enum {
@@ -372,6 +393,13 @@ struct ieee80211_if_managed {
         */
        int ave_beacon_signal;
 
+       /*
+        * Number of Beacon frames used in ave_beacon_signal. This can be used
+        * to avoid generating less reliable cqm events that would be based
+        * only on couple of received frames.
+        */
+       unsigned int count_beacon_signal;
+
        /*
         * Last Beacon frame signal strength average (ave_beacon_signal / 16)
         * that triggered a cqm event. 0 indicates that no event has been
@@ -380,19 +408,15 @@ struct ieee80211_if_managed {
        int last_cqm_event_signal;
 };
 
-enum ieee80211_ibss_request {
-       IEEE80211_IBSS_REQ_RUN  = 0,
-};
-
 struct ieee80211_if_ibss {
        struct timer_list timer;
-       struct work_struct work;
 
-       struct sk_buff_head skb_queue;
+       struct mutex mtx;
 
-       unsigned long request;
        unsigned long last_scan_completed;
 
+       u32 basic_rates;
+
        bool timer_running;
 
        bool fixed_bssid;
@@ -416,11 +440,9 @@ struct ieee80211_if_ibss {
 };
 
 struct ieee80211_if_mesh {
-       struct work_struct work;
        struct timer_list housekeeping_timer;
        struct timer_list mesh_path_timer;
        struct timer_list mesh_path_root_timer;
-       struct sk_buff_head skb_queue;
 
        unsigned long timers_running;
 
@@ -482,6 +504,19 @@ enum ieee80211_sub_if_data_flags {
        IEEE80211_SDATA_DONT_BRIDGE_PACKETS     = BIT(3),
 };
 
+/**
+ * enum ieee80211_sdata_state_bits - virtual interface state bits
+ * @SDATA_STATE_RUNNING: virtual interface is up & running; this
+ *     mirrors netif_running() but is separate for interface type
+ *     change handling while the interface is up
+ * @SDATA_STATE_OFFCHANNEL: This interface is currently in offchannel
+ *     mode, so queues are stopped
+ */
+enum ieee80211_sdata_state_bits {
+       SDATA_STATE_RUNNING,
+       SDATA_STATE_OFFCHANNEL,
+};
+
 struct ieee80211_sub_if_data {
        struct list_head list;
 
@@ -495,6 +530,8 @@ struct ieee80211_sub_if_data {
 
        unsigned int flags;
 
+       unsigned long state;
+
        int drop_unencrypted;
 
        char name[IFNAMSIZ];
@@ -505,17 +542,25 @@ struct ieee80211_sub_if_data {
         */
        bool ht_opmode_valid;
 
+       /* to detect idle changes */
+       bool old_idle;
+
        /* Fragment table for host-based reassembly */
        struct ieee80211_fragment_entry fragments[IEEE80211_FRAGMENT_MAX];
        unsigned int fragment_next;
 
-#define NUM_DEFAULT_KEYS 4
-#define NUM_DEFAULT_MGMT_KEYS 2
        struct ieee80211_key *keys[NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS];
        struct ieee80211_key *default_key;
        struct ieee80211_key *default_mgmt_key;
 
        u16 sequence_number;
+       __be16 control_port_protocol;
+       bool control_port_no_encrypt;
+
+       struct work_struct work;
+       struct sk_buff_head skb_queue;
+
+       bool arp_filter_state;
 
        /*
         * AP this belongs to: self in AP mode and
@@ -542,6 +587,7 @@ struct ieee80211_sub_if_data {
 #ifdef CONFIG_MAC80211_DEBUGFS
        struct {
                struct dentry *dir;
+               struct dentry *subdir_stations;
                struct dentry *default_key;
                struct dentry *default_mgmt_key;
        } debugfs;
@@ -569,11 +615,15 @@ ieee80211_sdata_set_mesh_id(struct ieee80211_sub_if_data *sdata,
 #endif
 }
 
+enum sdata_queue_type {
+       IEEE80211_SDATA_QUEUE_TYPE_FRAME        = 0,
+       IEEE80211_SDATA_QUEUE_AGG_START         = 1,
+       IEEE80211_SDATA_QUEUE_AGG_STOP          = 2,
+};
+
 enum {
        IEEE80211_RX_MSG        = 1,
        IEEE80211_TX_STATUS_MSG = 2,
-       IEEE80211_DELBA_MSG     = 3,
-       IEEE80211_ADDBA_MSG     = 4,
 };
 
 enum queue_stop_reason {
@@ -594,11 +644,17 @@ enum queue_stop_reason {
  *     determine if we are on the operating channel or not
  * @SCAN_OFF_CHANNEL: We're off our operating channel for scanning,
  *     gets only set in conjunction with SCAN_SW_SCANNING
+ * @SCAN_COMPLETED: Set for our scan work function when the driver reported
+ *     that the scan completed.
+ * @SCAN_ABORTED: Set for our scan work function when the driver reported
+ *     a scan complete for an aborted scan.
  */
 enum {
        SCAN_SW_SCANNING,
        SCAN_HW_SCANNING,
        SCAN_OFF_CHANNEL,
+       SCAN_COMPLETED,
+       SCAN_ABORTED,
 };
 
 /**
@@ -633,7 +689,6 @@ struct ieee80211_local {
        /*
         * work stuff, potentially off-channel (in the future)
         */
-       struct mutex work_mtx;
        struct list_head work_list;
        struct timer_list work_timer;
        struct work_struct work_work;
@@ -652,9 +707,13 @@ struct ieee80211_local {
        int open_count;
        int monitors, cooked_mntrs;
        /* number of interfaces with corresponding FIF_ flags */
-       int fif_fcsfail, fif_plcpfail, fif_control, fif_other_bss, fif_pspoll;
+       int fif_fcsfail, fif_plcpfail, fif_control, fif_other_bss, fif_pspoll,
+           fif_probe_req;
+       int probe_req_reg;
        unsigned int filter_flags; /* FIF_* */
 
+       bool wiphy_ciphers_allocated;
+
        /* protects the aggregated multicast list and filter calls */
        spinlock_t filter_lock;
 
@@ -724,13 +783,7 @@ struct ieee80211_local {
        struct sk_buff_head pending[IEEE80211_MAX_QUEUES];
        struct tasklet_struct tx_pending_tasklet;
 
-       /*
-        * This lock is used to prevent concurrent A-MPDU
-        * session start/stop processing, this thus also
-        * synchronises the ->ampdu_action() callback to
-        * drivers and limits it to one at a time.
-        */
-       spinlock_t ampdu_lock;
+       atomic_t agg_queue_stop[IEEE80211_MAX_QUEUES];
 
        /* number of interfaces with corresponding IFF_ flags */
        atomic_t iff_allmultis, iff_promiscs;
@@ -746,14 +799,15 @@ struct ieee80211_local {
        struct mutex iflist_mtx;
 
        /*
-        * Key lock, protects sdata's key_list and sta_info's
+        * Key mutex, protects sdata's key_list and sta_info's
         * key pointers (write access, they're RCU.)
         */
-       spinlock_t key_lock;
+       struct mutex key_mtx;
 
+       /* mutex for scan and work locking */
+       struct mutex mtx;
 
        /* Scanning and BSS list */
-       struct mutex scan_mtx;
        unsigned long scanning;
        struct cfg80211_ssid scan_ssid;
        struct cfg80211_scan_request *int_scan_req;
@@ -851,6 +905,15 @@ struct ieee80211_local {
        struct work_struct dynamic_ps_disable_work;
        struct timer_list dynamic_ps_timer;
        struct notifier_block network_latency_notifier;
+       struct notifier_block ifa_notifier;
+
+       /*
+        * The dynamic ps timeout configured from user space via WEXT -
+        * this will override whatever chosen by mac80211 internally.
+        */
+       int dynamic_ps_forced_timeout;
+       int dynamic_ps_user_timeout;
+       bool disable_dynamic_ps;
 
        int user_power_level; /* in dBm */
        int power_constr_level; /* in dBm */
@@ -862,10 +925,14 @@ struct ieee80211_local {
 #ifdef CONFIG_MAC80211_DEBUGFS
        struct local_debugfsdentries {
                struct dentry *rcdir;
-               struct dentry *stations;
                struct dentry *keys;
        } debugfs;
 #endif
+
+       /* dummy netdev for use w/ NAPI */
+       struct net_device napi_dev;
+
+       struct napi_struct napi;
 };
 
 static inline struct ieee80211_sub_if_data *
@@ -874,9 +941,8 @@ IEEE80211_DEV_TO_SUB_IF(struct net_device *dev)
        return netdev_priv(dev);
 }
 
-/* this struct represents 802.11n's RA/TID combination along with our vif */
+/* this struct represents 802.11n's RA/TID combination */
 struct ieee80211_ra_tid {
-       struct ieee80211_vif *vif;
        u8 ra[ETH_ALEN];
        u16 tid;
 };
@@ -985,29 +1051,27 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata,
 int ieee80211_mgd_disassoc(struct ieee80211_sub_if_data *sdata,
                           struct cfg80211_disassoc_request *req,
                           void *cookie);
-int ieee80211_mgd_action(struct ieee80211_sub_if_data *sdata,
-                        struct ieee80211_channel *chan,
-                        enum nl80211_channel_type channel_type,
-                        const u8 *buf, size_t len, u64 *cookie);
-ieee80211_rx_result ieee80211_sta_rx_mgmt(struct ieee80211_sub_if_data *sdata,
-                                         struct sk_buff *skb);
 void ieee80211_send_pspoll(struct ieee80211_local *local,
                           struct ieee80211_sub_if_data *sdata);
 void ieee80211_recalc_ps(struct ieee80211_local *local, s32 latency);
 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);
 void ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
                                      struct ieee80211_channel_sw_ie *sw_elem,
                                      struct ieee80211_bss *bss,
                                      u64 timestamp);
 void ieee80211_sta_quiesce(struct ieee80211_sub_if_data *sdata);
 void ieee80211_sta_restart(struct ieee80211_sub_if_data *sdata);
+void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata);
+void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
+                                 struct sk_buff *skb);
+void ieee80211_sta_reset_beacon_monitor(struct ieee80211_sub_if_data *sdata);
+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);
-ieee80211_rx_result
-ieee80211_ibss_rx_mgmt(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb);
 struct sta_info *ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata,
                                        u8 *bssid, u8 *addr, u32 supp_rates,
                                        gfp_t gfp);
@@ -1016,6 +1080,14 @@ int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata,
 int ieee80211_ibss_leave(struct ieee80211_sub_if_data *sdata);
 void ieee80211_ibss_quiesce(struct ieee80211_sub_if_data *sdata);
 void ieee80211_ibss_restart(struct ieee80211_sub_if_data *sdata);
+void ieee80211_ibss_work(struct ieee80211_sub_if_data *sdata);
+void ieee80211_ibss_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
+                                  struct sk_buff *skb);
+
+/* mesh code */
+void ieee80211_mesh_work(struct ieee80211_sub_if_data *sdata);
+void ieee80211_mesh_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
+                                  struct sk_buff *skb);
 
 /* scan/BSS handling */
 void ieee80211_scan_work(struct work_struct *work);
@@ -1061,10 +1133,12 @@ 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);
 
 static inline bool ieee80211_sdata_running(struct ieee80211_sub_if_data *sdata)
 {
-       return netif_running(sdata->dev);
+       return test_bit(SDATA_STATE_RUNNING, &sdata->state);
 }
 
 /* tx handling */
@@ -1098,10 +1172,13 @@ void ieee80211_send_delba(struct ieee80211_sub_if_data *sdata,
 int ieee80211_send_smps_action(struct ieee80211_sub_if_data *sdata,
                               enum ieee80211_smps_mode smps, const u8 *da,
                               const u8 *bssid);
+void ieee80211_request_smps_work(struct work_struct *work);
 
+void ___ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid,
+                                    u16 initiator, u16 reason, bool stop);
 void __ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid,
-                                   u16 initiator, u16 reason);
-void ieee80211_sta_tear_down_BA_sessions(struct sta_info *sta);
+                                   u16 initiator, u16 reason, bool stop);
+void ieee80211_sta_tear_down_BA_sessions(struct sta_info *sta, bool tx);
 void ieee80211_process_delba(struct ieee80211_sub_if_data *sdata,
                             struct sta_info *sta,
                             struct ieee80211_mgmt *mgmt, size_t len);
@@ -1115,9 +1192,16 @@ void ieee80211_process_addba_request(struct ieee80211_local *local,
                                     size_t len);
 
 int __ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid,
-                                  enum ieee80211_back_parties initiator);
+                                  enum ieee80211_back_parties initiator,
+                                  bool tx);
 int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid,
-                                   enum ieee80211_back_parties initiator);
+                                   enum ieee80211_back_parties initiator,
+                                   bool tx);
+void ieee80211_start_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u16 tid);
+void ieee80211_stop_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u8 tid);
+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);
 
 /* Spectrum management */
 void ieee80211_process_measurement_req(struct ieee80211_sub_if_data *sdata,
@@ -1133,6 +1217,12 @@ int __ieee80211_suspend(struct ieee80211_hw *hw);
 
 static inline int __ieee80211_resume(struct ieee80211_hw *hw)
 {
+       struct ieee80211_local *local = hw_to_local(hw);
+
+       WARN(test_bit(SCAN_HW_SCANNING, &local->scanning),
+               "%s: resume with hardware scan still in progress\n",
+               wiphy_name(hw->wiphy));
+
        return ieee80211_reconfig(hw_to_local(hw));
 }
 #else
@@ -1195,7 +1285,8 @@ void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata,
                         const u8 *key, u8 key_len, u8 key_idx);
 int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer,
                             const u8 *ie, size_t ie_len,
-                            enum ieee80211_band band);
+                            enum ieee80211_band band, u32 rate_mask,
+                            u8 channel);
 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);
@@ -1208,8 +1299,7 @@ u32 ieee80211_sta_get_rates(struct ieee80211_local *local,
                            enum ieee80211_band band);
 int __ieee80211_request_smps(struct ieee80211_sub_if_data *sdata,
                             enum ieee80211_smps_mode smps_mode);
-void ieee80211_recalc_smps(struct ieee80211_local *local,
-                          struct ieee80211_sub_if_data *forsdata);
+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);