// SPDX-License-Identifier: BSD-3-Clause-Clear
/*
 * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
 * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
 */

#include "testmode.h"
#include <net/netlink.h>
#include "debug.h"
#include "wmi.h"
#include "hw.h"
#include "core.h"
#include "testmode_i.h"

#define ATH11K_FTM_SEGHDR_CURRENT_SEQ		GENMASK(3, 0)
#define ATH11K_FTM_SEGHDR_TOTAL_SEGMENTS	GENMASK(7, 4)

static const struct nla_policy ath11k_tm_policy[ATH11K_TM_ATTR_MAX + 1] = {
	[ATH11K_TM_ATTR_CMD]		= { .type = NLA_U32 },
	[ATH11K_TM_ATTR_DATA]		= { .type = NLA_BINARY,
					    .len = ATH11K_TM_DATA_MAX_LEN },
	[ATH11K_TM_ATTR_WMI_CMDID]	= { .type = NLA_U32 },
	[ATH11K_TM_ATTR_VERSION_MAJOR]	= { .type = NLA_U32 },
	[ATH11K_TM_ATTR_VERSION_MINOR]	= { .type = NLA_U32 },
};

static struct ath11k *ath11k_tm_get_ar(struct ath11k_base *ab)
{
	struct ath11k_pdev *pdev;
	struct ath11k *ar = NULL;
	int i;

	for (i = 0; i < ab->num_radios; i++) {
		pdev = &ab->pdevs[i];
		ar = pdev->ar;

		if (ar && ar->state == ATH11K_STATE_FTM)
			break;
	}

	return ar;
}

/* This function handles unsegmented events. Data in various events are aggregated
 * in application layer, this event is unsegmented from host perspective.
 */
static void ath11k_tm_wmi_event_unsegmented(struct ath11k_base *ab, u32 cmd_id,
					    struct sk_buff *skb)
{
	struct sk_buff *nl_skb;
	struct ath11k *ar;

	ath11k_dbg(ab, ATH11K_DBG_TESTMODE,
		   "event wmi cmd_id %d skb length %d\n",
		   cmd_id, skb->len);
	ath11k_dbg_dump(ab, ATH11K_DBG_TESTMODE, NULL, "", skb->data, skb->len);

	ar = ath11k_tm_get_ar(ab);
	if (!ar) {
		ath11k_warn(ab, "testmode event not handled due to invalid pdev\n");
		return;
	}

	spin_lock_bh(&ar->data_lock);

	nl_skb = cfg80211_testmode_alloc_event_skb(ar->hw->wiphy,
						   2 * nla_total_size(sizeof(u32)) +
						   nla_total_size(skb->len),
						   GFP_ATOMIC);
	if (!nl_skb) {
		ath11k_warn(ab,
			    "failed to allocate skb for unsegmented testmode wmi event\n");
		goto out;
	}

	if (nla_put_u32(nl_skb, ATH11K_TM_ATTR_CMD, ATH11K_TM_CMD_WMI) ||
	    nla_put_u32(nl_skb, ATH11K_TM_ATTR_WMI_CMDID, cmd_id) ||
	    nla_put(nl_skb, ATH11K_TM_ATTR_DATA, skb->len, skb->data)) {
		ath11k_warn(ab, "failed to populate testmode unsegmented event\n");
		kfree_skb(nl_skb);
		goto out;
	}

	cfg80211_testmode_event(nl_skb, GFP_ATOMIC);
	spin_unlock_bh(&ar->data_lock);
	return;

out:
	spin_unlock_bh(&ar->data_lock);
	ath11k_warn(ab, "Failed to send testmode event to higher layers\n");
}

/* This function handles segmented events. Data of various events received
 * from firmware is aggregated and sent to application layer
 */
static int ath11k_tm_process_event(struct ath11k_base *ab, u32 cmd_id,
				   const struct wmi_ftm_event_msg *ftm_msg,
				   u16 length)
{
	struct sk_buff *nl_skb;
	int ret = 0;
	struct ath11k *ar;
	u8 const *buf_pos;
	u16 datalen;
	u8 total_segments, current_seq;
	u32 data_pos;
	u32 pdev_id;

	ath11k_dbg(ab, ATH11K_DBG_TESTMODE,
		   "event wmi cmd_id %d ftm event msg %pK datalen %d\n",
		   cmd_id, ftm_msg, length);
	ath11k_dbg_dump(ab, ATH11K_DBG_TESTMODE, NULL, "", ftm_msg, length);
	pdev_id = DP_HW2SW_MACID(ftm_msg->seg_hdr.pdev_id);

	if (pdev_id >= ab->num_radios) {
		ath11k_warn(ab, "testmode event not handled due to invalid pdev id: %d\n",
			    pdev_id);
		return -EINVAL;
	}

	ar = ab->pdevs[pdev_id].ar;
	if (!ar) {
		ath11k_warn(ab, "testmode event not handled due to absence of pdev\n");
		return -ENODEV;
	}

	current_seq = FIELD_GET(ATH11K_FTM_SEGHDR_CURRENT_SEQ,
				ftm_msg->seg_hdr.segmentinfo);
	total_segments = FIELD_GET(ATH11K_FTM_SEGHDR_TOTAL_SEGMENTS,
				   ftm_msg->seg_hdr.segmentinfo);
	datalen = length - (sizeof(struct wmi_ftm_seg_hdr));
	buf_pos = ftm_msg->data;

	spin_lock_bh(&ar->data_lock);

	if (current_seq == 0) {
		ab->testmode.expected_seq = 0;
		ab->testmode.data_pos = 0;
	}

	data_pos = ab->testmode.data_pos;

	if ((data_pos + datalen) > ATH11K_FTM_EVENT_MAX_BUF_LENGTH) {
		ath11k_warn(ab, "Invalid ftm event length at %d: %d\n",
			    data_pos, datalen);
		ret = -EINVAL;
		goto out;
	}

	memcpy(&ab->testmode.eventdata[data_pos], buf_pos, datalen);
	data_pos += datalen;

	if (++ab->testmode.expected_seq != total_segments) {
		ab->testmode.data_pos = data_pos;
		ath11k_dbg(ab, ATH11K_DBG_TESTMODE,
			   "partial data received current_seq %d total_seg %d\n",
			    current_seq, total_segments);
		goto out;
	}

	ath11k_dbg(ab, ATH11K_DBG_TESTMODE,
		   "total data length pos %d len %d\n",
		    data_pos, ftm_msg->seg_hdr.len);
	nl_skb = cfg80211_testmode_alloc_event_skb(ar->hw->wiphy,
						   2 * nla_total_size(sizeof(u32)) +
						   nla_total_size(data_pos),
						   GFP_ATOMIC);
	if (!nl_skb) {
		ath11k_warn(ab,
			    "failed to allocate skb for segmented testmode wmi event\n");
		ret = -ENOMEM;
		goto out;
	}

	if (nla_put_u32(nl_skb, ATH11K_TM_ATTR_CMD,
			ATH11K_TM_CMD_WMI_FTM) ||
	    nla_put_u32(nl_skb, ATH11K_TM_ATTR_WMI_CMDID, cmd_id) ||
	    nla_put(nl_skb, ATH11K_TM_ATTR_DATA, data_pos,
		    &ab->testmode.eventdata[0])) {
		ath11k_warn(ab, "failed to populate segmented testmode event");
		kfree_skb(nl_skb);
		ret = -ENOBUFS;
		goto out;
	}

	cfg80211_testmode_event(nl_skb, GFP_ATOMIC);

out:
	spin_unlock_bh(&ar->data_lock);
	return ret;
}

static void ath11k_tm_wmi_event_segmented(struct ath11k_base *ab, u32 cmd_id,
					  struct sk_buff *skb)
{
	const void **tb;
	const struct wmi_ftm_event_msg *ev;
	u16 length;
	int ret;

	tb = ath11k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC);
	if (IS_ERR(tb)) {
		ret = PTR_ERR(tb);
		ath11k_warn(ab, "failed to parse ftm event tlv: %d\n", ret);
		return;
	}

	ev = tb[WMI_TAG_ARRAY_BYTE];
	if (!ev) {
		ath11k_warn(ab, "failed to fetch ftm msg\n");
		kfree(tb);
		return;
	}

	length = skb->len - TLV_HDR_SIZE;
	ret = ath11k_tm_process_event(ab, cmd_id, ev, length);
	if (ret)
		ath11k_warn(ab, "Failed to process ftm event\n");

	kfree(tb);
}

void ath11k_tm_wmi_event(struct ath11k_base *ab, u32 cmd_id, struct sk_buff *skb)
{
	if (test_bit(ATH11K_FLAG_FTM_SEGMENTED, &ab->dev_flags))
		ath11k_tm_wmi_event_segmented(ab, cmd_id, skb);
	else
		ath11k_tm_wmi_event_unsegmented(ab, cmd_id, skb);
}

static int ath11k_tm_cmd_get_version(struct ath11k *ar, struct nlattr *tb[])
{
	struct sk_buff *skb;
	int ret;

	ath11k_dbg(ar->ab, ATH11K_DBG_TESTMODE,
		   "cmd get version_major %d version_minor %d\n",
		   ATH11K_TESTMODE_VERSION_MAJOR,
		   ATH11K_TESTMODE_VERSION_MINOR);

	skb = cfg80211_testmode_alloc_reply_skb(ar->hw->wiphy,
						nla_total_size(sizeof(u32)));
	if (!skb)
		return -ENOMEM;

	ret = nla_put_u32(skb, ATH11K_TM_ATTR_VERSION_MAJOR,
			  ATH11K_TESTMODE_VERSION_MAJOR);
	if (ret) {
		kfree_skb(skb);
		return ret;
	}

	ret = nla_put_u32(skb, ATH11K_TM_ATTR_VERSION_MINOR,
			  ATH11K_TESTMODE_VERSION_MINOR);
	if (ret) {
		kfree_skb(skb);
		return ret;
	}

	return cfg80211_testmode_reply(skb);
}

static int ath11k_tm_cmd_testmode_start(struct ath11k *ar, struct nlattr *tb[])
{
	int ret;

	mutex_lock(&ar->conf_mutex);

	if (ar->state == ATH11K_STATE_FTM) {
		ret = -EALREADY;
		goto err;
	}

	/* start utf only when the driver is not in use  */
	if (ar->state != ATH11K_STATE_OFF) {
		ret = -EBUSY;
		goto err;
	}

	ar->ab->testmode.eventdata = kzalloc(ATH11K_FTM_EVENT_MAX_BUF_LENGTH,
					     GFP_KERNEL);
	if (!ar->ab->testmode.eventdata) {
		ret = -ENOMEM;
		goto err;
	}

	ar->state = ATH11K_STATE_FTM;
	ar->ftm_msgref = 0;

	mutex_unlock(&ar->conf_mutex);

	ath11k_dbg(ar->ab, ATH11K_DBG_TESTMODE, "cmd start\n");
	return 0;

err:
	mutex_unlock(&ar->conf_mutex);
	return ret;
}

static int ath11k_tm_cmd_wmi(struct ath11k *ar, struct nlattr *tb[],
			     struct ieee80211_vif *vif)
{
	struct ath11k_pdev_wmi *wmi = ar->wmi;
	struct sk_buff *skb;
	struct ath11k_vif *arvif;
	u32 cmd_id, buf_len;
	int ret, tag;
	void *buf;
	u32 *ptr;

	mutex_lock(&ar->conf_mutex);

	if (!tb[ATH11K_TM_ATTR_DATA]) {
		ret = -EINVAL;
		goto out;
	}

	if (!tb[ATH11K_TM_ATTR_WMI_CMDID]) {
		ret = -EINVAL;
		goto out;
	}

	buf = nla_data(tb[ATH11K_TM_ATTR_DATA]);
	buf_len = nla_len(tb[ATH11K_TM_ATTR_DATA]);
	if (!buf_len) {
		ath11k_warn(ar->ab, "No data present in testmode wmi command\n");
		ret = -EINVAL;
		goto out;
	}

	cmd_id = nla_get_u32(tb[ATH11K_TM_ATTR_WMI_CMDID]);

	/* Make sure that the buffer length is long enough to
	 * hold TLV and pdev/vdev id.
	 */
	if (buf_len < sizeof(struct wmi_tlv) + sizeof(u32)) {
		ret = -EINVAL;
		goto out;
	}

	ptr = buf;
	tag = FIELD_GET(WMI_TLV_TAG, *ptr);

	/* pdev/vdev id start after TLV header */
	ptr++;

	if (tag == WMI_TAG_PDEV_SET_PARAM_CMD)
		*ptr = ar->pdev->pdev_id;

	if (ar->ab->fw_mode != ATH11K_FIRMWARE_MODE_FTM &&
	    (tag == WMI_TAG_VDEV_SET_PARAM_CMD || tag == WMI_TAG_UNIT_TEST_CMD)) {
		if (vif) {
			arvif = ath11k_vif_to_arvif(vif);
			*ptr = arvif->vdev_id;
		} else {
			ret = -EINVAL;
			goto out;
		}
	}

	ath11k_dbg(ar->ab, ATH11K_DBG_TESTMODE,
		   "cmd wmi cmd_id %d buf length %d\n",
		   cmd_id, buf_len);

	ath11k_dbg_dump(ar->ab, ATH11K_DBG_TESTMODE, NULL, "", buf, buf_len);

	skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, buf_len);
	if (!skb) {
		ret = -ENOMEM;
		goto out;
	}

	memcpy(skb->data, buf, buf_len);

	ret = ath11k_wmi_cmd_send(wmi, skb, cmd_id);
	if (ret) {
		dev_kfree_skb(skb);
		ath11k_warn(ar->ab, "failed to transmit wmi command (testmode): %d\n",
			    ret);
		goto out;
	}

	ret = 0;

out:
	mutex_unlock(&ar->conf_mutex);
	return ret;
}

static int ath11k_tm_cmd_wmi_ftm(struct ath11k *ar, struct nlattr *tb[])
{
	struct ath11k_pdev_wmi *wmi = ar->wmi;
	struct ath11k_base *ab = ar->ab;
	struct sk_buff *skb;
	u32 cmd_id, buf_len, hdr_info;
	int ret;
	void *buf;
	u8 segnumber = 0, seginfo;
	u16 chunk_len, total_bytes, num_segments;
	u8 *bufpos;
	struct wmi_ftm_cmd *ftm_cmd;

	set_bit(ATH11K_FLAG_FTM_SEGMENTED, &ab->dev_flags);

	mutex_lock(&ar->conf_mutex);

	if (ar->state != ATH11K_STATE_FTM) {
		ret = -ENETDOWN;
		goto out;
	}

	if (!tb[ATH11K_TM_ATTR_DATA]) {
		ret = -EINVAL;
		goto out;
	}

	buf = nla_data(tb[ATH11K_TM_ATTR_DATA]);
	buf_len = nla_len(tb[ATH11K_TM_ATTR_DATA]);
	cmd_id = WMI_PDEV_UTF_CMDID;

	ath11k_dbg(ar->ab, ATH11K_DBG_TESTMODE,
		   "cmd wmi ftm cmd_id %d buffer length %d\n",
		   cmd_id, buf_len);
	ath11k_dbg_dump(ar->ab, ATH11K_DBG_TESTMODE, NULL, "", buf, buf_len);

	bufpos = buf;
	total_bytes = buf_len;
	num_segments = total_bytes / MAX_WMI_UTF_LEN;

	if (buf_len - (num_segments * MAX_WMI_UTF_LEN))
		num_segments++;

	while (buf_len) {
		chunk_len = min_t(u16, buf_len, MAX_WMI_UTF_LEN);

		skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, (chunk_len +
					   sizeof(struct wmi_ftm_cmd)));
		if (!skb) {
			ret = -ENOMEM;
			goto out;
		}

		ftm_cmd = (struct wmi_ftm_cmd *)skb->data;
		hdr_info = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ARRAY_BYTE) |
			   FIELD_PREP(WMI_TLV_LEN, (chunk_len +
				      sizeof(struct wmi_ftm_seg_hdr)));
		ftm_cmd->tlv_header = hdr_info;
		ftm_cmd->seg_hdr.len = total_bytes;
		ftm_cmd->seg_hdr.msgref = ar->ftm_msgref;
		seginfo = FIELD_PREP(ATH11K_FTM_SEGHDR_TOTAL_SEGMENTS, num_segments) |
			  FIELD_PREP(ATH11K_FTM_SEGHDR_CURRENT_SEQ, segnumber);
		ftm_cmd->seg_hdr.segmentinfo = seginfo;
		segnumber++;

		memcpy(&ftm_cmd->data, bufpos, chunk_len);

		ret = ath11k_wmi_cmd_send(wmi, skb, cmd_id);
		if (ret) {
			ath11k_warn(ar->ab, "failed to send wmi ftm command: %d\n", ret);
			goto out;
		}

		buf_len -= chunk_len;
		bufpos += chunk_len;
	}

	ar->ftm_msgref++;
	ret = 0;

out:
	mutex_unlock(&ar->conf_mutex);
	return ret;
}

int ath11k_tm_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
		  void *data, int len)
{
	struct ath11k *ar = hw->priv;
	struct nlattr *tb[ATH11K_TM_ATTR_MAX + 1];
	int ret;

	ret = nla_parse(tb, ATH11K_TM_ATTR_MAX, data, len, ath11k_tm_policy,
			NULL);
	if (ret)
		return ret;

	if (!tb[ATH11K_TM_ATTR_CMD])
		return -EINVAL;

	switch (nla_get_u32(tb[ATH11K_TM_ATTR_CMD])) {
	case ATH11K_TM_CMD_GET_VERSION:
		return ath11k_tm_cmd_get_version(ar, tb);
	case ATH11K_TM_CMD_WMI:
		return ath11k_tm_cmd_wmi(ar, tb, vif);
	case ATH11K_TM_CMD_TESTMODE_START:
		return ath11k_tm_cmd_testmode_start(ar, tb);
	case ATH11K_TM_CMD_WMI_FTM:
		return ath11k_tm_cmd_wmi_ftm(ar, tb);
	default:
		return -EOPNOTSUPP;
	}
}
