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

Commit 59d43876 authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'hnx3-rxnfc'



Lipeng says:

====================
Support set_ringparam and {set|get}_rxnfc ethtool commands

1, Patch [1/5,2/5] add support for ethtool ops set_ringparam
   (ethtool -G) and fix related bug.
2, Patch [3/5,4/5, 5/5] add support for ethtool ops
   set_rxnfc/get_rxnfc (-n/-N) and fix related bug.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 652faa98 abf11d04
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -339,6 +339,10 @@ struct hnae3_ae_ops {
		       u8 *hfunc);
	int (*set_rss)(struct hnae3_handle *handle, const u32 *indir,
		       const u8 *key, const u8 hfunc);
	int (*set_rss_tuple)(struct hnae3_handle *handle,
			     struct ethtool_rxnfc *cmd);
	int (*get_rss_tuple)(struct hnae3_handle *handle,
			     struct ethtool_rxnfc *cmd);

	int (*get_tc_size)(struct hnae3_handle *handle);

+9 −0
Original line number Diff line number Diff line
@@ -85,6 +85,15 @@ static int hclge_init_cmd_queue(struct hclge_dev *hdev, int ring_type)
	return 0;
}

void hclge_cmd_reuse_desc(struct hclge_desc *desc, bool is_read)
{
	desc->flag = cpu_to_le16(HCLGE_CMD_FLAG_NO_INTR | HCLGE_CMD_FLAG_IN);
	if (is_read)
		desc->flag |= cpu_to_le16(HCLGE_CMD_FLAG_WR);
	else
		desc->flag &= cpu_to_le16(~HCLGE_CMD_FLAG_WR);
}

void hclge_cmd_setup_basic_desc(struct hclge_desc *desc,
				enum hclge_opcode_type opcode, bool is_read)
{
+1 −0
Original line number Diff line number Diff line
@@ -739,6 +739,7 @@ struct hclge_hw;
int hclge_cmd_send(struct hclge_hw *hw, struct hclge_desc *desc, int num);
void hclge_cmd_setup_basic_desc(struct hclge_desc *desc,
				enum hclge_opcode_type opcode, bool is_read);
void hclge_cmd_reuse_desc(struct hclge_desc *desc, bool is_read);

int hclge_cmd_set_promisc_mode(struct hclge_dev *hdev,
			       struct hclge_promisc_param *param);
+157 −2
Original line number Diff line number Diff line
@@ -2595,8 +2595,6 @@ static int hclge_set_rss_tc_mode(struct hclge_dev *hdev, u16 *tc_valid,

static int hclge_set_rss_input_tuple(struct hclge_dev *hdev)
{
#define HCLGE_RSS_INPUT_TUPLE_OTHER		0xf
#define HCLGE_RSS_INPUT_TUPLE_SCTP		0x1f
	struct hclge_rss_input_tuple_cmd *req;
	struct hclge_desc desc;
	int ret;
@@ -2677,6 +2675,161 @@ static int hclge_set_rss(struct hnae3_handle *handle, const u32 *indir,
	return ret;
}

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

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

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

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

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

	return hash_sets;
}

static int hclge_set_rss_tuple(struct hnae3_handle *handle,
			       struct ethtool_rxnfc *nfc)
{
	struct hclge_vport *vport = hclge_get_vport(handle);
	struct hclge_dev *hdev = vport->back;
	struct hclge_rss_input_tuple_cmd *req;
	struct hclge_desc desc;
	u8 tuple_sets;
	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_rss_input_tuple_cmd *)desc.data;
	hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_RSS_INPUT_TUPLE, true);
	ret = hclge_cmd_send(&hdev->hw, &desc, 1);
	if (ret) {
		dev_err(&hdev->pdev->dev,
			"Read rss tuple fail, status = %d\n", ret);
		return ret;
	}

	hclge_cmd_reuse_desc(&desc, false);

	tuple_sets = hclge_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 ((nfc->data & RXH_L4_B_0_1) ||
		    (nfc->data & RXH_L4_B_2_3))
			return -EINVAL;

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

	ret = hclge_cmd_send(&hdev->hw, &desc, 1);
	if (ret)
		dev_err(&hdev->pdev->dev,
			"Set rss tuple fail, status = %d\n", ret);

	return ret;
}

static int hclge_get_rss_tuple(struct hnae3_handle *handle,
			       struct ethtool_rxnfc *nfc)
{
	struct hclge_vport *vport = hclge_get_vport(handle);
	struct hclge_dev *hdev = vport->back;
	struct hclge_rss_input_tuple_cmd *req;
	struct hclge_desc desc;
	u8 tuple_sets;
	int ret;

	nfc->data = 0;

	req = (struct hclge_rss_input_tuple_cmd *)desc.data;
	hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_RSS_INPUT_TUPLE, true);
	ret = hclge_cmd_send(&hdev->hw, &desc, 1);
	if (ret) {
		dev_err(&hdev->pdev->dev,
			"Read rss tuple fail, status = %d\n", ret);
		return ret;
	}

	switch (nfc->flow_type) {
	case TCP_V4_FLOW:
		tuple_sets = req->ipv4_tcp_en;
		break;
	case UDP_V4_FLOW:
		tuple_sets = req->ipv4_udp_en;
		break;
	case TCP_V6_FLOW:
		tuple_sets = req->ipv6_tcp_en;
		break;
	case UDP_V6_FLOW:
		tuple_sets = req->ipv6_udp_en;
		break;
	case SCTP_V4_FLOW:
		tuple_sets = req->ipv4_sctp_en;
		break;
	case SCTP_V6_FLOW:
		tuple_sets = req->ipv6_sctp_en;
		break;
	case IPV4_FLOW:
	case IPV6_FLOW:
		tuple_sets = HCLGE_S_IP_BIT | HCLGE_D_IP_BIT;
		break;
	default:
		return -EINVAL;
	}

	if (!tuple_sets)
		return 0;

	if (tuple_sets & HCLGE_D_PORT_BIT)
		nfc->data |= RXH_L4_B_2_3;
	if (tuple_sets & HCLGE_S_PORT_BIT)
		nfc->data |= RXH_L4_B_0_1;
	if (tuple_sets & HCLGE_D_IP_BIT)
		nfc->data |= RXH_IP_DST;
	if (tuple_sets & HCLGE_S_IP_BIT)
		nfc->data |= RXH_IP_SRC;

	return 0;
}

static int hclge_get_tc_size(struct hnae3_handle *handle)
{
	struct hclge_vport *vport = hclge_get_vport(handle);
@@ -4344,6 +4497,8 @@ static const struct hnae3_ae_ops hclge_ops = {
	.get_rss_indir_size = hclge_get_rss_indir_size,
	.get_rss = hclge_get_rss,
	.set_rss = hclge_set_rss,
	.set_rss_tuple = hclge_set_rss_tuple,
	.get_rss_tuple = hclge_get_rss_tuple,
	.get_tc_size = hclge_get_tc_size,
	.get_mac_addr = hclge_get_mac_addr,
	.set_mac_addr = hclge_set_mac_addr,
+8 −0
Original line number Diff line number Diff line
@@ -41,6 +41,14 @@
#define HCLGE_RSS_CFG_TBL_NUM \
	(HCLGE_RSS_IND_TBL_SIZE / HCLGE_RSS_CFG_TBL_SIZE)

#define HCLGE_RSS_INPUT_TUPLE_OTHER	GENMASK(3, 0)
#define HCLGE_RSS_INPUT_TUPLE_SCTP	GENMASK(4, 0)
#define HCLGE_D_PORT_BIT		BIT(0)
#define HCLGE_S_PORT_BIT		BIT(1)
#define HCLGE_D_IP_BIT			BIT(2)
#define HCLGE_S_IP_BIT			BIT(3)
#define HCLGE_V_TAG_BIT			BIT(4)

#define HCLGE_RSS_TC_SIZE_0		1
#define HCLGE_RSS_TC_SIZE_1		2
#define HCLGE_RSS_TC_SIZE_2		4
Loading