Skip to content

Commit 220f7b3

Browse files
dberlinjannau
authored andcommitted
[brcmfmac] Structurize scan parameter handling
Signed-off-by: Daniel Berlin <dberlin@dberlin.org>
1 parent fe78d01 commit 220f7b3

8 files changed

Lines changed: 643 additions & 281 deletions

File tree

drivers/net/wireless/broadcom/brcm80211/brcmfmac/Makefile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,9 @@ brcmfmac-objs += \
2525
btcoex.o \
2626
vendor.o \
2727
pno.o \
28+
scan_param.o \
2829
xtlv.o
30+
2931
brcmfmac-$(CONFIG_BRCMFMAC_PROTO_BCDC) += \
3032
bcdc.o \
3133
fwsignal.o

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

Lines changed: 28 additions & 205 deletions
Original file line numberDiff line numberDiff line change
@@ -1102,170 +1102,13 @@ void brcmf_set_mpc(struct brcmf_if *ifp, int mpc)
11021102
}
11031103
}
11041104

1105-
static void brcmf_scan_params_v2_to_v1(struct brcmf_scan_params_v2_le *params_v2_le,
1106-
struct brcmf_scan_params_le *params_le)
1107-
{
1108-
size_t params_size;
1109-
u32 ch;
1110-
int n_channels, n_ssids;
1111-
1112-
memcpy(&params_le->ssid_le, &params_v2_le->ssid_le,
1113-
sizeof(params_le->ssid_le));
1114-
memcpy(&params_le->bssid, &params_v2_le->bssid,
1115-
sizeof(params_le->bssid));
1116-
1117-
params_le->bss_type = params_v2_le->bss_type;
1118-
params_le->scan_type = le32_to_cpu(params_v2_le->scan_type);
1119-
params_le->nprobes = params_v2_le->nprobes;
1120-
params_le->active_time = params_v2_le->active_time;
1121-
params_le->passive_time = params_v2_le->passive_time;
1122-
params_le->home_time = params_v2_le->home_time;
1123-
params_le->channel_num = params_v2_le->channel_num;
1124-
1125-
ch = le32_to_cpu(params_v2_le->channel_num);
1126-
n_channels = ch & BRCMF_SCAN_PARAMS_COUNT_MASK;
1127-
n_ssids = ch >> BRCMF_SCAN_PARAMS_NSSID_SHIFT;
1128-
1129-
params_size = sizeof(u16) * n_channels;
1130-
if (n_ssids > 0) {
1131-
params_size = roundup(params_size, sizeof(u32));
1132-
params_size += sizeof(struct brcmf_ssid_le) * n_ssids;
1133-
}
1134-
1135-
memcpy(&params_le->channel_list[0],
1136-
&params_v2_le->channel_list[0], params_size);
1137-
}
1138-
1139-
static u32 brcmf_nl80211_scan_flags_to_scan_flags(u32 nl80211_flags)
1140-
{
1141-
u32 scan_flags = 0;
1142-
if (nl80211_flags & NL80211_SCAN_FLAG_LOW_SPAN) {
1143-
scan_flags |= BRCMF_SCANFLAGS_LOW_SPAN;
1144-
brcmf_dbg(SCAN, "requested low span scan\n");
1145-
}
1146-
if (nl80211_flags & NL80211_SCAN_FLAG_HIGH_ACCURACY) {
1147-
scan_flags |= BRCMF_SCANFLAGS_HIGH_ACCURACY;
1148-
brcmf_dbg(SCAN, "requested high accuracy scan\n");
1149-
}
1150-
if (nl80211_flags & NL80211_SCAN_FLAG_LOW_POWER) {
1151-
scan_flags |= BRCMF_SCANFLAGS_LOW_POWER;
1152-
brcmf_dbg(SCAN, "requested low power scan\n");
1153-
}
1154-
if (nl80211_flags & NL80211_SCAN_FLAG_LOW_PRIORITY) {
1155-
scan_flags |= BRCMF_SCANFLAGS_LOW_PRIO;
1156-
brcmf_dbg(SCAN, "requested low priority scan\n");
1157-
}
1158-
return scan_flags;
1159-
}
1160-
1161-
static void brcmf_escan_prep(struct brcmf_cfg80211_info *cfg,
1162-
struct brcmf_if *ifp,
1163-
struct brcmf_scan_params_v2_le *params_le,
1164-
struct cfg80211_scan_request *request)
1165-
{
1166-
u32 n_ssids;
1167-
u32 n_channels;
1168-
s32 i;
1169-
s32 offset;
1170-
u16 chanspec;
1171-
char *ptr;
1172-
int length;
1173-
struct brcmf_ssid_le ssid_le;
1174-
u32 scan_type = BRCMF_SCANTYPE_ACTIVE;
1175-
1176-
eth_broadcast_addr(params_le->bssid);
1177-
1178-
length = BRCMF_SCAN_PARAMS_V2_FIXED_SIZE;
1179-
1180-
if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_SCAN_V3))
1181-
params_le->version = cpu_to_le16(BRCMF_SCAN_PARAMS_VERSION_V3);
1182-
else
1183-
params_le->version = cpu_to_le16(BRCMF_SCAN_PARAMS_VERSION_V2);
1184-
1185-
params_le->bss_type = DOT11_BSSTYPE_ANY;
1186-
params_le->ssid_type = 0;
1187-
params_le->channel_num = 0;
1188-
params_le->nprobes = cpu_to_le32(-1);
1189-
params_le->active_time = cpu_to_le32(-1);
1190-
params_le->passive_time = cpu_to_le32(-1);
1191-
params_le->home_time = cpu_to_le32(-1);
1192-
memset(&params_le->ssid_le, 0, sizeof(params_le->ssid_le));
1193-
1194-
/* Scan abort */
1195-
if (!request) {
1196-
length += sizeof(u16);
1197-
params_le->channel_num = cpu_to_le32(1);
1198-
params_le->channel_list[0] = cpu_to_le16(-1);
1199-
params_le->length = cpu_to_le16(length);
1200-
return;
1201-
}
1202-
1203-
n_ssids = request->n_ssids;
1204-
n_channels = request->n_channels;
1205-
1206-
/* Copy channel array if applicable */
1207-
brcmf_dbg(SCAN, "### List of channelspecs to scan ### %d\n",
1208-
n_channels);
1209-
if (n_channels > 0) {
1210-
length += roundup(sizeof(u16) * n_channels, sizeof(u32));
1211-
for (i = 0; i < n_channels; i++) {
1212-
chanspec = channel_to_chanspec(&cfg->d11inf,
1213-
request->channels[i]);
1214-
brcmf_dbg(SCAN, "Chan : %d, Channel spec: %x\n",
1215-
request->channels[i]->hw_value, chanspec);
1216-
params_le->channel_list[i] = cpu_to_le16(chanspec);
1217-
}
1218-
} else {
1219-
brcmf_dbg(SCAN, "Scanning all channels\n");
1220-
}
1221-
1222-
/* Copy ssid array if applicable */
1223-
brcmf_dbg(SCAN, "### List of SSIDs to scan ### %d\n", n_ssids);
1224-
if (n_ssids > 0) {
1225-
offset = offsetof(struct brcmf_scan_params_v2_le, channel_list) +
1226-
n_channels * sizeof(u16);
1227-
offset = roundup(offset, sizeof(u32));
1228-
length += sizeof(ssid_le) * n_ssids;
1229-
ptr = (char *)params_le + offset;
1230-
for (i = 0; i < n_ssids; i++) {
1231-
memset(&ssid_le, 0, sizeof(ssid_le));
1232-
ssid_le.SSID_len =
1233-
cpu_to_le32(request->ssids[i].ssid_len);
1234-
memcpy(ssid_le.SSID, request->ssids[i].ssid,
1235-
request->ssids[i].ssid_len);
1236-
if (!ssid_le.SSID_len)
1237-
brcmf_dbg(SCAN, "%d: Broadcast scan\n", i);
1238-
else
1239-
brcmf_dbg(SCAN, "%d: scan for %.32s size=%d\n",
1240-
i, ssid_le.SSID, ssid_le.SSID_len);
1241-
memcpy(ptr, &ssid_le, sizeof(ssid_le));
1242-
ptr += sizeof(ssid_le);
1243-
}
1244-
} else {
1245-
brcmf_dbg(SCAN, "Performing passive scan\n");
1246-
scan_type = BRCMF_SCANTYPE_PASSIVE;
1247-
}
1248-
scan_type |= brcmf_nl80211_scan_flags_to_scan_flags(request->flags);
1249-
params_le->scan_type = cpu_to_le32(scan_type);
1250-
params_le->length = cpu_to_le16(length);
12511105

1252-
/* Include RNR results if requested */
1253-
if (request->flags & NL80211_SCAN_FLAG_COLOCATED_6GHZ) {
1254-
params_le->ssid_type |= BRCMF_SCANSSID_INC_RNR;
1255-
}
1256-
1257-
/* Adding mask to channel numbers */
1258-
params_le->channel_num =
1259-
cpu_to_le32((n_ssids << BRCMF_SCAN_PARAMS_NSSID_SHIFT) |
1260-
(n_channels & BRCMF_SCAN_PARAMS_COUNT_MASK));
1261-
}
12621106

12631107
s32 brcmf_notify_escan_complete(struct brcmf_cfg80211_info *cfg,
12641108
struct brcmf_if *ifp, bool aborted,
12651109
bool fw_abort)
12661110
{
12671111
struct brcmf_pub *drvr = cfg->pub;
1268-
struct brcmf_scan_params_v2_le params_v2_le;
12691112
struct cfg80211_scan_request *scan_request;
12701113
u64 reqid;
12711114
u32 bucket;
@@ -1281,25 +1124,16 @@ s32 brcmf_notify_escan_complete(struct brcmf_cfg80211_info *cfg,
12811124
timer_delete_sync(&cfg->escan_timeout);
12821125

12831126
if (fw_abort) {
1127+
u32 len;
1128+
void *data = drvr->scan_param_handler.get_prepped_struct(cfg, &len, NULL);
1129+
if (!data){
1130+
bphy_err(drvr, "Scan abort failed to prepare abort struct\n");
1131+
return 0;
1132+
}
12841133
/* Do a scan abort to stop the driver's scan engine */
12851134
brcmf_dbg(SCAN, "ABORT scan in firmware\n");
1286-
1287-
brcmf_escan_prep(cfg, ifp, &params_v2_le, NULL);
1288-
1289-
/* E-Scan (or anyother type) can be aborted by SCAN */
1290-
if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_SCAN_V2)) {
1291-
err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SCAN,
1292-
&params_v2_le,
1293-
sizeof(params_v2_le));
1294-
} else {
1295-
struct brcmf_scan_params_le params_le;
1296-
1297-
brcmf_scan_params_v2_to_v1(&params_v2_le, &params_le);
1298-
err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SCAN,
1299-
&params_le,
1300-
sizeof(params_le));
1301-
}
1302-
1135+
err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SCAN, data, len);
1136+
kfree(data);
13031137
if (err)
13041138
bphy_err(drvr, "Scan abort failed\n");
13051139
}
@@ -1523,49 +1357,39 @@ brcmf_run_escan(struct brcmf_cfg80211_info *cfg, struct brcmf_if *ifp,
15231357
struct cfg80211_scan_request *request)
15241358
{
15251359
struct brcmf_pub *drvr = cfg->pub;
1526-
s32 params_size = BRCMF_SCAN_PARAMS_V2_FIXED_SIZE +
1527-
offsetof(struct brcmf_escan_params_le, params_v2_le);
1360+
u32 struct_size = 0;
1361+
void *prepped_params = NULL;
1362+
u32 params_size = 0;
15281363
struct brcmf_escan_params_le *params;
15291364
s32 err = 0;
15301365

15311366
brcmf_dbg(SCAN, "E-SCAN START\n");
15321367

1533-
if (request != NULL) {
1534-
/* Allocate space for populating ssids in struct */
1535-
params_size += sizeof(u32) * ((request->n_channels + 1) / 2);
1536-
1537-
/* Allocate space for populating ssids in struct */
1538-
params_size += sizeof(struct brcmf_ssid_le) * request->n_ssids;
1368+
prepped_params = drvr->scan_param_handler.get_prepped_struct(cfg, &struct_size, request);
1369+
if (!prepped_params) {
1370+
err = -EINVAL;
1371+
goto exit;
1372+
}
1373+
params_size = struct_size +
1374+
offsetof(struct brcmf_escan_params_le, params_v4_le);
1375+
if (!params_size) {
1376+
err = -EINVAL;
1377+
goto exit;
15391378
}
15401379

15411380
params = kzalloc(params_size, GFP_KERNEL);
15421381
if (!params) {
15431382
err = -ENOMEM;
15441383
goto exit;
15451384
}
1546-
BUG_ON(params_size + sizeof("escan") >= BRCMF_DCMD_MEDLEN);
1547-
brcmf_escan_prep(cfg, ifp, &params->params_v2_le, request);
1548-
1549-
if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_SCAN_V3)) {
1550-
params->version = cpu_to_le32(BRCMF_ESCAN_REQ_VERSION_V3);
1551-
} else if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_SCAN_V2)) {
1552-
params->version = cpu_to_le32(BRCMF_ESCAN_REQ_VERSION_V2);
1553-
} else {
1554-
struct brcmf_escan_params_le *params_v1;
1555-
1556-
params_size -= BRCMF_SCAN_PARAMS_V2_FIXED_SIZE;
1557-
params_size += BRCMF_SCAN_PARAMS_FIXED_SIZE;
1558-
params_v1 = kzalloc(params_size, GFP_KERNEL);
1559-
if (!params_v1) {
1560-
err = -ENOMEM;
1561-
goto exit_params;
1562-
}
1563-
params_v1->version = cpu_to_le32(BRCMF_ESCAN_REQ_VERSION);
1564-
brcmf_scan_params_v2_to_v1(&params->params_v2_le, &params_v1->params_le);
1565-
kfree(params);
1566-
params = params_v1;
1567-
}
1385+
/* Copy into the largest part */
1386+
unsafe_memcpy(
1387+
&params->params_v4_le, prepped_params, struct_size,
1388+
/* A composite flex-array that is at least as large as the memcpy due to the allocation above */);
15681389

1390+
/* We can now free the original prepped parameters */
1391+
kfree(prepped_params);
1392+
params->version = cpu_to_le32(drvr->scan_param_handler.version);
15691393
params->action = cpu_to_le16(WL_ESCAN_ACTION_START);
15701394
params->sync_id = cpu_to_le16(0x1234);
15711395

@@ -1577,7 +1401,6 @@ brcmf_run_escan(struct brcmf_cfg80211_info *cfg, struct brcmf_if *ifp,
15771401
bphy_err(drvr, "error (%d)\n", err);
15781402
}
15791403

1580-
exit_params:
15811404
kfree(params);
15821405
exit:
15831406
return err;

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

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ struct brcmf_rev_info {
9898
};
9999

100100
struct brcmf_pno_info;
101+
enum nl80211_band;
101102
/**
102103
* struct pno_struct_handler
103104
*/
@@ -114,6 +115,13 @@ struct pno_struct_handler {
114115
u8 (*ssid)[IEEE80211_MAX_SSID_LEN], u8 *ssid_len,
115116
u8 *channel, enum nl80211_band *band);
116117
};
118+
struct cfg80211_scan_request;
119+
struct scan_param_struct_handler {
120+
u8 version;
121+
void *(*get_prepped_struct)(struct brcmf_cfg80211_info *cfg,
122+
u32 *struct_size,
123+
struct cfg80211_scan_request *request);
124+
};
117125

118126
/* Common structure for module and instance linkage */
119127
struct brcmf_pub {
@@ -165,6 +173,7 @@ struct brcmf_pub {
165173
void *vdata;
166174
u16 cnt_ver;
167175
struct pno_struct_handler pno_handler;
176+
struct scan_param_struct_handler scan_param_handler;
168177
};
169178

170179
/* forward declarations */

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

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include "feature.h"
1818
#include "common.h"
1919
#include "pno.h"
20+
#include "scan_param.h"
2021

2122
#define BRCMF_FW_UNSUPPORTED 23
2223

@@ -291,7 +292,7 @@ static int brcmf_feat_fwcap_debugfs_read(struct seq_file *seq, void *data)
291292
void brcmf_feat_attach(struct brcmf_pub *drvr)
292293
{
293294
struct brcmf_if *ifp = brcmf_get_ifp(drvr, 0);
294-
struct brcmf_wl_scan_version_le scan_ver;
295+
struct brcmf_scan_version_le scan_ver;
295296
struct brcmf_pno_param_v3_le pno_params;
296297
struct brcmf_pno_macaddr_le pfn_mac;
297298
struct brcmf_gscan_config gscan_cfg;
@@ -347,16 +348,11 @@ void brcmf_feat_attach(struct brcmf_pub *drvr)
347348

348349
err = brcmf_fil_iovar_data_get(ifp, "scan_ver", &scan_ver, sizeof(scan_ver));
349350
if (!err) {
350-
int ver = le16_to_cpu(scan_ver.scan_ver_major);
351-
352-
if (ver == 2) {
353-
ifp->drvr->feat_flags |= BIT(BRCMF_FEAT_SCAN_V2);
354-
} else if (ver == 3) {
355-
/* We consider SCAN_V3 a subtype of SCAN_V2 since the
356-
* structure is essentially the same.
357-
*/
358-
ifp->drvr->feat_flags |= BIT(BRCMF_FEAT_SCAN_V2) | BIT(BRCMF_FEAT_SCAN_V3);
359-
}
351+
u16 ver = le16_to_cpu(scan_ver.scan_ver_major);
352+
brcmf_scan_param_setup_for_version(drvr, ver);
353+
} else {
354+
/* Default tp version 1. */
355+
brcmf_scan_param_setup_for_version(drvr, 1);
360356
}
361357

362358
/* See what version of PFN scan is supported*/

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

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,7 @@
3030
* SAE: simultaneous authentication of equals
3131
* FWAUTH: Firmware authenticator
3232
* DUMP_OBSS: Firmware has capable to dump obss info to support ACS
33-
* SCAN_V2: Version 2 scan params
3433
* SAE_EXT: SAE authentication handled by user-space supplicant
35-
* SCAN_v3: Version 3 scan params
3634
* PMKID_V2: Version 2 PMKID
3735
* PMKID_V3: Version 3 PMKID
3836
* EVENT_MSGS_EXT: Event messages extension
@@ -62,8 +60,6 @@
6260
BRCMF_FEAT_DEF(SAE) \
6361
BRCMF_FEAT_DEF(FWAUTH) \
6462
BRCMF_FEAT_DEF(DUMP_OBSS) \
65-
BRCMF_FEAT_DEF(SCAN_V2) \
66-
BRCMF_FEAT_DEF(SCAN_V3) \
6763
BRCMF_FEAT_DEF(PMKID_V2) \
6864
BRCMF_FEAT_DEF(PMKID_V3) \
6965
BRCMF_FEAT_DEF(SAE_EXT) \

0 commit comments

Comments
 (0)