Skip to content

Commit 1d84867

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

8 files changed

Lines changed: 643 additions & 283 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 & 207 deletions
Original file line numberDiff line numberDiff line change
@@ -1117,170 +1117,11 @@ bool brcmf_is_apmode_operating(struct wiphy *wiphy)
11171117
return ret;
11181118
}
11191119

1120-
static void brcmf_scan_params_v2_to_v1(struct brcmf_scan_params_v2_le *params_v2_le,
1121-
struct brcmf_scan_params_le *params_le)
1122-
{
1123-
size_t params_size;
1124-
u32 ch;
1125-
int n_channels, n_ssids;
1126-
1127-
memcpy(&params_le->ssid_le, &params_v2_le->ssid_le,
1128-
sizeof(params_le->ssid_le));
1129-
memcpy(&params_le->bssid, &params_v2_le->bssid,
1130-
sizeof(params_le->bssid));
1131-
1132-
params_le->bss_type = params_v2_le->bss_type;
1133-
params_le->scan_type = le32_to_cpu(params_v2_le->scan_type);
1134-
params_le->nprobes = params_v2_le->nprobes;
1135-
params_le->active_time = params_v2_le->active_time;
1136-
params_le->passive_time = params_v2_le->passive_time;
1137-
params_le->home_time = params_v2_le->home_time;
1138-
params_le->channel_num = params_v2_le->channel_num;
1139-
1140-
ch = le32_to_cpu(params_v2_le->channel_num);
1141-
n_channels = ch & BRCMF_SCAN_PARAMS_COUNT_MASK;
1142-
n_ssids = ch >> BRCMF_SCAN_PARAMS_NSSID_SHIFT;
1143-
1144-
params_size = sizeof(u16) * n_channels;
1145-
if (n_ssids > 0) {
1146-
params_size = roundup(params_size, sizeof(u32));
1147-
params_size += sizeof(struct brcmf_ssid_le) * n_ssids;
1148-
}
1149-
1150-
memcpy(&params_le->channel_list[0],
1151-
&params_v2_le->channel_list[0], params_size);
1152-
}
1153-
1154-
static u32 brcmf_nl80211_scan_flags_to_scan_flags(u32 nl80211_flags)
1155-
{
1156-
u32 scan_flags = 0;
1157-
if (nl80211_flags & NL80211_SCAN_FLAG_LOW_SPAN) {
1158-
scan_flags |= BRCMF_SCANFLAGS_LOW_SPAN;
1159-
brcmf_dbg(SCAN, "requested low span scan\n");
1160-
}
1161-
if (nl80211_flags & NL80211_SCAN_FLAG_HIGH_ACCURACY) {
1162-
scan_flags |= BRCMF_SCANFLAGS_HIGH_ACCURACY;
1163-
brcmf_dbg(SCAN, "requested high accuracy scan\n");
1164-
}
1165-
if (nl80211_flags & NL80211_SCAN_FLAG_LOW_POWER) {
1166-
scan_flags |= BRCMF_SCANFLAGS_LOW_POWER;
1167-
brcmf_dbg(SCAN, "requested low power scan\n");
1168-
}
1169-
if (nl80211_flags & NL80211_SCAN_FLAG_LOW_PRIORITY) {
1170-
scan_flags |= BRCMF_SCANFLAGS_LOW_PRIO;
1171-
brcmf_dbg(SCAN, "requested low priority scan\n");
1172-
}
1173-
return scan_flags;
1174-
}
1175-
1176-
static void brcmf_escan_prep(struct brcmf_cfg80211_info *cfg,
1177-
struct brcmf_if *ifp,
1178-
struct brcmf_scan_params_v2_le *params_le,
1179-
struct cfg80211_scan_request *request)
1180-
{
1181-
u32 n_ssids;
1182-
u32 n_channels;
1183-
s32 i;
1184-
s32 offset;
1185-
u16 chanspec;
1186-
char *ptr;
1187-
int length;
1188-
struct brcmf_ssid_le ssid_le;
1189-
u32 scan_type = BRCMF_SCANTYPE_ACTIVE;
1190-
1191-
eth_broadcast_addr(params_le->bssid);
1192-
1193-
length = BRCMF_SCAN_PARAMS_V2_FIXED_SIZE;
1194-
1195-
if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_SCAN_V3))
1196-
params_le->version = cpu_to_le16(BRCMF_SCAN_PARAMS_VERSION_V3);
1197-
else
1198-
params_le->version = cpu_to_le16(BRCMF_SCAN_PARAMS_VERSION_V2);
1199-
1200-
params_le->bss_type = DOT11_BSSTYPE_ANY;
1201-
params_le->ssid_type = 0;
1202-
params_le->channel_num = 0;
1203-
params_le->nprobes = cpu_to_le32(-1);
1204-
params_le->active_time = cpu_to_le32(-1);
1205-
params_le->passive_time = cpu_to_le32(-1);
1206-
params_le->home_time = cpu_to_le32(-1);
1207-
memset(&params_le->ssid_le, 0, sizeof(params_le->ssid_le));
1208-
1209-
/* Scan abort */
1210-
if (!request) {
1211-
length += sizeof(u16);
1212-
params_le->channel_num = cpu_to_le32(1);
1213-
params_le->channel_list[0] = cpu_to_le16(-1);
1214-
params_le->length = cpu_to_le16(length);
1215-
return;
1216-
}
1217-
1218-
n_ssids = request->n_ssids;
1219-
n_channels = request->n_channels;
1220-
1221-
/* Copy channel array if applicable */
1222-
brcmf_dbg(SCAN, "### List of channelspecs to scan ### %d\n",
1223-
n_channels);
1224-
if (n_channels > 0) {
1225-
length += roundup(sizeof(u16) * n_channels, sizeof(u32));
1226-
for (i = 0; i < n_channels; i++) {
1227-
chanspec = channel_to_chanspec(&cfg->d11inf,
1228-
request->channels[i]);
1229-
brcmf_dbg(SCAN, "Chan : %d, Channel spec: %x\n",
1230-
request->channels[i]->hw_value, chanspec);
1231-
params_le->channel_list[i] = cpu_to_le16(chanspec);
1232-
}
1233-
} else {
1234-
brcmf_dbg(SCAN, "Scanning all channels\n");
1235-
}
1236-
1237-
/* Copy ssid array if applicable */
1238-
brcmf_dbg(SCAN, "### List of SSIDs to scan ### %d\n", n_ssids);
1239-
if (n_ssids > 0) {
1240-
offset = offsetof(struct brcmf_scan_params_v2_le, channel_list) +
1241-
n_channels * sizeof(u16);
1242-
offset = roundup(offset, sizeof(u32));
1243-
length += sizeof(ssid_le) * n_ssids;
1244-
ptr = (char *)params_le + offset;
1245-
for (i = 0; i < n_ssids; i++) {
1246-
memset(&ssid_le, 0, sizeof(ssid_le));
1247-
ssid_le.SSID_len =
1248-
cpu_to_le32(request->ssids[i].ssid_len);
1249-
memcpy(ssid_le.SSID, request->ssids[i].ssid,
1250-
request->ssids[i].ssid_len);
1251-
if (!ssid_le.SSID_len)
1252-
brcmf_dbg(SCAN, "%d: Broadcast scan\n", i);
1253-
else
1254-
brcmf_dbg(SCAN, "%d: scan for %.32s size=%d\n",
1255-
i, ssid_le.SSID, ssid_le.SSID_len);
1256-
memcpy(ptr, &ssid_le, sizeof(ssid_le));
1257-
ptr += sizeof(ssid_le);
1258-
}
1259-
} else {
1260-
brcmf_dbg(SCAN, "Performing passive scan\n");
1261-
scan_type = BRCMF_SCANTYPE_PASSIVE;
1262-
}
1263-
scan_type |= brcmf_nl80211_scan_flags_to_scan_flags(request->flags);
1264-
params_le->scan_type = cpu_to_le32(scan_type);
1265-
params_le->length = cpu_to_le16(length);
1266-
1267-
/* Include RNR results if requested */
1268-
if (request->flags & NL80211_SCAN_FLAG_COLOCATED_6GHZ) {
1269-
params_le->ssid_type |= BRCMF_SCANSSID_INC_RNR;
1270-
}
1271-
1272-
/* Adding mask to channel numbers */
1273-
params_le->channel_num =
1274-
cpu_to_le32((n_ssids << BRCMF_SCAN_PARAMS_NSSID_SHIFT) |
1275-
(n_channels & BRCMF_SCAN_PARAMS_COUNT_MASK));
1276-
}
1277-
12781120
s32 brcmf_notify_escan_complete(struct brcmf_cfg80211_info *cfg,
12791121
struct brcmf_if *ifp, bool aborted,
12801122
bool fw_abort)
12811123
{
12821124
struct brcmf_pub *drvr = cfg->pub;
1283-
struct brcmf_scan_params_v2_le params_v2_le;
12841125
struct cfg80211_scan_request *scan_request;
12851126
u64 reqid;
12861127
u32 bucket;
@@ -1296,25 +1137,16 @@ s32 brcmf_notify_escan_complete(struct brcmf_cfg80211_info *cfg,
12961137
timer_delete_sync(&cfg->escan_timeout);
12971138

12981139
if (fw_abort) {
1140+
u32 len;
1141+
void *data = drvr->scan_param_handler.get_prepped_struct(cfg, &len, NULL);
1142+
if (!data){
1143+
bphy_err(drvr, "Scan abort failed to prepare abort struct\n");
1144+
return 0;
1145+
}
12991146
/* Do a scan abort to stop the driver's scan engine */
13001147
brcmf_dbg(SCAN, "ABORT scan in firmware\n");
1301-
1302-
brcmf_escan_prep(cfg, ifp, &params_v2_le, NULL);
1303-
1304-
/* E-Scan (or anyother type) can be aborted by SCAN */
1305-
if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_SCAN_V2)) {
1306-
err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SCAN,
1307-
&params_v2_le,
1308-
sizeof(params_v2_le));
1309-
} else {
1310-
struct brcmf_scan_params_le params_le;
1311-
1312-
brcmf_scan_params_v2_to_v1(&params_v2_le, &params_le);
1313-
err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SCAN,
1314-
&params_le,
1315-
sizeof(params_le));
1316-
}
1317-
1148+
err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SCAN, data, len);
1149+
kfree(data);
13181150
if (err)
13191151
bphy_err(drvr, "Scan abort failed\n");
13201152
}
@@ -1538,49 +1370,39 @@ brcmf_run_escan(struct brcmf_cfg80211_info *cfg, struct brcmf_if *ifp,
15381370
struct cfg80211_scan_request *request)
15391371
{
15401372
struct brcmf_pub *drvr = cfg->pub;
1541-
s32 params_size = BRCMF_SCAN_PARAMS_V2_FIXED_SIZE +
1542-
offsetof(struct brcmf_escan_params_le, params_v2_le);
1373+
u32 struct_size = 0;
1374+
void *prepped_params = NULL;
1375+
u32 params_size = 0;
15431376
struct brcmf_escan_params_le *params;
15441377
s32 err = 0;
15451378

15461379
brcmf_dbg(SCAN, "E-SCAN START\n");
15471380

1548-
if (request != NULL) {
1549-
/* Allocate space for populating ssids in struct */
1550-
params_size += sizeof(u32) * ((request->n_channels + 1) / 2);
1551-
1552-
/* Allocate space for populating ssids in struct */
1553-
params_size += sizeof(struct brcmf_ssid_le) * request->n_ssids;
1381+
prepped_params = drvr->scan_param_handler.get_prepped_struct(cfg, &struct_size, request);
1382+
if (!prepped_params) {
1383+
err = -EINVAL;
1384+
goto exit;
1385+
}
1386+
params_size = struct_size +
1387+
offsetof(struct brcmf_escan_params_le, params_v4_le);
1388+
if (!params_size) {
1389+
err = -EINVAL;
1390+
goto exit;
15541391
}
15551392

15561393
params = kzalloc(params_size, GFP_KERNEL);
15571394
if (!params) {
15581395
err = -ENOMEM;
15591396
goto exit;
15601397
}
1561-
BUG_ON(params_size + sizeof("escan") >= BRCMF_DCMD_MEDLEN);
1562-
brcmf_escan_prep(cfg, ifp, &params->params_v2_le, request);
1563-
1564-
if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_SCAN_V3)) {
1565-
params->version = cpu_to_le32(BRCMF_ESCAN_REQ_VERSION_V3);
1566-
} else if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_SCAN_V2)) {
1567-
params->version = cpu_to_le32(BRCMF_ESCAN_REQ_VERSION_V2);
1568-
} else {
1569-
struct brcmf_escan_params_le *params_v1;
1570-
1571-
params_size -= BRCMF_SCAN_PARAMS_V2_FIXED_SIZE;
1572-
params_size += BRCMF_SCAN_PARAMS_FIXED_SIZE;
1573-
params_v1 = kzalloc(params_size, GFP_KERNEL);
1574-
if (!params_v1) {
1575-
err = -ENOMEM;
1576-
goto exit_params;
1577-
}
1578-
params_v1->version = cpu_to_le32(BRCMF_ESCAN_REQ_VERSION);
1579-
brcmf_scan_params_v2_to_v1(&params->params_v2_le, &params_v1->params_le);
1580-
kfree(params);
1581-
params = params_v1;
1582-
}
1398+
/* Copy into the largest part */
1399+
unsafe_memcpy(
1400+
&params->params_v4_le, prepped_params, struct_size,
1401+
/* A composite flex-array that is at least as large as the memcpy due to the allocation above */);
15831402

1403+
/* We can now free the original prepped parameters */
1404+
kfree(prepped_params);
1405+
params->version = cpu_to_le32(drvr->scan_param_handler.version);
15841406
params->action = cpu_to_le16(WL_ESCAN_ACTION_START);
15851407
params->sync_id = cpu_to_le16(0x1234);
15861408

@@ -1592,7 +1414,6 @@ brcmf_run_escan(struct brcmf_cfg80211_info *cfg, struct brcmf_if *ifp,
15921414
bphy_err(drvr, "error (%d)\n", err);
15931415
}
15941416

1595-
exit_params:
15961417
kfree(params);
15971418
exit:
15981419
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)