• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /netgear-R7000-V1.0.7.12_1.2.5/components/opensource/linux/linux-2.6.36/net/wireless/
1/*
2 * Wireless configuration interface internals.
3 *
4 * Copyright 2006-2010	Johannes Berg <johannes@sipsolutions.net>
5 */
6#ifndef __NET_WIRELESS_CORE_H
7#define __NET_WIRELESS_CORE_H
8#include <linux/mutex.h>
9#include <linux/list.h>
10#include <linux/netdevice.h>
11#include <linux/kref.h>
12#include <linux/rbtree.h>
13#include <linux/debugfs.h>
14#include <linux/rfkill.h>
15#include <linux/workqueue.h>
16#include <net/genetlink.h>
17#include <net/cfg80211.h>
18#include "reg.h"
19
20struct cfg80211_registered_device {
21	const struct cfg80211_ops *ops;
22	struct list_head list;
23	/* we hold this mutex during any call so that
24	 * we cannot do multiple calls at once, and also
25	 * to avoid the deregister call to proceed while
26	 * any call is in progress */
27	struct mutex mtx;
28
29	/* rfkill support */
30	struct rfkill_ops rfkill_ops;
31	struct rfkill *rfkill;
32	struct work_struct rfkill_sync;
33
34	/* ISO / IEC 3166 alpha2 for which this device is receiving
35	 * country IEs on, this can help disregard country IEs from APs
36	 * on the same alpha2 quickly. The alpha2 may differ from
37	 * cfg80211_regdomain's alpha2 when an intersection has occurred.
38	 * If the AP is reconfigured this can also be used to tell us if
39	 * the country on the country IE changed. */
40	char country_ie_alpha2[2];
41
42	/* If a Country IE has been received this tells us the environment
43	 * which its telling us its in. This defaults to ENVIRON_ANY */
44	enum environment_cap env;
45
46	/* wiphy index, internal only */
47	int wiphy_idx;
48
49	/* associate netdev list */
50	struct mutex devlist_mtx;
51	/* protected by devlist_mtx or RCU */
52	struct list_head netdev_list;
53	int devlist_generation;
54	int opencount; /* also protected by devlist_mtx */
55	wait_queue_head_t dev_wait;
56
57	/* BSSes/scanning */
58	spinlock_t bss_lock;
59	struct list_head bss_list;
60	struct rb_root bss_tree;
61	u32 bss_generation;
62	struct cfg80211_scan_request *scan_req; /* protected by RTNL */
63	unsigned long suspend_at;
64	struct work_struct scan_done_wk;
65
66#ifdef CONFIG_NL80211_TESTMODE
67	struct genl_info *testmode_info;
68#endif
69
70	struct work_struct conn_work;
71	struct work_struct event_work;
72
73	/* must be last because of the way we do wiphy_priv(),
74	 * and it should at least be aligned to NETDEV_ALIGN */
75	struct wiphy wiphy __attribute__((__aligned__(NETDEV_ALIGN)));
76};
77
78static inline
79struct cfg80211_registered_device *wiphy_to_dev(struct wiphy *wiphy)
80{
81	BUG_ON(!wiphy);
82	return container_of(wiphy, struct cfg80211_registered_device, wiphy);
83}
84
85/* Note 0 is valid, hence phy0 */
86static inline
87bool wiphy_idx_valid(int wiphy_idx)
88{
89	return (wiphy_idx >= 0);
90}
91
92
93extern struct workqueue_struct *cfg80211_wq;
94extern struct mutex cfg80211_mutex;
95extern struct list_head cfg80211_rdev_list;
96extern int cfg80211_rdev_list_generation;
97
98#define assert_cfg80211_lock() WARN_ON(!mutex_is_locked(&cfg80211_mutex))
99
100/*
101 * You can use this to mark a wiphy_idx as not having an associated wiphy.
102 * It guarantees cfg80211_rdev_by_wiphy_idx(wiphy_idx) will return NULL
103 */
104#define WIPHY_IDX_STALE -1
105
106struct cfg80211_internal_bss {
107	struct list_head list;
108	struct rb_node rbn;
109	unsigned long ts;
110	struct kref ref;
111	atomic_t hold;
112	bool beacon_ies_allocated;
113	bool proberesp_ies_allocated;
114
115	/* must be last because of priv member */
116	struct cfg80211_bss pub;
117};
118
119static inline struct cfg80211_internal_bss *bss_from_pub(struct cfg80211_bss *pub)
120{
121	return container_of(pub, struct cfg80211_internal_bss, pub);
122}
123
124static inline void cfg80211_ref_bss(struct cfg80211_internal_bss *bss)
125{
126	kref_get(&bss->ref);
127}
128
129static inline void cfg80211_hold_bss(struct cfg80211_internal_bss *bss)
130{
131	atomic_inc(&bss->hold);
132}
133
134static inline void cfg80211_unhold_bss(struct cfg80211_internal_bss *bss)
135{
136	int r = atomic_dec_return(&bss->hold);
137	WARN_ON(r < 0);
138}
139
140
141struct cfg80211_registered_device *cfg80211_rdev_by_wiphy_idx(int wiphy_idx);
142int get_wiphy_idx(struct wiphy *wiphy);
143
144struct cfg80211_registered_device *
145__cfg80211_rdev_from_info(struct genl_info *info);
146
147/*
148 * This function returns a pointer to the driver
149 * that the genl_info item that is passed refers to.
150 * If successful, it returns non-NULL and also locks
151 * the driver's mutex!
152 *
153 * This means that you need to call cfg80211_unlock_rdev()
154 * before being allowed to acquire &cfg80211_mutex!
155 *
156 * This is necessary because we need to lock the global
157 * mutex to get an item off the list safely, and then
158 * we lock the rdev mutex so it doesn't go away under us.
159 *
160 * We don't want to keep cfg80211_mutex locked
161 * for all the time in order to allow requests on
162 * other interfaces to go through at the same time.
163 *
164 * The result of this can be a PTR_ERR and hence must
165 * be checked with IS_ERR() for errors.
166 */
167extern struct cfg80211_registered_device *
168cfg80211_get_dev_from_info(struct genl_info *info);
169
170/* requires cfg80211_rdev_mutex to be held! */
171struct wiphy *wiphy_idx_to_wiphy(int wiphy_idx);
172
173/* identical to cfg80211_get_dev_from_info but only operate on ifindex */
174extern struct cfg80211_registered_device *
175cfg80211_get_dev_from_ifindex(struct net *net, int ifindex);
176
177int cfg80211_switch_netns(struct cfg80211_registered_device *rdev,
178			  struct net *net);
179
180static inline void cfg80211_lock_rdev(struct cfg80211_registered_device *rdev)
181{
182	mutex_lock(&rdev->mtx);
183}
184
185static inline void cfg80211_unlock_rdev(struct cfg80211_registered_device *rdev)
186{
187	BUG_ON(IS_ERR(rdev) || !rdev);
188	mutex_unlock(&rdev->mtx);
189}
190
191static inline void wdev_lock(struct wireless_dev *wdev)
192	__acquires(wdev)
193{
194	mutex_lock(&wdev->mtx);
195	__acquire(wdev->mtx);
196}
197
198static inline void wdev_unlock(struct wireless_dev *wdev)
199	__releases(wdev)
200{
201	__release(wdev->mtx);
202	mutex_unlock(&wdev->mtx);
203}
204
205#define ASSERT_RDEV_LOCK(rdev) WARN_ON(!mutex_is_locked(&(rdev)->mtx));
206#define ASSERT_WDEV_LOCK(wdev) WARN_ON(!mutex_is_locked(&(wdev)->mtx));
207
208enum cfg80211_event_type {
209	EVENT_CONNECT_RESULT,
210	EVENT_ROAMED,
211	EVENT_DISCONNECTED,
212	EVENT_IBSS_JOINED,
213};
214
215struct cfg80211_event {
216	struct list_head list;
217	enum cfg80211_event_type type;
218
219	union {
220		struct {
221			u8 bssid[ETH_ALEN];
222			const u8 *req_ie;
223			const u8 *resp_ie;
224			size_t req_ie_len;
225			size_t resp_ie_len;
226			u16 status;
227		} cr;
228		struct {
229			u8 bssid[ETH_ALEN];
230			const u8 *req_ie;
231			const u8 *resp_ie;
232			size_t req_ie_len;
233			size_t resp_ie_len;
234		} rm;
235		struct {
236			const u8 *ie;
237			size_t ie_len;
238			u16 reason;
239		} dc;
240		struct {
241			u8 bssid[ETH_ALEN];
242		} ij;
243	};
244};
245
246struct cfg80211_cached_keys {
247	struct key_params params[6];
248	u8 data[6][WLAN_MAX_KEY_LEN];
249	int def, defmgmt;
250};
251
252
253/* free object */
254extern void cfg80211_dev_free(struct cfg80211_registered_device *rdev);
255
256extern int cfg80211_dev_rename(struct cfg80211_registered_device *rdev,
257			       char *newname);
258
259void ieee80211_set_bitrate_flags(struct wiphy *wiphy);
260void wiphy_update_regulatory(struct wiphy *wiphy,
261			     enum nl80211_reg_initiator setby);
262
263void cfg80211_bss_expire(struct cfg80211_registered_device *dev);
264void cfg80211_bss_age(struct cfg80211_registered_device *dev,
265                      unsigned long age_secs);
266
267/* IBSS */
268int __cfg80211_join_ibss(struct cfg80211_registered_device *rdev,
269			 struct net_device *dev,
270			 struct cfg80211_ibss_params *params,
271			 struct cfg80211_cached_keys *connkeys);
272int cfg80211_join_ibss(struct cfg80211_registered_device *rdev,
273		       struct net_device *dev,
274		       struct cfg80211_ibss_params *params,
275		       struct cfg80211_cached_keys *connkeys);
276void cfg80211_clear_ibss(struct net_device *dev, bool nowext);
277int __cfg80211_leave_ibss(struct cfg80211_registered_device *rdev,
278			  struct net_device *dev, bool nowext);
279int cfg80211_leave_ibss(struct cfg80211_registered_device *rdev,
280			struct net_device *dev, bool nowext);
281void __cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid);
282int cfg80211_ibss_wext_join(struct cfg80211_registered_device *rdev,
283			    struct wireless_dev *wdev);
284
285/* MLME */
286int __cfg80211_mlme_auth(struct cfg80211_registered_device *rdev,
287			 struct net_device *dev,
288			 struct ieee80211_channel *chan,
289			 enum nl80211_auth_type auth_type,
290			 const u8 *bssid,
291			 const u8 *ssid, int ssid_len,
292			 const u8 *ie, int ie_len,
293			 const u8 *key, int key_len, int key_idx,
294			 bool local_state_change);
295int cfg80211_mlme_auth(struct cfg80211_registered_device *rdev,
296		       struct net_device *dev, struct ieee80211_channel *chan,
297		       enum nl80211_auth_type auth_type, const u8 *bssid,
298		       const u8 *ssid, int ssid_len,
299		       const u8 *ie, int ie_len,
300		       const u8 *key, int key_len, int key_idx,
301		       bool local_state_change);
302int __cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev,
303			  struct net_device *dev,
304			  struct ieee80211_channel *chan,
305			  const u8 *bssid, const u8 *prev_bssid,
306			  const u8 *ssid, int ssid_len,
307			  const u8 *ie, int ie_len, bool use_mfp,
308			  struct cfg80211_crypto_settings *crypt);
309int cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev,
310			struct net_device *dev, struct ieee80211_channel *chan,
311			const u8 *bssid, const u8 *prev_bssid,
312			const u8 *ssid, int ssid_len,
313			const u8 *ie, int ie_len, bool use_mfp,
314			struct cfg80211_crypto_settings *crypt);
315int __cfg80211_mlme_deauth(struct cfg80211_registered_device *rdev,
316			   struct net_device *dev, const u8 *bssid,
317			   const u8 *ie, int ie_len, u16 reason,
318			   bool local_state_change);
319int cfg80211_mlme_deauth(struct cfg80211_registered_device *rdev,
320			 struct net_device *dev, const u8 *bssid,
321			 const u8 *ie, int ie_len, u16 reason,
322			 bool local_state_change);
323int cfg80211_mlme_disassoc(struct cfg80211_registered_device *rdev,
324			   struct net_device *dev, const u8 *bssid,
325			   const u8 *ie, int ie_len, u16 reason,
326			   bool local_state_change);
327void cfg80211_mlme_down(struct cfg80211_registered_device *rdev,
328			struct net_device *dev);
329void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid,
330			       const u8 *req_ie, size_t req_ie_len,
331			       const u8 *resp_ie, size_t resp_ie_len,
332			       u16 status, bool wextev,
333			       struct cfg80211_bss *bss);
334int cfg80211_mlme_register_action(struct wireless_dev *wdev, u32 snd_pid,
335				  const u8 *match_data, int match_len);
336void cfg80211_mlme_unregister_actions(struct wireless_dev *wdev, u32 nlpid);
337void cfg80211_mlme_purge_actions(struct wireless_dev *wdev);
338int cfg80211_mlme_action(struct cfg80211_registered_device *rdev,
339			 struct net_device *dev,
340			 struct ieee80211_channel *chan,
341			 enum nl80211_channel_type channel_type,
342			 bool channel_type_valid,
343			 const u8 *buf, size_t len, u64 *cookie);
344
345/* SME */
346int __cfg80211_connect(struct cfg80211_registered_device *rdev,
347		       struct net_device *dev,
348		       struct cfg80211_connect_params *connect,
349		       struct cfg80211_cached_keys *connkeys,
350		       const u8 *prev_bssid);
351int cfg80211_connect(struct cfg80211_registered_device *rdev,
352		     struct net_device *dev,
353		     struct cfg80211_connect_params *connect,
354		     struct cfg80211_cached_keys *connkeys);
355int __cfg80211_disconnect(struct cfg80211_registered_device *rdev,
356			  struct net_device *dev, u16 reason,
357			  bool wextev);
358int cfg80211_disconnect(struct cfg80211_registered_device *rdev,
359			struct net_device *dev, u16 reason,
360			bool wextev);
361void __cfg80211_roamed(struct wireless_dev *wdev, const u8 *bssid,
362		       const u8 *req_ie, size_t req_ie_len,
363		       const u8 *resp_ie, size_t resp_ie_len);
364int cfg80211_mgd_wext_connect(struct cfg80211_registered_device *rdev,
365			      struct wireless_dev *wdev);
366
367void cfg80211_conn_work(struct work_struct *work);
368void cfg80211_sme_failed_assoc(struct wireless_dev *wdev);
369bool cfg80211_sme_failed_reassoc(struct wireless_dev *wdev);
370
371/* internal helpers */
372int cfg80211_validate_key_settings(struct cfg80211_registered_device *rdev,
373				   struct key_params *params, int key_idx,
374				   const u8 *mac_addr);
375void __cfg80211_disconnected(struct net_device *dev, const u8 *ie,
376			     size_t ie_len, u16 reason, bool from_ap);
377void cfg80211_sme_scan_done(struct net_device *dev);
378void cfg80211_sme_rx_auth(struct net_device *dev, const u8 *buf, size_t len);
379void cfg80211_sme_disassoc(struct net_device *dev, int idx);
380void __cfg80211_scan_done(struct work_struct *wk);
381void ___cfg80211_scan_done(struct cfg80211_registered_device *rdev, bool leak);
382void cfg80211_upload_connect_keys(struct wireless_dev *wdev);
383int cfg80211_change_iface(struct cfg80211_registered_device *rdev,
384			  struct net_device *dev, enum nl80211_iftype ntype,
385			  u32 *flags, struct vif_params *params);
386void cfg80211_process_rdev_events(struct cfg80211_registered_device *rdev);
387
388struct ieee80211_channel *
389rdev_freq_to_chan(struct cfg80211_registered_device *rdev,
390		  int freq, enum nl80211_channel_type channel_type);
391int cfg80211_set_freq(struct cfg80211_registered_device *rdev,
392		      struct wireless_dev *wdev, int freq,
393		      enum nl80211_channel_type channel_type);
394
395u16 cfg80211_calculate_bitrate(struct rate_info *rate);
396
397#ifdef CONFIG_CFG80211_DEVELOPER_WARNINGS
398#define CFG80211_DEV_WARN_ON(cond)	WARN_ON(cond)
399#else
400/*
401 * Trick to enable using it as a condition,
402 * and also not give a warning when it's
403 * not used that way.
404 */
405#define CFG80211_DEV_WARN_ON(cond)	({bool __r = (cond); __r; })
406#endif
407
408#endif /* __NET_WIRELESS_CORE_H */
409