Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9706f238 authored by Sarada Prasanna Garnayak's avatar Sarada Prasanna Garnayak
Browse files

Ath10k: enable WLAN channel switch announcement offload



The WLAN firmware supports the channel switch offload and
channel switch announcement event reporting to the WLAN driver.
In STA mode this feature adds support to wakeup the device from
the wow suspend on channel switch announcement by the connected
access point.

CRs-Fixed: 2170011
Change-Id: I68612beb0a808700a732fc858c8797200d1f4819
Signed-off-by: default avatarSarada Prasanna Garnayak <sgarna@codeaurora.org>
parent 3a9f9cc5
Loading
Loading
Loading
Loading
+12 −0
Original line number Diff line number Diff line
@@ -5004,6 +5004,15 @@ static int ath10k_add_interface(struct ieee80211_hw *hw,
		goto err;
	}

	if ((arvif->vdev_type == WMI_VDEV_TYPE_STA) && QCA_REV_WCN3990(ar)) {
		ret = ath10k_wmi_csa_offload(ar, arvif->vdev_id, true);
		if (ret) {
			ath10k_err(ar, "CSA offload failed for vdev %i: %d\n",
				   arvif->vdev_id, ret);
			goto err_vdev_delete;
		}
	}

	ar->free_vdev_map &= ~(1LL << arvif->vdev_id);
	list_add(&arvif->list, &ar->arvifs);

@@ -5216,6 +5225,9 @@ static void ath10k_remove_interface(struct ieee80211_hw *hw,
		kfree(arvif->u.ap.noa_data);
	}

	if ((arvif->vdev_type == WMI_VDEV_TYPE_STA) && QCA_REV_WCN3990(ar))
		ath10k_wmi_csa_offload(ar, arvif->vdev_id, false);

	ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %i delete (remove interface)\n",
		   arvif->vdev_id);

+19 −0
Original line number Diff line number Diff line
@@ -211,6 +211,8 @@ struct wmi_ops {
					(struct ath10k *ar,
					 enum wmi_bss_survey_req_type type);
	struct sk_buff *(*gen_echo)(struct ath10k *ar, u32 value);
	struct sk_buff *(*gen_csa_offload)(struct ath10k *ar,
					   u32 vdev_id, bool enable);
};

int ath10k_wmi_cmd_send(struct ath10k *ar, struct sk_buff *skb, u32 cmd_id);
@@ -1492,6 +1494,23 @@ ath10k_wmi_pdev_bss_chan_info_request(struct ath10k *ar,
				   wmi->cmd->pdev_bss_chan_info_request_cmdid);
}

static inline int
ath10k_wmi_csa_offload(struct ath10k *ar, u32 vdev_id, bool enable)
{
	struct sk_buff *skb;
	u32 cmd_id;

	if (!ar->wmi.ops->gen_csa_offload)
		return -EOPNOTSUPP;

	skb = ar->wmi.ops->gen_csa_offload(ar, vdev_id, enable);
	if (IS_ERR(skb))
		return PTR_ERR(skb);

	cmd_id = ar->wmi.cmd->csa_offload_enable_cmdid;
	return ath10k_wmi_cmd_send(ar, skb, cmd_id);
}

static inline int
ath10k_wmi_echo(struct ath10k *ar, u32 value)
{
+32 −0
Original line number Diff line number Diff line
@@ -3078,6 +3078,37 @@ ath10k_wmi_tlv_op_gen_tdls_peer_update(struct ath10k *ar,
	return skb;
}

static struct sk_buff *
ath10k_wmi_tlv_op_gen_csa_offload(struct ath10k *ar, u32 vdev_id, bool enable)
{
	struct wmi_csa_offload_enable_cmd *cmd;
	struct wmi_tlv *tlv;
	struct sk_buff *skb;
	int len;

	len = sizeof(*cmd) + sizeof(*tlv);
	skb = ath10k_wmi_alloc_skb(ar, len);
	if (!skb)
		return ERR_PTR(-ENOMEM);

	tlv = (void *)skb->data;
	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_CSA_OFFLOAD_ENABLE_CMD);
	tlv->len = __cpu_to_le16(sizeof(*cmd));
	cmd = (void *)tlv->value;

	cmd->vdev_id = __cpu_to_le32(vdev_id);
	if (enable)
		cmd->csa_offload_enable |=
			 __cpu_to_le32(WMI_CSA_OFFLOAD_ENABLE);
	else
		cmd->csa_offload_enable |=
			__cpu_to_le32(WMI_CSA_OFFLOAD_DISABLE);

	ath10k_dbg(ar, ATH10K_DBG_WMI,
		   "wmi CSA offload for vdev: %d\n", vdev_id);
	return skb;
}

static struct sk_buff *
ath10k_wmi_op_gen_gtk_offload(struct ath10k *ar, struct ath10k_vif *arvif)
{
@@ -3895,6 +3926,7 @@ static const struct wmi_ops wmi_tlv_ops = {
	.gen_sta_keepalive = ath10k_wmi_tlv_op_gen_sta_keepalive,
	.gen_set_arp_ns_offload = ath10k_wmi_tlv_op_gen_set_arp_ns_offload,
	.gen_gtk_offload = ath10k_wmi_op_gen_gtk_offload,
	.gen_csa_offload = ath10k_wmi_tlv_op_gen_csa_offload,
	.gen_wow_enable = ath10k_wmi_tlv_op_gen_wow_enable,
	.gen_wow_add_wakeup_event = ath10k_wmi_tlv_op_gen_wow_add_wakeup_event,
	.gen_wow_host_wakeup_ind = ath10k_wmi_tlv_gen_wow_host_wakeup_ind,