Commit 9446af06 authored by Sukesh Srikakula's avatar Sukesh Srikakula Committed by Greg Kroah-Hartman

staging: brcm80211: Fixed scan notification functionality in brcmfmac driver

Earlier brcmfmac driver used to report success even for an aborted scan. This
functionality is now fixed with this patch.

Cc: devel@linuxdriverproject.org
Cc: linux-wireless@vger.kernel.org
Reviewed-by: default avatarFranky (Zhenhui) Lin <frankyl@broadcom.com>
Reviewed-by: default avatarBrett Rudley <brudley@broadcom.com>
Signed-off-by: default avatarArend van Spriel <arend@broadcom.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent e4dd6325
...@@ -768,26 +768,25 @@ __wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev, ...@@ -768,26 +768,25 @@ __wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
(int)wl->status); (int)wl->status);
return -EAGAIN; return -EAGAIN;
} }
if (test_bit(WL_STATUS_CONNECTING, &wl->status)) {
WL_ERR("Connecting : status (%d)\n",
(int)wl->status);
return -EAGAIN;
}
iscan_req = false; iscan_req = false;
spec_scan = false; spec_scan = false;
if (request) { /* scan bss */ if (request) {
/* scan bss */
ssids = request->ssids; ssids = request->ssids;
if (wl->iscan_on && (!ssids || !ssids->ssid_len)) { /* for if (wl->iscan_on && (!ssids || !ssids->ssid_len))
* specific scan,
* ssids->ssid_len has
* non-zero(ssid string)
* length.
* Otherwise this is 0.
* we do not iscan for
* specific scan request
*/
iscan_req = true; iscan_req = true;
} } else {
} else { /* scan in ibss */ /* scan in ibss */
/* we don't do iscan in ibss */ /* we don't do iscan in ibss */
ssids = this_ssid; ssids = this_ssid;
} }
wl->scan_request = request; wl->scan_request = request;
set_bit(WL_STATUS_SCANNING, &wl->status); set_bit(WL_STATUS_SCANNING, &wl->status);
if (iscan_req) { if (iscan_req) {
...@@ -2883,21 +2882,23 @@ wl_notify_scan_status(struct wl_priv *wl, struct net_device *ndev, ...@@ -2883,21 +2882,23 @@ wl_notify_scan_status(struct wl_priv *wl, struct net_device *ndev,
struct wl_scan_results *bss_list; struct wl_scan_results *bss_list;
u32 len = WL_SCAN_BUF_MAX; u32 len = WL_SCAN_BUF_MAX;
s32 err = 0; s32 err = 0;
bool scan_abort = false;
if (wl->iscan_on && wl->iscan_kickstart) if (wl->iscan_on && wl->iscan_kickstart)
return wl_wakeup_iscan(wl_to_iscan(wl)); return wl_wakeup_iscan(wl_to_iscan(wl));
if (unlikely(!test_and_clear_bit(WL_STATUS_SCANNING, &wl->status))) { if (unlikely(!test_and_clear_bit(WL_STATUS_SCANNING, &wl->status))) {
WL_ERR("Scan complete while device not scanning\n"); WL_ERR("Scan complete while device not scanning\n");
return -EINVAL; scan_abort = true;
} err = -EINVAL;
if (unlikely(!wl->scan_request)) { goto scan_done_out;
} }
rtnl_lock();
err = wl_dev_ioctl(ndev, WLC_GET_CHANNEL, &channel_inform, err = wl_dev_ioctl(ndev, WLC_GET_CHANNEL, &channel_inform,
sizeof(channel_inform)); sizeof(channel_inform));
if (unlikely(err)) { if (unlikely(err)) {
WL_ERR("scan busy (%d)\n", err); WL_ERR("scan busy (%d)\n", err);
scan_abort = true;
goto scan_done_out; goto scan_done_out;
} }
channel_inform.scan_channel = le32_to_cpu(channel_inform.scan_channel); channel_inform.scan_channel = le32_to_cpu(channel_inform.scan_channel);
...@@ -2910,10 +2911,12 @@ wl_notify_scan_status(struct wl_priv *wl, struct net_device *ndev, ...@@ -2910,10 +2911,12 @@ wl_notify_scan_status(struct wl_priv *wl, struct net_device *ndev,
bss_list = wl->bss_list; bss_list = wl->bss_list;
memset(bss_list, 0, len); memset(bss_list, 0, len);
bss_list->buflen = cpu_to_le32(len); bss_list->buflen = cpu_to_le32(len);
err = wl_dev_ioctl(ndev, WLC_SCAN_RESULTS, bss_list, len); err = wl_dev_ioctl(ndev, WLC_SCAN_RESULTS, bss_list, len);
if (unlikely(err)) { if (unlikely(err)) {
WL_ERR("%s Scan_results error (%d)\n", ndev->name, err); WL_ERR("%s Scan_results error (%d)\n", ndev->name, err);
err = -EINVAL; err = -EINVAL;
scan_abort = true;
goto scan_done_out; goto scan_done_out;
} }
bss_list->buflen = le32_to_cpu(bss_list->buflen); bss_list->buflen = le32_to_cpu(bss_list->buflen);
...@@ -2921,16 +2924,18 @@ wl_notify_scan_status(struct wl_priv *wl, struct net_device *ndev, ...@@ -2921,16 +2924,18 @@ wl_notify_scan_status(struct wl_priv *wl, struct net_device *ndev,
bss_list->count = le32_to_cpu(bss_list->count); bss_list->count = le32_to_cpu(bss_list->count);
err = wl_inform_bss(wl); err = wl_inform_bss(wl);
if (err) if (err) {
scan_abort = true;
goto scan_done_out; goto scan_done_out;
}
scan_done_out: scan_done_out:
if (wl->scan_request) { if (wl->scan_request) {
cfg80211_scan_done(wl->scan_request, false); WL_DBG("calling cfg80211_scan_done\n");
cfg80211_scan_done(wl->scan_request, scan_abort);
wl_set_mpc(ndev, 1); wl_set_mpc(ndev, 1);
wl->scan_request = NULL; wl->scan_request = NULL;
} }
rtnl_unlock();
return err; return err;
} }
...@@ -4336,13 +4341,16 @@ s8 *wl_cfg80211_get_nvramname(void) ...@@ -4336,13 +4341,16 @@ s8 *wl_cfg80211_get_nvramname(void)
static void wl_set_mpc(struct net_device *ndev, int mpc) static void wl_set_mpc(struct net_device *ndev, int mpc)
{ {
s32 err = 0; s32 err = 0;
struct wl_priv *wl = ndev_to_wl(ndev);
err = wl_dev_intvar_set(ndev, "mpc", mpc); if (test_bit(WL_STATUS_READY, &wl->status)) {
if (unlikely(err)) { err = wl_dev_intvar_set(ndev, "mpc", mpc);
WL_ERR("fail to set mpc\n"); if (unlikely(err)) {
return; WL_ERR("fail to set mpc\n");
return;
}
WL_INFO("MPC : %d\n", mpc);
} }
WL_DBG("MPC : %d\n", mpc);
} }
static int wl_debugfs_add_netdev_params(struct wl_priv *wl) static int wl_debugfs_add_netdev_params(struct wl_priv *wl)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment