aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c')
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c3135
1 files changed, 2406 insertions, 729 deletions
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
index 50b5553b6964..c1abaa6db59e 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
@@ -28,6 +28,7 @@
28#include <linux/ieee80211.h> 28#include <linux/ieee80211.h>
29#include <linux/uaccess.h> 29#include <linux/uaccess.h>
30#include <net/cfg80211.h> 30#include <net/cfg80211.h>
31#include <net/netlink.h>
31 32
32#include <brcmu_utils.h> 33#include <brcmu_utils.h>
33#include <defs.h> 34#include <defs.h>
@@ -35,6 +36,58 @@
35#include "dhd.h" 36#include "dhd.h"
36#include "wl_cfg80211.h" 37#include "wl_cfg80211.h"
37 38
39#define BRCMF_SCAN_IE_LEN_MAX 2048
40#define BRCMF_PNO_VERSION 2
41#define BRCMF_PNO_TIME 30
42#define BRCMF_PNO_REPEAT 4
43#define BRCMF_PNO_FREQ_EXPO_MAX 3
44#define BRCMF_PNO_MAX_PFN_COUNT 16
45#define BRCMF_PNO_ENABLE_ADAPTSCAN_BIT 6
46#define BRCMF_PNO_HIDDEN_BIT 2
47#define BRCMF_PNO_WPA_AUTH_ANY 0xFFFFFFFF
48#define BRCMF_PNO_SCAN_COMPLETE 1
49#define BRCMF_PNO_SCAN_INCOMPLETE 0
50
51#define TLV_LEN_OFF 1 /* length offset */
52#define TLV_HDR_LEN 2 /* header length */
53#define TLV_BODY_OFF 2 /* body offset */
54#define TLV_OUI_LEN 3 /* oui id length */
55#define WPA_OUI "\x00\x50\xF2" /* WPA OUI */
56#define WPA_OUI_TYPE 1
57#define RSN_OUI "\x00\x0F\xAC" /* RSN OUI */
58#define WME_OUI_TYPE 2
59
60#define VS_IE_FIXED_HDR_LEN 6
61#define WPA_IE_VERSION_LEN 2
62#define WPA_IE_MIN_OUI_LEN 4
63#define WPA_IE_SUITE_COUNT_LEN 2
64
65#define WPA_CIPHER_NONE 0 /* None */
66#define WPA_CIPHER_WEP_40 1 /* WEP (40-bit) */
67#define WPA_CIPHER_TKIP 2 /* TKIP: default for WPA */
68#define WPA_CIPHER_AES_CCM 4 /* AES (CCM) */
69#define WPA_CIPHER_WEP_104 5 /* WEP (104-bit) */
70
71#define RSN_AKM_NONE 0 /* None (IBSS) */
72#define RSN_AKM_UNSPECIFIED 1 /* Over 802.1x */
73#define RSN_AKM_PSK 2 /* Pre-shared Key */
74#define RSN_CAP_LEN 2 /* Length of RSN capabilities */
75#define RSN_CAP_PTK_REPLAY_CNTR_MASK 0x000C
76
77#define VNDR_IE_CMD_LEN 4 /* length of the set command
78 * string :"add", "del" (+ NUL)
79 */
80#define VNDR_IE_COUNT_OFFSET 4
81#define VNDR_IE_PKTFLAG_OFFSET 8
82#define VNDR_IE_VSIE_OFFSET 12
83#define VNDR_IE_HDR_SIZE 12
84#define VNDR_IE_BEACON_FLAG 0x1
85#define VNDR_IE_PRBRSP_FLAG 0x2
86#define MAX_VNDR_IE_NUMBER 5
87
88#define DOT11_MGMT_HDR_LEN 24 /* d11 management header len */
89#define DOT11_BCN_PRB_FIXED_LEN 12 /* beacon/probe fixed length */
90
38#define BRCMF_ASSOC_PARAMS_FIXED_SIZE \ 91#define BRCMF_ASSOC_PARAMS_FIXED_SIZE \
39 (sizeof(struct brcmf_assoc_params_le) - sizeof(u16)) 92 (sizeof(struct brcmf_assoc_params_le) - sizeof(u16))
40 93
@@ -42,33 +95,12 @@ static const u8 ether_bcast[ETH_ALEN] = {255, 255, 255, 255, 255, 255};
42 95
43static u32 brcmf_dbg_level = WL_DBG_ERR; 96static u32 brcmf_dbg_level = WL_DBG_ERR;
44 97
45static void brcmf_set_drvdata(struct brcmf_cfg80211_dev *dev, void *data)
46{
47 dev->driver_data = data;
48}
49
50static void *brcmf_get_drvdata(struct brcmf_cfg80211_dev *dev)
51{
52 void *data = NULL;
53
54 if (dev)
55 data = dev->driver_data;
56 return data;
57}
58
59static
60struct brcmf_cfg80211_priv *brcmf_priv_get(struct brcmf_cfg80211_dev *cfg_dev)
61{
62 struct brcmf_cfg80211_iface *ci = brcmf_get_drvdata(cfg_dev);
63 return ci->cfg_priv;
64}
65
66static bool check_sys_up(struct wiphy *wiphy) 98static bool check_sys_up(struct wiphy *wiphy)
67{ 99{
68 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy); 100 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
69 if (!test_bit(WL_STATUS_READY, &cfg_priv->status)) { 101 if (!test_bit(WL_STATUS_READY, &cfg->status)) {
70 WL_INFO("device is not ready : status (%d)\n", 102 WL_INFO("device is not ready : status (%d)\n",
71 (int)cfg_priv->status); 103 (int)cfg->status);
72 return false; 104 return false;
73 } 105 }
74 return true; 106 return true;
@@ -256,6 +288,25 @@ struct brcmf_tlv {
256 u8 data[1]; 288 u8 data[1];
257}; 289};
258 290
291/* Vendor specific ie. id = 221, oui and type defines exact ie */
292struct brcmf_vs_tlv {
293 u8 id;
294 u8 len;
295 u8 oui[3];
296 u8 oui_type;
297};
298
299struct parsed_vndr_ie_info {
300 u8 *ie_ptr;
301 u32 ie_len; /* total length including id & length field */
302 struct brcmf_vs_tlv vndrie;
303};
304
305struct parsed_vndr_ies {
306 u32 count;
307 struct parsed_vndr_ie_info ie_info[MAX_VNDR_IE_NUMBER];
308};
309
259/* Quarter dBm units to mW 310/* Quarter dBm units to mW
260 * Table starts at QDBM_OFFSET, so the first entry is mW for qdBm=153 311 * Table starts at QDBM_OFFSET, so the first entry is mW for qdBm=153
261 * Table is offset so the last entry is largest mW value that fits in 312 * Table is offset so the last entry is largest mW value that fits in
@@ -353,6 +404,44 @@ brcmf_exec_dcmd_u32(struct net_device *ndev, u32 cmd, u32 *par)
353 return err; 404 return err;
354} 405}
355 406
407static s32
408brcmf_dev_iovar_setbuf_bsscfg(struct net_device *ndev, s8 *name,
409 void *param, s32 paramlen,
410 void *buf, s32 buflen, s32 bssidx)
411{
412 s32 err = -ENOMEM;
413 u32 len;
414
415 len = brcmf_c_mkiovar_bsscfg(name, param, paramlen,
416 buf, buflen, bssidx);
417 BUG_ON(!len);
418 if (len > 0)
419 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR, buf, len);
420 if (err)
421 WL_ERR("error (%d)\n", err);
422
423 return err;
424}
425
426static s32
427brcmf_dev_iovar_getbuf_bsscfg(struct net_device *ndev, s8 *name,
428 void *param, s32 paramlen,
429 void *buf, s32 buflen, s32 bssidx)
430{
431 s32 err = -ENOMEM;
432 u32 len;
433
434 len = brcmf_c_mkiovar_bsscfg(name, param, paramlen,
435 buf, buflen, bssidx);
436 BUG_ON(!len);
437 if (len > 0)
438 err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_VAR, buf, len);
439 if (err)
440 WL_ERR("error (%d)\n", err);
441
442 return err;
443}
444
356static void convert_key_from_CPU(struct brcmf_wsec_key *key, 445static void convert_key_from_CPU(struct brcmf_wsec_key *key,
357 struct brcmf_wsec_key_le *key_le) 446 struct brcmf_wsec_key_le *key_le)
358{ 447{
@@ -367,16 +456,22 @@ static void convert_key_from_CPU(struct brcmf_wsec_key *key,
367 memcpy(key_le->ea, key->ea, sizeof(key->ea)); 456 memcpy(key_le->ea, key->ea, sizeof(key->ea));
368} 457}
369 458
370static int send_key_to_dongle(struct net_device *ndev, 459static int
371 struct brcmf_wsec_key *key) 460send_key_to_dongle(struct brcmf_cfg80211_info *cfg, s32 bssidx,
461 struct net_device *ndev, struct brcmf_wsec_key *key)
372{ 462{
373 int err; 463 int err;
374 struct brcmf_wsec_key_le key_le; 464 struct brcmf_wsec_key_le key_le;
375 465
376 convert_key_from_CPU(key, &key_le); 466 convert_key_from_CPU(key, &key_le);
377 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_KEY, &key_le, sizeof(key_le)); 467
468 err = brcmf_dev_iovar_setbuf_bsscfg(ndev, "wsec_key", &key_le,
469 sizeof(key_le),
470 cfg->extra_buf,
471 WL_EXTRA_BUF_MAX, bssidx);
472
378 if (err) 473 if (err)
379 WL_ERR("WLC_SET_KEY error (%d)\n", err); 474 WL_ERR("wsec_key error (%d)\n", err);
380 return err; 475 return err;
381} 476}
382 477
@@ -385,14 +480,12 @@ brcmf_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev,
385 enum nl80211_iftype type, u32 *flags, 480 enum nl80211_iftype type, u32 *flags,
386 struct vif_params *params) 481 struct vif_params *params)
387{ 482{
388 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy); 483 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
389 struct wireless_dev *wdev;
390 s32 infra = 0; 484 s32 infra = 0;
485 s32 ap = 0;
391 s32 err = 0; 486 s32 err = 0;
392 487
393 WL_TRACE("Enter\n"); 488 WL_TRACE("Enter, ndev=%p, type=%d\n", ndev, type);
394 if (!check_sys_up(wiphy))
395 return -EIO;
396 489
397 switch (type) { 490 switch (type) {
398 case NL80211_IFTYPE_MONITOR: 491 case NL80211_IFTYPE_MONITOR:
@@ -401,29 +494,44 @@ brcmf_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev,
401 type); 494 type);
402 return -EOPNOTSUPP; 495 return -EOPNOTSUPP;
403 case NL80211_IFTYPE_ADHOC: 496 case NL80211_IFTYPE_ADHOC:
404 cfg_priv->conf->mode = WL_MODE_IBSS; 497 cfg->conf->mode = WL_MODE_IBSS;
405 infra = 0; 498 infra = 0;
406 break; 499 break;
407 case NL80211_IFTYPE_STATION: 500 case NL80211_IFTYPE_STATION:
408 cfg_priv->conf->mode = WL_MODE_BSS; 501 cfg->conf->mode = WL_MODE_BSS;
409 infra = 1; 502 infra = 1;
410 break; 503 break;
504 case NL80211_IFTYPE_AP:
505 cfg->conf->mode = WL_MODE_AP;
506 ap = 1;
507 break;
411 default: 508 default:
412 err = -EINVAL; 509 err = -EINVAL;
413 goto done; 510 goto done;
414 } 511 }
415 512
416 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_INFRA, &infra); 513 if (ap) {
417 if (err) { 514 set_bit(WL_STATUS_AP_CREATING, &cfg->status);
418 WL_ERR("WLC_SET_INFRA error (%d)\n", err); 515 if (!cfg->ap_info)
419 err = -EAGAIN; 516 cfg->ap_info = kzalloc(sizeof(*cfg->ap_info),
517 GFP_KERNEL);
518 if (!cfg->ap_info) {
519 err = -ENOMEM;
520 goto done;
521 }
522 WL_INFO("IF Type = AP\n");
420 } else { 523 } else {
421 wdev = ndev->ieee80211_ptr; 524 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_INFRA, &infra);
422 wdev->iftype = type; 525 if (err) {
526 WL_ERR("WLC_SET_INFRA error (%d)\n", err);
527 err = -EAGAIN;
528 goto done;
529 }
530 WL_INFO("IF Type = %s\n",
531 (cfg->conf->mode == WL_MODE_IBSS) ?
532 "Adhoc" : "Infra");
423 } 533 }
424 534 ndev->ieee80211_ptr->iftype = type;
425 WL_INFO("IF Type = %s\n",
426 (cfg_priv->conf->mode == WL_MODE_IBSS) ? "Adhoc" : "Infra");
427 535
428done: 536done:
429 WL_TRACE("Exit\n"); 537 WL_TRACE("Exit\n");
@@ -474,12 +582,55 @@ brcmf_dev_intvar_get(struct net_device *ndev, s8 *name, s32 *retval)
474 return err; 582 return err;
475} 583}
476 584
585static s32
586brcmf_dev_intvar_set_bsscfg(struct net_device *ndev, s8 *name, u32 val,
587 s32 bssidx)
588{
589 s8 buf[BRCMF_DCMD_SMLEN];
590 __le32 val_le;
591
592 val_le = cpu_to_le32(val);
593
594 return brcmf_dev_iovar_setbuf_bsscfg(ndev, name, &val_le,
595 sizeof(val_le), buf, sizeof(buf),
596 bssidx);
597}
598
599static s32
600brcmf_dev_intvar_get_bsscfg(struct net_device *ndev, s8 *name, s32 *val,
601 s32 bssidx)
602{
603 s8 buf[BRCMF_DCMD_SMLEN];
604 s32 err;
605 __le32 val_le;
606
607 memset(buf, 0, sizeof(buf));
608 err = brcmf_dev_iovar_getbuf_bsscfg(ndev, name, val, sizeof(*val), buf,
609 sizeof(buf), bssidx);
610 if (err == 0) {
611 memcpy(&val_le, buf, sizeof(val_le));
612 *val = le32_to_cpu(val_le);
613 }
614 return err;
615}
616
617
618/*
619 * For now brcmf_find_bssidx will return 0. Once p2p gets implemented this
620 * should return the ndev matching bssidx.
621 */
622static s32
623brcmf_find_bssidx(struct brcmf_cfg80211_info *cfg, struct net_device *ndev)
624{
625 return 0;
626}
627
477static void brcmf_set_mpc(struct net_device *ndev, int mpc) 628static void brcmf_set_mpc(struct net_device *ndev, int mpc)
478{ 629{
479 s32 err = 0; 630 s32 err = 0;
480 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev); 631 struct brcmf_cfg80211_info *cfg = ndev_to_cfg(ndev);
481 632
482 if (test_bit(WL_STATUS_READY, &cfg_priv->status)) { 633 if (test_bit(WL_STATUS_READY, &cfg->status)) {
483 err = brcmf_dev_intvar_set(ndev, "mpc", mpc); 634 err = brcmf_dev_intvar_set(ndev, "mpc", mpc);
484 if (err) { 635 if (err) {
485 WL_ERR("fail to set mpc\n"); 636 WL_ERR("fail to set mpc\n");
@@ -489,8 +640,8 @@ static void brcmf_set_mpc(struct net_device *ndev, int mpc)
489 } 640 }
490} 641}
491 642
492static void wl_iscan_prep(struct brcmf_scan_params_le *params_le, 643static void brcmf_iscan_prep(struct brcmf_scan_params_le *params_le,
493 struct brcmf_ssid *ssid) 644 struct brcmf_ssid *ssid)
494{ 645{
495 memcpy(params_le->bssid, ether_bcast, ETH_ALEN); 646 memcpy(params_le->bssid, ether_bcast, ETH_ALEN);
496 params_le->bss_type = DOT11_BSSTYPE_ANY; 647 params_le->bss_type = DOT11_BSSTYPE_ANY;
@@ -546,7 +697,7 @@ brcmf_run_iscan(struct brcmf_cfg80211_iscan_ctrl *iscan,
546 return -ENOMEM; 697 return -ENOMEM;
547 BUG_ON(params_size >= BRCMF_DCMD_SMLEN); 698 BUG_ON(params_size >= BRCMF_DCMD_SMLEN);
548 699
549 wl_iscan_prep(&params->params_le, ssid); 700 brcmf_iscan_prep(&params->params_le, ssid);
550 701
551 params->version = cpu_to_le32(BRCMF_ISCAN_REQ_VERSION); 702 params->version = cpu_to_le32(BRCMF_ISCAN_REQ_VERSION);
552 params->action = cpu_to_le16(action); 703 params->action = cpu_to_le16(action);
@@ -565,10 +716,10 @@ brcmf_run_iscan(struct brcmf_cfg80211_iscan_ctrl *iscan,
565 return err; 716 return err;
566} 717}
567 718
568static s32 brcmf_do_iscan(struct brcmf_cfg80211_priv *cfg_priv) 719static s32 brcmf_do_iscan(struct brcmf_cfg80211_info *cfg)
569{ 720{
570 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg_priv); 721 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg);
571 struct net_device *ndev = cfg_to_ndev(cfg_priv); 722 struct net_device *ndev = cfg_to_ndev(cfg);
572 struct brcmf_ssid ssid; 723 struct brcmf_ssid ssid;
573 __le32 passive_scan; 724 __le32 passive_scan;
574 s32 err = 0; 725 s32 err = 0;
@@ -578,19 +729,19 @@ static s32 brcmf_do_iscan(struct brcmf_cfg80211_priv *cfg_priv)
578 729
579 iscan->state = WL_ISCAN_STATE_SCANING; 730 iscan->state = WL_ISCAN_STATE_SCANING;
580 731
581 passive_scan = cfg_priv->active_scan ? 0 : cpu_to_le32(1); 732 passive_scan = cfg->active_scan ? 0 : cpu_to_le32(1);
582 err = brcmf_exec_dcmd(cfg_to_ndev(cfg_priv), BRCMF_C_SET_PASSIVE_SCAN, 733 err = brcmf_exec_dcmd(cfg_to_ndev(cfg), BRCMF_C_SET_PASSIVE_SCAN,
583 &passive_scan, sizeof(passive_scan)); 734 &passive_scan, sizeof(passive_scan));
584 if (err) { 735 if (err) {
585 WL_ERR("error (%d)\n", err); 736 WL_ERR("error (%d)\n", err);
586 return err; 737 return err;
587 } 738 }
588 brcmf_set_mpc(ndev, 0); 739 brcmf_set_mpc(ndev, 0);
589 cfg_priv->iscan_kickstart = true; 740 cfg->iscan_kickstart = true;
590 err = brcmf_run_iscan(iscan, &ssid, BRCMF_SCAN_ACTION_START); 741 err = brcmf_run_iscan(iscan, &ssid, BRCMF_SCAN_ACTION_START);
591 if (err) { 742 if (err) {
592 brcmf_set_mpc(ndev, 1); 743 brcmf_set_mpc(ndev, 1);
593 cfg_priv->iscan_kickstart = false; 744 cfg->iscan_kickstart = false;
594 return err; 745 return err;
595 } 746 }
596 mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000); 747 mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000);
@@ -599,31 +750,31 @@ static s32 brcmf_do_iscan(struct brcmf_cfg80211_priv *cfg_priv)
599} 750}
600 751
601static s32 752static s32
602__brcmf_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev, 753brcmf_cfg80211_iscan(struct wiphy *wiphy, struct net_device *ndev,
603 struct cfg80211_scan_request *request, 754 struct cfg80211_scan_request *request,
604 struct cfg80211_ssid *this_ssid) 755 struct cfg80211_ssid *this_ssid)
605{ 756{
606 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev); 757 struct brcmf_cfg80211_info *cfg = ndev_to_cfg(ndev);
607 struct cfg80211_ssid *ssids; 758 struct cfg80211_ssid *ssids;
608 struct brcmf_cfg80211_scan_req *sr = cfg_priv->scan_req_int; 759 struct brcmf_cfg80211_scan_req *sr = cfg->scan_req_int;
609 __le32 passive_scan; 760 __le32 passive_scan;
610 bool iscan_req; 761 bool iscan_req;
611 bool spec_scan; 762 bool spec_scan;
612 s32 err = 0; 763 s32 err = 0;
613 u32 SSID_len; 764 u32 SSID_len;
614 765
615 if (test_bit(WL_STATUS_SCANNING, &cfg_priv->status)) { 766 if (test_bit(WL_STATUS_SCANNING, &cfg->status)) {
616 WL_ERR("Scanning already : status (%lu)\n", cfg_priv->status); 767 WL_ERR("Scanning already : status (%lu)\n", cfg->status);
617 return -EAGAIN; 768 return -EAGAIN;
618 } 769 }
619 if (test_bit(WL_STATUS_SCAN_ABORTING, &cfg_priv->status)) { 770 if (test_bit(WL_STATUS_SCAN_ABORTING, &cfg->status)) {
620 WL_ERR("Scanning being aborted : status (%lu)\n", 771 WL_ERR("Scanning being aborted : status (%lu)\n",
621 cfg_priv->status); 772 cfg->status);
622 return -EAGAIN; 773 return -EAGAIN;
623 } 774 }
624 if (test_bit(WL_STATUS_CONNECTING, &cfg_priv->status)) { 775 if (test_bit(WL_STATUS_CONNECTING, &cfg->status)) {
625 WL_ERR("Connecting : status (%lu)\n", 776 WL_ERR("Connecting : status (%lu)\n",
626 cfg_priv->status); 777 cfg->status);
627 return -EAGAIN; 778 return -EAGAIN;
628 } 779 }
629 780
@@ -632,7 +783,7 @@ __brcmf_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
632 if (request) { 783 if (request) {
633 /* scan bss */ 784 /* scan bss */
634 ssids = request->ssids; 785 ssids = request->ssids;
635 if (cfg_priv->iscan_on && (!ssids || !ssids->ssid_len)) 786 if (cfg->iscan_on && (!ssids || !ssids->ssid_len))
636 iscan_req = true; 787 iscan_req = true;
637 } else { 788 } else {
638 /* scan in ibss */ 789 /* scan in ibss */
@@ -640,10 +791,10 @@ __brcmf_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
640 ssids = this_ssid; 791 ssids = this_ssid;
641 } 792 }
642 793
643 cfg_priv->scan_request = request; 794 cfg->scan_request = request;
644 set_bit(WL_STATUS_SCANNING, &cfg_priv->status); 795 set_bit(WL_STATUS_SCANNING, &cfg->status);
645 if (iscan_req) { 796 if (iscan_req) {
646 err = brcmf_do_iscan(cfg_priv); 797 err = brcmf_do_iscan(cfg);
647 if (!err) 798 if (!err)
648 return err; 799 return err;
649 else 800 else
@@ -662,7 +813,7 @@ __brcmf_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
662 WL_SCAN("Broadcast scan\n"); 813 WL_SCAN("Broadcast scan\n");
663 } 814 }
664 815
665 passive_scan = cfg_priv->active_scan ? 0 : cpu_to_le32(1); 816 passive_scan = cfg->active_scan ? 0 : cpu_to_le32(1);
666 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_PASSIVE_SCAN, 817 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_PASSIVE_SCAN,
667 &passive_scan, sizeof(passive_scan)); 818 &passive_scan, sizeof(passive_scan));
668 if (err) { 819 if (err) {
@@ -687,8 +838,346 @@ __brcmf_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
687 return 0; 838 return 0;
688 839
689scan_out: 840scan_out:
690 clear_bit(WL_STATUS_SCANNING, &cfg_priv->status); 841 clear_bit(WL_STATUS_SCANNING, &cfg->status);
691 cfg_priv->scan_request = NULL; 842 cfg->scan_request = NULL;
843 return err;
844}
845
846static void brcmf_escan_prep(struct brcmf_scan_params_le *params_le,
847 struct cfg80211_scan_request *request)
848{
849 u32 n_ssids;
850 u32 n_channels;
851 s32 i;
852 s32 offset;
853 u16 chanspec;
854 u16 channel;
855 struct ieee80211_channel *req_channel;
856 char *ptr;
857 struct brcmf_ssid_le ssid_le;
858
859 memcpy(params_le->bssid, ether_bcast, ETH_ALEN);
860 params_le->bss_type = DOT11_BSSTYPE_ANY;
861 params_le->scan_type = 0;
862 params_le->channel_num = 0;
863 params_le->nprobes = cpu_to_le32(-1);
864 params_le->active_time = cpu_to_le32(-1);
865 params_le->passive_time = cpu_to_le32(-1);
866 params_le->home_time = cpu_to_le32(-1);
867 memset(&params_le->ssid_le, 0, sizeof(params_le->ssid_le));
868
869 /* if request is null exit so it will be all channel broadcast scan */
870 if (!request)
871 return;
872
873 n_ssids = request->n_ssids;
874 n_channels = request->n_channels;
875 /* Copy channel array if applicable */
876 WL_SCAN("### List of channelspecs to scan ### %d\n", n_channels);
877 if (n_channels > 0) {
878 for (i = 0; i < n_channels; i++) {
879 chanspec = 0;
880 req_channel = request->channels[i];
881 channel = ieee80211_frequency_to_channel(
882 req_channel->center_freq);
883 if (req_channel->band == IEEE80211_BAND_2GHZ)
884 chanspec |= WL_CHANSPEC_BAND_2G;
885 else
886 chanspec |= WL_CHANSPEC_BAND_5G;
887
888 if (req_channel->flags & IEEE80211_CHAN_NO_HT40) {
889 chanspec |= WL_CHANSPEC_BW_20;
890 chanspec |= WL_CHANSPEC_CTL_SB_NONE;
891 } else {
892 chanspec |= WL_CHANSPEC_BW_40;
893 if (req_channel->flags &
894 IEEE80211_CHAN_NO_HT40PLUS)
895 chanspec |= WL_CHANSPEC_CTL_SB_LOWER;
896 else
897 chanspec |= WL_CHANSPEC_CTL_SB_UPPER;
898 }
899
900 chanspec |= (channel & WL_CHANSPEC_CHAN_MASK);
901 WL_SCAN("Chan : %d, Channel spec: %x\n",
902 channel, chanspec);
903 params_le->channel_list[i] = cpu_to_le16(chanspec);
904 }
905 } else {
906 WL_SCAN("Scanning all channels\n");
907 }
908 /* Copy ssid array if applicable */
909 WL_SCAN("### List of SSIDs to scan ### %d\n", n_ssids);
910 if (n_ssids > 0) {
911 offset = offsetof(struct brcmf_scan_params_le, channel_list) +
912 n_channels * sizeof(u16);
913 offset = roundup(offset, sizeof(u32));
914 ptr = (char *)params_le + offset;
915 for (i = 0; i < n_ssids; i++) {
916 memset(&ssid_le, 0, sizeof(ssid_le));
917 ssid_le.SSID_len =
918 cpu_to_le32(request->ssids[i].ssid_len);
919 memcpy(ssid_le.SSID, request->ssids[i].ssid,
920 request->ssids[i].ssid_len);
921 if (!ssid_le.SSID_len)
922 WL_SCAN("%d: Broadcast scan\n", i);
923 else
924 WL_SCAN("%d: scan for %s size =%d\n", i,
925 ssid_le.SSID, ssid_le.SSID_len);
926 memcpy(ptr, &ssid_le, sizeof(ssid_le));
927 ptr += sizeof(ssid_le);
928 }
929 } else {
930 WL_SCAN("Broadcast scan %p\n", request->ssids);
931 if ((request->ssids) && request->ssids->ssid_len) {
932 WL_SCAN("SSID %s len=%d\n", params_le->ssid_le.SSID,
933 request->ssids->ssid_len);
934 params_le->ssid_le.SSID_len =
935 cpu_to_le32(request->ssids->ssid_len);
936 memcpy(&params_le->ssid_le.SSID, request->ssids->ssid,
937 request->ssids->ssid_len);
938 }
939 }
940 /* Adding mask to channel numbers */
941 params_le->channel_num =
942 cpu_to_le32((n_ssids << BRCMF_SCAN_PARAMS_NSSID_SHIFT) |
943 (n_channels & BRCMF_SCAN_PARAMS_COUNT_MASK));
944}
945
946static s32
947brcmf_notify_escan_complete(struct brcmf_cfg80211_info *cfg,
948 struct net_device *ndev,
949 bool aborted, bool fw_abort)
950{
951 struct brcmf_scan_params_le params_le;
952 struct cfg80211_scan_request *scan_request;
953 s32 err = 0;
954
955 WL_SCAN("Enter\n");
956
957 /* clear scan request, because the FW abort can cause a second call */
958 /* to this functon and might cause a double cfg80211_scan_done */
959 scan_request = cfg->scan_request;
960 cfg->scan_request = NULL;
961
962 if (timer_pending(&cfg->escan_timeout))
963 del_timer_sync(&cfg->escan_timeout);
964
965 if (fw_abort) {
966 /* Do a scan abort to stop the driver's scan engine */
967 WL_SCAN("ABORT scan in firmware\n");
968 memset(&params_le, 0, sizeof(params_le));
969 memcpy(params_le.bssid, ether_bcast, ETH_ALEN);
970 params_le.bss_type = DOT11_BSSTYPE_ANY;
971 params_le.scan_type = 0;
972 params_le.channel_num = cpu_to_le32(1);
973 params_le.nprobes = cpu_to_le32(1);
974 params_le.active_time = cpu_to_le32(-1);
975 params_le.passive_time = cpu_to_le32(-1);
976 params_le.home_time = cpu_to_le32(-1);
977 /* Scan is aborted by setting channel_list[0] to -1 */
978 params_le.channel_list[0] = cpu_to_le16(-1);
979 /* E-Scan (or anyother type) can be aborted by SCAN */
980 err = brcmf_exec_dcmd(ndev, BRCMF_C_SCAN, &params_le,
981 sizeof(params_le));
982 if (err)
983 WL_ERR("Scan abort failed\n");
984 }
985 /*
986 * e-scan can be initiated by scheduled scan
987 * which takes precedence.
988 */
989 if (cfg->sched_escan) {
990 WL_SCAN("scheduled scan completed\n");
991 cfg->sched_escan = false;
992 if (!aborted)
993 cfg80211_sched_scan_results(cfg_to_wiphy(cfg));
994 brcmf_set_mpc(ndev, 1);
995 } else if (scan_request) {
996 WL_SCAN("ESCAN Completed scan: %s\n",
997 aborted ? "Aborted" : "Done");
998 cfg80211_scan_done(scan_request, aborted);
999 brcmf_set_mpc(ndev, 1);
1000 }
1001 if (!test_and_clear_bit(WL_STATUS_SCANNING, &cfg->status)) {
1002 WL_ERR("Scan complete while device not scanning\n");
1003 return -EPERM;
1004 }
1005
1006 return err;
1007}
1008
1009static s32
1010brcmf_run_escan(struct brcmf_cfg80211_info *cfg, struct net_device *ndev,
1011 struct cfg80211_scan_request *request, u16 action)
1012{
1013 s32 params_size = BRCMF_SCAN_PARAMS_FIXED_SIZE +
1014 offsetof(struct brcmf_escan_params_le, params_le);
1015 struct brcmf_escan_params_le *params;
1016 s32 err = 0;
1017
1018 WL_SCAN("E-SCAN START\n");
1019
1020 if (request != NULL) {
1021 /* Allocate space for populating ssids in struct */
1022 params_size += sizeof(u32) * ((request->n_channels + 1) / 2);
1023
1024 /* Allocate space for populating ssids in struct */
1025 params_size += sizeof(struct brcmf_ssid) * request->n_ssids;
1026 }
1027
1028 params = kzalloc(params_size, GFP_KERNEL);
1029 if (!params) {
1030 err = -ENOMEM;
1031 goto exit;
1032 }
1033 BUG_ON(params_size + sizeof("escan") >= BRCMF_DCMD_MEDLEN);
1034 brcmf_escan_prep(&params->params_le, request);
1035 params->version = cpu_to_le32(BRCMF_ESCAN_REQ_VERSION);
1036 params->action = cpu_to_le16(action);
1037 params->sync_id = cpu_to_le16(0x1234);
1038
1039 err = brcmf_dev_iovar_setbuf(ndev, "escan", params, params_size,
1040 cfg->escan_ioctl_buf, BRCMF_DCMD_MEDLEN);
1041 if (err) {
1042 if (err == -EBUSY)
1043 WL_INFO("system busy : escan canceled\n");
1044 else
1045 WL_ERR("error (%d)\n", err);
1046 }
1047
1048 kfree(params);
1049exit:
1050 return err;
1051}
1052
1053static s32
1054brcmf_do_escan(struct brcmf_cfg80211_info *cfg, struct wiphy *wiphy,
1055 struct net_device *ndev, struct cfg80211_scan_request *request)
1056{
1057 s32 err;
1058 __le32 passive_scan;
1059 struct brcmf_scan_results *results;
1060
1061 WL_SCAN("Enter\n");
1062 cfg->escan_info.ndev = ndev;
1063 cfg->escan_info.wiphy = wiphy;
1064 cfg->escan_info.escan_state = WL_ESCAN_STATE_SCANNING;
1065 passive_scan = cfg->active_scan ? 0 : cpu_to_le32(1);
1066 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_PASSIVE_SCAN,
1067 &passive_scan, sizeof(passive_scan));
1068 if (err) {
1069 WL_ERR("error (%d)\n", err);
1070 return err;
1071 }
1072 brcmf_set_mpc(ndev, 0);
1073 results = (struct brcmf_scan_results *)cfg->escan_info.escan_buf;
1074 results->version = 0;
1075 results->count = 0;
1076 results->buflen = WL_ESCAN_RESULTS_FIXED_SIZE;
1077
1078 err = brcmf_run_escan(cfg, ndev, request, WL_ESCAN_ACTION_START);
1079 if (err)
1080 brcmf_set_mpc(ndev, 1);
1081 return err;
1082}
1083
1084static s32
1085brcmf_cfg80211_escan(struct wiphy *wiphy, struct net_device *ndev,
1086 struct cfg80211_scan_request *request,
1087 struct cfg80211_ssid *this_ssid)
1088{
1089 struct brcmf_cfg80211_info *cfg = ndev_to_cfg(ndev);
1090 struct cfg80211_ssid *ssids;
1091 struct brcmf_cfg80211_scan_req *sr = cfg->scan_req_int;
1092 __le32 passive_scan;
1093 bool escan_req;
1094 bool spec_scan;
1095 s32 err;
1096 u32 SSID_len;
1097
1098 WL_SCAN("START ESCAN\n");
1099
1100 if (test_bit(WL_STATUS_SCANNING, &cfg->status)) {
1101 WL_ERR("Scanning already : status (%lu)\n", cfg->status);
1102 return -EAGAIN;
1103 }
1104 if (test_bit(WL_STATUS_SCAN_ABORTING, &cfg->status)) {
1105 WL_ERR("Scanning being aborted : status (%lu)\n",
1106 cfg->status);
1107 return -EAGAIN;
1108 }
1109 if (test_bit(WL_STATUS_CONNECTING, &cfg->status)) {
1110 WL_ERR("Connecting : status (%lu)\n",
1111 cfg->status);
1112 return -EAGAIN;
1113 }
1114
1115 /* Arm scan timeout timer */
1116 mod_timer(&cfg->escan_timeout, jiffies +
1117 WL_ESCAN_TIMER_INTERVAL_MS * HZ / 1000);
1118
1119 escan_req = false;
1120 if (request) {
1121 /* scan bss */
1122 ssids = request->ssids;
1123 escan_req = true;
1124 } else {
1125 /* scan in ibss */
1126 /* we don't do escan in ibss */
1127 ssids = this_ssid;
1128 }
1129
1130 cfg->scan_request = request;
1131 set_bit(WL_STATUS_SCANNING, &cfg->status);
1132 if (escan_req) {
1133 err = brcmf_do_escan(cfg, wiphy, ndev, request);
1134 if (!err)
1135 return err;
1136 else
1137 goto scan_out;
1138 } else {
1139 WL_SCAN("ssid \"%s\", ssid_len (%d)\n",
1140 ssids->ssid, ssids->ssid_len);
1141 memset(&sr->ssid_le, 0, sizeof(sr->ssid_le));
1142 SSID_len = min_t(u8, sizeof(sr->ssid_le.SSID), ssids->ssid_len);
1143 sr->ssid_le.SSID_len = cpu_to_le32(0);
1144 spec_scan = false;
1145 if (SSID_len) {
1146 memcpy(sr->ssid_le.SSID, ssids->ssid, SSID_len);
1147 sr->ssid_le.SSID_len = cpu_to_le32(SSID_len);
1148 spec_scan = true;
1149 } else
1150 WL_SCAN("Broadcast scan\n");
1151
1152 passive_scan = cfg->active_scan ? 0 : cpu_to_le32(1);
1153 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_PASSIVE_SCAN,
1154 &passive_scan, sizeof(passive_scan));
1155 if (err) {
1156 WL_ERR("WLC_SET_PASSIVE_SCAN error (%d)\n", err);
1157 goto scan_out;
1158 }
1159 brcmf_set_mpc(ndev, 0);
1160 err = brcmf_exec_dcmd(ndev, BRCMF_C_SCAN, &sr->ssid_le,
1161 sizeof(sr->ssid_le));
1162 if (err) {
1163 if (err == -EBUSY)
1164 WL_INFO("BUSY: scan for \"%s\" canceled\n",
1165 sr->ssid_le.SSID);
1166 else
1167 WL_ERR("WLC_SCAN error (%d)\n", err);
1168
1169 brcmf_set_mpc(ndev, 1);
1170 goto scan_out;
1171 }
1172 }
1173
1174 return 0;
1175
1176scan_out:
1177 clear_bit(WL_STATUS_SCANNING, &cfg->status);
1178 if (timer_pending(&cfg->escan_timeout))
1179 del_timer_sync(&cfg->escan_timeout);
1180 cfg->scan_request = NULL;
692 return err; 1181 return err;
693} 1182}
694 1183
@@ -697,6 +1186,7 @@ brcmf_cfg80211_scan(struct wiphy *wiphy,
697 struct cfg80211_scan_request *request) 1186 struct cfg80211_scan_request *request)
698{ 1187{
699 struct net_device *ndev = request->wdev->netdev; 1188 struct net_device *ndev = request->wdev->netdev;
1189 struct brcmf_cfg80211_info *cfg = ndev_to_cfg(ndev);
700 s32 err = 0; 1190 s32 err = 0;
701 1191
702 WL_TRACE("Enter\n"); 1192 WL_TRACE("Enter\n");
@@ -704,7 +1194,11 @@ brcmf_cfg80211_scan(struct wiphy *wiphy,
704 if (!check_sys_up(wiphy)) 1194 if (!check_sys_up(wiphy))
705 return -EIO; 1195 return -EIO;
706 1196
707 err = __brcmf_cfg80211_scan(wiphy, ndev, request, NULL); 1197 if (cfg->iscan_on)
1198 err = brcmf_cfg80211_iscan(wiphy, ndev, request, NULL);
1199 else if (cfg->escan_on)
1200 err = brcmf_cfg80211_escan(wiphy, ndev, request, NULL);
1201
708 if (err) 1202 if (err)
709 WL_ERR("scan error (%d)\n", err); 1203 WL_ERR("scan error (%d)\n", err);
710 1204
@@ -749,8 +1243,8 @@ static s32 brcmf_set_retry(struct net_device *ndev, u32 retry, bool l)
749 1243
750static s32 brcmf_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed) 1244static s32 brcmf_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
751{ 1245{
752 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy); 1246 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
753 struct net_device *ndev = cfg_to_ndev(cfg_priv); 1247 struct net_device *ndev = cfg_to_ndev(cfg);
754 s32 err = 0; 1248 s32 err = 0;
755 1249
756 WL_TRACE("Enter\n"); 1250 WL_TRACE("Enter\n");
@@ -758,30 +1252,30 @@ static s32 brcmf_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
758 return -EIO; 1252 return -EIO;
759 1253
760 if (changed & WIPHY_PARAM_RTS_THRESHOLD && 1254 if (changed & WIPHY_PARAM_RTS_THRESHOLD &&
761 (cfg_priv->conf->rts_threshold != wiphy->rts_threshold)) { 1255 (cfg->conf->rts_threshold != wiphy->rts_threshold)) {
762 cfg_priv->conf->rts_threshold = wiphy->rts_threshold; 1256 cfg->conf->rts_threshold = wiphy->rts_threshold;
763 err = brcmf_set_rts(ndev, cfg_priv->conf->rts_threshold); 1257 err = brcmf_set_rts(ndev, cfg->conf->rts_threshold);
764 if (!err) 1258 if (!err)
765 goto done; 1259 goto done;
766 } 1260 }
767 if (changed & WIPHY_PARAM_FRAG_THRESHOLD && 1261 if (changed & WIPHY_PARAM_FRAG_THRESHOLD &&
768 (cfg_priv->conf->frag_threshold != wiphy->frag_threshold)) { 1262 (cfg->conf->frag_threshold != wiphy->frag_threshold)) {
769 cfg_priv->conf->frag_threshold = wiphy->frag_threshold; 1263 cfg->conf->frag_threshold = wiphy->frag_threshold;
770 err = brcmf_set_frag(ndev, cfg_priv->conf->frag_threshold); 1264 err = brcmf_set_frag(ndev, cfg->conf->frag_threshold);
771 if (!err) 1265 if (!err)
772 goto done; 1266 goto done;
773 } 1267 }
774 if (changed & WIPHY_PARAM_RETRY_LONG 1268 if (changed & WIPHY_PARAM_RETRY_LONG
775 && (cfg_priv->conf->retry_long != wiphy->retry_long)) { 1269 && (cfg->conf->retry_long != wiphy->retry_long)) {
776 cfg_priv->conf->retry_long = wiphy->retry_long; 1270 cfg->conf->retry_long = wiphy->retry_long;
777 err = brcmf_set_retry(ndev, cfg_priv->conf->retry_long, true); 1271 err = brcmf_set_retry(ndev, cfg->conf->retry_long, true);
778 if (!err) 1272 if (!err)
779 goto done; 1273 goto done;
780 } 1274 }
781 if (changed & WIPHY_PARAM_RETRY_SHORT 1275 if (changed & WIPHY_PARAM_RETRY_SHORT
782 && (cfg_priv->conf->retry_short != wiphy->retry_short)) { 1276 && (cfg->conf->retry_short != wiphy->retry_short)) {
783 cfg_priv->conf->retry_short = wiphy->retry_short; 1277 cfg->conf->retry_short = wiphy->retry_short;
784 err = brcmf_set_retry(ndev, cfg_priv->conf->retry_short, false); 1278 err = brcmf_set_retry(ndev, cfg->conf->retry_short, false);
785 if (!err) 1279 if (!err)
786 goto done; 1280 goto done;
787 } 1281 }
@@ -791,61 +1285,6 @@ done:
791 return err; 1285 return err;
792} 1286}
793 1287
794static void *brcmf_read_prof(struct brcmf_cfg80211_priv *cfg_priv, s32 item)
795{
796 switch (item) {
797 case WL_PROF_SEC:
798 return &cfg_priv->profile->sec;
799 case WL_PROF_BSSID:
800 return &cfg_priv->profile->bssid;
801 case WL_PROF_SSID:
802 return &cfg_priv->profile->ssid;
803 }
804 WL_ERR("invalid item (%d)\n", item);
805 return NULL;
806}
807
808static s32
809brcmf_update_prof(struct brcmf_cfg80211_priv *cfg_priv,
810 const struct brcmf_event_msg *e, void *data, s32 item)
811{
812 s32 err = 0;
813 struct brcmf_ssid *ssid;
814
815 switch (item) {
816 case WL_PROF_SSID:
817 ssid = (struct brcmf_ssid *) data;
818 memset(cfg_priv->profile->ssid.SSID, 0,
819 sizeof(cfg_priv->profile->ssid.SSID));
820 memcpy(cfg_priv->profile->ssid.SSID,
821 ssid->SSID, ssid->SSID_len);
822 cfg_priv->profile->ssid.SSID_len = ssid->SSID_len;
823 break;
824 case WL_PROF_BSSID:
825 if (data)
826 memcpy(cfg_priv->profile->bssid, data, ETH_ALEN);
827 else
828 memset(cfg_priv->profile->bssid, 0, ETH_ALEN);
829 break;
830 case WL_PROF_SEC:
831 memcpy(&cfg_priv->profile->sec, data,
832 sizeof(cfg_priv->profile->sec));
833 break;
834 case WL_PROF_BEACONINT:
835 cfg_priv->profile->beacon_interval = *(u16 *)data;
836 break;
837 case WL_PROF_DTIMPERIOD:
838 cfg_priv->profile->dtim_period = *(u8 *)data;
839 break;
840 default:
841 WL_ERR("unsupported item (%d)\n", item);
842 err = -EOPNOTSUPP;
843 break;
844 }
845
846 return err;
847}
848
849static void brcmf_init_prof(struct brcmf_cfg80211_profile *prof) 1288static void brcmf_init_prof(struct brcmf_cfg80211_profile *prof)
850{ 1289{
851 memset(prof, 0, sizeof(*prof)); 1290 memset(prof, 0, sizeof(*prof));
@@ -878,20 +1317,20 @@ static void brcmf_ch_to_chanspec(int ch, struct brcmf_join_params *join_params,
878 } 1317 }
879} 1318}
880 1319
881static void brcmf_link_down(struct brcmf_cfg80211_priv *cfg_priv) 1320static void brcmf_link_down(struct brcmf_cfg80211_info *cfg)
882{ 1321{
883 struct net_device *ndev = NULL; 1322 struct net_device *ndev = NULL;
884 s32 err = 0; 1323 s32 err = 0;
885 1324
886 WL_TRACE("Enter\n"); 1325 WL_TRACE("Enter\n");
887 1326
888 if (cfg_priv->link_up) { 1327 if (cfg->link_up) {
889 ndev = cfg_to_ndev(cfg_priv); 1328 ndev = cfg_to_ndev(cfg);
890 WL_INFO("Call WLC_DISASSOC to stop excess roaming\n "); 1329 WL_INFO("Call WLC_DISASSOC to stop excess roaming\n ");
891 err = brcmf_exec_dcmd(ndev, BRCMF_C_DISASSOC, NULL, 0); 1330 err = brcmf_exec_dcmd(ndev, BRCMF_C_DISASSOC, NULL, 0);
892 if (err) 1331 if (err)
893 WL_ERR("WLC_DISASSOC failed (%d)\n", err); 1332 WL_ERR("WLC_DISASSOC failed (%d)\n", err);
894 cfg_priv->link_up = false; 1333 cfg->link_up = false;
895 } 1334 }
896 WL_TRACE("Exit\n"); 1335 WL_TRACE("Exit\n");
897} 1336}
@@ -900,13 +1339,13 @@ static s32
900brcmf_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *ndev, 1339brcmf_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *ndev,
901 struct cfg80211_ibss_params *params) 1340 struct cfg80211_ibss_params *params)
902{ 1341{
903 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy); 1342 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1343 struct brcmf_cfg80211_profile *profile = cfg->profile;
904 struct brcmf_join_params join_params; 1344 struct brcmf_join_params join_params;
905 size_t join_params_size = 0; 1345 size_t join_params_size = 0;
906 s32 err = 0; 1346 s32 err = 0;
907 s32 wsec = 0; 1347 s32 wsec = 0;
908 s32 bcnprd; 1348 s32 bcnprd;
909 struct brcmf_ssid ssid;
910 1349
911 WL_TRACE("Enter\n"); 1350 WL_TRACE("Enter\n");
912 if (!check_sys_up(wiphy)) 1351 if (!check_sys_up(wiphy))
@@ -919,7 +1358,7 @@ brcmf_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *ndev,
919 return -EOPNOTSUPP; 1358 return -EOPNOTSUPP;
920 } 1359 }
921 1360
922 set_bit(WL_STATUS_CONNECTING, &cfg_priv->status); 1361 set_bit(WL_STATUS_CONNECTING, &cfg->status);
923 1362
924 if (params->bssid) 1363 if (params->bssid)
925 WL_CONN("BSSID: %pM\n", params->bssid); 1364 WL_CONN("BSSID: %pM\n", params->bssid);
@@ -982,40 +1421,38 @@ brcmf_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *ndev,
982 memset(&join_params, 0, sizeof(struct brcmf_join_params)); 1421 memset(&join_params, 0, sizeof(struct brcmf_join_params));
983 1422
984 /* SSID */ 1423 /* SSID */
985 ssid.SSID_len = min_t(u32, params->ssid_len, 32); 1424 profile->ssid.SSID_len = min_t(u32, params->ssid_len, 32);
986 memcpy(ssid.SSID, params->ssid, ssid.SSID_len); 1425 memcpy(profile->ssid.SSID, params->ssid, profile->ssid.SSID_len);
987 memcpy(join_params.ssid_le.SSID, params->ssid, ssid.SSID_len); 1426 memcpy(join_params.ssid_le.SSID, params->ssid, profile->ssid.SSID_len);
988 join_params.ssid_le.SSID_len = cpu_to_le32(ssid.SSID_len); 1427 join_params.ssid_le.SSID_len = cpu_to_le32(profile->ssid.SSID_len);
989 join_params_size = sizeof(join_params.ssid_le); 1428 join_params_size = sizeof(join_params.ssid_le);
990 brcmf_update_prof(cfg_priv, NULL, &ssid, WL_PROF_SSID);
991 1429
992 /* BSSID */ 1430 /* BSSID */
993 if (params->bssid) { 1431 if (params->bssid) {
994 memcpy(join_params.params_le.bssid, params->bssid, ETH_ALEN); 1432 memcpy(join_params.params_le.bssid, params->bssid, ETH_ALEN);
995 join_params_size = sizeof(join_params.ssid_le) + 1433 join_params_size = sizeof(join_params.ssid_le) +
996 BRCMF_ASSOC_PARAMS_FIXED_SIZE; 1434 BRCMF_ASSOC_PARAMS_FIXED_SIZE;
1435 memcpy(profile->bssid, params->bssid, ETH_ALEN);
997 } else { 1436 } else {
998 memcpy(join_params.params_le.bssid, ether_bcast, ETH_ALEN); 1437 memcpy(join_params.params_le.bssid, ether_bcast, ETH_ALEN);
1438 memset(profile->bssid, 0, ETH_ALEN);
999 } 1439 }
1000 1440
1001 brcmf_update_prof(cfg_priv, NULL,
1002 &join_params.params_le.bssid, WL_PROF_BSSID);
1003
1004 /* Channel */ 1441 /* Channel */
1005 if (params->channel) { 1442 if (params->channel) {
1006 u32 target_channel; 1443 u32 target_channel;
1007 1444
1008 cfg_priv->channel = 1445 cfg->channel =
1009 ieee80211_frequency_to_channel( 1446 ieee80211_frequency_to_channel(
1010 params->channel->center_freq); 1447 params->channel->center_freq);
1011 if (params->channel_fixed) { 1448 if (params->channel_fixed) {
1012 /* adding chanspec */ 1449 /* adding chanspec */
1013 brcmf_ch_to_chanspec(cfg_priv->channel, 1450 brcmf_ch_to_chanspec(cfg->channel,
1014 &join_params, &join_params_size); 1451 &join_params, &join_params_size);
1015 } 1452 }
1016 1453
1017 /* set channel for starter */ 1454 /* set channel for starter */
1018 target_channel = cfg_priv->channel; 1455 target_channel = cfg->channel;
1019 err = brcmf_exec_dcmd_u32(ndev, BRCM_SET_CHANNEL, 1456 err = brcmf_exec_dcmd_u32(ndev, BRCM_SET_CHANNEL,
1020 &target_channel); 1457 &target_channel);
1021 if (err) { 1458 if (err) {
@@ -1023,9 +1460,9 @@ brcmf_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *ndev,
1023 goto done; 1460 goto done;
1024 } 1461 }
1025 } else 1462 } else
1026 cfg_priv->channel = 0; 1463 cfg->channel = 0;
1027 1464
1028 cfg_priv->ibss_starter = false; 1465 cfg->ibss_starter = false;
1029 1466
1030 1467
1031 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_SSID, 1468 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_SSID,
@@ -1037,7 +1474,7 @@ brcmf_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *ndev,
1037 1474
1038done: 1475done:
1039 if (err) 1476 if (err)
1040 clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status); 1477 clear_bit(WL_STATUS_CONNECTING, &cfg->status);
1041 WL_TRACE("Exit\n"); 1478 WL_TRACE("Exit\n");
1042 return err; 1479 return err;
1043} 1480}
@@ -1045,14 +1482,14 @@ done:
1045static s32 1482static s32
1046brcmf_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *ndev) 1483brcmf_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *ndev)
1047{ 1484{
1048 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy); 1485 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1049 s32 err = 0; 1486 s32 err = 0;
1050 1487
1051 WL_TRACE("Enter\n"); 1488 WL_TRACE("Enter\n");
1052 if (!check_sys_up(wiphy)) 1489 if (!check_sys_up(wiphy))
1053 return -EIO; 1490 return -EIO;
1054 1491
1055 brcmf_link_down(cfg_priv); 1492 brcmf_link_down(cfg);
1056 1493
1057 WL_TRACE("Exit\n"); 1494 WL_TRACE("Exit\n");
1058 1495
@@ -1062,7 +1499,8 @@ brcmf_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *ndev)
1062static s32 brcmf_set_wpa_version(struct net_device *ndev, 1499static s32 brcmf_set_wpa_version(struct net_device *ndev,
1063 struct cfg80211_connect_params *sme) 1500 struct cfg80211_connect_params *sme)
1064{ 1501{
1065 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev); 1502 struct brcmf_cfg80211_info *cfg = ndev_to_cfg(ndev);
1503 struct brcmf_cfg80211_profile *profile = cfg->profile;
1066 struct brcmf_cfg80211_security *sec; 1504 struct brcmf_cfg80211_security *sec;
1067 s32 val = 0; 1505 s32 val = 0;
1068 s32 err = 0; 1506 s32 err = 0;
@@ -1079,7 +1517,7 @@ static s32 brcmf_set_wpa_version(struct net_device *ndev,
1079 WL_ERR("set wpa_auth failed (%d)\n", err); 1517 WL_ERR("set wpa_auth failed (%d)\n", err);
1080 return err; 1518 return err;
1081 } 1519 }
1082 sec = brcmf_read_prof(cfg_priv, WL_PROF_SEC); 1520 sec = &profile->sec;
1083 sec->wpa_versions = sme->crypto.wpa_versions; 1521 sec->wpa_versions = sme->crypto.wpa_versions;
1084 return err; 1522 return err;
1085} 1523}
@@ -1087,7 +1525,8 @@ static s32 brcmf_set_wpa_version(struct net_device *ndev,
1087static s32 brcmf_set_auth_type(struct net_device *ndev, 1525static s32 brcmf_set_auth_type(struct net_device *ndev,
1088 struct cfg80211_connect_params *sme) 1526 struct cfg80211_connect_params *sme)
1089{ 1527{
1090 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev); 1528 struct brcmf_cfg80211_info *cfg = ndev_to_cfg(ndev);
1529 struct brcmf_cfg80211_profile *profile = cfg->profile;
1091 struct brcmf_cfg80211_security *sec; 1530 struct brcmf_cfg80211_security *sec;
1092 s32 val = 0; 1531 s32 val = 0;
1093 s32 err = 0; 1532 s32 err = 0;
@@ -1118,7 +1557,7 @@ static s32 brcmf_set_auth_type(struct net_device *ndev,
1118 WL_ERR("set auth failed (%d)\n", err); 1557 WL_ERR("set auth failed (%d)\n", err);
1119 return err; 1558 return err;
1120 } 1559 }
1121 sec = brcmf_read_prof(cfg_priv, WL_PROF_SEC); 1560 sec = &profile->sec;
1122 sec->auth_type = sme->auth_type; 1561 sec->auth_type = sme->auth_type;
1123 return err; 1562 return err;
1124} 1563}
@@ -1127,7 +1566,8 @@ static s32
1127brcmf_set_set_cipher(struct net_device *ndev, 1566brcmf_set_set_cipher(struct net_device *ndev,
1128 struct cfg80211_connect_params *sme) 1567 struct cfg80211_connect_params *sme)
1129{ 1568{
1130 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev); 1569 struct brcmf_cfg80211_info *cfg = ndev_to_cfg(ndev);
1570 struct brcmf_cfg80211_profile *profile = cfg->profile;
1131 struct brcmf_cfg80211_security *sec; 1571 struct brcmf_cfg80211_security *sec;
1132 s32 pval = 0; 1572 s32 pval = 0;
1133 s32 gval = 0; 1573 s32 gval = 0;
@@ -1183,7 +1623,7 @@ brcmf_set_set_cipher(struct net_device *ndev,
1183 return err; 1623 return err;
1184 } 1624 }
1185 1625
1186 sec = brcmf_read_prof(cfg_priv, WL_PROF_SEC); 1626 sec = &profile->sec;
1187 sec->cipher_pairwise = sme->crypto.ciphers_pairwise[0]; 1627 sec->cipher_pairwise = sme->crypto.ciphers_pairwise[0];
1188 sec->cipher_group = sme->crypto.cipher_group; 1628 sec->cipher_group = sme->crypto.cipher_group;
1189 1629
@@ -1193,7 +1633,8 @@ brcmf_set_set_cipher(struct net_device *ndev,
1193static s32 1633static s32
1194brcmf_set_key_mgmt(struct net_device *ndev, struct cfg80211_connect_params *sme) 1634brcmf_set_key_mgmt(struct net_device *ndev, struct cfg80211_connect_params *sme)
1195{ 1635{
1196 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev); 1636 struct brcmf_cfg80211_info *cfg = ndev_to_cfg(ndev);
1637 struct brcmf_cfg80211_profile *profile = cfg->profile;
1197 struct brcmf_cfg80211_security *sec; 1638 struct brcmf_cfg80211_security *sec;
1198 s32 val = 0; 1639 s32 val = 0;
1199 s32 err = 0; 1640 s32 err = 0;
@@ -1239,74 +1680,76 @@ brcmf_set_key_mgmt(struct net_device *ndev, struct cfg80211_connect_params *sme)
1239 return err; 1680 return err;
1240 } 1681 }
1241 } 1682 }
1242 sec = brcmf_read_prof(cfg_priv, WL_PROF_SEC); 1683 sec = &profile->sec;
1243 sec->wpa_auth = sme->crypto.akm_suites[0]; 1684 sec->wpa_auth = sme->crypto.akm_suites[0];
1244 1685
1245 return err; 1686 return err;
1246} 1687}
1247 1688
1248static s32 1689static s32
1249brcmf_set_wep_sharedkey(struct net_device *ndev, 1690brcmf_set_sharedkey(struct net_device *ndev,
1250 struct cfg80211_connect_params *sme) 1691 struct cfg80211_connect_params *sme)
1251{ 1692{
1252 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev); 1693 struct brcmf_cfg80211_info *cfg = ndev_to_cfg(ndev);
1694 struct brcmf_cfg80211_profile *profile = cfg->profile;
1253 struct brcmf_cfg80211_security *sec; 1695 struct brcmf_cfg80211_security *sec;
1254 struct brcmf_wsec_key key; 1696 struct brcmf_wsec_key key;
1255 s32 val; 1697 s32 val;
1256 s32 err = 0; 1698 s32 err = 0;
1699 s32 bssidx;
1257 1700
1258 WL_CONN("key len (%d)\n", sme->key_len); 1701 WL_CONN("key len (%d)\n", sme->key_len);
1259 1702
1260 if (sme->key_len == 0) 1703 if (sme->key_len == 0)
1261 return 0; 1704 return 0;
1262 1705
1263 sec = brcmf_read_prof(cfg_priv, WL_PROF_SEC); 1706 sec = &profile->sec;
1264 WL_CONN("wpa_versions 0x%x cipher_pairwise 0x%x\n", 1707 WL_CONN("wpa_versions 0x%x cipher_pairwise 0x%x\n",
1265 sec->wpa_versions, sec->cipher_pairwise); 1708 sec->wpa_versions, sec->cipher_pairwise);
1266 1709
1267 if (sec->wpa_versions & (NL80211_WPA_VERSION_1 | NL80211_WPA_VERSION_2)) 1710 if (sec->wpa_versions & (NL80211_WPA_VERSION_1 | NL80211_WPA_VERSION_2))
1268 return 0; 1711 return 0;
1269 1712
1270 if (sec->cipher_pairwise & 1713 if (!(sec->cipher_pairwise &
1271 (WLAN_CIPHER_SUITE_WEP40 | WLAN_CIPHER_SUITE_WEP104)) { 1714 (WLAN_CIPHER_SUITE_WEP40 | WLAN_CIPHER_SUITE_WEP104)))
1272 memset(&key, 0, sizeof(key)); 1715 return 0;
1273 key.len = (u32) sme->key_len;
1274 key.index = (u32) sme->key_idx;
1275 if (key.len > sizeof(key.data)) {
1276 WL_ERR("Too long key length (%u)\n", key.len);
1277 return -EINVAL;
1278 }
1279 memcpy(key.data, sme->key, key.len);
1280 key.flags = BRCMF_PRIMARY_KEY;
1281 switch (sec->cipher_pairwise) {
1282 case WLAN_CIPHER_SUITE_WEP40:
1283 key.algo = CRYPTO_ALGO_WEP1;
1284 break;
1285 case WLAN_CIPHER_SUITE_WEP104:
1286 key.algo = CRYPTO_ALGO_WEP128;
1287 break;
1288 default:
1289 WL_ERR("Invalid algorithm (%d)\n",
1290 sme->crypto.ciphers_pairwise[0]);
1291 return -EINVAL;
1292 }
1293 /* Set the new key/index */
1294 WL_CONN("key length (%d) key index (%d) algo (%d)\n",
1295 key.len, key.index, key.algo);
1296 WL_CONN("key \"%s\"\n", key.data);
1297 err = send_key_to_dongle(ndev, &key);
1298 if (err)
1299 return err;
1300 1716
1301 if (sec->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM) { 1717 memset(&key, 0, sizeof(key));
1302 WL_CONN("set auth_type to shared key\n"); 1718 key.len = (u32) sme->key_len;
1303 val = 1; /* shared key */ 1719 key.index = (u32) sme->key_idx;
1304 err = brcmf_dev_intvar_set(ndev, "auth", val); 1720 if (key.len > sizeof(key.data)) {
1305 if (err) { 1721 WL_ERR("Too long key length (%u)\n", key.len);
1306 WL_ERR("set auth failed (%d)\n", err); 1722 return -EINVAL;
1307 return err; 1723 }
1308 } 1724 memcpy(key.data, sme->key, key.len);
1309 } 1725 key.flags = BRCMF_PRIMARY_KEY;
1726 switch (sec->cipher_pairwise) {
1727 case WLAN_CIPHER_SUITE_WEP40:
1728 key.algo = CRYPTO_ALGO_WEP1;
1729 break;
1730 case WLAN_CIPHER_SUITE_WEP104:
1731 key.algo = CRYPTO_ALGO_WEP128;
1732 break;
1733 default:
1734 WL_ERR("Invalid algorithm (%d)\n",
1735 sme->crypto.ciphers_pairwise[0]);
1736 return -EINVAL;
1737 }
1738 /* Set the new key/index */
1739 WL_CONN("key length (%d) key index (%d) algo (%d)\n",
1740 key.len, key.index, key.algo);
1741 WL_CONN("key \"%s\"\n", key.data);
1742 bssidx = brcmf_find_bssidx(cfg, ndev);
1743 err = send_key_to_dongle(cfg, bssidx, ndev, &key);
1744 if (err)
1745 return err;
1746
1747 if (sec->auth_type == NL80211_AUTHTYPE_SHARED_KEY) {
1748 WL_CONN("set auth_type to shared key\n");
1749 val = WL_AUTH_SHARED_KEY; /* shared key */
1750 err = brcmf_dev_intvar_set_bsscfg(ndev, "auth", val, bssidx);
1751 if (err)
1752 WL_ERR("set auth failed (%d)\n", err);
1310 } 1753 }
1311 return err; 1754 return err;
1312} 1755}
@@ -1315,7 +1758,8 @@ static s32
1315brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev, 1758brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev,
1316 struct cfg80211_connect_params *sme) 1759 struct cfg80211_connect_params *sme)
1317{ 1760{
1318 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy); 1761 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1762 struct brcmf_cfg80211_profile *profile = cfg->profile;
1319 struct ieee80211_channel *chan = sme->channel; 1763 struct ieee80211_channel *chan = sme->channel;
1320 struct brcmf_join_params join_params; 1764 struct brcmf_join_params join_params;
1321 size_t join_params_size; 1765 size_t join_params_size;
@@ -1332,15 +1776,15 @@ brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev,
1332 return -EOPNOTSUPP; 1776 return -EOPNOTSUPP;
1333 } 1777 }
1334 1778
1335 set_bit(WL_STATUS_CONNECTING, &cfg_priv->status); 1779 set_bit(WL_STATUS_CONNECTING, &cfg->status);
1336 1780
1337 if (chan) { 1781 if (chan) {
1338 cfg_priv->channel = 1782 cfg->channel =
1339 ieee80211_frequency_to_channel(chan->center_freq); 1783 ieee80211_frequency_to_channel(chan->center_freq);
1340 WL_CONN("channel (%d), center_req (%d)\n", 1784 WL_CONN("channel (%d), center_req (%d)\n",
1341 cfg_priv->channel, chan->center_freq); 1785 cfg->channel, chan->center_freq);
1342 } else 1786 } else
1343 cfg_priv->channel = 0; 1787 cfg->channel = 0;
1344 1788
1345 WL_INFO("ie (%p), ie_len (%zd)\n", sme->ie, sme->ie_len); 1789 WL_INFO("ie (%p), ie_len (%zd)\n", sme->ie, sme->ie_len);
1346 1790
@@ -1368,20 +1812,20 @@ brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev,
1368 goto done; 1812 goto done;
1369 } 1813 }
1370 1814
1371 err = brcmf_set_wep_sharedkey(ndev, sme); 1815 err = brcmf_set_sharedkey(ndev, sme);
1372 if (err) { 1816 if (err) {
1373 WL_ERR("brcmf_set_wep_sharedkey failed (%d)\n", err); 1817 WL_ERR("brcmf_set_sharedkey failed (%d)\n", err);
1374 goto done; 1818 goto done;
1375 } 1819 }
1376 1820
1377 memset(&join_params, 0, sizeof(join_params)); 1821 memset(&join_params, 0, sizeof(join_params));
1378 join_params_size = sizeof(join_params.ssid_le); 1822 join_params_size = sizeof(join_params.ssid_le);
1379 1823
1380 ssid.SSID_len = min_t(u32, sizeof(ssid.SSID), (u32)sme->ssid_len); 1824 profile->ssid.SSID_len = min_t(u32,
1381 memcpy(&join_params.ssid_le.SSID, sme->ssid, ssid.SSID_len); 1825 sizeof(ssid.SSID), (u32)sme->ssid_len);
1382 memcpy(&ssid.SSID, sme->ssid, ssid.SSID_len); 1826 memcpy(&join_params.ssid_le.SSID, sme->ssid, profile->ssid.SSID_len);
1383 join_params.ssid_le.SSID_len = cpu_to_le32(ssid.SSID_len); 1827 memcpy(&profile->ssid.SSID, sme->ssid, profile->ssid.SSID_len);
1384 brcmf_update_prof(cfg_priv, NULL, &ssid, WL_PROF_SSID); 1828 join_params.ssid_le.SSID_len = cpu_to_le32(profile->ssid.SSID_len);
1385 1829
1386 memcpy(join_params.params_le.bssid, ether_bcast, ETH_ALEN); 1830 memcpy(join_params.params_le.bssid, ether_bcast, ETH_ALEN);
1387 1831
@@ -1389,7 +1833,7 @@ brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev,
1389 WL_CONN("ssid \"%s\", len (%d)\n", 1833 WL_CONN("ssid \"%s\", len (%d)\n",
1390 ssid.SSID, ssid.SSID_len); 1834 ssid.SSID, ssid.SSID_len);
1391 1835
1392 brcmf_ch_to_chanspec(cfg_priv->channel, 1836 brcmf_ch_to_chanspec(cfg->channel,
1393 &join_params, &join_params_size); 1837 &join_params, &join_params_size);
1394 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_SSID, 1838 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_SSID,
1395 &join_params, join_params_size); 1839 &join_params, join_params_size);
@@ -1398,7 +1842,7 @@ brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev,
1398 1842
1399done: 1843done:
1400 if (err) 1844 if (err)
1401 clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status); 1845 clear_bit(WL_STATUS_CONNECTING, &cfg->status);
1402 WL_TRACE("Exit\n"); 1846 WL_TRACE("Exit\n");
1403 return err; 1847 return err;
1404} 1848}
@@ -1407,7 +1851,8 @@ static s32
1407brcmf_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *ndev, 1851brcmf_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *ndev,
1408 u16 reason_code) 1852 u16 reason_code)
1409{ 1853{
1410 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy); 1854 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1855 struct brcmf_cfg80211_profile *profile = cfg->profile;
1411 struct brcmf_scb_val_le scbval; 1856 struct brcmf_scb_val_le scbval;
1412 s32 err = 0; 1857 s32 err = 0;
1413 1858
@@ -1415,16 +1860,16 @@ brcmf_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *ndev,
1415 if (!check_sys_up(wiphy)) 1860 if (!check_sys_up(wiphy))
1416 return -EIO; 1861 return -EIO;
1417 1862
1418 clear_bit(WL_STATUS_CONNECTED, &cfg_priv->status); 1863 clear_bit(WL_STATUS_CONNECTED, &cfg->status);
1419 1864
1420 memcpy(&scbval.ea, brcmf_read_prof(cfg_priv, WL_PROF_BSSID), ETH_ALEN); 1865 memcpy(&scbval.ea, &profile->bssid, ETH_ALEN);
1421 scbval.val = cpu_to_le32(reason_code); 1866 scbval.val = cpu_to_le32(reason_code);
1422 err = brcmf_exec_dcmd(ndev, BRCMF_C_DISASSOC, &scbval, 1867 err = brcmf_exec_dcmd(ndev, BRCMF_C_DISASSOC, &scbval,
1423 sizeof(struct brcmf_scb_val_le)); 1868 sizeof(struct brcmf_scb_val_le));
1424 if (err) 1869 if (err)
1425 WL_ERR("error (%d)\n", err); 1870 WL_ERR("error (%d)\n", err);
1426 1871
1427 cfg_priv->link_up = false; 1872 cfg->link_up = false;
1428 1873
1429 WL_TRACE("Exit\n"); 1874 WL_TRACE("Exit\n");
1430 return err; 1875 return err;
@@ -1435,8 +1880,8 @@ brcmf_cfg80211_set_tx_power(struct wiphy *wiphy,
1435 enum nl80211_tx_power_setting type, s32 mbm) 1880 enum nl80211_tx_power_setting type, s32 mbm)
1436{ 1881{
1437 1882
1438 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy); 1883 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1439 struct net_device *ndev = cfg_to_ndev(cfg_priv); 1884 struct net_device *ndev = cfg_to_ndev(cfg);
1440 u16 txpwrmw; 1885 u16 txpwrmw;
1441 s32 err = 0; 1886 s32 err = 0;
1442 s32 disable = 0; 1887 s32 disable = 0;
@@ -1472,7 +1917,7 @@ brcmf_cfg80211_set_tx_power(struct wiphy *wiphy,
1472 (s32) (brcmf_mw_to_qdbm(txpwrmw))); 1917 (s32) (brcmf_mw_to_qdbm(txpwrmw)));
1473 if (err) 1918 if (err)
1474 WL_ERR("qtxpower error (%d)\n", err); 1919 WL_ERR("qtxpower error (%d)\n", err);
1475 cfg_priv->conf->tx_power = dbm; 1920 cfg->conf->tx_power = dbm;
1476 1921
1477done: 1922done:
1478 WL_TRACE("Exit\n"); 1923 WL_TRACE("Exit\n");
@@ -1481,8 +1926,8 @@ done:
1481 1926
1482static s32 brcmf_cfg80211_get_tx_power(struct wiphy *wiphy, s32 *dbm) 1927static s32 brcmf_cfg80211_get_tx_power(struct wiphy *wiphy, s32 *dbm)
1483{ 1928{
1484 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy); 1929 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1485 struct net_device *ndev = cfg_to_ndev(cfg_priv); 1930 struct net_device *ndev = cfg_to_ndev(cfg);
1486 s32 txpwrdbm; 1931 s32 txpwrdbm;
1487 u8 result; 1932 u8 result;
1488 s32 err = 0; 1933 s32 err = 0;
@@ -1509,16 +1954,19 @@ static s32
1509brcmf_cfg80211_config_default_key(struct wiphy *wiphy, struct net_device *ndev, 1954brcmf_cfg80211_config_default_key(struct wiphy *wiphy, struct net_device *ndev,
1510 u8 key_idx, bool unicast, bool multicast) 1955 u8 key_idx, bool unicast, bool multicast)
1511{ 1956{
1957 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1512 u32 index; 1958 u32 index;
1513 u32 wsec; 1959 u32 wsec;
1514 s32 err = 0; 1960 s32 err = 0;
1961 s32 bssidx;
1515 1962
1516 WL_TRACE("Enter\n"); 1963 WL_TRACE("Enter\n");
1517 WL_CONN("key index (%d)\n", key_idx); 1964 WL_CONN("key index (%d)\n", key_idx);
1518 if (!check_sys_up(wiphy)) 1965 if (!check_sys_up(wiphy))
1519 return -EIO; 1966 return -EIO;
1520 1967
1521 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_GET_WSEC, &wsec); 1968 bssidx = brcmf_find_bssidx(cfg, ndev);
1969 err = brcmf_dev_intvar_get_bsscfg(ndev, "wsec", &wsec, bssidx);
1522 if (err) { 1970 if (err) {
1523 WL_ERR("WLC_GET_WSEC error (%d)\n", err); 1971 WL_ERR("WLC_GET_WSEC error (%d)\n", err);
1524 goto done; 1972 goto done;
@@ -1541,9 +1989,11 @@ static s32
1541brcmf_add_keyext(struct wiphy *wiphy, struct net_device *ndev, 1989brcmf_add_keyext(struct wiphy *wiphy, struct net_device *ndev,
1542 u8 key_idx, const u8 *mac_addr, struct key_params *params) 1990 u8 key_idx, const u8 *mac_addr, struct key_params *params)
1543{ 1991{
1992 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1544 struct brcmf_wsec_key key; 1993 struct brcmf_wsec_key key;
1545 struct brcmf_wsec_key_le key_le; 1994 struct brcmf_wsec_key_le key_le;
1546 s32 err = 0; 1995 s32 err = 0;
1996 s32 bssidx;
1547 1997
1548 memset(&key, 0, sizeof(key)); 1998 memset(&key, 0, sizeof(key));
1549 key.index = (u32) key_idx; 1999 key.index = (u32) key_idx;
@@ -1552,12 +2002,13 @@ brcmf_add_keyext(struct wiphy *wiphy, struct net_device *ndev,
1552 if (!is_multicast_ether_addr(mac_addr)) 2002 if (!is_multicast_ether_addr(mac_addr))
1553 memcpy((char *)&key.ea, (void *)mac_addr, ETH_ALEN); 2003 memcpy((char *)&key.ea, (void *)mac_addr, ETH_ALEN);
1554 key.len = (u32) params->key_len; 2004 key.len = (u32) params->key_len;
2005 bssidx = brcmf_find_bssidx(cfg, ndev);
1555 /* check for key index change */ 2006 /* check for key index change */
1556 if (key.len == 0) { 2007 if (key.len == 0) {
1557 /* key delete */ 2008 /* key delete */
1558 err = send_key_to_dongle(ndev, &key); 2009 err = send_key_to_dongle(cfg, bssidx, ndev, &key);
1559 if (err) 2010 if (err)
1560 return err; 2011 WL_ERR("key delete error (%d)\n", err);
1561 } else { 2012 } else {
1562 if (key.len > sizeof(key.data)) { 2013 if (key.len > sizeof(key.data)) {
1563 WL_ERR("Invalid key length (%d)\n", key.len); 2014 WL_ERR("Invalid key length (%d)\n", key.len);
@@ -1613,12 +2064,12 @@ brcmf_add_keyext(struct wiphy *wiphy, struct net_device *ndev,
1613 convert_key_from_CPU(&key, &key_le); 2064 convert_key_from_CPU(&key, &key_le);
1614 2065
1615 brcmf_netdev_wait_pend8021x(ndev); 2066 brcmf_netdev_wait_pend8021x(ndev);
1616 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_KEY, &key_le, 2067 err = brcmf_dev_iovar_setbuf_bsscfg(ndev, "wsec_key", &key_le,
1617 sizeof(key_le)); 2068 sizeof(key_le),
1618 if (err) { 2069 cfg->extra_buf,
1619 WL_ERR("WLC_SET_KEY error (%d)\n", err); 2070 WL_EXTRA_BUF_MAX, bssidx);
1620 return err; 2071 if (err)
1621 } 2072 WL_ERR("wsec_key error (%d)\n", err);
1622 } 2073 }
1623 return err; 2074 return err;
1624} 2075}
@@ -1628,11 +2079,13 @@ brcmf_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
1628 u8 key_idx, bool pairwise, const u8 *mac_addr, 2079 u8 key_idx, bool pairwise, const u8 *mac_addr,
1629 struct key_params *params) 2080 struct key_params *params)
1630{ 2081{
2082 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1631 struct brcmf_wsec_key key; 2083 struct brcmf_wsec_key key;
1632 s32 val; 2084 s32 val;
1633 s32 wsec; 2085 s32 wsec;
1634 s32 err = 0; 2086 s32 err = 0;
1635 u8 keybuf[8]; 2087 u8 keybuf[8];
2088 s32 bssidx;
1636 2089
1637 WL_TRACE("Enter\n"); 2090 WL_TRACE("Enter\n");
1638 WL_CONN("key index (%d)\n", key_idx); 2091 WL_CONN("key index (%d)\n", key_idx);
@@ -1659,25 +2112,33 @@ brcmf_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
1659 switch (params->cipher) { 2112 switch (params->cipher) {
1660 case WLAN_CIPHER_SUITE_WEP40: 2113 case WLAN_CIPHER_SUITE_WEP40:
1661 key.algo = CRYPTO_ALGO_WEP1; 2114 key.algo = CRYPTO_ALGO_WEP1;
2115 val = WEP_ENABLED;
1662 WL_CONN("WLAN_CIPHER_SUITE_WEP40\n"); 2116 WL_CONN("WLAN_CIPHER_SUITE_WEP40\n");
1663 break; 2117 break;
1664 case WLAN_CIPHER_SUITE_WEP104: 2118 case WLAN_CIPHER_SUITE_WEP104:
1665 key.algo = CRYPTO_ALGO_WEP128; 2119 key.algo = CRYPTO_ALGO_WEP128;
2120 val = WEP_ENABLED;
1666 WL_CONN("WLAN_CIPHER_SUITE_WEP104\n"); 2121 WL_CONN("WLAN_CIPHER_SUITE_WEP104\n");
1667 break; 2122 break;
1668 case WLAN_CIPHER_SUITE_TKIP: 2123 case WLAN_CIPHER_SUITE_TKIP:
1669 memcpy(keybuf, &key.data[24], sizeof(keybuf)); 2124 if (cfg->conf->mode != WL_MODE_AP) {
1670 memcpy(&key.data[24], &key.data[16], sizeof(keybuf)); 2125 WL_CONN("Swapping key\n");
1671 memcpy(&key.data[16], keybuf, sizeof(keybuf)); 2126 memcpy(keybuf, &key.data[24], sizeof(keybuf));
2127 memcpy(&key.data[24], &key.data[16], sizeof(keybuf));
2128 memcpy(&key.data[16], keybuf, sizeof(keybuf));
2129 }
1672 key.algo = CRYPTO_ALGO_TKIP; 2130 key.algo = CRYPTO_ALGO_TKIP;
2131 val = TKIP_ENABLED;
1673 WL_CONN("WLAN_CIPHER_SUITE_TKIP\n"); 2132 WL_CONN("WLAN_CIPHER_SUITE_TKIP\n");
1674 break; 2133 break;
1675 case WLAN_CIPHER_SUITE_AES_CMAC: 2134 case WLAN_CIPHER_SUITE_AES_CMAC:
1676 key.algo = CRYPTO_ALGO_AES_CCM; 2135 key.algo = CRYPTO_ALGO_AES_CCM;
2136 val = AES_ENABLED;
1677 WL_CONN("WLAN_CIPHER_SUITE_AES_CMAC\n"); 2137 WL_CONN("WLAN_CIPHER_SUITE_AES_CMAC\n");
1678 break; 2138 break;
1679 case WLAN_CIPHER_SUITE_CCMP: 2139 case WLAN_CIPHER_SUITE_CCMP:
1680 key.algo = CRYPTO_ALGO_AES_CCM; 2140 key.algo = CRYPTO_ALGO_AES_CCM;
2141 val = AES_ENABLED;
1681 WL_CONN("WLAN_CIPHER_SUITE_CCMP\n"); 2142 WL_CONN("WLAN_CIPHER_SUITE_CCMP\n");
1682 break; 2143 break;
1683 default: 2144 default:
@@ -1686,28 +2147,23 @@ brcmf_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
1686 goto done; 2147 goto done;
1687 } 2148 }
1688 2149
1689 err = send_key_to_dongle(ndev, &key); /* Set the new key/index */ 2150 bssidx = brcmf_find_bssidx(cfg, ndev);
2151 err = send_key_to_dongle(cfg, bssidx, ndev, &key);
1690 if (err) 2152 if (err)
1691 goto done; 2153 goto done;
1692 2154
1693 val = WEP_ENABLED; 2155 err = brcmf_dev_intvar_get_bsscfg(ndev, "wsec", &wsec, bssidx);
1694 err = brcmf_dev_intvar_get(ndev, "wsec", &wsec);
1695 if (err) { 2156 if (err) {
1696 WL_ERR("get wsec error (%d)\n", err); 2157 WL_ERR("get wsec error (%d)\n", err);
1697 goto done; 2158 goto done;
1698 } 2159 }
1699 wsec &= ~(WEP_ENABLED);
1700 wsec |= val; 2160 wsec |= val;
1701 err = brcmf_dev_intvar_set(ndev, "wsec", wsec); 2161 err = brcmf_dev_intvar_set_bsscfg(ndev, "wsec", wsec, bssidx);
1702 if (err) { 2162 if (err) {
1703 WL_ERR("set wsec error (%d)\n", err); 2163 WL_ERR("set wsec error (%d)\n", err);
1704 goto done; 2164 goto done;
1705 } 2165 }
1706 2166
1707 val = 1; /* assume shared key. otherwise 0 */
1708 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_AUTH, &val);
1709 if (err)
1710 WL_ERR("WLC_SET_AUTH error (%d)\n", err);
1711done: 2167done:
1712 WL_TRACE("Exit\n"); 2168 WL_TRACE("Exit\n");
1713 return err; 2169 return err;
@@ -1717,10 +2173,10 @@ static s32
1717brcmf_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev, 2173brcmf_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev,
1718 u8 key_idx, bool pairwise, const u8 *mac_addr) 2174 u8 key_idx, bool pairwise, const u8 *mac_addr)
1719{ 2175{
2176 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1720 struct brcmf_wsec_key key; 2177 struct brcmf_wsec_key key;
1721 s32 err = 0; 2178 s32 err = 0;
1722 s32 val; 2179 s32 bssidx;
1723 s32 wsec;
1724 2180
1725 WL_TRACE("Enter\n"); 2181 WL_TRACE("Enter\n");
1726 if (!check_sys_up(wiphy)) 2182 if (!check_sys_up(wiphy))
@@ -1735,7 +2191,8 @@ brcmf_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev,
1735 WL_CONN("key index (%d)\n", key_idx); 2191 WL_CONN("key index (%d)\n", key_idx);
1736 2192
1737 /* Set the new key/index */ 2193 /* Set the new key/index */
1738 err = send_key_to_dongle(ndev, &key); 2194 bssidx = brcmf_find_bssidx(cfg, ndev);
2195 err = send_key_to_dongle(cfg, bssidx, ndev, &key);
1739 if (err) { 2196 if (err) {
1740 if (err == -EINVAL) { 2197 if (err == -EINVAL) {
1741 if (key.index >= DOT11_MAX_DEFAULT_KEYS) 2198 if (key.index >= DOT11_MAX_DEFAULT_KEYS)
@@ -1744,35 +2201,8 @@ brcmf_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev,
1744 } 2201 }
1745 /* Ignore this error, may happen during DISASSOC */ 2202 /* Ignore this error, may happen during DISASSOC */
1746 err = -EAGAIN; 2203 err = -EAGAIN;
1747 goto done;
1748 } 2204 }
1749 2205
1750 val = 0;
1751 err = brcmf_dev_intvar_get(ndev, "wsec", &wsec);
1752 if (err) {
1753 WL_ERR("get wsec error (%d)\n", err);
1754 /* Ignore this error, may happen during DISASSOC */
1755 err = -EAGAIN;
1756 goto done;
1757 }
1758 wsec &= ~(WEP_ENABLED);
1759 wsec |= val;
1760 err = brcmf_dev_intvar_set(ndev, "wsec", wsec);
1761 if (err) {
1762 WL_ERR("set wsec error (%d)\n", err);
1763 /* Ignore this error, may happen during DISASSOC */
1764 err = -EAGAIN;
1765 goto done;
1766 }
1767
1768 val = 0; /* assume open key. otherwise 1 */
1769 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_AUTH, &val);
1770 if (err) {
1771 WL_ERR("WLC_SET_AUTH error (%d)\n", err);
1772 /* Ignore this error, may happen during DISASSOC */
1773 err = -EAGAIN;
1774 }
1775done:
1776 WL_TRACE("Exit\n"); 2206 WL_TRACE("Exit\n");
1777 return err; 2207 return err;
1778} 2208}
@@ -1783,10 +2213,12 @@ brcmf_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev,
1783 void (*callback) (void *cookie, struct key_params * params)) 2213 void (*callback) (void *cookie, struct key_params * params))
1784{ 2214{
1785 struct key_params params; 2215 struct key_params params;
1786 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy); 2216 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2217 struct brcmf_cfg80211_profile *profile = cfg->profile;
1787 struct brcmf_cfg80211_security *sec; 2218 struct brcmf_cfg80211_security *sec;
1788 s32 wsec; 2219 s32 wsec;
1789 s32 err = 0; 2220 s32 err = 0;
2221 s32 bssidx;
1790 2222
1791 WL_TRACE("Enter\n"); 2223 WL_TRACE("Enter\n");
1792 WL_CONN("key index (%d)\n", key_idx); 2224 WL_CONN("key index (%d)\n", key_idx);
@@ -1795,16 +2227,17 @@ brcmf_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev,
1795 2227
1796 memset(&params, 0, sizeof(params)); 2228 memset(&params, 0, sizeof(params));
1797 2229
1798 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_GET_WSEC, &wsec); 2230 bssidx = brcmf_find_bssidx(cfg, ndev);
2231 err = brcmf_dev_intvar_get_bsscfg(ndev, "wsec", &wsec, bssidx);
1799 if (err) { 2232 if (err) {
1800 WL_ERR("WLC_GET_WSEC error (%d)\n", err); 2233 WL_ERR("WLC_GET_WSEC error (%d)\n", err);
1801 /* Ignore this error, may happen during DISASSOC */ 2234 /* Ignore this error, may happen during DISASSOC */
1802 err = -EAGAIN; 2235 err = -EAGAIN;
1803 goto done; 2236 goto done;
1804 } 2237 }
1805 switch (wsec) { 2238 switch (wsec & ~SES_OW_ENABLED) {
1806 case WEP_ENABLED: 2239 case WEP_ENABLED:
1807 sec = brcmf_read_prof(cfg_priv, WL_PROF_SEC); 2240 sec = &profile->sec;
1808 if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP40) { 2241 if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP40) {
1809 params.cipher = WLAN_CIPHER_SUITE_WEP40; 2242 params.cipher = WLAN_CIPHER_SUITE_WEP40;
1810 WL_CONN("WLAN_CIPHER_SUITE_WEP40\n"); 2243 WL_CONN("WLAN_CIPHER_SUITE_WEP40\n");
@@ -1844,53 +2277,73 @@ brcmf_cfg80211_config_default_mgmt_key(struct wiphy *wiphy,
1844 2277
1845static s32 2278static s32
1846brcmf_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev, 2279brcmf_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev,
1847 u8 *mac, struct station_info *sinfo) 2280 u8 *mac, struct station_info *sinfo)
1848{ 2281{
1849 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy); 2282 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2283 struct brcmf_cfg80211_profile *profile = cfg->profile;
1850 struct brcmf_scb_val_le scb_val; 2284 struct brcmf_scb_val_le scb_val;
1851 int rssi; 2285 int rssi;
1852 s32 rate; 2286 s32 rate;
1853 s32 err = 0; 2287 s32 err = 0;
1854 u8 *bssid = brcmf_read_prof(cfg_priv, WL_PROF_BSSID); 2288 u8 *bssid = profile->bssid;
2289 struct brcmf_sta_info_le *sta_info_le;
1855 2290
1856 WL_TRACE("Enter\n"); 2291 WL_TRACE("Enter, MAC %pM\n", mac);
1857 if (!check_sys_up(wiphy)) 2292 if (!check_sys_up(wiphy))
1858 return -EIO; 2293 return -EIO;
1859 2294
1860 if (memcmp(mac, bssid, ETH_ALEN)) { 2295 if (cfg->conf->mode == WL_MODE_AP) {
1861 WL_ERR("Wrong Mac address cfg_mac-%X:%X:%X:%X:%X:%X" 2296 err = brcmf_dev_iovar_getbuf(ndev, "sta_info", mac, ETH_ALEN,
1862 "wl_bssid-%X:%X:%X:%X:%X:%X\n", 2297 cfg->dcmd_buf,
1863 mac[0], mac[1], mac[2], mac[3], mac[4], mac[5], 2298 WL_DCMD_LEN_MAX);
1864 bssid[0], bssid[1], bssid[2], bssid[3], 2299 if (err < 0) {
1865 bssid[4], bssid[5]); 2300 WL_ERR("GET STA INFO failed, %d\n", err);
1866 err = -ENOENT; 2301 goto done;
1867 goto done; 2302 }
1868 } 2303 sta_info_le = (struct brcmf_sta_info_le *)cfg->dcmd_buf;
1869
1870 /* Report the current tx rate */
1871 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_GET_RATE, &rate);
1872 if (err) {
1873 WL_ERR("Could not get rate (%d)\n", err);
1874 } else {
1875 sinfo->filled |= STATION_INFO_TX_BITRATE;
1876 sinfo->txrate.legacy = rate * 5;
1877 WL_CONN("Rate %d Mbps\n", rate / 2);
1878 }
1879 2304
1880 if (test_bit(WL_STATUS_CONNECTED, &cfg_priv->status)) { 2305 sinfo->filled = STATION_INFO_INACTIVE_TIME;
1881 memset(&scb_val, 0, sizeof(scb_val)); 2306 sinfo->inactive_time = le32_to_cpu(sta_info_le->idle) * 1000;
1882 err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_RSSI, &scb_val, 2307 if (le32_to_cpu(sta_info_le->flags) & BRCMF_STA_ASSOC) {
1883 sizeof(struct brcmf_scb_val_le)); 2308 sinfo->filled |= STATION_INFO_CONNECTED_TIME;
2309 sinfo->connected_time = le32_to_cpu(sta_info_le->in);
2310 }
2311 WL_TRACE("STA idle time : %d ms, connected time :%d sec\n",
2312 sinfo->inactive_time, sinfo->connected_time);
2313 } else if (cfg->conf->mode == WL_MODE_BSS) {
2314 if (memcmp(mac, bssid, ETH_ALEN)) {
2315 WL_ERR("Wrong Mac address cfg_mac-%pM wl_bssid-%pM\n",
2316 mac, bssid);
2317 err = -ENOENT;
2318 goto done;
2319 }
2320 /* Report the current tx rate */
2321 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_GET_RATE, &rate);
1884 if (err) { 2322 if (err) {
1885 WL_ERR("Could not get rssi (%d)\n", err); 2323 WL_ERR("Could not get rate (%d)\n", err);
2324 goto done;
1886 } else { 2325 } else {
1887 rssi = le32_to_cpu(scb_val.val); 2326 sinfo->filled |= STATION_INFO_TX_BITRATE;
1888 sinfo->filled |= STATION_INFO_SIGNAL; 2327 sinfo->txrate.legacy = rate * 5;
1889 sinfo->signal = rssi; 2328 WL_CONN("Rate %d Mbps\n", rate / 2);
1890 WL_CONN("RSSI %d dBm\n", rssi);
1891 } 2329 }
1892 }
1893 2330
2331 if (test_bit(WL_STATUS_CONNECTED, &cfg->status)) {
2332 memset(&scb_val, 0, sizeof(scb_val));
2333 err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_RSSI, &scb_val,
2334 sizeof(scb_val));
2335 if (err) {
2336 WL_ERR("Could not get rssi (%d)\n", err);
2337 goto done;
2338 } else {
2339 rssi = le32_to_cpu(scb_val.val);
2340 sinfo->filled |= STATION_INFO_SIGNAL;
2341 sinfo->signal = rssi;
2342 WL_CONN("RSSI %d dBm\n", rssi);
2343 }
2344 }
2345 } else
2346 err = -EPERM;
1894done: 2347done:
1895 WL_TRACE("Exit\n"); 2348 WL_TRACE("Exit\n");
1896 return err; 2349 return err;
@@ -1902,7 +2355,7 @@ brcmf_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *ndev,
1902{ 2355{
1903 s32 pm; 2356 s32 pm;
1904 s32 err = 0; 2357 s32 err = 0;
1905 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy); 2358 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1906 2359
1907 WL_TRACE("Enter\n"); 2360 WL_TRACE("Enter\n");
1908 2361
@@ -1910,14 +2363,13 @@ brcmf_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *ndev,
1910 * Powersave enable/disable request is coming from the 2363 * Powersave enable/disable request is coming from the
1911 * cfg80211 even before the interface is up. In that 2364 * cfg80211 even before the interface is up. In that
1912 * scenario, driver will be storing the power save 2365 * scenario, driver will be storing the power save
1913 * preference in cfg_priv struct to apply this to 2366 * preference in cfg struct to apply this to
1914 * FW later while initializing the dongle 2367 * FW later while initializing the dongle
1915 */ 2368 */
1916 cfg_priv->pwr_save = enabled; 2369 cfg->pwr_save = enabled;
1917 if (!test_bit(WL_STATUS_READY, &cfg_priv->status)) { 2370 if (!test_bit(WL_STATUS_READY, &cfg->status)) {
1918 2371
1919 WL_INFO("Device is not ready," 2372 WL_INFO("Device is not ready, storing the value in cfg_info struct\n");
1920 "storing the value in cfg_priv struct\n");
1921 goto done; 2373 goto done;
1922 } 2374 }
1923 2375
@@ -1995,10 +2447,10 @@ done:
1995 return err; 2447 return err;
1996} 2448}
1997 2449
1998static s32 brcmf_inform_single_bss(struct brcmf_cfg80211_priv *cfg_priv, 2450static s32 brcmf_inform_single_bss(struct brcmf_cfg80211_info *cfg,
1999 struct brcmf_bss_info_le *bi) 2451 struct brcmf_bss_info_le *bi)
2000{ 2452{
2001 struct wiphy *wiphy = cfg_to_wiphy(cfg_priv); 2453 struct wiphy *wiphy = cfg_to_wiphy(cfg);
2002 struct ieee80211_channel *notify_channel; 2454 struct ieee80211_channel *notify_channel;
2003 struct cfg80211_bss *bss; 2455 struct cfg80211_bss *bss;
2004 struct ieee80211_supported_band *band; 2456 struct ieee80211_supported_band *band;
@@ -2062,14 +2514,14 @@ next_bss_le(struct brcmf_scan_results *list, struct brcmf_bss_info_le *bss)
2062 le32_to_cpu(bss->length)); 2514 le32_to_cpu(bss->length));
2063} 2515}
2064 2516
2065static s32 brcmf_inform_bss(struct brcmf_cfg80211_priv *cfg_priv) 2517static s32 brcmf_inform_bss(struct brcmf_cfg80211_info *cfg)
2066{ 2518{
2067 struct brcmf_scan_results *bss_list; 2519 struct brcmf_scan_results *bss_list;
2068 struct brcmf_bss_info_le *bi = NULL; /* must be initialized */ 2520 struct brcmf_bss_info_le *bi = NULL; /* must be initialized */
2069 s32 err = 0; 2521 s32 err = 0;
2070 int i; 2522 int i;
2071 2523
2072 bss_list = cfg_priv->bss_list; 2524 bss_list = cfg->bss_list;
2073 if (bss_list->version != BRCMF_BSS_INFO_VERSION) { 2525 if (bss_list->version != BRCMF_BSS_INFO_VERSION) {
2074 WL_ERR("Version %d != WL_BSS_INFO_VERSION\n", 2526 WL_ERR("Version %d != WL_BSS_INFO_VERSION\n",
2075 bss_list->version); 2527 bss_list->version);
@@ -2078,17 +2530,17 @@ static s32 brcmf_inform_bss(struct brcmf_cfg80211_priv *cfg_priv)
2078 WL_SCAN("scanned AP count (%d)\n", bss_list->count); 2530 WL_SCAN("scanned AP count (%d)\n", bss_list->count);
2079 for (i = 0; i < bss_list->count && i < WL_AP_MAX; i++) { 2531 for (i = 0; i < bss_list->count && i < WL_AP_MAX; i++) {
2080 bi = next_bss_le(bss_list, bi); 2532 bi = next_bss_le(bss_list, bi);
2081 err = brcmf_inform_single_bss(cfg_priv, bi); 2533 err = brcmf_inform_single_bss(cfg, bi);
2082 if (err) 2534 if (err)
2083 break; 2535 break;
2084 } 2536 }
2085 return err; 2537 return err;
2086} 2538}
2087 2539
2088static s32 wl_inform_ibss(struct brcmf_cfg80211_priv *cfg_priv, 2540static s32 wl_inform_ibss(struct brcmf_cfg80211_info *cfg,
2089 struct net_device *ndev, const u8 *bssid) 2541 struct net_device *ndev, const u8 *bssid)
2090{ 2542{
2091 struct wiphy *wiphy = cfg_to_wiphy(cfg_priv); 2543 struct wiphy *wiphy = cfg_to_wiphy(cfg);
2092 struct ieee80211_channel *notify_channel; 2544 struct ieee80211_channel *notify_channel;
2093 struct brcmf_bss_info_le *bi = NULL; 2545 struct brcmf_bss_info_le *bi = NULL;
2094 struct ieee80211_supported_band *band; 2546 struct ieee80211_supported_band *band;
@@ -2163,9 +2615,9 @@ CleanUp:
2163 return err; 2615 return err;
2164} 2616}
2165 2617
2166static bool brcmf_is_ibssmode(struct brcmf_cfg80211_priv *cfg_priv) 2618static bool brcmf_is_ibssmode(struct brcmf_cfg80211_info *cfg)
2167{ 2619{
2168 return cfg_priv->conf->mode == WL_MODE_IBSS; 2620 return cfg->conf->mode == WL_MODE_IBSS;
2169} 2621}
2170 2622
2171/* 2623/*
@@ -2182,22 +2634,62 @@ static struct brcmf_tlv *brcmf_parse_tlvs(void *buf, int buflen, uint key)
2182 totlen = buflen; 2634 totlen = buflen;
2183 2635
2184 /* find tagged parameter */ 2636 /* find tagged parameter */
2185 while (totlen >= 2) { 2637 while (totlen >= TLV_HDR_LEN) {
2186 int len = elt->len; 2638 int len = elt->len;
2187 2639
2188 /* validate remaining totlen */ 2640 /* validate remaining totlen */
2189 if ((elt->id == key) && (totlen >= (len + 2))) 2641 if ((elt->id == key) && (totlen >= (len + TLV_HDR_LEN)))
2190 return elt; 2642 return elt;
2191 2643
2192 elt = (struct brcmf_tlv *) ((u8 *) elt + (len + 2)); 2644 elt = (struct brcmf_tlv *) ((u8 *) elt + (len + TLV_HDR_LEN));
2193 totlen -= (len + 2); 2645 totlen -= (len + TLV_HDR_LEN);
2194 } 2646 }
2195 2647
2196 return NULL; 2648 return NULL;
2197} 2649}
2198 2650
2199static s32 brcmf_update_bss_info(struct brcmf_cfg80211_priv *cfg_priv) 2651/* Is any of the tlvs the expected entry? If
2652 * not update the tlvs buffer pointer/length.
2653 */
2654static bool
2655brcmf_tlv_has_ie(u8 *ie, u8 **tlvs, u32 *tlvs_len,
2656 u8 *oui, u32 oui_len, u8 type)
2657{
2658 /* If the contents match the OUI and the type */
2659 if (ie[TLV_LEN_OFF] >= oui_len + 1 &&
2660 !memcmp(&ie[TLV_BODY_OFF], oui, oui_len) &&
2661 type == ie[TLV_BODY_OFF + oui_len]) {
2662 return true;
2663 }
2664
2665 if (tlvs == NULL)
2666 return false;
2667 /* point to the next ie */
2668 ie += ie[TLV_LEN_OFF] + TLV_HDR_LEN;
2669 /* calculate the length of the rest of the buffer */
2670 *tlvs_len -= (int)(ie - *tlvs);
2671 /* update the pointer to the start of the buffer */
2672 *tlvs = ie;
2673
2674 return false;
2675}
2676
2677struct brcmf_vs_tlv *
2678brcmf_find_wpaie(u8 *parse, u32 len)
2679{
2680 struct brcmf_tlv *ie;
2681
2682 while ((ie = brcmf_parse_tlvs(parse, len, WLAN_EID_WPA))) {
2683 if (brcmf_tlv_has_ie((u8 *)ie, &parse, &len,
2684 WPA_OUI, TLV_OUI_LEN, WPA_OUI_TYPE))
2685 return (struct brcmf_vs_tlv *)ie;
2686 }
2687 return NULL;
2688}
2689
2690static s32 brcmf_update_bss_info(struct brcmf_cfg80211_info *cfg)
2200{ 2691{
2692 struct brcmf_cfg80211_profile *profile = cfg->profile;
2201 struct brcmf_bss_info_le *bi; 2693 struct brcmf_bss_info_le *bi;
2202 struct brcmf_ssid *ssid; 2694 struct brcmf_ssid *ssid;
2203 struct brcmf_tlv *tim; 2695 struct brcmf_tlv *tim;
@@ -2208,21 +2700,21 @@ static s32 brcmf_update_bss_info(struct brcmf_cfg80211_priv *cfg_priv)
2208 s32 err = 0; 2700 s32 err = 0;
2209 2701
2210 WL_TRACE("Enter\n"); 2702 WL_TRACE("Enter\n");
2211 if (brcmf_is_ibssmode(cfg_priv)) 2703 if (brcmf_is_ibssmode(cfg))
2212 return err; 2704 return err;
2213 2705
2214 ssid = (struct brcmf_ssid *)brcmf_read_prof(cfg_priv, WL_PROF_SSID); 2706 ssid = &profile->ssid;
2215 2707
2216 *(__le32 *)cfg_priv->extra_buf = cpu_to_le32(WL_EXTRA_BUF_MAX); 2708 *(__le32 *)cfg->extra_buf = cpu_to_le32(WL_EXTRA_BUF_MAX);
2217 err = brcmf_exec_dcmd(cfg_to_ndev(cfg_priv), BRCMF_C_GET_BSS_INFO, 2709 err = brcmf_exec_dcmd(cfg_to_ndev(cfg), BRCMF_C_GET_BSS_INFO,
2218 cfg_priv->extra_buf, WL_EXTRA_BUF_MAX); 2710 cfg->extra_buf, WL_EXTRA_BUF_MAX);
2219 if (err) { 2711 if (err) {
2220 WL_ERR("Could not get bss info %d\n", err); 2712 WL_ERR("Could not get bss info %d\n", err);
2221 goto update_bss_info_out; 2713 goto update_bss_info_out;
2222 } 2714 }
2223 2715
2224 bi = (struct brcmf_bss_info_le *)(cfg_priv->extra_buf + 4); 2716 bi = (struct brcmf_bss_info_le *)(cfg->extra_buf + 4);
2225 err = brcmf_inform_single_bss(cfg_priv, bi); 2717 err = brcmf_inform_single_bss(cfg, bi);
2226 if (err) 2718 if (err)
2227 goto update_bss_info_out; 2719 goto update_bss_info_out;
2228 2720
@@ -2240,7 +2732,7 @@ static s32 brcmf_update_bss_info(struct brcmf_cfg80211_priv *cfg_priv)
2240 * so we speficially query dtim information to dongle. 2732 * so we speficially query dtim information to dongle.
2241 */ 2733 */
2242 u32 var; 2734 u32 var;
2243 err = brcmf_dev_intvar_get(cfg_to_ndev(cfg_priv), 2735 err = brcmf_dev_intvar_get(cfg_to_ndev(cfg),
2244 "dtim_assoc", &var); 2736 "dtim_assoc", &var);
2245 if (err) { 2737 if (err) {
2246 WL_ERR("wl dtim_assoc failed (%d)\n", err); 2738 WL_ERR("wl dtim_assoc failed (%d)\n", err);
@@ -2249,20 +2741,22 @@ static s32 brcmf_update_bss_info(struct brcmf_cfg80211_priv *cfg_priv)
2249 dtim_period = (u8)var; 2741 dtim_period = (u8)var;
2250 } 2742 }
2251 2743
2252 brcmf_update_prof(cfg_priv, NULL, &beacon_interval, WL_PROF_BEACONINT); 2744 profile->beacon_interval = beacon_interval;
2253 brcmf_update_prof(cfg_priv, NULL, &dtim_period, WL_PROF_DTIMPERIOD); 2745 profile->dtim_period = dtim_period;
2254 2746
2255update_bss_info_out: 2747update_bss_info_out:
2256 WL_TRACE("Exit"); 2748 WL_TRACE("Exit");
2257 return err; 2749 return err;
2258} 2750}
2259 2751
2260static void brcmf_term_iscan(struct brcmf_cfg80211_priv *cfg_priv) 2752static void brcmf_abort_scanning(struct brcmf_cfg80211_info *cfg)
2261{ 2753{
2262 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg_priv); 2754 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg);
2755 struct escan_info *escan = &cfg->escan_info;
2263 struct brcmf_ssid ssid; 2756 struct brcmf_ssid ssid;
2264 2757
2265 if (cfg_priv->iscan_on) { 2758 set_bit(WL_STATUS_SCAN_ABORTING, &cfg->status);
2759 if (cfg->iscan_on) {
2266 iscan->state = WL_ISCAN_STATE_IDLE; 2760 iscan->state = WL_ISCAN_STATE_IDLE;
2267 2761
2268 if (iscan->timer_on) { 2762 if (iscan->timer_on) {
@@ -2275,27 +2769,40 @@ static void brcmf_term_iscan(struct brcmf_cfg80211_priv *cfg_priv)
2275 /* Abort iscan running in FW */ 2769 /* Abort iscan running in FW */
2276 memset(&ssid, 0, sizeof(ssid)); 2770 memset(&ssid, 0, sizeof(ssid));
2277 brcmf_run_iscan(iscan, &ssid, WL_SCAN_ACTION_ABORT); 2771 brcmf_run_iscan(iscan, &ssid, WL_SCAN_ACTION_ABORT);
2772
2773 if (cfg->scan_request) {
2774 /* Indidate scan abort to cfg80211 layer */
2775 WL_INFO("Terminating scan in progress\n");
2776 cfg80211_scan_done(cfg->scan_request, true);
2777 cfg->scan_request = NULL;
2778 }
2779 }
2780 if (cfg->escan_on && cfg->scan_request) {
2781 escan->escan_state = WL_ESCAN_STATE_IDLE;
2782 brcmf_notify_escan_complete(cfg, escan->ndev, true, true);
2278 } 2783 }
2784 clear_bit(WL_STATUS_SCANNING, &cfg->status);
2785 clear_bit(WL_STATUS_SCAN_ABORTING, &cfg->status);
2279} 2786}
2280 2787
2281static void brcmf_notify_iscan_complete(struct brcmf_cfg80211_iscan_ctrl *iscan, 2788static void brcmf_notify_iscan_complete(struct brcmf_cfg80211_iscan_ctrl *iscan,
2282 bool aborted) 2789 bool aborted)
2283{ 2790{
2284 struct brcmf_cfg80211_priv *cfg_priv = iscan_to_cfg(iscan); 2791 struct brcmf_cfg80211_info *cfg = iscan_to_cfg(iscan);
2285 struct net_device *ndev = cfg_to_ndev(cfg_priv); 2792 struct net_device *ndev = cfg_to_ndev(cfg);
2286 2793
2287 if (!test_and_clear_bit(WL_STATUS_SCANNING, &cfg_priv->status)) { 2794 if (!test_and_clear_bit(WL_STATUS_SCANNING, &cfg->status)) {
2288 WL_ERR("Scan complete while device not scanning\n"); 2795 WL_ERR("Scan complete while device not scanning\n");
2289 return; 2796 return;
2290 } 2797 }
2291 if (cfg_priv->scan_request) { 2798 if (cfg->scan_request) {
2292 WL_SCAN("ISCAN Completed scan: %s\n", 2799 WL_SCAN("ISCAN Completed scan: %s\n",
2293 aborted ? "Aborted" : "Done"); 2800 aborted ? "Aborted" : "Done");
2294 cfg80211_scan_done(cfg_priv->scan_request, aborted); 2801 cfg80211_scan_done(cfg->scan_request, aborted);
2295 brcmf_set_mpc(ndev, 1); 2802 brcmf_set_mpc(ndev, 1);
2296 cfg_priv->scan_request = NULL; 2803 cfg->scan_request = NULL;
2297 } 2804 }
2298 cfg_priv->iscan_kickstart = false; 2805 cfg->iscan_kickstart = false;
2299} 2806}
2300 2807
2301static s32 brcmf_wakeup_iscan(struct brcmf_cfg80211_iscan_ctrl *iscan) 2808static s32 brcmf_wakeup_iscan(struct brcmf_cfg80211_iscan_ctrl *iscan)
@@ -2348,21 +2855,21 @@ brcmf_get_iscan_results(struct brcmf_cfg80211_iscan_ctrl *iscan, u32 *status,
2348 return err; 2855 return err;
2349} 2856}
2350 2857
2351static s32 brcmf_iscan_done(struct brcmf_cfg80211_priv *cfg_priv) 2858static s32 brcmf_iscan_done(struct brcmf_cfg80211_info *cfg)
2352{ 2859{
2353 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_priv->iscan; 2860 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg->iscan;
2354 s32 err = 0; 2861 s32 err = 0;
2355 2862
2356 iscan->state = WL_ISCAN_STATE_IDLE; 2863 iscan->state = WL_ISCAN_STATE_IDLE;
2357 brcmf_inform_bss(cfg_priv); 2864 brcmf_inform_bss(cfg);
2358 brcmf_notify_iscan_complete(iscan, false); 2865 brcmf_notify_iscan_complete(iscan, false);
2359 2866
2360 return err; 2867 return err;
2361} 2868}
2362 2869
2363static s32 brcmf_iscan_pending(struct brcmf_cfg80211_priv *cfg_priv) 2870static s32 brcmf_iscan_pending(struct brcmf_cfg80211_info *cfg)
2364{ 2871{
2365 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_priv->iscan; 2872 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg->iscan;
2366 s32 err = 0; 2873 s32 err = 0;
2367 2874
2368 /* Reschedule the timer */ 2875 /* Reschedule the timer */
@@ -2372,12 +2879,12 @@ static s32 brcmf_iscan_pending(struct brcmf_cfg80211_priv *cfg_priv)
2372 return err; 2879 return err;
2373} 2880}
2374 2881
2375static s32 brcmf_iscan_inprogress(struct brcmf_cfg80211_priv *cfg_priv) 2882static s32 brcmf_iscan_inprogress(struct brcmf_cfg80211_info *cfg)
2376{ 2883{
2377 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_priv->iscan; 2884 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg->iscan;
2378 s32 err = 0; 2885 s32 err = 0;
2379 2886
2380 brcmf_inform_bss(cfg_priv); 2887 brcmf_inform_bss(cfg);
2381 brcmf_run_iscan(iscan, NULL, BRCMF_SCAN_ACTION_CONTINUE); 2888 brcmf_run_iscan(iscan, NULL, BRCMF_SCAN_ACTION_CONTINUE);
2382 /* Reschedule the timer */ 2889 /* Reschedule the timer */
2383 mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000); 2890 mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000);
@@ -2386,9 +2893,9 @@ static s32 brcmf_iscan_inprogress(struct brcmf_cfg80211_priv *cfg_priv)
2386 return err; 2893 return err;
2387} 2894}
2388 2895
2389static s32 brcmf_iscan_aborted(struct brcmf_cfg80211_priv *cfg_priv) 2896static s32 brcmf_iscan_aborted(struct brcmf_cfg80211_info *cfg)
2390{ 2897{
2391 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_priv->iscan; 2898 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg->iscan;
2392 s32 err = 0; 2899 s32 err = 0;
2393 2900
2394 iscan->state = WL_ISCAN_STATE_IDLE; 2901 iscan->state = WL_ISCAN_STATE_IDLE;
@@ -2402,7 +2909,7 @@ static void brcmf_cfg80211_iscan_handler(struct work_struct *work)
2402 struct brcmf_cfg80211_iscan_ctrl *iscan = 2909 struct brcmf_cfg80211_iscan_ctrl *iscan =
2403 container_of(work, struct brcmf_cfg80211_iscan_ctrl, 2910 container_of(work, struct brcmf_cfg80211_iscan_ctrl,
2404 work); 2911 work);
2405 struct brcmf_cfg80211_priv *cfg_priv = iscan_to_cfg(iscan); 2912 struct brcmf_cfg80211_info *cfg = iscan_to_cfg(iscan);
2406 struct brcmf_cfg80211_iscan_eloop *el = &iscan->el; 2913 struct brcmf_cfg80211_iscan_eloop *el = &iscan->el;
2407 u32 status = BRCMF_SCAN_RESULTS_PARTIAL; 2914 u32 status = BRCMF_SCAN_RESULTS_PARTIAL;
2408 2915
@@ -2411,12 +2918,12 @@ static void brcmf_cfg80211_iscan_handler(struct work_struct *work)
2411 iscan->timer_on = 0; 2918 iscan->timer_on = 0;
2412 } 2919 }
2413 2920
2414 if (brcmf_get_iscan_results(iscan, &status, &cfg_priv->bss_list)) { 2921 if (brcmf_get_iscan_results(iscan, &status, &cfg->bss_list)) {
2415 status = BRCMF_SCAN_RESULTS_ABORTED; 2922 status = BRCMF_SCAN_RESULTS_ABORTED;
2416 WL_ERR("Abort iscan\n"); 2923 WL_ERR("Abort iscan\n");
2417 } 2924 }
2418 2925
2419 el->handler[status](cfg_priv); 2926 el->handler[status](cfg);
2420} 2927}
2421 2928
2422static void brcmf_iscan_timer(unsigned long data) 2929static void brcmf_iscan_timer(unsigned long data)
@@ -2431,11 +2938,11 @@ static void brcmf_iscan_timer(unsigned long data)
2431 } 2938 }
2432} 2939}
2433 2940
2434static s32 brcmf_invoke_iscan(struct brcmf_cfg80211_priv *cfg_priv) 2941static s32 brcmf_invoke_iscan(struct brcmf_cfg80211_info *cfg)
2435{ 2942{
2436 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg_priv); 2943 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg);
2437 2944
2438 if (cfg_priv->iscan_on) { 2945 if (cfg->iscan_on) {
2439 iscan->state = WL_ISCAN_STATE_IDLE; 2946 iscan->state = WL_ISCAN_STATE_IDLE;
2440 INIT_WORK(&iscan->work, brcmf_cfg80211_iscan_handler); 2947 INIT_WORK(&iscan->work, brcmf_cfg80211_iscan_handler);
2441 } 2948 }
@@ -2453,26 +2960,192 @@ static void brcmf_init_iscan_eloop(struct brcmf_cfg80211_iscan_eloop *el)
2453 el->handler[BRCMF_SCAN_RESULTS_NO_MEM] = brcmf_iscan_aborted; 2960 el->handler[BRCMF_SCAN_RESULTS_NO_MEM] = brcmf_iscan_aborted;
2454} 2961}
2455 2962
2456static s32 brcmf_init_iscan(struct brcmf_cfg80211_priv *cfg_priv) 2963static s32 brcmf_init_iscan(struct brcmf_cfg80211_info *cfg)
2457{ 2964{
2458 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg_priv); 2965 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg);
2459 int err = 0; 2966 int err = 0;
2460 2967
2461 if (cfg_priv->iscan_on) { 2968 if (cfg->iscan_on) {
2462 iscan->ndev = cfg_to_ndev(cfg_priv); 2969 iscan->ndev = cfg_to_ndev(cfg);
2463 brcmf_init_iscan_eloop(&iscan->el); 2970 brcmf_init_iscan_eloop(&iscan->el);
2464 iscan->timer_ms = WL_ISCAN_TIMER_INTERVAL_MS; 2971 iscan->timer_ms = WL_ISCAN_TIMER_INTERVAL_MS;
2465 init_timer(&iscan->timer); 2972 init_timer(&iscan->timer);
2466 iscan->timer.data = (unsigned long) iscan; 2973 iscan->timer.data = (unsigned long) iscan;
2467 iscan->timer.function = brcmf_iscan_timer; 2974 iscan->timer.function = brcmf_iscan_timer;
2468 err = brcmf_invoke_iscan(cfg_priv); 2975 err = brcmf_invoke_iscan(cfg);
2469 if (!err) 2976 if (!err)
2470 iscan->data = cfg_priv; 2977 iscan->data = cfg;
2471 } 2978 }
2472 2979
2473 return err; 2980 return err;
2474} 2981}
2475 2982
2983static void brcmf_cfg80211_escan_timeout_worker(struct work_struct *work)
2984{
2985 struct brcmf_cfg80211_info *cfg =
2986 container_of(work, struct brcmf_cfg80211_info,
2987 escan_timeout_work);
2988
2989 brcmf_notify_escan_complete(cfg,
2990 cfg->escan_info.ndev, true, true);
2991}
2992
2993static void brcmf_escan_timeout(unsigned long data)
2994{
2995 struct brcmf_cfg80211_info *cfg =
2996 (struct brcmf_cfg80211_info *)data;
2997
2998 if (cfg->scan_request) {
2999 WL_ERR("timer expired\n");
3000 if (cfg->escan_on)
3001 schedule_work(&cfg->escan_timeout_work);
3002 }
3003}
3004
3005static s32
3006brcmf_compare_update_same_bss(struct brcmf_bss_info_le *bss,
3007 struct brcmf_bss_info_le *bss_info_le)
3008{
3009 if (!memcmp(&bss_info_le->BSSID, &bss->BSSID, ETH_ALEN) &&
3010 (CHSPEC_BAND(le16_to_cpu(bss_info_le->chanspec)) ==
3011 CHSPEC_BAND(le16_to_cpu(bss->chanspec))) &&
3012 bss_info_le->SSID_len == bss->SSID_len &&
3013 !memcmp(bss_info_le->SSID, bss->SSID, bss_info_le->SSID_len)) {
3014 if ((bss->flags & WLC_BSS_RSSI_ON_CHANNEL) ==
3015 (bss_info_le->flags & WLC_BSS_RSSI_ON_CHANNEL)) {
3016 s16 bss_rssi = le16_to_cpu(bss->RSSI);
3017 s16 bss_info_rssi = le16_to_cpu(bss_info_le->RSSI);
3018
3019 /* preserve max RSSI if the measurements are
3020 * both on-channel or both off-channel
3021 */
3022 if (bss_info_rssi > bss_rssi)
3023 bss->RSSI = bss_info_le->RSSI;
3024 } else if ((bss->flags & WLC_BSS_RSSI_ON_CHANNEL) &&
3025 (bss_info_le->flags & WLC_BSS_RSSI_ON_CHANNEL) == 0) {
3026 /* preserve the on-channel rssi measurement
3027 * if the new measurement is off channel
3028 */
3029 bss->RSSI = bss_info_le->RSSI;
3030 bss->flags |= WLC_BSS_RSSI_ON_CHANNEL;
3031 }
3032 return 1;
3033 }
3034 return 0;
3035}
3036
3037static s32
3038brcmf_cfg80211_escan_handler(struct brcmf_cfg80211_info *cfg,
3039 struct net_device *ndev,
3040 const struct brcmf_event_msg *e, void *data)
3041{
3042 s32 status;
3043 s32 err = 0;
3044 struct brcmf_escan_result_le *escan_result_le;
3045 struct brcmf_bss_info_le *bss_info_le;
3046 struct brcmf_bss_info_le *bss = NULL;
3047 u32 bi_length;
3048 struct brcmf_scan_results *list;
3049 u32 i;
3050 bool aborted;
3051
3052 status = be32_to_cpu(e->status);
3053
3054 if (!ndev || !cfg->escan_on ||
3055 !test_bit(WL_STATUS_SCANNING, &cfg->status)) {
3056 WL_ERR("scan not ready ndev %p wl->escan_on %d drv_status %x\n",
3057 ndev, cfg->escan_on,
3058 !test_bit(WL_STATUS_SCANNING, &cfg->status));
3059 return -EPERM;
3060 }
3061
3062 if (status == BRCMF_E_STATUS_PARTIAL) {
3063 WL_SCAN("ESCAN Partial result\n");
3064 escan_result_le = (struct brcmf_escan_result_le *) data;
3065 if (!escan_result_le) {
3066 WL_ERR("Invalid escan result (NULL pointer)\n");
3067 goto exit;
3068 }
3069 if (!cfg->scan_request) {
3070 WL_SCAN("result without cfg80211 request\n");
3071 goto exit;
3072 }
3073
3074 if (le16_to_cpu(escan_result_le->bss_count) != 1) {
3075 WL_ERR("Invalid bss_count %d: ignoring\n",
3076 escan_result_le->bss_count);
3077 goto exit;
3078 }
3079 bss_info_le = &escan_result_le->bss_info_le;
3080
3081 bi_length = le32_to_cpu(bss_info_le->length);
3082 if (bi_length != (le32_to_cpu(escan_result_le->buflen) -
3083 WL_ESCAN_RESULTS_FIXED_SIZE)) {
3084 WL_ERR("Invalid bss_info length %d: ignoring\n",
3085 bi_length);
3086 goto exit;
3087 }
3088
3089 if (!(cfg_to_wiphy(cfg)->interface_modes &
3090 BIT(NL80211_IFTYPE_ADHOC))) {
3091 if (le16_to_cpu(bss_info_le->capability) &
3092 WLAN_CAPABILITY_IBSS) {
3093 WL_ERR("Ignoring IBSS result\n");
3094 goto exit;
3095 }
3096 }
3097
3098 list = (struct brcmf_scan_results *)
3099 cfg->escan_info.escan_buf;
3100 if (bi_length > WL_ESCAN_BUF_SIZE - list->buflen) {
3101 WL_ERR("Buffer is too small: ignoring\n");
3102 goto exit;
3103 }
3104
3105 for (i = 0; i < list->count; i++) {
3106 bss = bss ? (struct brcmf_bss_info_le *)
3107 ((unsigned char *)bss +
3108 le32_to_cpu(bss->length)) : list->bss_info_le;
3109 if (brcmf_compare_update_same_bss(bss, bss_info_le))
3110 goto exit;
3111 }
3112 memcpy(&(cfg->escan_info.escan_buf[list->buflen]),
3113 bss_info_le, bi_length);
3114 list->version = le32_to_cpu(bss_info_le->version);
3115 list->buflen += bi_length;
3116 list->count++;
3117 } else {
3118 cfg->escan_info.escan_state = WL_ESCAN_STATE_IDLE;
3119 if (cfg->scan_request) {
3120 cfg->bss_list = (struct brcmf_scan_results *)
3121 cfg->escan_info.escan_buf;
3122 brcmf_inform_bss(cfg);
3123 aborted = status != BRCMF_E_STATUS_SUCCESS;
3124 brcmf_notify_escan_complete(cfg, ndev, aborted,
3125 false);
3126 } else
3127 WL_ERR("Unexpected scan result 0x%x\n", status);
3128 }
3129exit:
3130 return err;
3131}
3132
3133static void brcmf_init_escan(struct brcmf_cfg80211_info *cfg)
3134{
3135
3136 if (cfg->escan_on) {
3137 cfg->el.handler[BRCMF_E_ESCAN_RESULT] =
3138 brcmf_cfg80211_escan_handler;
3139 cfg->escan_info.escan_state = WL_ESCAN_STATE_IDLE;
3140 /* Init scan_timeout timer */
3141 init_timer(&cfg->escan_timeout);
3142 cfg->escan_timeout.data = (unsigned long) cfg;
3143 cfg->escan_timeout.function = brcmf_escan_timeout;
3144 INIT_WORK(&cfg->escan_timeout_work,
3145 brcmf_cfg80211_escan_timeout_worker);
3146 }
3147}
3148
2476static __always_inline void brcmf_delay(u32 ms) 3149static __always_inline void brcmf_delay(u32 ms)
2477{ 3150{
2478 if (ms < 1000 / HZ) { 3151 if (ms < 1000 / HZ) {
@@ -2485,7 +3158,7 @@ static __always_inline void brcmf_delay(u32 ms)
2485 3158
2486static s32 brcmf_cfg80211_resume(struct wiphy *wiphy) 3159static s32 brcmf_cfg80211_resume(struct wiphy *wiphy)
2487{ 3160{
2488 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy); 3161 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2489 3162
2490 /* 3163 /*
2491 * Check for WL_STATUS_READY before any function call which 3164 * Check for WL_STATUS_READY before any function call which
@@ -2494,7 +3167,7 @@ static s32 brcmf_cfg80211_resume(struct wiphy *wiphy)
2494 */ 3167 */
2495 WL_TRACE("Enter\n"); 3168 WL_TRACE("Enter\n");
2496 3169
2497 if (test_bit(WL_STATUS_READY, &cfg_priv->status)) 3170 if (test_bit(WL_STATUS_READY, &cfg->status))
2498 brcmf_invoke_iscan(wiphy_to_cfg(wiphy)); 3171 brcmf_invoke_iscan(wiphy_to_cfg(wiphy));
2499 3172
2500 WL_TRACE("Exit\n"); 3173 WL_TRACE("Exit\n");
@@ -2504,8 +3177,8 @@ static s32 brcmf_cfg80211_resume(struct wiphy *wiphy)
2504static s32 brcmf_cfg80211_suspend(struct wiphy *wiphy, 3177static s32 brcmf_cfg80211_suspend(struct wiphy *wiphy,
2505 struct cfg80211_wowlan *wow) 3178 struct cfg80211_wowlan *wow)
2506{ 3179{
2507 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy); 3180 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2508 struct net_device *ndev = cfg_to_ndev(cfg_priv); 3181 struct net_device *ndev = cfg_to_ndev(cfg);
2509 3182
2510 WL_TRACE("Enter\n"); 3183 WL_TRACE("Enter\n");
2511 3184
@@ -2519,12 +3192,12 @@ static s32 brcmf_cfg80211_suspend(struct wiphy *wiphy,
2519 * While going to suspend if associated with AP disassociate 3192 * While going to suspend if associated with AP disassociate
2520 * from AP to save power while system is in suspended state 3193 * from AP to save power while system is in suspended state
2521 */ 3194 */
2522 if ((test_bit(WL_STATUS_CONNECTED, &cfg_priv->status) || 3195 if ((test_bit(WL_STATUS_CONNECTED, &cfg->status) ||
2523 test_bit(WL_STATUS_CONNECTING, &cfg_priv->status)) && 3196 test_bit(WL_STATUS_CONNECTING, &cfg->status)) &&
2524 test_bit(WL_STATUS_READY, &cfg_priv->status)) { 3197 test_bit(WL_STATUS_READY, &cfg->status)) {
2525 WL_INFO("Disassociating from AP" 3198 WL_INFO("Disassociating from AP"
2526 " while entering suspend state\n"); 3199 " while entering suspend state\n");
2527 brcmf_link_down(cfg_priv); 3200 brcmf_link_down(cfg);
2528 3201
2529 /* 3202 /*
2530 * Make sure WPA_Supplicant receives all the event 3203 * Make sure WPA_Supplicant receives all the event
@@ -2534,24 +3207,14 @@ static s32 brcmf_cfg80211_suspend(struct wiphy *wiphy,
2534 brcmf_delay(500); 3207 brcmf_delay(500);
2535 } 3208 }
2536 3209
2537 set_bit(WL_STATUS_SCAN_ABORTING, &cfg_priv->status); 3210 if (test_bit(WL_STATUS_READY, &cfg->status))
2538 if (test_bit(WL_STATUS_READY, &cfg_priv->status)) 3211 brcmf_abort_scanning(cfg);
2539 brcmf_term_iscan(cfg_priv); 3212 else
2540 3213 clear_bit(WL_STATUS_SCANNING, &cfg->status);
2541 if (cfg_priv->scan_request) {
2542 /* Indidate scan abort to cfg80211 layer */
2543 WL_INFO("Terminating scan in progress\n");
2544 cfg80211_scan_done(cfg_priv->scan_request, true);
2545 cfg_priv->scan_request = NULL;
2546 }
2547 clear_bit(WL_STATUS_SCANNING, &cfg_priv->status);
2548 clear_bit(WL_STATUS_SCAN_ABORTING, &cfg_priv->status);
2549 3214
2550 /* Turn off watchdog timer */ 3215 /* Turn off watchdog timer */
2551 if (test_bit(WL_STATUS_READY, &cfg_priv->status)) { 3216 if (test_bit(WL_STATUS_READY, &cfg->status))
2552 WL_INFO("Enable MPC\n");
2553 brcmf_set_mpc(ndev, 1); 3217 brcmf_set_mpc(ndev, 1);
2554 }
2555 3218
2556 WL_TRACE("Exit\n"); 3219 WL_TRACE("Exit\n");
2557 3220
@@ -2561,14 +3224,14 @@ static s32 brcmf_cfg80211_suspend(struct wiphy *wiphy,
2561static __used s32 3224static __used s32
2562brcmf_dev_bufvar_set(struct net_device *ndev, s8 *name, s8 *buf, s32 len) 3225brcmf_dev_bufvar_set(struct net_device *ndev, s8 *name, s8 *buf, s32 len)
2563{ 3226{
2564 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev); 3227 struct brcmf_cfg80211_info *cfg = ndev_to_cfg(ndev);
2565 u32 buflen; 3228 u32 buflen;
2566 3229
2567 buflen = brcmf_c_mkiovar(name, buf, len, cfg_priv->dcmd_buf, 3230 buflen = brcmf_c_mkiovar(name, buf, len, cfg->dcmd_buf,
2568 WL_DCMD_LEN_MAX); 3231 WL_DCMD_LEN_MAX);
2569 BUG_ON(!buflen); 3232 BUG_ON(!buflen);
2570 3233
2571 return brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR, cfg_priv->dcmd_buf, 3234 return brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR, cfg->dcmd_buf,
2572 buflen); 3235 buflen);
2573} 3236}
2574 3237
@@ -2576,20 +3239,20 @@ static s32
2576brcmf_dev_bufvar_get(struct net_device *ndev, s8 *name, s8 *buf, 3239brcmf_dev_bufvar_get(struct net_device *ndev, s8 *name, s8 *buf,
2577 s32 buf_len) 3240 s32 buf_len)
2578{ 3241{
2579 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev); 3242 struct brcmf_cfg80211_info *cfg = ndev_to_cfg(ndev);
2580 u32 len; 3243 u32 len;
2581 s32 err = 0; 3244 s32 err = 0;
2582 3245
2583 len = brcmf_c_mkiovar(name, NULL, 0, cfg_priv->dcmd_buf, 3246 len = brcmf_c_mkiovar(name, NULL, 0, cfg->dcmd_buf,
2584 WL_DCMD_LEN_MAX); 3247 WL_DCMD_LEN_MAX);
2585 BUG_ON(!len); 3248 BUG_ON(!len);
2586 err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_VAR, cfg_priv->dcmd_buf, 3249 err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_VAR, cfg->dcmd_buf,
2587 WL_DCMD_LEN_MAX); 3250 WL_DCMD_LEN_MAX);
2588 if (err) { 3251 if (err) {
2589 WL_ERR("error (%d)\n", err); 3252 WL_ERR("error (%d)\n", err);
2590 return err; 3253 return err;
2591 } 3254 }
2592 memcpy(buf, cfg_priv->dcmd_buf, buf_len); 3255 memcpy(buf, cfg->dcmd_buf, buf_len);
2593 3256
2594 return err; 3257 return err;
2595} 3258}
@@ -2622,8 +3285,8 @@ static s32
2622brcmf_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *ndev, 3285brcmf_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *ndev,
2623 struct cfg80211_pmksa *pmksa) 3286 struct cfg80211_pmksa *pmksa)
2624{ 3287{
2625 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy); 3288 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2626 struct pmkid_list *pmkids = &cfg_priv->pmk_list->pmkids; 3289 struct pmkid_list *pmkids = &cfg->pmk_list->pmkids;
2627 s32 err = 0; 3290 s32 err = 0;
2628 int i; 3291 int i;
2629 int pmkid_len; 3292 int pmkid_len;
@@ -2651,7 +3314,7 @@ brcmf_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *ndev,
2651 for (i = 0; i < WLAN_PMKID_LEN; i++) 3314 for (i = 0; i < WLAN_PMKID_LEN; i++)
2652 WL_CONN("%02x\n", pmkids->pmkid[pmkid_len].PMKID[i]); 3315 WL_CONN("%02x\n", pmkids->pmkid[pmkid_len].PMKID[i]);
2653 3316
2654 err = brcmf_update_pmklist(ndev, cfg_priv->pmk_list, err); 3317 err = brcmf_update_pmklist(ndev, cfg->pmk_list, err);
2655 3318
2656 WL_TRACE("Exit\n"); 3319 WL_TRACE("Exit\n");
2657 return err; 3320 return err;
@@ -2661,7 +3324,7 @@ static s32
2661brcmf_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *ndev, 3324brcmf_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *ndev,
2662 struct cfg80211_pmksa *pmksa) 3325 struct cfg80211_pmksa *pmksa)
2663{ 3326{
2664 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy); 3327 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2665 struct pmkid_list pmkid; 3328 struct pmkid_list pmkid;
2666 s32 err = 0; 3329 s32 err = 0;
2667 int i, pmkid_len; 3330 int i, pmkid_len;
@@ -2678,30 +3341,30 @@ brcmf_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *ndev,
2678 for (i = 0; i < WLAN_PMKID_LEN; i++) 3341 for (i = 0; i < WLAN_PMKID_LEN; i++)
2679 WL_CONN("%02x\n", pmkid.pmkid[0].PMKID[i]); 3342 WL_CONN("%02x\n", pmkid.pmkid[0].PMKID[i]);
2680 3343
2681 pmkid_len = le32_to_cpu(cfg_priv->pmk_list->pmkids.npmkid); 3344 pmkid_len = le32_to_cpu(cfg->pmk_list->pmkids.npmkid);
2682 for (i = 0; i < pmkid_len; i++) 3345 for (i = 0; i < pmkid_len; i++)
2683 if (!memcmp 3346 if (!memcmp
2684 (pmksa->bssid, &cfg_priv->pmk_list->pmkids.pmkid[i].BSSID, 3347 (pmksa->bssid, &cfg->pmk_list->pmkids.pmkid[i].BSSID,
2685 ETH_ALEN)) 3348 ETH_ALEN))
2686 break; 3349 break;
2687 3350
2688 if ((pmkid_len > 0) 3351 if ((pmkid_len > 0)
2689 && (i < pmkid_len)) { 3352 && (i < pmkid_len)) {
2690 memset(&cfg_priv->pmk_list->pmkids.pmkid[i], 0, 3353 memset(&cfg->pmk_list->pmkids.pmkid[i], 0,
2691 sizeof(struct pmkid)); 3354 sizeof(struct pmkid));
2692 for (; i < (pmkid_len - 1); i++) { 3355 for (; i < (pmkid_len - 1); i++) {
2693 memcpy(&cfg_priv->pmk_list->pmkids.pmkid[i].BSSID, 3356 memcpy(&cfg->pmk_list->pmkids.pmkid[i].BSSID,
2694 &cfg_priv->pmk_list->pmkids.pmkid[i + 1].BSSID, 3357 &cfg->pmk_list->pmkids.pmkid[i + 1].BSSID,
2695 ETH_ALEN); 3358 ETH_ALEN);
2696 memcpy(&cfg_priv->pmk_list->pmkids.pmkid[i].PMKID, 3359 memcpy(&cfg->pmk_list->pmkids.pmkid[i].PMKID,
2697 &cfg_priv->pmk_list->pmkids.pmkid[i + 1].PMKID, 3360 &cfg->pmk_list->pmkids.pmkid[i + 1].PMKID,
2698 WLAN_PMKID_LEN); 3361 WLAN_PMKID_LEN);
2699 } 3362 }
2700 cfg_priv->pmk_list->pmkids.npmkid = cpu_to_le32(pmkid_len - 1); 3363 cfg->pmk_list->pmkids.npmkid = cpu_to_le32(pmkid_len - 1);
2701 } else 3364 } else
2702 err = -EINVAL; 3365 err = -EINVAL;
2703 3366
2704 err = brcmf_update_pmklist(ndev, cfg_priv->pmk_list, err); 3367 err = brcmf_update_pmklist(ndev, cfg->pmk_list, err);
2705 3368
2706 WL_TRACE("Exit\n"); 3369 WL_TRACE("Exit\n");
2707 return err; 3370 return err;
@@ -2711,21 +3374,979 @@ brcmf_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *ndev,
2711static s32 3374static s32
2712brcmf_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *ndev) 3375brcmf_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *ndev)
2713{ 3376{
2714 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy); 3377 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2715 s32 err = 0; 3378 s32 err = 0;
2716 3379
2717 WL_TRACE("Enter\n"); 3380 WL_TRACE("Enter\n");
2718 if (!check_sys_up(wiphy)) 3381 if (!check_sys_up(wiphy))
2719 return -EIO; 3382 return -EIO;
2720 3383
2721 memset(cfg_priv->pmk_list, 0, sizeof(*cfg_priv->pmk_list)); 3384 memset(cfg->pmk_list, 0, sizeof(*cfg->pmk_list));
2722 err = brcmf_update_pmklist(ndev, cfg_priv->pmk_list, err); 3385 err = brcmf_update_pmklist(ndev, cfg->pmk_list, err);
2723 3386
2724 WL_TRACE("Exit\n"); 3387 WL_TRACE("Exit\n");
2725 return err; 3388 return err;
2726 3389
2727} 3390}
2728 3391
3392/*
3393 * PFN result doesn't have all the info which are
3394 * required by the supplicant
3395 * (For e.g IEs) Do a target Escan so that sched scan results are reported
3396 * via wl_inform_single_bss in the required format. Escan does require the
3397 * scan request in the form of cfg80211_scan_request. For timebeing, create
3398 * cfg80211_scan_request one out of the received PNO event.
3399 */
3400static s32
3401brcmf_notify_sched_scan_results(struct brcmf_cfg80211_info *cfg,
3402 struct net_device *ndev,
3403 const struct brcmf_event_msg *e, void *data)
3404{
3405 struct brcmf_pno_net_info_le *netinfo, *netinfo_start;
3406 struct cfg80211_scan_request *request = NULL;
3407 struct cfg80211_ssid *ssid = NULL;
3408 struct ieee80211_channel *channel = NULL;
3409 struct wiphy *wiphy = cfg_to_wiphy(cfg);
3410 int err = 0;
3411 int channel_req = 0;
3412 int band = 0;
3413 struct brcmf_pno_scanresults_le *pfn_result;
3414 u32 result_count;
3415 u32 status;
3416
3417 WL_SCAN("Enter\n");
3418
3419 if (e->event_type == cpu_to_be32(BRCMF_E_PFN_NET_LOST)) {
3420 WL_SCAN("PFN NET LOST event. Do Nothing\n");
3421 return 0;
3422 }
3423
3424 pfn_result = (struct brcmf_pno_scanresults_le *)data;
3425 result_count = le32_to_cpu(pfn_result->count);
3426 status = le32_to_cpu(pfn_result->status);
3427
3428 /*
3429 * PFN event is limited to fit 512 bytes so we may get
3430 * multiple NET_FOUND events. For now place a warning here.
3431 */
3432 WARN_ON(status != BRCMF_PNO_SCAN_COMPLETE);
3433 WL_SCAN("PFN NET FOUND event. count: %d\n", result_count);
3434 if (result_count > 0) {
3435 int i;
3436
3437 request = kzalloc(sizeof(*request), GFP_KERNEL);
3438 ssid = kcalloc(result_count, sizeof(*ssid), GFP_KERNEL);
3439 channel = kcalloc(result_count, sizeof(*channel), GFP_KERNEL);
3440 if (!request || !ssid || !channel) {
3441 err = -ENOMEM;
3442 goto out_err;
3443 }
3444
3445 request->wiphy = wiphy;
3446 data += sizeof(struct brcmf_pno_scanresults_le);
3447 netinfo_start = (struct brcmf_pno_net_info_le *)data;
3448
3449 for (i = 0; i < result_count; i++) {
3450 netinfo = &netinfo_start[i];
3451 if (!netinfo) {
3452 WL_ERR("Invalid netinfo ptr. index: %d\n", i);
3453 err = -EINVAL;
3454 goto out_err;
3455 }
3456
3457 WL_SCAN("SSID:%s Channel:%d\n",
3458 netinfo->SSID, netinfo->channel);
3459 memcpy(ssid[i].ssid, netinfo->SSID, netinfo->SSID_len);
3460 ssid[i].ssid_len = netinfo->SSID_len;
3461 request->n_ssids++;
3462
3463 channel_req = netinfo->channel;
3464 if (channel_req <= CH_MAX_2G_CHANNEL)
3465 band = NL80211_BAND_2GHZ;
3466 else
3467 band = NL80211_BAND_5GHZ;
3468 channel[i].center_freq =
3469 ieee80211_channel_to_frequency(channel_req,
3470 band);
3471 channel[i].band = band;
3472 channel[i].flags |= IEEE80211_CHAN_NO_HT40;
3473 request->channels[i] = &channel[i];
3474 request->n_channels++;
3475 }
3476
3477 /* assign parsed ssid array */
3478 if (request->n_ssids)
3479 request->ssids = &ssid[0];
3480
3481 if (test_bit(WL_STATUS_SCANNING, &cfg->status)) {
3482 /* Abort any on-going scan */
3483 brcmf_abort_scanning(cfg);
3484 }
3485
3486 set_bit(WL_STATUS_SCANNING, &cfg->status);
3487 err = brcmf_do_escan(cfg, wiphy, ndev, request);
3488 if (err) {
3489 clear_bit(WL_STATUS_SCANNING, &cfg->status);
3490 goto out_err;
3491 }
3492 cfg->sched_escan = true;
3493 cfg->scan_request = request;
3494 } else {
3495 WL_ERR("FALSE PNO Event. (pfn_count == 0)\n");
3496 goto out_err;
3497 }
3498
3499 kfree(ssid);
3500 kfree(channel);
3501 kfree(request);
3502 return 0;
3503
3504out_err:
3505 kfree(ssid);
3506 kfree(channel);
3507 kfree(request);
3508 cfg80211_sched_scan_stopped(wiphy);
3509 return err;
3510}
3511
3512#ifndef CONFIG_BRCMISCAN
3513static int brcmf_dev_pno_clean(struct net_device *ndev)
3514{
3515 char iovbuf[128];
3516 int ret;
3517
3518 /* Disable pfn */
3519 ret = brcmf_dev_intvar_set(ndev, "pfn", 0);
3520 if (ret == 0) {
3521 /* clear pfn */
3522 ret = brcmf_dev_iovar_setbuf(ndev, "pfnclear", NULL, 0,
3523 iovbuf, sizeof(iovbuf));
3524 }
3525 if (ret < 0)
3526 WL_ERR("failed code %d\n", ret);
3527
3528 return ret;
3529}
3530
3531static int brcmf_dev_pno_config(struct net_device *ndev)
3532{
3533 struct brcmf_pno_param_le pfn_param;
3534 char iovbuf[128];
3535
3536 memset(&pfn_param, 0, sizeof(pfn_param));
3537 pfn_param.version = cpu_to_le32(BRCMF_PNO_VERSION);
3538
3539 /* set extra pno params */
3540 pfn_param.flags = cpu_to_le16(1 << BRCMF_PNO_ENABLE_ADAPTSCAN_BIT);
3541 pfn_param.repeat = BRCMF_PNO_REPEAT;
3542 pfn_param.exp = BRCMF_PNO_FREQ_EXPO_MAX;
3543
3544 /* set up pno scan fr */
3545 pfn_param.scan_freq = cpu_to_le32(BRCMF_PNO_TIME);
3546
3547 return brcmf_dev_iovar_setbuf(ndev, "pfn_set",
3548 &pfn_param, sizeof(pfn_param),
3549 iovbuf, sizeof(iovbuf));
3550}
3551
3552static int
3553brcmf_cfg80211_sched_scan_start(struct wiphy *wiphy,
3554 struct net_device *ndev,
3555 struct cfg80211_sched_scan_request *request)
3556{
3557 char iovbuf[128];
3558 struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy);
3559 struct brcmf_pno_net_param_le pfn;
3560 int i;
3561 int ret = 0;
3562
3563 WL_SCAN("Enter n_match_sets:%d n_ssids:%d\n",
3564 request->n_match_sets, request->n_ssids);
3565 if (test_bit(WL_STATUS_SCANNING, &cfg->status)) {
3566 WL_ERR("Scanning already : status (%lu)\n", cfg->status);
3567 return -EAGAIN;
3568 }
3569
3570 if (!request || !request->n_ssids || !request->n_match_sets) {
3571 WL_ERR("Invalid sched scan req!! n_ssids:%d\n",
3572 request->n_ssids);
3573 return -EINVAL;
3574 }
3575
3576 if (request->n_ssids > 0) {
3577 for (i = 0; i < request->n_ssids; i++) {
3578 /* Active scan req for ssids */
3579 WL_SCAN(">>> Active scan req for ssid (%s)\n",
3580 request->ssids[i].ssid);
3581
3582 /*
3583 * match_set ssids is a supert set of n_ssid list,
3584 * so we need not add these set seperately.
3585 */
3586 }
3587 }
3588
3589 if (request->n_match_sets > 0) {
3590 /* clean up everything */
3591 ret = brcmf_dev_pno_clean(ndev);
3592 if (ret < 0) {
3593 WL_ERR("failed error=%d\n", ret);
3594 return ret;
3595 }
3596
3597 /* configure pno */
3598 ret = brcmf_dev_pno_config(ndev);
3599 if (ret < 0) {
3600 WL_ERR("PNO setup failed!! ret=%d\n", ret);
3601 return -EINVAL;
3602 }
3603
3604 /* configure each match set */
3605 for (i = 0; i < request->n_match_sets; i++) {
3606 struct cfg80211_ssid *ssid;
3607 u32 ssid_len;
3608
3609 ssid = &request->match_sets[i].ssid;
3610 ssid_len = ssid->ssid_len;
3611
3612 if (!ssid_len) {
3613 WL_ERR("skip broadcast ssid\n");
3614 continue;
3615 }
3616 pfn.auth = cpu_to_le32(WLAN_AUTH_OPEN);
3617 pfn.wpa_auth = cpu_to_le32(BRCMF_PNO_WPA_AUTH_ANY);
3618 pfn.wsec = cpu_to_le32(0);
3619 pfn.infra = cpu_to_le32(1);
3620 pfn.flags = cpu_to_le32(1 << BRCMF_PNO_HIDDEN_BIT);
3621 pfn.ssid.SSID_len = cpu_to_le32(ssid_len);
3622 memcpy(pfn.ssid.SSID, ssid->ssid, ssid_len);
3623 ret = brcmf_dev_iovar_setbuf(ndev, "pfn_add",
3624 &pfn, sizeof(pfn),
3625 iovbuf, sizeof(iovbuf));
3626 WL_SCAN(">>> PNO filter %s for ssid (%s)\n",
3627 ret == 0 ? "set" : "failed",
3628 ssid->ssid);
3629 }
3630 /* Enable the PNO */
3631 if (brcmf_dev_intvar_set(ndev, "pfn", 1) < 0) {
3632 WL_ERR("PNO enable failed!! ret=%d\n", ret);
3633 return -EINVAL;
3634 }
3635 } else {
3636 return -EINVAL;
3637 }
3638
3639 return 0;
3640}
3641
3642static int brcmf_cfg80211_sched_scan_stop(struct wiphy *wiphy,
3643 struct net_device *ndev)
3644{
3645 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3646
3647 WL_SCAN("enter\n");
3648 brcmf_dev_pno_clean(ndev);
3649 if (cfg->sched_escan)
3650 brcmf_notify_escan_complete(cfg, ndev, true, true);
3651 return 0;
3652}
3653#endif /* CONFIG_BRCMISCAN */
3654
3655#ifdef CONFIG_NL80211_TESTMODE
3656static int brcmf_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
3657{
3658 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3659 struct net_device *ndev = cfg->wdev->netdev;
3660 struct brcmf_dcmd *dcmd = data;
3661 struct sk_buff *reply;
3662 int ret;
3663
3664 ret = brcmf_netlink_dcmd(ndev, dcmd);
3665 if (ret == 0) {
3666 reply = cfg80211_testmode_alloc_reply_skb(wiphy, sizeof(*dcmd));
3667 nla_put(reply, NL80211_ATTR_TESTDATA, sizeof(*dcmd), dcmd);
3668 ret = cfg80211_testmode_reply(reply);
3669 }
3670 return ret;
3671}
3672#endif
3673
3674static s32 brcmf_configure_opensecurity(struct net_device *ndev, s32 bssidx)
3675{
3676 s32 err;
3677
3678 /* set auth */
3679 err = brcmf_dev_intvar_set_bsscfg(ndev, "auth", 0, bssidx);
3680 if (err < 0) {
3681 WL_ERR("auth error %d\n", err);
3682 return err;
3683 }
3684 /* set wsec */
3685 err = brcmf_dev_intvar_set_bsscfg(ndev, "wsec", 0, bssidx);
3686 if (err < 0) {
3687 WL_ERR("wsec error %d\n", err);
3688 return err;
3689 }
3690 /* set upper-layer auth */
3691 err = brcmf_dev_intvar_set_bsscfg(ndev, "wpa_auth",
3692 WPA_AUTH_NONE, bssidx);
3693 if (err < 0) {
3694 WL_ERR("wpa_auth error %d\n", err);
3695 return err;
3696 }
3697
3698 return 0;
3699}
3700
3701static bool brcmf_valid_wpa_oui(u8 *oui, bool is_rsn_ie)
3702{
3703 if (is_rsn_ie)
3704 return (memcmp(oui, RSN_OUI, TLV_OUI_LEN) == 0);
3705
3706 return (memcmp(oui, WPA_OUI, TLV_OUI_LEN) == 0);
3707}
3708
3709static s32
3710brcmf_configure_wpaie(struct net_device *ndev, struct brcmf_vs_tlv *wpa_ie,
3711 bool is_rsn_ie, s32 bssidx)
3712{
3713 u32 auth = 0; /* d11 open authentication */
3714 u16 count;
3715 s32 err = 0;
3716 s32 len = 0;
3717 u32 i;
3718 u32 wsec;
3719 u32 pval = 0;
3720 u32 gval = 0;
3721 u32 wpa_auth = 0;
3722 u32 offset;
3723 u8 *data;
3724 u16 rsn_cap;
3725 u32 wme_bss_disable;
3726
3727 WL_TRACE("Enter\n");
3728 if (wpa_ie == NULL)
3729 goto exit;
3730
3731 len = wpa_ie->len + TLV_HDR_LEN;
3732 data = (u8 *)wpa_ie;
3733 offset = 0;
3734 if (!is_rsn_ie)
3735 offset += VS_IE_FIXED_HDR_LEN;
3736 offset += WPA_IE_VERSION_LEN;
3737
3738 /* check for multicast cipher suite */
3739 if (offset + WPA_IE_MIN_OUI_LEN > len) {
3740 err = -EINVAL;
3741 WL_ERR("no multicast cipher suite\n");
3742 goto exit;
3743 }
3744
3745 if (!brcmf_valid_wpa_oui(&data[offset], is_rsn_ie)) {
3746 err = -EINVAL;
3747 WL_ERR("ivalid OUI\n");
3748 goto exit;
3749 }
3750 offset += TLV_OUI_LEN;
3751
3752 /* pick up multicast cipher */
3753 switch (data[offset]) {
3754 case WPA_CIPHER_NONE:
3755 gval = 0;
3756 break;
3757 case WPA_CIPHER_WEP_40:
3758 case WPA_CIPHER_WEP_104:
3759 gval = WEP_ENABLED;
3760 break;
3761 case WPA_CIPHER_TKIP:
3762 gval = TKIP_ENABLED;
3763 break;
3764 case WPA_CIPHER_AES_CCM:
3765 gval = AES_ENABLED;
3766 break;
3767 default:
3768 err = -EINVAL;
3769 WL_ERR("Invalid multi cast cipher info\n");
3770 goto exit;
3771 }
3772
3773 offset++;
3774 /* walk thru unicast cipher list and pick up what we recognize */
3775 count = data[offset] + (data[offset + 1] << 8);
3776 offset += WPA_IE_SUITE_COUNT_LEN;
3777 /* Check for unicast suite(s) */
3778 if (offset + (WPA_IE_MIN_OUI_LEN * count) > len) {
3779 err = -EINVAL;
3780 WL_ERR("no unicast cipher suite\n");
3781 goto exit;
3782 }
3783 for (i = 0; i < count; i++) {
3784 if (!brcmf_valid_wpa_oui(&data[offset], is_rsn_ie)) {
3785 err = -EINVAL;
3786 WL_ERR("ivalid OUI\n");
3787 goto exit;
3788 }
3789 offset += TLV_OUI_LEN;
3790 switch (data[offset]) {
3791 case WPA_CIPHER_NONE:
3792 break;
3793 case WPA_CIPHER_WEP_40:
3794 case WPA_CIPHER_WEP_104:
3795 pval |= WEP_ENABLED;
3796 break;
3797 case WPA_CIPHER_TKIP:
3798 pval |= TKIP_ENABLED;
3799 break;
3800 case WPA_CIPHER_AES_CCM:
3801 pval |= AES_ENABLED;
3802 break;
3803 default:
3804 WL_ERR("Ivalid unicast security info\n");
3805 }
3806 offset++;
3807 }
3808 /* walk thru auth management suite list and pick up what we recognize */
3809 count = data[offset] + (data[offset + 1] << 8);
3810 offset += WPA_IE_SUITE_COUNT_LEN;
3811 /* Check for auth key management suite(s) */
3812 if (offset + (WPA_IE_MIN_OUI_LEN * count) > len) {
3813 err = -EINVAL;
3814 WL_ERR("no auth key mgmt suite\n");
3815 goto exit;
3816 }
3817 for (i = 0; i < count; i++) {
3818 if (!brcmf_valid_wpa_oui(&data[offset], is_rsn_ie)) {
3819 err = -EINVAL;
3820 WL_ERR("ivalid OUI\n");
3821 goto exit;
3822 }
3823 offset += TLV_OUI_LEN;
3824 switch (data[offset]) {
3825 case RSN_AKM_NONE:
3826 WL_TRACE("RSN_AKM_NONE\n");
3827 wpa_auth |= WPA_AUTH_NONE;
3828 break;
3829 case RSN_AKM_UNSPECIFIED:
3830 WL_TRACE("RSN_AKM_UNSPECIFIED\n");
3831 is_rsn_ie ? (wpa_auth |= WPA2_AUTH_UNSPECIFIED) :
3832 (wpa_auth |= WPA_AUTH_UNSPECIFIED);
3833 break;
3834 case RSN_AKM_PSK:
3835 WL_TRACE("RSN_AKM_PSK\n");
3836 is_rsn_ie ? (wpa_auth |= WPA2_AUTH_PSK) :
3837 (wpa_auth |= WPA_AUTH_PSK);
3838 break;
3839 default:
3840 WL_ERR("Ivalid key mgmt info\n");
3841 }
3842 offset++;
3843 }
3844
3845 if (is_rsn_ie) {
3846 wme_bss_disable = 1;
3847 if ((offset + RSN_CAP_LEN) <= len) {
3848 rsn_cap = data[offset] + (data[offset + 1] << 8);
3849 if (rsn_cap & RSN_CAP_PTK_REPLAY_CNTR_MASK)
3850 wme_bss_disable = 0;
3851 }
3852 /* set wme_bss_disable to sync RSN Capabilities */
3853 err = brcmf_dev_intvar_set_bsscfg(ndev, "wme_bss_disable",
3854 wme_bss_disable, bssidx);
3855 if (err < 0) {
3856 WL_ERR("wme_bss_disable error %d\n", err);
3857 goto exit;
3858 }
3859 }
3860 /* FOR WPS , set SES_OW_ENABLED */
3861 wsec = (pval | gval | SES_OW_ENABLED);
3862
3863 /* set auth */
3864 err = brcmf_dev_intvar_set_bsscfg(ndev, "auth", auth, bssidx);
3865 if (err < 0) {
3866 WL_ERR("auth error %d\n", err);
3867 goto exit;
3868 }
3869 /* set wsec */
3870 err = brcmf_dev_intvar_set_bsscfg(ndev, "wsec", wsec, bssidx);
3871 if (err < 0) {
3872 WL_ERR("wsec error %d\n", err);
3873 goto exit;
3874 }
3875 /* set upper-layer auth */
3876 err = brcmf_dev_intvar_set_bsscfg(ndev, "wpa_auth", wpa_auth, bssidx);
3877 if (err < 0) {
3878 WL_ERR("wpa_auth error %d\n", err);
3879 goto exit;
3880 }
3881
3882exit:
3883 return err;
3884}
3885
3886static s32
3887brcmf_parse_vndr_ies(u8 *vndr_ie_buf, u32 vndr_ie_len,
3888 struct parsed_vndr_ies *vndr_ies)
3889{
3890 s32 err = 0;
3891 struct brcmf_vs_tlv *vndrie;
3892 struct brcmf_tlv *ie;
3893 struct parsed_vndr_ie_info *parsed_info;
3894 s32 remaining_len;
3895
3896 remaining_len = (s32)vndr_ie_len;
3897 memset(vndr_ies, 0, sizeof(*vndr_ies));
3898
3899 ie = (struct brcmf_tlv *)vndr_ie_buf;
3900 while (ie) {
3901 if (ie->id != WLAN_EID_VENDOR_SPECIFIC)
3902 goto next;
3903 vndrie = (struct brcmf_vs_tlv *)ie;
3904 /* len should be bigger than OUI length + one */
3905 if (vndrie->len < (VS_IE_FIXED_HDR_LEN - TLV_HDR_LEN + 1)) {
3906 WL_ERR("invalid vndr ie. length is too small %d\n",
3907 vndrie->len);
3908 goto next;
3909 }
3910 /* if wpa or wme ie, do not add ie */
3911 if (!memcmp(vndrie->oui, (u8 *)WPA_OUI, TLV_OUI_LEN) &&
3912 ((vndrie->oui_type == WPA_OUI_TYPE) ||
3913 (vndrie->oui_type == WME_OUI_TYPE))) {
3914 WL_TRACE("Found WPA/WME oui. Do not add it\n");
3915 goto next;
3916 }
3917
3918 parsed_info = &vndr_ies->ie_info[vndr_ies->count];
3919
3920 /* save vndr ie information */
3921 parsed_info->ie_ptr = (char *)vndrie;
3922 parsed_info->ie_len = vndrie->len + TLV_HDR_LEN;
3923 memcpy(&parsed_info->vndrie, vndrie, sizeof(*vndrie));
3924
3925 vndr_ies->count++;
3926
3927 WL_TRACE("** OUI %02x %02x %02x, type 0x%02x\n",
3928 parsed_info->vndrie.oui[0],
3929 parsed_info->vndrie.oui[1],
3930 parsed_info->vndrie.oui[2],
3931 parsed_info->vndrie.oui_type);
3932
3933 if (vndr_ies->count >= MAX_VNDR_IE_NUMBER)
3934 break;
3935next:
3936 remaining_len -= ie->len;
3937 if (remaining_len <= 2)
3938 ie = NULL;
3939 else
3940 ie = (struct brcmf_tlv *)(((u8 *)ie) + ie->len);
3941 }
3942 return err;
3943}
3944
3945static u32
3946brcmf_vndr_ie(u8 *iebuf, s32 pktflag, u8 *ie_ptr, u32 ie_len, s8 *add_del_cmd)
3947{
3948
3949 __le32 iecount_le;
3950 __le32 pktflag_le;
3951
3952 strncpy(iebuf, add_del_cmd, VNDR_IE_CMD_LEN - 1);
3953 iebuf[VNDR_IE_CMD_LEN - 1] = '\0';
3954
3955 iecount_le = cpu_to_le32(1);
3956 memcpy(&iebuf[VNDR_IE_COUNT_OFFSET], &iecount_le, sizeof(iecount_le));
3957
3958 pktflag_le = cpu_to_le32(pktflag);
3959 memcpy(&iebuf[VNDR_IE_PKTFLAG_OFFSET], &pktflag_le, sizeof(pktflag_le));
3960
3961 memcpy(&iebuf[VNDR_IE_VSIE_OFFSET], ie_ptr, ie_len);
3962
3963 return ie_len + VNDR_IE_HDR_SIZE;
3964}
3965
3966s32
3967brcmf_set_management_ie(struct brcmf_cfg80211_info *cfg,
3968 struct net_device *ndev, s32 bssidx, s32 pktflag,
3969 u8 *vndr_ie_buf, u32 vndr_ie_len)
3970{
3971 s32 err = 0;
3972 u8 *iovar_ie_buf;
3973 u8 *curr_ie_buf;
3974 u8 *mgmt_ie_buf = NULL;
3975 u32 mgmt_ie_buf_len = 0;
3976 u32 *mgmt_ie_len = 0;
3977 u32 del_add_ie_buf_len = 0;
3978 u32 total_ie_buf_len = 0;
3979 u32 parsed_ie_buf_len = 0;
3980 struct parsed_vndr_ies old_vndr_ies;
3981 struct parsed_vndr_ies new_vndr_ies;
3982 struct parsed_vndr_ie_info *vndrie_info;
3983 s32 i;
3984 u8 *ptr;
3985 u32 remained_buf_len;
3986
3987 WL_TRACE("bssidx %d, pktflag : 0x%02X\n", bssidx, pktflag);
3988 iovar_ie_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL);
3989 if (!iovar_ie_buf)
3990 return -ENOMEM;
3991 curr_ie_buf = iovar_ie_buf;
3992 if (test_bit(WL_STATUS_AP_CREATING, &cfg->status) ||
3993 test_bit(WL_STATUS_AP_CREATED, &cfg->status)) {
3994 switch (pktflag) {
3995 case VNDR_IE_PRBRSP_FLAG:
3996 mgmt_ie_buf = cfg->ap_info->probe_res_ie;
3997 mgmt_ie_len = &cfg->ap_info->probe_res_ie_len;
3998 mgmt_ie_buf_len =
3999 sizeof(cfg->ap_info->probe_res_ie);
4000 break;
4001 case VNDR_IE_BEACON_FLAG:
4002 mgmt_ie_buf = cfg->ap_info->beacon_ie;
4003 mgmt_ie_len = &cfg->ap_info->beacon_ie_len;
4004 mgmt_ie_buf_len = sizeof(cfg->ap_info->beacon_ie);
4005 break;
4006 default:
4007 err = -EPERM;
4008 WL_ERR("not suitable type\n");
4009 goto exit;
4010 }
4011 bssidx = 0;
4012 } else {
4013 err = -EPERM;
4014 WL_ERR("not suitable type\n");
4015 goto exit;
4016 }
4017
4018 if (vndr_ie_len > mgmt_ie_buf_len) {
4019 err = -ENOMEM;
4020 WL_ERR("extra IE size too big\n");
4021 goto exit;
4022 }
4023
4024 /* parse and save new vndr_ie in curr_ie_buff before comparing it */
4025 if (vndr_ie_buf && vndr_ie_len && curr_ie_buf) {
4026 ptr = curr_ie_buf;
4027 brcmf_parse_vndr_ies(vndr_ie_buf, vndr_ie_len, &new_vndr_ies);
4028 for (i = 0; i < new_vndr_ies.count; i++) {
4029 vndrie_info = &new_vndr_ies.ie_info[i];
4030 memcpy(ptr + parsed_ie_buf_len, vndrie_info->ie_ptr,
4031 vndrie_info->ie_len);
4032 parsed_ie_buf_len += vndrie_info->ie_len;
4033 }
4034 }
4035
4036 if (mgmt_ie_buf != NULL) {
4037 if (parsed_ie_buf_len && (parsed_ie_buf_len == *mgmt_ie_len) &&
4038 (memcmp(mgmt_ie_buf, curr_ie_buf,
4039 parsed_ie_buf_len) == 0)) {
4040 WL_TRACE("Previous mgmt IE is equals to current IE");
4041 goto exit;
4042 }
4043
4044 /* parse old vndr_ie */
4045 brcmf_parse_vndr_ies(mgmt_ie_buf, *mgmt_ie_len, &old_vndr_ies);
4046
4047 /* make a command to delete old ie */
4048 for (i = 0; i < old_vndr_ies.count; i++) {
4049 vndrie_info = &old_vndr_ies.ie_info[i];
4050
4051 WL_TRACE("DEL ID : %d, Len: %d , OUI:%02x:%02x:%02x\n",
4052 vndrie_info->vndrie.id,
4053 vndrie_info->vndrie.len,
4054 vndrie_info->vndrie.oui[0],
4055 vndrie_info->vndrie.oui[1],
4056 vndrie_info->vndrie.oui[2]);
4057
4058 del_add_ie_buf_len = brcmf_vndr_ie(curr_ie_buf, pktflag,
4059 vndrie_info->ie_ptr,
4060 vndrie_info->ie_len,
4061 "del");
4062 curr_ie_buf += del_add_ie_buf_len;
4063 total_ie_buf_len += del_add_ie_buf_len;
4064 }
4065 }
4066
4067 *mgmt_ie_len = 0;
4068 /* Add if there is any extra IE */
4069 if (mgmt_ie_buf && parsed_ie_buf_len) {
4070 ptr = mgmt_ie_buf;
4071
4072 remained_buf_len = mgmt_ie_buf_len;
4073
4074 /* make a command to add new ie */
4075 for (i = 0; i < new_vndr_ies.count; i++) {
4076 vndrie_info = &new_vndr_ies.ie_info[i];
4077
4078 WL_TRACE("ADDED ID : %d, Len: %d, OUI:%02x:%02x:%02x\n",
4079 vndrie_info->vndrie.id,
4080 vndrie_info->vndrie.len,
4081 vndrie_info->vndrie.oui[0],
4082 vndrie_info->vndrie.oui[1],
4083 vndrie_info->vndrie.oui[2]);
4084
4085 del_add_ie_buf_len = brcmf_vndr_ie(curr_ie_buf, pktflag,
4086 vndrie_info->ie_ptr,
4087 vndrie_info->ie_len,
4088 "add");
4089 /* verify remained buf size before copy data */
4090 remained_buf_len -= vndrie_info->ie_len;
4091 if (remained_buf_len < 0) {
4092 WL_ERR("no space in mgmt_ie_buf: len left %d",
4093 remained_buf_len);
4094 break;
4095 }
4096
4097 /* save the parsed IE in wl struct */
4098 memcpy(ptr + (*mgmt_ie_len), vndrie_info->ie_ptr,
4099 vndrie_info->ie_len);
4100 *mgmt_ie_len += vndrie_info->ie_len;
4101
4102 curr_ie_buf += del_add_ie_buf_len;
4103 total_ie_buf_len += del_add_ie_buf_len;
4104 }
4105 }
4106 if (total_ie_buf_len) {
4107 err = brcmf_dev_iovar_setbuf_bsscfg(ndev, "vndr_ie",
4108 iovar_ie_buf,
4109 total_ie_buf_len,
4110 cfg->extra_buf,
4111 WL_EXTRA_BUF_MAX, bssidx);
4112 if (err)
4113 WL_ERR("vndr ie set error : %d\n", err);
4114 }
4115
4116exit:
4117 kfree(iovar_ie_buf);
4118 return err;
4119}
4120
4121static s32
4122brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
4123 struct cfg80211_ap_settings *settings)
4124{
4125 s32 ie_offset;
4126 struct brcmf_tlv *ssid_ie;
4127 struct brcmf_ssid_le ssid_le;
4128 s32 ioctl_value;
4129 s32 err = -EPERM;
4130 struct brcmf_tlv *rsn_ie;
4131 struct brcmf_vs_tlv *wpa_ie;
4132 struct brcmf_join_params join_params;
4133 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
4134 s32 bssidx = 0;
4135
4136 WL_TRACE("channel_type=%d, beacon_interval=%d, dtim_period=%d,\n",
4137 settings->channel_type, settings->beacon_interval,
4138 settings->dtim_period);
4139 WL_TRACE("ssid=%s(%d), auth_type=%d, inactivity_timeout=%d\n",
4140 settings->ssid, settings->ssid_len, settings->auth_type,
4141 settings->inactivity_timeout);
4142
4143 if (!test_bit(WL_STATUS_AP_CREATING, &cfg->status)) {
4144 WL_ERR("Not in AP creation mode\n");
4145 return -EPERM;
4146 }
4147
4148 memset(&ssid_le, 0, sizeof(ssid_le));
4149 if (settings->ssid == NULL || settings->ssid_len == 0) {
4150 ie_offset = DOT11_MGMT_HDR_LEN + DOT11_BCN_PRB_FIXED_LEN;
4151 ssid_ie = brcmf_parse_tlvs(
4152 (u8 *)&settings->beacon.head[ie_offset],
4153 settings->beacon.head_len - ie_offset,
4154 WLAN_EID_SSID);
4155 if (!ssid_ie)
4156 return -EINVAL;
4157
4158 memcpy(ssid_le.SSID, ssid_ie->data, ssid_ie->len);
4159 ssid_le.SSID_len = cpu_to_le32(ssid_ie->len);
4160 WL_TRACE("SSID is (%s) in Head\n", ssid_le.SSID);
4161 } else {
4162 memcpy(ssid_le.SSID, settings->ssid, settings->ssid_len);
4163 ssid_le.SSID_len = cpu_to_le32((u32)settings->ssid_len);
4164 }
4165
4166 brcmf_set_mpc(ndev, 0);
4167 ioctl_value = 1;
4168 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_DOWN, &ioctl_value);
4169 if (err < 0) {
4170 WL_ERR("BRCMF_C_DOWN error %d\n", err);
4171 goto exit;
4172 }
4173 ioctl_value = 1;
4174 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_INFRA, &ioctl_value);
4175 if (err < 0) {
4176 WL_ERR("SET INFRA error %d\n", err);
4177 goto exit;
4178 }
4179 ioctl_value = 1;
4180 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_AP, &ioctl_value);
4181 if (err < 0) {
4182 WL_ERR("setting AP mode failed %d\n", err);
4183 goto exit;
4184 }
4185
4186 /* find the RSN_IE */
4187 rsn_ie = brcmf_parse_tlvs((u8 *)settings->beacon.tail,
4188 settings->beacon.tail_len, WLAN_EID_RSN);
4189
4190 /* find the WPA_IE */
4191 wpa_ie = brcmf_find_wpaie((u8 *)settings->beacon.tail,
4192 settings->beacon.tail_len);
4193
4194 kfree(cfg->ap_info->rsn_ie);
4195 cfg->ap_info->rsn_ie = NULL;
4196 kfree(cfg->ap_info->wpa_ie);
4197 cfg->ap_info->wpa_ie = NULL;
4198
4199 if ((wpa_ie != NULL || rsn_ie != NULL)) {
4200 WL_TRACE("WPA(2) IE is found\n");
4201 if (wpa_ie != NULL) {
4202 /* WPA IE */
4203 err = brcmf_configure_wpaie(ndev, wpa_ie, false,
4204 bssidx);
4205 if (err < 0)
4206 goto exit;
4207 cfg->ap_info->wpa_ie = kmemdup(wpa_ie,
4208 wpa_ie->len +
4209 TLV_HDR_LEN,
4210 GFP_KERNEL);
4211 } else {
4212 /* RSN IE */
4213 err = brcmf_configure_wpaie(ndev,
4214 (struct brcmf_vs_tlv *)rsn_ie, true, bssidx);
4215 if (err < 0)
4216 goto exit;
4217 cfg->ap_info->rsn_ie = kmemdup(rsn_ie,
4218 rsn_ie->len +
4219 TLV_HDR_LEN,
4220 GFP_KERNEL);
4221 }
4222 cfg->ap_info->security_mode = true;
4223 } else {
4224 WL_TRACE("No WPA(2) IEs found\n");
4225 brcmf_configure_opensecurity(ndev, bssidx);
4226 cfg->ap_info->security_mode = false;
4227 }
4228 /* Set Beacon IEs to FW */
4229 err = brcmf_set_management_ie(cfg, ndev, bssidx,
4230 VNDR_IE_BEACON_FLAG,
4231 (u8 *)settings->beacon.tail,
4232 settings->beacon.tail_len);
4233 if (err)
4234 WL_ERR("Set Beacon IE Failed\n");
4235 else
4236 WL_TRACE("Applied Vndr IEs for Beacon\n");
4237
4238 /* Set Probe Response IEs to FW */
4239 err = brcmf_set_management_ie(cfg, ndev, bssidx,
4240 VNDR_IE_PRBRSP_FLAG,
4241 (u8 *)settings->beacon.proberesp_ies,
4242 settings->beacon.proberesp_ies_len);
4243 if (err)
4244 WL_ERR("Set Probe Resp IE Failed\n");
4245 else
4246 WL_TRACE("Applied Vndr IEs for Probe Resp\n");
4247
4248 if (settings->beacon_interval) {
4249 ioctl_value = settings->beacon_interval;
4250 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_BCNPRD,
4251 &ioctl_value);
4252 if (err < 0) {
4253 WL_ERR("Beacon Interval Set Error, %d\n", err);
4254 goto exit;
4255 }
4256 }
4257 if (settings->dtim_period) {
4258 ioctl_value = settings->dtim_period;
4259 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_DTIMPRD,
4260 &ioctl_value);
4261 if (err < 0) {
4262 WL_ERR("DTIM Interval Set Error, %d\n", err);
4263 goto exit;
4264 }
4265 }
4266 ioctl_value = 1;
4267 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_UP, &ioctl_value);
4268 if (err < 0) {
4269 WL_ERR("BRCMF_C_UP error (%d)\n", err);
4270 goto exit;
4271 }
4272
4273 memset(&join_params, 0, sizeof(join_params));
4274 /* join parameters starts with ssid */
4275 memcpy(&join_params.ssid_le, &ssid_le, sizeof(ssid_le));
4276 /* create softap */
4277 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_SSID, &join_params,
4278 sizeof(join_params));
4279 if (err < 0) {
4280 WL_ERR("SET SSID error (%d)\n", err);
4281 goto exit;
4282 }
4283 clear_bit(WL_STATUS_AP_CREATING, &cfg->status);
4284 set_bit(WL_STATUS_AP_CREATED, &cfg->status);
4285
4286exit:
4287 if (err)
4288 brcmf_set_mpc(ndev, 1);
4289 return err;
4290}
4291
4292static int brcmf_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *ndev)
4293{
4294 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
4295 s32 ioctl_value;
4296 s32 err = -EPERM;
4297
4298 WL_TRACE("Enter\n");
4299
4300 if (cfg->conf->mode == WL_MODE_AP) {
4301 /* Due to most likely deauths outstanding we sleep */
4302 /* first to make sure they get processed by fw. */
4303 msleep(400);
4304 ioctl_value = 0;
4305 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_AP, &ioctl_value);
4306 if (err < 0) {
4307 WL_ERR("setting AP mode failed %d\n", err);
4308 goto exit;
4309 }
4310 ioctl_value = 0;
4311 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_UP, &ioctl_value);
4312 if (err < 0) {
4313 WL_ERR("BRCMF_C_UP error %d\n", err);
4314 goto exit;
4315 }
4316 brcmf_set_mpc(ndev, 1);
4317 clear_bit(WL_STATUS_AP_CREATING, &cfg->status);
4318 clear_bit(WL_STATUS_AP_CREATED, &cfg->status);
4319 }
4320exit:
4321 return err;
4322}
4323
4324static int
4325brcmf_cfg80211_del_station(struct wiphy *wiphy, struct net_device *ndev,
4326 u8 *mac)
4327{
4328 struct brcmf_scb_val_le scbval;
4329 s32 err;
4330
4331 if (!mac)
4332 return -EFAULT;
4333
4334 WL_TRACE("Enter %pM\n", mac);
4335
4336 if (!check_sys_up(wiphy))
4337 return -EIO;
4338
4339 memcpy(&scbval.ea, mac, ETH_ALEN);
4340 scbval.val = cpu_to_le32(WLAN_REASON_DEAUTH_LEAVING);
4341 err = brcmf_exec_dcmd(ndev, BRCMF_C_SCB_DEAUTHENTICATE_FOR_REASON,
4342 &scbval, sizeof(scbval));
4343 if (err)
4344 WL_ERR("SCB_DEAUTHENTICATE_FOR_REASON failed %d\n", err);
4345
4346 WL_TRACE("Exit\n");
4347 return err;
4348}
4349
2729static struct cfg80211_ops wl_cfg80211_ops = { 4350static struct cfg80211_ops wl_cfg80211_ops = {
2730 .change_virtual_intf = brcmf_cfg80211_change_iface, 4351 .change_virtual_intf = brcmf_cfg80211_change_iface,
2731 .scan = brcmf_cfg80211_scan, 4352 .scan = brcmf_cfg80211_scan,
@@ -2748,7 +4369,18 @@ static struct cfg80211_ops wl_cfg80211_ops = {
2748 .resume = brcmf_cfg80211_resume, 4369 .resume = brcmf_cfg80211_resume,
2749 .set_pmksa = brcmf_cfg80211_set_pmksa, 4370 .set_pmksa = brcmf_cfg80211_set_pmksa,
2750 .del_pmksa = brcmf_cfg80211_del_pmksa, 4371 .del_pmksa = brcmf_cfg80211_del_pmksa,
2751 .flush_pmksa = brcmf_cfg80211_flush_pmksa 4372 .flush_pmksa = brcmf_cfg80211_flush_pmksa,
4373 .start_ap = brcmf_cfg80211_start_ap,
4374 .stop_ap = brcmf_cfg80211_stop_ap,
4375 .del_station = brcmf_cfg80211_del_station,
4376#ifndef CONFIG_BRCMISCAN
4377 /* scheduled scan need e-scan, which is mutual exclusive with i-scan */
4378 .sched_scan_start = brcmf_cfg80211_sched_scan_start,
4379 .sched_scan_stop = brcmf_cfg80211_sched_scan_stop,
4380#endif
4381#ifdef CONFIG_NL80211_TESTMODE
4382 .testmode_cmd = brcmf_cfg80211_testmode
4383#endif
2752}; 4384};
2753 4385
2754static s32 brcmf_mode_to_nl80211_iftype(s32 mode) 4386static s32 brcmf_mode_to_nl80211_iftype(s32 mode)
@@ -2767,8 +4399,18 @@ static s32 brcmf_mode_to_nl80211_iftype(s32 mode)
2767 return err; 4399 return err;
2768} 4400}
2769 4401
2770static struct wireless_dev *brcmf_alloc_wdev(s32 sizeof_iface, 4402static void brcmf_wiphy_pno_params(struct wiphy *wiphy)
2771 struct device *ndev) 4403{
4404#ifndef CONFIG_BRCMFISCAN
4405 /* scheduled scan settings */
4406 wiphy->max_sched_scan_ssids = BRCMF_PNO_MAX_PFN_COUNT;
4407 wiphy->max_match_sets = BRCMF_PNO_MAX_PFN_COUNT;
4408 wiphy->max_sched_scan_ie_len = BRCMF_SCAN_IE_LEN_MAX;
4409 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
4410#endif
4411}
4412
4413static struct wireless_dev *brcmf_alloc_wdev(struct device *ndev)
2772{ 4414{
2773 struct wireless_dev *wdev; 4415 struct wireless_dev *wdev;
2774 s32 err = 0; 4416 s32 err = 0;
@@ -2777,9 +4419,8 @@ static struct wireless_dev *brcmf_alloc_wdev(s32 sizeof_iface,
2777 if (!wdev) 4419 if (!wdev)
2778 return ERR_PTR(-ENOMEM); 4420 return ERR_PTR(-ENOMEM);
2779 4421
2780 wdev->wiphy = 4422 wdev->wiphy = wiphy_new(&wl_cfg80211_ops,
2781 wiphy_new(&wl_cfg80211_ops, 4423 sizeof(struct brcmf_cfg80211_info));
2782 sizeof(struct brcmf_cfg80211_priv) + sizeof_iface);
2783 if (!wdev->wiphy) { 4424 if (!wdev->wiphy) {
2784 WL_ERR("Could not allocate wiphy device\n"); 4425 WL_ERR("Could not allocate wiphy device\n");
2785 err = -ENOMEM; 4426 err = -ENOMEM;
@@ -2788,8 +4429,9 @@ static struct wireless_dev *brcmf_alloc_wdev(s32 sizeof_iface,
2788 set_wiphy_dev(wdev->wiphy, ndev); 4429 set_wiphy_dev(wdev->wiphy, ndev);
2789 wdev->wiphy->max_scan_ssids = WL_NUM_SCAN_MAX; 4430 wdev->wiphy->max_scan_ssids = WL_NUM_SCAN_MAX;
2790 wdev->wiphy->max_num_pmkids = WL_NUM_PMKIDS_MAX; 4431 wdev->wiphy->max_num_pmkids = WL_NUM_PMKIDS_MAX;
2791 wdev->wiphy->interface_modes = 4432 wdev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
2792 BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC); 4433 BIT(NL80211_IFTYPE_ADHOC) |
4434 BIT(NL80211_IFTYPE_AP);
2793 wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &__wl_band_2ghz; 4435 wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &__wl_band_2ghz;
2794 wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_a; /* Set 4436 wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_a; /* Set
2795 * it as 11a by default. 4437 * it as 11a by default.
@@ -2805,6 +4447,7 @@ static struct wireless_dev *brcmf_alloc_wdev(s32 sizeof_iface,
2805 * save mode 4447 * save mode
2806 * by default 4448 * by default
2807 */ 4449 */
4450 brcmf_wiphy_pno_params(wdev->wiphy);
2808 err = wiphy_register(wdev->wiphy); 4451 err = wiphy_register(wdev->wiphy);
2809 if (err < 0) { 4452 if (err < 0) {
2810 WL_ERR("Could not register wiphy device (%d)\n", err); 4453 WL_ERR("Could not register wiphy device (%d)\n", err);
@@ -2821,9 +4464,9 @@ wiphy_new_out:
2821 return ERR_PTR(err); 4464 return ERR_PTR(err);
2822} 4465}
2823 4466
2824static void brcmf_free_wdev(struct brcmf_cfg80211_priv *cfg_priv) 4467static void brcmf_free_wdev(struct brcmf_cfg80211_info *cfg)
2825{ 4468{
2826 struct wireless_dev *wdev = cfg_priv->wdev; 4469 struct wireless_dev *wdev = cfg->wdev;
2827 4470
2828 if (!wdev) { 4471 if (!wdev) {
2829 WL_ERR("wdev is invalid\n"); 4472 WL_ERR("wdev is invalid\n");
@@ -2832,10 +4475,10 @@ static void brcmf_free_wdev(struct brcmf_cfg80211_priv *cfg_priv)
2832 wiphy_unregister(wdev->wiphy); 4475 wiphy_unregister(wdev->wiphy);
2833 wiphy_free(wdev->wiphy); 4476 wiphy_free(wdev->wiphy);
2834 kfree(wdev); 4477 kfree(wdev);
2835 cfg_priv->wdev = NULL; 4478 cfg->wdev = NULL;
2836} 4479}
2837 4480
2838static bool brcmf_is_linkup(struct brcmf_cfg80211_priv *cfg_priv, 4481static bool brcmf_is_linkup(struct brcmf_cfg80211_info *cfg,
2839 const struct brcmf_event_msg *e) 4482 const struct brcmf_event_msg *e)
2840{ 4483{
2841 u32 event = be32_to_cpu(e->event_type); 4484 u32 event = be32_to_cpu(e->event_type);
@@ -2843,14 +4486,14 @@ static bool brcmf_is_linkup(struct brcmf_cfg80211_priv *cfg_priv,
2843 4486
2844 if (event == BRCMF_E_SET_SSID && status == BRCMF_E_STATUS_SUCCESS) { 4487 if (event == BRCMF_E_SET_SSID && status == BRCMF_E_STATUS_SUCCESS) {
2845 WL_CONN("Processing set ssid\n"); 4488 WL_CONN("Processing set ssid\n");
2846 cfg_priv->link_up = true; 4489 cfg->link_up = true;
2847 return true; 4490 return true;
2848 } 4491 }
2849 4492
2850 return false; 4493 return false;
2851} 4494}
2852 4495
2853static bool brcmf_is_linkdown(struct brcmf_cfg80211_priv *cfg_priv, 4496static bool brcmf_is_linkdown(struct brcmf_cfg80211_info *cfg,
2854 const struct brcmf_event_msg *e) 4497 const struct brcmf_event_msg *e)
2855{ 4498{
2856 u32 event = be32_to_cpu(e->event_type); 4499 u32 event = be32_to_cpu(e->event_type);
@@ -2863,7 +4506,7 @@ static bool brcmf_is_linkdown(struct brcmf_cfg80211_priv *cfg_priv,
2863 return false; 4506 return false;
2864} 4507}
2865 4508
2866static bool brcmf_is_nonetwork(struct brcmf_cfg80211_priv *cfg_priv, 4509static bool brcmf_is_nonetwork(struct brcmf_cfg80211_info *cfg,
2867 const struct brcmf_event_msg *e) 4510 const struct brcmf_event_msg *e)
2868{ 4511{
2869 u32 event = be32_to_cpu(e->event_type); 4512 u32 event = be32_to_cpu(e->event_type);
@@ -2884,9 +4527,9 @@ static bool brcmf_is_nonetwork(struct brcmf_cfg80211_priv *cfg_priv,
2884 return false; 4527 return false;
2885} 4528}
2886 4529
2887static void brcmf_clear_assoc_ies(struct brcmf_cfg80211_priv *cfg_priv) 4530static void brcmf_clear_assoc_ies(struct brcmf_cfg80211_info *cfg)
2888{ 4531{
2889 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg_priv); 4532 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
2890 4533
2891 kfree(conn_info->req_ie); 4534 kfree(conn_info->req_ie);
2892 conn_info->req_ie = NULL; 4535 conn_info->req_ie = NULL;
@@ -2896,30 +4539,30 @@ static void brcmf_clear_assoc_ies(struct brcmf_cfg80211_priv *cfg_priv)
2896 conn_info->resp_ie_len = 0; 4539 conn_info->resp_ie_len = 0;
2897} 4540}
2898 4541
2899static s32 brcmf_get_assoc_ies(struct brcmf_cfg80211_priv *cfg_priv) 4542static s32 brcmf_get_assoc_ies(struct brcmf_cfg80211_info *cfg)
2900{ 4543{
2901 struct net_device *ndev = cfg_to_ndev(cfg_priv); 4544 struct net_device *ndev = cfg_to_ndev(cfg);
2902 struct brcmf_cfg80211_assoc_ielen_le *assoc_info; 4545 struct brcmf_cfg80211_assoc_ielen_le *assoc_info;
2903 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg_priv); 4546 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
2904 u32 req_len; 4547 u32 req_len;
2905 u32 resp_len; 4548 u32 resp_len;
2906 s32 err = 0; 4549 s32 err = 0;
2907 4550
2908 brcmf_clear_assoc_ies(cfg_priv); 4551 brcmf_clear_assoc_ies(cfg);
2909 4552
2910 err = brcmf_dev_bufvar_get(ndev, "assoc_info", cfg_priv->extra_buf, 4553 err = brcmf_dev_bufvar_get(ndev, "assoc_info", cfg->extra_buf,
2911 WL_ASSOC_INFO_MAX); 4554 WL_ASSOC_INFO_MAX);
2912 if (err) { 4555 if (err) {
2913 WL_ERR("could not get assoc info (%d)\n", err); 4556 WL_ERR("could not get assoc info (%d)\n", err);
2914 return err; 4557 return err;
2915 } 4558 }
2916 assoc_info = 4559 assoc_info =
2917 (struct brcmf_cfg80211_assoc_ielen_le *)cfg_priv->extra_buf; 4560 (struct brcmf_cfg80211_assoc_ielen_le *)cfg->extra_buf;
2918 req_len = le32_to_cpu(assoc_info->req_len); 4561 req_len = le32_to_cpu(assoc_info->req_len);
2919 resp_len = le32_to_cpu(assoc_info->resp_len); 4562 resp_len = le32_to_cpu(assoc_info->resp_len);
2920 if (req_len) { 4563 if (req_len) {
2921 err = brcmf_dev_bufvar_get(ndev, "assoc_req_ies", 4564 err = brcmf_dev_bufvar_get(ndev, "assoc_req_ies",
2922 cfg_priv->extra_buf, 4565 cfg->extra_buf,
2923 WL_ASSOC_INFO_MAX); 4566 WL_ASSOC_INFO_MAX);
2924 if (err) { 4567 if (err) {
2925 WL_ERR("could not get assoc req (%d)\n", err); 4568 WL_ERR("could not get assoc req (%d)\n", err);
@@ -2927,7 +4570,7 @@ static s32 brcmf_get_assoc_ies(struct brcmf_cfg80211_priv *cfg_priv)
2927 } 4570 }
2928 conn_info->req_ie_len = req_len; 4571 conn_info->req_ie_len = req_len;
2929 conn_info->req_ie = 4572 conn_info->req_ie =
2930 kmemdup(cfg_priv->extra_buf, conn_info->req_ie_len, 4573 kmemdup(cfg->extra_buf, conn_info->req_ie_len,
2931 GFP_KERNEL); 4574 GFP_KERNEL);
2932 } else { 4575 } else {
2933 conn_info->req_ie_len = 0; 4576 conn_info->req_ie_len = 0;
@@ -2935,7 +4578,7 @@ static s32 brcmf_get_assoc_ies(struct brcmf_cfg80211_priv *cfg_priv)
2935 } 4578 }
2936 if (resp_len) { 4579 if (resp_len) {
2937 err = brcmf_dev_bufvar_get(ndev, "assoc_resp_ies", 4580 err = brcmf_dev_bufvar_get(ndev, "assoc_resp_ies",
2938 cfg_priv->extra_buf, 4581 cfg->extra_buf,
2939 WL_ASSOC_INFO_MAX); 4582 WL_ASSOC_INFO_MAX);
2940 if (err) { 4583 if (err) {
2941 WL_ERR("could not get assoc resp (%d)\n", err); 4584 WL_ERR("could not get assoc resp (%d)\n", err);
@@ -2943,7 +4586,7 @@ static s32 brcmf_get_assoc_ies(struct brcmf_cfg80211_priv *cfg_priv)
2943 } 4586 }
2944 conn_info->resp_ie_len = resp_len; 4587 conn_info->resp_ie_len = resp_len;
2945 conn_info->resp_ie = 4588 conn_info->resp_ie =
2946 kmemdup(cfg_priv->extra_buf, conn_info->resp_ie_len, 4589 kmemdup(cfg->extra_buf, conn_info->resp_ie_len,
2947 GFP_KERNEL); 4590 GFP_KERNEL);
2948 } else { 4591 } else {
2949 conn_info->resp_ie_len = 0; 4592 conn_info->resp_ie_len = 0;
@@ -2956,12 +4599,13 @@ static s32 brcmf_get_assoc_ies(struct brcmf_cfg80211_priv *cfg_priv)
2956} 4599}
2957 4600
2958static s32 4601static s32
2959brcmf_bss_roaming_done(struct brcmf_cfg80211_priv *cfg_priv, 4602brcmf_bss_roaming_done(struct brcmf_cfg80211_info *cfg,
2960 struct net_device *ndev, 4603 struct net_device *ndev,
2961 const struct brcmf_event_msg *e) 4604 const struct brcmf_event_msg *e)
2962{ 4605{
2963 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg_priv); 4606 struct brcmf_cfg80211_profile *profile = cfg->profile;
2964 struct wiphy *wiphy = cfg_to_wiphy(cfg_priv); 4607 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
4608 struct wiphy *wiphy = cfg_to_wiphy(cfg);
2965 struct brcmf_channel_info_le channel_le; 4609 struct brcmf_channel_info_le channel_le;
2966 struct ieee80211_channel *notify_channel; 4610 struct ieee80211_channel *notify_channel;
2967 struct ieee80211_supported_band *band; 4611 struct ieee80211_supported_band *band;
@@ -2971,9 +4615,9 @@ brcmf_bss_roaming_done(struct brcmf_cfg80211_priv *cfg_priv,
2971 4615
2972 WL_TRACE("Enter\n"); 4616 WL_TRACE("Enter\n");
2973 4617
2974 brcmf_get_assoc_ies(cfg_priv); 4618 brcmf_get_assoc_ies(cfg);
2975 brcmf_update_prof(cfg_priv, NULL, &e->addr, WL_PROF_BSSID); 4619 memcpy(profile->bssid, e->addr, ETH_ALEN);
2976 brcmf_update_bss_info(cfg_priv); 4620 brcmf_update_bss_info(cfg);
2977 4621
2978 brcmf_exec_dcmd(ndev, BRCMF_C_GET_CHANNEL, &channel_le, 4622 brcmf_exec_dcmd(ndev, BRCMF_C_GET_CHANNEL, &channel_le,
2979 sizeof(channel_le)); 4623 sizeof(channel_le));
@@ -2989,37 +4633,35 @@ brcmf_bss_roaming_done(struct brcmf_cfg80211_priv *cfg_priv,
2989 freq = ieee80211_channel_to_frequency(target_channel, band->band); 4633 freq = ieee80211_channel_to_frequency(target_channel, band->band);
2990 notify_channel = ieee80211_get_channel(wiphy, freq); 4634 notify_channel = ieee80211_get_channel(wiphy, freq);
2991 4635
2992 cfg80211_roamed(ndev, notify_channel, 4636 cfg80211_roamed(ndev, notify_channel, (u8 *)profile->bssid,
2993 (u8 *)brcmf_read_prof(cfg_priv, WL_PROF_BSSID),
2994 conn_info->req_ie, conn_info->req_ie_len, 4637 conn_info->req_ie, conn_info->req_ie_len,
2995 conn_info->resp_ie, conn_info->resp_ie_len, GFP_KERNEL); 4638 conn_info->resp_ie, conn_info->resp_ie_len, GFP_KERNEL);
2996 WL_CONN("Report roaming result\n"); 4639 WL_CONN("Report roaming result\n");
2997 4640
2998 set_bit(WL_STATUS_CONNECTED, &cfg_priv->status); 4641 set_bit(WL_STATUS_CONNECTED, &cfg->status);
2999 WL_TRACE("Exit\n"); 4642 WL_TRACE("Exit\n");
3000 return err; 4643 return err;
3001} 4644}
3002 4645
3003static s32 4646static s32
3004brcmf_bss_connect_done(struct brcmf_cfg80211_priv *cfg_priv, 4647brcmf_bss_connect_done(struct brcmf_cfg80211_info *cfg,
3005 struct net_device *ndev, const struct brcmf_event_msg *e, 4648 struct net_device *ndev, const struct brcmf_event_msg *e,
3006 bool completed) 4649 bool completed)
3007{ 4650{
3008 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg_priv); 4651 struct brcmf_cfg80211_profile *profile = cfg->profile;
4652 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
3009 s32 err = 0; 4653 s32 err = 0;
3010 4654
3011 WL_TRACE("Enter\n"); 4655 WL_TRACE("Enter\n");
3012 4656
3013 if (test_and_clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status)) { 4657 if (test_and_clear_bit(WL_STATUS_CONNECTING, &cfg->status)) {
3014 if (completed) { 4658 if (completed) {
3015 brcmf_get_assoc_ies(cfg_priv); 4659 brcmf_get_assoc_ies(cfg);
3016 brcmf_update_prof(cfg_priv, NULL, &e->addr, 4660 memcpy(profile->bssid, e->addr, ETH_ALEN);
3017 WL_PROF_BSSID); 4661 brcmf_update_bss_info(cfg);
3018 brcmf_update_bss_info(cfg_priv);
3019 } 4662 }
3020 cfg80211_connect_result(ndev, 4663 cfg80211_connect_result(ndev,
3021 (u8 *)brcmf_read_prof(cfg_priv, 4664 (u8 *)profile->bssid,
3022 WL_PROF_BSSID),
3023 conn_info->req_ie, 4665 conn_info->req_ie,
3024 conn_info->req_ie_len, 4666 conn_info->req_ie_len,
3025 conn_info->resp_ie, 4667 conn_info->resp_ie,
@@ -3028,7 +4670,7 @@ brcmf_bss_connect_done(struct brcmf_cfg80211_priv *cfg_priv,
3028 WLAN_STATUS_AUTH_TIMEOUT, 4670 WLAN_STATUS_AUTH_TIMEOUT,
3029 GFP_KERNEL); 4671 GFP_KERNEL);
3030 if (completed) 4672 if (completed)
3031 set_bit(WL_STATUS_CONNECTED, &cfg_priv->status); 4673 set_bit(WL_STATUS_CONNECTED, &cfg->status);
3032 WL_CONN("Report connect result - connection %s\n", 4674 WL_CONN("Report connect result - connection %s\n",
3033 completed ? "succeeded" : "failed"); 4675 completed ? "succeeded" : "failed");
3034 } 4676 }
@@ -3037,52 +4679,93 @@ brcmf_bss_connect_done(struct brcmf_cfg80211_priv *cfg_priv,
3037} 4679}
3038 4680
3039static s32 4681static s32
3040brcmf_notify_connect_status(struct brcmf_cfg80211_priv *cfg_priv, 4682brcmf_notify_connect_status_ap(struct brcmf_cfg80211_info *cfg,
4683 struct net_device *ndev,
4684 const struct brcmf_event_msg *e, void *data)
4685{
4686 s32 err = 0;
4687 u32 event = be32_to_cpu(e->event_type);
4688 u32 reason = be32_to_cpu(e->reason);
4689 u32 len = be32_to_cpu(e->datalen);
4690 static int generation;
4691
4692 struct station_info sinfo;
4693
4694 WL_CONN("event %d, reason %d\n", event, reason);
4695 memset(&sinfo, 0, sizeof(sinfo));
4696
4697 sinfo.filled = 0;
4698 if (((event == BRCMF_E_ASSOC_IND) || (event == BRCMF_E_REASSOC_IND)) &&
4699 reason == BRCMF_E_STATUS_SUCCESS) {
4700 sinfo.filled = STATION_INFO_ASSOC_REQ_IES;
4701 if (!data) {
4702 WL_ERR("No IEs present in ASSOC/REASSOC_IND");
4703 return -EINVAL;
4704 }
4705 sinfo.assoc_req_ies = data;
4706 sinfo.assoc_req_ies_len = len;
4707 generation++;
4708 sinfo.generation = generation;
4709 cfg80211_new_sta(ndev, e->addr, &sinfo, GFP_ATOMIC);
4710 } else if ((event == BRCMF_E_DISASSOC_IND) ||
4711 (event == BRCMF_E_DEAUTH_IND) ||
4712 (event == BRCMF_E_DEAUTH)) {
4713 generation++;
4714 sinfo.generation = generation;
4715 cfg80211_del_sta(ndev, e->addr, GFP_ATOMIC);
4716 }
4717 return err;
4718}
4719
4720static s32
4721brcmf_notify_connect_status(struct brcmf_cfg80211_info *cfg,
3041 struct net_device *ndev, 4722 struct net_device *ndev,
3042 const struct brcmf_event_msg *e, void *data) 4723 const struct brcmf_event_msg *e, void *data)
3043{ 4724{
4725 struct brcmf_cfg80211_profile *profile = cfg->profile;
3044 s32 err = 0; 4726 s32 err = 0;
3045 4727
3046 if (brcmf_is_linkup(cfg_priv, e)) { 4728 if (cfg->conf->mode == WL_MODE_AP) {
4729 err = brcmf_notify_connect_status_ap(cfg, ndev, e, data);
4730 } else if (brcmf_is_linkup(cfg, e)) {
3047 WL_CONN("Linkup\n"); 4731 WL_CONN("Linkup\n");
3048 if (brcmf_is_ibssmode(cfg_priv)) { 4732 if (brcmf_is_ibssmode(cfg)) {
3049 brcmf_update_prof(cfg_priv, NULL, (void *)e->addr, 4733 memcpy(profile->bssid, e->addr, ETH_ALEN);
3050 WL_PROF_BSSID); 4734 wl_inform_ibss(cfg, ndev, e->addr);
3051 wl_inform_ibss(cfg_priv, ndev, e->addr);
3052 cfg80211_ibss_joined(ndev, e->addr, GFP_KERNEL); 4735 cfg80211_ibss_joined(ndev, e->addr, GFP_KERNEL);
3053 clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status); 4736 clear_bit(WL_STATUS_CONNECTING, &cfg->status);
3054 set_bit(WL_STATUS_CONNECTED, &cfg_priv->status); 4737 set_bit(WL_STATUS_CONNECTED, &cfg->status);
3055 } else 4738 } else
3056 brcmf_bss_connect_done(cfg_priv, ndev, e, true); 4739 brcmf_bss_connect_done(cfg, ndev, e, true);
3057 } else if (brcmf_is_linkdown(cfg_priv, e)) { 4740 } else if (brcmf_is_linkdown(cfg, e)) {
3058 WL_CONN("Linkdown\n"); 4741 WL_CONN("Linkdown\n");
3059 if (brcmf_is_ibssmode(cfg_priv)) { 4742 if (brcmf_is_ibssmode(cfg)) {
3060 clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status); 4743 clear_bit(WL_STATUS_CONNECTING, &cfg->status);
3061 if (test_and_clear_bit(WL_STATUS_CONNECTED, 4744 if (test_and_clear_bit(WL_STATUS_CONNECTED,
3062 &cfg_priv->status)) 4745 &cfg->status))
3063 brcmf_link_down(cfg_priv); 4746 brcmf_link_down(cfg);
3064 } else { 4747 } else {
3065 brcmf_bss_connect_done(cfg_priv, ndev, e, false); 4748 brcmf_bss_connect_done(cfg, ndev, e, false);
3066 if (test_and_clear_bit(WL_STATUS_CONNECTED, 4749 if (test_and_clear_bit(WL_STATUS_CONNECTED,
3067 &cfg_priv->status)) { 4750 &cfg->status)) {
3068 cfg80211_disconnected(ndev, 0, NULL, 0, 4751 cfg80211_disconnected(ndev, 0, NULL, 0,
3069 GFP_KERNEL); 4752 GFP_KERNEL);
3070 brcmf_link_down(cfg_priv); 4753 brcmf_link_down(cfg);
3071 } 4754 }
3072 } 4755 }
3073 brcmf_init_prof(cfg_priv->profile); 4756 brcmf_init_prof(cfg->profile);
3074 } else if (brcmf_is_nonetwork(cfg_priv, e)) { 4757 } else if (brcmf_is_nonetwork(cfg, e)) {
3075 if (brcmf_is_ibssmode(cfg_priv)) 4758 if (brcmf_is_ibssmode(cfg))
3076 clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status); 4759 clear_bit(WL_STATUS_CONNECTING, &cfg->status);
3077 else 4760 else
3078 brcmf_bss_connect_done(cfg_priv, ndev, e, false); 4761 brcmf_bss_connect_done(cfg, ndev, e, false);
3079 } 4762 }
3080 4763
3081 return err; 4764 return err;
3082} 4765}
3083 4766
3084static s32 4767static s32
3085brcmf_notify_roaming_status(struct brcmf_cfg80211_priv *cfg_priv, 4768brcmf_notify_roaming_status(struct brcmf_cfg80211_info *cfg,
3086 struct net_device *ndev, 4769 struct net_device *ndev,
3087 const struct brcmf_event_msg *e, void *data) 4770 const struct brcmf_event_msg *e, void *data)
3088{ 4771{
@@ -3091,17 +4774,17 @@ brcmf_notify_roaming_status(struct brcmf_cfg80211_priv *cfg_priv,
3091 u32 status = be32_to_cpu(e->status); 4774 u32 status = be32_to_cpu(e->status);
3092 4775
3093 if (event == BRCMF_E_ROAM && status == BRCMF_E_STATUS_SUCCESS) { 4776 if (event == BRCMF_E_ROAM && status == BRCMF_E_STATUS_SUCCESS) {
3094 if (test_bit(WL_STATUS_CONNECTED, &cfg_priv->status)) 4777 if (test_bit(WL_STATUS_CONNECTED, &cfg->status))
3095 brcmf_bss_roaming_done(cfg_priv, ndev, e); 4778 brcmf_bss_roaming_done(cfg, ndev, e);
3096 else 4779 else
3097 brcmf_bss_connect_done(cfg_priv, ndev, e, true); 4780 brcmf_bss_connect_done(cfg, ndev, e, true);
3098 } 4781 }
3099 4782
3100 return err; 4783 return err;
3101} 4784}
3102 4785
3103static s32 4786static s32
3104brcmf_notify_mic_status(struct brcmf_cfg80211_priv *cfg_priv, 4787brcmf_notify_mic_status(struct brcmf_cfg80211_info *cfg,
3105 struct net_device *ndev, 4788 struct net_device *ndev,
3106 const struct brcmf_event_msg *e, void *data) 4789 const struct brcmf_event_msg *e, void *data)
3107{ 4790{
@@ -3120,7 +4803,7 @@ brcmf_notify_mic_status(struct brcmf_cfg80211_priv *cfg_priv,
3120} 4803}
3121 4804
3122static s32 4805static s32
3123brcmf_notify_scan_status(struct brcmf_cfg80211_priv *cfg_priv, 4806brcmf_notify_scan_status(struct brcmf_cfg80211_info *cfg,
3124 struct net_device *ndev, 4807 struct net_device *ndev,
3125 const struct brcmf_event_msg *e, void *data) 4808 const struct brcmf_event_msg *e, void *data)
3126{ 4809{
@@ -3133,12 +4816,12 @@ brcmf_notify_scan_status(struct brcmf_cfg80211_priv *cfg_priv,
3133 4816
3134 WL_TRACE("Enter\n"); 4817 WL_TRACE("Enter\n");
3135 4818
3136 if (cfg_priv->iscan_on && cfg_priv->iscan_kickstart) { 4819 if (cfg->iscan_on && cfg->iscan_kickstart) {
3137 WL_TRACE("Exit\n"); 4820 WL_TRACE("Exit\n");
3138 return brcmf_wakeup_iscan(cfg_to_iscan(cfg_priv)); 4821 return brcmf_wakeup_iscan(cfg_to_iscan(cfg));
3139 } 4822 }
3140 4823
3141 if (!test_and_clear_bit(WL_STATUS_SCANNING, &cfg_priv->status)) { 4824 if (!test_and_clear_bit(WL_STATUS_SCANNING, &cfg->status)) {
3142 WL_ERR("Scan complete while device not scanning\n"); 4825 WL_ERR("Scan complete while device not scanning\n");
3143 scan_abort = true; 4826 scan_abort = true;
3144 err = -EINVAL; 4827 err = -EINVAL;
@@ -3155,35 +4838,33 @@ brcmf_notify_scan_status(struct brcmf_cfg80211_priv *cfg_priv,
3155 scan_channel = le32_to_cpu(channel_inform_le.scan_channel); 4838 scan_channel = le32_to_cpu(channel_inform_le.scan_channel);
3156 if (scan_channel) 4839 if (scan_channel)
3157 WL_CONN("channel_inform.scan_channel (%d)\n", scan_channel); 4840 WL_CONN("channel_inform.scan_channel (%d)\n", scan_channel);
3158 cfg_priv->bss_list = cfg_priv->scan_results; 4841 cfg->bss_list = cfg->scan_results;
3159 bss_list_le = (struct brcmf_scan_results_le *) cfg_priv->bss_list; 4842 bss_list_le = (struct brcmf_scan_results_le *) cfg->bss_list;
3160 4843
3161 memset(cfg_priv->scan_results, 0, len); 4844 memset(cfg->scan_results, 0, len);
3162 bss_list_le->buflen = cpu_to_le32(len); 4845 bss_list_le->buflen = cpu_to_le32(len);
3163 err = brcmf_exec_dcmd(ndev, BRCMF_C_SCAN_RESULTS, 4846 err = brcmf_exec_dcmd(ndev, BRCMF_C_SCAN_RESULTS,
3164 cfg_priv->scan_results, len); 4847 cfg->scan_results, len);
3165 if (err) { 4848 if (err) {
3166 WL_ERR("%s Scan_results error (%d)\n", ndev->name, err); 4849 WL_ERR("%s Scan_results error (%d)\n", ndev->name, err);
3167 err = -EINVAL; 4850 err = -EINVAL;
3168 scan_abort = true; 4851 scan_abort = true;
3169 goto scan_done_out; 4852 goto scan_done_out;
3170 } 4853 }
3171 cfg_priv->scan_results->buflen = le32_to_cpu(bss_list_le->buflen); 4854 cfg->scan_results->buflen = le32_to_cpu(bss_list_le->buflen);
3172 cfg_priv->scan_results->version = le32_to_cpu(bss_list_le->version); 4855 cfg->scan_results->version = le32_to_cpu(bss_list_le->version);
3173 cfg_priv->scan_results->count = le32_to_cpu(bss_list_le->count); 4856 cfg->scan_results->count = le32_to_cpu(bss_list_le->count);
3174 4857
3175 err = brcmf_inform_bss(cfg_priv); 4858 err = brcmf_inform_bss(cfg);
3176 if (err) { 4859 if (err)
3177 scan_abort = true; 4860 scan_abort = true;
3178 goto scan_done_out;
3179 }
3180 4861
3181scan_done_out: 4862scan_done_out:
3182 if (cfg_priv->scan_request) { 4863 if (cfg->scan_request) {
3183 WL_SCAN("calling cfg80211_scan_done\n"); 4864 WL_SCAN("calling cfg80211_scan_done\n");
3184 cfg80211_scan_done(cfg_priv->scan_request, scan_abort); 4865 cfg80211_scan_done(cfg->scan_request, scan_abort);
3185 brcmf_set_mpc(ndev, 1); 4866 brcmf_set_mpc(ndev, 1);
3186 cfg_priv->scan_request = NULL; 4867 cfg->scan_request = NULL;
3187 } 4868 }
3188 4869
3189 WL_TRACE("Exit\n"); 4870 WL_TRACE("Exit\n");
@@ -3206,68 +4887,85 @@ static void brcmf_init_eloop_handler(struct brcmf_cfg80211_event_loop *el)
3206 memset(el, 0, sizeof(*el)); 4887 memset(el, 0, sizeof(*el));
3207 el->handler[BRCMF_E_SCAN_COMPLETE] = brcmf_notify_scan_status; 4888 el->handler[BRCMF_E_SCAN_COMPLETE] = brcmf_notify_scan_status;
3208 el->handler[BRCMF_E_LINK] = brcmf_notify_connect_status; 4889 el->handler[BRCMF_E_LINK] = brcmf_notify_connect_status;
4890 el->handler[BRCMF_E_DEAUTH_IND] = brcmf_notify_connect_status;
4891 el->handler[BRCMF_E_DEAUTH] = brcmf_notify_connect_status;
4892 el->handler[BRCMF_E_DISASSOC_IND] = brcmf_notify_connect_status;
4893 el->handler[BRCMF_E_ASSOC_IND] = brcmf_notify_connect_status;
4894 el->handler[BRCMF_E_REASSOC_IND] = brcmf_notify_connect_status;
3209 el->handler[BRCMF_E_ROAM] = brcmf_notify_roaming_status; 4895 el->handler[BRCMF_E_ROAM] = brcmf_notify_roaming_status;
3210 el->handler[BRCMF_E_MIC_ERROR] = brcmf_notify_mic_status; 4896 el->handler[BRCMF_E_MIC_ERROR] = brcmf_notify_mic_status;
3211 el->handler[BRCMF_E_SET_SSID] = brcmf_notify_connect_status; 4897 el->handler[BRCMF_E_SET_SSID] = brcmf_notify_connect_status;
4898 el->handler[BRCMF_E_PFN_NET_FOUND] = brcmf_notify_sched_scan_results;
4899}
4900
4901static void brcmf_deinit_priv_mem(struct brcmf_cfg80211_info *cfg)
4902{
4903 kfree(cfg->scan_results);
4904 cfg->scan_results = NULL;
4905 kfree(cfg->bss_info);
4906 cfg->bss_info = NULL;
4907 kfree(cfg->conf);
4908 cfg->conf = NULL;
4909 kfree(cfg->profile);
4910 cfg->profile = NULL;
4911 kfree(cfg->scan_req_int);
4912 cfg->scan_req_int = NULL;
4913 kfree(cfg->escan_ioctl_buf);
4914 cfg->escan_ioctl_buf = NULL;
4915 kfree(cfg->dcmd_buf);
4916 cfg->dcmd_buf = NULL;
4917 kfree(cfg->extra_buf);
4918 cfg->extra_buf = NULL;
4919 kfree(cfg->iscan);
4920 cfg->iscan = NULL;
4921 kfree(cfg->pmk_list);
4922 cfg->pmk_list = NULL;
4923 if (cfg->ap_info) {
4924 kfree(cfg->ap_info->wpa_ie);
4925 kfree(cfg->ap_info->rsn_ie);
4926 kfree(cfg->ap_info);
4927 cfg->ap_info = NULL;
4928 }
3212} 4929}
3213 4930
3214static void brcmf_deinit_priv_mem(struct brcmf_cfg80211_priv *cfg_priv) 4931static s32 brcmf_init_priv_mem(struct brcmf_cfg80211_info *cfg)
3215{ 4932{
3216 kfree(cfg_priv->scan_results); 4933 cfg->scan_results = kzalloc(WL_SCAN_BUF_MAX, GFP_KERNEL);
3217 cfg_priv->scan_results = NULL; 4934 if (!cfg->scan_results)
3218 kfree(cfg_priv->bss_info);
3219 cfg_priv->bss_info = NULL;
3220 kfree(cfg_priv->conf);
3221 cfg_priv->conf = NULL;
3222 kfree(cfg_priv->profile);
3223 cfg_priv->profile = NULL;
3224 kfree(cfg_priv->scan_req_int);
3225 cfg_priv->scan_req_int = NULL;
3226 kfree(cfg_priv->dcmd_buf);
3227 cfg_priv->dcmd_buf = NULL;
3228 kfree(cfg_priv->extra_buf);
3229 cfg_priv->extra_buf = NULL;
3230 kfree(cfg_priv->iscan);
3231 cfg_priv->iscan = NULL;
3232 kfree(cfg_priv->pmk_list);
3233 cfg_priv->pmk_list = NULL;
3234}
3235
3236static s32 brcmf_init_priv_mem(struct brcmf_cfg80211_priv *cfg_priv)
3237{
3238 cfg_priv->scan_results = kzalloc(WL_SCAN_BUF_MAX, GFP_KERNEL);
3239 if (!cfg_priv->scan_results)
3240 goto init_priv_mem_out; 4935 goto init_priv_mem_out;
3241 cfg_priv->conf = kzalloc(sizeof(*cfg_priv->conf), GFP_KERNEL); 4936 cfg->conf = kzalloc(sizeof(*cfg->conf), GFP_KERNEL);
3242 if (!cfg_priv->conf) 4937 if (!cfg->conf)
3243 goto init_priv_mem_out; 4938 goto init_priv_mem_out;
3244 cfg_priv->profile = kzalloc(sizeof(*cfg_priv->profile), GFP_KERNEL); 4939 cfg->profile = kzalloc(sizeof(*cfg->profile), GFP_KERNEL);
3245 if (!cfg_priv->profile) 4940 if (!cfg->profile)
3246 goto init_priv_mem_out; 4941 goto init_priv_mem_out;
3247 cfg_priv->bss_info = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL); 4942 cfg->bss_info = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
3248 if (!cfg_priv->bss_info) 4943 if (!cfg->bss_info)
3249 goto init_priv_mem_out; 4944 goto init_priv_mem_out;
3250 cfg_priv->scan_req_int = kzalloc(sizeof(*cfg_priv->scan_req_int), 4945 cfg->scan_req_int = kzalloc(sizeof(*cfg->scan_req_int),
3251 GFP_KERNEL); 4946 GFP_KERNEL);
3252 if (!cfg_priv->scan_req_int) 4947 if (!cfg->scan_req_int)
4948 goto init_priv_mem_out;
4949 cfg->escan_ioctl_buf = kzalloc(BRCMF_DCMD_MEDLEN, GFP_KERNEL);
4950 if (!cfg->escan_ioctl_buf)
3253 goto init_priv_mem_out; 4951 goto init_priv_mem_out;
3254 cfg_priv->dcmd_buf = kzalloc(WL_DCMD_LEN_MAX, GFP_KERNEL); 4952 cfg->dcmd_buf = kzalloc(WL_DCMD_LEN_MAX, GFP_KERNEL);
3255 if (!cfg_priv->dcmd_buf) 4953 if (!cfg->dcmd_buf)
3256 goto init_priv_mem_out; 4954 goto init_priv_mem_out;
3257 cfg_priv->extra_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL); 4955 cfg->extra_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL);
3258 if (!cfg_priv->extra_buf) 4956 if (!cfg->extra_buf)
3259 goto init_priv_mem_out; 4957 goto init_priv_mem_out;
3260 cfg_priv->iscan = kzalloc(sizeof(*cfg_priv->iscan), GFP_KERNEL); 4958 cfg->iscan = kzalloc(sizeof(*cfg->iscan), GFP_KERNEL);
3261 if (!cfg_priv->iscan) 4959 if (!cfg->iscan)
3262 goto init_priv_mem_out; 4960 goto init_priv_mem_out;
3263 cfg_priv->pmk_list = kzalloc(sizeof(*cfg_priv->pmk_list), GFP_KERNEL); 4961 cfg->pmk_list = kzalloc(sizeof(*cfg->pmk_list), GFP_KERNEL);
3264 if (!cfg_priv->pmk_list) 4962 if (!cfg->pmk_list)
3265 goto init_priv_mem_out; 4963 goto init_priv_mem_out;
3266 4964
3267 return 0; 4965 return 0;
3268 4966
3269init_priv_mem_out: 4967init_priv_mem_out:
3270 brcmf_deinit_priv_mem(cfg_priv); 4968 brcmf_deinit_priv_mem(cfg);
3271 4969
3272 return -ENOMEM; 4970 return -ENOMEM;
3273} 4971}
@@ -3277,17 +4975,17 @@ init_priv_mem_out:
3277*/ 4975*/
3278 4976
3279static struct brcmf_cfg80211_event_q *brcmf_deq_event( 4977static struct brcmf_cfg80211_event_q *brcmf_deq_event(
3280 struct brcmf_cfg80211_priv *cfg_priv) 4978 struct brcmf_cfg80211_info *cfg)
3281{ 4979{
3282 struct brcmf_cfg80211_event_q *e = NULL; 4980 struct brcmf_cfg80211_event_q *e = NULL;
3283 4981
3284 spin_lock_irq(&cfg_priv->evt_q_lock); 4982 spin_lock_irq(&cfg->evt_q_lock);
3285 if (!list_empty(&cfg_priv->evt_q_list)) { 4983 if (!list_empty(&cfg->evt_q_list)) {
3286 e = list_first_entry(&cfg_priv->evt_q_list, 4984 e = list_first_entry(&cfg->evt_q_list,
3287 struct brcmf_cfg80211_event_q, evt_q_list); 4985 struct brcmf_cfg80211_event_q, evt_q_list);
3288 list_del(&e->evt_q_list); 4986 list_del(&e->evt_q_list);
3289 } 4987 }
3290 spin_unlock_irq(&cfg_priv->evt_q_lock); 4988 spin_unlock_irq(&cfg->evt_q_lock);
3291 4989
3292 return e; 4990 return e;
3293} 4991}
@@ -3299,23 +4997,33 @@ static struct brcmf_cfg80211_event_q *brcmf_deq_event(
3299*/ 4997*/
3300 4998
3301static s32 4999static s32
3302brcmf_enq_event(struct brcmf_cfg80211_priv *cfg_priv, u32 event, 5000brcmf_enq_event(struct brcmf_cfg80211_info *cfg, u32 event,
3303 const struct brcmf_event_msg *msg) 5001 const struct brcmf_event_msg *msg, void *data)
3304{ 5002{
3305 struct brcmf_cfg80211_event_q *e; 5003 struct brcmf_cfg80211_event_q *e;
3306 s32 err = 0; 5004 s32 err = 0;
3307 ulong flags; 5005 ulong flags;
5006 u32 data_len;
5007 u32 total_len;
3308 5008
3309 e = kzalloc(sizeof(struct brcmf_cfg80211_event_q), GFP_ATOMIC); 5009 total_len = sizeof(struct brcmf_cfg80211_event_q);
5010 if (data)
5011 data_len = be32_to_cpu(msg->datalen);
5012 else
5013 data_len = 0;
5014 total_len += data_len;
5015 e = kzalloc(total_len, GFP_ATOMIC);
3310 if (!e) 5016 if (!e)
3311 return -ENOMEM; 5017 return -ENOMEM;
3312 5018
3313 e->etype = event; 5019 e->etype = event;
3314 memcpy(&e->emsg, msg, sizeof(struct brcmf_event_msg)); 5020 memcpy(&e->emsg, msg, sizeof(struct brcmf_event_msg));
5021 if (data)
5022 memcpy(&e->edata, data, data_len);
3315 5023
3316 spin_lock_irqsave(&cfg_priv->evt_q_lock, flags); 5024 spin_lock_irqsave(&cfg->evt_q_lock, flags);
3317 list_add_tail(&e->evt_q_list, &cfg_priv->evt_q_list); 5025 list_add_tail(&e->evt_q_list, &cfg->evt_q_list);
3318 spin_unlock_irqrestore(&cfg_priv->evt_q_lock, flags); 5026 spin_unlock_irqrestore(&cfg->evt_q_lock, flags);
3319 5027
3320 return err; 5028 return err;
3321} 5029}
@@ -3327,12 +5035,12 @@ static void brcmf_put_event(struct brcmf_cfg80211_event_q *e)
3327 5035
3328static void brcmf_cfg80211_event_handler(struct work_struct *work) 5036static void brcmf_cfg80211_event_handler(struct work_struct *work)
3329{ 5037{
3330 struct brcmf_cfg80211_priv *cfg_priv = 5038 struct brcmf_cfg80211_info *cfg =
3331 container_of(work, struct brcmf_cfg80211_priv, 5039 container_of(work, struct brcmf_cfg80211_info,
3332 event_work); 5040 event_work);
3333 struct brcmf_cfg80211_event_q *e; 5041 struct brcmf_cfg80211_event_q *e;
3334 5042
3335 e = brcmf_deq_event(cfg_priv); 5043 e = brcmf_deq_event(cfg);
3336 if (unlikely(!e)) { 5044 if (unlikely(!e)) {
3337 WL_ERR("event queue empty...\n"); 5045 WL_ERR("event queue empty...\n");
3338 return; 5046 return;
@@ -3340,137 +5048,131 @@ static void brcmf_cfg80211_event_handler(struct work_struct *work)
3340 5048
3341 do { 5049 do {
3342 WL_INFO("event type (%d)\n", e->etype); 5050 WL_INFO("event type (%d)\n", e->etype);
3343 if (cfg_priv->el.handler[e->etype]) 5051 if (cfg->el.handler[e->etype])
3344 cfg_priv->el.handler[e->etype](cfg_priv, 5052 cfg->el.handler[e->etype](cfg,
3345 cfg_to_ndev(cfg_priv), 5053 cfg_to_ndev(cfg),
3346 &e->emsg, e->edata); 5054 &e->emsg, e->edata);
3347 else 5055 else
3348 WL_INFO("Unknown Event (%d): ignoring\n", e->etype); 5056 WL_INFO("Unknown Event (%d): ignoring\n", e->etype);
3349 brcmf_put_event(e); 5057 brcmf_put_event(e);
3350 } while ((e = brcmf_deq_event(cfg_priv))); 5058 } while ((e = brcmf_deq_event(cfg)));
3351 5059
3352} 5060}
3353 5061
3354static void brcmf_init_eq(struct brcmf_cfg80211_priv *cfg_priv) 5062static void brcmf_init_eq(struct brcmf_cfg80211_info *cfg)
3355{ 5063{
3356 spin_lock_init(&cfg_priv->evt_q_lock); 5064 spin_lock_init(&cfg->evt_q_lock);
3357 INIT_LIST_HEAD(&cfg_priv->evt_q_list); 5065 INIT_LIST_HEAD(&cfg->evt_q_list);
3358} 5066}
3359 5067
3360static void brcmf_flush_eq(struct brcmf_cfg80211_priv *cfg_priv) 5068static void brcmf_flush_eq(struct brcmf_cfg80211_info *cfg)
3361{ 5069{
3362 struct brcmf_cfg80211_event_q *e; 5070 struct brcmf_cfg80211_event_q *e;
3363 5071
3364 spin_lock_irq(&cfg_priv->evt_q_lock); 5072 spin_lock_irq(&cfg->evt_q_lock);
3365 while (!list_empty(&cfg_priv->evt_q_list)) { 5073 while (!list_empty(&cfg->evt_q_list)) {
3366 e = list_first_entry(&cfg_priv->evt_q_list, 5074 e = list_first_entry(&cfg->evt_q_list,
3367 struct brcmf_cfg80211_event_q, evt_q_list); 5075 struct brcmf_cfg80211_event_q, evt_q_list);
3368 list_del(&e->evt_q_list); 5076 list_del(&e->evt_q_list);
3369 kfree(e); 5077 kfree(e);
3370 } 5078 }
3371 spin_unlock_irq(&cfg_priv->evt_q_lock); 5079 spin_unlock_irq(&cfg->evt_q_lock);
3372} 5080}
3373 5081
3374static s32 wl_init_priv(struct brcmf_cfg80211_priv *cfg_priv) 5082static s32 wl_init_priv(struct brcmf_cfg80211_info *cfg)
3375{ 5083{
3376 s32 err = 0; 5084 s32 err = 0;
3377 5085
3378 cfg_priv->scan_request = NULL; 5086 cfg->scan_request = NULL;
3379 cfg_priv->pwr_save = true; 5087 cfg->pwr_save = true;
3380 cfg_priv->iscan_on = true; /* iscan on & off switch. 5088#ifdef CONFIG_BRCMISCAN
5089 cfg->iscan_on = true; /* iscan on & off switch.
3381 we enable iscan per default */ 5090 we enable iscan per default */
3382 cfg_priv->roam_on = true; /* roam on & off switch. 5091 cfg->escan_on = false; /* escan on & off switch.
5092 we disable escan per default */
5093#else
5094 cfg->iscan_on = false; /* iscan on & off switch.
5095 we disable iscan per default */
5096 cfg->escan_on = true; /* escan on & off switch.
5097 we enable escan per default */
5098#endif
5099 cfg->roam_on = true; /* roam on & off switch.
3383 we enable roam per default */ 5100 we enable roam per default */
3384 5101
3385 cfg_priv->iscan_kickstart = false; 5102 cfg->iscan_kickstart = false;
3386 cfg_priv->active_scan = true; /* we do active scan for 5103 cfg->active_scan = true; /* we do active scan for
3387 specific scan per default */ 5104 specific scan per default */
3388 cfg_priv->dongle_up = false; /* dongle is not up yet */ 5105 cfg->dongle_up = false; /* dongle is not up yet */
3389 brcmf_init_eq(cfg_priv); 5106 brcmf_init_eq(cfg);
3390 err = brcmf_init_priv_mem(cfg_priv); 5107 err = brcmf_init_priv_mem(cfg);
3391 if (err) 5108 if (err)
3392 return err; 5109 return err;
3393 INIT_WORK(&cfg_priv->event_work, brcmf_cfg80211_event_handler); 5110 INIT_WORK(&cfg->event_work, brcmf_cfg80211_event_handler);
3394 brcmf_init_eloop_handler(&cfg_priv->el); 5111 brcmf_init_eloop_handler(&cfg->el);
3395 mutex_init(&cfg_priv->usr_sync); 5112 mutex_init(&cfg->usr_sync);
3396 err = brcmf_init_iscan(cfg_priv); 5113 err = brcmf_init_iscan(cfg);
3397 if (err) 5114 if (err)
3398 return err; 5115 return err;
3399 brcmf_init_conf(cfg_priv->conf); 5116 brcmf_init_escan(cfg);
3400 brcmf_init_prof(cfg_priv->profile); 5117 brcmf_init_conf(cfg->conf);
3401 brcmf_link_down(cfg_priv); 5118 brcmf_init_prof(cfg->profile);
5119 brcmf_link_down(cfg);
3402 5120
3403 return err; 5121 return err;
3404} 5122}
3405 5123
3406static void wl_deinit_priv(struct brcmf_cfg80211_priv *cfg_priv) 5124static void wl_deinit_priv(struct brcmf_cfg80211_info *cfg)
3407{ 5125{
3408 cancel_work_sync(&cfg_priv->event_work); 5126 cancel_work_sync(&cfg->event_work);
3409 cfg_priv->dongle_up = false; /* dongle down */ 5127 cfg->dongle_up = false; /* dongle down */
3410 brcmf_flush_eq(cfg_priv); 5128 brcmf_flush_eq(cfg);
3411 brcmf_link_down(cfg_priv); 5129 brcmf_link_down(cfg);
3412 brcmf_term_iscan(cfg_priv); 5130 brcmf_abort_scanning(cfg);
3413 brcmf_deinit_priv_mem(cfg_priv); 5131 brcmf_deinit_priv_mem(cfg);
3414} 5132}
3415 5133
3416struct brcmf_cfg80211_dev *brcmf_cfg80211_attach(struct net_device *ndev, 5134struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct net_device *ndev,
3417 struct device *busdev, 5135 struct device *busdev,
3418 void *data) 5136 struct brcmf_pub *drvr)
3419{ 5137{
3420 struct wireless_dev *wdev; 5138 struct wireless_dev *wdev;
3421 struct brcmf_cfg80211_priv *cfg_priv; 5139 struct brcmf_cfg80211_info *cfg;
3422 struct brcmf_cfg80211_iface *ci;
3423 struct brcmf_cfg80211_dev *cfg_dev;
3424 s32 err = 0; 5140 s32 err = 0;
3425 5141
3426 if (!ndev) { 5142 if (!ndev) {
3427 WL_ERR("ndev is invalid\n"); 5143 WL_ERR("ndev is invalid\n");
3428 return NULL; 5144 return NULL;
3429 } 5145 }
3430 cfg_dev = kzalloc(sizeof(struct brcmf_cfg80211_dev), GFP_KERNEL);
3431 if (!cfg_dev)
3432 return NULL;
3433 5146
3434 wdev = brcmf_alloc_wdev(sizeof(struct brcmf_cfg80211_iface), busdev); 5147 wdev = brcmf_alloc_wdev(busdev);
3435 if (IS_ERR(wdev)) { 5148 if (IS_ERR(wdev)) {
3436 kfree(cfg_dev);
3437 return NULL; 5149 return NULL;
3438 } 5150 }
3439 5151
3440 wdev->iftype = brcmf_mode_to_nl80211_iftype(WL_MODE_BSS); 5152 wdev->iftype = brcmf_mode_to_nl80211_iftype(WL_MODE_BSS);
3441 cfg_priv = wdev_to_cfg(wdev); 5153 cfg = wdev_to_cfg(wdev);
3442 cfg_priv->wdev = wdev; 5154 cfg->wdev = wdev;
3443 cfg_priv->pub = data; 5155 cfg->pub = drvr;
3444 ci = (struct brcmf_cfg80211_iface *)&cfg_priv->ci;
3445 ci->cfg_priv = cfg_priv;
3446 ndev->ieee80211_ptr = wdev; 5156 ndev->ieee80211_ptr = wdev;
3447 SET_NETDEV_DEV(ndev, wiphy_dev(wdev->wiphy)); 5157 SET_NETDEV_DEV(ndev, wiphy_dev(wdev->wiphy));
3448 wdev->netdev = ndev; 5158 wdev->netdev = ndev;
3449 err = wl_init_priv(cfg_priv); 5159 err = wl_init_priv(cfg);
3450 if (err) { 5160 if (err) {
3451 WL_ERR("Failed to init iwm_priv (%d)\n", err); 5161 WL_ERR("Failed to init iwm_priv (%d)\n", err);
3452 goto cfg80211_attach_out; 5162 goto cfg80211_attach_out;
3453 } 5163 }
3454 brcmf_set_drvdata(cfg_dev, ci);
3455 5164
3456 return cfg_dev; 5165 return cfg;
3457 5166
3458cfg80211_attach_out: 5167cfg80211_attach_out:
3459 brcmf_free_wdev(cfg_priv); 5168 brcmf_free_wdev(cfg);
3460 kfree(cfg_dev);
3461 return NULL; 5169 return NULL;
3462} 5170}
3463 5171
3464void brcmf_cfg80211_detach(struct brcmf_cfg80211_dev *cfg_dev) 5172void brcmf_cfg80211_detach(struct brcmf_cfg80211_info *cfg)
3465{ 5173{
3466 struct brcmf_cfg80211_priv *cfg_priv; 5174 wl_deinit_priv(cfg);
3467 5175 brcmf_free_wdev(cfg);
3468 cfg_priv = brcmf_priv_get(cfg_dev);
3469
3470 wl_deinit_priv(cfg_priv);
3471 brcmf_free_wdev(cfg_priv);
3472 brcmf_set_drvdata(cfg_dev, NULL);
3473 kfree(cfg_dev);
3474} 5176}
3475 5177
3476void 5178void
@@ -3478,10 +5180,10 @@ brcmf_cfg80211_event(struct net_device *ndev,
3478 const struct brcmf_event_msg *e, void *data) 5180 const struct brcmf_event_msg *e, void *data)
3479{ 5181{
3480 u32 event_type = be32_to_cpu(e->event_type); 5182 u32 event_type = be32_to_cpu(e->event_type);
3481 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev); 5183 struct brcmf_cfg80211_info *cfg = ndev_to_cfg(ndev);
3482 5184
3483 if (!brcmf_enq_event(cfg_priv, event_type, e)) 5185 if (!brcmf_enq_event(cfg, event_type, e, data))
3484 schedule_work(&cfg_priv->event_work); 5186 schedule_work(&cfg->event_work);
3485} 5187}
3486 5188
3487static s32 brcmf_dongle_mode(struct net_device *ndev, s32 iftype) 5189static s32 brcmf_dongle_mode(struct net_device *ndev, s32 iftype)
@@ -3502,6 +5204,9 @@ static s32 brcmf_dongle_mode(struct net_device *ndev, s32 iftype)
3502 case NL80211_IFTYPE_STATION: 5204 case NL80211_IFTYPE_STATION:
3503 infra = 1; 5205 infra = 1;
3504 break; 5206 break;
5207 case NL80211_IFTYPE_AP:
5208 infra = 1;
5209 break;
3505 default: 5210 default:
3506 err = -EINVAL; 5211 err = -EINVAL;
3507 WL_ERR("invalid type (%d)\n", iftype); 5212 WL_ERR("invalid type (%d)\n", iftype);
@@ -3554,6 +5259,8 @@ static s32 brcmf_dongle_eventmsg(struct net_device *ndev)
3554 setbit(eventmask, BRCMF_E_TXFAIL); 5259 setbit(eventmask, BRCMF_E_TXFAIL);
3555 setbit(eventmask, BRCMF_E_JOIN_START); 5260 setbit(eventmask, BRCMF_E_JOIN_START);
3556 setbit(eventmask, BRCMF_E_SCAN_COMPLETE); 5261 setbit(eventmask, BRCMF_E_SCAN_COMPLETE);
5262 setbit(eventmask, BRCMF_E_ESCAN_RESULT);
5263 setbit(eventmask, BRCMF_E_PFN_NET_FOUND);
3557 5264
3558 brcmf_c_mkiovar("event_msgs", eventmask, BRCMF_EVENTING_MASK_LEN, 5265 brcmf_c_mkiovar("event_msgs", eventmask, BRCMF_EVENTING_MASK_LEN,
3559 iovbuf, sizeof(iovbuf)); 5266 iovbuf, sizeof(iovbuf));
@@ -3672,46 +5379,46 @@ dongle_scantime_out:
3672 return err; 5379 return err;
3673} 5380}
3674 5381
3675static s32 wl_update_wiphybands(struct brcmf_cfg80211_priv *cfg_priv) 5382static s32 wl_update_wiphybands(struct brcmf_cfg80211_info *cfg)
3676{ 5383{
3677 struct wiphy *wiphy; 5384 struct wiphy *wiphy;
3678 s32 phy_list; 5385 s32 phy_list;
3679 s8 phy; 5386 s8 phy;
3680 s32 err = 0; 5387 s32 err = 0;
3681 5388
3682 err = brcmf_exec_dcmd(cfg_to_ndev(cfg_priv), BRCM_GET_PHYLIST, 5389 err = brcmf_exec_dcmd(cfg_to_ndev(cfg), BRCM_GET_PHYLIST,
3683 &phy_list, sizeof(phy_list)); 5390 &phy_list, sizeof(phy_list));
3684 if (err) { 5391 if (err) {
3685 WL_ERR("error (%d)\n", err); 5392 WL_ERR("error (%d)\n", err);
3686 return err; 5393 return err;
3687 } 5394 }
3688 5395
3689 phy = ((char *)&phy_list)[1]; 5396 phy = ((char *)&phy_list)[0];
3690 WL_INFO("%c phy\n", phy); 5397 WL_INFO("%c phy\n", phy);
3691 if (phy == 'n' || phy == 'a') { 5398 if (phy == 'n' || phy == 'a') {
3692 wiphy = cfg_to_wiphy(cfg_priv); 5399 wiphy = cfg_to_wiphy(cfg);
3693 wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_n; 5400 wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_n;
3694 } 5401 }
3695 5402
3696 return err; 5403 return err;
3697} 5404}
3698 5405
3699static s32 brcmf_dongle_probecap(struct brcmf_cfg80211_priv *cfg_priv) 5406static s32 brcmf_dongle_probecap(struct brcmf_cfg80211_info *cfg)
3700{ 5407{
3701 return wl_update_wiphybands(cfg_priv); 5408 return wl_update_wiphybands(cfg);
3702} 5409}
3703 5410
3704static s32 brcmf_config_dongle(struct brcmf_cfg80211_priv *cfg_priv) 5411static s32 brcmf_config_dongle(struct brcmf_cfg80211_info *cfg)
3705{ 5412{
3706 struct net_device *ndev; 5413 struct net_device *ndev;
3707 struct wireless_dev *wdev; 5414 struct wireless_dev *wdev;
3708 s32 power_mode; 5415 s32 power_mode;
3709 s32 err = 0; 5416 s32 err = 0;
3710 5417
3711 if (cfg_priv->dongle_up) 5418 if (cfg->dongle_up)
3712 return err; 5419 return err;
3713 5420
3714 ndev = cfg_to_ndev(cfg_priv); 5421 ndev = cfg_to_ndev(cfg);
3715 wdev = ndev->ieee80211_ptr; 5422 wdev = ndev->ieee80211_ptr;
3716 5423
3717 brcmf_dongle_scantime(ndev, WL_SCAN_CHANNEL_TIME, 5424 brcmf_dongle_scantime(ndev, WL_SCAN_CHANNEL_TIME,
@@ -3721,21 +5428,21 @@ static s32 brcmf_config_dongle(struct brcmf_cfg80211_priv *cfg_priv)
3721 if (err) 5428 if (err)
3722 goto default_conf_out; 5429 goto default_conf_out;
3723 5430
3724 power_mode = cfg_priv->pwr_save ? PM_FAST : PM_OFF; 5431 power_mode = cfg->pwr_save ? PM_FAST : PM_OFF;
3725 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_PM, &power_mode); 5432 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_PM, &power_mode);
3726 if (err) 5433 if (err)
3727 goto default_conf_out; 5434 goto default_conf_out;
3728 WL_INFO("power save set to %s\n", 5435 WL_INFO("power save set to %s\n",
3729 (power_mode ? "enabled" : "disabled")); 5436 (power_mode ? "enabled" : "disabled"));
3730 5437
3731 err = brcmf_dongle_roam(ndev, (cfg_priv->roam_on ? 0 : 1), 5438 err = brcmf_dongle_roam(ndev, (cfg->roam_on ? 0 : 1),
3732 WL_BEACON_TIMEOUT); 5439 WL_BEACON_TIMEOUT);
3733 if (err) 5440 if (err)
3734 goto default_conf_out; 5441 goto default_conf_out;
3735 err = brcmf_dongle_mode(ndev, wdev->iftype); 5442 err = brcmf_dongle_mode(ndev, wdev->iftype);
3736 if (err && err != -EINPROGRESS) 5443 if (err && err != -EINPROGRESS)
3737 goto default_conf_out; 5444 goto default_conf_out;
3738 err = brcmf_dongle_probecap(cfg_priv); 5445 err = brcmf_dongle_probecap(cfg);
3739 if (err) 5446 if (err)
3740 goto default_conf_out; 5447 goto default_conf_out;
3741 5448
@@ -3743,31 +5450,31 @@ static s32 brcmf_config_dongle(struct brcmf_cfg80211_priv *cfg_priv)
3743 5450
3744default_conf_out: 5451default_conf_out:
3745 5452
3746 cfg_priv->dongle_up = true; 5453 cfg->dongle_up = true;
3747 5454
3748 return err; 5455 return err;
3749 5456
3750} 5457}
3751 5458
3752static int brcmf_debugfs_add_netdev_params(struct brcmf_cfg80211_priv *cfg_priv) 5459static int brcmf_debugfs_add_netdev_params(struct brcmf_cfg80211_info *cfg)
3753{ 5460{
3754 char buf[10+IFNAMSIZ]; 5461 char buf[10+IFNAMSIZ];
3755 struct dentry *fd; 5462 struct dentry *fd;
3756 s32 err = 0; 5463 s32 err = 0;
3757 5464
3758 sprintf(buf, "netdev:%s", cfg_to_ndev(cfg_priv)->name); 5465 sprintf(buf, "netdev:%s", cfg_to_ndev(cfg)->name);
3759 cfg_priv->debugfsdir = debugfs_create_dir(buf, 5466 cfg->debugfsdir = debugfs_create_dir(buf,
3760 cfg_to_wiphy(cfg_priv)->debugfsdir); 5467 cfg_to_wiphy(cfg)->debugfsdir);
3761 5468
3762 fd = debugfs_create_u16("beacon_int", S_IRUGO, cfg_priv->debugfsdir, 5469 fd = debugfs_create_u16("beacon_int", S_IRUGO, cfg->debugfsdir,
3763 (u16 *)&cfg_priv->profile->beacon_interval); 5470 (u16 *)&cfg->profile->beacon_interval);
3764 if (!fd) { 5471 if (!fd) {
3765 err = -ENOMEM; 5472 err = -ENOMEM;
3766 goto err_out; 5473 goto err_out;
3767 } 5474 }
3768 5475
3769 fd = debugfs_create_u8("dtim_period", S_IRUGO, cfg_priv->debugfsdir, 5476 fd = debugfs_create_u8("dtim_period", S_IRUGO, cfg->debugfsdir,
3770 (u8 *)&cfg_priv->profile->dtim_period); 5477 (u8 *)&cfg->profile->dtim_period);
3771 if (!fd) { 5478 if (!fd) {
3772 err = -ENOMEM; 5479 err = -ENOMEM;
3773 goto err_out; 5480 goto err_out;
@@ -3777,40 +5484,40 @@ err_out:
3777 return err; 5484 return err;
3778} 5485}
3779 5486
3780static void brcmf_debugfs_remove_netdev(struct brcmf_cfg80211_priv *cfg_priv) 5487static void brcmf_debugfs_remove_netdev(struct brcmf_cfg80211_info *cfg)
3781{ 5488{
3782 debugfs_remove_recursive(cfg_priv->debugfsdir); 5489 debugfs_remove_recursive(cfg->debugfsdir);
3783 cfg_priv->debugfsdir = NULL; 5490 cfg->debugfsdir = NULL;
3784} 5491}
3785 5492
3786static s32 __brcmf_cfg80211_up(struct brcmf_cfg80211_priv *cfg_priv) 5493static s32 __brcmf_cfg80211_up(struct brcmf_cfg80211_info *cfg)
3787{ 5494{
3788 s32 err = 0; 5495 s32 err = 0;
3789 5496
3790 set_bit(WL_STATUS_READY, &cfg_priv->status); 5497 set_bit(WL_STATUS_READY, &cfg->status);
3791 5498
3792 brcmf_debugfs_add_netdev_params(cfg_priv); 5499 brcmf_debugfs_add_netdev_params(cfg);
3793 5500
3794 err = brcmf_config_dongle(cfg_priv); 5501 err = brcmf_config_dongle(cfg);
3795 if (err) 5502 if (err)
3796 return err; 5503 return err;
3797 5504
3798 brcmf_invoke_iscan(cfg_priv); 5505 brcmf_invoke_iscan(cfg);
3799 5506
3800 return err; 5507 return err;
3801} 5508}
3802 5509
3803static s32 __brcmf_cfg80211_down(struct brcmf_cfg80211_priv *cfg_priv) 5510static s32 __brcmf_cfg80211_down(struct brcmf_cfg80211_info *cfg)
3804{ 5511{
3805 /* 5512 /*
3806 * While going down, if associated with AP disassociate 5513 * While going down, if associated with AP disassociate
3807 * from AP to save power 5514 * from AP to save power
3808 */ 5515 */
3809 if ((test_bit(WL_STATUS_CONNECTED, &cfg_priv->status) || 5516 if ((test_bit(WL_STATUS_CONNECTED, &cfg->status) ||
3810 test_bit(WL_STATUS_CONNECTING, &cfg_priv->status)) && 5517 test_bit(WL_STATUS_CONNECTING, &cfg->status)) &&
3811 test_bit(WL_STATUS_READY, &cfg_priv->status)) { 5518 test_bit(WL_STATUS_READY, &cfg->status)) {
3812 WL_INFO("Disassociating from AP"); 5519 WL_INFO("Disassociating from AP");
3813 brcmf_link_down(cfg_priv); 5520 brcmf_link_down(cfg);
3814 5521
3815 /* Make sure WPA_Supplicant receives all the event 5522 /* Make sure WPA_Supplicant receives all the event
3816 generated due to DISASSOC call to the fw to keep 5523 generated due to DISASSOC call to the fw to keep
@@ -3819,63 +5526,33 @@ static s32 __brcmf_cfg80211_down(struct brcmf_cfg80211_priv *cfg_priv)
3819 brcmf_delay(500); 5526 brcmf_delay(500);
3820 } 5527 }
3821 5528
3822 set_bit(WL_STATUS_SCAN_ABORTING, &cfg_priv->status); 5529 brcmf_abort_scanning(cfg);
3823 brcmf_term_iscan(cfg_priv); 5530 clear_bit(WL_STATUS_READY, &cfg->status);
3824 if (cfg_priv->scan_request) {
3825 cfg80211_scan_done(cfg_priv->scan_request, true);
3826 /* May need to perform this to cover rmmod */
3827 /* wl_set_mpc(cfg_to_ndev(wl), 1); */
3828 cfg_priv->scan_request = NULL;
3829 }
3830 clear_bit(WL_STATUS_READY, &cfg_priv->status);
3831 clear_bit(WL_STATUS_SCANNING, &cfg_priv->status);
3832 clear_bit(WL_STATUS_SCAN_ABORTING, &cfg_priv->status);
3833 5531
3834 brcmf_debugfs_remove_netdev(cfg_priv); 5532 brcmf_debugfs_remove_netdev(cfg);
3835 5533
3836 return 0; 5534 return 0;
3837} 5535}
3838 5536
3839s32 brcmf_cfg80211_up(struct brcmf_cfg80211_dev *cfg_dev) 5537s32 brcmf_cfg80211_up(struct brcmf_cfg80211_info *cfg)
3840{ 5538{
3841 struct brcmf_cfg80211_priv *cfg_priv;
3842 s32 err = 0; 5539 s32 err = 0;
3843 5540
3844 cfg_priv = brcmf_priv_get(cfg_dev); 5541 mutex_lock(&cfg->usr_sync);
3845 mutex_lock(&cfg_priv->usr_sync); 5542 err = __brcmf_cfg80211_up(cfg);
3846 err = __brcmf_cfg80211_up(cfg_priv); 5543 mutex_unlock(&cfg->usr_sync);
3847 mutex_unlock(&cfg_priv->usr_sync);
3848 5544
3849 return err; 5545 return err;
3850} 5546}
3851 5547
3852s32 brcmf_cfg80211_down(struct brcmf_cfg80211_dev *cfg_dev) 5548s32 brcmf_cfg80211_down(struct brcmf_cfg80211_info *cfg)
3853{ 5549{
3854 struct brcmf_cfg80211_priv *cfg_priv;
3855 s32 err = 0; 5550 s32 err = 0;
3856 5551
3857 cfg_priv = brcmf_priv_get(cfg_dev); 5552 mutex_lock(&cfg->usr_sync);
3858 mutex_lock(&cfg_priv->usr_sync); 5553 err = __brcmf_cfg80211_down(cfg);
3859 err = __brcmf_cfg80211_down(cfg_priv); 5554 mutex_unlock(&cfg->usr_sync);
3860 mutex_unlock(&cfg_priv->usr_sync);
3861 5555
3862 return err; 5556 return err;
3863} 5557}
3864 5558
3865static __used s32 brcmf_add_ie(struct brcmf_cfg80211_priv *cfg_priv,
3866 u8 t, u8 l, u8 *v)
3867{
3868 struct brcmf_cfg80211_ie *ie = &cfg_priv->ie;
3869 s32 err = 0;
3870
3871 if (ie->offset + l + 2 > WL_TLV_INFO_MAX) {
3872 WL_ERR("ei crosses buffer boundary\n");
3873 return -ENOSPC;
3874 }
3875 ie->buf[ie->offset] = t;
3876 ie->buf[ie->offset + 1] = l;
3877 memcpy(&ie->buf[ie->offset + 2], v, l);
3878 ie->offset += l + 2;
3879
3880 return err;
3881}