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 20 struct 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 struct cfg80211_sched_scan_request *sched_scan_req; 64 unsigned long suspend_at; 65 struct work_struct scan_done_wk; 66 struct work_struct sched_scan_results_wk; 67 68 #ifdef CONFIG_NL80211_TESTMODE 69 struct genl_info *testmode_info; 70 #endif 71 72 struct work_struct conn_work; 73 struct work_struct event_work; 74 75 struct cfg80211_wowlan *wowlan; 76 77 /* must be last because of the way we do wiphy_priv(), 78 * and it should at least be aligned to NETDEV_ALIGN */ 79 struct wiphy wiphy __attribute__((__aligned__(NETDEV_ALIGN))); 80 }; 81 82 static inline 83 struct cfg80211_registered_device *wiphy_to_dev(struct wiphy *wiphy) 84 { 85 BUG_ON(!wiphy); 86 return container_of(wiphy, struct cfg80211_registered_device, wiphy); 87 } 88 89 /* Note 0 is valid, hence phy0 */ 90 static inline 91 bool wiphy_idx_valid(int wiphy_idx) 92 { 93 return wiphy_idx >= 0; 94 } 95 96 static inline void 97 cfg80211_rdev_free_wowlan(struct cfg80211_registered_device *rdev) 98 { 99 int i; 100 101 if (!rdev->wowlan) 102 return; 103 for (i = 0; i < rdev->wowlan->n_patterns; i++) 104 kfree(rdev->wowlan->patterns[i].mask); 105 kfree(rdev->wowlan->patterns); 106 kfree(rdev->wowlan); 107 } 108 109 extern struct workqueue_struct *cfg80211_wq; 110 extern struct mutex cfg80211_mutex; 111 extern struct list_head cfg80211_rdev_list; 112 extern int cfg80211_rdev_list_generation; 113 114 static inline void assert_cfg80211_lock(void) 115 { 116 lockdep_assert_held(&cfg80211_mutex); 117 } 118 119 /* 120 * You can use this to mark a wiphy_idx as not having an associated wiphy. 121 * It guarantees cfg80211_rdev_by_wiphy_idx(wiphy_idx) will return NULL 122 */ 123 #define WIPHY_IDX_STALE -1 124 125 struct cfg80211_internal_bss { 126 struct list_head list; 127 struct rb_node rbn; 128 unsigned long ts; 129 struct kref ref; 130 atomic_t hold; 131 bool beacon_ies_allocated; 132 bool proberesp_ies_allocated; 133 134 /* must be last because of priv member */ 135 struct cfg80211_bss pub; 136 }; 137 138 static inline struct cfg80211_internal_bss *bss_from_pub(struct cfg80211_bss *pub) 139 { 140 return container_of(pub, struct cfg80211_internal_bss, pub); 141 } 142 143 static inline void cfg80211_ref_bss(struct cfg80211_internal_bss *bss) 144 { 145 kref_get(&bss->ref); 146 } 147 148 static inline void cfg80211_hold_bss(struct cfg80211_internal_bss *bss) 149 { 150 atomic_inc(&bss->hold); 151 } 152 153 static inline void cfg80211_unhold_bss(struct cfg80211_internal_bss *bss) 154 { 155 int r = atomic_dec_return(&bss->hold); 156 WARN_ON(r < 0); 157 } 158 159 160 struct cfg80211_registered_device *cfg80211_rdev_by_wiphy_idx(int wiphy_idx); 161 int get_wiphy_idx(struct wiphy *wiphy); 162 163 struct cfg80211_registered_device * 164 __cfg80211_rdev_from_info(struct genl_info *info); 165 166 /* 167 * This function returns a pointer to the driver 168 * that the genl_info item that is passed refers to. 169 * If successful, it returns non-NULL and also locks 170 * the driver's mutex! 171 * 172 * This means that you need to call cfg80211_unlock_rdev() 173 * before being allowed to acquire &cfg80211_mutex! 174 * 175 * This is necessary because we need to lock the global 176 * mutex to get an item off the list safely, and then 177 * we lock the rdev mutex so it doesn't go away under us. 178 * 179 * We don't want to keep cfg80211_mutex locked 180 * for all the time in order to allow requests on 181 * other interfaces to go through at the same time. 182 * 183 * The result of this can be a PTR_ERR and hence must 184 * be checked with IS_ERR() for errors. 185 */ 186 extern struct cfg80211_registered_device * 187 cfg80211_get_dev_from_info(struct genl_info *info); 188 189 /* requires cfg80211_rdev_mutex to be held! */ 190 struct wiphy *wiphy_idx_to_wiphy(int wiphy_idx); 191 192 /* identical to cfg80211_get_dev_from_info but only operate on ifindex */ 193 extern struct cfg80211_registered_device * 194 cfg80211_get_dev_from_ifindex(struct net *net, int ifindex); 195 196 int cfg80211_switch_netns(struct cfg80211_registered_device *rdev, 197 struct net *net); 198 199 static inline void cfg80211_lock_rdev(struct cfg80211_registered_device *rdev) 200 { 201 mutex_lock(&rdev->mtx); 202 } 203 204 static inline void cfg80211_unlock_rdev(struct cfg80211_registered_device *rdev) 205 { 206 BUG_ON(IS_ERR(rdev) || !rdev); 207 mutex_unlock(&rdev->mtx); 208 } 209 210 static inline void wdev_lock(struct wireless_dev *wdev) 211 __acquires(wdev) 212 { 213 mutex_lock(&wdev->mtx); 214 __acquire(wdev->mtx); 215 } 216 217 static inline void wdev_unlock(struct wireless_dev *wdev) 218 __releases(wdev) 219 { 220 __release(wdev->mtx); 221 mutex_unlock(&wdev->mtx); 222 } 223 224 #define ASSERT_RDEV_LOCK(rdev) lockdep_assert_held(&(rdev)->mtx) 225 #define ASSERT_WDEV_LOCK(wdev) lockdep_assert_held(&(wdev)->mtx) 226 227 enum cfg80211_event_type { 228 EVENT_CONNECT_RESULT, 229 EVENT_ROAMED, 230 EVENT_DISCONNECTED, 231 EVENT_IBSS_JOINED, 232 }; 233 234 struct cfg80211_event { 235 struct list_head list; 236 enum cfg80211_event_type type; 237 238 union { 239 struct { 240 u8 bssid[ETH_ALEN]; 241 const u8 *req_ie; 242 const u8 *resp_ie; 243 size_t req_ie_len; 244 size_t resp_ie_len; 245 u16 status; 246 } cr; 247 struct { 248 struct ieee80211_channel *channel; 249 u8 bssid[ETH_ALEN]; 250 const u8 *req_ie; 251 const u8 *resp_ie; 252 size_t req_ie_len; 253 size_t resp_ie_len; 254 } rm; 255 struct { 256 const u8 *ie; 257 size_t ie_len; 258 u16 reason; 259 } dc; 260 struct { 261 u8 bssid[ETH_ALEN]; 262 } ij; 263 }; 264 }; 265 266 struct cfg80211_cached_keys { 267 struct key_params params[6]; 268 u8 data[6][WLAN_MAX_KEY_LEN]; 269 int def, defmgmt; 270 }; 271 272 273 /* free object */ 274 extern void cfg80211_dev_free(struct cfg80211_registered_device *rdev); 275 276 extern int cfg80211_dev_rename(struct cfg80211_registered_device *rdev, 277 char *newname); 278 279 void ieee80211_set_bitrate_flags(struct wiphy *wiphy); 280 void wiphy_update_regulatory(struct wiphy *wiphy, 281 enum nl80211_reg_initiator setby); 282 283 void cfg80211_bss_expire(struct cfg80211_registered_device *dev); 284 void cfg80211_bss_age(struct cfg80211_registered_device *dev, 285 unsigned long age_secs); 286 287 /* IBSS */ 288 int __cfg80211_join_ibss(struct cfg80211_registered_device *rdev, 289 struct net_device *dev, 290 struct cfg80211_ibss_params *params, 291 struct cfg80211_cached_keys *connkeys); 292 int cfg80211_join_ibss(struct cfg80211_registered_device *rdev, 293 struct net_device *dev, 294 struct cfg80211_ibss_params *params, 295 struct cfg80211_cached_keys *connkeys); 296 void cfg80211_clear_ibss(struct net_device *dev, bool nowext); 297 int __cfg80211_leave_ibss(struct cfg80211_registered_device *rdev, 298 struct net_device *dev, bool nowext); 299 int cfg80211_leave_ibss(struct cfg80211_registered_device *rdev, 300 struct net_device *dev, bool nowext); 301 void __cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid); 302 int cfg80211_ibss_wext_join(struct cfg80211_registered_device *rdev, 303 struct wireless_dev *wdev); 304 305 /* mesh */ 306 extern const struct mesh_config default_mesh_config; 307 extern const struct mesh_setup default_mesh_setup; 308 int __cfg80211_join_mesh(struct cfg80211_registered_device *rdev, 309 struct net_device *dev, 310 const struct mesh_setup *setup, 311 const struct mesh_config *conf); 312 int cfg80211_join_mesh(struct cfg80211_registered_device *rdev, 313 struct net_device *dev, 314 const struct mesh_setup *setup, 315 const struct mesh_config *conf); 316 int cfg80211_leave_mesh(struct cfg80211_registered_device *rdev, 317 struct net_device *dev); 318 319 /* MLME */ 320 int __cfg80211_mlme_auth(struct cfg80211_registered_device *rdev, 321 struct net_device *dev, 322 struct ieee80211_channel *chan, 323 enum nl80211_auth_type auth_type, 324 const u8 *bssid, 325 const u8 *ssid, int ssid_len, 326 const u8 *ie, int ie_len, 327 const u8 *key, int key_len, int key_idx, 328 bool local_state_change); 329 int cfg80211_mlme_auth(struct cfg80211_registered_device *rdev, 330 struct net_device *dev, struct ieee80211_channel *chan, 331 enum nl80211_auth_type auth_type, const u8 *bssid, 332 const u8 *ssid, int ssid_len, 333 const u8 *ie, int ie_len, 334 const u8 *key, int key_len, int key_idx, 335 bool local_state_change); 336 int __cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev, 337 struct net_device *dev, 338 struct ieee80211_channel *chan, 339 const u8 *bssid, const u8 *prev_bssid, 340 const u8 *ssid, int ssid_len, 341 const u8 *ie, int ie_len, bool use_mfp, 342 struct cfg80211_crypto_settings *crypt); 343 int cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev, 344 struct net_device *dev, struct ieee80211_channel *chan, 345 const u8 *bssid, const u8 *prev_bssid, 346 const u8 *ssid, int ssid_len, 347 const u8 *ie, int ie_len, bool use_mfp, 348 struct cfg80211_crypto_settings *crypt); 349 int __cfg80211_mlme_deauth(struct cfg80211_registered_device *rdev, 350 struct net_device *dev, const u8 *bssid, 351 const u8 *ie, int ie_len, u16 reason, 352 bool local_state_change); 353 int cfg80211_mlme_deauth(struct cfg80211_registered_device *rdev, 354 struct net_device *dev, const u8 *bssid, 355 const u8 *ie, int ie_len, u16 reason, 356 bool local_state_change); 357 int cfg80211_mlme_disassoc(struct cfg80211_registered_device *rdev, 358 struct net_device *dev, const u8 *bssid, 359 const u8 *ie, int ie_len, u16 reason, 360 bool local_state_change); 361 void cfg80211_mlme_down(struct cfg80211_registered_device *rdev, 362 struct net_device *dev); 363 void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid, 364 const u8 *req_ie, size_t req_ie_len, 365 const u8 *resp_ie, size_t resp_ie_len, 366 u16 status, bool wextev, 367 struct cfg80211_bss *bss); 368 int cfg80211_mlme_register_mgmt(struct wireless_dev *wdev, u32 snd_pid, 369 u16 frame_type, const u8 *match_data, 370 int match_len); 371 void cfg80211_mlme_unregister_socket(struct wireless_dev *wdev, u32 nlpid); 372 void cfg80211_mlme_purge_registrations(struct wireless_dev *wdev); 373 int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev, 374 struct net_device *dev, 375 struct ieee80211_channel *chan, bool offchan, 376 enum nl80211_channel_type channel_type, 377 bool channel_type_valid, unsigned int wait, 378 const u8 *buf, size_t len, u64 *cookie); 379 380 /* SME */ 381 int __cfg80211_connect(struct cfg80211_registered_device *rdev, 382 struct net_device *dev, 383 struct cfg80211_connect_params *connect, 384 struct cfg80211_cached_keys *connkeys, 385 const u8 *prev_bssid); 386 int cfg80211_connect(struct cfg80211_registered_device *rdev, 387 struct net_device *dev, 388 struct cfg80211_connect_params *connect, 389 struct cfg80211_cached_keys *connkeys); 390 int __cfg80211_disconnect(struct cfg80211_registered_device *rdev, 391 struct net_device *dev, u16 reason, 392 bool wextev); 393 int cfg80211_disconnect(struct cfg80211_registered_device *rdev, 394 struct net_device *dev, u16 reason, 395 bool wextev); 396 void __cfg80211_roamed(struct wireless_dev *wdev, 397 struct ieee80211_channel *channel, 398 const u8 *bssid, 399 const u8 *req_ie, size_t req_ie_len, 400 const u8 *resp_ie, size_t resp_ie_len); 401 int cfg80211_mgd_wext_connect(struct cfg80211_registered_device *rdev, 402 struct wireless_dev *wdev); 403 404 void cfg80211_conn_work(struct work_struct *work); 405 void cfg80211_sme_failed_assoc(struct wireless_dev *wdev); 406 bool cfg80211_sme_failed_reassoc(struct wireless_dev *wdev); 407 408 /* internal helpers */ 409 int cfg80211_validate_key_settings(struct cfg80211_registered_device *rdev, 410 struct key_params *params, int key_idx, 411 bool pairwise, const u8 *mac_addr); 412 void __cfg80211_disconnected(struct net_device *dev, const u8 *ie, 413 size_t ie_len, u16 reason, bool from_ap); 414 void cfg80211_sme_scan_done(struct net_device *dev); 415 void cfg80211_sme_rx_auth(struct net_device *dev, const u8 *buf, size_t len); 416 void cfg80211_sme_disassoc(struct net_device *dev, int idx); 417 void __cfg80211_scan_done(struct work_struct *wk); 418 void ___cfg80211_scan_done(struct cfg80211_registered_device *rdev, bool leak); 419 void __cfg80211_sched_scan_results(struct work_struct *wk); 420 int __cfg80211_stop_sched_scan(struct cfg80211_registered_device *rdev, 421 bool driver_initiated); 422 void cfg80211_upload_connect_keys(struct wireless_dev *wdev); 423 int cfg80211_change_iface(struct cfg80211_registered_device *rdev, 424 struct net_device *dev, enum nl80211_iftype ntype, 425 u32 *flags, struct vif_params *params); 426 void cfg80211_process_rdev_events(struct cfg80211_registered_device *rdev); 427 428 int cfg80211_can_change_interface(struct cfg80211_registered_device *rdev, 429 struct wireless_dev *wdev, 430 enum nl80211_iftype iftype); 431 432 static inline int 433 cfg80211_can_add_interface(struct cfg80211_registered_device *rdev, 434 enum nl80211_iftype iftype) 435 { 436 return cfg80211_can_change_interface(rdev, NULL, iftype); 437 } 438 439 struct ieee80211_channel * 440 rdev_freq_to_chan(struct cfg80211_registered_device *rdev, 441 int freq, enum nl80211_channel_type channel_type); 442 int cfg80211_set_freq(struct cfg80211_registered_device *rdev, 443 struct wireless_dev *wdev, int freq, 444 enum nl80211_channel_type channel_type); 445 446 u16 cfg80211_calculate_bitrate(struct rate_info *rate); 447 448 int cfg80211_validate_beacon_int(struct cfg80211_registered_device *rdev, 449 u32 beacon_int); 450 451 #ifdef CONFIG_CFG80211_DEVELOPER_WARNINGS 452 #define CFG80211_DEV_WARN_ON(cond) WARN_ON(cond) 453 #else 454 /* 455 * Trick to enable using it as a condition, 456 * and also not give a warning when it's 457 * not used that way. 458 */ 459 #define CFG80211_DEV_WARN_ON(cond) ({bool __r = (cond); __r; }) 460 #endif 461 462 #endif /* __NET_WIRELESS_CORE_H */ 463