Skip to content

Commit ab266df

Browse files
committed
[brcmfmac] Structurize scan parameter handling
Signed-off-by: Daniel Berlin <[email protected]>
1 parent 790f0f3 commit ab266df

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
@@ -1098,170 +1098,13 @@ void brcmf_set_mpc(struct brcmf_if *ifp, int mpc)
10981098
}
10991099
}
11001100

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

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

12591103
s32 brcmf_notify_escan_complete(struct brcmf_cfg80211_info *cfg,
12601104
struct brcmf_if *ifp, bool aborted,
12611105
bool fw_abort)
12621106
{
12631107
struct brcmf_pub *drvr = cfg->pub;
1264-
struct brcmf_scan_params_v2_le params_v2_le;
12651108
struct cfg80211_scan_request *scan_request;
12661109
u64 reqid;
12671110
u32 bucket;
@@ -1278,25 +1121,16 @@ s32 brcmf_notify_escan_complete(struct brcmf_cfg80211_info *cfg,
12781121
del_timer_sync(&cfg->escan_timeout);
12791122

12801123
if (fw_abort) {
1124+
u32 len;
1125+
void *data = drvr->scan_param_handler.get_prepped_struct(cfg, &len, NULL);
1126+
if (!data){
1127+
bphy_err(drvr, "Scan abort failed to prepare abort struct\n");
1128+
return 0;
1129+
}
12811130
/* Do a scan abort to stop the driver's scan engine */
12821131
brcmf_dbg(SCAN, "ABORT scan in firmware\n");
1283-
1284-
brcmf_escan_prep(cfg, ifp, &params_v2_le, NULL);
1285-
1286-
/* E-Scan (or anyother type) can be aborted by SCAN */
1287-
if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_SCAN_V2)) {
1288-
err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SCAN,
1289-
&params_v2_le,
1290-
sizeof(params_v2_le));
1291-
} else {
1292-
struct brcmf_scan_params_le params_le;
1293-
1294-
brcmf_scan_params_v2_to_v1(&params_v2_le, &params_le);
1295-
err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SCAN,
1296-
&params_le,
1297-
sizeof(params_le));
1298-
}
1299-
1132+
err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SCAN, data, len);
1133+
kfree(data);
13001134
if (err)
13011135
bphy_err(drvr, "Scan abort failed\n");
13021136
}
@@ -1520,49 +1354,39 @@ brcmf_run_escan(struct brcmf_cfg80211_info *cfg, struct brcmf_if *ifp,
15201354
struct cfg80211_scan_request *request)
15211355
{
15221356
struct brcmf_pub *drvr = cfg->pub;
1523-
s32 params_size = BRCMF_SCAN_PARAMS_V2_FIXED_SIZE +
1524-
offsetof(struct brcmf_escan_params_le, params_v2_le);
1357+
u32 struct_size = 0;
1358+
void *prepped_params = NULL;
1359+
u32 params_size = 0;
15251360
struct brcmf_escan_params_le *params;
15261361
s32 err = 0;
15271362

15281363
brcmf_dbg(SCAN, "E-SCAN START\n");
15291364

1530-
if (request != NULL) {
1531-
/* Allocate space for populating ssids in struct */
1532-
params_size += sizeof(u32) * ((request->n_channels + 1) / 2);
1533-
1534-
/* Allocate space for populating ssids in struct */
1535-
params_size += sizeof(struct brcmf_ssid_le) * request->n_ssids;
1365+
prepped_params = drvr->scan_param_handler.get_prepped_struct(cfg, &struct_size, request);
1366+
if (!prepped_params) {
1367+
err = -EINVAL;
1368+
goto exit;
1369+
}
1370+
params_size = struct_size +
1371+
offsetof(struct brcmf_escan_params_le, params_v4_le);
1372+
if (!params_size) {
1373+
err = -EINVAL;
1374+
goto exit;
15361375
}
15371376

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

1387+
/* We can now free the original prepped parameters */
1388+
kfree(prepped_params);
1389+
params->version = cpu_to_le32(drvr->scan_param_handler.version);
15661390
params->action = cpu_to_le16(WL_ESCAN_ACTION_START);
15671391
params->sync_id = cpu_to_le16(0x1234);
15681392

@@ -1574,7 +1398,6 @@ brcmf_run_escan(struct brcmf_cfg80211_info *cfg, struct brcmf_if *ifp,
15741398
bphy_err(drvr, "error (%d)\n", err);
15751399
}
15761400

1577-
exit_params:
15781401
kfree(params);
15791402
exit:
15801403
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
@@ -16,6 +16,7 @@
1616
#include "feature.h"
1717
#include "common.h"
1818
#include "pno.h"
19+
#include "scan_param.h"
1920

2021
#define BRCMF_FW_UNSUPPORTED 23
2122

@@ -289,7 +290,7 @@ static int brcmf_feat_fwcap_debugfs_read(struct seq_file *seq, void *data)
289290
void brcmf_feat_attach(struct brcmf_pub *drvr)
290291
{
291292
struct brcmf_if *ifp = brcmf_get_ifp(drvr, 0);
292-
struct brcmf_wl_scan_version_le scan_ver;
293+
struct brcmf_scan_version_le scan_ver;
293294
struct brcmf_pno_param_v3_le pno_params;
294295
struct brcmf_pno_macaddr_le pfn_mac;
295296
struct brcmf_gscan_config gscan_cfg;
@@ -345,16 +346,11 @@ void brcmf_feat_attach(struct brcmf_pub *drvr)
345346

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

360356
/* 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,8 +30,6 @@
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
34-
* SCAN_v3: Version 3 scan params
3533
* PMKID_V2: Version 2 PMKID
3634
* PMKID_V3: Version 3 PMKID
3735
* EVENT_MSGS_EXT: Event messages extension
@@ -61,8 +59,6 @@
6159
BRCMF_FEAT_DEF(SAE) \
6260
BRCMF_FEAT_DEF(FWAUTH) \
6361
BRCMF_FEAT_DEF(DUMP_OBSS) \
64-
BRCMF_FEAT_DEF(SCAN_V2) \
65-
BRCMF_FEAT_DEF(SCAN_V3) \
6662
BRCMF_FEAT_DEF(PMKID_V2) \
6763
BRCMF_FEAT_DEF(PMKID_V3) \
6864
BRCMF_FEAT_DEF(EVENT_MSGS_EXT) \

0 commit comments

Comments
 (0)