brcmfmac: separate connection status from scanning status

The connection status is to be kept per virtual interface and
the scanning status is for device. So they need to be separated
for multiple interface support.

Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
Signed-off-by: Arend van Spriel <arend@broadcom.com>
Signed-off-by: Franky Lin <frankyl@broadcom.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
This commit is contained in:
Arend van Spriel 2012-10-22 13:55:33 -07:00 committed by John W. Linville
parent 0abb5f21b7
commit c117903322
2 changed files with 156 additions and 120 deletions

View File

@ -100,11 +100,9 @@ static u32 brcmf_dbg_level = WL_DBG_ERR;
static bool check_sys_up(struct brcmf_cfg80211_vif *vif) static bool check_sys_up(struct brcmf_cfg80211_vif *vif)
{ {
struct brcmf_cfg80211_info *cfg = wdev_priv(&vif->wdev); if (!test_bit(BRCMF_VIF_STATUS_READY, &vif->sme_state)) {
WL_INFO("device is not ready : status (%lu)\n",
if (!test_bit(WL_STATUS_READY, &cfg->status)) { vif->sme_state);
WL_INFO("device is not ready : status (%d)\n",
(int)cfg->status);
return false; return false;
} }
return true; return true;
@ -457,6 +455,7 @@ brcmf_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev,
enum nl80211_iftype type, u32 *flags, enum nl80211_iftype type, u32 *flags,
struct vif_params *params) struct vif_params *params)
{ {
struct brcmf_if *ifp = netdev_priv(ndev);
struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
s32 infra = 0; s32 infra = 0;
s32 ap = 0; s32 ap = 0;
@ -488,7 +487,7 @@ brcmf_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev,
} }
if (ap) { if (ap) {
set_bit(WL_STATUS_AP_CREATING, &cfg->status); set_bit(BRCMF_VIF_STATUS_AP_CREATING, &ifp->vif->sme_state);
if (!cfg->ap_info) if (!cfg->ap_info)
cfg->ap_info = kzalloc(sizeof(*cfg->ap_info), cfg->ap_info = kzalloc(sizeof(*cfg->ap_info),
GFP_KERNEL); GFP_KERNEL);
@ -519,11 +518,11 @@ brcmf_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev,
static void brcmf_set_mpc(struct net_device *ndev, int mpc) static void brcmf_set_mpc(struct net_device *ndev, int mpc)
{ {
struct brcmf_if *ifp = netdev_priv(ndev);
s32 err = 0; s32 err = 0;
struct brcmf_cfg80211_info *cfg = ndev_to_cfg(ndev);
if (test_bit(WL_STATUS_READY, &cfg->status)) { if (check_sys_up(ifp->vif)) {
err = brcmf_fil_iovar_int_set(netdev_priv(ndev), "mpc", mpc); err = brcmf_fil_iovar_int_set(ifp, "mpc", mpc);
if (err) { if (err) {
WL_ERR("fail to set mpc\n"); WL_ERR("fail to set mpc\n");
return; return;
@ -622,6 +621,7 @@ brcmf_cfg80211_iscan(struct wiphy *wiphy, struct net_device *ndev,
struct cfg80211_scan_request *request, struct cfg80211_scan_request *request,
struct cfg80211_ssid *this_ssid) struct cfg80211_ssid *this_ssid)
{ {
struct brcmf_if *ifp = netdev_priv(ndev);
struct brcmf_cfg80211_info *cfg = ndev_to_cfg(ndev); struct brcmf_cfg80211_info *cfg = ndev_to_cfg(ndev);
struct cfg80211_ssid *ssids; struct cfg80211_ssid *ssids;
struct brcmf_cfg80211_scan_req *sr = cfg->scan_req_int; struct brcmf_cfg80211_scan_req *sr = cfg->scan_req_int;
@ -631,18 +631,17 @@ brcmf_cfg80211_iscan(struct wiphy *wiphy, struct net_device *ndev,
s32 err = 0; s32 err = 0;
u32 SSID_len; u32 SSID_len;
if (test_bit(WL_STATUS_SCANNING, &cfg->status)) { if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
WL_ERR("Scanning already : status (%lu)\n", cfg->status); WL_ERR("Scanning already: status (%lu)\n", cfg->scan_status);
return -EAGAIN; return -EAGAIN;
} }
if (test_bit(WL_STATUS_SCAN_ABORTING, &cfg->status)) { if (test_bit(BRCMF_SCAN_STATUS_ABORT, &cfg->scan_status)) {
WL_ERR("Scanning being aborted : status (%lu)\n", WL_ERR("Scanning being aborted: status (%lu)\n",
cfg->status); cfg->scan_status);
return -EAGAIN; return -EAGAIN;
} }
if (test_bit(WL_STATUS_CONNECTING, &cfg->status)) { if (test_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state)) {
WL_ERR("Connecting : status (%lu)\n", WL_ERR("Connecting: status (%lu)\n", ifp->vif->sme_state);
cfg->status);
return -EAGAIN; return -EAGAIN;
} }
@ -660,7 +659,7 @@ brcmf_cfg80211_iscan(struct wiphy *wiphy, struct net_device *ndev,
} }
cfg->scan_request = request; cfg->scan_request = request;
set_bit(WL_STATUS_SCANNING, &cfg->status); set_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
if (iscan_req) { if (iscan_req) {
err = brcmf_do_iscan(cfg); err = brcmf_do_iscan(cfg);
if (!err) if (!err)
@ -682,15 +681,14 @@ brcmf_cfg80211_iscan(struct wiphy *wiphy, struct net_device *ndev,
} }
passive_scan = cfg->active_scan ? 0 : 1; passive_scan = cfg->active_scan ? 0 : 1;
err = brcmf_fil_cmd_int_set(netdev_priv(ndev), err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PASSIVE_SCAN,
BRCMF_C_SET_PASSIVE_SCAN,
passive_scan); passive_scan);
if (err) { if (err) {
WL_ERR("WLC_SET_PASSIVE_SCAN error (%d)\n", err); WL_ERR("WLC_SET_PASSIVE_SCAN error (%d)\n", err);
goto scan_out; goto scan_out;
} }
brcmf_set_mpc(ndev, 0); brcmf_set_mpc(ndev, 0);
err = brcmf_fil_cmd_data_set(netdev_priv(ndev), BRCMF_C_SCAN, err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SCAN,
&sr->ssid_le, sizeof(sr->ssid_le)); &sr->ssid_le, sizeof(sr->ssid_le));
if (err) { if (err) {
if (err == -EBUSY) if (err == -EBUSY)
@ -707,7 +705,7 @@ brcmf_cfg80211_iscan(struct wiphy *wiphy, struct net_device *ndev,
return 0; return 0;
scan_out: scan_out:
clear_bit(WL_STATUS_SCANNING, &cfg->status); clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
cfg->scan_request = NULL; cfg->scan_request = NULL;
return err; return err;
} }
@ -844,7 +842,7 @@ brcmf_notify_escan_complete(struct brcmf_cfg80211_info *cfg,
cfg80211_scan_done(scan_request, aborted); cfg80211_scan_done(scan_request, aborted);
brcmf_set_mpc(ndev, 1); brcmf_set_mpc(ndev, 1);
} }
if (!test_and_clear_bit(WL_STATUS_SCANNING, &cfg->status)) { if (!test_and_clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
WL_ERR("Scan complete while device not scanning\n"); WL_ERR("Scan complete while device not scanning\n");
return -EPERM; return -EPERM;
} }
@ -932,6 +930,7 @@ brcmf_cfg80211_escan(struct wiphy *wiphy, struct net_device *ndev,
struct cfg80211_scan_request *request, struct cfg80211_scan_request *request,
struct cfg80211_ssid *this_ssid) struct cfg80211_ssid *this_ssid)
{ {
struct brcmf_if *ifp = netdev_priv(ndev);
struct brcmf_cfg80211_info *cfg = ndev_to_cfg(ndev); struct brcmf_cfg80211_info *cfg = ndev_to_cfg(ndev);
struct cfg80211_ssid *ssids; struct cfg80211_ssid *ssids;
struct brcmf_cfg80211_scan_req *sr = cfg->scan_req_int; struct brcmf_cfg80211_scan_req *sr = cfg->scan_req_int;
@ -943,18 +942,17 @@ brcmf_cfg80211_escan(struct wiphy *wiphy, struct net_device *ndev,
WL_SCAN("START ESCAN\n"); WL_SCAN("START ESCAN\n");
if (test_bit(WL_STATUS_SCANNING, &cfg->status)) { if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
WL_ERR("Scanning already : status (%lu)\n", cfg->status); WL_ERR("Scanning already: status (%lu)\n", cfg->scan_status);
return -EAGAIN; return -EAGAIN;
} }
if (test_bit(WL_STATUS_SCAN_ABORTING, &cfg->status)) { if (test_bit(BRCMF_SCAN_STATUS_ABORT, &cfg->scan_status)) {
WL_ERR("Scanning being aborted : status (%lu)\n", WL_ERR("Scanning being aborted: status (%lu)\n",
cfg->status); cfg->scan_status);
return -EAGAIN; return -EAGAIN;
} }
if (test_bit(WL_STATUS_CONNECTING, &cfg->status)) { if (test_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state)) {
WL_ERR("Connecting : status (%lu)\n", WL_ERR("Connecting: status (%lu)\n", ifp->vif->sme_state);
cfg->status);
return -EAGAIN; return -EAGAIN;
} }
@ -974,7 +972,7 @@ brcmf_cfg80211_escan(struct wiphy *wiphy, struct net_device *ndev,
} }
cfg->scan_request = request; cfg->scan_request = request;
set_bit(WL_STATUS_SCANNING, &cfg->status); set_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
if (escan_req) { if (escan_req) {
err = brcmf_do_escan(cfg, wiphy, ndev, request); err = brcmf_do_escan(cfg, wiphy, ndev, request);
if (!err) if (!err)
@ -996,15 +994,14 @@ brcmf_cfg80211_escan(struct wiphy *wiphy, struct net_device *ndev,
WL_SCAN("Broadcast scan\n"); WL_SCAN("Broadcast scan\n");
passive_scan = cfg->active_scan ? 0 : 1; passive_scan = cfg->active_scan ? 0 : 1;
err = brcmf_fil_cmd_int_set(netdev_priv(ndev), err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PASSIVE_SCAN,
BRCMF_C_SET_PASSIVE_SCAN,
passive_scan); passive_scan);
if (err) { if (err) {
WL_ERR("WLC_SET_PASSIVE_SCAN error (%d)\n", err); WL_ERR("WLC_SET_PASSIVE_SCAN error (%d)\n", err);
goto scan_out; goto scan_out;
} }
brcmf_set_mpc(ndev, 0); brcmf_set_mpc(ndev, 0);
err = brcmf_fil_cmd_data_set(netdev_priv(ndev), BRCMF_C_SCAN, err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SCAN,
&sr->ssid_le, sizeof(sr->ssid_le)); &sr->ssid_le, sizeof(sr->ssid_le));
if (err) { if (err) {
if (err == -EBUSY) if (err == -EBUSY)
@ -1021,7 +1018,7 @@ brcmf_cfg80211_escan(struct wiphy *wiphy, struct net_device *ndev,
return 0; return 0;
scan_out: scan_out:
clear_bit(WL_STATUS_SCANNING, &cfg->status); clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
if (timer_pending(&cfg->escan_timeout)) if (timer_pending(&cfg->escan_timeout))
del_timer_sync(&cfg->escan_timeout); del_timer_sync(&cfg->escan_timeout);
cfg->scan_request = NULL; cfg->scan_request = NULL;
@ -1210,7 +1207,7 @@ brcmf_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *ndev,
return -EOPNOTSUPP; return -EOPNOTSUPP;
} }
set_bit(WL_STATUS_CONNECTING, &cfg->status); set_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state);
if (params->bssid) if (params->bssid)
WL_CONN("BSSID: %pM\n", params->bssid); WL_CONN("BSSID: %pM\n", params->bssid);
@ -1251,7 +1248,7 @@ brcmf_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *ndev,
if (params->privacy) if (params->privacy)
wsec |= WEP_ENABLED; wsec |= WEP_ENABLED;
err = brcmf_fil_iovar_int_set(netdev_priv(ndev), "wsec", wsec); err = brcmf_fil_iovar_int_set(ifp, "wsec", wsec);
if (err) { if (err) {
WL_ERR("wsec failed (%d)\n", err); WL_ERR("wsec failed (%d)\n", err);
goto done; goto done;
@ -1263,7 +1260,7 @@ brcmf_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *ndev,
else else
bcnprd = 100; bcnprd = 100;
err = brcmf_fil_cmd_int_set(netdev_priv(ndev), BRCM_SET_BCNPRD, bcnprd); err = brcmf_fil_cmd_int_set(ifp, BRCM_SET_BCNPRD, bcnprd);
if (err) { if (err) {
WL_ERR("WLC_SET_BCNPRD failed (%d)\n", err); WL_ERR("WLC_SET_BCNPRD failed (%d)\n", err);
goto done; goto done;
@ -1305,7 +1302,7 @@ brcmf_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *ndev,
/* set channel for starter */ /* set channel for starter */
target_channel = cfg->channel; target_channel = cfg->channel;
err = brcmf_fil_cmd_int_set(netdev_priv(ndev), BRCM_SET_CHANNEL, err = brcmf_fil_cmd_int_set(ifp, BRCM_SET_CHANNEL,
target_channel); target_channel);
if (err) { if (err) {
WL_ERR("WLC_SET_CHANNEL failed (%d)\n", err); WL_ERR("WLC_SET_CHANNEL failed (%d)\n", err);
@ -1317,7 +1314,7 @@ brcmf_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *ndev,
cfg->ibss_starter = false; cfg->ibss_starter = false;
err = brcmf_fil_cmd_data_set(netdev_priv(ndev), BRCMF_C_SET_SSID, err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID,
&join_params, join_params_size); &join_params, join_params_size);
if (err) { if (err) {
WL_ERR("WLC_SET_SSID failed (%d)\n", err); WL_ERR("WLC_SET_SSID failed (%d)\n", err);
@ -1326,7 +1323,7 @@ brcmf_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *ndev,
done: done:
if (err) if (err)
clear_bit(WL_STATUS_CONNECTING, &cfg->status); clear_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state);
WL_TRACE("Exit\n"); WL_TRACE("Exit\n");
return err; return err;
} }
@ -1625,7 +1622,7 @@ brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev,
return -EOPNOTSUPP; return -EOPNOTSUPP;
} }
set_bit(WL_STATUS_CONNECTING, &cfg->status); set_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state);
if (chan) { if (chan) {
cfg->channel = cfg->channel =
@ -1684,14 +1681,14 @@ brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev,
brcmf_ch_to_chanspec(cfg->channel, brcmf_ch_to_chanspec(cfg->channel,
&join_params, &join_params_size); &join_params, &join_params_size);
err = brcmf_fil_cmd_data_set(netdev_priv(ndev), BRCMF_C_SET_SSID, err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID,
&join_params, join_params_size); &join_params, join_params_size);
if (err) if (err)
WL_ERR("WLC_SET_SSID failed (%d)\n", err); WL_ERR("WLC_SET_SSID failed (%d)\n", err);
done: done:
if (err) if (err)
clear_bit(WL_STATUS_CONNECTING, &cfg->status); clear_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state);
WL_TRACE("Exit\n"); WL_TRACE("Exit\n");
return err; return err;
} }
@ -1710,11 +1707,11 @@ brcmf_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *ndev,
if (!check_sys_up(ifp->vif)) if (!check_sys_up(ifp->vif))
return -EIO; return -EIO;
clear_bit(WL_STATUS_CONNECTED, &cfg->status); clear_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state);
memcpy(&scbval.ea, &profile->bssid, ETH_ALEN); memcpy(&scbval.ea, &profile->bssid, ETH_ALEN);
scbval.val = cpu_to_le32(reason_code); scbval.val = cpu_to_le32(reason_code);
err = brcmf_fil_cmd_data_set(netdev_priv(ndev), BRCMF_C_DISASSOC, err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_DISASSOC,
&scbval, sizeof(scbval)); &scbval, sizeof(scbval));
if (err) if (err)
WL_ERR("error (%d)\n", err); WL_ERR("error (%d)\n", err);
@ -2162,10 +2159,11 @@ brcmf_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev,
WL_CONN("Rate %d Mbps\n", rate / 2); WL_CONN("Rate %d Mbps\n", rate / 2);
} }
if (test_bit(WL_STATUS_CONNECTED, &cfg->status)) { if (test_bit(BRCMF_VIF_STATUS_CONNECTED,
&ifp->vif->sme_state)) {
memset(&scb_val, 0, sizeof(scb_val)); memset(&scb_val, 0, sizeof(scb_val));
err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_RSSI, &scb_val, err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_RSSI,
sizeof(scb_val)); &scb_val, sizeof(scb_val));
if (err) { if (err) {
WL_ERR("Could not get rssi (%d)\n", err); WL_ERR("Could not get rssi (%d)\n", err);
goto done; goto done;
@ -2190,6 +2188,7 @@ brcmf_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *ndev,
s32 pm; s32 pm;
s32 err = 0; s32 err = 0;
struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
struct brcmf_if *ifp = netdev_priv(ndev);
WL_TRACE("Enter\n"); WL_TRACE("Enter\n");
@ -2201,7 +2200,7 @@ brcmf_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *ndev,
* FW later while initializing the dongle * FW later while initializing the dongle
*/ */
cfg->pwr_save = enabled; cfg->pwr_save = enabled;
if (!test_bit(WL_STATUS_READY, &cfg->status)) { if (!check_sys_up(ifp->vif)) {
WL_INFO("Device is not ready, storing the value in cfg_info struct\n"); WL_INFO("Device is not ready, storing the value in cfg_info struct\n");
goto done; goto done;
@ -2210,7 +2209,7 @@ brcmf_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *ndev,
pm = enabled ? PM_FAST : PM_OFF; pm = enabled ? PM_FAST : PM_OFF;
WL_INFO("power save %s\n", (pm ? "enabled" : "disabled")); WL_INFO("power save %s\n", (pm ? "enabled" : "disabled"));
err = brcmf_fil_cmd_int_set(netdev_priv(ndev), BRCMF_C_SET_PM, pm); err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PM, pm);
if (err) { if (err) {
if (err == -ENODEV) if (err == -ENODEV)
WL_ERR("net_device is not ready yet\n"); WL_ERR("net_device is not ready yet\n");
@ -2592,7 +2591,7 @@ static void brcmf_abort_scanning(struct brcmf_cfg80211_info *cfg)
struct escan_info *escan = &cfg->escan_info; struct escan_info *escan = &cfg->escan_info;
struct brcmf_ssid ssid; struct brcmf_ssid ssid;
set_bit(WL_STATUS_SCAN_ABORTING, &cfg->status); set_bit(BRCMF_SCAN_STATUS_ABORT, &cfg->scan_status);
if (cfg->iscan_on) { if (cfg->iscan_on) {
iscan->state = WL_ISCAN_STATE_IDLE; iscan->state = WL_ISCAN_STATE_IDLE;
@ -2618,8 +2617,8 @@ static void brcmf_abort_scanning(struct brcmf_cfg80211_info *cfg)
escan->escan_state = WL_ESCAN_STATE_IDLE; escan->escan_state = WL_ESCAN_STATE_IDLE;
brcmf_notify_escan_complete(cfg, escan->ndev, true, true); brcmf_notify_escan_complete(cfg, escan->ndev, true, true);
} }
clear_bit(WL_STATUS_SCANNING, &cfg->status); clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
clear_bit(WL_STATUS_SCAN_ABORTING, &cfg->status); clear_bit(BRCMF_SCAN_STATUS_ABORT, &cfg->scan_status);
} }
static void brcmf_notify_iscan_complete(struct brcmf_cfg80211_iscan_ctrl *iscan, static void brcmf_notify_iscan_complete(struct brcmf_cfg80211_iscan_ctrl *iscan,
@ -2628,7 +2627,7 @@ static void brcmf_notify_iscan_complete(struct brcmf_cfg80211_iscan_ctrl *iscan,
struct brcmf_cfg80211_info *cfg = iscan_to_cfg(iscan); struct brcmf_cfg80211_info *cfg = iscan_to_cfg(iscan);
struct net_device *ndev = cfg_to_ndev(cfg); struct net_device *ndev = cfg_to_ndev(cfg);
if (!test_and_clear_bit(WL_STATUS_SCANNING, &cfg->status)) { if (!test_and_clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
WL_ERR("Scan complete while device not scanning\n"); WL_ERR("Scan complete while device not scanning\n");
return; return;
} }
@ -2886,10 +2885,10 @@ brcmf_cfg80211_escan_handler(struct brcmf_cfg80211_info *cfg,
status = be32_to_cpu(e->status); status = be32_to_cpu(e->status);
if (!ndev || !cfg->escan_on || if (!ndev || !cfg->escan_on ||
!test_bit(WL_STATUS_SCANNING, &cfg->status)) { !test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
WL_ERR("scan not ready ndev %p wl->escan_on %d drv_status %x\n", WL_ERR("scan not ready ndev %p wl->escan_on %d drv_status %x\n",
ndev, cfg->escan_on, ndev, cfg->escan_on,
!test_bit(WL_STATUS_SCANNING, &cfg->status)); !test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status));
return -EPERM; return -EPERM;
} }
@ -2993,15 +2992,16 @@ static __always_inline void brcmf_delay(u32 ms)
static s32 brcmf_cfg80211_resume(struct wiphy *wiphy) static s32 brcmf_cfg80211_resume(struct wiphy *wiphy)
{ {
struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
/* /*
* Check for WL_STATUS_READY before any function call which * Check for BRCMF_VIF_STATUS_READY before any function call which
* could result is bus access. Don't block the resume for * could result is bus access. Don't block the resume for
* any driver error conditions * any driver error conditions
*/ */
WL_TRACE("Enter\n"); WL_TRACE("Enter\n");
if (test_bit(WL_STATUS_READY, &cfg->status)) if (check_sys_up(ifp->vif))
brcmf_invoke_iscan(wiphy_to_cfg(wiphy)); brcmf_invoke_iscan(wiphy_to_cfg(wiphy));
WL_TRACE("Exit\n"); WL_TRACE("Exit\n");
@ -3013,11 +3013,12 @@ static s32 brcmf_cfg80211_suspend(struct wiphy *wiphy,
{ {
struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
struct net_device *ndev = cfg_to_ndev(cfg); struct net_device *ndev = cfg_to_ndev(cfg);
struct brcmf_if *ifp = netdev_priv(ndev);
WL_TRACE("Enter\n"); WL_TRACE("Enter\n");
/* /*
* Check for WL_STATUS_READY before any function call which * Check for BRCMF_VIF_STATUS_READY before any function call which
* could result is bus access. Don't block the suspend for * could result is bus access. Don't block the suspend for
* any driver error conditions * any driver error conditions
*/ */
@ -3026,9 +3027,9 @@ static s32 brcmf_cfg80211_suspend(struct wiphy *wiphy,
* While going to suspend if associated with AP disassociate * While going to suspend if associated with AP disassociate
* from AP to save power while system is in suspended state * from AP to save power while system is in suspended state
*/ */
if ((test_bit(WL_STATUS_CONNECTED, &cfg->status) || if ((test_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state) ||
test_bit(WL_STATUS_CONNECTING, &cfg->status)) && test_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state)) &&
test_bit(WL_STATUS_READY, &cfg->status)) { check_sys_up(ifp->vif)) {
WL_INFO("Disassociating from AP" WL_INFO("Disassociating from AP"
" while entering suspend state\n"); " while entering suspend state\n");
brcmf_link_down(cfg); brcmf_link_down(cfg);
@ -3041,13 +3042,13 @@ static s32 brcmf_cfg80211_suspend(struct wiphy *wiphy,
brcmf_delay(500); brcmf_delay(500);
} }
if (test_bit(WL_STATUS_READY, &cfg->status)) if (test_bit(BRCMF_VIF_STATUS_READY, &ifp->vif->sme_state))
brcmf_abort_scanning(cfg); brcmf_abort_scanning(cfg);
else else
clear_bit(WL_STATUS_SCANNING, &cfg->status); clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
/* Turn off watchdog timer */ /* Turn off watchdog timer */
if (test_bit(WL_STATUS_READY, &cfg->status)) if (test_bit(BRCMF_VIF_STATUS_READY, &ifp->vif->sme_state))
brcmf_set_mpc(ndev, 1); brcmf_set_mpc(ndev, 1);
WL_TRACE("Exit\n"); WL_TRACE("Exit\n");
@ -3279,15 +3280,15 @@ brcmf_notify_sched_scan_results(struct brcmf_cfg80211_info *cfg,
if (request->n_ssids) if (request->n_ssids)
request->ssids = &ssid[0]; request->ssids = &ssid[0];
if (test_bit(WL_STATUS_SCANNING, &cfg->status)) { if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
/* Abort any on-going scan */ /* Abort any on-going scan */
brcmf_abort_scanning(cfg); brcmf_abort_scanning(cfg);
} }
set_bit(WL_STATUS_SCANNING, &cfg->status); set_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
err = brcmf_do_escan(cfg, wiphy, ndev, request); err = brcmf_do_escan(cfg, wiphy, ndev, request);
if (err) { if (err) {
clear_bit(WL_STATUS_SCANNING, &cfg->status); clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
goto out_err; goto out_err;
} }
cfg->sched_escan = true; cfg->sched_escan = true;
@ -3352,6 +3353,7 @@ brcmf_cfg80211_sched_scan_start(struct wiphy *wiphy,
struct net_device *ndev, struct net_device *ndev,
struct cfg80211_sched_scan_request *request) struct cfg80211_sched_scan_request *request)
{ {
struct brcmf_if *ifp = netdev_priv(ndev);
struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy); struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy);
struct brcmf_pno_net_param_le pfn; struct brcmf_pno_net_param_le pfn;
int i; int i;
@ -3359,8 +3361,8 @@ brcmf_cfg80211_sched_scan_start(struct wiphy *wiphy,
WL_SCAN("Enter n_match_sets:%d n_ssids:%d\n", WL_SCAN("Enter n_match_sets:%d n_ssids:%d\n",
request->n_match_sets, request->n_ssids); request->n_match_sets, request->n_ssids);
if (test_bit(WL_STATUS_SCANNING, &cfg->status)) { if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
WL_ERR("Scanning already : status (%lu)\n", cfg->status); WL_ERR("Scanning already: status (%lu)\n", cfg->scan_status);
return -EAGAIN; return -EAGAIN;
} }
@ -3417,15 +3419,14 @@ brcmf_cfg80211_sched_scan_start(struct wiphy *wiphy,
pfn.flags = cpu_to_le32(1 << BRCMF_PNO_HIDDEN_BIT); pfn.flags = cpu_to_le32(1 << BRCMF_PNO_HIDDEN_BIT);
pfn.ssid.SSID_len = cpu_to_le32(ssid_len); pfn.ssid.SSID_len = cpu_to_le32(ssid_len);
memcpy(pfn.ssid.SSID, ssid->ssid, ssid_len); memcpy(pfn.ssid.SSID, ssid->ssid, ssid_len);
ret = brcmf_fil_iovar_data_set(netdev_priv(ndev), ret = brcmf_fil_iovar_data_set(ifp, "pfn_add", &pfn,
"pfn_add", &pfn,
sizeof(pfn)); sizeof(pfn));
WL_SCAN(">>> PNO filter %s for ssid (%s)\n", WL_SCAN(">>> PNO filter %s for ssid (%s)\n",
ret == 0 ? "set" : "failed", ret == 0 ? "set" : "failed",
ssid->ssid); ssid->ssid);
} }
/* Enable the PNO */ /* Enable the PNO */
if (brcmf_fil_iovar_int_set(netdev_priv(ndev), "pfn", 1) < 0) { if (brcmf_fil_iovar_int_set(ifp, "pfn", 1) < 0) {
WL_ERR("PNO enable failed!! ret=%d\n", ret); WL_ERR("PNO enable failed!! ret=%d\n", ret);
return -EINVAL; return -EINVAL;
} }
@ -3774,6 +3775,7 @@ brcmf_set_management_ie(struct brcmf_cfg80211_info *cfg,
struct net_device *ndev, s32 pktflag, struct net_device *ndev, s32 pktflag,
u8 *vndr_ie_buf, u32 vndr_ie_len) u8 *vndr_ie_buf, u32 vndr_ie_len)
{ {
struct brcmf_if *ifp = netdev_priv(ndev);
s32 err = 0; s32 err = 0;
u8 *iovar_ie_buf; u8 *iovar_ie_buf;
u8 *curr_ie_buf; u8 *curr_ie_buf;
@ -3796,8 +3798,8 @@ brcmf_set_management_ie(struct brcmf_cfg80211_info *cfg,
if (!iovar_ie_buf) if (!iovar_ie_buf)
return -ENOMEM; return -ENOMEM;
curr_ie_buf = iovar_ie_buf; curr_ie_buf = iovar_ie_buf;
if (test_bit(WL_STATUS_AP_CREATING, &cfg->status) || if (test_bit(BRCMF_VIF_STATUS_AP_CREATING, &ifp->vif->sme_state) ||
test_bit(WL_STATUS_AP_CREATED, &cfg->status)) { test_bit(BRCMF_VIF_STATUS_AP_CREATED, &ifp->vif->sme_state)) {
switch (pktflag) { switch (pktflag) {
case VNDR_IE_PRBRSP_FLAG: case VNDR_IE_PRBRSP_FLAG:
mgmt_ie_buf = cfg->ap_info->probe_res_ie; mgmt_ie_buf = cfg->ap_info->probe_res_ie;
@ -3909,8 +3911,7 @@ brcmf_set_management_ie(struct brcmf_cfg80211_info *cfg,
} }
} }
if (total_ie_buf_len) { if (total_ie_buf_len) {
err = brcmf_fil_bsscfg_data_set(netdev_priv(ndev), "vndr_ie", err = brcmf_fil_bsscfg_data_set(ifp, "vndr_ie", iovar_ie_buf,
iovar_ie_buf,
total_ie_buf_len); total_ie_buf_len);
if (err) if (err)
WL_ERR("vndr ie set error : %d\n", err); WL_ERR("vndr ie set error : %d\n", err);
@ -3943,7 +3944,7 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
settings->ssid, settings->ssid_len, settings->auth_type, settings->ssid, settings->ssid_len, settings->auth_type,
settings->inactivity_timeout); settings->inactivity_timeout);
if (!test_bit(WL_STATUS_AP_CREATING, &cfg->status)) { if (!test_bit(BRCMF_VIF_STATUS_AP_CREATING, &ifp->vif->sme_state)) {
WL_ERR("Not in AP creation mode\n"); WL_ERR("Not in AP creation mode\n");
return -EPERM; return -EPERM;
} }
@ -4077,8 +4078,8 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
WL_ERR("SET SSID error (%d)\n", err); WL_ERR("SET SSID error (%d)\n", err);
goto exit; goto exit;
} }
clear_bit(WL_STATUS_AP_CREATING, &cfg->status); clear_bit(BRCMF_VIF_STATUS_AP_CREATING, &ifp->vif->sme_state);
set_bit(WL_STATUS_AP_CREATED, &cfg->status); set_bit(BRCMF_VIF_STATUS_AP_CREATED, &ifp->vif->sme_state);
exit: exit:
if (err) if (err)
@ -4088,6 +4089,7 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
static int brcmf_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *ndev) static int brcmf_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *ndev)
{ {
struct brcmf_if *ifp = netdev_priv(ndev);
struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
s32 err = -EPERM; s32 err = -EPERM;
@ -4109,8 +4111,8 @@ static int brcmf_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *ndev)
goto exit; goto exit;
} }
brcmf_set_mpc(ndev, 1); brcmf_set_mpc(ndev, 1);
clear_bit(WL_STATUS_AP_CREATING, &cfg->status); clear_bit(BRCMF_VIF_STATUS_AP_CREATING, &ifp->vif->sme_state);
clear_bit(WL_STATUS_AP_CREATED, &cfg->status); clear_bit(BRCMF_VIF_STATUS_AP_CREATED, &ifp->vif->sme_state);
} }
exit: exit:
return err; return err;
@ -4424,7 +4426,8 @@ brcmf_bss_roaming_done(struct brcmf_cfg80211_info *cfg,
struct net_device *ndev, struct net_device *ndev,
const struct brcmf_event_msg *e) const struct brcmf_event_msg *e)
{ {
struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev); struct brcmf_if *ifp = netdev_priv(ndev);
struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg); struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
struct wiphy *wiphy = cfg_to_wiphy(cfg); struct wiphy *wiphy = cfg_to_wiphy(cfg);
struct ieee80211_channel *notify_channel = NULL; struct ieee80211_channel *notify_channel = NULL;
@ -4449,7 +4452,7 @@ brcmf_bss_roaming_done(struct brcmf_cfg80211_info *cfg,
/* data sent to dongle has to be little endian */ /* data sent to dongle has to be little endian */
*(__le32 *)buf = cpu_to_le32(WL_BSS_INFO_MAX); *(__le32 *)buf = cpu_to_le32(WL_BSS_INFO_MAX);
err = brcmf_fil_cmd_data_get(netdev_priv(ndev), BRCMF_C_GET_BSS_INFO, err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_BSS_INFO,
buf, WL_BSS_INFO_MAX); buf, WL_BSS_INFO_MAX);
if (err) if (err)
@ -4474,7 +4477,7 @@ brcmf_bss_roaming_done(struct brcmf_cfg80211_info *cfg,
conn_info->resp_ie, conn_info->resp_ie_len, GFP_KERNEL); conn_info->resp_ie, conn_info->resp_ie_len, GFP_KERNEL);
WL_CONN("Report roaming result\n"); WL_CONN("Report roaming result\n");
set_bit(WL_STATUS_CONNECTED, &cfg->status); set_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state);
WL_TRACE("Exit\n"); WL_TRACE("Exit\n");
return err; return err;
} }
@ -4484,13 +4487,15 @@ brcmf_bss_connect_done(struct brcmf_cfg80211_info *cfg,
struct net_device *ndev, const struct brcmf_event_msg *e, struct net_device *ndev, const struct brcmf_event_msg *e,
bool completed) bool completed)
{ {
struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev); struct brcmf_if *ifp = netdev_priv(ndev);
struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg); struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
s32 err = 0; s32 err = 0;
WL_TRACE("Enter\n"); WL_TRACE("Enter\n");
if (test_and_clear_bit(WL_STATUS_CONNECTING, &cfg->status)) { if (test_and_clear_bit(BRCMF_VIF_STATUS_CONNECTING,
&ifp->vif->sme_state)) {
if (completed) { if (completed) {
brcmf_get_assoc_ies(cfg); brcmf_get_assoc_ies(cfg);
memcpy(profile->bssid, e->addr, ETH_ALEN); memcpy(profile->bssid, e->addr, ETH_ALEN);
@ -4506,7 +4511,8 @@ brcmf_bss_connect_done(struct brcmf_cfg80211_info *cfg,
WLAN_STATUS_AUTH_TIMEOUT, WLAN_STATUS_AUTH_TIMEOUT,
GFP_KERNEL); GFP_KERNEL);
if (completed) if (completed)
set_bit(WL_STATUS_CONNECTED, &cfg->status); set_bit(BRCMF_VIF_STATUS_CONNECTED,
&ifp->vif->sme_state);
WL_CONN("Report connect result - connection %s\n", WL_CONN("Report connect result - connection %s\n",
completed ? "succeeded" : "failed"); completed ? "succeeded" : "failed");
} }
@ -4558,7 +4564,8 @@ brcmf_notify_connect_status(struct brcmf_cfg80211_info *cfg,
struct net_device *ndev, struct net_device *ndev,
const struct brcmf_event_msg *e, void *data) const struct brcmf_event_msg *e, void *data)
{ {
struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev); struct brcmf_if *ifp = netdev_priv(ndev);
struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
s32 err = 0; s32 err = 0;
if (cfg->conf->mode == WL_MODE_AP) { if (cfg->conf->mode == WL_MODE_AP) {
@ -4569,30 +4576,34 @@ brcmf_notify_connect_status(struct brcmf_cfg80211_info *cfg,
memcpy(profile->bssid, e->addr, ETH_ALEN); memcpy(profile->bssid, e->addr, ETH_ALEN);
wl_inform_ibss(cfg, ndev, e->addr); wl_inform_ibss(cfg, ndev, e->addr);
cfg80211_ibss_joined(ndev, e->addr, GFP_KERNEL); cfg80211_ibss_joined(ndev, e->addr, GFP_KERNEL);
clear_bit(WL_STATUS_CONNECTING, &cfg->status); clear_bit(BRCMF_VIF_STATUS_CONNECTING,
set_bit(WL_STATUS_CONNECTED, &cfg->status); &ifp->vif->sme_state);
set_bit(BRCMF_VIF_STATUS_CONNECTED,
&ifp->vif->sme_state);
} else } else
brcmf_bss_connect_done(cfg, ndev, e, true); brcmf_bss_connect_done(cfg, ndev, e, true);
} else if (brcmf_is_linkdown(cfg, e)) { } else if (brcmf_is_linkdown(cfg, e)) {
WL_CONN("Linkdown\n"); WL_CONN("Linkdown\n");
if (brcmf_is_ibssmode(cfg)) { if (brcmf_is_ibssmode(cfg)) {
clear_bit(WL_STATUS_CONNECTING, &cfg->status); clear_bit(BRCMF_VIF_STATUS_CONNECTING,
if (test_and_clear_bit(WL_STATUS_CONNECTED, &ifp->vif->sme_state);
&cfg->status)) if (test_and_clear_bit(BRCMF_VIF_STATUS_CONNECTED,
&ifp->vif->sme_state))
brcmf_link_down(cfg); brcmf_link_down(cfg);
} else { } else {
brcmf_bss_connect_done(cfg, ndev, e, false); brcmf_bss_connect_done(cfg, ndev, e, false);
if (test_and_clear_bit(WL_STATUS_CONNECTED, if (test_and_clear_bit(BRCMF_VIF_STATUS_CONNECTED,
&cfg->status)) { &ifp->vif->sme_state)) {
cfg80211_disconnected(ndev, 0, NULL, 0, cfg80211_disconnected(ndev, 0, NULL, 0,
GFP_KERNEL); GFP_KERNEL);
brcmf_link_down(cfg); brcmf_link_down(cfg);
} }
} }
brcmf_init_prof(ndev_to_prof(ndev)); brcmf_init_prof(ndev_to_prof(ndev));
} else if (brcmf_is_nonetwork(cfg, e)) { } else if (brcmf_is_nonetwork(cfg, e)) {
if (brcmf_is_ibssmode(cfg)) if (brcmf_is_ibssmode(cfg))
clear_bit(WL_STATUS_CONNECTING, &cfg->status); clear_bit(BRCMF_VIF_STATUS_CONNECTING,
&ifp->vif->sme_state);
else else
brcmf_bss_connect_done(cfg, ndev, e, false); brcmf_bss_connect_done(cfg, ndev, e, false);
} }
@ -4605,12 +4616,13 @@ brcmf_notify_roaming_status(struct brcmf_cfg80211_info *cfg,
struct net_device *ndev, struct net_device *ndev,
const struct brcmf_event_msg *e, void *data) const struct brcmf_event_msg *e, void *data)
{ {
struct brcmf_if *ifp = netdev_priv(ndev);
s32 err = 0; s32 err = 0;
u32 event = be32_to_cpu(e->event_type); u32 event = be32_to_cpu(e->event_type);
u32 status = be32_to_cpu(e->status); u32 status = be32_to_cpu(e->status);
if (event == BRCMF_E_ROAM && status == BRCMF_E_STATUS_SUCCESS) { if (event == BRCMF_E_ROAM && status == BRCMF_E_STATUS_SUCCESS) {
if (test_bit(WL_STATUS_CONNECTED, &cfg->status)) if (test_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state))
brcmf_bss_roaming_done(cfg, ndev, e); brcmf_bss_roaming_done(cfg, ndev, e);
else else
brcmf_bss_connect_done(cfg, ndev, e, true); brcmf_bss_connect_done(cfg, ndev, e, true);
@ -4643,6 +4655,7 @@ brcmf_notify_scan_status(struct brcmf_cfg80211_info *cfg,
struct net_device *ndev, struct net_device *ndev,
const struct brcmf_event_msg *e, void *data) const struct brcmf_event_msg *e, void *data)
{ {
struct brcmf_if *ifp = netdev_priv(ndev);
struct brcmf_channel_info_le channel_inform_le; struct brcmf_channel_info_le channel_inform_le;
struct brcmf_scan_results_le *bss_list_le; struct brcmf_scan_results_le *bss_list_le;
u32 len = WL_SCAN_BUF_MAX; u32 len = WL_SCAN_BUF_MAX;
@ -4657,14 +4670,14 @@ brcmf_notify_scan_status(struct brcmf_cfg80211_info *cfg,
return brcmf_wakeup_iscan(cfg_to_iscan(cfg)); return brcmf_wakeup_iscan(cfg_to_iscan(cfg));
} }
if (!test_and_clear_bit(WL_STATUS_SCANNING, &cfg->status)) { if (!test_and_clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
WL_ERR("Scan complete while device not scanning\n"); WL_ERR("Scan complete while device not scanning\n");
scan_abort = true; scan_abort = true;
err = -EINVAL; err = -EINVAL;
goto scan_done_out; goto scan_done_out;
} }
err = brcmf_fil_cmd_data_get(netdev_priv(ndev), BRCMF_C_GET_CHANNEL, err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_CHANNEL,
&channel_inform_le, &channel_inform_le,
sizeof(channel_inform_le)); sizeof(channel_inform_le));
if (err) { if (err) {
@ -4680,7 +4693,7 @@ brcmf_notify_scan_status(struct brcmf_cfg80211_info *cfg,
memset(cfg->scan_results, 0, len); memset(cfg->scan_results, 0, len);
bss_list_le->buflen = cpu_to_le32(len); bss_list_le->buflen = cpu_to_le32(len);
err = brcmf_fil_cmd_data_get(netdev_priv(ndev), BRCMF_C_SCAN_RESULTS, err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_SCAN_RESULTS,
cfg->scan_results, len); cfg->scan_results, len);
if (err) { if (err) {
WL_ERR("%s Scan_results error (%d)\n", ndev->name, err); WL_ERR("%s Scan_results error (%d)\n", ndev->name, err);
@ -5289,9 +5302,10 @@ static void brcmf_debugfs_remove_netdev(struct brcmf_cfg80211_info *cfg)
static s32 __brcmf_cfg80211_up(struct brcmf_cfg80211_info *cfg) static s32 __brcmf_cfg80211_up(struct brcmf_cfg80211_info *cfg)
{ {
struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
s32 err = 0; s32 err = 0;
set_bit(WL_STATUS_READY, &cfg->status); set_bit(BRCMF_VIF_STATUS_READY, &ifp->vif->sme_state);
brcmf_debugfs_add_netdev_params(cfg); brcmf_debugfs_add_netdev_params(cfg);
@ -5306,13 +5320,16 @@ static s32 __brcmf_cfg80211_up(struct brcmf_cfg80211_info *cfg)
static s32 __brcmf_cfg80211_down(struct brcmf_cfg80211_info *cfg) static s32 __brcmf_cfg80211_down(struct brcmf_cfg80211_info *cfg)
{ {
struct net_device *ndev = cfg_to_ndev(cfg);
struct brcmf_if *ifp = netdev_priv(ndev);
/* /*
* While going down, if associated with AP disassociate * While going down, if associated with AP disassociate
* from AP to save power * from AP to save power
*/ */
if ((test_bit(WL_STATUS_CONNECTED, &cfg->status) || if ((test_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state) ||
test_bit(WL_STATUS_CONNECTING, &cfg->status)) && test_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state)) &&
test_bit(WL_STATUS_READY, &cfg->status)) { check_sys_up(ifp->vif)) {
WL_INFO("Disassociating from AP"); WL_INFO("Disassociating from AP");
brcmf_link_down(cfg); brcmf_link_down(cfg);
@ -5324,7 +5341,7 @@ static s32 __brcmf_cfg80211_down(struct brcmf_cfg80211_info *cfg)
} }
brcmf_abort_scanning(cfg); brcmf_abort_scanning(cfg);
clear_bit(WL_STATUS_READY, &cfg->status); clear_bit(BRCMF_VIF_STATUS_READY, &ifp->vif->sme_state);
brcmf_debugfs_remove_netdev(cfg); brcmf_debugfs_remove_netdev(cfg);

View File

@ -127,15 +127,15 @@ do { \
#define WL_AUTH_SHARED_KEY 1 /* d11 shared authentication */ #define WL_AUTH_SHARED_KEY 1 /* d11 shared authentication */
#define IE_MAX_LEN 512 #define IE_MAX_LEN 512
/* dongle status */ /**
enum wl_status { * enum brcmf_scan_status - dongle scan status
WL_STATUS_READY, *
WL_STATUS_SCANNING, * @BRCMF_SCAN_STATUS_BUSY: scanning in progress on dongle.
WL_STATUS_SCAN_ABORTING, * @BRCMF_SCAN_STATUS_ABORT: scan being aborted on dongle.
WL_STATUS_CONNECTING, */
WL_STATUS_CONNECTED, enum brcmf_scan_status {
WL_STATUS_AP_CREATING, BRCMF_SCAN_STATUS_BUSY,
WL_STATUS_AP_CREATED BRCMF_SCAN_STATUS_ABORT,
}; };
/* wi-fi mode */ /* wi-fi mode */
@ -235,6 +235,23 @@ struct brcmf_cfg80211_profile {
s32 band; s32 band;
}; };
/**
* enum brcmf_vif_status - bit indices for vif status.
*
* @BRCMF_VIF_STATUS_READY: ready for operation.
* @BRCMF_VIF_STATUS_CONNECTING: connect/join in progress.
* @BRCMF_VIF_STATUS_CONNECTED: connected/joined succesfully.
* @BRCMF_VIF_STATUS_AP_CREATING: interface configured for AP operation.
* @BRCMF_VIF_STATUS_AP_CREATED: AP operation started.
*/
enum brcmf_vif_status {
BRCMF_VIF_STATUS_READY,
BRCMF_VIF_STATUS_CONNECTING,
BRCMF_VIF_STATUS_CONNECTED,
BRCMF_VIF_STATUS_AP_CREATING,
BRCMF_VIF_STATUS_AP_CREATED
};
/** /**
* struct brcmf_cfg80211_vif - virtual interface specific information. * struct brcmf_cfg80211_vif - virtual interface specific information.
* *
@ -243,6 +260,7 @@ struct brcmf_cfg80211_profile {
* @profile: profile information. * @profile: profile information.
* @mode: operating mode. * @mode: operating mode.
* @roam_off: roaming state. * @roam_off: roaming state.
* @sme_state: SME state using enum brcmf_vif_status bits.
* @pm_block: power-management blocked. * @pm_block: power-management blocked.
* @list: linked list. * @list: linked list.
*/ */
@ -252,6 +270,7 @@ struct brcmf_cfg80211_vif {
struct brcmf_cfg80211_profile profile; struct brcmf_cfg80211_profile profile;
s32 mode; s32 mode;
s32 roam_off; s32 roam_off;
unsigned long sme_state;
bool pm_block; bool pm_block;
struct list_head list; struct list_head list;
}; };
@ -420,7 +439,7 @@ struct brcmf_pno_scanresults_le {
* @conn_info: association info. * @conn_info: association info.
* @pmk_list: wpa2 pmk list. * @pmk_list: wpa2 pmk list.
* @event_work: event handler work struct. * @event_work: event handler work struct.
* @status: current dongle status. * @scan_status: scan activity on the dongle.
* @pub: common driver information. * @pub: common driver information.
* @channel: current channel. * @channel: current channel.
* @iscan_on: iscan on/off switch. * @iscan_on: iscan on/off switch.
@ -462,7 +481,7 @@ struct brcmf_cfg80211_info {
struct brcmf_cfg80211_connect_info conn_info; struct brcmf_cfg80211_connect_info conn_info;
struct brcmf_cfg80211_pmk_list *pmk_list; struct brcmf_cfg80211_pmk_list *pmk_list;
struct work_struct event_work; struct work_struct event_work;
unsigned long status; unsigned long scan_status;
struct brcmf_pub *pub; struct brcmf_pub *pub;
u32 channel; u32 channel;
bool iscan_on; bool iscan_on;