Commit 9fe929aa authored by Arend van Spriel's avatar Arend van Spriel Committed by Kalle Valo

brcmfmac: add firmware feature detection for gscan feature

Detect gscan support in firmware by doing pfn_gscan_cfg iovar with
invalid version.
Reviewed-by: default avatarHante Meuleman <hante.meuleman@broadcom.com>
Reviewed-by: default avatarPieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com>
Reviewed-by: default avatarFranky Lin <franky.lin@broadcom.com>
Signed-off-by: default avatarArend van Spriel <arend.vanspriel@broadcom.com>
Signed-off-by: default avatarKalle Valo <kvalo@codeaurora.org>
parent a95cfad9
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
#include "feature.h" #include "feature.h"
#include "common.h" #include "common.h"
#define BRCMF_FW_UNSUPPORTED 23
/* /*
* expand feature list to array of feature strings. * expand feature list to array of feature strings.
...@@ -113,6 +114,22 @@ static void brcmf_feat_iovar_int_get(struct brcmf_if *ifp, ...@@ -113,6 +114,22 @@ static void brcmf_feat_iovar_int_get(struct brcmf_if *ifp,
} }
} }
static void brcmf_feat_iovar_data_set(struct brcmf_if *ifp,
enum brcmf_feat_id id, char *name,
const void *data, size_t len)
{
int err;
err = brcmf_fil_iovar_data_set(ifp, name, data, len);
if (err != -BRCMF_FW_UNSUPPORTED) {
brcmf_dbg(INFO, "enabling feature: %s\n", brcmf_feat_names[id]);
ifp->drvr->feat_flags |= BIT(id);
} else {
brcmf_dbg(TRACE, "%s feature check failed: %d\n",
brcmf_feat_names[id], err);
}
}
static void brcmf_feat_firmware_capabilities(struct brcmf_if *ifp) static void brcmf_feat_firmware_capabilities(struct brcmf_if *ifp)
{ {
char caps[256]; char caps[256];
...@@ -136,11 +153,14 @@ void brcmf_feat_attach(struct brcmf_pub *drvr) ...@@ -136,11 +153,14 @@ void brcmf_feat_attach(struct brcmf_pub *drvr)
{ {
struct brcmf_if *ifp = brcmf_get_ifp(drvr, 0); struct brcmf_if *ifp = brcmf_get_ifp(drvr, 0);
struct brcmf_pno_macaddr_le pfn_mac; struct brcmf_pno_macaddr_le pfn_mac;
struct brcmf_gscan_config gscan_cfg;
u32 wowl_cap; u32 wowl_cap;
s32 err; s32 err;
brcmf_feat_firmware_capabilities(ifp); brcmf_feat_firmware_capabilities(ifp);
memset(&gscan_cfg, 0, sizeof(gscan_cfg));
brcmf_feat_iovar_data_set(ifp, BRCMF_FEAT_GSCAN, "pfn_gscan_cfg",
&gscan_cfg, sizeof(gscan_cfg));
brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_PNO, "pfn"); brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_PNO, "pfn");
if (drvr->bus_if->wowl_supported) if (drvr->bus_if->wowl_supported)
brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_WOWL, "wowl"); brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_WOWL, "wowl");
......
...@@ -31,6 +31,7 @@ ...@@ -31,6 +31,7 @@
* WOWL_GTK: (WOWL) GTK rekeying offload * WOWL_GTK: (WOWL) GTK rekeying offload
* WOWL_ARP_ND: ARP and Neighbor Discovery offload support during WOWL. * WOWL_ARP_ND: ARP and Neighbor Discovery offload support during WOWL.
* MFP: 802.11w Management Frame Protection. * MFP: 802.11w Management Frame Protection.
* GSCAN: enhanced scan offload feature.
*/ */
#define BRCMF_FEAT_LIST \ #define BRCMF_FEAT_LIST \
BRCMF_FEAT_DEF(MBSS) \ BRCMF_FEAT_DEF(MBSS) \
...@@ -44,7 +45,8 @@ ...@@ -44,7 +45,8 @@
BRCMF_FEAT_DEF(WOWL_ND) \ BRCMF_FEAT_DEF(WOWL_ND) \
BRCMF_FEAT_DEF(WOWL_GTK) \ BRCMF_FEAT_DEF(WOWL_GTK) \
BRCMF_FEAT_DEF(WOWL_ARP_ND) \ BRCMF_FEAT_DEF(WOWL_ARP_ND) \
BRCMF_FEAT_DEF(MFP) BRCMF_FEAT_DEF(MFP) \
BRCMF_FEAT_DEF(GSCAN)
/* /*
* Quirks: * Quirks:
......
...@@ -835,4 +835,63 @@ struct brcmf_gtk_keyinfo_le { ...@@ -835,4 +835,63 @@ struct brcmf_gtk_keyinfo_le {
u8 replay_counter[BRCMF_RSN_REPLAY_LEN]; u8 replay_counter[BRCMF_RSN_REPLAY_LEN];
}; };
/**
* struct brcmf_gscan_bucket_config - configuration data for channel bucket.
*
* @bucket_end_index: !unknown!
* @bucket_freq_multiple: !unknown!
* @flag: !unknown!
* @reserved: !unknown!
* @repeat: !unknown!
* @max_freq_multiple: !unknown!
*/
struct brcmf_gscan_bucket_config {
u8 bucket_end_index;
u8 bucket_freq_multiple;
u8 flag;
u8 reserved;
__le16 repeat;
__le16 max_freq_multiple;
};
/* version supported which must match firmware */
#define BRCMF_GSCAN_CFG_VERSION 1
/**
* enum brcmf_gscan_cfg_flags - bit values for gscan flags.
*
* @BRCMF_GSCAN_CFG_FLAGS_ALL_RESULTS: send probe responses/beacons to host.
* @BRCMF_GSCAN_CFG_FLAGS_CHANGE_ONLY: indicated only flags member is changed.
*/
enum brcmf_gscan_cfg_flags {
BRCMF_GSCAN_CFG_FLAGS_ALL_RESULTS = BIT(0),
BRCMF_GSCAN_CFG_FLAGS_CHANGE_ONLY = BIT(7),
};
/**
* struct brcmf_gscan_config - configuration data for gscan.
*
* @version: version of the api to match firmware.
* @flags: flags according %enum brcmf_gscan_cfg_flags.
* @buffer_threshold: percentage threshold of buffer to generate an event.
* @swc_nbssid_threshold: number of BSSIDs with significant change that
* will generate an event.
* @swc_rssi_window_size: size of rssi cache buffer (max=8).
* @count_of_channel_buckets: number of array members in @bucket.
* @retry_threshold: !unknown!
* @lost_ap_window: !unknown!
* @bucket: array of channel buckets.
*/
struct brcmf_gscan_config {
__le16 version;
u8 flags;
u8 buffer_threshold;
u8 swc_nbssid_threshold;
u8 swc_rssi_window_size;
u8 count_of_channel_buckets;
u8 retry_threshold;
__le16 lost_ap_window;
struct brcmf_gscan_bucket_config bucket[1];
};
#endif /* FWIL_TYPES_H_ */ #endif /* FWIL_TYPES_H_ */
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