Skip to content

Commit 289c1cd

Browse files
committed
brcmfmac: cfg80211: Add support for PMKID_V3 operations
Add support for the new PMKID_V3 API, which allows performing PMKID mutations individually, instead of requiring the driver to keep track of the full list. This new API is required by at least BCM4387. Note that PMKID_V2 is not implemented yet. Reviewed-by: Linus Walleij <linus.walleij@linaro.org> Signed-off-by: Hector Martin <marcan@marcan.st>
1 parent 9c95ca3 commit 289c1cd

2 files changed

Lines changed: 132 additions & 3 deletions

File tree

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

Lines changed: 49 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4310,6 +4310,37 @@ static s32 brcmf_cfg80211_suspend(struct wiphy *wiphy,
43104310
return 0;
43114311
}
43124312

4313+
static s32
4314+
brcmf_pmksa_v3_op(struct brcmf_if *ifp, struct cfg80211_pmksa *pmksa,
4315+
bool alive)
4316+
{
4317+
struct brcmf_pmk_op_v3_le *pmk_op;
4318+
int length = offsetof(struct brcmf_pmk_op_v3_le, pmk);
4319+
int ret;
4320+
4321+
pmk_op = kzalloc(sizeof(*pmk_op), GFP_KERNEL);
4322+
pmk_op->version = cpu_to_le16(BRCMF_PMKSA_VER_3);
4323+
4324+
if (!pmksa) {
4325+
/* Flush operation, operate on entire list */
4326+
pmk_op->count = cpu_to_le16(0);
4327+
} else {
4328+
/* Single PMK operation */
4329+
pmk_op->count = cpu_to_le16(1);
4330+
length += sizeof(struct brcmf_pmksa_v3);
4331+
memcpy(pmk_op->pmk[0].bssid, pmksa->bssid, ETH_ALEN);
4332+
memcpy(pmk_op->pmk[0].pmkid, pmksa->pmkid, WLAN_PMKID_LEN);
4333+
pmk_op->pmk[0].pmkid_len = WLAN_PMKID_LEN;
4334+
pmk_op->pmk[0].time_left = alive ? BRCMF_PMKSA_NO_EXPIRY : 0;
4335+
}
4336+
4337+
pmk_op->length = cpu_to_le16(length);
4338+
4339+
ret = brcmf_fil_iovar_data_set(ifp, "pmkid_info", pmk_op, sizeof(*pmk_op));
4340+
kfree(pmk_op);
4341+
return ret;
4342+
}
4343+
43134344
static __used s32
43144345
brcmf_update_pmklist(struct brcmf_cfg80211_info *cfg, struct brcmf_if *ifp)
43154346
{
@@ -4343,6 +4374,14 @@ brcmf_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *ndev,
43434374
if (!check_vif_up(ifp->vif))
43444375
return -EIO;
43454376

4377+
brcmf_dbg(CONN, "set_pmksa - PMK bssid: %pM =\n", pmksa->bssid);
4378+
brcmf_dbg(CONN, "%*ph\n", WLAN_PMKID_LEN, pmksa->pmkid);
4379+
4380+
if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_PMKID_V3))
4381+
return brcmf_pmksa_v3_op(ifp, pmksa, true);
4382+
4383+
/* TODO: implement PMKID_V2 */
4384+
43464385
npmk = le32_to_cpu(cfg->pmk_list.npmk);
43474386
for (i = 0; i < npmk; i++)
43484387
if (!memcmp(pmksa->bssid, pmk[i].bssid, ETH_ALEN))
@@ -4359,9 +4398,6 @@ brcmf_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *ndev,
43594398
return -EINVAL;
43604399
}
43614400

4362-
brcmf_dbg(CONN, "set_pmksa - PMK bssid: %pM =\n", pmk[npmk].bssid);
4363-
brcmf_dbg(CONN, "%*ph\n", WLAN_PMKID_LEN, pmk[npmk].pmkid);
4364-
43654401
err = brcmf_update_pmklist(cfg, ifp);
43664402

43674403
brcmf_dbg(TRACE, "Exit\n");
@@ -4385,6 +4421,11 @@ brcmf_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *ndev,
43854421

43864422
brcmf_dbg(CONN, "del_pmksa - PMK bssid = %pM\n", pmksa->bssid);
43874423

4424+
if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_PMKID_V3))
4425+
return brcmf_pmksa_v3_op(ifp, pmksa, false);
4426+
4427+
/* TODO: implement PMKID_V2 */
4428+
43884429
npmk = le32_to_cpu(cfg->pmk_list.npmk);
43894430
for (i = 0; i < npmk; i++)
43904431
if (!memcmp(pmksa->bssid, pmk[i].bssid, ETH_ALEN))
@@ -4421,6 +4462,11 @@ brcmf_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *ndev)
44214462
if (!check_vif_up(ifp->vif))
44224463
return -EIO;
44234464

4465+
if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_PMKID_V3))
4466+
return brcmf_pmksa_v3_op(ifp, NULL, false);
4467+
4468+
/* TODO: implement PMKID_V2 */
4469+
44244470
memset(&cfg->pmk_list, 0, sizeof(cfg->pmk_list));
44254471
err = brcmf_update_pmklist(cfg, ifp);
44264472

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

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,10 @@
174174

175175
#define BRCMF_HE_CAP_MCS_MAP_NSS_MAX 8
176176

177+
#define BRCMF_PMKSA_VER_2 2
178+
#define BRCMF_PMKSA_VER_3 3
179+
#define BRCMF_PMKSA_NO_EXPIRY 0xffffffff
180+
177181
/* MAX_CHUNK_LEN is the maximum length for data passing to firmware in each
178182
* ioctl. It is relatively small because firmware has small maximum size input
179183
* playload restriction for ioctls.
@@ -355,6 +359,12 @@ struct brcmf_ssid_le {
355359
unsigned char SSID[IEEE80211_MAX_SSID_LEN];
356360
};
357361

362+
/* Alternate SSID structure used in some places... */
363+
struct brcmf_ssid8_le {
364+
u8 SSID_len;
365+
unsigned char SSID[IEEE80211_MAX_SSID_LEN];
366+
};
367+
358368
struct brcmf_scan_params_le {
359369
struct brcmf_ssid_le ssid_le; /* default: {0, ""} */
360370
u8 bssid[ETH_ALEN]; /* default: bcast */
@@ -875,6 +885,51 @@ struct brcmf_pmksa {
875885
u8 pmkid[WLAN_PMKID_LEN];
876886
};
877887

888+
/**
889+
* struct brcmf_pmksa_v2 - PMK Security Association
890+
*
891+
* @length: Length of the structure.
892+
* @bssid: The AP's BSSID.
893+
* @pmkid: The PMK ID.
894+
* @pmk: PMK material for FILS key derivation.
895+
* @pmk_len: Length of PMK data.
896+
* @ssid: The AP's SSID.
897+
* @fils_cache_id: FILS cache identifier
898+
*/
899+
struct brcmf_pmksa_v2 {
900+
__le16 length;
901+
u8 bssid[ETH_ALEN];
902+
u8 pmkid[WLAN_PMKID_LEN];
903+
u8 pmk[WLAN_PMK_LEN_SUITE_B_192];
904+
__le16 pmk_len;
905+
struct brcmf_ssid8_le ssid;
906+
u16 fils_cache_id;
907+
};
908+
909+
/**
910+
* struct brcmf_pmksa_v3 - PMK Security Association
911+
*
912+
* @bssid: The AP's BSSID.
913+
* @pmkid: The PMK ID.
914+
* @pmkid_len: The length of the PMK ID.
915+
* @pmk: PMK material for FILS key derivation.
916+
* @pmk_len: Length of PMK data.
917+
* @fils_cache_id: FILS cache identifier
918+
* @ssid: The AP's SSID.
919+
* @time_left: Remaining time until expiry. 0 = expired, ~0 = no expiry.
920+
*/
921+
struct brcmf_pmksa_v3 {
922+
u8 bssid[ETH_ALEN];
923+
u8 pmkid[WLAN_PMKID_LEN];
924+
u8 pmkid_len;
925+
u8 pmk[WLAN_PMK_LEN_SUITE_B_192];
926+
u8 pmk_len;
927+
__le16 fils_cache_id;
928+
u8 pad;
929+
struct brcmf_ssid8_le ssid;
930+
__le32 time_left;
931+
};
932+
878933
/**
879934
* struct brcmf_pmk_list_le - List of pmksa's.
880935
*
@@ -886,6 +941,34 @@ struct brcmf_pmk_list_le {
886941
struct brcmf_pmksa pmk[BRCMF_MAXPMKID];
887942
};
888943

944+
/**
945+
* struct brcmf_pmk_list_v2_le - List of pmksa's.
946+
*
947+
* @version: Request version.
948+
* @length: Length of this structure.
949+
* @pmk: PMK SA information.
950+
*/
951+
struct brcmf_pmk_list_v2_le {
952+
__le16 version;
953+
__le16 length;
954+
struct brcmf_pmksa_v2 pmk[BRCMF_MAXPMKID];
955+
};
956+
957+
/**
958+
* struct brcmf_pmk_op_v3_le - Operation on PMKSA list.
959+
*
960+
* @version: Request version.
961+
* @length: Length of this structure.
962+
* @pmk: PMK SA information.
963+
*/
964+
struct brcmf_pmk_op_v3_le {
965+
__le16 version;
966+
__le16 length;
967+
__le16 count;
968+
__le16 pad;
969+
struct brcmf_pmksa_v3 pmk[BRCMF_MAXPMKID];
970+
};
971+
889972
/**
890973
* struct brcmf_pno_param_le - PNO scan configuration parameters
891974
*

0 commit comments

Comments
 (0)