mirror of https://gitee.com/openkylin/linux.git
brcmfmac: Reshuffle functions to avoid forward declarations
Function prototype forward declarations are to be avoided. This patch shuffles some of the functions so the forward declarations can be removed. Reviewed-by: Arend Van Spriel <arend@broadcom.com> Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com> Signed-off-by: Hante Meuleman <meuleman@broadcom.com> Signed-off-by: Arend van Spriel <arend@broadcom.com> Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
This commit is contained in:
parent
3021ad9a4f
commit
5419f7f17d
|
@ -238,18 +238,6 @@ struct parsed_vndr_ies {
|
||||||
struct parsed_vndr_ie_info ie_info[VNDR_IE_PARSE_LIMIT];
|
struct parsed_vndr_ie_info ie_info[VNDR_IE_PARSE_LIMIT];
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Function prototype forward declarations */
|
|
||||||
static int
|
|
||||||
brcmf_cfg80211_sched_scan_start(struct wiphy *wiphy,
|
|
||||||
struct net_device *ndev,
|
|
||||||
struct cfg80211_sched_scan_request *request);
|
|
||||||
static int brcmf_cfg80211_sched_scan_stop(struct wiphy *wiphy,
|
|
||||||
struct net_device *ndev);
|
|
||||||
static s32
|
|
||||||
brcmf_notify_sched_scan_results(struct brcmf_if *ifp,
|
|
||||||
const struct brcmf_event_msg *e, void *data);
|
|
||||||
|
|
||||||
|
|
||||||
static u16 chandef_to_chanspec(struct brcmu_d11inf *d11inf,
|
static u16 chandef_to_chanspec(struct brcmu_d11inf *d11inf,
|
||||||
struct cfg80211_chan_def *ch)
|
struct cfg80211_chan_def *ch)
|
||||||
{
|
{
|
||||||
|
@ -3081,6 +3069,296 @@ static void brcmf_init_escan(struct brcmf_cfg80211_info *cfg)
|
||||||
brcmf_cfg80211_escan_timeout_worker);
|
brcmf_cfg80211_escan_timeout_worker);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* PFN result doesn't have all the info which are required by the supplicant
|
||||||
|
* (For e.g IEs) Do a target Escan so that sched scan results are reported
|
||||||
|
* via wl_inform_single_bss in the required format. Escan does require the
|
||||||
|
* scan request in the form of cfg80211_scan_request. For timebeing, create
|
||||||
|
* cfg80211_scan_request one out of the received PNO event.
|
||||||
|
*/
|
||||||
|
static s32
|
||||||
|
brcmf_notify_sched_scan_results(struct brcmf_if *ifp,
|
||||||
|
const struct brcmf_event_msg *e, void *data)
|
||||||
|
{
|
||||||
|
struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
|
||||||
|
struct brcmf_pno_net_info_le *netinfo, *netinfo_start;
|
||||||
|
struct cfg80211_scan_request *request = NULL;
|
||||||
|
struct cfg80211_ssid *ssid = NULL;
|
||||||
|
struct ieee80211_channel *channel = NULL;
|
||||||
|
struct wiphy *wiphy = cfg_to_wiphy(cfg);
|
||||||
|
int err = 0;
|
||||||
|
int channel_req = 0;
|
||||||
|
int band = 0;
|
||||||
|
struct brcmf_pno_scanresults_le *pfn_result;
|
||||||
|
u32 result_count;
|
||||||
|
u32 status;
|
||||||
|
|
||||||
|
brcmf_dbg(SCAN, "Enter\n");
|
||||||
|
|
||||||
|
if (e->event_code == BRCMF_E_PFN_NET_LOST) {
|
||||||
|
brcmf_dbg(SCAN, "PFN NET LOST event. Do Nothing\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
pfn_result = (struct brcmf_pno_scanresults_le *)data;
|
||||||
|
result_count = le32_to_cpu(pfn_result->count);
|
||||||
|
status = le32_to_cpu(pfn_result->status);
|
||||||
|
|
||||||
|
/* PFN event is limited to fit 512 bytes so we may get
|
||||||
|
* multiple NET_FOUND events. For now place a warning here.
|
||||||
|
*/
|
||||||
|
WARN_ON(status != BRCMF_PNO_SCAN_COMPLETE);
|
||||||
|
brcmf_dbg(SCAN, "PFN NET FOUND event. count: %d\n", result_count);
|
||||||
|
if (result_count > 0) {
|
||||||
|
int i;
|
||||||
|
|
||||||
|
request = kzalloc(sizeof(*request), GFP_KERNEL);
|
||||||
|
ssid = kcalloc(result_count, sizeof(*ssid), GFP_KERNEL);
|
||||||
|
channel = kcalloc(result_count, sizeof(*channel), GFP_KERNEL);
|
||||||
|
if (!request || !ssid || !channel) {
|
||||||
|
err = -ENOMEM;
|
||||||
|
goto out_err;
|
||||||
|
}
|
||||||
|
|
||||||
|
request->wiphy = wiphy;
|
||||||
|
data += sizeof(struct brcmf_pno_scanresults_le);
|
||||||
|
netinfo_start = (struct brcmf_pno_net_info_le *)data;
|
||||||
|
|
||||||
|
for (i = 0; i < result_count; i++) {
|
||||||
|
netinfo = &netinfo_start[i];
|
||||||
|
if (!netinfo) {
|
||||||
|
brcmf_err("Invalid netinfo ptr. index: %d\n",
|
||||||
|
i);
|
||||||
|
err = -EINVAL;
|
||||||
|
goto out_err;
|
||||||
|
}
|
||||||
|
|
||||||
|
brcmf_dbg(SCAN, "SSID:%s Channel:%d\n",
|
||||||
|
netinfo->SSID, netinfo->channel);
|
||||||
|
memcpy(ssid[i].ssid, netinfo->SSID, netinfo->SSID_len);
|
||||||
|
ssid[i].ssid_len = netinfo->SSID_len;
|
||||||
|
request->n_ssids++;
|
||||||
|
|
||||||
|
channel_req = netinfo->channel;
|
||||||
|
if (channel_req <= CH_MAX_2G_CHANNEL)
|
||||||
|
band = NL80211_BAND_2GHZ;
|
||||||
|
else
|
||||||
|
band = NL80211_BAND_5GHZ;
|
||||||
|
channel[i].center_freq =
|
||||||
|
ieee80211_channel_to_frequency(channel_req,
|
||||||
|
band);
|
||||||
|
channel[i].band = band;
|
||||||
|
channel[i].flags |= IEEE80211_CHAN_NO_HT40;
|
||||||
|
request->channels[i] = &channel[i];
|
||||||
|
request->n_channels++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* assign parsed ssid array */
|
||||||
|
if (request->n_ssids)
|
||||||
|
request->ssids = &ssid[0];
|
||||||
|
|
||||||
|
if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
|
||||||
|
/* Abort any on-going scan */
|
||||||
|
brcmf_abort_scanning(cfg);
|
||||||
|
}
|
||||||
|
|
||||||
|
set_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
|
||||||
|
cfg->escan_info.run = brcmf_run_escan;
|
||||||
|
err = brcmf_do_escan(cfg, wiphy, ifp, request);
|
||||||
|
if (err) {
|
||||||
|
clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
|
||||||
|
goto out_err;
|
||||||
|
}
|
||||||
|
cfg->sched_escan = true;
|
||||||
|
cfg->scan_request = request;
|
||||||
|
} else {
|
||||||
|
brcmf_err("FALSE PNO Event. (pfn_count == 0)\n");
|
||||||
|
goto out_err;
|
||||||
|
}
|
||||||
|
|
||||||
|
kfree(ssid);
|
||||||
|
kfree(channel);
|
||||||
|
kfree(request);
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
out_err:
|
||||||
|
kfree(ssid);
|
||||||
|
kfree(channel);
|
||||||
|
kfree(request);
|
||||||
|
cfg80211_sched_scan_stopped(wiphy);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int brcmf_dev_pno_clean(struct net_device *ndev)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
/* Disable pfn */
|
||||||
|
ret = brcmf_fil_iovar_int_set(netdev_priv(ndev), "pfn", 0);
|
||||||
|
if (ret == 0) {
|
||||||
|
/* clear pfn */
|
||||||
|
ret = brcmf_fil_iovar_data_set(netdev_priv(ndev), "pfnclear",
|
||||||
|
NULL, 0);
|
||||||
|
}
|
||||||
|
if (ret < 0)
|
||||||
|
brcmf_err("failed code %d\n", ret);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int brcmf_dev_pno_config(struct brcmf_if *ifp,
|
||||||
|
struct cfg80211_sched_scan_request *request)
|
||||||
|
{
|
||||||
|
struct brcmf_pno_param_le pfn_param;
|
||||||
|
struct brcmf_pno_macaddr_le pfn_mac;
|
||||||
|
s32 err;
|
||||||
|
u8 *mac_mask;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
memset(&pfn_param, 0, sizeof(pfn_param));
|
||||||
|
pfn_param.version = cpu_to_le32(BRCMF_PNO_VERSION);
|
||||||
|
|
||||||
|
/* set extra pno params */
|
||||||
|
pfn_param.flags = cpu_to_le16(1 << BRCMF_PNO_ENABLE_ADAPTSCAN_BIT);
|
||||||
|
pfn_param.repeat = BRCMF_PNO_REPEAT;
|
||||||
|
pfn_param.exp = BRCMF_PNO_FREQ_EXPO_MAX;
|
||||||
|
|
||||||
|
/* set up pno scan fr */
|
||||||
|
pfn_param.scan_freq = cpu_to_le32(BRCMF_PNO_TIME);
|
||||||
|
|
||||||
|
err = brcmf_fil_iovar_data_set(ifp, "pfn_set", &pfn_param,
|
||||||
|
sizeof(pfn_param));
|
||||||
|
if (err) {
|
||||||
|
brcmf_err("pfn_set failed, err=%d\n", err);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Find out if mac randomization should be turned on */
|
||||||
|
if (!(request->flags & NL80211_SCAN_FLAG_RANDOM_ADDR))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
pfn_mac.version = BRCMF_PFN_MACADDR_CFG_VER;
|
||||||
|
pfn_mac.flags = BRCMF_PFN_MAC_OUI_ONLY | BRCMF_PFN_SET_MAC_UNASSOC;
|
||||||
|
|
||||||
|
memcpy(pfn_mac.mac, request->mac_addr, ETH_ALEN);
|
||||||
|
mac_mask = request->mac_addr_mask;
|
||||||
|
for (i = 0; i < ETH_ALEN; i++) {
|
||||||
|
pfn_mac.mac[i] &= mac_mask[i];
|
||||||
|
pfn_mac.mac[i] |= get_random_int() & ~(mac_mask[i]);
|
||||||
|
}
|
||||||
|
/* Clear multi bit */
|
||||||
|
pfn_mac.mac[0] &= 0xFE;
|
||||||
|
/* Set locally administered */
|
||||||
|
pfn_mac.mac[0] |= 0x02;
|
||||||
|
|
||||||
|
err = brcmf_fil_iovar_data_set(ifp, "pfn_macaddr", &pfn_mac,
|
||||||
|
sizeof(pfn_mac));
|
||||||
|
if (err)
|
||||||
|
brcmf_err("pfn_macaddr failed, err=%d\n", err);
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
brcmf_cfg80211_sched_scan_start(struct wiphy *wiphy,
|
||||||
|
struct net_device *ndev,
|
||||||
|
struct cfg80211_sched_scan_request *request)
|
||||||
|
{
|
||||||
|
struct brcmf_if *ifp = netdev_priv(ndev);
|
||||||
|
struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy);
|
||||||
|
struct brcmf_pno_net_param_le pfn;
|
||||||
|
int i;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
brcmf_dbg(SCAN, "Enter n_match_sets:%d n_ssids:%d\n",
|
||||||
|
request->n_match_sets, request->n_ssids);
|
||||||
|
if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
|
||||||
|
brcmf_err("Scanning already: status (%lu)\n", cfg->scan_status);
|
||||||
|
return -EAGAIN;
|
||||||
|
}
|
||||||
|
if (test_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status)) {
|
||||||
|
brcmf_err("Scanning suppressed: status (%lu)\n",
|
||||||
|
cfg->scan_status);
|
||||||
|
return -EAGAIN;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!request->n_ssids || !request->n_match_sets) {
|
||||||
|
brcmf_dbg(SCAN, "Invalid sched scan req!! n_ssids:%d\n",
|
||||||
|
request->n_ssids);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (request->n_ssids > 0) {
|
||||||
|
for (i = 0; i < request->n_ssids; i++) {
|
||||||
|
/* Active scan req for ssids */
|
||||||
|
brcmf_dbg(SCAN, ">>> Active scan req for ssid (%s)\n",
|
||||||
|
request->ssids[i].ssid);
|
||||||
|
|
||||||
|
/* match_set ssids is a supert set of n_ssid list,
|
||||||
|
* so we need not add these set separately.
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (request->n_match_sets > 0) {
|
||||||
|
/* clean up everything */
|
||||||
|
ret = brcmf_dev_pno_clean(ndev);
|
||||||
|
if (ret < 0) {
|
||||||
|
brcmf_err("failed error=%d\n", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* configure pno */
|
||||||
|
if (brcmf_dev_pno_config(ifp, request))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
/* configure each match set */
|
||||||
|
for (i = 0; i < request->n_match_sets; i++) {
|
||||||
|
struct cfg80211_ssid *ssid;
|
||||||
|
u32 ssid_len;
|
||||||
|
|
||||||
|
ssid = &request->match_sets[i].ssid;
|
||||||
|
ssid_len = ssid->ssid_len;
|
||||||
|
|
||||||
|
if (!ssid_len) {
|
||||||
|
brcmf_err("skip broadcast ssid\n");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
pfn.auth = cpu_to_le32(WLAN_AUTH_OPEN);
|
||||||
|
pfn.wpa_auth = cpu_to_le32(BRCMF_PNO_WPA_AUTH_ANY);
|
||||||
|
pfn.wsec = cpu_to_le32(0);
|
||||||
|
pfn.infra = cpu_to_le32(1);
|
||||||
|
pfn.flags = cpu_to_le32(1 << BRCMF_PNO_HIDDEN_BIT);
|
||||||
|
pfn.ssid.SSID_len = cpu_to_le32(ssid_len);
|
||||||
|
memcpy(pfn.ssid.SSID, ssid->ssid, ssid_len);
|
||||||
|
ret = brcmf_fil_iovar_data_set(ifp, "pfn_add", &pfn,
|
||||||
|
sizeof(pfn));
|
||||||
|
brcmf_dbg(SCAN, ">>> PNO filter %s for ssid (%s)\n",
|
||||||
|
ret == 0 ? "set" : "failed", ssid->ssid);
|
||||||
|
}
|
||||||
|
/* Enable the PNO */
|
||||||
|
if (brcmf_fil_iovar_int_set(ifp, "pfn", 1) < 0) {
|
||||||
|
brcmf_err("PNO enable failed!! ret=%d\n", ret);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int brcmf_cfg80211_sched_scan_stop(struct wiphy *wiphy,
|
||||||
|
struct net_device *ndev)
|
||||||
|
{
|
||||||
|
struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
|
||||||
|
|
||||||
|
brcmf_dbg(SCAN, "enter\n");
|
||||||
|
brcmf_dev_pno_clean(ndev);
|
||||||
|
if (cfg->sched_escan)
|
||||||
|
brcmf_notify_escan_complete(cfg, netdev_priv(ndev), true, true);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static __always_inline void brcmf_delay(u32 ms)
|
static __always_inline void brcmf_delay(u32 ms)
|
||||||
{
|
{
|
||||||
if (ms < 1000 / HZ) {
|
if (ms < 1000 / HZ) {
|
||||||
|
@ -3500,300 +3778,6 @@ brcmf_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *ndev)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* PFN result doesn't have all the info which are
|
|
||||||
* required by the supplicant
|
|
||||||
* (For e.g IEs) Do a target Escan so that sched scan results are reported
|
|
||||||
* via wl_inform_single_bss in the required format. Escan does require the
|
|
||||||
* scan request in the form of cfg80211_scan_request. For timebeing, create
|
|
||||||
* cfg80211_scan_request one out of the received PNO event.
|
|
||||||
*/
|
|
||||||
static s32
|
|
||||||
brcmf_notify_sched_scan_results(struct brcmf_if *ifp,
|
|
||||||
const struct brcmf_event_msg *e, void *data)
|
|
||||||
{
|
|
||||||
struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
|
|
||||||
struct brcmf_pno_net_info_le *netinfo, *netinfo_start;
|
|
||||||
struct cfg80211_scan_request *request = NULL;
|
|
||||||
struct cfg80211_ssid *ssid = NULL;
|
|
||||||
struct ieee80211_channel *channel = NULL;
|
|
||||||
struct wiphy *wiphy = cfg_to_wiphy(cfg);
|
|
||||||
int err = 0;
|
|
||||||
int channel_req = 0;
|
|
||||||
int band = 0;
|
|
||||||
struct brcmf_pno_scanresults_le *pfn_result;
|
|
||||||
u32 result_count;
|
|
||||||
u32 status;
|
|
||||||
|
|
||||||
brcmf_dbg(SCAN, "Enter\n");
|
|
||||||
|
|
||||||
if (e->event_code == BRCMF_E_PFN_NET_LOST) {
|
|
||||||
brcmf_dbg(SCAN, "PFN NET LOST event. Do Nothing\n");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
pfn_result = (struct brcmf_pno_scanresults_le *)data;
|
|
||||||
result_count = le32_to_cpu(pfn_result->count);
|
|
||||||
status = le32_to_cpu(pfn_result->status);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* PFN event is limited to fit 512 bytes so we may get
|
|
||||||
* multiple NET_FOUND events. For now place a warning here.
|
|
||||||
*/
|
|
||||||
WARN_ON(status != BRCMF_PNO_SCAN_COMPLETE);
|
|
||||||
brcmf_dbg(SCAN, "PFN NET FOUND event. count: %d\n", result_count);
|
|
||||||
if (result_count > 0) {
|
|
||||||
int i;
|
|
||||||
|
|
||||||
request = kzalloc(sizeof(*request), GFP_KERNEL);
|
|
||||||
ssid = kcalloc(result_count, sizeof(*ssid), GFP_KERNEL);
|
|
||||||
channel = kcalloc(result_count, sizeof(*channel), GFP_KERNEL);
|
|
||||||
if (!request || !ssid || !channel) {
|
|
||||||
err = -ENOMEM;
|
|
||||||
goto out_err;
|
|
||||||
}
|
|
||||||
|
|
||||||
request->wiphy = wiphy;
|
|
||||||
data += sizeof(struct brcmf_pno_scanresults_le);
|
|
||||||
netinfo_start = (struct brcmf_pno_net_info_le *)data;
|
|
||||||
|
|
||||||
for (i = 0; i < result_count; i++) {
|
|
||||||
netinfo = &netinfo_start[i];
|
|
||||||
if (!netinfo) {
|
|
||||||
brcmf_err("Invalid netinfo ptr. index: %d\n",
|
|
||||||
i);
|
|
||||||
err = -EINVAL;
|
|
||||||
goto out_err;
|
|
||||||
}
|
|
||||||
|
|
||||||
brcmf_dbg(SCAN, "SSID:%s Channel:%d\n",
|
|
||||||
netinfo->SSID, netinfo->channel);
|
|
||||||
memcpy(ssid[i].ssid, netinfo->SSID, netinfo->SSID_len);
|
|
||||||
ssid[i].ssid_len = netinfo->SSID_len;
|
|
||||||
request->n_ssids++;
|
|
||||||
|
|
||||||
channel_req = netinfo->channel;
|
|
||||||
if (channel_req <= CH_MAX_2G_CHANNEL)
|
|
||||||
band = NL80211_BAND_2GHZ;
|
|
||||||
else
|
|
||||||
band = NL80211_BAND_5GHZ;
|
|
||||||
channel[i].center_freq =
|
|
||||||
ieee80211_channel_to_frequency(channel_req,
|
|
||||||
band);
|
|
||||||
channel[i].band = band;
|
|
||||||
channel[i].flags |= IEEE80211_CHAN_NO_HT40;
|
|
||||||
request->channels[i] = &channel[i];
|
|
||||||
request->n_channels++;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* assign parsed ssid array */
|
|
||||||
if (request->n_ssids)
|
|
||||||
request->ssids = &ssid[0];
|
|
||||||
|
|
||||||
if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
|
|
||||||
/* Abort any on-going scan */
|
|
||||||
brcmf_abort_scanning(cfg);
|
|
||||||
}
|
|
||||||
|
|
||||||
set_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
|
|
||||||
cfg->escan_info.run = brcmf_run_escan;
|
|
||||||
err = brcmf_do_escan(cfg, wiphy, ifp, request);
|
|
||||||
if (err) {
|
|
||||||
clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
|
|
||||||
goto out_err;
|
|
||||||
}
|
|
||||||
cfg->sched_escan = true;
|
|
||||||
cfg->scan_request = request;
|
|
||||||
} else {
|
|
||||||
brcmf_err("FALSE PNO Event. (pfn_count == 0)\n");
|
|
||||||
goto out_err;
|
|
||||||
}
|
|
||||||
|
|
||||||
kfree(ssid);
|
|
||||||
kfree(channel);
|
|
||||||
kfree(request);
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
out_err:
|
|
||||||
kfree(ssid);
|
|
||||||
kfree(channel);
|
|
||||||
kfree(request);
|
|
||||||
cfg80211_sched_scan_stopped(wiphy);
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int brcmf_dev_pno_clean(struct net_device *ndev)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
/* Disable pfn */
|
|
||||||
ret = brcmf_fil_iovar_int_set(netdev_priv(ndev), "pfn", 0);
|
|
||||||
if (ret == 0) {
|
|
||||||
/* clear pfn */
|
|
||||||
ret = brcmf_fil_iovar_data_set(netdev_priv(ndev), "pfnclear",
|
|
||||||
NULL, 0);
|
|
||||||
}
|
|
||||||
if (ret < 0)
|
|
||||||
brcmf_err("failed code %d\n", ret);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int brcmf_dev_pno_config(struct brcmf_if *ifp,
|
|
||||||
struct cfg80211_sched_scan_request *request)
|
|
||||||
{
|
|
||||||
struct brcmf_pno_param_le pfn_param;
|
|
||||||
struct brcmf_pno_macaddr_le pfn_mac;
|
|
||||||
s32 err;
|
|
||||||
u8 *mac_mask;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
memset(&pfn_param, 0, sizeof(pfn_param));
|
|
||||||
pfn_param.version = cpu_to_le32(BRCMF_PNO_VERSION);
|
|
||||||
|
|
||||||
/* set extra pno params */
|
|
||||||
pfn_param.flags = cpu_to_le16(1 << BRCMF_PNO_ENABLE_ADAPTSCAN_BIT);
|
|
||||||
pfn_param.repeat = BRCMF_PNO_REPEAT;
|
|
||||||
pfn_param.exp = BRCMF_PNO_FREQ_EXPO_MAX;
|
|
||||||
|
|
||||||
/* set up pno scan fr */
|
|
||||||
pfn_param.scan_freq = cpu_to_le32(BRCMF_PNO_TIME);
|
|
||||||
|
|
||||||
err = brcmf_fil_iovar_data_set(ifp, "pfn_set", &pfn_param,
|
|
||||||
sizeof(pfn_param));
|
|
||||||
if (err) {
|
|
||||||
brcmf_err("pfn_set failed, err=%d\n", err);
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Find out if mac randomization should be turned on */
|
|
||||||
if (!(request->flags & NL80211_SCAN_FLAG_RANDOM_ADDR))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
pfn_mac.version = BRCMF_PFN_MACADDR_CFG_VER;
|
|
||||||
pfn_mac.flags = BRCMF_PFN_MAC_OUI_ONLY | BRCMF_PFN_SET_MAC_UNASSOC;
|
|
||||||
|
|
||||||
memcpy(pfn_mac.mac, request->mac_addr, ETH_ALEN);
|
|
||||||
mac_mask = request->mac_addr_mask;
|
|
||||||
for (i = 0; i < ETH_ALEN; i++) {
|
|
||||||
pfn_mac.mac[i] &= mac_mask[i];
|
|
||||||
pfn_mac.mac[i] |= get_random_int() & ~(mac_mask[i]);
|
|
||||||
}
|
|
||||||
/* Clear multi bit */
|
|
||||||
pfn_mac.mac[0] &= 0xFE;
|
|
||||||
/* Set locally administered */
|
|
||||||
pfn_mac.mac[0] |= 0x02;
|
|
||||||
|
|
||||||
err = brcmf_fil_iovar_data_set(ifp, "pfn_macaddr", &pfn_mac,
|
|
||||||
sizeof(pfn_mac));
|
|
||||||
if (err)
|
|
||||||
brcmf_err("pfn_macaddr failed, err=%d\n", err);
|
|
||||||
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
brcmf_cfg80211_sched_scan_start(struct wiphy *wiphy,
|
|
||||||
struct net_device *ndev,
|
|
||||||
struct cfg80211_sched_scan_request *request)
|
|
||||||
{
|
|
||||||
struct brcmf_if *ifp = netdev_priv(ndev);
|
|
||||||
struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy);
|
|
||||||
struct brcmf_pno_net_param_le pfn;
|
|
||||||
int i;
|
|
||||||
int ret = 0;
|
|
||||||
|
|
||||||
brcmf_dbg(SCAN, "Enter n_match_sets:%d n_ssids:%d\n",
|
|
||||||
request->n_match_sets, request->n_ssids);
|
|
||||||
if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
|
|
||||||
brcmf_err("Scanning already: status (%lu)\n", cfg->scan_status);
|
|
||||||
return -EAGAIN;
|
|
||||||
}
|
|
||||||
if (test_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status)) {
|
|
||||||
brcmf_err("Scanning suppressed: status (%lu)\n",
|
|
||||||
cfg->scan_status);
|
|
||||||
return -EAGAIN;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!request->n_ssids || !request->n_match_sets) {
|
|
||||||
brcmf_dbg(SCAN, "Invalid sched scan req!! n_ssids:%d\n",
|
|
||||||
request->n_ssids);
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (request->n_ssids > 0) {
|
|
||||||
for (i = 0; i < request->n_ssids; i++) {
|
|
||||||
/* Active scan req for ssids */
|
|
||||||
brcmf_dbg(SCAN, ">>> Active scan req for ssid (%s)\n",
|
|
||||||
request->ssids[i].ssid);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* match_set ssids is a supert set of n_ssid list,
|
|
||||||
* so we need not add these set seperately.
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (request->n_match_sets > 0) {
|
|
||||||
/* clean up everything */
|
|
||||||
ret = brcmf_dev_pno_clean(ndev);
|
|
||||||
if (ret < 0) {
|
|
||||||
brcmf_err("failed error=%d\n", ret);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* configure pno */
|
|
||||||
if (brcmf_dev_pno_config(ifp, request))
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
/* configure each match set */
|
|
||||||
for (i = 0; i < request->n_match_sets; i++) {
|
|
||||||
struct cfg80211_ssid *ssid;
|
|
||||||
u32 ssid_len;
|
|
||||||
|
|
||||||
ssid = &request->match_sets[i].ssid;
|
|
||||||
ssid_len = ssid->ssid_len;
|
|
||||||
|
|
||||||
if (!ssid_len) {
|
|
||||||
brcmf_err("skip broadcast ssid\n");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
pfn.auth = cpu_to_le32(WLAN_AUTH_OPEN);
|
|
||||||
pfn.wpa_auth = cpu_to_le32(BRCMF_PNO_WPA_AUTH_ANY);
|
|
||||||
pfn.wsec = cpu_to_le32(0);
|
|
||||||
pfn.infra = cpu_to_le32(1);
|
|
||||||
pfn.flags = cpu_to_le32(1 << BRCMF_PNO_HIDDEN_BIT);
|
|
||||||
pfn.ssid.SSID_len = cpu_to_le32(ssid_len);
|
|
||||||
memcpy(pfn.ssid.SSID, ssid->ssid, ssid_len);
|
|
||||||
ret = brcmf_fil_iovar_data_set(ifp, "pfn_add", &pfn,
|
|
||||||
sizeof(pfn));
|
|
||||||
brcmf_dbg(SCAN, ">>> PNO filter %s for ssid (%s)\n",
|
|
||||||
ret == 0 ? "set" : "failed", ssid->ssid);
|
|
||||||
}
|
|
||||||
/* Enable the PNO */
|
|
||||||
if (brcmf_fil_iovar_int_set(ifp, "pfn", 1) < 0) {
|
|
||||||
brcmf_err("PNO enable failed!! ret=%d\n", ret);
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int brcmf_cfg80211_sched_scan_stop(struct wiphy *wiphy,
|
|
||||||
struct net_device *ndev)
|
|
||||||
{
|
|
||||||
struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
|
|
||||||
|
|
||||||
brcmf_dbg(SCAN, "enter\n");
|
|
||||||
brcmf_dev_pno_clean(ndev);
|
|
||||||
if (cfg->sched_escan)
|
|
||||||
brcmf_notify_escan_complete(cfg, netdev_priv(ndev), true, true);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static s32 brcmf_configure_opensecurity(struct brcmf_if *ifp)
|
static s32 brcmf_configure_opensecurity(struct brcmf_if *ifp)
|
||||||
{
|
{
|
||||||
s32 err;
|
s32 err;
|
||||||
|
|
Loading…
Reference in New Issue