diff options
Diffstat (limited to 'drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c')
-rw-r--r-- | drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 204 |
1 files changed, 46 insertions, 158 deletions
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c index aaed4ab503ad..6e70df978159 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c @@ -472,47 +472,6 @@ send_key_to_dongle(struct brcmf_if *ifp, struct brcmf_wsec_key *key) return err; } -static s32 -brcmf_configure_arp_nd_offload(struct brcmf_if *ifp, bool enable) -{ - s32 err; - u32 mode; - - if (enable) - mode = BRCMF_ARP_OL_AGENT | BRCMF_ARP_OL_PEER_AUTO_REPLY; - else - mode = 0; - - /* Try to set and enable ARP offload feature, this may fail, then it */ - /* is simply not supported and err 0 will be returned */ - err = brcmf_fil_iovar_int_set(ifp, "arp_ol", mode); - if (err) { - brcmf_dbg(TRACE, "failed to set ARP offload mode to 0x%x, err = %d\n", - mode, err); - err = 0; - } else { - err = brcmf_fil_iovar_int_set(ifp, "arpoe", enable); - if (err) { - brcmf_dbg(TRACE, "failed to configure (%d) ARP offload err = %d\n", - enable, err); - err = 0; - } else - brcmf_dbg(TRACE, "successfully configured (%d) ARP offload to 0x%x\n", - enable, mode); - } - - err = brcmf_fil_iovar_int_set(ifp, "ndoe", enable); - if (err) { - brcmf_dbg(TRACE, "failed to configure (%d) ND offload err = %d\n", - enable, err); - err = 0; - } else - brcmf_dbg(TRACE, "successfully configured (%d) ND offload to 0x%x\n", - enable, mode); - - return err; -} - static void brcmf_cfg80211_update_proto_addr_mode(struct wireless_dev *wdev) { @@ -980,7 +939,7 @@ static void brcmf_escan_prep(struct brcmf_cfg80211_info *cfg, eth_broadcast_addr(params_le->bssid); params_le->bss_type = DOT11_BSSTYPE_ANY; - params_le->scan_type = 0; + params_le->scan_type = BRCMF_SCANTYPE_ACTIVE; params_le->channel_num = 0; params_le->nprobes = cpu_to_le32(-1); params_le->active_time = cpu_to_le32(-1); @@ -988,12 +947,9 @@ static void brcmf_escan_prep(struct brcmf_cfg80211_info *cfg, params_le->home_time = cpu_to_le32(-1); memset(¶ms_le->ssid_le, 0, sizeof(params_le->ssid_le)); - /* if request is null exit so it will be all channel broadcast scan */ - if (!request) - return; - n_ssids = request->n_ssids; n_channels = request->n_channels; + /* Copy channel array if applicable */ brcmf_dbg(SCAN, "### List of channelspecs to scan ### %d\n", n_channels); @@ -1030,16 +986,8 @@ static void brcmf_escan_prep(struct brcmf_cfg80211_info *cfg, ptr += sizeof(ssid_le); } } else { - brcmf_dbg(SCAN, "Broadcast scan %p\n", request->ssids); - if ((request->ssids) && request->ssids->ssid_len) { - brcmf_dbg(SCAN, "SSID %s len=%d\n", - params_le->ssid_le.SSID, - request->ssids->ssid_len); - params_le->ssid_le.SSID_len = - cpu_to_le32(request->ssids->ssid_len); - memcpy(¶ms_le->ssid_le.SSID, request->ssids->ssid, - request->ssids->ssid_len); - } + brcmf_dbg(SCAN, "Performing passive scan\n"); + params_le->scan_type = BRCMF_SCANTYPE_PASSIVE; } /* Adding mask to channel numbers */ params_le->channel_num = @@ -1095,7 +1043,6 @@ brcmf_do_escan(struct brcmf_if *ifp, struct cfg80211_scan_request *request) { struct brcmf_cfg80211_info *cfg = ifp->drvr->config; s32 err; - u32 passive_scan; struct brcmf_scan_results *results; struct escan_info *escan = &cfg->escan_info; @@ -1103,13 +1050,7 @@ brcmf_do_escan(struct brcmf_if *ifp, struct cfg80211_scan_request *request) escan->ifp = ifp; escan->wiphy = cfg->wiphy; escan->escan_state = WL_ESCAN_STATE_SCANNING; - passive_scan = cfg->active_scan ? 0 : 1; - err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PASSIVE_SCAN, - passive_scan); - if (err) { - brcmf_err("error (%d)\n", err); - return err; - } + brcmf_scan_config_mpc(ifp, 0); results = (struct brcmf_scan_results *)cfg->escan_info.escan_buf; results->version = 0; @@ -1123,21 +1064,16 @@ brcmf_do_escan(struct brcmf_if *ifp, struct cfg80211_scan_request *request) } static s32 -brcmf_cfg80211_escan(struct wiphy *wiphy, struct brcmf_cfg80211_vif *vif, - struct cfg80211_scan_request *request, - struct cfg80211_ssid *this_ssid) +brcmf_cfg80211_scan(struct wiphy *wiphy, struct cfg80211_scan_request *request) { - struct brcmf_if *ifp = vif->ifp; struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); - struct cfg80211_ssid *ssids; - u32 passive_scan; - bool escan_req; - bool spec_scan; - s32 err; - struct brcmf_ssid_le ssid_le; - u32 SSID_len; + struct brcmf_cfg80211_vif *vif; + s32 err = 0; - brcmf_dbg(SCAN, "START ESCAN\n"); + brcmf_dbg(TRACE, "Enter\n"); + vif = container_of(request->wdev, struct brcmf_cfg80211_vif, wdev); + if (!check_vif_up(vif)) + return -EIO; if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) { brcmf_err("Scanning already: status (%lu)\n", cfg->scan_status); @@ -1153,8 +1089,8 @@ brcmf_cfg80211_escan(struct wiphy *wiphy, struct brcmf_cfg80211_vif *vif, cfg->scan_status); return -EAGAIN; } - if (test_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state)) { - brcmf_err("Connecting: status (%lu)\n", ifp->vif->sme_state); + if (test_bit(BRCMF_VIF_STATUS_CONNECTING, &vif->sme_state)) { + brcmf_err("Connecting: status (%lu)\n", vif->sme_state); return -EAGAIN; } @@ -1162,96 +1098,38 @@ brcmf_cfg80211_escan(struct wiphy *wiphy, struct brcmf_cfg80211_vif *vif, if (vif == cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif) vif = cfg->p2p.bss_idx[P2PAPI_BSSCFG_PRIMARY].vif; - escan_req = false; - if (request) { - /* scan bss */ - ssids = request->ssids; - escan_req = true; - } else { - /* scan in ibss */ - /* we don't do escan in ibss */ - ssids = this_ssid; - } + brcmf_dbg(SCAN, "START ESCAN\n"); cfg->scan_request = request; set_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status); - if (escan_req) { - cfg->escan_info.run = brcmf_run_escan; - err = brcmf_p2p_scan_prep(wiphy, request, vif); - if (err) - goto scan_out; - err = brcmf_do_escan(vif->ifp, request); - if (err) - goto scan_out; - } else { - brcmf_dbg(SCAN, "ssid \"%s\", ssid_len (%d)\n", - ssids->ssid, ssids->ssid_len); - memset(&ssid_le, 0, sizeof(ssid_le)); - SSID_len = min_t(u8, sizeof(ssid_le.SSID), ssids->ssid_len); - ssid_le.SSID_len = cpu_to_le32(0); - spec_scan = false; - if (SSID_len) { - memcpy(ssid_le.SSID, ssids->ssid, SSID_len); - ssid_le.SSID_len = cpu_to_le32(SSID_len); - spec_scan = true; - } else - brcmf_dbg(SCAN, "Broadcast scan\n"); + cfg->escan_info.run = brcmf_run_escan; + err = brcmf_p2p_scan_prep(wiphy, request, vif); + if (err) + goto scan_out; - passive_scan = cfg->active_scan ? 0 : 1; - err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PASSIVE_SCAN, - passive_scan); - if (err) { - brcmf_err("WLC_SET_PASSIVE_SCAN error (%d)\n", err); - goto scan_out; - } - brcmf_scan_config_mpc(ifp, 0); - err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SCAN, &ssid_le, - sizeof(ssid_le)); - if (err) { - if (err == -EBUSY) - brcmf_dbg(INFO, "BUSY: scan for \"%s\" canceled\n", - ssid_le.SSID); - else - brcmf_err("WLC_SCAN error (%d)\n", err); + err = brcmf_vif_set_mgmt_ie(vif, BRCMF_VNDR_IE_PRBREQ_FLAG, + request->ie, request->ie_len); + if (err) + goto scan_out; - brcmf_scan_config_mpc(ifp, 1); - goto scan_out; - } - } + err = brcmf_do_escan(vif->ifp, request); + if (err) + goto scan_out; /* Arm scan timeout timer */ - mod_timer(&cfg->escan_timeout, jiffies + - BRCMF_ESCAN_TIMER_INTERVAL_MS * HZ / 1000); + mod_timer(&cfg->escan_timeout, + jiffies + msecs_to_jiffies(BRCMF_ESCAN_TIMER_INTERVAL_MS)); return 0; scan_out: + brcmf_err("scan error (%d)\n", err); clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status); cfg->scan_request = NULL; return err; } -static s32 -brcmf_cfg80211_scan(struct wiphy *wiphy, struct cfg80211_scan_request *request) -{ - struct brcmf_cfg80211_vif *vif; - s32 err = 0; - - brcmf_dbg(TRACE, "Enter\n"); - vif = container_of(request->wdev, struct brcmf_cfg80211_vif, wdev); - if (!check_vif_up(vif)) - return -EIO; - - err = brcmf_cfg80211_escan(wiphy, vif, request, NULL); - - if (err) - brcmf_err("scan error (%d)\n", err); - - brcmf_dbg(TRACE, "Exit\n"); - return err; -} - static s32 brcmf_set_rts(struct net_device *ndev, u32 rts_threshold) { s32 err = 0; @@ -3162,6 +3040,7 @@ brcmf_cfg80211_escan_handler(struct brcmf_if *ifp, struct brcmf_cfg80211_info *cfg = ifp->drvr->config; s32 status; struct brcmf_escan_result_le *escan_result_le; + u32 escan_buflen; struct brcmf_bss_info_le *bss_info_le; struct brcmf_bss_info_le *bss = NULL; u32 bi_length; @@ -3181,11 +3060,23 @@ brcmf_cfg80211_escan_handler(struct brcmf_if *ifp, if (status == BRCMF_E_STATUS_PARTIAL) { brcmf_dbg(SCAN, "ESCAN Partial result\n"); + if (e->datalen < sizeof(*escan_result_le)) { + brcmf_err("invalid event data length\n"); + goto exit; + } escan_result_le = (struct brcmf_escan_result_le *) data; if (!escan_result_le) { brcmf_err("Invalid escan result (NULL pointer)\n"); goto exit; } + escan_buflen = le32_to_cpu(escan_result_le->buflen); + if (escan_buflen > BRCMF_ESCAN_BUF_SIZE || + escan_buflen > e->datalen || + escan_buflen < sizeof(*escan_result_le)) { + brcmf_err("Invalid escan buffer length: %d\n", + escan_buflen); + goto exit; + } if (le16_to_cpu(escan_result_le->bss_count) != 1) { brcmf_err("Invalid bss_count %d: ignoring\n", escan_result_le->bss_count); @@ -3202,9 +3093,8 @@ brcmf_cfg80211_escan_handler(struct brcmf_if *ifp, } bi_length = le32_to_cpu(bss_info_le->length); - if (bi_length != (le32_to_cpu(escan_result_le->buflen) - - WL_ESCAN_RESULTS_FIXED_SIZE)) { - brcmf_err("Invalid bss_info length %d: ignoring\n", + if (bi_length != escan_buflen - WL_ESCAN_RESULTS_FIXED_SIZE) { + brcmf_err("Ignoring invalid bss_info length: %d\n", bi_length); goto exit; } @@ -3260,9 +3150,8 @@ static void brcmf_init_escan(struct brcmf_cfg80211_info *cfg) brcmf_cfg80211_escan_handler); cfg->escan_info.escan_state = WL_ESCAN_STATE_IDLE; /* Init scan_timeout timer */ - init_timer(&cfg->escan_timeout); - cfg->escan_timeout.data = (unsigned long) cfg; - cfg->escan_timeout.function = brcmf_escan_timeout; + setup_timer(&cfg->escan_timeout, brcmf_escan_timeout, + (unsigned long)cfg); INIT_WORK(&cfg->escan_timeout_work, brcmf_cfg80211_escan_timeout_worker); } @@ -5876,7 +5765,6 @@ static s32 wl_init_priv(struct brcmf_cfg80211_info *cfg) cfg->scan_request = NULL; cfg->pwr_save = true; - cfg->active_scan = true; /* we do active scan per default */ cfg->dongle_up = false; /* dongle is not up yet */ err = brcmf_init_priv_mem(cfg); if (err) |