// SPDX-License-Identifier: GPL-2.0+
// Copyright (c) 2021-2021 Hisilicon Limited.
#include <linux/skbuff.h>

#include "hnae3.h"
#include "hclge_comm_cmd.h"
#include "hclge_comm_rss.h"

static const u8 hclge_comm_hash_key[] = {
	0x6D, 0x5A, 0x56, 0xDA, 0x25, 0x5B, 0x0E, 0xC2,
	0x41, 0x67, 0x25, 0x3D, 0x43, 0xA3, 0x8F, 0xB0,
	0xD0, 0xCA, 0x2B, 0xCB, 0xAE, 0x7B, 0x30, 0xB4,
	0x77, 0xCB, 0x2D, 0xA3, 0x80, 0x30, 0xF2, 0x0C,
	0x6A, 0x42, 0xB7, 0x3B, 0xBE, 0xAC, 0x01, 0xFA
};

static void
hclge_comm_init_rss_tuple(struct hnae3_ae_dev *ae_dev,
			  struct hclge_comm_rss_tuple_cfg *rss_tuple_cfg)
{
	rss_tuple_cfg->ipv4_tcp_en = HCLGE_COMM_RSS_INPUT_TUPLE_OTHER;
	rss_tuple_cfg->ipv4_udp_en = HCLGE_COMM_RSS_INPUT_TUPLE_OTHER;
	rss_tuple_cfg->ipv4_sctp_en = HCLGE_COMM_RSS_INPUT_TUPLE_SCTP;
	rss_tuple_cfg->ipv4_fragment_en = HCLGE_COMM_RSS_INPUT_TUPLE_OTHER;
	rss_tuple_cfg->ipv6_tcp_en = HCLGE_COMM_RSS_INPUT_TUPLE_OTHER;
	rss_tuple_cfg->ipv6_udp_en = HCLGE_COMM_RSS_INPUT_TUPLE_OTHER;
	rss_tuple_cfg->ipv6_sctp_en =
		ae_dev->dev_version <= HNAE3_DEVICE_VERSION_V2 ?
		HCLGE_COMM_RSS_INPUT_TUPLE_SCTP_NO_PORT :
		HCLGE_COMM_RSS_INPUT_TUPLE_SCTP;
	rss_tuple_cfg->ipv6_fragment_en = HCLGE_COMM_RSS_INPUT_TUPLE_OTHER;
}

int hclge_comm_rss_init_cfg(struct hnae3_handle *nic,
			    struct hnae3_ae_dev *ae_dev,
			    struct hclge_comm_rss_cfg *rss_cfg)
{
	u16 rss_ind_tbl_size = ae_dev->dev_specs.rss_ind_tbl_size;
	int rss_algo = HCLGE_COMM_RSS_HASH_ALGO_TOEPLITZ;
	u16 *rss_ind_tbl;

	if (nic->flags & HNAE3_SUPPORT_VF)
		rss_cfg->rss_size = nic->kinfo.rss_size;

	if (ae_dev->dev_version >= HNAE3_DEVICE_VERSION_V2)
		rss_algo = HCLGE_COMM_RSS_HASH_ALGO_SIMPLE;

	hclge_comm_init_rss_tuple(ae_dev, &rss_cfg->rss_tuple_sets);

	rss_cfg->rss_algo = rss_algo;

	rss_ind_tbl = devm_kcalloc(&ae_dev->pdev->dev, rss_ind_tbl_size,
				   sizeof(*rss_ind_tbl), GFP_KERNEL);
	if (!rss_ind_tbl)
		return -ENOMEM;

	rss_cfg->rss_indirection_tbl = rss_ind_tbl;
	memcpy(rss_cfg->rss_hash_key, hclge_comm_hash_key,
	       HCLGE_COMM_RSS_KEY_SIZE);

	hclge_comm_rss_indir_init_cfg(ae_dev, rss_cfg);

	return 0;
}

void hclge_comm_get_rss_tc_info(u16 rss_size, u8 hw_tc_map, u16 *tc_offset,
				u16 *tc_valid, u16 *tc_size)
{
	u16 roundup_size;
	u32 i;

	roundup_size = roundup_pow_of_two(rss_size);
	roundup_size = ilog2(roundup_size);

	for (i = 0; i < HCLGE_COMM_MAX_TC_NUM; i++) {
		tc_valid[i] = 1;
		tc_size[i] = roundup_size;
		tc_offset[i] = (hw_tc_map & BIT(i)) ? rss_size * i : 0;
	}
}

int hclge_comm_set_rss_tc_mode(struct hclge_comm_hw *hw, u16 *tc_offset,
			       u16 *tc_valid, u16 *tc_size)
{
	struct hclge_comm_rss_tc_mode_cmd *req;
	struct hclge_desc desc;
	unsigned int i;
	int ret;

	req = (struct hclge_comm_rss_tc_mode_cmd *)desc.data;

	hclge_comm_cmd_setup_basic_desc(&desc, HCLGE_OPC_RSS_TC_MODE, false);
	for (i = 0; i < HCLGE_COMM_MAX_TC_NUM; i++) {
		u16 mode = 0;

		hnae3_set_bit(mode, HCLGE_COMM_RSS_TC_VALID_B,
			      (tc_valid[i] & 0x1));
		hnae3_set_field(mode, HCLGE_COMM_RSS_TC_SIZE_M,
				HCLGE_COMM_RSS_TC_SIZE_S, tc_size[i]);
		hnae3_set_bit(mode, HCLGE_COMM_RSS_TC_SIZE_MSB_B,
			      tc_size[i] >> HCLGE_COMM_RSS_TC_SIZE_MSB_OFFSET &
			      0x1);
		hnae3_set_field(mode, HCLGE_COMM_RSS_TC_OFFSET_M,
				HCLGE_COMM_RSS_TC_OFFSET_S, tc_offset[i]);

		req->rss_tc_mode[i] = cpu_to_le16(mode);
	}

	ret = hclge_comm_cmd_send(hw, &desc, 1);
	if (ret)
		dev_err(&hw->cmq.csq.pdev->dev,
			"failed to set rss tc mode, ret = %d.\n", ret);

	return ret;
}

int hclge_comm_set_rss_hash_key(struct hclge_comm_rss_cfg *rss_cfg,
				struct hclge_comm_hw *hw, const u8 *key,
				const u8 hfunc)
{
	u8 hash_algo;
	int ret;

	ret = hclge_comm_parse_rss_hfunc(rss_cfg, hfunc, &hash_algo);
	if (ret)
		return ret;

	/* Set the RSS Hash Key if specififed by the user */
	if (key) {
		ret = hclge_comm_set_rss_algo_key(hw, hash_algo, key);
		if (ret)
			return ret;

		/* Update the shadow RSS key with user specified qids */
		memcpy(rss_cfg->rss_hash_key, key, HCLGE_COMM_RSS_KEY_SIZE);
	} else {
		ret = hclge_comm_set_rss_algo_key(hw, hash_algo,
						  rss_cfg->rss_hash_key);
		if (ret)
			return ret;
	}
	rss_cfg->rss_algo = hash_algo;

	return 0;
}

int hclge_comm_set_rss_tuple(struct hnae3_ae_dev *ae_dev,
			     struct hclge_comm_hw *hw,
			     struct hclge_comm_rss_cfg *rss_cfg,
			     struct ethtool_rxnfc *nfc)
{
	struct hclge_comm_rss_input_tuple_cmd *req;
	struct hclge_desc desc;
	int ret;

	if (nfc->data &
	    ~(RXH_IP_SRC | RXH_IP_DST | RXH_L4_B_0_1 | RXH_L4_B_2_3))
		return -EINVAL;

	req = (struct hclge_comm_rss_input_tuple_cmd *)desc.data;
	hclge_comm_cmd_setup_basic_desc(&desc, HCLGE_OPC_RSS_INPUT_TUPLE,
					false);

	ret = hclge_comm_init_rss_tuple_cmd(rss_cfg, nfc, ae_dev, req);
	if (ret) {
		dev_err(&hw->cmq.csq.pdev->dev,
			"failed to init rss tuple cmd, ret = %d.\n", ret);
		return ret;
	}

	ret = hclge_comm_cmd_send(hw, &desc, 1);
	if (ret) {
		dev_err(&hw->cmq.csq.pdev->dev,
			"failed to set rss tuple, ret = %d.\n", ret);
		return ret;
	}

	rss_cfg->rss_tuple_sets.ipv4_tcp_en = req->ipv4_tcp_en;
	rss_cfg->rss_tuple_sets.ipv4_udp_en = req->ipv4_udp_en;
	rss_cfg->rss_tuple_sets.ipv4_sctp_en = req->ipv4_sctp_en;
	rss_cfg->rss_tuple_sets.ipv4_fragment_en = req->ipv4_fragment_en;
	rss_cfg->rss_tuple_sets.ipv6_tcp_en = req->ipv6_tcp_en;
	rss_cfg->rss_tuple_sets.ipv6_udp_en = req->ipv6_udp_en;
	rss_cfg->rss_tuple_sets.ipv6_sctp_en = req->ipv6_sctp_en;
	rss_cfg->rss_tuple_sets.ipv6_fragment_en = req->ipv6_fragment_en;
	return 0;
}

u32 hclge_comm_get_rss_key_size(struct hnae3_handle *handle)
{
	return HCLGE_COMM_RSS_KEY_SIZE;
}

void hclge_comm_get_rss_type(struct hnae3_handle *nic,
			     struct hclge_comm_rss_tuple_cfg *rss_tuple_sets)
{
	if (rss_tuple_sets->ipv4_tcp_en ||
	    rss_tuple_sets->ipv4_udp_en ||
	    rss_tuple_sets->ipv4_sctp_en ||
	    rss_tuple_sets->ipv6_tcp_en ||
	    rss_tuple_sets->ipv6_udp_en ||
	    rss_tuple_sets->ipv6_sctp_en)
		nic->kinfo.rss_type = PKT_HASH_TYPE_L4;
	else if (rss_tuple_sets->ipv4_fragment_en ||
		 rss_tuple_sets->ipv6_fragment_en)
		nic->kinfo.rss_type = PKT_HASH_TYPE_L3;
	else
		nic->kinfo.rss_type = PKT_HASH_TYPE_NONE;
}

int hclge_comm_parse_rss_hfunc(struct hclge_comm_rss_cfg *rss_cfg,
			       const u8 hfunc, u8 *hash_algo)
{
	switch (hfunc) {
	case ETH_RSS_HASH_TOP:
		*hash_algo = HCLGE_COMM_RSS_HASH_ALGO_TOEPLITZ;
		return 0;
	case ETH_RSS_HASH_XOR:
		*hash_algo = HCLGE_COMM_RSS_HASH_ALGO_SIMPLE;
		return 0;
	case ETH_RSS_HASH_NO_CHANGE:
		*hash_algo = rss_cfg->rss_algo;
		return 0;
	default:
		return -EINVAL;
	}
}

void hclge_comm_rss_indir_init_cfg(struct hnae3_ae_dev *ae_dev,
				   struct hclge_comm_rss_cfg *rss_cfg)
{
	u16 i;
	/* Initialize RSS indirect table */
	for (i = 0; i < ae_dev->dev_specs.rss_ind_tbl_size; i++)
		rss_cfg->rss_indirection_tbl[i] = i % rss_cfg->rss_size;
}

int hclge_comm_get_rss_tuple(struct hclge_comm_rss_cfg *rss_cfg, int flow_type,
			     u8 *tuple_sets)
{
	switch (flow_type) {
	case TCP_V4_FLOW:
		*tuple_sets = rss_cfg->rss_tuple_sets.ipv4_tcp_en;
		break;
	case UDP_V4_FLOW:
		*tuple_sets = rss_cfg->rss_tuple_sets.ipv4_udp_en;
		break;
	case TCP_V6_FLOW:
		*tuple_sets = rss_cfg->rss_tuple_sets.ipv6_tcp_en;
		break;
	case UDP_V6_FLOW:
		*tuple_sets = rss_cfg->rss_tuple_sets.ipv6_udp_en;
		break;
	case SCTP_V4_FLOW:
		*tuple_sets = rss_cfg->rss_tuple_sets.ipv4_sctp_en;
		break;
	case SCTP_V6_FLOW:
		*tuple_sets = rss_cfg->rss_tuple_sets.ipv6_sctp_en;
		break;
	case IPV4_FLOW:
	case IPV6_FLOW:
		*tuple_sets = HCLGE_COMM_S_IP_BIT | HCLGE_COMM_D_IP_BIT;
		break;
	default:
		return -EINVAL;
	}

	return 0;
}

static void
hclge_comm_append_rss_msb_info(struct hclge_comm_rss_ind_tbl_cmd *req,
			       u16 qid, u32 j)
{
	u8 rss_msb_oft;
	u8 rss_msb_val;

	rss_msb_oft =
		j * HCLGE_COMM_RSS_CFG_TBL_BW_H / BITS_PER_BYTE;
	rss_msb_val = (qid >> HCLGE_COMM_RSS_CFG_TBL_BW_L & 0x1) <<
		(j * HCLGE_COMM_RSS_CFG_TBL_BW_H % BITS_PER_BYTE);
	req->rss_qid_h[rss_msb_oft] |= rss_msb_val;
}

int hclge_comm_set_rss_indir_table(struct hnae3_ae_dev *ae_dev,
				   struct hclge_comm_hw *hw, const u16 *indir)
{
	struct hclge_comm_rss_ind_tbl_cmd *req;
	struct hclge_desc desc;
	u16 rss_cfg_tbl_num;
	int ret;
	u16 qid;
	u16 i;
	u32 j;

	req = (struct hclge_comm_rss_ind_tbl_cmd *)desc.data;
	rss_cfg_tbl_num = ae_dev->dev_specs.rss_ind_tbl_size /
			  HCLGE_COMM_RSS_CFG_TBL_SIZE;

	for (i = 0; i < rss_cfg_tbl_num; i++) {
		hclge_comm_cmd_setup_basic_desc(&desc,
						HCLGE_OPC_RSS_INDIR_TABLE,
						false);

		req->start_table_index =
			cpu_to_le16(i * HCLGE_COMM_RSS_CFG_TBL_SIZE);
		req->rss_set_bitmap =
			cpu_to_le16(HCLGE_COMM_RSS_SET_BITMAP_MSK);
		for (j = 0; j < HCLGE_COMM_RSS_CFG_TBL_SIZE; j++) {
			qid = indir[i * HCLGE_COMM_RSS_CFG_TBL_SIZE + j];
			req->rss_qid_l[j] = qid & 0xff;
			hclge_comm_append_rss_msb_info(req, qid, j);
		}
		ret = hclge_comm_cmd_send(hw, &desc, 1);
		if (ret) {
			dev_err(&hw->cmq.csq.pdev->dev,
				"failed to configure rss table, ret = %d.\n",
				ret);
			return ret;
		}
	}
	return 0;
}

int hclge_comm_set_rss_input_tuple(struct hnae3_handle *nic,
				   struct hclge_comm_hw *hw, bool is_pf,
				   struct hclge_comm_rss_cfg *rss_cfg)
{
	struct hclge_comm_rss_input_tuple_cmd *req;
	struct hclge_desc desc;
	int ret;

	hclge_comm_cmd_setup_basic_desc(&desc, HCLGE_OPC_RSS_INPUT_TUPLE,
					false);

	req = (struct hclge_comm_rss_input_tuple_cmd *)desc.data;

	req->ipv4_tcp_en = rss_cfg->rss_tuple_sets.ipv4_tcp_en;
	req->ipv4_udp_en = rss_cfg->rss_tuple_sets.ipv4_udp_en;
	req->ipv4_sctp_en = rss_cfg->rss_tuple_sets.ipv4_sctp_en;
	req->ipv4_fragment_en = rss_cfg->rss_tuple_sets.ipv4_fragment_en;
	req->ipv6_tcp_en = rss_cfg->rss_tuple_sets.ipv6_tcp_en;
	req->ipv6_udp_en = rss_cfg->rss_tuple_sets.ipv6_udp_en;
	req->ipv6_sctp_en = rss_cfg->rss_tuple_sets.ipv6_sctp_en;
	req->ipv6_fragment_en = rss_cfg->rss_tuple_sets.ipv6_fragment_en;

	if (is_pf)
		hclge_comm_get_rss_type(nic, &rss_cfg->rss_tuple_sets);

	ret = hclge_comm_cmd_send(hw, &desc, 1);
	if (ret)
		dev_err(&hw->cmq.csq.pdev->dev,
			"failed to configure rss input, ret = %d.\n", ret);
	return ret;
}

void hclge_comm_get_rss_hash_info(struct hclge_comm_rss_cfg *rss_cfg, u8 *key,
				  u8 *hfunc)
{
	/* Get hash algorithm */
	if (hfunc) {
		switch (rss_cfg->rss_algo) {
		case HCLGE_COMM_RSS_HASH_ALGO_TOEPLITZ:
			*hfunc = ETH_RSS_HASH_TOP;
			break;
		case HCLGE_COMM_RSS_HASH_ALGO_SIMPLE:
			*hfunc = ETH_RSS_HASH_XOR;
			break;
		default:
			*hfunc = ETH_RSS_HASH_UNKNOWN;
			break;
		}
	}

	/* Get the RSS Key required by the user */
	if (key)
		memcpy(key, rss_cfg->rss_hash_key, HCLGE_COMM_RSS_KEY_SIZE);
}

void hclge_comm_get_rss_indir_tbl(struct hclge_comm_rss_cfg *rss_cfg,
				  u32 *indir, u16 rss_ind_tbl_size)
{
	u16 i;

	if (!indir)
		return;

	for (i = 0; i < rss_ind_tbl_size; i++)
		indir[i] = rss_cfg->rss_indirection_tbl[i];
}

int hclge_comm_set_rss_algo_key(struct hclge_comm_hw *hw, const u8 hfunc,
				const u8 *key)
{
	struct hclge_comm_rss_config_cmd *req;
	unsigned int key_offset = 0;
	struct hclge_desc desc;
	int key_counts;
	int key_size;
	int ret;

	key_counts = HCLGE_COMM_RSS_KEY_SIZE;
	req = (struct hclge_comm_rss_config_cmd *)desc.data;

	while (key_counts) {
		hclge_comm_cmd_setup_basic_desc(&desc,
						HCLGE_OPC_RSS_GENERIC_CONFIG,
						false);

		req->hash_config |= (hfunc & HCLGE_COMM_RSS_HASH_ALGO_MASK);
		req->hash_config |=
			(key_offset << HCLGE_COMM_RSS_HASH_KEY_OFFSET_B);

		key_size = min(HCLGE_COMM_RSS_HASH_KEY_NUM, key_counts);
		memcpy(req->hash_key,
		       key + key_offset * HCLGE_COMM_RSS_HASH_KEY_NUM,
		       key_size);

		key_counts -= key_size;
		key_offset++;
		ret = hclge_comm_cmd_send(hw, &desc, 1);
		if (ret) {
			dev_err(&hw->cmq.csq.pdev->dev,
				"failed to configure RSS key, ret = %d.\n",
				ret);
			return ret;
		}
	}

	return 0;
}

static u8 hclge_comm_get_rss_hash_bits(struct ethtool_rxnfc *nfc)
{
	u8 hash_sets = nfc->data & RXH_L4_B_0_1 ? HCLGE_COMM_S_PORT_BIT : 0;

	if (nfc->data & RXH_L4_B_2_3)
		hash_sets |= HCLGE_COMM_D_PORT_BIT;
	else
		hash_sets &= ~HCLGE_COMM_D_PORT_BIT;

	if (nfc->data & RXH_IP_SRC)
		hash_sets |= HCLGE_COMM_S_IP_BIT;
	else
		hash_sets &= ~HCLGE_COMM_S_IP_BIT;

	if (nfc->data & RXH_IP_DST)
		hash_sets |= HCLGE_COMM_D_IP_BIT;
	else
		hash_sets &= ~HCLGE_COMM_D_IP_BIT;

	if (nfc->flow_type == SCTP_V4_FLOW || nfc->flow_type == SCTP_V6_FLOW)
		hash_sets |= HCLGE_COMM_V_TAG_BIT;

	return hash_sets;
}

int hclge_comm_init_rss_tuple_cmd(struct hclge_comm_rss_cfg *rss_cfg,
				  struct ethtool_rxnfc *nfc,
				  struct hnae3_ae_dev *ae_dev,
				  struct hclge_comm_rss_input_tuple_cmd *req)
{
	u8 tuple_sets;

	req->ipv4_tcp_en = rss_cfg->rss_tuple_sets.ipv4_tcp_en;
	req->ipv4_udp_en = rss_cfg->rss_tuple_sets.ipv4_udp_en;
	req->ipv4_sctp_en = rss_cfg->rss_tuple_sets.ipv4_sctp_en;
	req->ipv4_fragment_en = rss_cfg->rss_tuple_sets.ipv4_fragment_en;
	req->ipv6_tcp_en = rss_cfg->rss_tuple_sets.ipv6_tcp_en;
	req->ipv6_udp_en = rss_cfg->rss_tuple_sets.ipv6_udp_en;
	req->ipv6_sctp_en = rss_cfg->rss_tuple_sets.ipv6_sctp_en;
	req->ipv6_fragment_en = rss_cfg->rss_tuple_sets.ipv6_fragment_en;

	tuple_sets = hclge_comm_get_rss_hash_bits(nfc);
	switch (nfc->flow_type) {
	case TCP_V4_FLOW:
		req->ipv4_tcp_en = tuple_sets;
		break;
	case TCP_V6_FLOW:
		req->ipv6_tcp_en = tuple_sets;
		break;
	case UDP_V4_FLOW:
		req->ipv4_udp_en = tuple_sets;
		break;
	case UDP_V6_FLOW:
		req->ipv6_udp_en = tuple_sets;
		break;
	case SCTP_V4_FLOW:
		req->ipv4_sctp_en = tuple_sets;
		break;
	case SCTP_V6_FLOW:
		if (ae_dev->dev_version <= HNAE3_DEVICE_VERSION_V2 &&
		    (nfc->data & (RXH_L4_B_0_1 | RXH_L4_B_2_3)))
			return -EINVAL;

		req->ipv6_sctp_en = tuple_sets;
		break;
	case IPV4_FLOW:
		req->ipv4_fragment_en = HCLGE_COMM_RSS_INPUT_TUPLE_OTHER;
		break;
	case IPV6_FLOW:
		req->ipv6_fragment_en = HCLGE_COMM_RSS_INPUT_TUPLE_OTHER;
		break;
	default:
		return -EINVAL;
	}

	return 0;
}

u64 hclge_comm_convert_rss_tuple(u8 tuple_sets)
{
	u64 tuple_data = 0;

	if (tuple_sets & HCLGE_COMM_D_PORT_BIT)
		tuple_data |= RXH_L4_B_2_3;
	if (tuple_sets & HCLGE_COMM_S_PORT_BIT)
		tuple_data |= RXH_L4_B_0_1;
	if (tuple_sets & HCLGE_COMM_D_IP_BIT)
		tuple_data |= RXH_IP_DST;
	if (tuple_sets & HCLGE_COMM_S_IP_BIT)
		tuple_data |= RXH_IP_SRC;

	return tuple_data;
}
