Skip to content

Commit

Permalink
wcn36xx: Add GTK offload info to WoWLAN resume
Browse files Browse the repository at this point in the history
Having enabled GTK rekey in suspend, we need to extract the replay counter
from the firmware on resume and perform a ieee80211_gtk_rekey_notify() so
that the STA remains verified from the perspective of the AP.

In order to enable the SMD command and response we need to pack the
existing command/response structures. Given these structures are currently
unused, there's no need to backport this as a fix.

Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
Tested-by: Benjamin Li <benl@squareup.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
Link: https://lore.kernel.org/r/20210605011140.2004643-10-bryan.odonoghue@linaro.org
  • Loading branch information
Bryan O'Donoghue authored and Kalle Valo committed Jun 14, 2021
1 parent 6693f76 commit bedf116
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 2 deletions.
4 changes: 2 additions & 2 deletions drivers/net/wireless/ath/wcn36xx/hal.h
Original file line number Diff line number Diff line change
Expand Up @@ -4919,7 +4919,7 @@ struct wcn36xx_hal_gtk_offload_rsp_msg {
struct wcn36xx_hal_gtk_offload_get_info_req_msg {
struct wcn36xx_hal_msg_header header;
u8 bss_index;
};
} __packed;

struct wcn36xx_hal_gtk_offload_get_info_rsp_msg {
struct wcn36xx_hal_msg_header header;
Expand All @@ -4943,7 +4943,7 @@ struct wcn36xx_hal_gtk_offload_get_info_rsp_msg {
u32 igtk_rekey_count;

u8 bss_index;
};
} __packed;

struct dhcp_info {
/* Indicates the device mode which indicates about the DHCP activity */
Expand Down
1 change: 1 addition & 0 deletions drivers/net/wireless/ath/wcn36xx/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -1142,6 +1142,7 @@ static int wcn36xx_resume(struct ieee80211_hw *hw)
vif = wcn36xx_get_first_assoc_vif(wcn);
if (vif) {
wcn36xx_smd_set_power_params(wcn, false);
wcn36xx_smd_gtk_offload_get_info(wcn, vif);
wcn36xx_smd_gtk_offload(wcn, vif, false);
wcn36xx_smd_ipv6_ns_offload(wcn, vif, false);
wcn36xx_smd_arp_offload(wcn, vif, false);
Expand Down
73 changes: 73 additions & 0 deletions drivers/net/wireless/ath/wcn36xx/smd.c
Original file line number Diff line number Diff line change
Expand Up @@ -2894,6 +2894,78 @@ int wcn36xx_smd_gtk_offload(struct wcn36xx *wcn, struct ieee80211_vif *vif,
return ret;
}

static int wcn36xx_smd_gtk_offload_get_info_rsp(struct wcn36xx *wcn,
struct ieee80211_vif *vif)
{
struct wcn36xx_vif *vif_priv = wcn36xx_vif_to_priv(vif);
struct wcn36xx_hal_gtk_offload_get_info_rsp_msg *rsp;
__be64 replay_ctr;

if (wcn36xx_smd_rsp_status_check(wcn->hal_buf, wcn->hal_rsp_len))
return -EIO;

rsp = (struct wcn36xx_hal_gtk_offload_get_info_rsp_msg *)wcn->hal_buf;

if (rsp->bss_index != vif_priv->bss_index) {
wcn36xx_err("gtk_offload_info invalid response bss index %d\n",
rsp->bss_index);
return -ENOENT;
}

if (vif_priv->rekey_data.replay_ctr != cpu_to_le64(rsp->key_replay_counter)) {
replay_ctr = cpu_to_be64(rsp->key_replay_counter);
vif_priv->rekey_data.replay_ctr =
cpu_to_le64(rsp->key_replay_counter);
ieee80211_gtk_rekey_notify(vif, vif->bss_conf.bssid,
(void *)&replay_ctr, GFP_KERNEL);
wcn36xx_dbg(WCN36XX_DBG_HAL,
"GTK replay counter increment %llu\n",
rsp->key_replay_counter);
}

wcn36xx_dbg(WCN36XX_DBG_HAL,
"gtk offload info status %d last_rekey_status %d "
"replay_counter %llu total_rekey_count %d gtk_rekey_count %d "
"igtk_rekey_count %d bss_index %d\n",
rsp->status, rsp->last_rekey_status,
rsp->key_replay_counter, rsp->total_rekey_count,
rsp->gtk_rekey_count, rsp->igtk_rekey_count,
rsp->bss_index);

return 0;
}

int wcn36xx_smd_gtk_offload_get_info(struct wcn36xx *wcn,
struct ieee80211_vif *vif)
{
struct wcn36xx_vif *vif_priv = wcn36xx_vif_to_priv(vif);
struct wcn36xx_hal_gtk_offload_get_info_req_msg msg_body;
int ret;

mutex_lock(&wcn->hal_mutex);

INIT_HAL_MSG(msg_body, WCN36XX_HAL_GTK_OFFLOAD_GETINFO_REQ);

msg_body.bss_index = vif_priv->bss_index;

PREPARE_HAL_BUF(wcn->hal_buf, msg_body);

ret = wcn36xx_smd_send_and_wait(wcn, msg_body.header.len);
if (ret) {
wcn36xx_err("Sending gtk_offload_get_info failed\n");
goto out;
}
ret = wcn36xx_smd_rsp_status_check(wcn->hal_buf, wcn->hal_rsp_len);
if (ret) {
wcn36xx_err("gtk_offload_get_info failed err=%d\n", ret);
goto out;
}
ret = wcn36xx_smd_gtk_offload_get_info_rsp(wcn, vif);
out:
mutex_unlock(&wcn->hal_mutex);
return ret;
}

int wcn36xx_smd_rsp_process(struct rpmsg_device *rpdev,
void *buf, int len, void *priv, u32 addr)
{
Expand Down Expand Up @@ -2944,6 +3016,7 @@ int wcn36xx_smd_rsp_process(struct rpmsg_device *rpdev,
case WCN36XX_HAL_STOP_SCAN_OFFLOAD_RSP:
case WCN36XX_HAL_HOST_OFFLOAD_RSP:
case WCN36XX_HAL_GTK_OFFLOAD_RSP:
case WCN36XX_HAL_GTK_OFFLOAD_GETINFO_RSP:
memcpy(wcn->hal_buf, buf, len);
wcn->hal_rsp_len = len;
complete(&wcn->hal_rsp_compl);
Expand Down
3 changes: 3 additions & 0 deletions drivers/net/wireless/ath/wcn36xx/smd.h
Original file line number Diff line number Diff line change
Expand Up @@ -156,4 +156,7 @@ int wcn36xx_smd_ipv6_ns_offload(struct wcn36xx *wcn, struct ieee80211_vif *vif,
int wcn36xx_smd_gtk_offload(struct wcn36xx *wcn, struct ieee80211_vif *vif,
bool enable);

int wcn36xx_smd_gtk_offload_get_info(struct wcn36xx *wcn,
struct ieee80211_vif *vif);

#endif /* _SMD_H_ */

0 comments on commit bedf116

Please sign in to comment.