--- a/amd64/src/wl/sys/wl_cfg80211_hybrid.c +++ b/amd64/src/wl/sys/wl_cfg80211_hybrid.c @@ -1968,7 +1968,7 @@ if (dtoh32(bi->length) > WL_BSS_INFO_MAX) { WL_DBG(("Beacon is larger than buffer. Discarding\n")); - return err; + return -E2BIG; } notif_bss_info = kzalloc(sizeof(*notif_bss_info) + sizeof(*mgmt) - sizeof(u8) + WL_BSS_INFO_MAX, GFP_KERNEL); @@ -1992,9 +1992,15 @@ beacon_proberesp->capab_info = cpu_to_le16(bi->capability); wl_rst_ie(wl); - wl_mrg_ie(wl, ((u8 *) bi) + bi->ie_offset, bi->ie_length); - wl_cp_ie(wl, beacon_proberesp->variable, WL_BSS_INFO_MAX - + err = wl_mrg_ie(wl, ((u8 *) bi) + bi->ie_offset, bi->ie_length); + if (err) + goto inform_single_bss_out; + + err = wl_cp_ie(wl, beacon_proberesp->variable, WL_BSS_INFO_MAX - offsetof(struct wl_cfg80211_bss_info, frame_buf)); + if (err) + goto inform_single_bss_out; + notif_bss_info->frame_len = offsetof(struct ieee80211_mgmt, u.beacon.variable) + wl_get_ielen(wl); #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 39) @@ -2006,14 +2012,14 @@ #endif if (freq == 0) { WL_ERR(("Invalid channel, fail to chcnage channel to freq\n")); - kfree(notif_bss_info); - return -EINVAL; + err = -EINVAL; + goto inform_single_bss_out; } channel = ieee80211_get_channel(wiphy, freq); if (unlikely(!channel)) { WL_ERR(("ieee80211_get_channel error\n")); - kfree(notif_bss_info); - return -EINVAL; + err = -EINVAL; + goto inform_single_bss_out; } WL_DBG(("SSID : \"%s\", rssi %d, channel %d, capability : 0x04%x, bssid %pM\n", @@ -2021,28 +2027,37 @@ mgmt->u.beacon.capab_info, &bi->BSSID)); signal = notif_bss_info->rssi * 100; - cbss = cfg80211_inform_bss_frame(wiphy, channel, mgmt, - le16_to_cpu(notif_bss_info->frame_len), signal, GFP_KERNEL); - if (unlikely(!cbss)) { - WL_ERR(("cfg80211_inform_bss_frame error\n")); - kfree(notif_bss_info); - return -EINVAL; - } - notify_ie = (u8 *)bi + le16_to_cpu(bi->ie_offset); - notify_ielen = le32_to_cpu(bi->ie_length); + if (!wl->scan_request) { + cbss = cfg80211_inform_bss_frame(wiphy, channel, mgmt, + le16_to_cpu(notif_bss_info->frame_len), signal, GFP_KERNEL); + if (unlikely(!cbss)) { + WL_ERR(("cfg80211_inform_bss_frame error\n")); + err = -ENOMEM; + goto inform_single_bss_out; + } + } else { + notify_ie = (u8 *)bi + le16_to_cpu(bi->ie_offset); + notify_ielen = le32_to_cpu(bi->ie_length); #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 18, 0) - cbss = cfg80211_inform_bss(wiphy, channel, (const u8 *)(bi->BSSID.octet), - 0, beacon_proberesp->capab_info, beacon_proberesp->beacon_int, - (const u8 *)notify_ie, notify_ielen, signal, GFP_KERNEL); + cbss = cfg80211_inform_bss(wiphy, channel, (const u8 *)(bi->BSSID.octet), + 0, beacon_proberesp->capab_info, beacon_proberesp->beacon_int, + (const u8 *)notify_ie, notify_ielen, signal, GFP_KERNEL); #else - cbss = cfg80211_inform_bss(wiphy, channel, CFG80211_BSS_FTYPE_UNKNOWN, (const u8 *)(bi->BSSID.octet), - 0, beacon_proberesp->capab_info, beacon_proberesp->beacon_int, - (const u8 *)notify_ie, notify_ielen, signal, GFP_KERNEL); + cbss = cfg80211_inform_bss(wiphy, channel, + wl->active_scan ? + CFG80211_BSS_FTYPE_PRESP : CFG80211_BSS_FTYPE_BEACON, + (const u8 *)(bi->BSSID.octet), 0, + beacon_proberesp->capab_info, + beacon_proberesp->beacon_int, + (const u8 *)notify_ie, notify_ielen, signal, GFP_KERNEL); #endif - - if (unlikely(!cbss)) - return -ENOMEM; + if (unlikely(!cbss)) { + WL_ERR(("cfg80211_inform_bss error\n")); + err = -ENOMEM; + goto inform_single_bss_out; + } + } #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0) cfg80211_put_bss(wiphy, cbss); @@ -2050,6 +2065,7 @@ cfg80211_put_bss(cbss); #endif +inform_single_bss_out: kfree(notif_bss_info); return err; @@ -2316,6 +2332,9 @@ if (err) goto update_bss_info_out; + bss = cfg80211_get_bss(wl_to_wiphy(wl), NULL, (s8 *)&wl->bssid, + ssid->SSID, ssid->SSID_len, WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS); + ie = ((u8 *)bi) + bi->ie_offset; ie_len = bi->ie_length; } else { @@ -2328,11 +2347,18 @@ ie_len = bss->len_information_elements; #endif wl->conf->channel = *bss->channel; + } + + if (bss) { #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0) cfg80211_put_bss(wiphy, bss); #else cfg80211_put_bss(bss); #endif + } else { + WL_DBG(("Could not update BSS\n")); + err = -EINVAL; + goto update_bss_info_out; } tim = bcm_parse_tlvs(ie, ie_len, WLAN_EID_TIM); @@ -2360,10 +2386,17 @@ struct wl_cfg80211_connect_info *conn_info = wl_to_conn(wl); s32 err = 0; - wl_get_assoc_ies(wl); + err = wl_get_assoc_ies(wl); + if (err) + return err; + memcpy(wl->profile->bssid, &e->addr, ETHER_ADDR_LEN); memcpy(&wl->bssid, &e->addr, ETHER_ADDR_LEN); - wl_update_bss_info(wl); + + err = wl_update_bss_info(wl); + if (err) + return err; + cfg80211_roamed(ndev, #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 39) &wl->conf->channel,