-
-
Save dberlin/31401500fcd83d5cee0effac49a5dce4 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | |
index 326c1fb07257..cdb67ebff97e 100644 | |
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | |
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | |
@@ -100,6 +100,14 @@ | |
#define PKT_TOKEN_IDX 15 | |
#define IDLE_TOKEN_IDX 12 | |
+ | |
+#define MGMT_AUTH_FRAME_DWELL_TIME 4000 | |
+#define MGMT_AUTH_FRAME_WAIT_TIME (MGMT_AUTH_FRAME_DWELL_TIME + 100) | |
+#define BRCMF_EXTAUTH_START 1 | |
+#define BRCMF_EXTAUTH_ABORT 2 | |
+#define BRCMF_EXTAUTH_FAIL 3 | |
+#define BRCMF_EXTAUTH_SUCCESS 4 | |
+ | |
struct brcmf_dump_survey { | |
u32 obss; | |
u32 ibss; | |
@@ -1365,7 +1373,7 @@ static int brcmf_set_wsec(struct brcmf_if *ifp, const u8 *key, u16 key_len, u16 | |
static int brcmf_set_pmk(struct brcmf_if *ifp, const u8 *pmk_data, u16 pmk_len) | |
{ | |
- return brcmf_set_wsec(ifp, pmk_data, pmk_len, 0); | |
+ return brcmf_set_wsec(ifp, pmk_data, pmk_len, BRCMF_WSEC_PASSPHRASE); | |
} | |
static int brcmf_set_sae_password(struct brcmf_if *ifp, const u8 *pwd_data, | |
@@ -5399,6 +5407,7 @@ brcmf_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev, | |
s32 ie_len; | |
struct brcmf_fil_action_frame_le *action_frame; | |
struct brcmf_fil_af_params_le *af_params; | |
+ | |
bool ack; | |
s32 chan_nr; | |
u32 freq; | |
@@ -5482,11 +5491,85 @@ brcmf_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev, | |
cfg80211_mgmt_tx_status(wdev, *cookie, buf, len, ack, | |
GFP_KERNEL); | |
kfree(af_params); | |
+ } else if (ieee80211_is_auth(mgmt->frame_control)) { | |
+ struct brcmf_mf_params_le *mf_params; | |
+ u32 mf_params_len; | |
+ s32 timeout; | |
+ u32 hw_channel; | |
+ | |
+ reinit_completion(&vif->mgmt_tx); | |
+ clear_bit(BRCMF_MGMT_TX_ACK, &vif->mgmt_tx_status); | |
+ clear_bit(BRCMF_MGMT_TX_NOACK, &vif->mgmt_tx_status); | |
+ clear_bit(BRCMF_MGMT_TX_OFF_CHAN_COMPLETED, | |
+ &vif->mgmt_tx_status); | |
+ | |
+ mf_params_len = offsetof(struct brcmf_mf_params_le, data) + | |
+ (len - DOT11_MGMT_HDR_LEN); | |
+ mf_params = kzalloc(mf_params_len, GFP_KERNEL); | |
+ if (!mf_params) { | |
+ err = -ENOMEM; | |
+ goto exit; | |
+ } | |
+ | |
+ mf_params->dwell_time = cpu_to_le32(MGMT_AUTH_FRAME_DWELL_TIME); | |
+ mf_params->len = cpu_to_le16(len - DOT11_MGMT_HDR_LEN); | |
+ mf_params->frame_control = mgmt->frame_control; | |
+ | |
+ if (chan) { | |
+ freq = chan->center_freq; | |
+ chan_nr = ieee80211_frequency_to_channel(freq); | |
+ mf_params->channel = cpu_to_le32(chan_nr); | |
+ } else { | |
+ brcmf_fil_cmd_int_get(vif->ifp, BRCMF_C_GET_CHANNEL, | |
+ &hw_channel); | |
+ mf_params->channel = hw_channel; | |
+ } | |
+ | |
+ memcpy(&mf_params->da[0], &mgmt->da[0], ETH_ALEN); | |
+ memcpy(&mf_params->bssid[0], &mgmt->bssid[0], ETH_ALEN); | |
+ mf_params->packet_id = cpu_to_le32(*cookie); | |
+ memcpy(mf_params->data, &buf[DOT11_MGMT_HDR_LEN], | |
+ le16_to_cpu(mf_params->len)); | |
+ | |
+ brcmf_dbg( | |
+ TRACE, | |
+ "Auth frame, cookie=%d, fc=%04x, len=%d, channel=%d\n", | |
+ le32_to_cpu(mf_params->packet_id), | |
+ le16_to_cpu(mf_params->frame_control), | |
+ le16_to_cpu(mf_params->len), | |
+ le32_to_cpu(mf_params->channel)); | |
+ | |
+ vif->mgmt_tx_id = le32_to_cpu(mf_params->packet_id); | |
+ set_bit(BRCMF_MGMT_TX_SEND_FRAME, &vif->mgmt_tx_status); | |
+ | |
+ err = brcmf_fil_bsscfg_data_set(vif->ifp, "mgmt_frame", | |
+ mf_params, mf_params_len); | |
+ if (err) { | |
+ bphy_err(drvr, "Failed to send Auth frame: err=%d\n", | |
+ err); | |
+ goto tx_status; | |
+ } | |
+ | |
+ timeout = wait_for_completion_timeout( | |
+ &vif->mgmt_tx, MGMT_AUTH_FRAME_WAIT_TIME); | |
+ if (test_bit(BRCMF_MGMT_TX_ACK, &vif->mgmt_tx_status)) { | |
+ brcmf_dbg(TRACE, | |
+ "TX Auth frame operation is success\n"); | |
+ ack = true; | |
+ } else { | |
+ bphy_err( | |
+ drvr, | |
+ "TX Auth frame operation is failed: status=%ld)\n", | |
+ vif->mgmt_tx_status); | |
+ } | |
+tx_status: | |
+ cfg80211_mgmt_tx_status(wdev, *cookie, buf, len, ack, | |
+ GFP_KERNEL); | |
+ kfree(mf_params); | |
} else { | |
brcmf_dbg(TRACE, "Unhandled, fc=%04x!!\n", mgmt->frame_control); | |
brcmf_dbg_hex_dump(true, buf, len, "payload, len=%zu\n", len); | |
} | |
- | |
exit: | |
return err; | |
} | |
@@ -5830,6 +5913,43 @@ static int brcmf_cfg80211_del_pmk(struct wiphy *wiphy, struct net_device *dev, | |
return brcmf_set_pmk(ifp, NULL, 0); | |
} | |
+static int | |
+brcmf_cfg80211_external_auth(struct wiphy *wiphy, struct net_device *dev, | |
+ struct cfg80211_external_auth_params *params) | |
+{ | |
+ struct brcmf_if *ifp; | |
+ struct brcmf_pub *drvr; | |
+ struct brcmf_auth_req_status_le auth_status; | |
+ int ret = 0; | |
+ | |
+ brcmf_dbg(TRACE, "Enter\n"); | |
+ | |
+ ifp = netdev_priv(dev); | |
+ drvr = ifp->drvr; | |
+ if (params->status == WLAN_STATUS_SUCCESS) { | |
+ auth_status.flags = cpu_to_le16(BRCMF_EXTAUTH_SUCCESS); | |
+ } else { | |
+ bphy_err(drvr, "External authentication failed: status=%d\n", | |
+ params->status); | |
+ auth_status.flags = cpu_to_le16(BRCMF_EXTAUTH_FAIL); | |
+ } | |
+ | |
+ memcpy(auth_status.peer_mac, params->bssid, ETH_ALEN); | |
+ auth_status.ssid_len = cpu_to_le32( | |
+ min_t(u8, params->ssid.ssid_len, IEEE80211_MAX_SSID_LEN)); | |
+ memcpy(auth_status.ssid, params->ssid.ssid, auth_status.ssid_len); | |
+ memset(auth_status.pmkid, 0, WLAN_PMKID_LEN); | |
+ if (params->pmkid) | |
+ memcpy(auth_status.pmkid, params->pmkid, WLAN_PMKID_LEN); | |
+ | |
+ ret = brcmf_fil_iovar_data_set(ifp, "auth_status", &auth_status, | |
+ sizeof(auth_status)); | |
+ if (ret < 0) | |
+ bphy_err(drvr, "auth_status iovar failed: ret=%d\n", ret); | |
+ | |
+ return ret; | |
+} | |
+ | |
static struct cfg80211_ops brcmf_cfg80211_ops = { | |
.add_virtual_intf = brcmf_cfg80211_add_iface, | |
.del_virtual_intf = brcmf_cfg80211_del_iface, | |
@@ -5877,6 +5997,7 @@ static struct cfg80211_ops brcmf_cfg80211_ops = { | |
.update_connect_params = brcmf_cfg80211_update_conn_params, | |
.set_pmk = brcmf_cfg80211_set_pmk, | |
.del_pmk = brcmf_cfg80211_del_pmk, | |
+ .external_auth = brcmf_cfg80211_external_auth, | |
}; | |
struct cfg80211_ops *brcmf_cfg80211_get_ops(struct brcmf_mp_device *settings) | |
@@ -6666,6 +6787,162 @@ static s32 brcmf_notify_vif_event(struct brcmf_if *ifp, | |
return -EINVAL; | |
} | |
+static s32 | |
+brcmf_notify_ext_auth_request(struct brcmf_if *ifp, | |
+ const struct brcmf_event_msg *e, void *data) | |
+{ | |
+ struct brcmf_pub *drvr = ifp->drvr; | |
+ struct cfg80211_external_auth_params params; | |
+ struct brcmf_auth_req_status_le *auth_req = | |
+ (struct brcmf_auth_req_status_le *)data; | |
+ s32 err = 0; | |
+ | |
+ brcmf_dbg(INFO, "Enter: event %s (%d) received\n", | |
+ brcmf_fweh_event_name(e->event_code), e->event_code); | |
+ | |
+ if (e->datalen < sizeof(*auth_req)) { | |
+ bphy_err(drvr, "Event %s (%d) data too small. Ignore\n", | |
+ brcmf_fweh_event_name(e->event_code), e->event_code); | |
+ return -EINVAL; | |
+ } | |
+ | |
+ memset(¶ms, 0, sizeof(params)); | |
+ params.action = NL80211_EXTERNAL_AUTH_START; | |
+ params.key_mgmt_suite = ntohl(WLAN_AKM_SUITE_SAE); | |
+ params.status = WLAN_STATUS_SUCCESS; | |
+ params.ssid.ssid_len = min_t(u32, 32, le32_to_cpu(auth_req->ssid_len)); | |
+ memcpy(params.ssid.ssid, auth_req->ssid, params.ssid.ssid_len); | |
+ memcpy(params.bssid, auth_req->peer_mac, ETH_ALEN); | |
+ | |
+ err = cfg80211_external_auth_request(ifp->ndev, ¶ms, GFP_ATOMIC); | |
+ if (err) | |
+ bphy_err(drvr, "Ext Auth request to supplicant failed (%d)\n", | |
+ err); | |
+ | |
+ return err; | |
+} | |
+ | |
+int brcmf_extract_mgmt_frame_data(struct brcmf_if *ifp, | |
+ const struct brcmf_event_msg *e, void *data, | |
+ u16 *chanspec, u32 *mgmt_frame_len, | |
+ u8 **mgmt_frame) | |
+{ | |
+ struct brcmf_rx_mgmt_data *rxframe = (struct brcmf_rx_mgmt_data *)data; | |
+ struct brcmf_rx_mgmt_data_v2 *rxframe_v2 = | |
+ (struct brcmf_rx_mgmt_data_v2 *)data; | |
+ struct brcmf_pub *drvr = ifp->drvr; | |
+ u16 version; | |
+ | |
+ version = be16_to_cpu(rxframe->version); | |
+ if (version == 1) { | |
+ if (e->datalen < sizeof(*rxframe)) { | |
+ bphy_err(drvr, "Event %s (%d) data too small. Ignore\n", | |
+ brcmf_fweh_event_name(e->event_code), | |
+ e->event_code); | |
+ return -EINVAL; | |
+ } | |
+ *mgmt_frame_len = | |
+ e->datalen - sizeof(struct brcmf_rx_mgmt_data); | |
+ *mgmt_frame = (u8 *)(rxframe + 1); | |
+ *chanspec = be16_to_cpu(rxframe->chanspec); | |
+ | |
+ } else if (version == 2) { | |
+ if (e->datalen < sizeof(*rxframe_v2)) { | |
+ bphy_err(drvr, "Event %s (%d) data too small. Ignore\n", | |
+ brcmf_fweh_event_name(e->event_code), | |
+ e->event_code); | |
+ return -EINVAL; | |
+ } | |
+ *mgmt_frame_len = | |
+ e->datalen - sizeof(struct brcmf_rx_mgmt_data_v2); | |
+ | |
+ *mgmt_frame = (u8 *)(rxframe_v2 + 1); | |
+ *chanspec = be16_to_cpu(rxframe_v2->chanspec); | |
+ } else { | |
+ bphy_err(drvr, "Unsupported mgmt data version:%d\n", version); | |
+ return -EINVAL; | |
+ } | |
+ return 0; | |
+} | |
+ | |
+static s32 | |
+brcmf_notify_auth_frame_rx(struct brcmf_if *ifp, | |
+ const struct brcmf_event_msg *e, void *data) | |
+{ | |
+ struct brcmf_pub *drvr = ifp->drvr; | |
+ struct brcmf_cfg80211_info *cfg = drvr->config; | |
+ struct wireless_dev *wdev; | |
+ u32 mgmt_frame_len; | |
+ u8 *frame; | |
+ struct brcmu_chan ch; | |
+ struct ieee80211_mgmt *mgmt_frame; | |
+ s32 freq; | |
+ u16 chanspec = 0; | |
+ s32 err; | |
+ | |
+ brcmf_dbg(INFO, "Enter: event %s (%d) received\n", | |
+ brcmf_fweh_event_name(e->event_code), e->event_code); | |
+ err = brcmf_extract_mgmt_frame_data(ifp, e, data, &chanspec, &mgmt_frame_len, &frame); | |
+ if (err) { | |
+ bphy_err(drvr, "Error extracting management frame data:%d\n", err); | |
+ return err; | |
+ } | |
+ wdev = &ifp->vif->wdev; | |
+ WARN_ON(!wdev); | |
+ | |
+ ch.chspec = chanspec; | |
+ cfg->d11inf.decchspec(&ch); | |
+ | |
+ mgmt_frame = kzalloc(mgmt_frame_len, GFP_KERNEL); | |
+ if (!mgmt_frame) | |
+ return -ENOMEM; | |
+ | |
+ mgmt_frame->frame_control = cpu_to_le16(IEEE80211_STYPE_AUTH); | |
+ memcpy(mgmt_frame->da, ifp->mac_addr, ETH_ALEN); | |
+ memcpy(mgmt_frame->sa, e->addr, ETH_ALEN); | |
+ brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_BSSID, mgmt_frame->bssid, | |
+ ETH_ALEN); | |
+ frame += offsetof(struct ieee80211_mgmt, u); | |
+ memcpy(&mgmt_frame->u, frame, | |
+ mgmt_frame_len - offsetof(struct ieee80211_mgmt, u)); | |
+ | |
+ freq = ieee80211_channel_to_frequency( | |
+ ch.control_ch_num, fwil_band_to_nl80211(ch.band)); | |
+ | |
+ cfg80211_rx_mgmt(wdev, freq, 0, (u8 *)mgmt_frame, mgmt_frame_len, | |
+ NL80211_RXMGMT_FLAG_EXTERNAL_AUTH); | |
+ kfree(mgmt_frame); | |
+ return 0; | |
+} | |
+ | |
+static s32 brcmf_notify_mgmt_tx_status(struct brcmf_if *ifp, | |
+ const struct brcmf_event_msg *e, | |
+ void *data) | |
+{ | |
+ struct brcmf_cfg80211_vif *vif = ifp->vif; | |
+ u32 *packet_id = (u32 *)data; | |
+ | |
+ brcmf_dbg(INFO, "Enter: event %s (%d), status=%d\n", | |
+ brcmf_fweh_event_name(e->event_code), e->event_code, | |
+ e->status); | |
+ | |
+ if (!test_bit(BRCMF_MGMT_TX_SEND_FRAME, &vif->mgmt_tx_status) || | |
+ (*packet_id != vif->mgmt_tx_id)) | |
+ return 0; | |
+ | |
+ if (e->event_code == BRCMF_E_MGMT_FRAME_TXSTATUS) { | |
+ if (e->status == BRCMF_E_STATUS_SUCCESS) | |
+ set_bit(BRCMF_MGMT_TX_ACK, &vif->mgmt_tx_status); | |
+ else | |
+ set_bit(BRCMF_MGMT_TX_NOACK, &vif->mgmt_tx_status); | |
+ } else { | |
+ set_bit(BRCMF_MGMT_TX_OFF_CHAN_COMPLETED, &vif->mgmt_tx_status); | |
+ } | |
+ | |
+ complete(&vif->mgmt_tx); | |
+ return 0; | |
+} | |
+ | |
static void brcmf_init_conf(struct brcmf_cfg80211_conf *conf) | |
{ | |
conf->frag_threshold = (u32)-1; | |
@@ -6708,6 +6985,14 @@ static void brcmf_register_event_handlers(struct brcmf_cfg80211_info *cfg) | |
brcmf_p2p_notify_action_tx_complete); | |
brcmf_fweh_register(cfg->pub, BRCMF_E_ACTION_FRAME_OFF_CHAN_COMPLETE, | |
brcmf_p2p_notify_action_tx_complete); | |
+ brcmf_fweh_register(cfg->pub, BRCMF_E_EXT_AUTH_REQ, | |
+ brcmf_notify_ext_auth_request); | |
+ brcmf_fweh_register(cfg->pub, BRCMF_E_EXT_AUTH_FRAME_RX, | |
+ brcmf_notify_auth_frame_rx); | |
+ brcmf_fweh_register(cfg->pub, BRCMF_E_MGMT_FRAME_TXSTATUS, | |
+ brcmf_notify_mgmt_tx_status); | |
+ brcmf_fweh_register(cfg->pub, BRCMF_E_MGMT_FRAME_OFF_CHAN_COMPLETE, | |
+ brcmf_notify_mgmt_tx_status); | |
brcmf_fweh_register(cfg->pub, BRCMF_E_PSK_SUP, | |
brcmf_notify_connect_status); | |
brcmf_fweh_register(cfg->pub, BRCMF_E_RSSI, brcmf_notify_rssi); | |
@@ -7742,6 +8027,7 @@ brcmf_txrx_stypes[NUM_NL80211_IFTYPES] = { | |
[NL80211_IFTYPE_STATION] = { | |
.tx = 0xffff, | |
.rx = BIT(IEEE80211_STYPE_ACTION >> 4) | | |
+ BIT(IEEE80211_STYPE_AUTH >> 4) | | |
BIT(IEEE80211_STYPE_PROBE_REQ >> 4) | |
}, | |
[NL80211_IFTYPE_P2P_CLIENT] = { | |
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h | |
index c1685c53b74d..64a8815a497d 100644 | |
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h | |
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h | |
@@ -93,6 +93,21 @@ | |
#define BRCMF_VIF_EVENT_TIMEOUT msecs_to_jiffies(1500) | |
+/** | |
+ * enum brcmf_mgmt_tx_status - mgmt frame tx status | |
+ * | |
+ * @BRCMF_MGMT_TX_ACK: mgmt frame acked | |
+ * @BRCMF_MGMT_TX_NOACK: mgmt frame not acked | |
+ * @BRCMF_MGMT_TX_OFF_CHAN_COMPLETED: off-channel complete | |
+ * @BRCMF_MGMT_TX_SEND_FRAME: mgmt frame tx is in progres | |
+ */ | |
+enum brcmf_mgmt_tx_status { | |
+ BRCMF_MGMT_TX_ACK, | |
+ BRCMF_MGMT_TX_NOACK, | |
+ BRCMF_MGMT_TX_OFF_CHAN_COMPLETED, | |
+ BRCMF_MGMT_TX_SEND_FRAME | |
+}; | |
+ | |
/** | |
* enum brcmf_scan_status - scan engine status | |
* | |
@@ -227,6 +242,9 @@ struct brcmf_cfg80211_vif { | |
unsigned long sme_state; | |
struct vif_saved_ie saved_ie; | |
struct list_head list; | |
+ struct completion mgmt_tx; | |
+ unsigned long mgmt_tx_status; | |
+ u32 mgmt_tx_id; | |
u16 mgmt_rx_reg; | |
bool mbss; | |
int is_11d; | |
@@ -490,5 +508,8 @@ s32 brcmf_notify_escan_complete(struct brcmf_cfg80211_info *cfg, | |
void brcmf_set_mpc(struct brcmf_if *ndev, int mpc); | |
void brcmf_abort_scanning(struct brcmf_cfg80211_info *cfg); | |
void brcmf_cfg80211_free_netdev(struct net_device *ndev); | |
- | |
+s32 brcmf_extract_mgmt_frame_data(struct brcmf_if *ifp, | |
+ const struct brcmf_event_msg *e, | |
+ void *data, u16 *chanspec, u32 *mgmt_frame_len, | |
+ u8 **mgmt_frame); | |
#endif /* BRCMFMAC_CFG80211_H */ | |
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.h | |
index 041e5efb852d..7c658dc7fe6d 100644 | |
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.h | |
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.h | |
@@ -61,7 +61,7 @@ struct brcmf_cfg80211_info; | |
BRCMF_ENUM_DEF(IBSS_ASSOC, 39) \ | |
BRCMF_ENUM_DEF(RADIO, 40) \ | |
BRCMF_ENUM_DEF(PSM_WATCHDOG, 41) \ | |
- BRCMF_ENUM_DEF(PROBREQ_MSG, 44) \ | |
+ BRCMF_ENUM_DEF(PROBEREQ_MSG, 44) \ | |
BRCMF_ENUM_DEF(SCAN_CONFIRM_IND, 45) \ | |
BRCMF_ENUM_DEF(PSK_SUP, 46) \ | |
BRCMF_ENUM_DEF(COUNTRY_CODE_CHANGED, 47) \ | |
@@ -90,7 +90,13 @@ struct brcmf_cfg80211_info; | |
BRCMF_ENUM_DEF(FIFO_CREDIT_MAP, 74) \ | |
BRCMF_ENUM_DEF(ACTION_FRAME_RX, 75) \ | |
BRCMF_ENUM_DEF(TDLS_PEER_EVENT, 92) \ | |
- BRCMF_ENUM_DEF(BCMC_CREDIT_SUPPORT, 127) | |
+ BRCMF_ENUM_DEF(PHY_TEMP, 111) \ | |
+ BRCMF_ENUM_DEF(BCMC_CREDIT_SUPPORT, 127) \ | |
+ BRCMF_ENUM_DEF(PROBEREQ_MSG_RX, 137) \ | |
+ BRCMF_ENUM_DEF(EXT_AUTH_REQ, 187) \ | |
+ BRCMF_ENUM_DEF(EXT_AUTH_FRAME_RX, 188) \ | |
+ BRCMF_ENUM_DEF(MGMT_FRAME_TXSTATUS, 189) \ | |
+ BRCMF_ENUM_DEF(MGMT_FRAME_OFF_CHAN_COMPLETE, 190) | |
#define BRCMF_ENUM_DEF(id, val) \ | |
BRCMF_E_##id = (val), | |
@@ -102,7 +108,7 @@ enum brcmf_fweh_event_code { | |
* minimum length check in device firmware so it is | |
* hard-coded here. | |
*/ | |
- BRCMF_E_LAST = 139 | |
+ BRCMF_E_LAST = 196 | |
}; | |
#undef BRCMF_ENUM_DEF | |
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h | |
index 39ad612802e2..b93d249a9f7f 100644 | |
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h | |
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h | |
@@ -71,8 +71,8 @@ | |
#define BRCMF_SCANSSID_INC_RNR 0x02 /* Include RNR channels*/ | |
#define BRCMF_WSEC_MAX_PSK_LEN 32 | |
-#define BRCMF_WSEC_PASSPHRASE BIT(0) | |
- | |
+#define BRCMF_WSEC_PASSPHRASE BIT(0) /* PSK password */ | |
+#define BRCMF_WSEC_SAE_PASSPHRASE BIT(1) /* SAE password */ | |
#define BRCMF_WSEC_MAX_SAE_PASSWORD_LEN 256 | |
/* primary (ie tx) key */ | |
@@ -811,6 +811,47 @@ struct brcmf_wsec_sae_pwd_le { | |
u8 key[BRCMF_WSEC_MAX_SAE_PASSWORD_LEN]; | |
}; | |
+/** | |
+ * struct brcmf_auth_req_status_le - external auth request and status update | |
+ * | |
+ * @flags: flags for external auth status | |
+ * @peer_mac: peer MAC address | |
+ * @ssid_len: length of ssid | |
+ * @ssid: ssid characters | |
+ */ | |
+struct brcmf_auth_req_status_le { | |
+ __le16 flags; | |
+ u8 peer_mac[ETH_ALEN]; | |
+ __le32 ssid_len; | |
+ u8 ssid[IEEE80211_MAX_SSID_LEN]; | |
+ u8 pmkid[WLAN_PMKID_LEN]; | |
+}; | |
+ | |
+/** | |
+ * struct brcmf_mf_params_le - management frame parameters for mgmt_frame iovar | |
+ * | |
+ * @version: version of the iovar | |
+ * @dwell_time: dwell duration in ms | |
+ * @len: length of frame data | |
+ * @frame_control: frame control | |
+ * @channel: channel | |
+ * @da: peer MAC address | |
+ * @bssid: BSS network identifier | |
+ * @packet_id: packet identifier | |
+ * @data: frame data | |
+ */ | |
+struct brcmf_mf_params_le { | |
+ __le32 version; | |
+ __le32 dwell_time; | |
+ __le16 len; | |
+ __le16 frame_control; | |
+ __le16 channel; | |
+ u8 da[ETH_ALEN]; | |
+ u8 bssid[ETH_ALEN]; | |
+ __le32 packet_id; | |
+ u8 data[1]; | |
+}; | |
+ | |
/* Used to get specific STA parameters */ | |
struct brcmf_scb_val_le { | |
__le32 val; | |
@@ -972,6 +1013,18 @@ struct brcmf_rx_mgmt_data { | |
__be32 rate; | |
}; | |
+#define BRCMF_MAX_PHY_CORE_NUM 4 | |
+struct brcmf_rx_mgmt_data_v2 { | |
+ __be16 version; | |
+ __be16 length; | |
+ __be16 chanspec; | |
+ __be16 pad; | |
+ __be32 rssi; | |
+ __be32 mactime; | |
+ __be32 rate; | |
+ char per_core_rssi[BRCMF_MAX_PHY_CORE_NUM]; | |
+}; | |
+ | |
/** | |
* struct brcmf_fil_wowl_pattern_le - wowl pattern configuration struct. | |
* | |
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c | |
index 071b0706d137..e6be87631c4d 100644 | |
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c | |
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c | |
@@ -1391,9 +1391,8 @@ int brcmf_p2p_notify_action_frame_rx(struct brcmf_if *ifp, | |
struct brcmf_p2p_info *p2p = &cfg->p2p; | |
struct afx_hdl *afx_hdl = &p2p->afx_hdl; | |
struct wireless_dev *wdev; | |
- u32 mgmt_frame_len = e->datalen - sizeof(struct brcmf_rx_mgmt_data); | |
- struct brcmf_rx_mgmt_data *rxframe = (struct brcmf_rx_mgmt_data *)data; | |
- u8 *frame = (u8 *)(rxframe + 1); | |
+ u32 mgmt_frame_len; | |
+ u8 *frame; | |
struct brcmf_p2p_pub_act_frame *act_frm; | |
struct brcmf_p2psd_gas_pub_act_frame *sd_act_frm; | |
struct brcmu_chan ch; | |
@@ -1401,13 +1400,18 @@ int brcmf_p2p_notify_action_frame_rx(struct brcmf_if *ifp, | |
s32 freq; | |
u16 mgmt_type; | |
u8 action; | |
+ u16 chanspec; | |
+ s32 err; | |
- if (e->datalen < sizeof(*rxframe)) { | |
- brcmf_dbg(SCAN, "Event data to small. Ignore\n"); | |
- return 0; | |
+ err = brcmf_extract_mgmt_frame_data(ifp, e, data, &chanspec, | |
+ &mgmt_frame_len, &frame); | |
+ if (err) { | |
+ bphy_err(cfg, "Error extracting management frame data:%d\n", | |
+ err); | |
+ return err; | |
} | |
- ch.chspec = be16_to_cpu(rxframe->chanspec); | |
+ ch.chspec = chanspec; | |
cfg->d11inf.decchspec(&ch); | |
/* Check if wpa_supplicant has registered for this frame */ | |
brcmf_dbg(INFO, "ifp->vif->mgmt_rx_reg %04x\n", ifp->vif->mgmt_rx_reg); | |
@@ -1938,22 +1942,26 @@ s32 brcmf_p2p_notify_rx_mgmt_p2p_probereq(struct brcmf_if *ifp, | |
struct brcmf_p2p_info *p2p = &cfg->p2p; | |
struct afx_hdl *afx_hdl = &p2p->afx_hdl; | |
struct brcmf_cfg80211_vif *vif = ifp->vif; | |
- struct brcmf_rx_mgmt_data *rxframe = (struct brcmf_rx_mgmt_data *)data; | |
struct brcmu_chan ch; | |
u8 *mgmt_frame; | |
u32 mgmt_frame_len; | |
s32 freq; | |
u16 mgmt_type; | |
+ s32 err; | |
+ u16 chanspec; | |
brcmf_dbg(INFO, "Enter: event %d reason %d\n", e->event_code, | |
e->reason); | |
- if (e->datalen < sizeof(*rxframe)) { | |
- brcmf_dbg(SCAN, "Event data to small. Ignore\n"); | |
- return 0; | |
+ err = brcmf_extract_mgmt_frame_data(ifp, e, data, &chanspec, | |
+ &mgmt_frame_len, &mgmt_frame); | |
+ if (err) { | |
+ bphy_err(cfg, "Error extracting management frame data:%d\n", | |
+ err); | |
+ return err; | |
} | |
- ch.chspec = be16_to_cpu(rxframe->chanspec); | |
+ ch.chspec = chanspec; | |
cfg->d11inf.decchspec(&ch); | |
if (test_bit(BRCMF_P2P_STATUS_FINDING_COMMON_CHANNEL, &p2p->status) && | |
@@ -1981,8 +1989,6 @@ s32 brcmf_p2p_notify_rx_mgmt_p2p_probereq(struct brcmf_if *ifp, | |
if ((vif->mgmt_rx_reg & BIT(mgmt_type)) == 0) | |
return 0; | |
- mgmt_frame = (u8 *)(rxframe + 1); | |
- mgmt_frame_len = e->datalen - sizeof(*rxframe); | |
freq = ieee80211_channel_to_frequency(ch.control_ch_num, | |
ch.band == BRCMU_CHAN_BAND_2G ? | |
NL80211_BAND_2GHZ : |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment