1 /* 2 * Linux Cfg80211 support 3 * 4 * Copyright (C) 1999-2010, Broadcom Corporation 5 * 6 * Unless you and Broadcom execute a separate written software license 7 * agreement governing use of this software, this software is licensed to you 8 * under the terms of the GNU General Public License version 2 (the "GPL"), 9 * available at http://www.broadcom.com/licenses/GPLv2.php, with the 10 * following added to such license: 11 * 12 * As a special exception, the copyright holders of this software give you 13 * permission to link this software with independent modules, and to copy and 14 * distribute the resulting executable under terms of your choice, provided that 15 * you also meet, for each linked independent module, the terms and conditions of 16 * the license of that module. An independent module is a module which is not 17 * derived from this software. The special exception does not apply to any 18 * modifications of the software. 19 * 20 * Notwithstanding the above, under no circumstances may you combine this 21 * software in any way with any other Broadcom software provided under a license 22 * other than the GPL, without Broadcom's express prior written consent. 23 * 24 * $Id: wl_cfg80211.c,v 1.1.2.28 2010/05/04 21:43:38 Exp $ 25 */ 26 27 #include <typedefs.h> 28 #include <linuxver.h> 29 #include <osl.h> 30 31 #include <bcmutils.h> 32 #include <bcmendian.h> 33 #include <proto/ethernet.h> 34 35 #include <linux/if_arp.h> 36 #include <asm/uaccess.h> 37 38 #include <dngl_stats.h> 39 #include <dhd.h> 40 #include <dhdioctl.h> 41 #include <wlioctl.h> 42 43 #include <proto/ethernet.h> 44 #include <dngl_stats.h> 45 #include <dhd.h> 46 47 #include <linux/kernel.h> 48 #include <linux/netdevice.h> 49 #include <linux/sched.h> 50 #include <linux/etherdevice.h> 51 #include <linux/wireless.h> 52 #include <linux/ieee80211.h> 53 #include <net/cfg80211.h> 54 55 #include <net/rtnetlink.h> 56 #include <linux/mmc/sdio_func.h> 57 #include <linux/firmware.h> 58 #include <wl_cfg80211.h> 59 60 static struct sdio_func *cfg80211_sdio_func = NULL; 61 static struct wl_dev *wl_cfg80211_dev = NULL; 62 63 #ifdef WL_CFG80211_BACKTRACE 64 uint32 wl_dbg_level = WL_DBG_ERR | WL_DBG_INFO | WL_DBG_DBG; 65 #else 66 uint32 wl_dbg_level = WL_DBG_ERR | WL_DBG_INFO; 67 #endif 68 69 #define WL_4329_FW_FILE "brcm/fw_4329.bin" 70 #define WL_4329_NVRAM_FILE "brcm/nvram_4329.txt" 71 72 /* 73 ** cfg80211_ops api/callback list 74 */ 75 static int32 wl_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev, 76 enum nl80211_iftype type, uint32 *flags, struct vif_params *params); 77 static int32 __wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev, 78 struct cfg80211_scan_request *request, struct cfg80211_ssid *this_ssid); 79 static int32 wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev, 80 struct cfg80211_scan_request *request); 81 static int32 wl_cfg80211_set_wiphy_params(struct wiphy *wiphy, uint32 changed); 82 static int32 wl_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev, 83 struct cfg80211_ibss_params *params); 84 static int32 wl_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev); 85 static int32 wl_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev, 86 uint8 *mac, struct station_info *sinfo); 87 static int32 wl_cfg80211_set_power_mgmt(struct wiphy *wiphy, 88 struct net_device *dev, bool enabled, int32 timeout); 89 static int32 wl_cfg80211_set_bitrate_mask(struct wiphy *wiphy, 90 struct net_device *dev, const uint8 *addr, 91 const struct cfg80211_bitrate_mask *mask); 92 static int wl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev, 93 struct cfg80211_connect_params *sme); 94 static int32 wl_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev, 95 uint16 reason_code); 96 static int32 wl_cfg80211_set_tx_power(struct wiphy *wiphy, enum tx_power_setting type, int32 dbm); 97 static int32 wl_cfg80211_get_tx_power(struct wiphy *wiphy, int32 *dbm); 98 static int32 wl_cfg80211_config_default_key(struct wiphy *wiphy, struct net_device *dev, 99 uint8 key_idx); 100 static int32 wl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *dev, 101 uint8 key_idx, const uint8 *mac_addr, struct key_params *params); 102 static int32 wl_cfg80211_del_key(struct wiphy *wiphy, struct net_device *dev, 103 uint8 key_idx, const uint8 *mac_addr); 104 static int32 wl_cfg80211_get_key(struct wiphy *wiphy, struct net_device *dev, 105 uint8 key_idx, const uint8 *mac_addr, void *cookie, 106 void (*callback)(void *cookie, struct key_params *params)); 107 static int32 wl_cfg80211_config_default_mgmt_key(struct wiphy *wiphy, 108 struct net_device *dev, uint8 key_idx); 109 static int32 wl_cfg80211_resume(struct wiphy *wiphy); 110 static int32 wl_cfg80211_suspend(struct wiphy *wiphy); 111 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 33)) || \ 112 defined(CHROMIUMOS_COMPAT_WIRELESS) 113 static int32 wl_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev, 114 struct cfg80211_pmksa *pmksa); 115 static int32 wl_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev, 116 struct cfg80211_pmksa *pmksa); 117 static int32 wl_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev); 118 #endif 119 /* 120 ** event & event Q handlers for cfg80211 interfaces 121 */ 122 static int32 wl_create_event_handler(struct wl_priv *wl); 123 static void wl_destroy_event_handler(struct wl_priv *wl); 124 static int32 wl_event_handler(void *data); 125 static void wl_init_eq(struct wl_priv *wl); 126 static void wl_flush_eq(struct wl_priv *wl); 127 static void wl_lock_eq(struct wl_priv *wl); 128 static void wl_unlock_eq(struct wl_priv *wl); 129 static void wl_init_eq_lock(struct wl_priv *wl); 130 static void wl_init_eloop_handler(struct wl_event_loop *el); 131 static struct wl_event_q *wl_deq_event(struct wl_priv *wl); 132 static int32 wl_enq_event(struct wl_priv *wl, uint32 type, const wl_event_msg_t *msg, void *data); 133 static void wl_put_event(struct wl_event_q *e); 134 static void wl_wakeup_event(struct wl_priv *wl); 135 static int32 wl_notify_connect_status(struct wl_priv *wl, struct net_device *ndev, 136 const wl_event_msg_t *e, void* data); 137 static int32 wl_notify_roaming_status(struct wl_priv *wl, struct net_device *ndev, 138 const wl_event_msg_t *e, void* data); 139 static int32 wl_notify_scan_status(struct wl_priv *wl, struct net_device *ndev, 140 const wl_event_msg_t *e, void* data); 141 static int32 wl_bss_connect_done(struct wl_priv *wl, struct net_device *ndev, 142 const wl_event_msg_t *e, void* data); 143 static int32 wl_bss_roaming_done(struct wl_priv *wl, struct net_device *ndev, 144 const wl_event_msg_t *e, void* data); 145 static int32 wl_notify_mic_status(struct wl_priv *wl, struct net_device *ndev, 146 const wl_event_msg_t *e, void* data); 147 148 /* 149 ** register/deregister sdio function 150 */ 151 static struct sdio_func *wl_sdio_func(void); 152 static void wl_clear_sdio_func(void); 153 154 /* 155 ** ioctl utilites 156 */ 157 static int32 wl_dev_bufvar_get(struct net_device *dev, int8 *name, int8 *buf, int32 buf_len); 158 static __used int32 wl_dev_bufvar_set(struct net_device *dev, int8 *name, int8 *buf, int32 len); 159 static int32 wl_dev_intvar_set(struct net_device *dev, int8 *name, int32 val); 160 static int32 wl_dev_intvar_get(struct net_device *dev, int8 *name, int32 *retval); 161 static int32 wl_dev_ioctl(struct net_device *dev, uint32 cmd, void *arg, uint32 len); 162 163 164 /* 165 ** cfg80211 set_wiphy_params utilities 166 */ 167 static int32 wl_set_frag(struct net_device *dev, uint32 frag_threshold); 168 static int32 wl_set_rts(struct net_device *dev, uint32 frag_threshold); 169 static int32 wl_set_retry(struct net_device *dev, uint32 retry, bool l); 170 171 /* 172 ** wl profile utilities 173 */ 174 static int32 wl_update_prof(struct wl_priv *wl, const wl_event_msg_t *e, void *data, int32 item); 175 static void * wl_read_prof(struct wl_priv *wl, int32 item); 176 static void wl_init_prof(struct wl_profile *prof); 177 178 179 /* 180 ** cfg80211 connect utilites 181 */ 182 static int32 wl_set_wpa_version(struct net_device *dev, struct cfg80211_connect_params *sme); 183 static int32 wl_set_auth_type(struct net_device *dev, struct cfg80211_connect_params *sme); 184 static int32 wl_set_set_cipher(struct net_device *dev, struct cfg80211_connect_params *sme); 185 static int32 wl_set_key_mgmt(struct net_device *dev, struct cfg80211_connect_params *sme); 186 static int32 wl_set_set_sharedkey(struct net_device *dev, struct cfg80211_connect_params *sme); 187 static int32 wl_get_assoc_ies(struct wl_priv *wl); 188 189 190 /* 191 ** information element utilities 192 */ 193 static void wl_rst_ie(struct wl_priv *wl); 194 static int32 wl_add_ie(struct wl_priv *wl, uint8 t, uint8 l, uint8 *v); 195 static int32 wl_mrg_ie(struct wl_priv *wl, uint8 *ie_stream, uint16 ie_size); 196 static int32 wl_cp_ie(struct wl_priv *wl, uint8 *dst, uint16 dst_size); 197 static uint32 wl_get_ielen(struct wl_priv *wl); 198 199 200 static int32 wl_mode_to_nl80211_iftype(int32 mode); 201 202 static struct wireless_dev *wl_alloc_wdev(int32 sizeof_iface, struct device *dev); 203 static void wl_free_wdev(struct wl_priv *wl); 204 205 static int32 wl_inform_bss(struct wl_priv *wl); 206 static int32 wl_inform_single_bss(struct wl_priv *wl, struct wl_bss_info *bi); 207 static int32 wl_update_bss_info(struct wl_priv *wl); 208 209 static int32 wl_add_keyext(struct wiphy *wiphy, struct net_device *dev, 210 uint8 key_idx, const uint8 *mac_addr, struct key_params *params); 211 212 213 /* 214 ** key indianess swap utilities 215 */ 216 static void swap_key_from_BE(struct wl_wsec_key *key); 217 static void swap_key_to_BE(struct wl_wsec_key *key); 218 219 220 /* 221 ** wl_priv memory init/deinit utilities 222 */ 223 static int32 wl_init_priv_mem(struct wl_priv *wl); 224 static void wl_deinit_priv_mem(struct wl_priv *wl); 225 226 static void wl_delay(uint32 ms); 227 228 /* 229 ** store/restore cfg80211 instance data 230 */ 231 static void wl_set_drvdata(struct wl_dev *dev, void *data); 232 static void *wl_get_drvdata(struct wl_dev *dev); 233 234 /* 235 ** ibss mode utilities 236 */ 237 static bool wl_is_ibssmode(struct wl_priv *wl); 238 static bool wl_is_ibssstarter(struct wl_priv *wl); 239 240 /* 241 ** dongle up/down , default configuration utilities 242 */ 243 static bool wl_is_linkdown(struct wl_priv *wl, const wl_event_msg_t *e); 244 static bool wl_is_linkup(struct wl_priv *wl, const wl_event_msg_t *e); 245 static void wl_link_up(struct wl_priv *wl); 246 static void wl_link_down(struct wl_priv *wl); 247 static int32 wl_dongle_mode(struct net_device *ndev, int32 iftype); 248 static int32 __wl_cfg80211_up(struct wl_priv *wl); 249 static int32 __wl_cfg80211_down(struct wl_priv *wl); 250 static int32 wl_dongle_probecap(struct wl_priv *wl); 251 static void wl_init_conf(struct wl_conf *conf); 252 253 /* 254 ** dongle configuration utilities 255 */ 256 #ifndef EMBEDDED_PLATFORM 257 static int32 wl_dongle_mode(struct net_device *ndev, int32 iftype); 258 static int32 wl_dongle_country(struct net_device *ndev, uint8 ccode); 259 static int32 wl_dongle_up(struct net_device *ndev, uint32 up); 260 static int32 wl_dongle_power(struct net_device *ndev, uint32 power_mode); 261 static int32 wl_dongle_glom(struct net_device *ndev, uint32 glom, uint32 dongle_align); 262 static int32 wl_dongle_roam(struct net_device *ndev, uint32 roamvar, uint32 bcn_timeout); 263 static int32 wl_dongle_eventmsg(struct net_device *ndev); 264 static int32 wl_dongle_scantime(struct net_device *ndev, int32 scan_assoc_time, 265 int32 scan_unassoc_time); 266 static int32 wl_dongle_offload(struct net_device *ndev, int32 arpoe, int32 arp_ol); 267 static int32 wl_pattern_atoh(int8 *src, int8 *dst); 268 static int32 wl_dongle_filter(struct net_device *ndev, uint32 filter_mode); 269 static int32 wl_update_wiphybands(struct wl_priv *wl); 270 #endif /* !EMBEDDED_PLATFORM */ 271 static int32 wl_config_dongle(struct wl_priv *wl, bool need_lock); 272 273 /* 274 ** iscan handler 275 */ 276 static void wl_iscan_timer(ulong data); 277 static void wl_term_iscan(struct wl_priv *wl); 278 static int32 wl_init_iscan(struct wl_priv *wl); 279 static int32 wl_iscan_thread(void *data); 280 static int32 wl_dev_iovar_setbuf(struct net_device *dev, int8 *iovar, void *param, 281 int32 paramlen, void *bufptr, int32 buflen); 282 static int32 wl_dev_iovar_getbuf(struct net_device *dev, int8 *iovar, void *param, 283 int32 paramlen, void *bufptr, int32 buflen); 284 static int32 wl_run_iscan(struct wl_iscan_ctrl *iscan, struct wlc_ssid *ssid, uint16 action); 285 static int32 wl_do_iscan(struct wl_priv *wl); 286 static int32 wl_wakeup_iscan(struct wl_iscan_ctrl *iscan); 287 static int32 wl_invoke_iscan(struct wl_priv *wl); 288 static int32 wl_get_iscan_results(struct wl_iscan_ctrl *iscan, uint32 *status, 289 struct wl_scan_results **bss_list); 290 static void wl_notify_iscan_complete(struct wl_iscan_ctrl *iscan, bool aborted); 291 static void wl_init_iscan_eloop(struct wl_iscan_eloop *el); 292 static int32 wl_iscan_done(struct wl_priv *wl); 293 static int32 wl_iscan_pending(struct wl_priv *wl); 294 static int32 wl_iscan_inprogress(struct wl_priv *wl); 295 static int32 wl_iscan_aborted(struct wl_priv *wl); 296 297 /* 298 ** fw/nvram downloading handler 299 */ 300 static void wl_init_fw(struct wl_fw_ctrl *fw); 301 302 /* 303 * find most significant bit set 304 */ 305 static __used uint32 wl_find_msb(uint16 bit16); 306 307 /* 308 * update pmklist to dongle 309 */ 310 static __used int32 wl_update_pmklist(struct net_device *dev, struct wl_pmk_list *pmk_list, 311 int32 err); 312 313 314 #define WL_PRIV_GET() \ 315 ({ \ 316 struct wl_iface *ci; \ 317 if (unlikely(!(wl_cfg80211_dev && (ci = wl_get_drvdata(wl_cfg80211_dev))))) { \ 318 WL_ERR(("wl_cfg80211_dev is unavailable\n")); \ 319 BUG(); \ 320 } \ 321 ci_to_wl(ci); \ 322 }) 323 324 #define CHECK_SYS_UP() \ 325 do { \ 326 struct wl_priv *wl = wiphy_to_wl(wiphy); \ 327 if (unlikely(!test_bit(WL_STATUS_READY, &wl->status))) { \ 328 WL_INFO(("device is not ready : status (%d)\n", (int)wl->status)); \ 329 return -EIO; \ 330 } \ 331 } while (0) 332 333 334 extern int dhd_wait_pend8021x(struct net_device *dev); 335 336 #if (WL_DBG_LEVEL > 0) 337 #define WL_DBG_ESTR_MAX 32 338 static int8 wl_dbg_estr[][WL_DBG_ESTR_MAX] = { 339 "SET_SSID", "JOIN", "START", "AUTH", "AUTH_IND", 340 "DEAUTH", "DEAUTH_IND", "ASSOC", "ASSOC_IND", "REASSOC", 341 "REASSOC_IND", "DISASSOC", "DISASSOC_IND", "QUIET_START", "QUIET_END", 342 "BEACON_RX", "LINK", "MIC_ERROR", "NDIS_LINK", "ROAM", 343 "TXFAIL", "PMKID_CACHE", "RETROGRADE_TSF", "PRUNE", "AUTOAUTH", 344 "EAPOL_MSG", "SCAN_COMPLETE", "ADDTS_IND", "DELTS_IND", "BCNSENT_IND", 345 "BCNRX_MSG", "BCNLOST_MSG", "ROAM_PREP", "PFN_NET_FOUND", "PFN_NET_LOST", 346 "RESET_COMPLETE", "JOIN_START", "ROAM_START", "ASSOC_START", "IBSS_ASSOC", 347 "RADIO", "PSM_WATCHDOG", 348 "PROBREQ_MSG", 349 "SCAN_CONFIRM_IND", "PSK_SUP", "COUNTRY_CODE_CHANGED", "EXCEEDED_MEDIUM_TIME", "ICV_ERROR", 350 "UNICAST_DECODE_ERROR", "MULTICAST_DECODE_ERROR", "TRACE", 351 "IF", 352 "RSSI", "PFN_SCAN_COMPLETE", "ACTION_FRAME", "ACTION_FRAME_COMPLETE", 353 }; 354 #endif /* WL_DBG_LEVEL */ 355 356 #define CHAN2G(_channel, _freq, _flags) { \ 357 .band = IEEE80211_BAND_2GHZ, \ 358 .center_freq = (_freq), \ 359 .hw_value = (_channel), \ 360 .flags = (_flags), \ 361 .max_antenna_gain = 0, \ 362 .max_power = 30, \ 363 } 364 365 #define CHAN5G(_channel, _flags) { \ 366 .band = IEEE80211_BAND_5GHZ, \ 367 .center_freq = 5000 + (5 * (_channel)), \ 368 .hw_value = (_channel), \ 369 .flags = (_flags), \ 370 .max_antenna_gain = 0, \ 371 .max_power = 30, \ 372 } 373 374 #define RATE_TO_BASE100KBPS(rate) (((rate) * 10) / 2) 375 #define RATETAB_ENT(_rateid, _flags) \ 376 { \ 377 .bitrate = RATE_TO_BASE100KBPS(_rateid), \ 378 .hw_value = (_rateid), \ 379 .flags = (_flags), \ 380 } 381 382 static struct ieee80211_rate __wl_rates[] = { 383 RATETAB_ENT(WLC_RATE_1M, 0), 384 RATETAB_ENT(WLC_RATE_2M, IEEE80211_RATE_SHORT_PREAMBLE), 385 RATETAB_ENT(WLC_RATE_5M5, IEEE80211_RATE_SHORT_PREAMBLE), 386 RATETAB_ENT(WLC_RATE_11M, IEEE80211_RATE_SHORT_PREAMBLE), 387 RATETAB_ENT(WLC_RATE_6M, 0), 388 RATETAB_ENT(WLC_RATE_9M, 0), 389 RATETAB_ENT(WLC_RATE_12M, 0), 390 RATETAB_ENT(WLC_RATE_18M, 0), 391 RATETAB_ENT(WLC_RATE_24M, 0), 392 RATETAB_ENT(WLC_RATE_36M, 0), 393 RATETAB_ENT(WLC_RATE_48M, 0), 394 RATETAB_ENT(WLC_RATE_54M, 0), 395 }; 396 397 #define wl_a_rates (__wl_rates + 4) 398 #define wl_a_rates_size 8 399 #define wl_g_rates (__wl_rates + 0) 400 #define wl_g_rates_size 12 401 402 static struct ieee80211_channel __wl_2ghz_channels[] = { 403 CHAN2G(1, 2412, 0), 404 CHAN2G(2, 2417, 0), 405 CHAN2G(3, 2422, 0), 406 CHAN2G(4, 2427, 0), 407 CHAN2G(5, 2432, 0), 408 CHAN2G(6, 2437, 0), 409 CHAN2G(7, 2442, 0), 410 CHAN2G(8, 2447, 0), 411 CHAN2G(9, 2452, 0), 412 CHAN2G(10, 2457, 0), 413 CHAN2G(11, 2462, 0), 414 CHAN2G(12, 2467, 0), 415 CHAN2G(13, 2472, 0), 416 CHAN2G(14, 2484, 0), 417 }; 418 419 static struct ieee80211_channel __wl_5ghz_a_channels[] = { 420 CHAN5G(34, 0), CHAN5G(36, 0), 421 CHAN5G(38, 0), CHAN5G(40, 0), 422 CHAN5G(42, 0), CHAN5G(44, 0), 423 CHAN5G(46, 0), CHAN5G(48, 0), 424 CHAN5G(52, 0), CHAN5G(56, 0), 425 CHAN5G(60, 0), CHAN5G(64, 0), 426 CHAN5G(100, 0), CHAN5G(104, 0), 427 CHAN5G(108, 0), CHAN5G(112, 0), 428 CHAN5G(116, 0), CHAN5G(120, 0), 429 CHAN5G(124, 0), CHAN5G(128, 0), 430 CHAN5G(132, 0), CHAN5G(136, 0), 431 CHAN5G(140, 0), CHAN5G(149, 0), 432 CHAN5G(153, 0), CHAN5G(157, 0), 433 CHAN5G(161, 0), CHAN5G(165, 0), 434 CHAN5G(184, 0), CHAN5G(188, 0), 435 CHAN5G(192, 0), CHAN5G(196, 0), 436 CHAN5G(200, 0), CHAN5G(204, 0), 437 CHAN5G(208, 0), CHAN5G(212, 0), 438 CHAN5G(216, 0), 439 }; 440 441 static struct ieee80211_channel __wl_5ghz_n_channels[] = { 442 CHAN5G(32, 0), CHAN5G(34, 0), 443 CHAN5G(36, 0), CHAN5G(38, 0), 444 CHAN5G(40, 0), CHAN5G(42, 0), 445 CHAN5G(44, 0), CHAN5G(46, 0), 446 CHAN5G(48, 0), CHAN5G(50, 0), 447 CHAN5G(52, 0), CHAN5G(54, 0), 448 CHAN5G(56, 0), CHAN5G(58, 0), 449 CHAN5G(60, 0), CHAN5G(62, 0), 450 CHAN5G(64, 0), CHAN5G(66, 0), 451 CHAN5G(68, 0), CHAN5G(70, 0), 452 CHAN5G(72, 0), CHAN5G(74, 0), 453 CHAN5G(76, 0), CHAN5G(78, 0), 454 CHAN5G(80, 0), CHAN5G(82, 0), 455 CHAN5G(84, 0), CHAN5G(86, 0), 456 CHAN5G(88, 0), CHAN5G(90, 0), 457 CHAN5G(92, 0), CHAN5G(94, 0), 458 CHAN5G(96, 0), CHAN5G(98, 0), 459 CHAN5G(100, 0), CHAN5G(102, 0), 460 CHAN5G(104, 0), CHAN5G(106, 0), 461 CHAN5G(108, 0), CHAN5G(110, 0), 462 CHAN5G(112, 0), CHAN5G(114, 0), 463 CHAN5G(116, 0), CHAN5G(118, 0), 464 CHAN5G(120, 0), CHAN5G(122, 0), 465 CHAN5G(124, 0), CHAN5G(126, 0), 466 CHAN5G(128, 0), CHAN5G(130, 0), 467 CHAN5G(132, 0), CHAN5G(134, 0), 468 CHAN5G(136, 0), CHAN5G(138, 0), 469 CHAN5G(140, 0), CHAN5G(142, 0), 470 CHAN5G(144, 0), CHAN5G(145, 0), 471 CHAN5G(146, 0), CHAN5G(147, 0), 472 CHAN5G(148, 0), CHAN5G(149, 0), 473 CHAN5G(150, 0), CHAN5G(151, 0), 474 CHAN5G(152, 0), CHAN5G(153, 0), 475 CHAN5G(154, 0), CHAN5G(155, 0), 476 CHAN5G(156, 0), CHAN5G(157, 0), 477 CHAN5G(158, 0), CHAN5G(159, 0), 478 CHAN5G(160, 0), CHAN5G(161, 0), 479 CHAN5G(162, 0), CHAN5G(163, 0), 480 CHAN5G(164, 0), CHAN5G(165, 0), 481 CHAN5G(166, 0), CHAN5G(168, 0), 482 CHAN5G(170, 0), CHAN5G(172, 0), 483 CHAN5G(174, 0), CHAN5G(176, 0), 484 CHAN5G(178, 0), CHAN5G(180, 0), 485 CHAN5G(182, 0), CHAN5G(184, 0), 486 CHAN5G(186, 0), CHAN5G(188, 0), 487 CHAN5G(190, 0), CHAN5G(192, 0), 488 CHAN5G(194, 0), CHAN5G(196, 0), 489 CHAN5G(198, 0), CHAN5G(200, 0), 490 CHAN5G(202, 0), CHAN5G(204, 0), 491 CHAN5G(206, 0), CHAN5G(208, 0), 492 CHAN5G(210, 0), CHAN5G(212, 0), 493 CHAN5G(214, 0), CHAN5G(216, 0), 494 CHAN5G(218, 0), CHAN5G(220, 0), 495 CHAN5G(222, 0), CHAN5G(224, 0), 496 CHAN5G(226, 0), CHAN5G(228, 0), 497 }; 498 499 static struct ieee80211_supported_band __wl_band_2ghz = { 500 .band = IEEE80211_BAND_2GHZ, 501 .channels = __wl_2ghz_channels, 502 .n_channels = ARRAY_SIZE(__wl_2ghz_channels), 503 .bitrates = wl_g_rates, 504 .n_bitrates = wl_g_rates_size, 505 }; 506 507 static struct ieee80211_supported_band __wl_band_5ghz_a = { 508 .band = IEEE80211_BAND_5GHZ, 509 .channels = __wl_5ghz_a_channels, 510 .n_channels = ARRAY_SIZE(__wl_5ghz_a_channels), 511 .bitrates = wl_a_rates, 512 .n_bitrates = wl_a_rates_size, 513 }; 514 515 static struct ieee80211_supported_band __wl_band_5ghz_n = { 516 .band = IEEE80211_BAND_5GHZ, 517 .channels = __wl_5ghz_n_channels, 518 .n_channels = ARRAY_SIZE(__wl_5ghz_n_channels), 519 .bitrates = wl_a_rates, 520 .n_bitrates = wl_a_rates_size, 521 }; 522 523 static const uint32 __wl_cipher_suites[] = { 524 WLAN_CIPHER_SUITE_WEP40, 525 WLAN_CIPHER_SUITE_WEP104, 526 WLAN_CIPHER_SUITE_TKIP, 527 WLAN_CIPHER_SUITE_CCMP, 528 WLAN_CIPHER_SUITE_AES_CMAC, 529 }; 530 531 static void 532 swap_key_from_BE(struct wl_wsec_key *key) 533 { 534 key->index = htod32(key->index); 535 key->len = htod32(key->len); 536 key->algo = htod32(key->algo); 537 key->flags = htod32(key->flags); 538 key->rxiv.hi = htod32(key->rxiv.hi); 539 key->rxiv.lo = htod16(key->rxiv.lo); 540 key->iv_initialized = htod32(key->iv_initialized); 541 } 542 543 static void 544 swap_key_to_BE(struct wl_wsec_key *key) 545 { 546 key->index = dtoh32(key->index); 547 key->len = dtoh32(key->len); 548 key->algo = dtoh32(key->algo); 549 key->flags = dtoh32(key->flags); 550 key->rxiv.hi = dtoh32(key->rxiv.hi); 551 key->rxiv.lo = dtoh16(key->rxiv.lo); 552 key->iv_initialized = dtoh32(key->iv_initialized); 553 } 554 555 static int32 556 wl_dev_ioctl(struct net_device *dev, uint32 cmd, void *arg, uint32 len) 557 { 558 struct ifreq ifr; 559 struct wl_ioctl ioc; 560 mm_segment_t fs; 561 int32 err = 0; 562 563 #ifdef WL_CFG80211_BACKTRACE 564 WL_DBG(("In : cmd (%d)\n", cmd)); 565 #endif 566 memset(&ioc, 0, sizeof(ioc)); 567 ioc.cmd = cmd; 568 ioc.buf = arg; 569 ioc.len = len; 570 strcpy(ifr.ifr_name, dev->name); 571 ifr.ifr_data = (caddr_t) &ioc; 572 573 574 fs = get_fs(); 575 set_fs(get_ds()); 576 err = dev->netdev_ops->ndo_do_ioctl(dev, &ifr, SIOCDEVPRIVATE); 577 set_fs(fs); 578 #ifdef WL_CFG80211_BACKTRACE 579 WL_DBG(("Out\n")); 580 #endif 581 582 return err; 583 } 584 585 static int32 586 wl_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev, 587 enum nl80211_iftype type, uint32 *flags, struct vif_params *params) 588 { 589 struct wl_priv *wl = wiphy_to_wl(wiphy); 590 struct wireless_dev *wdev; 591 int32 infra = 0; 592 int32 ap = 0; 593 int32 err = 0; 594 595 #ifdef WL_CFG80211_BACKTRACE 596 WL_DBG(("In\n")); 597 #endif 598 CHECK_SYS_UP(); 599 switch (type) { 600 case NL80211_IFTYPE_MONITOR: 601 case NL80211_IFTYPE_WDS: 602 WL_ERR(("type (%d) : currently we do not support this type\n", type)); 603 return -EOPNOTSUPP; 604 case NL80211_IFTYPE_ADHOC: 605 wl->conf->mode = WL_MODE_IBSS; 606 break; 607 case NL80211_IFTYPE_STATION: 608 wl->conf->mode = WL_MODE_BSS; 609 infra = 1; 610 break; 611 default: 612 return -EINVAL; 613 } 614 infra = htod32(infra); 615 ap = htod32(ap); 616 wdev = ndev->ieee80211_ptr; 617 wdev->iftype = type; 618 WL_DBG(("%s : ap (%d), infra (%d)\n", ndev->name, ap, infra)); 619 if (unlikely((err = wl_dev_ioctl(ndev, WLC_SET_INFRA, &infra, sizeof(infra)))) || 620 unlikely((err = wl_dev_ioctl(ndev, WLC_SET_AP, &ap, sizeof(ap))))) { 621 WL_ERR(("Error (%d)\n", err)); 622 return err; 623 } 624 #ifdef WL_CFG80211_BACKTRACE 625 WL_DBG(("Out\n")); 626 #endif 627 /* -EINPROGRESS: Call commit handler */ 628 return -EINPROGRESS; 629 } 630 631 static void 632 wl_iscan_prep(struct wl_scan_params *params, struct wlc_ssid *ssid) 633 { 634 memcpy(¶ms->bssid, ðer_bcast, ETHER_ADDR_LEN); 635 params->bss_type = DOT11_BSSTYPE_ANY; 636 params->scan_type = 0; 637 params->nprobes = -1; 638 params->active_time = -1; 639 params->passive_time = -1; 640 params->home_time = -1; 641 params->channel_num = 0; 642 643 params->nprobes = htod32(params->nprobes); 644 params->active_time = htod32(params->active_time); 645 params->passive_time = htod32(params->passive_time); 646 params->home_time = htod32(params->home_time); 647 if (ssid && ssid->SSID_len) 648 memcpy(¶ms->ssid, ssid, sizeof(wlc_ssid_t)); 649 650 } 651 652 static int32 653 wl_dev_iovar_setbuf(struct net_device *dev, int8 *iovar, void *param, 654 int32 paramlen, void *bufptr, int32 buflen) 655 { 656 int32 iolen; 657 658 iolen = bcm_mkiovar(iovar, param, paramlen, bufptr, buflen); 659 BUG_ON(unlikely(!iolen)); 660 661 return wl_dev_ioctl(dev, WLC_SET_VAR, bufptr, iolen); 662 } 663 664 static int32 665 wl_dev_iovar_getbuf(struct net_device *dev, int8 *iovar, void *param, 666 int32 paramlen, void *bufptr, int32 buflen) 667 { 668 int32 iolen; 669 670 iolen = bcm_mkiovar(iovar, param, paramlen, bufptr, buflen); 671 BUG_ON(unlikely(!iolen)); 672 673 return wl_dev_ioctl(dev, WLC_GET_VAR, bufptr, buflen); 674 } 675 676 static int32 677 wl_run_iscan(struct wl_iscan_ctrl *iscan, struct wlc_ssid *ssid, uint16 action) 678 { 679 int32 params_size = (WL_SCAN_PARAMS_FIXED_SIZE + OFFSETOF(wl_iscan_params_t, params)); 680 struct wl_iscan_params *params; 681 int32 err = 0; 682 683 #ifdef WL_CFG80211_BACKTRACE 684 WL_DBG(("In\n")); 685 #endif 686 if (ssid && ssid->SSID_len) 687 params_size += sizeof(struct wlc_ssid); 688 params = (struct wl_iscan_params *)kzalloc(params_size, GFP_KERNEL); 689 if (unlikely(!params)) 690 return -ENOMEM; 691 memset(params, 0, params_size); 692 BUG_ON(unlikely(params_size >= WLC_IOCTL_SMLEN)); 693 694 wl_iscan_prep(¶ms->params, ssid); 695 696 params->version = htod32(ISCAN_REQ_VERSION); 697 params->action = htod16(action); 698 params->scan_duration = htod16(0); 699 700 /* params_size += OFFSETOF(wl_iscan_params_t, params); */ 701 if (unlikely((err = wl_dev_iovar_setbuf(iscan->dev, "iscan", params, params_size, 702 iscan->ioctl_buf, WLC_IOCTL_SMLEN)))) { 703 if (err == -EBUSY) { 704 WL_INFO(("system busy : iscan canceled\n")); 705 } else { 706 WL_ERR(("error (%d)\n", err)); 707 } 708 } 709 kfree(params); 710 #ifdef WL_CFG80211_BACKTRACE 711 WL_DBG(("Out\n")); 712 #endif 713 return err; 714 } 715 716 717 static int32 718 wl_do_iscan(struct wl_priv *wl) 719 { 720 struct wl_iscan_ctrl *iscan = wl_to_iscan(wl); 721 struct wlc_ssid ssid; 722 int32 err = 0; 723 724 #ifdef WL_CFG80211_BACKTRACE 725 WL_DBG(("In\n")); 726 #endif 727 /* Broadcast scan by default */ 728 memset(&ssid, 0, sizeof(ssid)); 729 730 iscan->state = WL_ISCAN_STATE_SCANING; 731 732 if (wl->active_scan) { 733 int32 passive_scan = 0; 734 /* make it active scan */ 735 if (unlikely((err = wl_dev_ioctl(wl_to_ndev(wl), WLC_SET_PASSIVE_SCAN, 736 &passive_scan, sizeof(passive_scan))))) { 737 WL_DBG(("error (%d)\n", err)); 738 return err; 739 } 740 } 741 wl->iscan_kickstart = TRUE; 742 wl_run_iscan(iscan, &ssid, WL_SCAN_ACTION_START); 743 mod_timer(&iscan->timer, jiffies + iscan->timer_ms*HZ/1000); 744 iscan->timer_on = 1; 745 746 #ifdef WL_CFG80211_BACKTRACE 747 WL_DBG(("Out\n")); 748 #endif 749 750 return err; 751 } 752 753 754 static int32 755 __wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev, 756 struct cfg80211_scan_request *request, struct cfg80211_ssid *this_ssid) 757 { 758 struct wl_priv *wl = ndev_to_wl(ndev); 759 struct cfg80211_ssid *ssids; 760 struct wl_scan_req *sr = wl_to_sr(wl); 761 uint32 n_ssids; 762 bool iscan_req; 763 bool spec_scan; 764 int32 err = 0; 765 766 #ifdef WL_CFG80211_BACKTRACE 767 WL_DBG(("In\n")); 768 #endif 769 if (unlikely(test_bit(WL_STATUS_SCANNING, &wl->status))) { 770 WL_ERR(("Scanning already : status (%d)\n", (int)wl->status)); 771 return -EAGAIN; 772 } 773 if (unlikely(test_bit(WL_STATUS_SCAN_ABORTING, &wl->status))) { 774 WL_ERR(("Scanning being aborted : status (%d)\n", (int)wl->status)); 775 return -EAGAIN; 776 } 777 778 iscan_req = FALSE; 779 spec_scan = FALSE; 780 if (request) { /* scan bss */ 781 ssids = request->ssids; 782 n_ssids = min(request->n_ssids, WL_NUM_SCAN_MAX); 783 if (wl->iscan_on && n_ssids && !ssids->ssid_len) { /* for specific scan, 784 * ssids->ssid_len has 785 * non-zero(ssid string) length. 786 * Otherwise this is 0. 787 * we do not iscan for 788 * specific scan request 789 */ 790 iscan_req = TRUE; 791 } 792 } else { /* scan in ibss */ 793 /* we don't do iscan in ibss */ 794 ssids = this_ssid; 795 n_ssids = 1; 796 } 797 wl->scan_request = request; 798 set_bit(WL_STATUS_SCANNING, &wl->status); 799 if (iscan_req) { 800 if (likely(!(err = wl_do_iscan(wl)))) 801 return err; 802 else 803 goto scan_out; 804 } else { 805 WL_DBG(("n_ssid (%d), ssid \"%s\", ssid_len (%d)\n", 806 n_ssids, ssids->ssid, ssids->ssid_len)); 807 memset(&sr->ssid, 0, sizeof(sr->ssid)); 808 if (n_ssids) { 809 sr->ssid.SSID_len = MIN(sizeof(sr->ssid.SSID), ssids->ssid_len); 810 if (sr->ssid.SSID_len) { 811 memcpy(sr->ssid.SSID, ssids->ssid, sr->ssid.SSID_len); 812 sr->ssid.SSID_len = htod32(sr->ssid.SSID_len); 813 WL_DBG(("Specific scan ssid=\"%s\" len=%d\n", sr->ssid.SSID, 814 sr->ssid.SSID_len)); 815 spec_scan = TRUE; 816 } else { 817 WL_DBG(("Broadcast scan\n")); 818 } 819 } else { 820 /* broadcast scan */ 821 WL_DBG(("Broadcast scan\n")); 822 } 823 WL_DBG(("sr->ssid.SSID_len (%d)\n", sr->ssid.SSID_len)); 824 if (wl->active_scan) { 825 int32 pssive_scan = 0; 826 /* make it active scan */ 827 if (unlikely((err = wl_dev_ioctl(ndev, WLC_SET_PASSIVE_SCAN, 828 &pssive_scan, sizeof(pssive_scan))))) { 829 WL_ERR(("WLC_SET_PASSIVE_SCAN error (%d)\n", err)); 830 goto scan_out; 831 } 832 } 833 if ((err = wl_dev_ioctl(ndev, WLC_SCAN, &sr->ssid, sizeof(sr->ssid)))) { 834 if (err == -EBUSY) { 835 WL_INFO(("system busy : scan for \"%s\" canceled\n", 836 sr->ssid.SSID)); 837 } else { 838 WL_ERR(("WLC_SCAN error (%d)\n", err)); 839 } 840 goto scan_out; 841 } 842 } 843 #ifdef WL_CFG80211_BACKTRACE 844 WL_DBG(("Out\n")); 845 #endif 846 847 return 0; 848 849 scan_out: 850 clear_bit(WL_STATUS_SCANNING, &wl->status); 851 wl->scan_request = NULL; 852 return err; 853 } 854 855 856 static int32 857 wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev, 858 struct cfg80211_scan_request *request) 859 { 860 int32 err = 0; 861 862 #ifdef WL_CFG80211_BACKTRACE 863 WL_DBG(("In\n")); 864 #endif 865 CHECK_SYS_UP(); 866 if (unlikely((err = __wl_cfg80211_scan(wiphy, ndev, request, NULL)))) { 867 WL_DBG(("scan error (%d)\n", err)); 868 return err; 869 } 870 #ifdef WL_CFG80211_BACKTRACE 871 WL_DBG(("Out\n")); 872 #endif 873 874 return err; 875 } 876 877 static int32 878 wl_dev_intvar_set(struct net_device *dev, int8 *name, int32 val) 879 { 880 int8 buf[WLC_IOCTL_SMLEN]; 881 uint32 len; 882 int32 err = 0; 883 884 val = htod32(val); 885 len = bcm_mkiovar(name, (char *)(&val), sizeof(val), buf, sizeof(buf)); 886 BUG_ON(unlikely(!len)); 887 888 if (unlikely((err = wl_dev_ioctl(dev, WLC_SET_VAR, buf, len)))) { 889 WL_ERR(("error (%d)\n", err)); 890 } 891 892 return err; 893 } 894 895 static int32 896 wl_dev_intvar_get(struct net_device *dev, int8 *name, int32 *retval) 897 { 898 union { 899 int8 buf[WLC_IOCTL_SMLEN]; 900 int32 val; 901 } var; 902 uint32 len; 903 uint32 data_null; 904 int32 err = 0; 905 906 len = bcm_mkiovar(name, (char *)(&data_null), 0, (char *)(&var), sizeof(var.buf)); 907 BUG_ON(unlikely(!len)); 908 if (unlikely((err = wl_dev_ioctl(dev, WLC_GET_VAR, &var, len)))) { 909 WL_ERR(("error (%d)\n", err)); 910 } 911 *retval = dtoh32(var.val); 912 913 return err; 914 } 915 916 static int32 917 wl_set_rts(struct net_device *dev, uint32 rts_threshold) 918 { 919 int32 err = 0; 920 921 #ifdef WL_CFG80211_BACKTRACE 922 WL_DBG(("In\n")); 923 #endif 924 if (unlikely((err = wl_dev_intvar_set(dev, "rtsthresh", rts_threshold)))) { 925 WL_ERR(("Error (%d)\n", err)); 926 return err; 927 } 928 #ifdef WL_CFG80211_BACKTRACE 929 WL_DBG(("Out\n")); 930 #endif 931 return err; 932 } 933 934 static int32 935 wl_set_frag(struct net_device *dev, uint32 frag_threshold) 936 { 937 int32 err = 0; 938 939 #ifdef WL_CFG80211_BACKTRACE 940 WL_DBG(("In\n")); 941 #endif 942 if (unlikely((err = wl_dev_intvar_set(dev, "fragthresh", frag_threshold)))) { 943 WL_ERR(("Error (%d)\n", err)); 944 return err; 945 } 946 #ifdef WL_CFG80211_BACKTRACE 947 WL_DBG(("Out\n")); 948 #endif 949 return err; 950 } 951 952 static int32 953 wl_set_retry(struct net_device *dev, uint32 retry, bool l) 954 { 955 int32 err = 0; 956 uint32 cmd = (l ? WLC_SET_LRL : WLC_SET_SRL); 957 958 #ifdef WL_CFG80211_BACKTRACE 959 WL_DBG(("In\n")); 960 #endif 961 retry = htod32(retry); 962 if (unlikely((err = wl_dev_ioctl(dev, cmd, &retry, sizeof(retry))))) { 963 WL_ERR(("cmd (%d) , error (%d)\n", cmd, err)); 964 return err; 965 } 966 #ifdef WL_CFG80211_BACKTRACE 967 WL_DBG(("Out\n")); 968 #endif 969 return err; 970 } 971 972 static int32 973 wl_cfg80211_set_wiphy_params(struct wiphy *wiphy, uint32 changed) 974 { 975 struct wl_priv *wl = wiphy_to_wl(wiphy); 976 struct net_device *ndev = wl_to_ndev(wl); 977 int32 err = 0; 978 979 #ifdef WL_CFG80211_BACKTRACE 980 WL_DBG(("In\n")); 981 #endif 982 CHECK_SYS_UP(); 983 if (changed & WIPHY_PARAM_RTS_THRESHOLD && 984 (wl->conf->rts_threshold != wiphy->rts_threshold)) { 985 wl->conf->rts_threshold = wiphy->rts_threshold; 986 if (!(err = wl_set_rts(ndev, wl->conf->rts_threshold))) { 987 return err; 988 } 989 } 990 if (changed & WIPHY_PARAM_FRAG_THRESHOLD && 991 (wl->conf->frag_threshold != wiphy->frag_threshold)) { 992 wl->conf->frag_threshold = wiphy->frag_threshold; 993 if (!(err = wl_set_frag(ndev, wl->conf->frag_threshold))) { 994 return err; 995 } 996 } 997 if (changed & WIPHY_PARAM_RETRY_LONG && (wl->conf->retry_long != wiphy->retry_long)) { 998 wl->conf->retry_long = wiphy->retry_long; 999 if (!(err = wl_set_retry(ndev, wl->conf->retry_long, TRUE))) { 1000 return err; 1001 } 1002 } 1003 if (changed & WIPHY_PARAM_RETRY_SHORT && (wl->conf->retry_short != wiphy->retry_short)) { 1004 wl->conf->retry_short = wiphy->retry_short; 1005 if (!(err = wl_set_retry(ndev, wl->conf->retry_short, FALSE))) { 1006 return err; 1007 } 1008 } 1009 #ifdef WL_CFG80211_BACKTRACE 1010 WL_DBG(("Out\n")); 1011 #endif 1012 1013 return err; 1014 } 1015 1016 static int32 1017 wl_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev, 1018 struct cfg80211_ibss_params *params) 1019 { 1020 struct wl_priv *wl = wiphy_to_wl(wiphy); 1021 struct cfg80211_bss *bss; 1022 struct ieee80211_channel *chan; 1023 struct wl_join_params join_params; 1024 struct cfg80211_ssid ssid; 1025 int32 scan_retry = 0; 1026 int32 err = 0; 1027 1028 #ifdef WL_CFG80211_BACKTRACE 1029 WL_DBG(("In \n")); 1030 #endif 1031 CHECK_SYS_UP(); 1032 if (params->bssid) { 1033 WL_ERR(("Invalid bssid\n")); 1034 return -EOPNOTSUPP; 1035 } 1036 bss = cfg80211_get_ibss(wiphy, NULL, params->ssid, params->ssid_len); 1037 if (!bss) { 1038 memcpy(ssid.ssid, params->ssid, params->ssid_len); 1039 ssid.ssid_len = params->ssid_len; 1040 do { 1041 if (unlikely(__wl_cfg80211_scan(wiphy, dev, NULL, &ssid) == -EBUSY)) { 1042 wl_delay(150); 1043 } else { 1044 break; 1045 } 1046 } while (++scan_retry < WL_SCAN_RETRY_MAX); 1047 rtnl_unlock(); /* to allow scan_inform to paropagate to cfg80211 plane */ 1048 schedule_timeout_interruptible(4 * HZ); /* wait 4 secons till scan done.... */ 1049 rtnl_lock(); 1050 bss = cfg80211_get_ibss(wiphy, NULL, 1051 params->ssid, params->ssid_len); 1052 } 1053 if (bss) { 1054 wl->ibss_starter = FALSE; 1055 WL_DBG(("Found IBSS\n")); 1056 } else { 1057 wl->ibss_starter = TRUE; 1058 } 1059 if ((chan = params->channel)) { 1060 wl->channel = ieee80211_frequency_to_channel(chan->center_freq); 1061 } 1062 /* 1063 ** Join with specific BSSID and cached SSID 1064 ** If SSID is zero join based on BSSID only 1065 */ 1066 memset(&join_params, 0, sizeof(join_params)); 1067 memcpy((void *)join_params.ssid.SSID, (void *)params->ssid, params->ssid_len); 1068 join_params.ssid.SSID_len = htod32(params->ssid_len); 1069 if (params->bssid) 1070 memcpy(&join_params.params.bssid, params->bssid, ETHER_ADDR_LEN); 1071 else 1072 memset(&join_params.params.bssid, 0, ETHER_ADDR_LEN); 1073 1074 if (unlikely((err = wl_dev_ioctl(dev, WLC_SET_SSID, &join_params, sizeof(join_params))))) { 1075 WL_ERR(("Error (%d)\n", err)); 1076 return err; 1077 } 1078 #ifdef WL_CFG80211_BACKTRACE 1079 WL_DBG(("Out\n")); 1080 #endif 1081 return err; 1082 } 1083 1084 static int32 1085 wl_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev) 1086 { 1087 struct wl_priv *wl = wiphy_to_wl(wiphy); 1088 int32 err = 0; 1089 1090 #ifdef WL_CFG80211_BACKTRACE 1091 WL_DBG(("In\n")); 1092 #endif 1093 CHECK_SYS_UP(); 1094 wl_link_down(wl); 1095 #ifdef WL_CFG80211_BACKTRACE 1096 WL_DBG(("Out\n")); 1097 #endif 1098 1099 return err; 1100 } 1101 1102 static int32 1103 wl_set_wpa_version(struct net_device *dev, struct cfg80211_connect_params *sme) 1104 { 1105 struct wl_priv *wl = ndev_to_wl(dev); 1106 struct wl_security *sec; 1107 int32 val = 0; 1108 int32 err = 0; 1109 1110 #ifdef WL_CFG80211_BACKTRACE 1111 WL_DBG(("In\n")); 1112 #endif 1113 if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_1) 1114 val = WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED; 1115 else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2) 1116 val = WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED; 1117 else 1118 val = WPA_AUTH_DISABLED; 1119 WL_DBG(("setting wpa_auth to 0x%0x\n", val)); 1120 if (unlikely((err = wl_dev_intvar_set(dev, "wpa_auth", val)))) { 1121 WL_ERR(("set wpa_auth failed (%d)\n", err)); 1122 return err; 1123 } 1124 sec = wl_read_prof(wl, WL_PROF_SEC); 1125 sec->wpa_versions = sme->crypto.wpa_versions; 1126 #ifdef WL_CFG80211_BACKTRACE 1127 WL_DBG(("Out\n")); 1128 #endif 1129 return err; 1130 } 1131 1132 static int32 1133 wl_set_auth_type(struct net_device *dev, struct cfg80211_connect_params *sme) 1134 { 1135 struct wl_priv *wl = ndev_to_wl(dev); 1136 struct wl_security *sec; 1137 int32 val = 0; 1138 int32 err = 0; 1139 1140 #ifdef WL_CFG80211_BACKTRACE 1141 WL_DBG(("In\n")); 1142 #endif 1143 switch (sme->auth_type) { 1144 case NL80211_AUTHTYPE_OPEN_SYSTEM: 1145 val = 0; 1146 WL_DBG(("open system\n")); 1147 break; 1148 case NL80211_AUTHTYPE_SHARED_KEY: 1149 val = 1; 1150 WL_DBG(("shared key\n")); 1151 break; 1152 case NL80211_AUTHTYPE_AUTOMATIC: 1153 val = 2; 1154 WL_DBG(("automatic\n")); 1155 break; 1156 case NL80211_AUTHTYPE_NETWORK_EAP: 1157 WL_DBG(("network eap\n")); 1158 default : 1159 val = 2; 1160 WL_ERR(("invalid auth type (%d)\n", sme->auth_type)); 1161 break; 1162 } 1163 1164 if (unlikely((err = wl_dev_intvar_set(dev, "auth", val)))) { 1165 WL_ERR(("set auth failed (%d)\n", err)); 1166 return err; 1167 } 1168 sec = wl_read_prof(wl, WL_PROF_SEC); 1169 sec->auth_type = sme->auth_type; 1170 #ifdef WL_CFG80211_BACKTRACE 1171 WL_DBG(("Out\n")); 1172 #endif 1173 return err; 1174 } 1175 1176 1177 static int32 1178 wl_set_set_cipher(struct net_device *dev, struct cfg80211_connect_params *sme) 1179 { 1180 struct wl_priv *wl = ndev_to_wl(dev); 1181 struct wl_security *sec; 1182 int32 pval = 0; 1183 int32 gval = 0; 1184 int32 err = 0; 1185 1186 #ifdef WL_CFG80211_BACKTRACE 1187 WL_DBG(("In\n")); 1188 #endif 1189 if (sme->crypto.n_ciphers_pairwise) { 1190 switch (sme->crypto.ciphers_pairwise[0]) { 1191 case WLAN_CIPHER_SUITE_WEP40: 1192 case WLAN_CIPHER_SUITE_WEP104: 1193 pval = WEP_ENABLED; 1194 break; 1195 case WLAN_CIPHER_SUITE_TKIP: 1196 pval = TKIP_ENABLED; 1197 break; 1198 case WLAN_CIPHER_SUITE_CCMP: 1199 pval = AES_ENABLED; 1200 break; 1201 case WLAN_CIPHER_SUITE_AES_CMAC: 1202 pval = AES_ENABLED; 1203 break; 1204 default: 1205 WL_ERR(("invalid cipher pairwise (%d)\n", 1206 sme->crypto.ciphers_pairwise[0])); 1207 return -EINVAL; 1208 } 1209 } 1210 if (sme->crypto.cipher_group) { 1211 switch (sme->crypto.cipher_group) { 1212 case WLAN_CIPHER_SUITE_WEP40: 1213 case WLAN_CIPHER_SUITE_WEP104: 1214 gval = WEP_ENABLED; 1215 break; 1216 case WLAN_CIPHER_SUITE_TKIP: 1217 gval = TKIP_ENABLED; 1218 break; 1219 case WLAN_CIPHER_SUITE_CCMP: 1220 gval = AES_ENABLED; 1221 break; 1222 case WLAN_CIPHER_SUITE_AES_CMAC: 1223 gval = AES_ENABLED; 1224 break; 1225 default: 1226 WL_ERR(("invalid cipher group (%d)\n", sme->crypto.cipher_group)); 1227 return -EINVAL; 1228 } 1229 } 1230 1231 WL_DBG(("pval (%d) gval (%d)\n", pval, gval)); 1232 if (unlikely((err = wl_dev_intvar_set(dev, "wsec", pval|gval)))) { 1233 WL_ERR(("error (%d)\n", err)); 1234 return err; 1235 } 1236 1237 sec = wl_read_prof(wl, WL_PROF_SEC); 1238 sec->cipher_pairwise = sme->crypto.ciphers_pairwise[0]; 1239 sec->cipher_group = sme->crypto.cipher_group; 1240 #ifdef WL_CFG80211_BACKTRACE 1241 WL_DBG(("Out\n")); 1242 #endif 1243 1244 return err; 1245 } 1246 1247 static int32 1248 wl_set_key_mgmt(struct net_device *dev, struct cfg80211_connect_params *sme) 1249 { 1250 struct wl_priv *wl = ndev_to_wl(dev); 1251 struct wl_security *sec; 1252 int32 val = 0; 1253 int32 err = 0; 1254 1255 #ifdef WL_CFG80211_BACKTRACE 1256 WL_DBG(("In\n")); 1257 #endif 1258 1259 if (sme->crypto.n_akm_suites) { 1260 if (unlikely((err = wl_dev_intvar_get(dev, "wpa_auth", &val)))) { 1261 WL_ERR(("could not get wpa_auth (%d)\n", err)); 1262 return err; 1263 } 1264 if (val & (WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED)) { 1265 switch (sme->crypto.akm_suites[0]) { 1266 case WLAN_AKM_SUITE_8021X: 1267 val = WPA_AUTH_UNSPECIFIED; 1268 break; 1269 case WLAN_AKM_SUITE_PSK: 1270 val = WPA_AUTH_PSK; 1271 break; 1272 default : 1273 WL_ERR(("invalid cipher group (%d)\n", 1274 sme->crypto.cipher_group)); 1275 return -EINVAL; 1276 } 1277 } else if (val & (WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED)) { 1278 switch (sme->crypto.akm_suites[0]) { 1279 case WLAN_AKM_SUITE_8021X: 1280 val = WPA2_AUTH_UNSPECIFIED; 1281 break; 1282 case WLAN_AKM_SUITE_PSK: 1283 val = WPA2_AUTH_PSK; 1284 break; 1285 default : 1286 WL_ERR(("invalid cipher group (%d)\n", 1287 sme->crypto.cipher_group)); 1288 return -EINVAL; 1289 } 1290 } 1291 1292 WL_DBG(("setting wpa_auth to %d\n", val)); 1293 if (unlikely((err = wl_dev_intvar_set(dev, "wpa_auth", val)))) { 1294 WL_ERR(("could not set wpa_auth (%d)\n", err)); 1295 return err; 1296 } 1297 } 1298 sec = wl_read_prof(wl, WL_PROF_SEC); 1299 sec->wpa_auth = sme->crypto.akm_suites[0]; 1300 #ifdef WL_CFG80211_BACKTRACE 1301 WL_DBG(("Out\n")); 1302 #endif 1303 1304 return err; 1305 } 1306 1307 static int32 1308 wl_set_set_sharedkey(struct net_device *dev, struct cfg80211_connect_params *sme) 1309 { 1310 struct wl_priv *wl = ndev_to_wl(dev); 1311 struct wl_security *sec; 1312 struct wl_wsec_key key; 1313 int32 val; 1314 int32 err = 0; 1315 1316 #ifdef WL_CFG80211_BACKTRACE 1317 WL_DBG(("In\n")); 1318 #endif 1319 WL_DBG(("key len (%d)\n", sme->key_len)); 1320 if (sme->key_len) { 1321 sec = wl_read_prof(wl, WL_PROF_SEC); 1322 WL_DBG(("wpa_versions 0x%x cipher_pairwise 0x%x\n", sec->wpa_versions, 1323 sec->cipher_pairwise)); 1324 if (!(sec->wpa_versions & (NL80211_WPA_VERSION_1 | NL80211_WPA_VERSION_2)) && 1325 (sec->cipher_pairwise & (WLAN_CIPHER_SUITE_WEP40 | 1326 WLAN_CIPHER_SUITE_WEP104))) { 1327 memset(&key, 0, sizeof(key)); 1328 key.len = (uint32)sme->key_len; 1329 key.index = (uint32)sme->key_idx; 1330 if (unlikely(key.len > sizeof(key.data))) { 1331 WL_ERR(("Too long key length (%u)\n", key.len)); 1332 return -EINVAL; 1333 } 1334 memcpy(key.data, sme->key, key.len); 1335 key.flags = WL_PRIMARY_KEY; 1336 switch (sec->cipher_pairwise) { 1337 case WLAN_CIPHER_SUITE_WEP40: 1338 key.algo = CRYPTO_ALGO_WEP1; 1339 break; 1340 case WLAN_CIPHER_SUITE_WEP104: 1341 key.algo = CRYPTO_ALGO_WEP128; 1342 break; 1343 default : 1344 WL_ERR(("Invalid algorithm (%d)\n", 1345 sme->crypto.ciphers_pairwise[0])); 1346 return -EINVAL; 1347 } 1348 /* Set the new key/index */ 1349 WL_DBG(("key length (%d) key index (%d) algo (%d)\n", key.len, 1350 key.index, key.algo)); 1351 WL_DBG(("key \"%s\"\n", key.data)); 1352 swap_key_from_BE(&key); 1353 if (unlikely((err = wl_dev_ioctl(dev, WLC_SET_KEY, &key, sizeof(key))))) { 1354 WL_ERR(("WLC_SET_KEY error (%d)\n", err)); 1355 return err; 1356 } 1357 if (sec->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM) { 1358 WL_DBG(("set auth_type to shared key\n")); 1359 val = 1; /* shared key */ 1360 if (unlikely((err = wl_dev_intvar_set(dev, "auth", val)))) { 1361 WL_ERR(("set auth failed (%d)\n", err)); 1362 return err; 1363 } 1364 } 1365 } 1366 } 1367 #ifdef WL_CFG80211_BACKTRACE 1368 WL_DBG(("Out\n")); 1369 #endif 1370 return err; 1371 } 1372 1373 static int32 1374 wl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev, 1375 struct cfg80211_connect_params *sme) 1376 { 1377 struct wl_priv *wl = wiphy_to_wl(wiphy); 1378 struct ieee80211_channel *chan = sme->channel; 1379 struct wlc_ssid ssid; 1380 int32 err = 0; 1381 1382 #ifdef WL_CFG80211_BACKTRACE 1383 WL_DBG(("In \n")); 1384 #endif 1385 CHECK_SYS_UP(); 1386 if (unlikely(!sme->ssid)) { 1387 WL_ERR(("Invalid ssid\n")); 1388 return -EOPNOTSUPP; 1389 } 1390 if (chan) { 1391 wl->channel = ieee80211_frequency_to_channel(chan->center_freq); 1392 WL_DBG(("channel (%d), center_req (%d) \n", wl->channel, chan->center_freq)); 1393 } 1394 WL_DBG(("ie (%p), ie_len (%d)\n", sme->ie, sme->ie_len)); 1395 if (unlikely((err = wl_set_wpa_version(dev, sme)))) { 1396 return err; 1397 } 1398 if (unlikely((err = wl_set_auth_type(dev, sme)))) { 1399 return err; 1400 } 1401 if (unlikely((err = wl_set_set_cipher(dev, sme)))) { 1402 return err; 1403 } 1404 if (unlikely((err = wl_set_key_mgmt(dev, sme)))) { 1405 return err; 1406 } 1407 if (unlikely((err = wl_set_set_sharedkey(dev, sme)))) { 1408 return err; 1409 } 1410 wl_update_prof(wl, NULL, sme->bssid, WL_PROF_BSSID); 1411 /* 1412 ** Join with specific BSSID and cached SSID 1413 ** If SSID is zero join based on BSSID only 1414 */ 1415 memset(&ssid, 0, sizeof(ssid)); 1416 ssid.SSID_len = MIN(sizeof(ssid.SSID), sme->ssid_len); 1417 memcpy(ssid.SSID, sme->ssid, ssid.SSID_len); 1418 ssid.SSID_len = htod32(ssid.SSID_len); 1419 wl_update_prof(wl, NULL, &ssid, WL_PROF_SSID); 1420 if (ssid.SSID_len < IEEE80211_MAX_SSID_LEN) { 1421 WL_DBG(("ssid \"%s\", len (%d)\n", ssid.SSID, ssid.SSID_len)); 1422 } 1423 if (unlikely((err = wl_dev_ioctl(dev, WLC_SET_SSID, &ssid, sizeof(ssid))))) { 1424 WL_ERR(("error (%d)\n", err)); 1425 return err; 1426 } 1427 set_bit(WL_STATUS_CONNECTING, &wl->status); 1428 #ifdef WL_CFG80211_BACKTRACE 1429 WL_DBG(("Out\n")); 1430 #endif 1431 1432 return err; 1433 } 1434 1435 static int32 1436 wl_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev, 1437 uint16 reason_code) 1438 { 1439 struct wl_priv *wl = wiphy_to_wl(wiphy); 1440 scb_val_t scbval; 1441 bool act = FALSE; 1442 int32 err = 0; 1443 1444 #ifdef WL_CFG80211_BACKTRACE 1445 WL_DBG(("In\n")); 1446 #endif 1447 WL_DBG(("Reason %d\n", reason_code)); 1448 CHECK_SYS_UP(); 1449 if (likely((act = *(bool *)wl_read_prof(wl, WL_PROF_ACT)))) { 1450 scbval.val = reason_code; 1451 memcpy(&scbval.ea, &wl->bssid, ETHER_ADDR_LEN); 1452 scbval.val = htod32(scbval.val); 1453 if (unlikely((err = wl_dev_ioctl(dev, WLC_DISASSOC, &scbval, 1454 sizeof(scb_val_t))))) { 1455 WL_ERR(("error (%d)\n", err)); 1456 return err; 1457 } 1458 } 1459 #ifdef WL_CFG80211_BACKTRACE 1460 WL_DBG(("Out\n")); 1461 #endif 1462 1463 return err; 1464 } 1465 1466 static int32 1467 wl_cfg80211_set_tx_power(struct wiphy *wiphy, enum tx_power_setting type, int32 dbm) 1468 { 1469 1470 struct wl_priv *wl = wiphy_to_wl(wiphy); 1471 struct net_device *ndev = wl_to_ndev(wl); 1472 uint16 txpwrmw; 1473 int32 err = 0; 1474 int32 disable = 0; 1475 1476 #ifdef WL_CFG80211_BACKTRACE 1477 WL_DBG(("In\n")); 1478 #endif 1479 CHECK_SYS_UP(); 1480 switch (type) { 1481 case TX_POWER_AUTOMATIC: 1482 break; 1483 case TX_POWER_LIMITED: 1484 if (dbm < 0) { 1485 WL_ERR(("TX_POWER_LIMITTED - dbm is negative\n")); 1486 return -EINVAL; 1487 } 1488 break; 1489 case TX_POWER_FIXED: 1490 if (dbm < 0) { 1491 WL_ERR(("TX_POWER_FIXED - dbm is negative..\n")); 1492 return -EINVAL; 1493 } 1494 break; 1495 } 1496 /* Make sure radio is off or on as far as software is concerned */ 1497 disable = WL_RADIO_SW_DISABLE << 16; 1498 disable = htod32(disable); 1499 if (unlikely((err = wl_dev_ioctl(ndev, WLC_SET_RADIO, &disable, sizeof(disable))))) { 1500 WL_ERR(("WLC_SET_RADIO error (%d)\n", err)); 1501 return err; 1502 } 1503 1504 if (dbm > 0xffff) 1505 txpwrmw = 0xffff; 1506 else 1507 txpwrmw = (uint16)dbm; 1508 if (unlikely((err = wl_dev_intvar_set(ndev, "qtxpower", 1509 (int32)(bcm_mw_to_qdbm(txpwrmw)))))) { 1510 WL_ERR(("qtxpower error (%d)\n", err)); 1511 return err; 1512 } 1513 wl->conf->tx_power = dbm; 1514 #ifdef WL_CFG80211_BACKTRACE 1515 WL_DBG(("Out\n")); 1516 #endif 1517 1518 return err; 1519 } 1520 1521 static int32 1522 wl_cfg80211_get_tx_power(struct wiphy *wiphy, int32 *dbm) 1523 { 1524 struct wl_priv *wl = wiphy_to_wl(wiphy); 1525 struct net_device *ndev = wl_to_ndev(wl); 1526 int32 txpwrdbm; 1527 uint8 result; 1528 int32 err = 0; 1529 1530 #ifdef WL_CFG80211_BACKTRACE 1531 WL_DBG(("In\n")); 1532 #endif 1533 CHECK_SYS_UP(); 1534 if (unlikely((err = wl_dev_intvar_get(ndev, "qtxpower", &txpwrdbm)))) { 1535 WL_ERR(("error (%d)\n", err)); 1536 return err; 1537 } 1538 result = (uint8)(txpwrdbm & ~WL_TXPWR_OVERRIDE); 1539 *dbm = (int32)bcm_qdbm_to_mw(result); 1540 #ifdef WL_CFG80211_BACKTRACE 1541 WL_DBG(("Out\n")); 1542 #endif 1543 1544 return err; 1545 } 1546 1547 static int32 1548 wl_cfg80211_config_default_key(struct wiphy *wiphy, struct net_device *dev, uint8 key_idx) 1549 { 1550 uint32 index; 1551 int32 wsec; 1552 int32 err = 0; 1553 1554 #ifdef WL_CFG80211_BACKTRACE 1555 WL_DBG(("In\n")); 1556 #endif 1557 WL_DBG(("key index (%d)\n", key_idx)); 1558 CHECK_SYS_UP(); 1559 1560 if (unlikely(err = wl_dev_ioctl(dev, WLC_GET_WSEC, &wsec, sizeof(wsec)))) { 1561 WL_ERR(("WLC_GET_WSEC error (%d)\n", err)); 1562 return err; 1563 } 1564 wsec = dtoh32(wsec); 1565 if (wsec & WEP_ENABLED) { 1566 /* Just select a new current key */ 1567 index = (uint32)key_idx; 1568 index = htod32(index); 1569 if (unlikely((err = wl_dev_ioctl(dev, WLC_SET_KEY_PRIMARY, 1570 &index, sizeof(index))))) { 1571 WL_ERR(("error (%d)\n", err)); 1572 } 1573 } 1574 #ifdef WL_CFG80211_BACKTRACE 1575 WL_DBG(("Out\n")); 1576 #endif 1577 return err; 1578 } 1579 1580 static int32 1581 wl_add_keyext(struct wiphy *wiphy, struct net_device *dev, 1582 uint8 key_idx, const uint8 *mac_addr, struct key_params *params) 1583 { 1584 struct wl_wsec_key key; 1585 int32 err = 0; 1586 1587 #ifdef WL_CFG80211_BACKTRACE 1588 WL_DBG(("In\n")); 1589 #endif 1590 memset(&key, 0, sizeof(key)); 1591 key.index = (uint32)key_idx; 1592 /* Instead of bcast for ea address for default wep keys, driver needs it to be Null */ 1593 if (!ETHER_ISMULTI(mac_addr)) 1594 memcpy((char *)&key.ea, (void *)mac_addr, ETHER_ADDR_LEN); 1595 key.len = (uint32)params->key_len; 1596 /* check for key index change */ 1597 if (key.len == 0) { 1598 /* key delete */ 1599 swap_key_from_BE(&key); 1600 if (unlikely((err = wl_dev_ioctl(dev, WLC_SET_KEY, &key, sizeof(key))))) { 1601 WL_ERR(("key delete error (%d)\n", err)); 1602 return err; 1603 } 1604 } else { 1605 if (key.len > sizeof(key.data)) { 1606 WL_ERR(("Invalid key length (%d)\n", key.len)); 1607 return -EINVAL; 1608 } 1609 1610 WL_DBG(("Setting the key index %d\n", key.index)); 1611 memcpy(key.data, params->key, key.len); 1612 1613 if (params->cipher == WLAN_CIPHER_SUITE_TKIP) { 1614 uint8 keybuf[8]; 1615 memcpy(keybuf, &key.data[24], sizeof(keybuf)); 1616 memcpy(&key.data[24], &key.data[16], sizeof(keybuf)); 1617 memcpy(&key.data[16], keybuf, sizeof(keybuf)); 1618 } 1619 1620 /* if IW_ENCODE_EXT_RX_SEQ_VALID set */ 1621 if (params->seq && params->seq_len == 6) { 1622 /* rx iv */ 1623 uint8 *ivptr; 1624 ivptr = (uint8 *)params->seq; 1625 key.rxiv.hi = (ivptr[5] << 24) | (ivptr[4] << 16) | 1626 (ivptr[3] << 8) | ivptr[2]; 1627 key.rxiv.lo = (ivptr[1] << 8) | ivptr[0]; 1628 key.iv_initialized = TRUE; 1629 } 1630 1631 switch (params->cipher) { 1632 case WLAN_CIPHER_SUITE_WEP40: 1633 key.algo = CRYPTO_ALGO_WEP1; 1634 WL_DBG(("WLAN_CIPHER_SUITE_WEP40\n")); 1635 break; 1636 case WLAN_CIPHER_SUITE_WEP104: 1637 key.algo = CRYPTO_ALGO_WEP128; 1638 WL_DBG(("WLAN_CIPHER_SUITE_WEP104\n")); 1639 break; 1640 case WLAN_CIPHER_SUITE_TKIP: 1641 key.algo = CRYPTO_ALGO_TKIP; 1642 WL_DBG(("WLAN_CIPHER_SUITE_TKIP\n")); 1643 break; 1644 case WLAN_CIPHER_SUITE_AES_CMAC: 1645 key.algo = CRYPTO_ALGO_AES_CCM; 1646 WL_DBG(("WLAN_CIPHER_SUITE_AES_CMAC\n")); 1647 break; 1648 case WLAN_CIPHER_SUITE_CCMP: 1649 key.algo = CRYPTO_ALGO_AES_CCM; 1650 WL_DBG(("WLAN_CIPHER_SUITE_CCMP\n")); 1651 break; 1652 default: 1653 WL_ERR(("Invalid cipher (0x%x)\n", params->cipher)); 1654 return -EINVAL; 1655 } 1656 swap_key_from_BE(&key); 1657 1658 dhd_wait_pend8021x(dev); 1659 if (unlikely((err = wl_dev_ioctl(dev, WLC_SET_KEY, &key, sizeof(key))))) { 1660 WL_ERR(("WLC_SET_KEY error (%d)\n", err)); 1661 return err; 1662 } 1663 } 1664 #ifdef WL_CFG80211_BACKTRACE 1665 WL_DBG(("Out\n")); 1666 #endif 1667 return err; 1668 } 1669 1670 static int32 1671 wl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *dev, 1672 uint8 key_idx, const uint8 *mac_addr, struct key_params *params) 1673 { 1674 struct wl_wsec_key key; 1675 int32 val; 1676 int32 wsec; 1677 int32 err = 0; 1678 1679 #ifdef WL_CFG80211_BACKTRACE 1680 WL_DBG(("In\n")); 1681 #endif 1682 WL_DBG(("key index (%d)\n", key_idx)); 1683 CHECK_SYS_UP(); 1684 1685 if (mac_addr) 1686 return wl_add_keyext(wiphy, dev, key_idx, mac_addr, params); 1687 memset(&key, 0, sizeof(key)); 1688 1689 key.len = (uint32)params->key_len; 1690 key.index = (uint32)key_idx; 1691 1692 if (unlikely(key.len > sizeof(key.data))) { 1693 WL_ERR(("Too long key length (%u)\n", key.len)); 1694 return -EINVAL; 1695 } 1696 memcpy(key.data, params->key, key.len); 1697 1698 key.flags = WL_PRIMARY_KEY; 1699 switch (params->cipher) { 1700 case WLAN_CIPHER_SUITE_WEP40: 1701 key.algo = CRYPTO_ALGO_WEP1; 1702 WL_DBG(("WLAN_CIPHER_SUITE_WEP40\n")); 1703 break; 1704 case WLAN_CIPHER_SUITE_WEP104: 1705 key.algo = CRYPTO_ALGO_WEP128; 1706 WL_DBG(("WLAN_CIPHER_SUITE_WEP104\n")); 1707 break; 1708 case WLAN_CIPHER_SUITE_TKIP: 1709 key.algo = CRYPTO_ALGO_TKIP; 1710 WL_DBG(("WLAN_CIPHER_SUITE_TKIP\n")); 1711 break; 1712 case WLAN_CIPHER_SUITE_AES_CMAC: 1713 key.algo = CRYPTO_ALGO_AES_CCM; 1714 WL_DBG(("WLAN_CIPHER_SUITE_AES_CMAC\n")); 1715 break; 1716 case WLAN_CIPHER_SUITE_CCMP: 1717 key.algo = CRYPTO_ALGO_AES_CCM; 1718 WL_DBG(("WLAN_CIPHER_SUITE_CCMP\n")); 1719 break; 1720 default: 1721 WL_ERR(("Invalid cipher (0x%x)\n", params->cipher)); 1722 return -EINVAL; 1723 } 1724 1725 /* Set the new key/index */ 1726 swap_key_from_BE(&key); 1727 if (unlikely((err = wl_dev_ioctl(dev, WLC_SET_KEY, &key, sizeof(key))))) { 1728 WL_ERR(("WLC_SET_KEY error (%d)\n", err)); 1729 return err; 1730 } 1731 1732 val = WEP_ENABLED; 1733 if (unlikely((err = wl_dev_intvar_get(dev, "wsec", &wsec)))) { 1734 WL_ERR(("get wsec error (%d)\n", err)); 1735 return err; 1736 } 1737 wsec &= ~(WEP_ENABLED); 1738 wsec |= val; 1739 if (unlikely((err = wl_dev_intvar_set(dev, "wsec", wsec)))) { 1740 WL_ERR(("set wsec error (%d)\n", err)); 1741 return err; 1742 } 1743 1744 val = 1; /* assume shared key. otherwise 0 */ 1745 val = htod32(val); 1746 if (unlikely((err = wl_dev_ioctl(dev, WLC_SET_AUTH, &val, sizeof(val))))) { 1747 WL_ERR(("WLC_SET_AUTH error (%d)\n", err)); 1748 return err; 1749 } 1750 #ifdef WL_CFG80211_BACKTRACE 1751 WL_DBG(("Out\n")); 1752 #endif 1753 return err; 1754 } 1755 1756 static int32 1757 wl_cfg80211_del_key(struct wiphy *wiphy, struct net_device *dev, 1758 uint8 key_idx, const uint8 *mac_addr) 1759 { 1760 struct wl_wsec_key key; 1761 int32 err = 0; 1762 int32 val; 1763 int32 wsec; 1764 1765 #ifdef WL_CFG80211_BACKTRACE 1766 WL_DBG(("In\n")); 1767 #endif 1768 CHECK_SYS_UP(); 1769 memset(&key, 0, sizeof(key)); 1770 1771 key.index = (uint32)key_idx; 1772 key.flags = WL_PRIMARY_KEY; 1773 key.algo = CRYPTO_ALGO_OFF; 1774 1775 WL_DBG(("key index (%d)\n", key_idx)); 1776 /* Set the new key/index */ 1777 swap_key_from_BE(&key); 1778 if (unlikely((err = wl_dev_ioctl(dev, WLC_SET_KEY, &key, sizeof(key))))) { 1779 if (err == -EINVAL) { 1780 if (key.index >= DOT11_MAX_DEFAULT_KEYS) { 1781 /* we ignore this key index in this case */ 1782 WL_DBG(("invalid key index (%d)\n", key_idx)); 1783 } 1784 } else { 1785 WL_ERR(("WLC_SET_KEY error (%d)\n", err)); 1786 } 1787 return err; 1788 } 1789 1790 val = 0; 1791 if (unlikely((err = wl_dev_intvar_get(dev, "wsec", &wsec)))) { 1792 WL_ERR(("get wsec error (%d)\n", err)); 1793 return err; 1794 } 1795 wsec &= ~(WEP_ENABLED); 1796 wsec |= val; 1797 if (unlikely((err = wl_dev_intvar_set(dev, "wsec", wsec)))) { 1798 WL_ERR(("set wsec error (%d)\n", err)); 1799 return err; 1800 } 1801 1802 val = 0; /* assume open key. otherwise 1 */ 1803 val = htod32(val); 1804 if (unlikely((err = wl_dev_ioctl(dev, WLC_SET_AUTH, &val, sizeof(val))))) { 1805 WL_ERR(("WLC_SET_AUTH error (%d)\n", err)); 1806 return err; 1807 } 1808 #ifdef WL_CFG80211_BACKTRACE 1809 WL_DBG(("Out\n")); 1810 #endif 1811 return err; 1812 } 1813 1814 static int32 1815 wl_cfg80211_get_key(struct wiphy *wiphy, struct net_device *dev, 1816 uint8 key_idx, const uint8 *mac_addr, void *cookie, 1817 void (*callback)(void *cookie, struct key_params *params)) 1818 { 1819 struct key_params params; 1820 struct wl_wsec_key key; 1821 struct wl_priv *wl = wiphy_to_wl(wiphy); 1822 struct wl_security *sec; 1823 int32 wsec; 1824 int32 err = 0; 1825 1826 #ifdef WL_CFG80211_BACKTRACE 1827 WL_DBG(("In\n")); 1828 #endif 1829 WL_DBG(("key index (%d)\n", key_idx)); 1830 CHECK_SYS_UP(); 1831 1832 memset(&key, 0, sizeof(key)); 1833 key.index = key_idx; 1834 swap_key_to_BE(&key); 1835 memset(¶ms, 0, sizeof(params)); 1836 params.key_len = (uint8)MIN(DOT11_MAX_KEY_SIZE, key.len); 1837 memcpy(params.key, key.data, params.key_len); 1838 1839 if (unlikely(err = wl_dev_ioctl(dev, WLC_GET_WSEC, &wsec, sizeof(wsec)))) { 1840 WL_ERR(("WLC_GET_WSEC error (%d)\n", err)); 1841 return err; 1842 } 1843 wsec = dtoh32(wsec); 1844 switch (wsec) { 1845 case WEP_ENABLED: 1846 sec = wl_read_prof(wl, WL_PROF_SEC); 1847 if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP40) { 1848 params.cipher = WLAN_CIPHER_SUITE_WEP40; 1849 WL_DBG(("WLAN_CIPHER_SUITE_WEP40\n")); 1850 } else if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP104) { 1851 params.cipher = WLAN_CIPHER_SUITE_WEP104; 1852 WL_DBG(("WLAN_CIPHER_SUITE_WEP104\n")); 1853 } 1854 break; 1855 case TKIP_ENABLED: 1856 params.cipher = WLAN_CIPHER_SUITE_TKIP; 1857 WL_DBG(("WLAN_CIPHER_SUITE_TKIP\n")); 1858 break; 1859 case AES_ENABLED: 1860 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC; 1861 WL_DBG(("WLAN_CIPHER_SUITE_AES_CMAC\n")); 1862 break; 1863 default: 1864 WL_ERR(("Invalid algo (0x%x)\n", wsec)); 1865 return -EINVAL; 1866 } 1867 1868 callback(cookie, ¶ms); 1869 #ifdef WL_CFG80211_BACKTRACE 1870 WL_DBG(("Out\n")); 1871 #endif 1872 return err; 1873 } 1874 1875 static int32 1876 wl_cfg80211_config_default_mgmt_key(struct wiphy *wiphy, 1877 struct net_device *dev, uint8 key_idx) 1878 { 1879 WL_INFO(("Not supported\n")); 1880 CHECK_SYS_UP(); 1881 return -EOPNOTSUPP; 1882 } 1883 1884 static int32 1885 wl_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev, 1886 uint8 *mac, struct station_info *sinfo) 1887 1888 { 1889 struct wl_priv *wl = wiphy_to_wl(wiphy); 1890 scb_val_t scb_val; 1891 int rssi; 1892 int32 rate; 1893 int32 err = 0; 1894 1895 #ifdef WL_CFG80211_BACKTRACE 1896 WL_DBG(("In\n")); 1897 #endif 1898 CHECK_SYS_UP(); 1899 if (unlikely(memcmp(mac, wl_read_prof(wl, WL_PROF_BSSID), ETHER_ADDR_LEN))) { 1900 WL_ERR(("Wrong Mac address\n")); 1901 return -ENOENT; 1902 } 1903 1904 /* Report the current tx rate */ 1905 if ((err = wl_dev_ioctl(dev, WLC_GET_RATE, &rate, sizeof(rate)))) { 1906 WL_ERR(("Could not get rate (%d)\n", err)); 1907 } else { 1908 rate = dtoh32(rate); 1909 sinfo->filled |= STATION_INFO_TX_BITRATE; 1910 sinfo->txrate.legacy = rate * 5; 1911 WL_DBG(("Rate %d Mbps\n", (rate/2))); 1912 } 1913 1914 if (test_bit(WL_STATUS_CONNECTED, &wl->status)) { 1915 scb_val.val = 0; 1916 if (unlikely(err = wl_dev_ioctl(dev, WLC_GET_RSSI, &scb_val, sizeof(scb_val_t)))) { 1917 WL_ERR(("Could not get rssi (%d)\n", err)); 1918 return err; 1919 } 1920 rssi = dtoh32(scb_val.val); 1921 sinfo->filled |= STATION_INFO_SIGNAL; 1922 sinfo->signal = rssi; 1923 WL_DBG(("RSSI %d dBm\n", rssi)); 1924 } 1925 #ifdef WL_CFG80211_BACKTRACE 1926 WL_DBG(("Out\n")); 1927 #endif 1928 1929 return err; 1930 } 1931 1932 static int32 1933 wl_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev, 1934 bool enabled, int32 timeout) 1935 { 1936 int32 pm; 1937 int32 err = 0; 1938 1939 #ifdef WL_CFG80211_BACKTRACE 1940 WL_DBG(("In\n")); 1941 #endif 1942 CHECK_SYS_UP(); 1943 pm = enabled ? PM_FAST : PM_OFF; 1944 pm = htod32(pm); 1945 WL_DBG(("power save %s\n", (pm ? "enabled" : "disabled"))); 1946 if (unlikely((err = wl_dev_ioctl(dev, WLC_SET_PM, &pm, sizeof(pm))))) { 1947 if (err == -ENODEV) { 1948 WL_DBG(("net_device is not ready yet\n")); 1949 } else { 1950 WL_ERR(("error (%d)\n", err)); 1951 } 1952 return err; 1953 } 1954 #ifdef WL_CFG80211_BACKTRACE 1955 WL_DBG(("Out\n")); 1956 #endif 1957 return err; 1958 } 1959 1960 static __used uint32 1961 wl_find_msb(uint16 bit16) 1962 { 1963 uint32 ret = 0; 1964 1965 if (bit16 & 0xff00) { 1966 ret += 8; 1967 bit16 >>= 8; 1968 } 1969 1970 if (bit16 & 0xf0) { 1971 ret += 4; 1972 bit16 >>= 4; 1973 } 1974 1975 if (bit16 & 0xc) { 1976 ret += 2; 1977 bit16 >>= 2; 1978 } 1979 1980 if (bit16 & 2) 1981 ret += bit16 & 2; 1982 else if (bit16) 1983 ret += bit16; 1984 1985 return ret; 1986 } 1987 1988 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 33)) || \ 1989 defined(CHROMIUMOS_COMPAT_WIRELESS) 1990 static int32 1991 wl_cfg80211_set_bitrate_mask(struct wiphy *wiphy, struct net_device *dev, 1992 const uint8 *addr, const struct cfg80211_bitrate_mask *mask) 1993 { 1994 struct wl_rateset rateset; 1995 int32 rate; 1996 int32 val; 1997 int32 err_bg; 1998 int32 err_a; 1999 uint32 legacy; 2000 int32 err = 0; 2001 2002 #ifdef WL_CFG80211_BACKTRACE 2003 WL_DBG(("In\n")); 2004 #endif 2005 CHECK_SYS_UP(); 2006 /* addr param is always NULL. ignore it */ 2007 /* Get current rateset */ 2008 if (unlikely((err = wl_dev_ioctl(dev, WLC_GET_CURR_RATESET, &rateset, 2009 sizeof(rateset))))) { 2010 WL_ERR(("could not get current rateset (%d)\n", err)); 2011 return err; 2012 } 2013 2014 rateset.count = dtoh32(rateset.count); 2015 2016 if (!(legacy = wl_find_msb(mask->control[IEEE80211_BAND_2GHZ].legacy))) 2017 legacy = wl_find_msb(mask->control[IEEE80211_BAND_5GHZ].legacy); 2018 2019 val = wl_g_rates[legacy-1].bitrate * 100000; 2020 2021 if (val < rateset.count) { 2022 /* Select rate by rateset index */ 2023 rate = rateset.rates[val] & 0x7f; 2024 } else { 2025 /* Specified rate in bps */ 2026 rate = val / 500000; 2027 } 2028 2029 WL_DBG(("rate %d mbps\n", (rate/2))); 2030 2031 /* 2032 * 2033 * Set rate override, 2034 * Since the is a/b/g-blind, both a/bg_rate are enforced. 2035 */ 2036 err_bg = wl_dev_intvar_set(dev, "bg_rate", rate); 2037 err_a = wl_dev_intvar_set(dev, "a_rate", rate); 2038 if (unlikely(err_bg && err_a)) { 2039 WL_ERR(("could not set fixed rate (%d) (%d)\n", err_bg, err_a)); 2040 return (err_bg | err_a); 2041 } 2042 2043 #ifdef WL_CFG80211_BACKTRACE 2044 WL_DBG(("Out\n")); 2045 #endif 2046 2047 return err; 2048 } 2049 #else 2050 static int32 2051 wl_cfg80211_set_bitrate_mask(struct wiphy *wiphy, struct net_device *dev, 2052 const uint8 *addr, const struct cfg80211_bitrate_mask *mask) 2053 { 2054 struct wl_rateset rateset; 2055 int32 rate; 2056 int32 val; 2057 int32 err_bg; 2058 int32 err_a; 2059 int32 err = 0; 2060 int i; 2061 2062 #ifdef WL_CFG80211_BACKTRACE 2063 WL_DBG(("In\n")); 2064 #endif 2065 CHECK_SYS_UP(); 2066 /* addr param is always NULL. ignore it */ 2067 /* Get current rateset */ 2068 if (unlikely((err = wl_dev_ioctl(dev, WLC_GET_CURR_RATESET, &rateset, 2069 sizeof(rateset))))) { 2070 WL_ERR(("could not get current rateset (%d)\n", err)); 2071 return err; 2072 } 2073 2074 rateset.count = dtoh32(rateset.count); 2075 2076 if (mask->fixed || mask->maxrate) { 2077 val = mask->fixed ? (mask->fixed * 1000) : (mask->maxrate * 1000); 2078 if (val < rateset.count) { 2079 /* Select rate by rateset index */ 2080 rate = rateset.rates[val] & 0x7f; 2081 } else { 2082 /* Specified rate in bps */ 2083 rate = val / 500000; 2084 } 2085 } else { 2086 /* Select maximum rate */ 2087 rate = rateset.rates[rateset.count - 1] & 0x7f; 2088 } 2089 2090 if (mask->fixed) { 2091 /* 2092 Set rate override, 2093 Since the is a/b/g-blind, both a/bg_rate are enforced. 2094 */ 2095 err_bg = wl_dev_intvar_set(dev, "bg_rate", rate); 2096 err_a = wl_dev_intvar_set(dev, "a_rate", rate); 2097 if (unlikely(err_bg && err_a)) { 2098 WL_ERR(("could not set fixed rate (%d) (%d)\n", err_bg, err_a)); 2099 return (err_bg | err_a); 2100 } 2101 } else { 2102 /* 2103 clear rate override 2104 Since the is a/b/g-blind, both a/bg_rate are enforced. 2105 */ 2106 /* 0 is for clearing rate override */ 2107 err_bg = wl_dev_intvar_set(dev, "bg_rate", 0); 2108 /* 0 is for clearing rate override */ 2109 err_a = wl_dev_intvar_set(dev, "a_rate", 0); 2110 2111 if (unlikely(err_bg && err_a)) { 2112 WL_ERR(("could not set max rate (%d) (%d)\n", err_bg, err_a)); 2113 return (err_bg | err_a); 2114 } 2115 2116 /* Remove rates above selected rate */ 2117 for (i = 0; i < rateset.count; i++) 2118 if ((rateset.rates[i] & 0x7f) > rate) 2119 break; 2120 rateset.count = htod32(i); 2121 2122 /* Set current rateset */ 2123 if (unlikely((err = wl_dev_ioctl(dev, WLC_SET_RATESET, &rateset, 2124 sizeof(rateset))))) { 2125 WL_ERR(("error (%d)\n", err)); 2126 return err; 2127 } 2128 } 2129 #ifdef WL_CFG80211_BACKTRACE 2130 WL_DBG(("Out\n")); 2131 #endif 2132 2133 return err; 2134 } 2135 #endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 33)) */ 2136 2137 static int32 2138 wl_cfg80211_resume(struct wiphy *wiphy) 2139 { 2140 int32 err = 0; 2141 2142 #ifdef WL_CFG80211_BACKTRACE 2143 WL_DBG(("In\n")); 2144 #endif 2145 CHECK_SYS_UP(); 2146 wl_invoke_iscan(wiphy_to_wl(wiphy)); 2147 #ifdef WL_CFG80211_BACKTRACE 2148 WL_DBG(("Out\n")); 2149 #endif 2150 2151 return err; 2152 } 2153 2154 static int32 2155 wl_cfg80211_suspend(struct wiphy *wiphy) 2156 { 2157 struct wl_priv *wl = wiphy_to_wl(wiphy); 2158 int32 err = 0; 2159 2160 #ifdef WL_CFG80211_BACKTRACE 2161 WL_DBG(("In\n")); 2162 #endif 2163 CHECK_SYS_UP(); 2164 2165 set_bit(WL_STATUS_SCAN_ABORTING, &wl->status); 2166 wl_term_iscan(wl); 2167 if (wl->scan_request) { 2168 cfg80211_scan_done(wl->scan_request, TRUE); /* TRUE means abort */ 2169 wl->scan_request = NULL; 2170 } 2171 clear_bit(WL_STATUS_SCANNING, &wl->status); 2172 clear_bit(WL_STATUS_SCAN_ABORTING, &wl->status); 2173 2174 #ifdef WL_CFG80211_BACKTRACE 2175 WL_DBG(("Out\n")); 2176 #endif 2177 2178 return err; 2179 } 2180 2181 static __used int32 2182 wl_update_pmklist(struct net_device *dev, struct wl_pmk_list *pmk_list, int32 err) 2183 { 2184 int8 eabuf[ETHER_ADDR_STR_LEN]; 2185 int i, j; 2186 2187 memset(eabuf, 0, ETHER_ADDR_STR_LEN); 2188 2189 WL_DBG(("No of elements %d\n", pmk_list->pmkids.npmkid)); 2190 for (i = 0; i < pmk_list->pmkids.npmkid; i++) { 2191 WL_DBG(("PMKID[%d]: %s =\n", i, 2192 bcm_ether_ntoa(&pmk_list->pmkids.pmkid[i].BSSID, 2193 eabuf))); 2194 for (j = 0; j < WPA2_PMKID_LEN; j++) { 2195 WL_DBG(("%02x\n", pmk_list->pmkids.pmkid[i].PMKID[j])); 2196 } 2197 } 2198 if (likely(!err)) { 2199 err = wl_dev_bufvar_set(dev, "pmkid_info", (char *)pmk_list, 2200 sizeof(*pmk_list)); 2201 } 2202 2203 return err; 2204 } 2205 2206 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 33)) || \ 2207 defined(CHROMIUMOS_COMPAT_WIRELESS) 2208 static int32 2209 wl_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev, 2210 struct cfg80211_pmksa *pmksa) 2211 { 2212 struct wl_priv *wl = wiphy_to_wl(wiphy); 2213 int8 eabuf[ETHER_ADDR_STR_LEN]; 2214 int32 err = 0; 2215 int i; 2216 #ifdef WL_CFG80211_BACKTRACE 2217 WL_DBG(("In\n")); 2218 #endif 2219 2220 CHECK_SYS_UP(); 2221 memset(eabuf, 0, ETHER_ADDR_STR_LEN); 2222 for (i = 0; i < wl->pmk_list->pmkids.npmkid; i++) 2223 if (!memcmp(pmksa->bssid, &wl->pmk_list->pmkids.pmkid[i].BSSID, 2224 ETHER_ADDR_LEN)) 2225 break; 2226 if (i < WL_NUM_PMKIDS_MAX) { 2227 memcpy(&wl->pmk_list->pmkids.pmkid[i].BSSID, pmksa->bssid, ETHER_ADDR_LEN); 2228 memcpy(&wl->pmk_list->pmkids.pmkid[i].PMKID, pmksa->pmkid, WPA2_PMKID_LEN); 2229 if (i == wl->pmk_list->pmkids.npmkid) 2230 wl->pmk_list->pmkids.npmkid++; 2231 } else { 2232 err = -EINVAL; 2233 } 2234 WL_DBG(("set_pmksa,IW_PMKSA_ADD - PMKID: %s =\n", 2235 bcm_ether_ntoa(&wl->pmk_list->pmkids.pmkid[wl->pmk_list->pmkids.npmkid].BSSID, 2236 eabuf))); 2237 for (i = 0; i < WPA2_PMKID_LEN; i++) { 2238 WL_DBG(("%02x\n", 2239 wl->pmk_list->pmkids.pmkid[wl->pmk_list->pmkids.npmkid].PMKID[i])); 2240 } 2241 2242 err = wl_update_pmklist(dev, wl->pmk_list, err); 2243 2244 #ifdef WL_CFG80211_BACKTRACE 2245 WL_DBG(("Out\n")); 2246 #endif 2247 2248 return err; 2249 } 2250 2251 static int32 2252 wl_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev, 2253 struct cfg80211_pmksa *pmksa) 2254 { 2255 struct wl_priv *wl = wiphy_to_wl(wiphy); 2256 int8 eabuf[ETHER_ADDR_STR_LEN]; 2257 struct _pmkid_list pmkid; 2258 int32 err = 0; 2259 int i; 2260 2261 #ifdef WL_CFG80211_BACKTRACE 2262 WL_DBG(("In\n")); 2263 #endif 2264 2265 CHECK_SYS_UP(); 2266 memset(eabuf, 0, ETHER_ADDR_STR_LEN); 2267 memcpy(&pmkid.pmkid[0].BSSID, pmksa->bssid, ETHER_ADDR_LEN); 2268 memcpy(&pmkid.pmkid[0].PMKID, pmksa->pmkid, WPA2_PMKID_LEN); 2269 2270 WL_DBG(("del_pmksa,IW_PMKSA_REMOVE - PMKID: %s =\n", 2271 bcm_ether_ntoa(&pmkid.pmkid[0].BSSID, eabuf))); 2272 for (i = 0; i < WPA2_PMKID_LEN; i++) { 2273 WL_DBG(("%02x\n", pmkid.pmkid[0].PMKID[i])); 2274 } 2275 2276 for (i = 0; i < wl->pmk_list->pmkids.npmkid; i++) 2277 if (!memcmp(pmksa->bssid, &wl->pmk_list->pmkids.pmkid[i].BSSID, ETHER_ADDR_LEN)) 2278 break; 2279 2280 if ((wl->pmk_list->pmkids.npmkid > 0) && (i < wl->pmk_list->pmkids.npmkid)) { 2281 memset(&wl->pmk_list->pmkids.pmkid[i], 0, sizeof(pmkid_t)); 2282 for (; i < (wl->pmk_list->pmkids.npmkid - 1); i++) { 2283 memcpy(&wl->pmk_list->pmkids.pmkid[i].BSSID, 2284 &wl->pmk_list->pmkids.pmkid[i+1].BSSID, ETHER_ADDR_LEN); 2285 memcpy(&wl->pmk_list->pmkids.pmkid[i].PMKID, 2286 &wl->pmk_list->pmkids.pmkid[i+1].PMKID, WPA2_PMKID_LEN); 2287 } 2288 wl->pmk_list->pmkids.npmkid--; 2289 } 2290 else { 2291 err = -EINVAL; 2292 } 2293 2294 err = wl_update_pmklist(dev, wl->pmk_list, err); 2295 2296 #ifdef WL_CFG80211_BACKTRACE 2297 WL_DBG(("Out\n")); 2298 #endif 2299 return err; 2300 2301 } 2302 2303 static int32 2304 wl_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev) 2305 { 2306 struct wl_priv *wl = wiphy_to_wl(wiphy); 2307 int32 err = 0; 2308 2309 #ifdef WL_CFG80211_BACKTRACE 2310 WL_DBG(("In\n")); 2311 #endif 2312 CHECK_SYS_UP(); 2313 memset(wl->pmk_list, 0, sizeof(*wl->pmk_list)); 2314 err = wl_update_pmklist(dev, wl->pmk_list, err); 2315 #ifdef WL_CFG80211_BACKTRACE 2316 WL_DBG(("Out\n")); 2317 #endif 2318 return err; 2319 2320 } 2321 #endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 33)) */ 2322 2323 static struct cfg80211_ops wl_cfg80211_ops = { 2324 .change_virtual_intf = wl_cfg80211_change_iface, 2325 .scan = wl_cfg80211_scan, 2326 .set_wiphy_params = wl_cfg80211_set_wiphy_params, 2327 .join_ibss = wl_cfg80211_join_ibss, 2328 .leave_ibss = wl_cfg80211_leave_ibss, 2329 .get_station = wl_cfg80211_get_station, 2330 .set_tx_power = wl_cfg80211_set_tx_power, 2331 .get_tx_power = wl_cfg80211_get_tx_power, 2332 .add_key = wl_cfg80211_add_key, 2333 .del_key = wl_cfg80211_del_key, 2334 .get_key = wl_cfg80211_get_key, 2335 .set_default_key = wl_cfg80211_config_default_key, 2336 .set_default_mgmt_key = wl_cfg80211_config_default_mgmt_key, 2337 .set_power_mgmt = wl_cfg80211_set_power_mgmt, 2338 .set_bitrate_mask = wl_cfg80211_set_bitrate_mask, 2339 .connect = wl_cfg80211_connect, 2340 .disconnect = wl_cfg80211_disconnect, 2341 .suspend = wl_cfg80211_suspend, 2342 .resume = wl_cfg80211_resume, 2343 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 33)) || \ 2344 defined(CHROMIUMOS_COMPAT_WIRELESS) 2345 .set_pmksa = wl_cfg80211_set_pmksa, 2346 .del_pmksa = wl_cfg80211_del_pmksa, 2347 .flush_pmksa = wl_cfg80211_flush_pmksa 2348 #endif 2349 }; 2350 2351 static int32 2352 wl_mode_to_nl80211_iftype(int32 mode) 2353 { 2354 int32 err = 0; 2355 2356 #ifdef WL_CFG80211_BACKTRACE 2357 WL_DBG(("In\n")); 2358 #endif 2359 switch (mode) { 2360 case WL_MODE_BSS: 2361 return NL80211_IFTYPE_STATION; 2362 case WL_MODE_IBSS: 2363 return NL80211_IFTYPE_ADHOC; 2364 default: 2365 return NL80211_IFTYPE_UNSPECIFIED; 2366 } 2367 #ifdef WL_CFG80211_BACKTRACE 2368 WL_DBG(("Out\n")); 2369 #endif 2370 2371 return err; 2372 } 2373 2374 static struct wireless_dev * 2375 wl_alloc_wdev(int32 sizeof_iface, struct device *dev) 2376 { 2377 struct wireless_dev *wdev; 2378 int32 err = 0; 2379 2380 #ifdef WL_CFG80211_BACKTRACE 2381 WL_DBG(("In\n")); 2382 #endif 2383 wdev = kzalloc(sizeof(*wdev), GFP_KERNEL); 2384 if (unlikely(!wdev)) { 2385 WL_ERR(("Could not allocate wireless device\n")); 2386 return ERR_PTR(-ENOMEM); 2387 } 2388 wdev->wiphy = wiphy_new(&wl_cfg80211_ops, sizeof(struct wl_priv) + sizeof_iface); 2389 if (unlikely(!wdev->wiphy)) { 2390 WL_ERR(("Couldn not allocate wiphy device\n")); 2391 err = -ENOMEM; 2392 goto wiphy_new_out; 2393 } 2394 set_wiphy_dev(wdev->wiphy, dev); 2395 wdev->wiphy->max_scan_ssids = WL_NUM_SCAN_MAX; 2396 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 33)) || \ 2397 defined(CHROMIUMOS_COMPAT_WIRELESS) 2398 wdev->wiphy->max_num_pmkids = WL_NUM_PMKIDS_MAX; 2399 #endif 2400 wdev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)| BIT(NL80211_IFTYPE_ADHOC); 2401 wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &__wl_band_2ghz; 2402 wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_a; /* Set it as 11a by default. 2403 ** This will be updated with 2404 ** 11n phy tables in "ifconfig up" 2405 ** if phy has 11n capability 2406 */ 2407 wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM; 2408 wdev->wiphy->cipher_suites = __wl_cipher_suites; 2409 wdev->wiphy->n_cipher_suites = ARRAY_SIZE(__wl_cipher_suites); 2410 #ifndef WL_POWERSAVE_DISABLED 2411 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 33)) || \ 2412 defined(CHROMIUMOS_COMPAT_WIRELESS) 2413 wdev->wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT; /* enable power 2414 * save mode by default 2415 */ 2416 #else 2417 wdev->wiphy->ps_default = TRUE; /* enable power save mode by default */ 2418 #endif 2419 #else 2420 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 33)) || \ 2421 defined(CHROMIUMOS_COMPAT_WIRELESS) 2422 wdev->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; 2423 #else 2424 wdev->wiphy->ps_default = FALSE; 2425 #endif 2426 #endif /* !WL_POWERSAVE_DISABLED */ 2427 if (unlikely(((err = wiphy_register(wdev->wiphy)) < 0))) { 2428 WL_ERR(("Couldn not register wiphy device (%d)\n", err)); 2429 goto wiphy_register_out; 2430 } 2431 return wdev; 2432 2433 wiphy_register_out: 2434 wiphy_free(wdev->wiphy); 2435 2436 wiphy_new_out: 2437 kfree(wdev); 2438 2439 #ifdef WL_CFG80211_BACKTRACE 2440 WL_DBG(("Out\n")); 2441 #endif 2442 2443 return ERR_PTR(err); 2444 } 2445 2446 static void 2447 wl_free_wdev(struct wl_priv *wl) 2448 { 2449 struct wireless_dev *wdev = wl_to_wdev(wl); 2450 2451 #ifdef WL_CFG80211_BACKTRACE 2452 WL_DBG(("In\n")); 2453 #endif 2454 if (unlikely(!wdev)) { 2455 WL_ERR(("wdev is invalid\n")); 2456 return; 2457 } 2458 wiphy_unregister(wdev->wiphy); 2459 wiphy_free(wdev->wiphy); 2460 kfree(wdev); 2461 wl_to_wdev(wl) = NULL; 2462 #ifdef WL_CFG80211_BACKTRACE 2463 WL_DBG(("Out\n")); 2464 #endif 2465 } 2466 2467 static int32 2468 wl_inform_bss(struct wl_priv *wl) 2469 { 2470 struct wl_scan_results *bss_list; 2471 struct wl_bss_info *bi = NULL; /* must be initialized */ 2472 int32 err = 0; 2473 int i; 2474 2475 2476 bss_list = wl->bss_list; 2477 if (unlikely(bss_list->version != WL_BSS_INFO_VERSION)) { 2478 WL_ERR(("Version %d != WL_BSS_INFO_VERSION\n", bss_list->version)); 2479 return -EOPNOTSUPP; 2480 } 2481 WL_DBG(("scanned AP count (%d)\n", bss_list->count)); 2482 bi = next_bss(bss_list, bi); 2483 for_each_bss(bss_list, bi, i) { 2484 if (unlikely(err = wl_inform_single_bss(wl, bi))) 2485 break; 2486 } 2487 return err; 2488 } 2489 2490 static int32 2491 wl_inform_single_bss(struct wl_priv *wl, struct wl_bss_info *bi) 2492 { 2493 struct wiphy *wiphy = wl_to_wiphy(wl); 2494 struct ieee80211_mgmt *mgmt; 2495 struct ieee80211_channel *channel; 2496 struct ieee80211_supported_band *band; 2497 struct wl_cfg80211_bss_info *notif_bss_info; 2498 struct wl_scan_req *sr = wl_to_sr(wl); 2499 uint32 signal; 2500 uint32 freq; 2501 int32 err = 0; 2502 2503 if (unlikely(dtoh32(bi->length) > WL_BSS_INFO_MAX)) { 2504 WL_DBG(("Beacon size is larger than allocated buffer. Discard it!!\n")); 2505 return err; 2506 } 2507 notif_bss_info = kzalloc(sizeof(*notif_bss_info) + sizeof(*mgmt) - sizeof(uint8) + 2508 WL_BSS_INFO_MAX, GFP_KERNEL); 2509 if (unlikely(!notif_bss_info)) { 2510 WL_ERR(("notif_bss_info alloc failed\n")); 2511 return -ENOMEM; 2512 } 2513 mgmt = (struct ieee80211_mgmt *)notif_bss_info->frame_buf; 2514 notif_bss_info->channel = CHSPEC_CHANNEL(bi->chanspec); 2515 if (notif_bss_info->channel <= CH_MAX_2G_CHANNEL) 2516 band = wiphy->bands[IEEE80211_BAND_2GHZ]; 2517 else 2518 band = wiphy->bands[IEEE80211_BAND_5GHZ]; 2519 notif_bss_info->rssi = bi->RSSI; 2520 memcpy(mgmt->bssid, &bi->BSSID, ETHER_ADDR_LEN); 2521 if (!memcmp(bi->SSID, sr->ssid.SSID, bi->SSID_len)) { 2522 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | 2523 IEEE80211_STYPE_PROBE_RESP); 2524 } 2525 mgmt->u.probe_resp.timestamp = 0; 2526 mgmt->u.probe_resp.beacon_int = cpu_to_le16(bi->beacon_period); 2527 mgmt->u.probe_resp.capab_info = cpu_to_le16(bi->capability); 2528 wl_rst_ie(wl); 2529 wl_add_ie(wl, WLAN_EID_SSID, bi->SSID_len, bi->SSID); 2530 wl_add_ie(wl, WLAN_EID_SUPP_RATES, bi->rateset.count, bi->rateset.rates); 2531 wl_mrg_ie(wl, ((uint8 *)bi) + bi->ie_offset, bi->ie_length); 2532 wl_cp_ie(wl, mgmt->u.probe_resp.variable, WL_BSS_INFO_MAX - 2533 offsetof(struct wl_cfg80211_bss_info, frame_buf)); 2534 notif_bss_info->frame_len = offsetof(struct ieee80211_mgmt, u.probe_resp.variable) + 2535 wl_get_ielen(wl); 2536 freq = ieee80211_channel_to_frequency(notif_bss_info->channel); 2537 channel = ieee80211_get_channel(wiphy, freq); 2538 2539 WL_DBG(("SSID : \"%s\", rssi (%d), capability : 0x04%x\n", bi->SSID, notif_bss_info->rssi, 2540 mgmt->u.probe_resp.capab_info)); 2541 2542 signal = notif_bss_info->rssi * 100; 2543 if (unlikely(!cfg80211_inform_bss_frame(wiphy, channel, mgmt, 2544 le16_to_cpu(notif_bss_info->frame_len), signal, GFP_KERNEL))) { 2545 WL_ERR(("cfg80211_inform_bss_frame error\n")); 2546 kfree(notif_bss_info); 2547 return -EINVAL; 2548 } 2549 kfree(notif_bss_info); 2550 2551 return err; 2552 } 2553 2554 static bool 2555 wl_is_linkup(struct wl_priv *wl, const wl_event_msg_t *e) 2556 { 2557 uint32 event = ntoh32(e->event_type); 2558 uint16 flags = ntoh16(e->flags); 2559 2560 if (event == WLC_E_JOIN || event == WLC_E_ASSOC_IND || event == WLC_E_REASSOC_IND) { 2561 return TRUE; 2562 } else if (event == WLC_E_LINK) { 2563 if (flags & WLC_EVENT_MSG_LINK) { 2564 if (wl_is_ibssmode(wl)) { 2565 if (wl_is_ibssstarter(wl)) { 2566 } 2567 } else { 2568 2569 } 2570 } 2571 } 2572 2573 return FALSE; 2574 } 2575 2576 static bool 2577 wl_is_linkdown(struct wl_priv *wl, const wl_event_msg_t *e) 2578 { 2579 uint32 event = ntoh32(e->event_type); 2580 uint16 flags = ntoh16(e->flags); 2581 2582 if (event == WLC_E_DEAUTH_IND || event == WLC_E_DISASSOC_IND) { 2583 return TRUE; 2584 } else if (event == WLC_E_LINK) { 2585 if (!(flags & WLC_EVENT_MSG_LINK)) { 2586 return TRUE; 2587 } 2588 } 2589 2590 return FALSE; 2591 } 2592 2593 static int32 2594 wl_notify_connect_status(struct wl_priv *wl, struct net_device *ndev, 2595 const wl_event_msg_t *e, void* data) 2596 { 2597 bool act; 2598 int32 err = 0; 2599 2600 #ifdef WL_CFG80211_BACKTRACE 2601 WL_DBG(("In\n")); 2602 #endif 2603 if (wl_is_linkup(wl, e)) { 2604 wl_link_up(wl); 2605 if (wl_is_ibssmode(wl)) { 2606 cfg80211_ibss_joined(ndev, (int8 *)&e->addr, GFP_KERNEL); 2607 WL_DBG(("joined in IBSS network\n")); 2608 } else { 2609 wl_bss_connect_done(wl, ndev, e, data); 2610 WL_DBG(("joined in BSS network \"%s\"\n", 2611 ((struct wlc_ssid *)wl_read_prof(wl, WL_PROF_SSID))->SSID)); 2612 } 2613 act = TRUE; 2614 wl_update_prof(wl, e, &act, WL_PROF_ACT); 2615 } else if (wl_is_linkdown(wl, e)) { 2616 cfg80211_disconnected(ndev, 0, NULL, 0, GFP_KERNEL); 2617 clear_bit(WL_STATUS_CONNECTED, &wl->status); 2618 wl_link_down(wl); 2619 wl_init_prof(wl->profile); 2620 } 2621 #ifdef WL_CFG80211_BACKTRACE 2622 WL_DBG(("Out\n")); 2623 #endif 2624 2625 return err; 2626 } 2627 2628 static int32 2629 wl_notify_roaming_status(struct wl_priv *wl, struct net_device *ndev, 2630 const wl_event_msg_t *e, void* data) 2631 { 2632 bool act; 2633 int32 err = 0; 2634 2635 #ifdef WL_CFG80211_BACKTRACE 2636 WL_DBG(("In\n")); 2637 #endif 2638 wl_bss_roaming_done(wl, ndev, e, data); 2639 act = TRUE; 2640 wl_update_prof(wl, e, &act, WL_PROF_ACT); 2641 #ifdef WL_CFG80211_BACKTRACE 2642 WL_DBG(("Out\n")); 2643 #endif 2644 2645 return err; 2646 } 2647 2648 static __used int32 2649 wl_dev_bufvar_set(struct net_device *dev, int8 *name, int8 *buf, int32 len) 2650 { 2651 struct wl_priv *wl = ndev_to_wl(dev); 2652 uint32 buflen; 2653 2654 buflen = bcm_mkiovar(name, buf, len, wl->ioctl_buf, WL_IOCTL_LEN_MAX); 2655 BUG_ON(unlikely(!buflen)); 2656 2657 return (wl_dev_ioctl(dev, WLC_SET_VAR, wl->ioctl_buf, buflen)); 2658 } 2659 2660 static int32 2661 wl_dev_bufvar_get(struct net_device *dev, int8 *name, int8 *buf, int32 buf_len) 2662 { 2663 struct wl_priv *wl = ndev_to_wl(dev); 2664 uint32 len; 2665 int32 err = 0; 2666 2667 len = bcm_mkiovar(name, NULL, 0, wl->ioctl_buf, WL_IOCTL_LEN_MAX); 2668 BUG_ON(unlikely(!len)); 2669 if (unlikely((err = wl_dev_ioctl(dev, WLC_GET_VAR, (void *)wl->ioctl_buf, 2670 WL_IOCTL_LEN_MAX)))) { 2671 WL_ERR(("error (%d)\n", err)); 2672 return err; 2673 } 2674 memcpy(buf, wl->ioctl_buf, buf_len); 2675 2676 return err; 2677 } 2678 2679 static int32 2680 wl_get_assoc_ies(struct wl_priv *wl) 2681 { 2682 struct net_device *ndev = wl_to_ndev(wl); 2683 struct wl_assoc_ielen *assoc_info; 2684 struct wl_connect_info *conn_info = wl_to_conn(wl); 2685 uint32 req_len; 2686 uint32 resp_len; 2687 int32 err = 0; 2688 2689 if (unlikely(err = wl_dev_bufvar_get(ndev, "assoc_info", wl->extra_buf, 2690 WL_ASSOC_INFO_MAX))) { 2691 WL_ERR(("could not get assoc info (%d)\n", err)); 2692 return err; 2693 } 2694 assoc_info = (struct wl_assoc_ielen *)wl->extra_buf; 2695 req_len = assoc_info->req_len; 2696 resp_len = assoc_info->resp_len; 2697 if (req_len) { 2698 if (unlikely(err = wl_dev_bufvar_get(ndev, "assoc_req_ies", wl->extra_buf, 2699 WL_ASSOC_INFO_MAX))) { 2700 WL_ERR(("could not get assoc req (%d)\n", err)); 2701 return err; 2702 } 2703 conn_info->req_ie_len = req_len; 2704 conn_info->req_ie = kmemdup(wl->extra_buf, conn_info->req_ie_len, GFP_KERNEL); 2705 } else { 2706 conn_info->req_ie_len = 0; 2707 conn_info->req_ie = NULL; 2708 } 2709 if (resp_len) { 2710 if (unlikely(err = wl_dev_bufvar_get(ndev, "assoc_resp_ies", wl->extra_buf, 2711 WL_ASSOC_INFO_MAX))) { 2712 WL_ERR(("could not get assoc resp (%d)\n", err)); 2713 return err; 2714 } 2715 conn_info->resp_ie_len = resp_len; 2716 conn_info->resp_ie = kmemdup(wl->extra_buf, conn_info->resp_ie_len, GFP_KERNEL); 2717 } else { 2718 conn_info->resp_ie_len = 0; 2719 conn_info->resp_ie = NULL; 2720 } 2721 WL_DBG(("req len (%d) resp len (%d)\n", conn_info->req_ie_len, conn_info->resp_ie_len)); 2722 2723 return err; 2724 } 2725 2726 static int32 2727 wl_update_bss_info(struct wl_priv *wl) 2728 { 2729 struct cfg80211_bss *bss; 2730 struct wl_bss_info *bi; 2731 struct wlc_ssid *ssid; 2732 int32 err = 0; 2733 2734 2735 #ifdef WL_CFG80211_BACKTRACE 2736 WL_DBG(("In\n")); 2737 #endif 2738 if (wl_is_ibssmode(wl)) 2739 return err; 2740 2741 ssid = (struct wlc_ssid *)wl_read_prof(wl, WL_PROF_SSID); 2742 bss = cfg80211_get_bss(wl_to_wiphy(wl), NULL, (int8 *)&wl->bssid, ssid->SSID, 2743 ssid->SSID_len, WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS); 2744 2745 rtnl_lock(); 2746 if (unlikely(!bss)) { 2747 WL_DBG(("Could not find the AP\n")); 2748 *(uint32*)wl->extra_buf = htod32(WL_EXTRA_BUF_MAX); 2749 if (unlikely(err = wl_dev_ioctl(wl_to_ndev(wl), WLC_GET_BSS_INFO, wl->extra_buf, 2750 WL_EXTRA_BUF_MAX))) { 2751 WL_ERR(("Could not get bss info %d\n", err)); 2752 goto update_bss_info_out; 2753 } 2754 bi = (struct wl_bss_info *)(wl->extra_buf + 4); 2755 if (unlikely(memcmp(&bi->BSSID, &wl->bssid, ETHER_ADDR_LEN))) { 2756 err = -EIO; 2757 goto update_bss_info_out; 2758 } 2759 if (unlikely((err = wl_inform_single_bss(wl, bi)))) 2760 goto update_bss_info_out; 2761 } else { 2762 WL_DBG(("Found the AP in the list - BSSID %02x:%02x:%02x:%02x:%02x:%02x\n", 2763 bss->bssid[0], bss->bssid[1], bss->bssid[2], bss->bssid[3], 2764 bss->bssid[4], bss->bssid[5])); 2765 cfg80211_put_bss(bss); 2766 } 2767 #ifdef WL_CFG80211_BACKTRACE 2768 WL_DBG(("Out\n")); 2769 #endif 2770 2771 update_bss_info_out: 2772 rtnl_unlock(); 2773 return err; 2774 } 2775 2776 static int32 2777 wl_bss_roaming_done(struct wl_priv *wl, struct net_device *ndev, 2778 const wl_event_msg_t *e, void* data) 2779 { 2780 struct wl_connect_info *conn_info = wl_to_conn(wl); 2781 int32 err = 0; 2782 2783 #ifdef WL_CFG80211_BACKTRACE 2784 WL_DBG(("In\n")); 2785 #endif 2786 wl_get_assoc_ies(wl); 2787 memcpy(&wl->bssid, &e->addr, ETHER_ADDR_LEN); 2788 wl_update_bss_info(wl); 2789 cfg80211_roamed(ndev, 2790 (uint8 *)&wl->bssid, 2791 conn_info->req_ie, conn_info->req_ie_len, 2792 conn_info->resp_ie, conn_info->resp_ie_len, 2793 GFP_KERNEL); 2794 WL_DBG(("Report roaming result\n")); 2795 2796 set_bit(WL_STATUS_CONNECTED, &wl->status); 2797 #ifdef WL_CFG80211_BACKTRACE 2798 WL_DBG(("Out\n")); 2799 #endif 2800 2801 return err; 2802 } 2803 2804 static int32 2805 wl_bss_connect_done(struct wl_priv *wl, struct net_device *ndev, 2806 const wl_event_msg_t *e, void* data) 2807 { 2808 struct wl_connect_info *conn_info = wl_to_conn(wl); 2809 int32 err = 0; 2810 2811 #ifdef WL_CFG80211_BACKTRACE 2812 WL_DBG(("In\n")); 2813 #endif 2814 wl_get_assoc_ies(wl); 2815 memcpy(&wl->bssid, &e->addr, ETHER_ADDR_LEN); 2816 wl_update_bss_info(wl); 2817 if (test_and_clear_bit(WL_STATUS_CONNECTING, &wl->status)) { 2818 cfg80211_connect_result(ndev, 2819 (uint8 *)&wl->bssid, 2820 conn_info->req_ie, conn_info->req_ie_len, 2821 conn_info->resp_ie, conn_info->resp_ie_len, 2822 WLAN_STATUS_SUCCESS, 2823 GFP_KERNEL); 2824 WL_DBG(("Report connect result\n")); 2825 } else { 2826 cfg80211_roamed(ndev, 2827 (uint8 *)&wl->bssid, 2828 conn_info->req_ie, conn_info->req_ie_len, 2829 conn_info->resp_ie, conn_info->resp_ie_len, 2830 GFP_KERNEL); 2831 WL_DBG(("Report roaming result\n")); 2832 } 2833 set_bit(WL_STATUS_CONNECTED, &wl->status); 2834 #ifdef WL_CFG80211_BACKTRACE 2835 WL_DBG(("Out\n")); 2836 #endif 2837 2838 return err; 2839 } 2840 2841 static int32 2842 wl_notify_mic_status(struct wl_priv *wl, struct net_device *ndev, 2843 const wl_event_msg_t *e, void* data) 2844 { 2845 uint16 flags = ntoh16(e->flags); 2846 enum nl80211_key_type key_type; 2847 2848 #ifdef WL_CFG80211_BACKTRACE 2849 WL_DBG(("In\n")); 2850 #endif 2851 2852 rtnl_lock(); 2853 if (flags & WLC_EVENT_MSG_GROUP) 2854 key_type = NL80211_KEYTYPE_GROUP; 2855 else 2856 key_type = NL80211_KEYTYPE_PAIRWISE; 2857 2858 cfg80211_michael_mic_failure(ndev, (uint8 *)&e->addr, key_type, -1, NULL, GFP_KERNEL); 2859 rtnl_unlock(); 2860 2861 #ifdef WL_CFG80211_BACKTRACE 2862 WL_DBG(("Out\n")); 2863 #endif 2864 return 0; 2865 } 2866 2867 static int32 2868 wl_notify_scan_status(struct wl_priv *wl, struct net_device *ndev, 2869 const wl_event_msg_t *e, void* data) 2870 { 2871 struct channel_info channel_inform; 2872 struct wl_scan_results *bss_list; 2873 uint32 len = WL_SCAN_BUF_MAX; 2874 int32 err = 0; 2875 2876 #ifdef WL_CFG80211_BACKTRACE 2877 WL_DBG(("In\n")); 2878 #endif 2879 2880 if (wl->iscan_on && wl->iscan_kickstart) 2881 return wl_wakeup_iscan(wl_to_iscan(wl)); 2882 2883 if (unlikely(!test_and_clear_bit(WL_STATUS_SCANNING, &wl->status))) { 2884 WL_ERR(("Scan complete while device not scanning\n")); 2885 return -EINVAL; 2886 } 2887 if (unlikely(!wl->scan_request)) { 2888 } 2889 rtnl_lock(); 2890 if (unlikely((err = wl_dev_ioctl(ndev, WLC_GET_CHANNEL, &channel_inform, 2891 sizeof(channel_inform))))) { 2892 WL_ERR(("scan busy (%d)\n", err)); 2893 goto scan_done_out; 2894 } 2895 channel_inform.scan_channel = dtoh32(channel_inform.scan_channel); 2896 if (unlikely(channel_inform.scan_channel)) { 2897 2898 WL_DBG(("channel_inform.scan_channel (%d)\n", channel_inform.scan_channel)); 2899 } 2900 wl->bss_list = wl->scan_results; 2901 bss_list = wl->bss_list; 2902 memset(bss_list, 0, len); 2903 bss_list->buflen = htod32(len); 2904 if (unlikely((err = wl_dev_ioctl(ndev, WLC_SCAN_RESULTS, bss_list, len)))) { 2905 WL_ERR(("%s Scan_results error (%d)\n", ndev->name, err)); 2906 err = -EINVAL; 2907 goto scan_done_out; 2908 } 2909 bss_list->buflen = dtoh32(bss_list->buflen); 2910 bss_list->version = dtoh32(bss_list->version); 2911 bss_list->count = dtoh32(bss_list->count); 2912 2913 if ((err = wl_inform_bss(wl))) { 2914 goto scan_done_out; 2915 } 2916 2917 scan_done_out : 2918 if (wl->scan_request) { 2919 cfg80211_scan_done(wl->scan_request, FALSE); 2920 wl->scan_request = NULL; 2921 } 2922 #ifdef WL_CFG80211_BACKTRACE 2923 WL_DBG(("Out\n")); 2924 #endif 2925 rtnl_unlock(); 2926 return err; 2927 } 2928 2929 static void 2930 wl_init_conf(struct wl_conf *conf) 2931 { 2932 conf->mode = (uint32)-1; 2933 conf->frag_threshold = (uint32)-1; 2934 conf->rts_threshold = (uint32)-1; 2935 conf->retry_short = (uint32)-1; 2936 conf->retry_long = (uint32)-1; 2937 conf->tx_power = -1; 2938 } 2939 2940 static void 2941 wl_init_prof(struct wl_profile *prof) 2942 { 2943 memset(prof, 0, sizeof(*prof)); 2944 } 2945 2946 static void 2947 wl_init_eloop_handler(struct wl_event_loop *el) 2948 { 2949 memset(el, 0, sizeof(*el)); 2950 el->handler[WLC_E_SCAN_COMPLETE] = wl_notify_scan_status; 2951 el->handler[WLC_E_JOIN] = wl_notify_connect_status; 2952 el->handler[WLC_E_LINK] = wl_notify_connect_status; 2953 el->handler[WLC_E_DEAUTH_IND] = wl_notify_connect_status; 2954 el->handler[WLC_E_DISASSOC_IND] = wl_notify_connect_status; 2955 el->handler[WLC_E_ASSOC_IND] = wl_notify_connect_status; 2956 el->handler[WLC_E_REASSOC_IND] = wl_notify_connect_status; 2957 el->handler[WLC_E_ROAM] = wl_notify_roaming_status; 2958 el->handler[WLC_E_MIC_ERROR] = wl_notify_mic_status; 2959 } 2960 2961 static int32 2962 wl_init_priv_mem(struct wl_priv *wl) 2963 { 2964 wl->scan_results = (void *)kzalloc(WL_SCAN_BUF_MAX, GFP_KERNEL); 2965 if (unlikely(!wl->scan_results)) { 2966 WL_ERR(("Scan results alloc failed\n")); 2967 goto init_priv_mem_out; 2968 } 2969 wl->conf = (void *)kzalloc(sizeof(*wl->conf), GFP_KERNEL); 2970 if (unlikely(!wl->conf)) { 2971 WL_ERR(("wl_conf alloc failed\n")); 2972 goto init_priv_mem_out; 2973 } 2974 wl->profile = (void *)kzalloc(sizeof(*wl->profile), GFP_KERNEL); 2975 if (unlikely(!wl->profile)) { 2976 WL_ERR(("wl_profile alloc failed\n")); 2977 goto init_priv_mem_out; 2978 } 2979 wl->bss_info = (void *)kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL); 2980 if (unlikely(!wl->bss_info)) { 2981 WL_ERR(("Bss information alloc failed\n")); 2982 goto init_priv_mem_out; 2983 } 2984 wl->scan_req_int = (void *)kzalloc(sizeof(*wl->scan_req_int), GFP_KERNEL); 2985 if (unlikely(!wl->scan_req_int)) { 2986 WL_ERR(("Scan req alloc failed\n")); 2987 goto init_priv_mem_out; 2988 } 2989 wl->ioctl_buf = (void *)kzalloc(WL_IOCTL_LEN_MAX, GFP_KERNEL); 2990 if (unlikely(!wl->ioctl_buf)) { 2991 WL_ERR(("Ioctl buf alloc failed\n")); 2992 goto init_priv_mem_out; 2993 } 2994 wl->extra_buf = (void *)kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL); 2995 if (unlikely(!wl->extra_buf)) { 2996 WL_ERR(("Extra buf alloc failed\n")); 2997 goto init_priv_mem_out; 2998 } 2999 wl->iscan = (void *)kzalloc(sizeof(*wl->iscan), GFP_KERNEL); 3000 if (unlikely(!wl->iscan)) { 3001 WL_ERR(("Iscan buf alloc failed\n")); 3002 goto init_priv_mem_out; 3003 } 3004 wl->fw = (void *)kzalloc(sizeof(*wl->fw), GFP_KERNEL); 3005 if (unlikely(!wl->fw)) { 3006 WL_ERR(("fw object alloc failed\n")); 3007 goto init_priv_mem_out; 3008 } 3009 wl->pmk_list = (void *)kzalloc(sizeof(*wl->pmk_list), GFP_KERNEL); 3010 if (unlikely(!wl->pmk_list)) { 3011 WL_ERR(("pmk list alloc failed\n")); 3012 goto init_priv_mem_out; 3013 } 3014 3015 return 0; 3016 3017 init_priv_mem_out: 3018 wl_deinit_priv_mem(wl); 3019 3020 return -ENOMEM; 3021 } 3022 3023 static void 3024 wl_deinit_priv_mem(struct wl_priv *wl) 3025 { 3026 if (wl->scan_results) { 3027 kfree(wl->scan_results); 3028 wl->scan_results = NULL; 3029 } 3030 if (wl->bss_info) { 3031 kfree(wl->bss_info); 3032 wl->bss_info = NULL; 3033 } 3034 if (wl->conf) { 3035 kfree(wl->conf); 3036 wl->conf = NULL; 3037 } 3038 if (wl->profile) { 3039 kfree(wl->profile); 3040 wl->profile = NULL; 3041 } 3042 if (wl->scan_req_int) { 3043 kfree(wl->scan_req_int); 3044 wl->scan_req_int = NULL; 3045 } 3046 if (wl->ioctl_buf) { 3047 kfree(wl->ioctl_buf); 3048 wl->ioctl_buf = NULL; 3049 } 3050 if (wl->extra_buf) { 3051 kfree(wl->extra_buf); 3052 wl->extra_buf = NULL; 3053 } 3054 if (wl->iscan) { 3055 kfree(wl->iscan); 3056 wl->iscan = NULL; 3057 } 3058 if (wl->fw) { 3059 kfree(wl->fw); 3060 wl->fw = NULL; 3061 } 3062 if (wl->pmk_list) { 3063 kfree(wl->pmk_list); 3064 wl->pmk_list = NULL; 3065 } 3066 } 3067 3068 3069 static int32 3070 wl_create_event_handler(struct wl_priv *wl) 3071 { 3072 sema_init(&wl->event_sync, 0); 3073 init_completion(&wl->event_exit); 3074 if (unlikely(((wl->event_pid = kernel_thread(wl_event_handler, wl, 0)) < 0))) { 3075 WL_ERR(("failed to create event thread\n")); 3076 return -ENOMEM; 3077 } 3078 WL_DBG(("pid %d\n", wl->event_pid)); 3079 return 0; 3080 } 3081 3082 static void 3083 wl_destroy_event_handler(struct wl_priv *wl) 3084 { 3085 if (wl->event_pid >= 0) { 3086 KILL_PROC(wl->event_pid, SIGTERM); 3087 wait_for_completion(&wl->event_exit); 3088 } 3089 } 3090 3091 static void 3092 wl_term_iscan(struct wl_priv *wl) 3093 { 3094 struct wl_iscan_ctrl *iscan = wl_to_iscan(wl); 3095 3096 if (wl->iscan_on && iscan->pid >= 0) { 3097 iscan->state = WL_ISCAN_STATE_IDLE; 3098 KILL_PROC(iscan->pid, SIGTERM); 3099 wait_for_completion(&iscan->exited); 3100 iscan->pid = -1; 3101 } 3102 } 3103 3104 static void 3105 wl_notify_iscan_complete(struct wl_iscan_ctrl *iscan, bool aborted) 3106 { 3107 struct wl_priv *wl = iscan_to_wl(iscan); 3108 3109 #ifdef WL_CFG80211_BACKTRACE 3110 WL_DBG(("In\n")); 3111 #endif 3112 if (unlikely(!test_and_clear_bit(WL_STATUS_SCANNING, &wl->status))) { 3113 WL_ERR(("Scan complete while device not scanning\n")); 3114 return; 3115 } 3116 if (likely(wl->scan_request)) { 3117 cfg80211_scan_done(wl->scan_request, aborted); 3118 wl->scan_request = NULL; 3119 } 3120 wl->iscan_kickstart = FALSE; 3121 #ifdef WL_CFG80211_BACKTRACE 3122 WL_DBG(("Out\n")); 3123 #endif 3124 } 3125 3126 static int32 3127 wl_wakeup_iscan(struct wl_iscan_ctrl *iscan) 3128 { 3129 if (likely(iscan->state != WL_ISCAN_STATE_IDLE)) { 3130 WL_DBG(("wake up iscan\n")); 3131 up(&iscan->sync); 3132 return 0; 3133 } 3134 3135 return -EIO; 3136 } 3137 3138 static int32 3139 wl_get_iscan_results(struct wl_iscan_ctrl *iscan, uint32 *status, struct wl_scan_results **bss_list) 3140 { 3141 struct wl_iscan_results list; 3142 struct wl_scan_results *results; 3143 struct wl_iscan_results *list_buf; 3144 int32 err = 0; 3145 3146 memset(iscan->scan_buf, 0, WL_ISCAN_BUF_MAX); 3147 list_buf = (struct wl_iscan_results *)iscan->scan_buf; 3148 results = &list_buf->results; 3149 results->buflen = WL_ISCAN_RESULTS_FIXED_SIZE; 3150 results->version = 0; 3151 results->count = 0; 3152 3153 memset(&list, 0, sizeof(list)); 3154 list.results.buflen = htod32(WL_ISCAN_BUF_MAX); 3155 if (unlikely((err = wl_dev_iovar_getbuf( 3156 iscan->dev, 3157 "iscanresults", 3158 &list, 3159 WL_ISCAN_RESULTS_FIXED_SIZE, 3160 iscan->scan_buf, 3161 WL_ISCAN_BUF_MAX)))) { 3162 WL_ERR(("error (%d)\n", err)); 3163 return err; 3164 } 3165 results->buflen = dtoh32(results->buflen); 3166 results->version = dtoh32(results->version); 3167 results->count = dtoh32(results->count); 3168 WL_DBG(("results->count = %d\n", results->count)); 3169 WL_DBG(("results->buflen = %d\n", results->buflen)); 3170 *status = dtoh32(list_buf->status); 3171 *bss_list = results; 3172 3173 return err; 3174 } 3175 3176 static int32 3177 wl_iscan_done(struct wl_priv *wl) 3178 { 3179 struct wl_iscan_ctrl *iscan = wl->iscan; 3180 int32 err = 0; 3181 3182 #ifdef WL_CFG80211_BACKTRACE 3183 WL_DBG(("In\n")); 3184 #endif 3185 iscan->state = WL_ISCAN_STATE_IDLE; 3186 rtnl_lock(); 3187 wl_inform_bss(wl); 3188 wl_notify_iscan_complete(iscan, FALSE); 3189 rtnl_unlock(); 3190 #ifdef WL_CFG80211_BACKTRACE 3191 WL_DBG(("Out\n")); 3192 #endif 3193 3194 return err; 3195 } 3196 3197 static int32 3198 wl_iscan_pending(struct wl_priv *wl) 3199 { 3200 struct wl_iscan_ctrl *iscan = wl->iscan; 3201 int32 err = 0; 3202 3203 #ifdef WL_CFG80211_BACKTRACE 3204 WL_DBG(("In\n")); 3205 #endif 3206 /* Reschedule the timer */ 3207 mod_timer(&iscan->timer, jiffies + iscan->timer_ms*HZ/1000); 3208 iscan->timer_on = 1; 3209 #ifdef WL_CFG80211_BACKTRACE 3210 WL_DBG(("Out\n")); 3211 #endif 3212 3213 return err; 3214 } 3215 3216 static int32 3217 wl_iscan_inprogress(struct wl_priv *wl) 3218 { 3219 struct wl_iscan_ctrl *iscan = wl->iscan; 3220 int32 err = 0; 3221 3222 #ifdef WL_CFG80211_BACKTRACE 3223 WL_DBG(("In\n")); 3224 #endif 3225 rtnl_lock(); 3226 wl_inform_bss(wl); 3227 wl_run_iscan(iscan, NULL, WL_SCAN_ACTION_CONTINUE); 3228 rtnl_unlock(); 3229 /* Reschedule the timer */ 3230 mod_timer(&iscan->timer, jiffies + iscan->timer_ms*HZ/1000); 3231 iscan->timer_on = 1; 3232 #ifdef WL_CFG80211_BACKTRACE 3233 WL_DBG(("Out\n")); 3234 #endif 3235 3236 return err; 3237 } 3238 3239 static int32 3240 wl_iscan_aborted(struct wl_priv *wl) 3241 { 3242 struct wl_iscan_ctrl *iscan = wl->iscan; 3243 int32 err = 0; 3244 3245 #ifdef WL_CFG80211_BACKTRACE 3246 WL_DBG(("In\n")); 3247 #endif 3248 iscan->state = WL_ISCAN_STATE_IDLE; 3249 rtnl_lock(); 3250 wl_notify_iscan_complete(iscan, TRUE); 3251 rtnl_unlock(); 3252 #ifdef WL_CFG80211_BACKTRACE 3253 WL_DBG(("Out\n")); 3254 #endif 3255 3256 return err; 3257 } 3258 3259 static int32 3260 wl_iscan_thread(void *data) 3261 { 3262 struct sched_param param = { .sched_priority = MAX_RT_PRIO-1 }; 3263 struct wl_iscan_ctrl *iscan = (struct wl_iscan_ctrl *)data; 3264 struct wl_priv *wl = iscan_to_wl(iscan); 3265 struct wl_iscan_eloop *el = &iscan->el; 3266 uint32 status; 3267 int err = 0; 3268 3269 #ifdef WL_CFG80211_BACKTRACE 3270 WL_DBG(("In\n")); 3271 #endif 3272 sched_setscheduler(current, SCHED_FIFO, ¶m); 3273 status = WL_SCAN_RESULTS_PARTIAL; 3274 while (likely(!down_interruptible(&iscan->sync))) { 3275 if (iscan->timer_on) { 3276 del_timer_sync(&iscan->timer); 3277 iscan->timer_on = 0; 3278 } 3279 rtnl_lock(); 3280 if (unlikely((err = wl_get_iscan_results(iscan, &status, &wl->bss_list)))) { 3281 status = WL_SCAN_RESULTS_ABORTED; 3282 WL_ERR(("Abort iscan\n")); 3283 } 3284 rtnl_unlock(); 3285 el->handler[status](wl); 3286 } 3287 if (iscan->timer_on) { 3288 del_timer_sync(&iscan->timer); 3289 iscan->timer_on = 0; 3290 } 3291 complete_and_exit(&iscan->exited, 0); 3292 #ifdef WL_CFG80211_BACKTRACE 3293 WL_DBG(("Out\n")); 3294 #endif 3295 3296 return 0; 3297 } 3298 3299 static void 3300 wl_iscan_timer(ulong data) 3301 { 3302 struct wl_iscan_ctrl *iscan = (struct wl_iscan_ctrl *)data; 3303 3304 if (iscan) { 3305 iscan->timer_on = 0; 3306 WL_DBG(("timer expired\n")); 3307 wl_wakeup_iscan(iscan); 3308 } 3309 } 3310 3311 static int32 3312 wl_invoke_iscan(struct wl_priv *wl) 3313 { 3314 struct wl_iscan_ctrl *iscan = wl_to_iscan(wl); 3315 int err = 0; 3316 3317 if (wl->iscan_on && iscan->pid < 0) { 3318 iscan->state = WL_ISCAN_STATE_IDLE; 3319 sema_init(&iscan->sync, 0); 3320 init_completion(&iscan->exited); 3321 iscan->pid = kernel_thread(wl_iscan_thread, iscan, 0); 3322 if (unlikely(iscan->pid < 0)) { 3323 WL_ERR(("Could not create iscan thread\n")); 3324 return -ENOMEM; 3325 } 3326 } 3327 3328 return err; 3329 } 3330 3331 static void 3332 wl_init_iscan_eloop(struct wl_iscan_eloop *el) 3333 { 3334 memset(el, 0, sizeof(*el)); 3335 el->handler[WL_SCAN_RESULTS_SUCCESS] = wl_iscan_done; 3336 el->handler[WL_SCAN_RESULTS_PARTIAL] = wl_iscan_inprogress; 3337 el->handler[WL_SCAN_RESULTS_PENDING] = wl_iscan_pending; 3338 el->handler[WL_SCAN_RESULTS_ABORTED] = wl_iscan_aborted; 3339 el->handler[WL_SCAN_RESULTS_NO_MEM] = wl_iscan_aborted; 3340 } 3341 3342 static int32 3343 wl_init_iscan(struct wl_priv *wl) 3344 { 3345 struct wl_iscan_ctrl *iscan = wl_to_iscan(wl); 3346 int err = 0; 3347 3348 if (wl->iscan_on) { 3349 iscan->dev = wl_to_ndev(wl); 3350 iscan->state = WL_ISCAN_STATE_IDLE; 3351 wl_init_iscan_eloop(&iscan->el); 3352 iscan->timer_ms = WL_ISCAN_TIMER_INTERVAL_MS; 3353 init_timer(&iscan->timer); 3354 iscan->timer.data = (ulong)iscan; 3355 iscan->timer.function = wl_iscan_timer; 3356 sema_init(&iscan->sync, 0); 3357 init_completion(&iscan->exited); 3358 iscan->pid = kernel_thread(wl_iscan_thread, iscan, 0); 3359 if (unlikely(iscan->pid < 0)) { 3360 WL_ERR(("Could not create iscan thread\n")); 3361 return -ENOMEM; 3362 } 3363 iscan->data = wl; 3364 } 3365 3366 return err; 3367 } 3368 3369 static void 3370 wl_init_fw(struct wl_fw_ctrl *fw) 3371 { 3372 fw->status = 0; /* init fw loading status. 0 means nothing was loaded yet */ 3373 } 3374 3375 static int32 3376 wl_init_priv(struct wl_priv *wl) 3377 { 3378 struct wiphy *wiphy = wl_to_wiphy(wl); 3379 int32 err = 0; 3380 3381 #ifdef WL_CFG80211_BACKTRACE 3382 WL_DBG(("In\n")); 3383 #endif 3384 wl->scan_request = NULL; 3385 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 33)) || \ 3386 defined(CHROMIUMOS_COMPAT_WIRELESS) 3387 wl->pwr_save = !!(wiphy->flags & WIPHY_FLAG_PS_ON_BY_DEFAULT); 3388 #else 3389 wl->pwr_save = wiphy->ps_default; 3390 #endif 3391 #ifndef WL_ISCAN_DISABLED 3392 wl->iscan_on = TRUE; /* iscan on & off switch. we enable iscan per default */ 3393 #else 3394 wl->iscan_on = FALSE; 3395 #endif /* WL_ISCAN_DISABLED */ 3396 #ifndef WL_ROAM_DISABLED 3397 wl->roam_on = TRUE; /* roam on & off switch. we enable roam per default */ 3398 #else 3399 wl->roam_on = FALSE; 3400 #endif /* WL_ROAM_DISABLED */ 3401 3402 wl->iscan_kickstart = FALSE; 3403 wl->active_scan = TRUE; /* we do active scan for specific scan per default */ 3404 wl->dongle_up = FALSE; /* dongle is not up yet */ 3405 wl_init_eq(wl); 3406 if (unlikely((err = wl_init_priv_mem(wl)))) 3407 return err; 3408 if (unlikely(wl_create_event_handler(wl))) 3409 return -ENOMEM; 3410 wl_init_eloop_handler(&wl->el); 3411 mutex_init(&wl->usr_sync); 3412 if (unlikely((err = wl_init_iscan(wl)))) 3413 return err; 3414 wl_init_fw(wl->fw); 3415 wl_init_conf(wl->conf); 3416 wl_init_prof(wl->profile); 3417 wl_link_down(wl); 3418 #ifdef WL_CFG80211_BACKTRACE 3419 WL_DBG(("Out\n")); 3420 #endif 3421 3422 return err; 3423 } 3424 3425 static void 3426 wl_deinit_priv(struct wl_priv *wl) 3427 { 3428 #ifdef WL_CFG80211_BACKTRACE 3429 WL_DBG(("In\n")); 3430 #endif 3431 wl_destroy_event_handler(wl); 3432 wl->dongle_up = FALSE; /* dongle down */ 3433 wl_flush_eq(wl); 3434 wl_link_down(wl); 3435 wl_term_iscan(wl); 3436 wl_deinit_priv_mem(wl); 3437 #ifdef WL_CFG80211_BACKTRACE 3438 WL_DBG(("Out\n")); 3439 #endif 3440 } 3441 3442 int32 3443 wl_cfg80211_attach(struct net_device *ndev, void *data) 3444 { 3445 struct wireless_dev *wdev; 3446 struct wl_priv *wl; 3447 struct wl_iface *ci; 3448 int32 err = 0; 3449 3450 #ifdef WL_CFG80211_BACKTRACE 3451 WL_DBG(("In\n")); 3452 #endif 3453 if (unlikely(!ndev)) { 3454 WL_ERR(("ndev is invaild\n")); 3455 return -ENODEV; 3456 } 3457 wl_cfg80211_dev = kzalloc(sizeof(struct wl_dev), GFP_KERNEL); 3458 if (unlikely(!wl_cfg80211_dev)) { 3459 WL_ERR(("wl_cfg80211_dev is invalid\n")); 3460 return -ENOMEM; 3461 } 3462 WL_DBG(("func %p\n", wl_sdio_func())); 3463 #ifndef WL_CFG80211_LOCALTEST 3464 wdev = wl_alloc_wdev(sizeof(struct wl_iface), &wl_sdio_func()->dev); 3465 #else 3466 wdev = wl_alloc_wdev(sizeof(struct wl_iface), NULL); 3467 #endif 3468 if (unlikely(IS_ERR(wdev))) 3469 return -ENOMEM; 3470 3471 wdev->iftype = wl_mode_to_nl80211_iftype(WL_MODE_BSS); 3472 wl = wdev_to_wl(wdev); 3473 wl->wdev = wdev; 3474 wl->pub = data; 3475 ci = (struct wl_iface *)wl_to_ci(wl); 3476 ci->wl = wl; 3477 ndev->ieee80211_ptr = wdev; 3478 SET_NETDEV_DEV(ndev, wiphy_dev(wdev->wiphy)); 3479 wdev->netdev = ndev; 3480 if (unlikely((err = wl_init_priv(wl)))) { 3481 WL_ERR(("Failed to init iwm_priv (%d)\n", err)); 3482 goto cfg80211_attach_out; 3483 } 3484 wl_set_drvdata(wl_cfg80211_dev, ci); 3485 set_bit(WL_STATUS_READY, &wl->status); 3486 #ifdef WL_CFG80211_BACKTRACE 3487 WL_DBG(("Out\n")); 3488 #endif 3489 3490 return err; 3491 3492 cfg80211_attach_out: 3493 wl_free_wdev(wl); 3494 return err; 3495 } 3496 3497 void 3498 wl_cfg80211_detach(void) 3499 { 3500 struct wl_priv *wl; 3501 3502 #ifdef WL_CFG80211_BACKTRACE 3503 WL_DBG(("In\n")); 3504 #endif 3505 wl = WL_PRIV_GET(); 3506 3507 wl_deinit_priv(wl); 3508 wl_free_wdev(wl); 3509 wl_set_drvdata(wl_cfg80211_dev, NULL); 3510 kfree(wl_cfg80211_dev); 3511 wl_cfg80211_dev = NULL; 3512 wl_clear_sdio_func(); 3513 #ifdef WL_CFG80211_BACKTRACE 3514 WL_DBG(("Out\n")); 3515 #endif 3516 } 3517 3518 static void 3519 wl_wakeup_event(struct wl_priv *wl) 3520 { 3521 up(&wl->event_sync); 3522 } 3523 3524 static int32 3525 wl_event_handler(void *data) 3526 { 3527 struct wl_priv *wl = (struct wl_priv *)data; 3528 struct sched_param param = { .sched_priority = MAX_RT_PRIO-1 }; 3529 struct wl_event_q *e; 3530 3531 #ifdef WL_CFG80211_BACKTRACE 3532 WL_DBG(("In\n")); 3533 #endif 3534 sched_setscheduler(current, SCHED_FIFO, ¶m); 3535 while (likely(!down_interruptible(&wl->event_sync))) { 3536 if (unlikely(!(e = wl_deq_event(wl)))) { 3537 WL_ERR(("eqeue empty..\n")); 3538 BUG(); 3539 } 3540 WL_DBG(("event type (%d)\n", e->etype)); 3541 if (wl->el.handler[e->etype]) { 3542 wl->el.handler[e->etype](wl, wl_to_ndev(wl), &e->emsg, e->edata); 3543 } else { 3544 WL_DBG(("Unknown Event (%d): ignoring\n", e->etype)); 3545 } 3546 wl_put_event(e); 3547 } 3548 complete_and_exit(&wl->event_exit, 0); 3549 #ifdef WL_CFG80211_BACKTRACE 3550 WL_DBG(("Out\n")); 3551 #endif 3552 } 3553 3554 void 3555 wl_cfg80211_event(struct net_device *ndev, const wl_event_msg_t *e, void* data) 3556 { 3557 uint32 event_type = ntoh32(e->event_type); 3558 struct wl_priv *wl = ndev_to_wl(ndev); 3559 #if (WL_DBG_LEVEL > 0) 3560 int8 *estr = (event_type <= sizeof(wl_dbg_estr)/WL_DBG_ESTR_MAX-1) ? 3561 wl_dbg_estr[event_type] : (int8 *)"Unknown"; 3562 #endif /* (WL_DBG_LEVEL > 0) */ 3563 WL_DBG(("event_type (%d):""WLC_E_""%s\n", event_type, estr)); 3564 if (likely(!wl_enq_event(wl, event_type, e, data))) 3565 wl_wakeup_event(wl); 3566 } 3567 3568 static void 3569 wl_init_eq(struct wl_priv *wl) 3570 { 3571 wl_init_eq_lock(wl); 3572 INIT_LIST_HEAD(&wl->eq_list); 3573 } 3574 3575 static void 3576 wl_flush_eq(struct wl_priv *wl) 3577 { 3578 struct wl_event_q *e; 3579 3580 wl_lock_eq(wl); 3581 while (!list_empty(&wl->eq_list)) { 3582 e = list_first_entry(&wl->eq_list, struct wl_event_q, eq_list); 3583 list_del(&e->eq_list); 3584 kfree(e); 3585 } 3586 wl_unlock_eq(wl); 3587 } 3588 3589 /* 3590 * retrieve first queued event from head 3591 */ 3592 3593 static struct wl_event_q * 3594 wl_deq_event(struct wl_priv *wl) 3595 { 3596 struct wl_event_q *e = NULL; 3597 3598 wl_lock_eq(wl); 3599 if (likely(!list_empty(&wl->eq_list))) { 3600 e = list_first_entry(&wl->eq_list, struct wl_event_q, eq_list); 3601 list_del(&e->eq_list); 3602 } 3603 wl_unlock_eq(wl); 3604 3605 return e; 3606 } 3607 3608 /* 3609 ** push event to tail of the queue 3610 */ 3611 3612 static int32 3613 wl_enq_event(struct wl_priv *wl, uint32 event, const wl_event_msg_t *msg, void *data) 3614 { 3615 struct wl_event_q *e; 3616 int32 err = 0; 3617 3618 if (unlikely(!(e = kzalloc(sizeof(struct wl_event_q), GFP_KERNEL)))) { 3619 WL_ERR(("event alloc failed\n")); 3620 return -ENOMEM; 3621 } 3622 3623 e->etype = event; 3624 memcpy(&e->emsg, msg, sizeof(wl_event_msg_t)); 3625 if (data) { 3626 } 3627 wl_lock_eq(wl); 3628 list_add_tail(&e->eq_list, &wl->eq_list); 3629 wl_unlock_eq(wl); 3630 3631 return err; 3632 } 3633 3634 static void 3635 wl_put_event(struct wl_event_q *e) 3636 { 3637 kfree(e); 3638 } 3639 3640 void 3641 wl_cfg80211_sdio_func(void *func) 3642 { 3643 cfg80211_sdio_func = (struct sdio_func *)func; 3644 } 3645 3646 static void 3647 wl_clear_sdio_func(void) 3648 { 3649 cfg80211_sdio_func = NULL; 3650 } 3651 3652 3653 static struct sdio_func * 3654 wl_sdio_func(void) 3655 { 3656 return cfg80211_sdio_func; 3657 } 3658 3659 static int32 3660 wl_dongle_mode(struct net_device *ndev, int32 iftype) 3661 { 3662 int32 infra = 0; 3663 int32 ap = 0; 3664 int32 err = 0; 3665 3666 switch (iftype) { 3667 case NL80211_IFTYPE_MONITOR: 3668 case NL80211_IFTYPE_WDS: 3669 WL_ERR(("type (%d) : currently we do not support this mode\n", iftype)); 3670 err = -EINVAL; 3671 return err; 3672 case NL80211_IFTYPE_ADHOC: 3673 break; 3674 case NL80211_IFTYPE_STATION: 3675 infra = 1; 3676 break; 3677 default: 3678 err = -EINVAL; 3679 WL_ERR(("invalid type (%d)\n", iftype)); 3680 return err; 3681 } 3682 infra = htod32(infra); 3683 ap = htod32(ap); 3684 WL_DBG(("%s ap (%d), infra (%d)\n", ndev->name, ap, infra)); 3685 if (unlikely(err = wl_dev_ioctl(ndev, WLC_SET_INFRA, &infra, sizeof(infra))) || 3686 unlikely(err = wl_dev_ioctl(ndev, WLC_SET_AP, &ap, sizeof(ap)))) { 3687 WL_ERR(("WLC_SET_INFRA error (%d)\n", err)); 3688 return err; 3689 } 3690 3691 return -EINPROGRESS; 3692 } 3693 3694 #ifndef EMBEDDED_PLATFORM 3695 static int32 3696 wl_dongle_country(struct net_device *ndev, uint8 ccode) 3697 { 3698 3699 int32 err = 0; 3700 3701 3702 return err; 3703 } 3704 3705 static int32 3706 wl_dongle_up(struct net_device *ndev, uint32 up) 3707 { 3708 int32 err = 0; 3709 3710 #ifdef WL_CFG80211_BACKTRACE 3711 WL_DBG(("In\n")); 3712 #endif 3713 if (unlikely(err = wl_dev_ioctl(ndev, WLC_UP, &up, sizeof(up)))) { 3714 WL_ERR(("WLC_UP error (%d)\n", err)); 3715 } 3716 #ifdef WL_CFG80211_BACKTRACE 3717 WL_DBG(("Out\n")); 3718 #endif 3719 return err; 3720 } 3721 3722 static int32 3723 wl_dongle_power(struct net_device *ndev, uint32 power_mode) 3724 { 3725 int32 err = 0; 3726 3727 if (unlikely(err = wl_dev_ioctl(ndev, WLC_SET_PM, &power_mode, sizeof(power_mode)))) { 3728 WL_ERR(("WLC_SET_PM error (%d)\n", err)); 3729 } 3730 return err; 3731 } 3732 3733 static int32 3734 wl_dongle_glom(struct net_device *ndev, uint32 glom, uint32 dongle_align) 3735 { 3736 int8 iovbuf[WL_EVENTING_MASK_LEN + 12]; /* Room for "event_msgs" + '\0' + bitvec */ 3737 int32 err = 0; 3738 3739 /* Match Host and Dongle rx alignment */ 3740 bcm_mkiovar("bus:txglomalign", (char *)&dongle_align, 4, iovbuf, sizeof(iovbuf)); 3741 if (unlikely(err = wl_dev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf)))) { 3742 WL_ERR(("txglomalign error (%d)\n", err)); 3743 goto dongle_glom_out; 3744 } 3745 /* disable glom option per default */ 3746 bcm_mkiovar("bus:txglom", (char *)&glom, 4, iovbuf, sizeof(iovbuf)); 3747 if (unlikely(err = wl_dev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf)))) { 3748 WL_ERR(("txglom error (%d)\n", err)); 3749 goto dongle_glom_out; 3750 } 3751 dongle_glom_out : 3752 return err; 3753 } 3754 3755 static int32 3756 wl_dongle_roam(struct net_device *ndev, uint32 roamvar, uint32 bcn_timeout) 3757 { 3758 int8 iovbuf[WL_EVENTING_MASK_LEN + 12]; /* Room for "event_msgs" + '\0' + bitvec */ 3759 int32 err = 0; 3760 3761 /* Setup timeout if Beacons are lost and roam is off to report link down */ 3762 if (roamvar) { 3763 bcm_mkiovar("bcn_timeout", (char *)&bcn_timeout, 4, iovbuf, sizeof(iovbuf)); 3764 if (unlikely(err = wl_dev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf)))) { 3765 WL_ERR(("bcn_timeout error (%d)\n", err)); 3766 goto dongle_rom_out; 3767 } 3768 } 3769 /* Enable/Disable built-in roaming to allow supplicant to take care of roaming */ 3770 bcm_mkiovar("roam_off", (char *)&roamvar, 4, iovbuf, sizeof(iovbuf)); 3771 if (unlikely(err = wl_dev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf)))) { 3772 WL_ERR(("roam_off error (%d)\n", err)); 3773 goto dongle_rom_out; 3774 } 3775 dongle_rom_out : 3776 return err; 3777 } 3778 3779 static int32 3780 wl_dongle_eventmsg(struct net_device *ndev) 3781 { 3782 3783 int8 iovbuf[WL_EVENTING_MASK_LEN + 12]; /* Room for "event_msgs" + '\0' + bitvec */ 3784 int8 eventmask[WL_EVENTING_MASK_LEN]; 3785 int32 err = 0; 3786 3787 /* Setup event_msgs */ 3788 bcm_mkiovar("event_msgs", eventmask, WL_EVENTING_MASK_LEN, iovbuf, sizeof(iovbuf)); 3789 if (unlikely(err = wl_dev_ioctl(ndev, WLC_GET_VAR, iovbuf, sizeof(iovbuf)))) { 3790 WL_ERR(("Get event_msgs error (%d)\n", err)); 3791 goto dongle_eventmsg_out; 3792 } 3793 memcpy(eventmask, iovbuf, WL_EVENTING_MASK_LEN); 3794 3795 setbit(eventmask, WLC_E_SET_SSID); 3796 setbit(eventmask, WLC_E_PRUNE); 3797 setbit(eventmask, WLC_E_AUTH); 3798 setbit(eventmask, WLC_E_REASSOC); 3799 setbit(eventmask, WLC_E_REASSOC_IND); 3800 setbit(eventmask, WLC_E_DEAUTH_IND); 3801 setbit(eventmask, WLC_E_DISASSOC_IND); 3802 setbit(eventmask, WLC_E_DISASSOC); 3803 setbit(eventmask, WLC_E_JOIN); 3804 setbit(eventmask, WLC_E_ASSOC_IND); 3805 setbit(eventmask, WLC_E_PSK_SUP); 3806 setbit(eventmask, WLC_E_LINK); 3807 setbit(eventmask, WLC_E_NDIS_LINK); 3808 setbit(eventmask, WLC_E_MIC_ERROR); 3809 setbit(eventmask, WLC_E_PMKID_CACHE); 3810 setbit(eventmask, WLC_E_TXFAIL); 3811 setbit(eventmask, WLC_E_JOIN_START); 3812 setbit(eventmask, WLC_E_SCAN_COMPLETE); 3813 3814 bcm_mkiovar("event_msgs", eventmask, WL_EVENTING_MASK_LEN, iovbuf, sizeof(iovbuf)); 3815 if (unlikely(err = wl_dev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf)))) { 3816 WL_ERR(("Set event_msgs error (%d)\n", err)); 3817 goto dongle_eventmsg_out; 3818 } 3819 3820 dongle_eventmsg_out : 3821 return err; 3822 } 3823 3824 static int32 3825 wl_dongle_scantime(struct net_device *ndev, int32 scan_assoc_time, int32 scan_unassoc_time) 3826 { 3827 int32 err = 0; 3828 3829 if ((err = wl_dev_ioctl(ndev, WLC_SET_SCAN_CHANNEL_TIME, &scan_assoc_time, 3830 sizeof(scan_assoc_time)))) { 3831 if (err == -EOPNOTSUPP) { 3832 WL_INFO(("Scan assoc time is not supported\n")); 3833 } else { 3834 WL_ERR(("Scan assoc time error (%d)\n", err)); 3835 } 3836 goto dongle_scantime_out; 3837 } 3838 if ((err = wl_dev_ioctl(ndev, WLC_SET_SCAN_UNASSOC_TIME, &scan_unassoc_time, 3839 sizeof(scan_unassoc_time)))) { 3840 if (err == -EOPNOTSUPP) { 3841 WL_INFO(("Scan unassoc time is not supported\n")); 3842 } else { 3843 WL_ERR(("Scan unassoc time error (%d)\n", err)); 3844 } 3845 goto dongle_scantime_out; 3846 } 3847 3848 dongle_scantime_out : 3849 return err; 3850 } 3851 3852 static int32 3853 wl_dongle_offload(struct net_device *ndev, int32 arpoe, int32 arp_ol) 3854 { 3855 int8 iovbuf[WL_EVENTING_MASK_LEN + 12]; /* Room for "event_msgs" + '\0' + bitvec */ 3856 int32 err = 0; 3857 3858 /* Set ARP offload */ 3859 bcm_mkiovar("arpoe", (char *)&arpoe, 4, iovbuf, sizeof(iovbuf)); 3860 if ((err = wl_dev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf)))) { 3861 if (err == -EOPNOTSUPP) { 3862 WL_INFO(("arpoe is not supported\n")); 3863 } else { 3864 WL_ERR(("arpoe error (%d)\n", err)); 3865 } 3866 goto dongle_offload_out; 3867 } 3868 bcm_mkiovar("arp_ol", (char *)&arp_ol, 4, iovbuf, sizeof(iovbuf)); 3869 if ((err = wl_dev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf)))) { 3870 if (err == -EOPNOTSUPP) { 3871 WL_INFO(("arp_ol is not supported\n")); 3872 } else { 3873 WL_ERR(("arp_ol error (%d)\n", err)); 3874 } 3875 goto dongle_offload_out; 3876 } 3877 3878 dongle_offload_out : 3879 return err; 3880 } 3881 3882 static int32 3883 wl_pattern_atoh(int8 *src, int8 *dst) 3884 { 3885 #define strtoul(nptr, endptr, base) bcm_strtoul((nptr), (endptr), (base)) 3886 int i; 3887 if (strncmp(src, "0x", 2) != 0 && 3888 strncmp(src, "0X", 2) != 0) { 3889 WL_ERR(("Mask invalid format. Needs to start with 0x\n")); 3890 return -1; 3891 } 3892 src = src + 2; /* Skip past 0x */ 3893 if (strlen(src) % 2 != 0) { 3894 WL_ERR(("Mask invalid format. Needs to be of even length\n")); 3895 return -1; 3896 } 3897 for (i = 0; *src != '\0'; i++) { 3898 char num[3]; 3899 strncpy(num, src, 2); 3900 num[2] = '\0'; 3901 dst[i] = (uint8)strtoul(num, NULL, 16); 3902 src += 2; 3903 } 3904 return i; 3905 } 3906 3907 static int32 3908 wl_dongle_filter(struct net_device *ndev, uint32 filter_mode) 3909 { 3910 int8 iovbuf[WL_EVENTING_MASK_LEN + 12]; /* Room for "event_msgs" + '\0' + bitvec */ 3911 const int8 *str; 3912 struct wl_pkt_filter pkt_filter; 3913 struct wl_pkt_filter *pkt_filterp; 3914 int32 buf_len; 3915 int32 str_len; 3916 uint32 mask_size; 3917 uint32 pattern_size; 3918 int8 buf[256]; 3919 int32 err = 0; 3920 3921 /* add a default packet filter pattern */ 3922 str = "pkt_filter_add"; 3923 str_len = strlen(str); 3924 strncpy(buf, str, str_len); 3925 buf[ str_len ] = '\0'; 3926 buf_len = str_len + 1; 3927 3928 pkt_filterp = (struct wl_pkt_filter *) (buf + str_len + 1); 3929 3930 /* Parse packet filter id. */ 3931 pkt_filter.id = htod32(100); 3932 3933 /* Parse filter polarity. */ 3934 pkt_filter.negate_match = htod32(0); 3935 3936 /* Parse filter type. */ 3937 pkt_filter.type = htod32(0); 3938 3939 /* Parse pattern filter offset. */ 3940 pkt_filter.u.pattern.offset = htod32(0); 3941 3942 /* Parse pattern filter mask. */ 3943 mask_size = htod32(wl_pattern_atoh("0xff", 3944 (char *) pkt_filterp->u.pattern.mask_and_pattern)); 3945 3946 /* Parse pattern filter pattern. */ 3947 pattern_size = htod32(wl_pattern_atoh("0x00", 3948 (char *) &pkt_filterp->u.pattern.mask_and_pattern[mask_size])); 3949 3950 if (mask_size != pattern_size) { 3951 WL_ERR(("Mask and pattern not the same size\n")); 3952 err = -EINVAL; 3953 goto dongle_filter_out; 3954 } 3955 3956 pkt_filter.u.pattern.size_bytes = mask_size; 3957 buf_len += WL_PKT_FILTER_FIXED_LEN; 3958 buf_len += (WL_PKT_FILTER_PATTERN_FIXED_LEN + 2 * mask_size); 3959 3960 /* Keep-alive attributes are set in local variable (keep_alive_pkt), and 3961 ** then memcpy'ed into buffer (keep_alive_pktp) since there is no 3962 ** guarantee that the buffer is properly aligned. 3963 */ 3964 memcpy((char *)pkt_filterp, &pkt_filter, 3965 WL_PKT_FILTER_FIXED_LEN + WL_PKT_FILTER_PATTERN_FIXED_LEN); 3966 3967 if ((err = wl_dev_ioctl(ndev, WLC_SET_VAR, buf, buf_len))) { 3968 if (err == -EOPNOTSUPP) { 3969 WL_INFO(("filter not supported\n")); 3970 } else { 3971 WL_ERR(("filter (%d)\n", err)); 3972 } 3973 goto dongle_filter_out; 3974 } 3975 3976 /* set mode to allow pattern */ 3977 bcm_mkiovar("pkt_filter_mode", (char *)&filter_mode, 4, iovbuf, sizeof(iovbuf)); 3978 if ((err = wl_dev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf)))) { 3979 if (err == -EOPNOTSUPP) { 3980 WL_INFO(("filter_mode not supported\n")); 3981 } else { 3982 WL_ERR(("filter_mode (%d)\n", err)); 3983 } 3984 goto dongle_filter_out; 3985 } 3986 3987 dongle_filter_out : 3988 return err; 3989 } 3990 #endif /* !EMBEDDED_PLATFORM */ 3991 3992 int32 3993 wl_config_dongle(struct wl_priv *wl, bool need_lock) 3994 { 3995 #ifndef DHD_SDALIGN 3996 #define DHD_SDALIGN 32 3997 #endif 3998 struct net_device *ndev; 3999 struct wireless_dev *wdev; 4000 int32 err = 0; 4001 4002 #ifdef WL_CFG80211_BACKTRACE 4003 WL_DBG(("In\n")); 4004 #endif 4005 if (wl->dongle_up) 4006 return err; 4007 4008 4009 ndev = wl_to_ndev(wl); 4010 wdev = ndev->ieee80211_ptr; 4011 if (need_lock) 4012 rtnl_lock(); 4013 4014 #ifndef EMBEDDED_PLATFORM 4015 if (unlikely((err = wl_dongle_up(ndev, 0)))) 4016 goto default_conf_out; 4017 if (unlikely((err = wl_dongle_country(ndev, 0)))) 4018 goto default_conf_out; 4019 if (unlikely((err = wl_dongle_power(ndev, PM_FAST)))) 4020 goto default_conf_out; 4021 if (unlikely((err = wl_dongle_glom(ndev, 0, DHD_SDALIGN)))) 4022 goto default_conf_out; 4023 if (unlikely((err = wl_dongle_roam(ndev, (wl->roam_on ? 0 : 1), 3)))) 4024 goto default_conf_out; 4025 if (unlikely((err = wl_dongle_eventmsg(ndev)))) 4026 goto default_conf_out; 4027 4028 wl_dongle_scantime(ndev, 40, 80); 4029 wl_dongle_offload(ndev, 1, 0xf); 4030 wl_dongle_filter(ndev, 1); 4031 #endif /* !EMBEDDED_PLATFORM */ 4032 4033 err = wl_dongle_mode(ndev, wdev->iftype); 4034 if (unlikely(err && err != -EINPROGRESS)) 4035 goto default_conf_out; 4036 if (unlikely((err = wl_dongle_probecap(wl)))) 4037 goto default_conf_out; 4038 4039 #ifdef WL_CFG80211_BACKTRACE 4040 WL_DBG(("Out\n")); 4041 #endif 4042 /* -EINPROGRESS: Call commit handler */ 4043 4044 default_conf_out : 4045 if (need_lock) 4046 rtnl_unlock(); 4047 4048 wl->dongle_up = TRUE; 4049 4050 return err; 4051 4052 } 4053 4054 static int32 4055 wl_update_wiphybands(struct wl_priv *wl) 4056 { 4057 struct wiphy *wiphy; 4058 int32 phy_list; 4059 int8 phy; 4060 int32 err = 0; 4061 4062 #ifdef WL_CFG80211_BACKTRACE 4063 WL_DBG(("In\n")); 4064 #endif 4065 if (unlikely(err = wl_dev_ioctl(wl_to_ndev(wl), WLC_GET_PHYLIST, &phy_list, 4066 sizeof(phy_list)))) { 4067 WL_ERR(("error (%d)\n", err)); 4068 return err; 4069 } 4070 4071 phy = ((char *)&phy_list)[1]; 4072 WL_DBG(("%c phy\n", phy)); 4073 if (phy == 'n' || phy == 'a') { 4074 wiphy = wl_to_wiphy(wl); 4075 wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_n; 4076 } 4077 #ifdef WL_CFG80211_BACKTRACE 4078 WL_DBG(("Out\n")); 4079 #endif 4080 4081 return err; 4082 } 4083 4084 static int32 4085 __wl_cfg80211_up(struct wl_priv *wl) 4086 { 4087 int32 err = 0; 4088 4089 if (unlikely(err = wl_config_dongle(wl, FALSE))) 4090 return err; 4091 4092 wl_invoke_iscan(wl); 4093 set_bit(WL_STATUS_READY, &wl->status); 4094 return err; 4095 } 4096 4097 static int32 4098 __wl_cfg80211_down(struct wl_priv *wl) 4099 { 4100 int32 err = 0; 4101 4102 /* Check if cfg80211 interface is already down */ 4103 if (!test_bit(WL_STATUS_READY, &wl->status)) 4104 return err; /* it is even not ready */ 4105 4106 set_bit(WL_STATUS_SCAN_ABORTING, &wl->status); 4107 wl_term_iscan(wl); 4108 if (wl->scan_request) { 4109 cfg80211_scan_done(wl->scan_request, TRUE); /* TRUE means abort */ 4110 wl->scan_request = NULL; 4111 } 4112 clear_bit(WL_STATUS_READY, &wl->status); 4113 clear_bit(WL_STATUS_SCANNING, &wl->status); 4114 clear_bit(WL_STATUS_SCAN_ABORTING, &wl->status); 4115 clear_bit(WL_STATUS_CONNECTED, &wl->status); 4116 4117 return err; 4118 } 4119 4120 int32 4121 wl_cfg80211_up(void) 4122 { 4123 struct wl_priv *wl; 4124 int32 err = 0; 4125 4126 #ifdef WL_CFG80211_BACKTRACE 4127 WL_DBG(("In\n")); 4128 #endif 4129 wl = WL_PRIV_GET(); 4130 mutex_lock(&wl->usr_sync); 4131 err = __wl_cfg80211_up(wl); 4132 mutex_unlock(&wl->usr_sync); 4133 #ifdef WL_CFG80211_BACKTRACE 4134 WL_DBG(("Out\n")); 4135 #endif 4136 4137 return err; 4138 } 4139 4140 int32 4141 wl_cfg80211_down(void) 4142 { 4143 struct wl_priv *wl; 4144 int32 err = 0; 4145 4146 #ifdef WL_CFG80211_BACKTRACE 4147 WL_DBG(("In\n")); 4148 #endif 4149 wl = WL_PRIV_GET(); 4150 mutex_lock(&wl->usr_sync); 4151 err = __wl_cfg80211_down(wl); 4152 mutex_unlock(&wl->usr_sync); 4153 #ifdef WL_CFG80211_BACKTRACE 4154 WL_DBG(("Out\n")); 4155 #endif 4156 4157 return err; 4158 } 4159 4160 static int32 4161 wl_dongle_probecap(struct wl_priv *wl) 4162 { 4163 int32 err = 0; 4164 4165 if (unlikely((err = wl_update_wiphybands(wl)))) 4166 return err; 4167 4168 return err; 4169 } 4170 4171 static void * 4172 wl_read_prof(struct wl_priv *wl, int32 item) 4173 { 4174 switch (item) { 4175 case WL_PROF_SEC: 4176 return &wl->profile->sec; 4177 case WL_PROF_ACT: 4178 return &wl->profile->active; 4179 case WL_PROF_BSSID: 4180 return &wl->profile->bssid; 4181 case WL_PROF_SSID: 4182 return &wl->profile->ssid; 4183 } 4184 WL_ERR(("invalid item (%d)\n", item)); 4185 return NULL; 4186 } 4187 4188 static int32 4189 wl_update_prof(struct wl_priv *wl, const wl_event_msg_t *e, void *data, int32 item) 4190 { 4191 int32 err = 0; 4192 struct wlc_ssid *ssid; 4193 4194 switch (item) { 4195 case WL_PROF_SSID: 4196 ssid = (wlc_ssid_t *)data; 4197 memset(wl->profile->ssid.SSID, 0, sizeof(wl->profile->ssid.SSID)); 4198 memcpy(wl->profile->ssid.SSID, ssid->SSID, ssid->SSID_len); 4199 wl->profile->ssid.SSID_len = ssid->SSID_len; 4200 break; 4201 case WL_PROF_BSSID: 4202 if (data) 4203 memcpy(wl->profile->bssid, data, ETHER_ADDR_LEN); 4204 else 4205 memset(wl->profile->bssid, 0, ETHER_ADDR_LEN); 4206 break; 4207 case WL_PROF_SEC: 4208 memcpy(&wl->profile->sec, data, sizeof(wl->profile->sec)); 4209 break; 4210 case WL_PROF_ACT: 4211 wl->profile->active = *(bool *)data; 4212 break; 4213 default : 4214 WL_ERR(("unsupported item (%d)\n", item)); 4215 err = -EOPNOTSUPP; 4216 break; 4217 } 4218 4219 return err; 4220 } 4221 4222 void 4223 wl_cfg80211_dbg_level(uint32 level) 4224 { 4225 wl_dbg_level = level; 4226 } 4227 4228 static bool 4229 wl_is_ibssmode(struct wl_priv *wl) 4230 { 4231 return (wl->conf->mode == WL_MODE_IBSS); 4232 } 4233 4234 static bool 4235 wl_is_ibssstarter(struct wl_priv *wl) 4236 { 4237 return wl->ibss_starter; 4238 } 4239 4240 static void 4241 wl_rst_ie(struct wl_priv *wl) 4242 { 4243 struct wl_ie *ie = wl_to_ie(wl); 4244 4245 ie->offset = 0; 4246 } 4247 4248 static int32 4249 wl_add_ie(struct wl_priv *wl, uint8 t, uint8 l, uint8 *v) 4250 { 4251 struct wl_ie *ie = wl_to_ie(wl); 4252 int32 err = 0; 4253 4254 if (unlikely(ie->offset + l + 2 > WL_TLV_INFO_MAX)) { 4255 WL_ERR(("ei crosses buffer boundary\n")); 4256 return -ENOSPC; 4257 } 4258 ie->buf[ie->offset] = t; 4259 ie->buf[ie->offset+1] = l; 4260 memcpy(&ie->buf[ie->offset+2], v, l); 4261 ie->offset += l+2; 4262 4263 return err; 4264 } 4265 4266 static int32 4267 wl_mrg_ie(struct wl_priv *wl, uint8 *ie_stream, uint16 ie_size) 4268 { 4269 struct wl_ie *ie = wl_to_ie(wl); 4270 int32 err = 0; 4271 4272 if (unlikely(ie->offset + ie_size > WL_TLV_INFO_MAX)) { 4273 WL_ERR(("ei_stream crosses buffer boundary\n")); 4274 return -ENOSPC; 4275 } 4276 memcpy(&ie->buf[ie->offset], ie_stream, ie_size); 4277 ie->offset += ie_size; 4278 4279 return err; 4280 } 4281 4282 static int32 4283 wl_cp_ie(struct wl_priv *wl, uint8 *dst, uint16 dst_size) 4284 { 4285 struct wl_ie *ie = wl_to_ie(wl); 4286 int32 err = 0; 4287 4288 if (unlikely(ie->offset > dst_size)) { 4289 WL_ERR(("dst_size is not enough\n")); 4290 return -ENOSPC; 4291 } 4292 memcpy(dst, &ie->buf[0], ie->offset); 4293 4294 return err; 4295 } 4296 4297 static uint32 4298 wl_get_ielen(struct wl_priv *wl) 4299 { 4300 struct wl_ie *ie = wl_to_ie(wl); 4301 4302 return ie->offset; 4303 } 4304 4305 static void 4306 wl_link_up(struct wl_priv *wl) 4307 { 4308 wl->link_up = TRUE; 4309 } 4310 4311 static void 4312 wl_link_down(struct wl_priv *wl) 4313 { 4314 struct wl_connect_info *conn_info = wl_to_conn(wl); 4315 4316 wl->link_up = FALSE; 4317 if (conn_info->req_ie) { 4318 kfree(conn_info->req_ie); 4319 conn_info->req_ie = NULL; 4320 } 4321 conn_info->req_ie_len = 0; 4322 if (conn_info->resp_ie) { 4323 kfree(conn_info->resp_ie); 4324 conn_info->resp_ie = NULL; 4325 } 4326 conn_info->resp_ie_len = 0; 4327 } 4328 4329 static void 4330 wl_lock_eq(struct wl_priv *wl) 4331 { 4332 spin_lock_irq(&wl->eq_lock); 4333 } 4334 4335 static void 4336 wl_unlock_eq(struct wl_priv *wl) 4337 { 4338 spin_unlock_irq(&wl->eq_lock); 4339 } 4340 4341 static void 4342 wl_init_eq_lock(struct wl_priv *wl) 4343 { 4344 spin_lock_init(&wl->eq_lock); 4345 } 4346 4347 static void 4348 wl_delay(uint32 ms) 4349 { 4350 if (ms < 1000 / HZ) { 4351 cond_resched(); 4352 mdelay(ms); 4353 } else { 4354 msleep(ms); 4355 } 4356 } 4357 4358 static void 4359 wl_set_drvdata(struct wl_dev *dev, void *data) 4360 { 4361 dev->driver_data = data; 4362 } 4363 4364 static void * 4365 wl_get_drvdata(struct wl_dev *dev) 4366 { 4367 return dev->driver_data; 4368 } 4369 4370 int32 4371 wl_cfg80211_read_fw(int8 *buf, uint32 size) 4372 { 4373 const struct firmware *fw_entry; 4374 struct wl_priv *wl; 4375 4376 #ifdef WL_CFG80211_BACKTRACE 4377 WL_DBG(("In : size (%d)\n", size)); 4378 #endif 4379 wl = WL_PRIV_GET(); 4380 4381 fw_entry = wl->fw->fw_entry; 4382 4383 if (fw_entry->size < wl->fw->ptr + size) { 4384 size = fw_entry->size - wl->fw->ptr; 4385 } 4386 memcpy(buf, &fw_entry->data[wl->fw->ptr], size); 4387 wl->fw->ptr += size; 4388 #ifdef WL_CFG80211_BACKTRACE 4389 WL_DBG(("Out : size (%d)\n", size)); 4390 #endif 4391 return size; 4392 } 4393 4394 void 4395 wl_cfg80211_release_fw(void) 4396 { 4397 struct wl_priv *wl; 4398 4399 #ifdef WL_CFG80211_BACKTRACE 4400 WL_DBG(("In\n")); 4401 #endif 4402 wl = WL_PRIV_GET(); 4403 release_firmware(wl->fw->fw_entry); 4404 wl->fw->ptr = 0; 4405 #ifdef WL_CFG80211_BACKTRACE 4406 WL_DBG(("Out\n")); 4407 #endif 4408 } 4409 4410 void * 4411 wl_cfg80211_request_fw(int8 *file_name) 4412 { 4413 struct wl_priv *wl; 4414 const struct firmware *fw_entry = NULL; 4415 int32 err = 0; 4416 4417 #ifdef WL_CFG80211_BACKTRACE 4418 WL_DBG(("In\n")); 4419 #endif 4420 WL_DBG(("file name : \"%s\"\n", file_name)); 4421 wl = WL_PRIV_GET(); 4422 4423 if (!test_bit(WL_FW_LOADING_DONE, &wl->fw->status)) { 4424 if (unlikely(err = request_firmware(&wl->fw->fw_entry, file_name, 4425 &wl_sdio_func()->dev))) { 4426 WL_ERR(("Could not download fw (%d)\n", err)); 4427 goto req_fw_out; 4428 } 4429 set_bit(WL_FW_LOADING_DONE, &wl->fw->status); 4430 fw_entry = wl->fw->fw_entry; 4431 if (fw_entry) { 4432 WL_DBG(("fw size (%d), data (%p)\n", fw_entry->size, fw_entry->data)); 4433 } 4434 } else if (!test_bit(WL_NVRAM_LOADING_DONE, &wl->fw->status)) { 4435 if (unlikely(err = request_firmware(&wl->fw->fw_entry, file_name, 4436 &wl_sdio_func()->dev))) { 4437 WL_ERR(("Could not download nvram (%d)\n", err)); 4438 goto req_fw_out; 4439 } 4440 set_bit(WL_NVRAM_LOADING_DONE, &wl->fw->status); 4441 fw_entry = wl->fw->fw_entry; 4442 if (fw_entry) { 4443 WL_DBG(("nvram size (%d), data (%p)\n", fw_entry->size, fw_entry->data)); 4444 } 4445 } else { 4446 WL_DBG(("Downloading already done. Nothing to do more\n")); 4447 err = -EPERM; 4448 } 4449 #ifdef WL_CFG80211_BACKTRACE 4450 WL_DBG(("Out\n")); 4451 #endif 4452 4453 req_fw_out: 4454 if (unlikely(err)) { 4455 return NULL; 4456 } 4457 wl->fw->ptr = 0; 4458 return (void *)fw_entry->data; 4459 } 4460 4461 int8 * 4462 wl_cfg80211_get_fwname(void) 4463 { 4464 struct wl_priv *wl; 4465 4466 #ifdef WL_CFG80211_BACKTRACE 4467 WL_DBG(("In\n")); 4468 #endif 4469 wl = WL_PRIV_GET(); 4470 strcpy(wl->fw->fw_name, WL_4329_FW_FILE); 4471 #ifdef WL_CFG80211_BACKTRACE 4472 WL_DBG(("Out\n")); 4473 #endif 4474 return wl->fw->fw_name; 4475 } 4476 4477 int8 * 4478 wl_cfg80211_get_nvramname(void) 4479 { 4480 struct wl_priv *wl; 4481 4482 #ifdef WL_CFG80211_BACKTRACE 4483 WL_DBG(("In\n")); 4484 #endif 4485 wl = WL_PRIV_GET(); 4486 strcpy(wl->fw->nvram_name, WL_4329_NVRAM_FILE); 4487 #ifdef WL_CFG80211_BACKTRACE 4488 WL_DBG(("Out\n")); 4489 #endif 4490 return wl->fw->nvram_name; 4491 } 4492