mac80211: generalise work handling
In order to use auth/assoc for different purposes
other than MLME, it needs to be split up. For other
purposes, a generic work handling (potentially on
another channel) will be useful.
To achieve that, this patch moves much of the MLME
work handling out of mlme into a new work API. The
API can currently handle probing a specific AP,
authentication and association. The MLME previously
handled probe/authentication as one step and will
continue to do so, but they are separate in the new
work handling.
Work items are RCU-managed to be able to check for
existence of an item for a specific frame in the RX
path, but they can be re-used which the MLME right
now will do for its combined probe/auth step.
Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 0339e90..97b6076 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -228,41 +228,63 @@
};
enum ieee80211_work_type {
- IEEE80211_WORK_AUTH_PROBE,
+ IEEE80211_WORK_DIRECT_PROBE,
IEEE80211_WORK_AUTH,
IEEE80211_WORK_ASSOC,
};
+/**
+ * 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,
+};
+
struct ieee80211_work {
struct list_head list;
+ struct rcu_head rcu_head;
+
+ struct ieee80211_sub_if_data *sdata;
+
+ enum work_done_result (*done)(struct ieee80211_work *wk,
+ struct sk_buff *skb);
+
struct ieee80211_channel *chan;
/* XXX: chan type? -- right now not really needed */
+
unsigned long timeout;
enum ieee80211_work_type type;
+ u8 filter_ta[ETH_ALEN];
+
union {
struct {
int tries;
u16 algorithm, transaction;
u8 ssid[IEEE80211_MAX_SSID_LEN];
u8 ssid_len;
- u8 bssid[ETH_ALEN];
u8 key[WLAN_KEY_LEN_WEP104];
u8 key_len, key_idx;
bool privacy;
- } auth;
+ } probe_auth;
struct {
struct ieee80211_bss *bss;
const u8 *supp_rates;
const u8 *ht_information_ie;
+ enum ieee80211_smps_mode smps;
int tries;
u16 capability;
- u8 bssid[ETH_ALEN], prev_bssid[ETH_ALEN];
+ u8 prev_bssid[ETH_ALEN];
u8 ssid[IEEE80211_MAX_SSID_LEN];
u8 ssid_len;
u8 supp_rates_len;
- bool wmm_used;
+ bool wmm_used, use_11n;
} assoc;
};
@@ -276,17 +298,11 @@
IEEE80211_STA_BEACON_POLL = BIT(0),
IEEE80211_STA_CONNECTION_POLL = BIT(1),
IEEE80211_STA_CONTROL_PORT = BIT(2),
- IEEE80211_STA_WMM_ENABLED = BIT(3),
IEEE80211_STA_DISABLE_11N = BIT(4),
IEEE80211_STA_CSA_RECEIVED = BIT(5),
IEEE80211_STA_MFP_ENABLED = BIT(6),
};
-/* flags for MLME request */
-enum ieee80211_sta_request {
- IEEE80211_STA_REQ_SCAN,
-};
-
struct ieee80211_if_managed {
struct timer_list timer;
struct timer_list conn_mon_timer;
@@ -302,12 +318,10 @@
struct mutex mtx;
struct ieee80211_bss *associated;
- struct list_head work_list;
u8 bssid[ETH_ALEN];
u16 aid;
- u16 capab;
struct sk_buff_head skb_queue;
@@ -316,8 +330,6 @@
enum ieee80211_smps_mode req_smps, /* requested smps mode */
ap_smps; /* smps mode AP thinks we're in */
- unsigned long request;
-
unsigned int flags;
u32 beacon_crc;
@@ -584,6 +596,15 @@
const struct ieee80211_ops *ops;
/*
+ * 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;
+ struct sk_buff_head work_skb_queue;
+
+ /*
* private workqueue to mac80211. mac80211 makes this accessible
* via ieee80211_queue_work()
*/
@@ -1127,6 +1148,14 @@
void ieee80211_recalc_smps(struct ieee80211_local *local,
struct ieee80211_sub_if_data *forsdata);
+/* 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);
+ieee80211_rx_result ieee80211_work_rx_mgmt(struct ieee80211_sub_if_data *sdata,
+ struct sk_buff *skb);
+
#ifdef CONFIG_MAC80211_NOINLINE
#define debug_noinline noinline
#else