Skip to content

Commit 9fe929a

Browse files
Arend van SprielKalle Valo
authored andcommitted
brcmfmac: add firmware feature detection for gscan feature
Detect gscan support in firmware by doing pfn_gscan_cfg iovar with invalid version. Reviewed-by: Hante Meuleman <[email protected]> Reviewed-by: Pieter-Paul Giesberts <[email protected]> Reviewed-by: Franky Lin <[email protected]> Signed-off-by: Arend van Spriel <[email protected]> Signed-off-by: Kalle Valo <[email protected]>
1 parent a95cfad commit 9fe929a

File tree

3 files changed

+83
-2
lines changed

3 files changed

+83
-2
lines changed

drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#include "feature.h"
2828
#include "common.h"
2929

30+
#define BRCMF_FW_UNSUPPORTED 23
3031

3132
/*
3233
* expand feature list to array of feature strings.
@@ -113,6 +114,22 @@ static void brcmf_feat_iovar_int_get(struct brcmf_if *ifp,
113114
}
114115
}
115116

117+
static void brcmf_feat_iovar_data_set(struct brcmf_if *ifp,
118+
enum brcmf_feat_id id, char *name,
119+
const void *data, size_t len)
120+
{
121+
int err;
122+
123+
err = brcmf_fil_iovar_data_set(ifp, name, data, len);
124+
if (err != -BRCMF_FW_UNSUPPORTED) {
125+
brcmf_dbg(INFO, "enabling feature: %s\n", brcmf_feat_names[id]);
126+
ifp->drvr->feat_flags |= BIT(id);
127+
} else {
128+
brcmf_dbg(TRACE, "%s feature check failed: %d\n",
129+
brcmf_feat_names[id], err);
130+
}
131+
}
132+
116133
static void brcmf_feat_firmware_capabilities(struct brcmf_if *ifp)
117134
{
118135
char caps[256];
@@ -136,11 +153,14 @@ void brcmf_feat_attach(struct brcmf_pub *drvr)
136153
{
137154
struct brcmf_if *ifp = brcmf_get_ifp(drvr, 0);
138155
struct brcmf_pno_macaddr_le pfn_mac;
156+
struct brcmf_gscan_config gscan_cfg;
139157
u32 wowl_cap;
140158
s32 err;
141159

142160
brcmf_feat_firmware_capabilities(ifp);
143-
161+
memset(&gscan_cfg, 0, sizeof(gscan_cfg));
162+
brcmf_feat_iovar_data_set(ifp, BRCMF_FEAT_GSCAN, "pfn_gscan_cfg",
163+
&gscan_cfg, sizeof(gscan_cfg));
144164
brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_PNO, "pfn");
145165
if (drvr->bus_if->wowl_supported)
146166
brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_WOWL, "wowl");

drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
* WOWL_GTK: (WOWL) GTK rekeying offload
3232
* WOWL_ARP_ND: ARP and Neighbor Discovery offload support during WOWL.
3333
* MFP: 802.11w Management Frame Protection.
34+
* GSCAN: enhanced scan offload feature.
3435
*/
3536
#define BRCMF_FEAT_LIST \
3637
BRCMF_FEAT_DEF(MBSS) \
@@ -44,7 +45,8 @@
4445
BRCMF_FEAT_DEF(WOWL_ND) \
4546
BRCMF_FEAT_DEF(WOWL_GTK) \
4647
BRCMF_FEAT_DEF(WOWL_ARP_ND) \
47-
BRCMF_FEAT_DEF(MFP)
48+
BRCMF_FEAT_DEF(MFP) \
49+
BRCMF_FEAT_DEF(GSCAN)
4850

4951
/*
5052
* Quirks:

drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -835,4 +835,63 @@ struct brcmf_gtk_keyinfo_le {
835835
u8 replay_counter[BRCMF_RSN_REPLAY_LEN];
836836
};
837837

838+
/**
839+
* struct brcmf_gscan_bucket_config - configuration data for channel bucket.
840+
*
841+
* @bucket_end_index: !unknown!
842+
* @bucket_freq_multiple: !unknown!
843+
* @flag: !unknown!
844+
* @reserved: !unknown!
845+
* @repeat: !unknown!
846+
* @max_freq_multiple: !unknown!
847+
*/
848+
struct brcmf_gscan_bucket_config {
849+
u8 bucket_end_index;
850+
u8 bucket_freq_multiple;
851+
u8 flag;
852+
u8 reserved;
853+
__le16 repeat;
854+
__le16 max_freq_multiple;
855+
};
856+
857+
/* version supported which must match firmware */
858+
#define BRCMF_GSCAN_CFG_VERSION 1
859+
860+
/**
861+
* enum brcmf_gscan_cfg_flags - bit values for gscan flags.
862+
*
863+
* @BRCMF_GSCAN_CFG_FLAGS_ALL_RESULTS: send probe responses/beacons to host.
864+
* @BRCMF_GSCAN_CFG_FLAGS_CHANGE_ONLY: indicated only flags member is changed.
865+
*/
866+
enum brcmf_gscan_cfg_flags {
867+
BRCMF_GSCAN_CFG_FLAGS_ALL_RESULTS = BIT(0),
868+
BRCMF_GSCAN_CFG_FLAGS_CHANGE_ONLY = BIT(7),
869+
};
870+
871+
/**
872+
* struct brcmf_gscan_config - configuration data for gscan.
873+
*
874+
* @version: version of the api to match firmware.
875+
* @flags: flags according %enum brcmf_gscan_cfg_flags.
876+
* @buffer_threshold: percentage threshold of buffer to generate an event.
877+
* @swc_nbssid_threshold: number of BSSIDs with significant change that
878+
* will generate an event.
879+
* @swc_rssi_window_size: size of rssi cache buffer (max=8).
880+
* @count_of_channel_buckets: number of array members in @bucket.
881+
* @retry_threshold: !unknown!
882+
* @lost_ap_window: !unknown!
883+
* @bucket: array of channel buckets.
884+
*/
885+
struct brcmf_gscan_config {
886+
__le16 version;
887+
u8 flags;
888+
u8 buffer_threshold;
889+
u8 swc_nbssid_threshold;
890+
u8 swc_rssi_window_size;
891+
u8 count_of_channel_buckets;
892+
u8 retry_threshold;
893+
__le16 lost_ap_window;
894+
struct brcmf_gscan_bucket_config bucket[1];
895+
};
896+
838897
#endif /* FWIL_TYPES_H_ */

0 commit comments

Comments
 (0)