// SPDX-License-Identifier: GPL-2.0-only
/*
 * Implementation of chip-to-host event (aka indications) of WFxxx Split Mac
 * (WSM) API.
 *
 * Copyright (c) 2017-2020, Silicon Laboratories, Inc.
 * Copyright (c) 2010, ST-Ericsson
 */
#include <linux/skbuff.h>
#include <linux/etherdevice.h>

#include "hif_rx.h"
#include "wfx.h"
#include "scan.h"
#include "bh.h"
#include "sta.h"
#include "data_rx.h"
#include "hif_api_cmd.h"

static int hif_generic_confirm(struct wfx_dev *wdev,
			       const struct hif_msg *hif, const void *buf)
{
	// All confirm messages start with status
	int status = le32_to_cpup((__le32 *)buf);
	int cmd = hif->id;
	int len = le16_to_cpu(hif->len) - 4; // drop header

	WARN(!mutex_is_locked(&wdev->hif_cmd.lock), "data locking error");

	if (!wdev->hif_cmd.buf_send) {
		dev_warn(wdev->dev, "unexpected confirmation: 0x%.2x\n", cmd);
		return -EINVAL;
	}

	if (cmd != wdev->hif_cmd.buf_send->id) {
		dev_warn(wdev->dev,
			 "chip response mismatch request: 0x%.2x vs 0x%.2x\n",
			 cmd, wdev->hif_cmd.buf_send->id);
		return -EINVAL;
	}

	if (wdev->hif_cmd.buf_recv) {
		if (wdev->hif_cmd.len_recv >= len && len > 0)
			memcpy(wdev->hif_cmd.buf_recv, buf, len);
		else
			status = -EIO;
	}
	wdev->hif_cmd.ret = status;

	complete(&wdev->hif_cmd.done);
	return status;
}

static int hif_tx_confirm(struct wfx_dev *wdev,
			  const struct hif_msg *hif, const void *buf)
{
	const struct hif_cnf_tx *body = buf;

	wfx_tx_confirm_cb(wdev, body);
	return 0;
}

static int hif_multi_tx_confirm(struct wfx_dev *wdev,
				const struct hif_msg *hif, const void *buf)
{
	const struct hif_cnf_multi_transmit *body = buf;
	int i;

	WARN(body->num_tx_confs <= 0, "corrupted message");
	for (i = 0; i < body->num_tx_confs; i++)
		wfx_tx_confirm_cb(wdev, &body->tx_conf_payload[i]);
	return 0;
}

static int hif_startup_indication(struct wfx_dev *wdev,
				  const struct hif_msg *hif, const void *buf)
{
	const struct hif_ind_startup *body = buf;

	if (body->status || body->firmware_type > 4) {
		dev_err(wdev->dev, "received invalid startup indication");
		return -EINVAL;
	}
	memcpy(&wdev->hw_caps, body, sizeof(struct hif_ind_startup));
	le16_to_cpus((__le16 *)&wdev->hw_caps.hardware_id);
	le16_to_cpus((__le16 *)&wdev->hw_caps.num_inp_ch_bufs);
	le16_to_cpus((__le16 *)&wdev->hw_caps.size_inp_ch_buf);
	le32_to_cpus((__le32 *)&wdev->hw_caps.supported_rate_mask);

	complete(&wdev->firmware_ready);
	return 0;
}

static int hif_wakeup_indication(struct wfx_dev *wdev,
				 const struct hif_msg *hif, const void *buf)
{
	if (!wdev->pdata.gpio_wakeup ||
	    gpiod_get_value(wdev->pdata.gpio_wakeup) == 0) {
		dev_warn(wdev->dev, "unexpected wake-up indication\n");
		return -EIO;
	}
	return 0;
}

static int hif_receive_indication(struct wfx_dev *wdev,
				  const struct hif_msg *hif,
				  const void *buf, struct sk_buff *skb)
{
	struct wfx_vif *wvif = wdev_to_wvif(wdev, hif->interface);
	const struct hif_ind_rx *body = buf;

	if (!wvif) {
		dev_warn(wdev->dev, "%s: ignore rx data for non-existent vif %d\n",
			 __func__, hif->interface);
		return -EIO;
	}
	skb_pull(skb, sizeof(struct hif_msg) + sizeof(struct hif_ind_rx));
	wfx_rx_cb(wvif, body, skb);

	return 0;
}

static int hif_event_indication(struct wfx_dev *wdev,
				const struct hif_msg *hif, const void *buf)
{
	struct wfx_vif *wvif = wdev_to_wvif(wdev, hif->interface);
	const struct hif_ind_event *body = buf;
	int type = le32_to_cpu(body->event_id);

	if (!wvif) {
		dev_warn(wdev->dev, "%s: received event for non-existent vif\n", __func__);
		return -EIO;
	}

	switch (type) {
	case HIF_EVENT_IND_RCPI_RSSI:
		wfx_event_report_rssi(wvif, body->event_data.rcpi_rssi);
		break;
	case HIF_EVENT_IND_BSSLOST:
		schedule_delayed_work(&wvif->beacon_loss_work, 0);
		break;
	case HIF_EVENT_IND_BSSREGAINED:
		cancel_delayed_work(&wvif->beacon_loss_work);
		dev_dbg(wdev->dev, "ignore BSSREGAINED indication\n");
		break;
	case HIF_EVENT_IND_PS_MODE_ERROR:
		dev_warn(wdev->dev, "error while processing power save request: %d\n",
			 le32_to_cpu(body->event_data.ps_mode_error));
		break;
	default:
		dev_warn(wdev->dev, "unhandled event indication: %.2x\n",
			 type);
		break;
	}
	return 0;
}

static int hif_pm_mode_complete_indication(struct wfx_dev *wdev,
					   const struct hif_msg *hif,
					   const void *buf)
{
	struct wfx_vif *wvif = wdev_to_wvif(wdev, hif->interface);

	if (!wvif) {
		dev_warn(wdev->dev, "%s: received event for non-existent vif\n", __func__);
		return -EIO;
	}
	complete(&wvif->set_pm_mode_complete);

	return 0;
}

static int hif_scan_complete_indication(struct wfx_dev *wdev,
					const struct hif_msg *hif,
					const void *buf)
{
	struct wfx_vif *wvif = wdev_to_wvif(wdev, hif->interface);

	if (!wvif) {
		dev_warn(wdev->dev, "%s: received event for non-existent vif\n", __func__);
		return -EIO;
	}

	wfx_scan_complete(wvif);

	return 0;
}

static int hif_join_complete_indication(struct wfx_dev *wdev,
					const struct hif_msg *hif,
					const void *buf)
{
	struct wfx_vif *wvif = wdev_to_wvif(wdev, hif->interface);

	if (!wvif) {
		dev_warn(wdev->dev, "%s: received event for non-existent vif\n", __func__);
		return -EIO;
	}
	dev_warn(wdev->dev, "unattended JoinCompleteInd\n");

	return 0;
}

static int hif_suspend_resume_indication(struct wfx_dev *wdev,
					 const struct hif_msg *hif,
					 const void *buf)
{
	const struct hif_ind_suspend_resume_tx *body = buf;
	struct wfx_vif *wvif;

	if (body->bc_mc_only) {
		wvif = wdev_to_wvif(wdev, hif->interface);
		if (!wvif) {
			dev_warn(wdev->dev, "%s: received event for non-existent vif\n", __func__);
			return -EIO;
		}
		if (body->resume)
			wfx_suspend_resume_mc(wvif, STA_NOTIFY_AWAKE);
		else
			wfx_suspend_resume_mc(wvif, STA_NOTIFY_SLEEP);
	} else {
		WARN(body->peer_sta_set, "misunderstood indication");
		WARN(hif->interface != 2, "misunderstood indication");
		if (body->resume)
			wfx_suspend_hot_dev(wdev, STA_NOTIFY_AWAKE);
		else
			wfx_suspend_hot_dev(wdev, STA_NOTIFY_SLEEP);
	}

	return 0;
}

static int hif_generic_indication(struct wfx_dev *wdev,
				  const struct hif_msg *hif, const void *buf)
{
	const struct hif_ind_generic *body = buf;
	int type = le32_to_cpu(body->type);

	switch (type) {
	case HIF_GENERIC_INDICATION_TYPE_RAW:
		return 0;
	case HIF_GENERIC_INDICATION_TYPE_STRING:
		dev_info(wdev->dev, "firmware says: %s\n", (char *)&body->data);
		return 0;
	case HIF_GENERIC_INDICATION_TYPE_RX_STATS:
		mutex_lock(&wdev->rx_stats_lock);
		// Older firmware send a generic indication beside RxStats
		if (!wfx_api_older_than(wdev, 1, 4))
			dev_info(wdev->dev, "Rx test ongoing. Temperature: %d degrees C\n",
				 body->data.rx_stats.current_temp);
		memcpy(&wdev->rx_stats, &body->data.rx_stats,
		       sizeof(wdev->rx_stats));
		mutex_unlock(&wdev->rx_stats_lock);
		return 0;
	case HIF_GENERIC_INDICATION_TYPE_TX_POWER_LOOP_INFO:
		mutex_lock(&wdev->tx_power_loop_info_lock);
		memcpy(&wdev->tx_power_loop_info,
		       &body->data.tx_power_loop_info,
		       sizeof(wdev->tx_power_loop_info));
		mutex_unlock(&wdev->tx_power_loop_info_lock);
		return 0;
	default:
		dev_err(wdev->dev, "generic_indication: unknown indication type: %#.8x\n",
			type);
		return -EIO;
	}
}

static const struct {
	int val;
	const char *str;
	bool has_param;
} hif_errors[] = {
	{ HIF_ERROR_FIRMWARE_ROLLBACK,
		"rollback status" },
	{ HIF_ERROR_FIRMWARE_DEBUG_ENABLED,
		"debug feature enabled" },
	{ HIF_ERROR_PDS_PAYLOAD,
		"PDS version is not supported" },
	{ HIF_ERROR_PDS_TESTFEATURE,
		"PDS ask for an unknown test mode" },
	{ HIF_ERROR_OOR_VOLTAGE,
		"out-of-range power supply voltage", true },
	{ HIF_ERROR_OOR_TEMPERATURE,
		"out-of-range temperature", true },
	{ HIF_ERROR_SLK_REQ_DURING_KEY_EXCHANGE,
		"secure link does not expect request during key exchange" },
	{ HIF_ERROR_SLK_SESSION_KEY,
		"secure link session key is invalid" },
	{ HIF_ERROR_SLK_OVERFLOW,
		"secure link overflow" },
	{ HIF_ERROR_SLK_WRONG_ENCRYPTION_STATE,
		"secure link messages list does not match message encryption" },
	{ HIF_ERROR_SLK_UNCONFIGURED,
		"secure link not yet configured" },
	{ HIF_ERROR_HIF_BUS_FREQUENCY_TOO_LOW,
		"bus clock is too slow (<1kHz)" },
	{ HIF_ERROR_HIF_RX_DATA_TOO_LARGE,
		"HIF message too large" },
	// Following errors only exists in old firmware versions:
	{ HIF_ERROR_HIF_TX_QUEUE_FULL,
		"HIF messages queue is full" },
	{ HIF_ERROR_HIF_BUS,
		"HIF bus" },
	{ HIF_ERROR_SLK_MULTI_TX_UNSUPPORTED,
		"secure link does not support multi-tx confirmations" },
	{ HIF_ERROR_SLK_OUTDATED_SESSION_KEY,
		"secure link session key is outdated" },
	{ HIF_ERROR_SLK_DECRYPTION,
		"secure link params (nonce or tag) mismatch" },
};

static int hif_error_indication(struct wfx_dev *wdev,
				const struct hif_msg *hif, const void *buf)
{
	const struct hif_ind_error *body = buf;
	int type = le32_to_cpu(body->type);
	int param = (s8)body->data[0];
	int i;

	for (i = 0; i < ARRAY_SIZE(hif_errors); i++)
		if (type == hif_errors[i].val)
			break;
	if (i < ARRAY_SIZE(hif_errors))
		if (hif_errors[i].has_param)
			dev_err(wdev->dev, "asynchronous error: %s: %d\n",
				hif_errors[i].str, param);
		else
			dev_err(wdev->dev, "asynchronous error: %s\n",
				hif_errors[i].str);
	else
		dev_err(wdev->dev, "asynchronous error: unknown: %08x\n", type);
	print_hex_dump(KERN_INFO, "hif: ", DUMP_PREFIX_OFFSET,
		       16, 1, hif, le16_to_cpu(hif->len), false);
	wdev->chip_frozen = true;

	return 0;
};

static int hif_exception_indication(struct wfx_dev *wdev,
				    const struct hif_msg *hif, const void *buf)
{
	const struct hif_ind_exception *body = buf;
	int type = le32_to_cpu(body->type);

	if (type == 4)
		dev_err(wdev->dev, "firmware assert %d\n",
			le32_to_cpup((__le32 *)body->data));
	else
		dev_err(wdev->dev, "firmware exception\n");
	print_hex_dump(KERN_INFO, "hif: ", DUMP_PREFIX_OFFSET,
		       16, 1, hif, le16_to_cpu(hif->len), false);
	wdev->chip_frozen = true;

	return -1;
}

static const struct {
	int msg_id;
	int (*handler)(struct wfx_dev *wdev,
		       const struct hif_msg *hif, const void *buf);
} hif_handlers[] = {
	/* Confirmations */
	{ HIF_CNF_ID_TX,                   hif_tx_confirm },
	{ HIF_CNF_ID_MULTI_TRANSMIT,       hif_multi_tx_confirm },
	/* Indications */
	{ HIF_IND_ID_STARTUP,              hif_startup_indication },
	{ HIF_IND_ID_WAKEUP,               hif_wakeup_indication },
	{ HIF_IND_ID_JOIN_COMPLETE,        hif_join_complete_indication },
	{ HIF_IND_ID_SET_PM_MODE_CMPL,     hif_pm_mode_complete_indication },
	{ HIF_IND_ID_SCAN_CMPL,            hif_scan_complete_indication },
	{ HIF_IND_ID_SUSPEND_RESUME_TX,    hif_suspend_resume_indication },
	{ HIF_IND_ID_EVENT,                hif_event_indication },
	{ HIF_IND_ID_GENERIC,              hif_generic_indication },
	{ HIF_IND_ID_ERROR,                hif_error_indication },
	{ HIF_IND_ID_EXCEPTION,            hif_exception_indication },
	// FIXME: allocate skb_p from hif_receive_indication and make it generic
	//{ HIF_IND_ID_RX,                 hif_receive_indication },
};

void wfx_handle_rx(struct wfx_dev *wdev, struct sk_buff *skb)
{
	int i;
	const struct hif_msg *hif = (const struct hif_msg *)skb->data;
	int hif_id = hif->id;

	if (hif_id == HIF_IND_ID_RX) {
		// hif_receive_indication take care of skb lifetime
		hif_receive_indication(wdev, hif, hif->body, skb);
		return;
	}
	// Note: mutex_is_lock cause an implicit memory barrier that protect
	// buf_send
	if (mutex_is_locked(&wdev->hif_cmd.lock) &&
	    wdev->hif_cmd.buf_send &&
	    wdev->hif_cmd.buf_send->id == hif_id) {
		hif_generic_confirm(wdev, hif, hif->body);
		goto free;
	}
	for (i = 0; i < ARRAY_SIZE(hif_handlers); i++) {
		if (hif_handlers[i].msg_id == hif_id) {
			if (hif_handlers[i].handler)
				hif_handlers[i].handler(wdev, hif, hif->body);
			goto free;
		}
	}
	if (hif_id & 0x80)
		dev_err(wdev->dev, "unsupported HIF indication: ID %02x\n",
			hif_id);
	else
		dev_err(wdev->dev, "unexpected HIF confirmation: ID %02x\n",
			hif_id);
free:
	dev_kfree_skb(skb);
}
