brintos

brintos / linux-shallow public Read only

0
0
Text · 13.9 KiB · 4e2bb65 Raw
519 lines · c
1// SPDX-License-Identifier: GPL-2.0+2// Copyright (c) 2021-2021 Hisilicon Limited.3#include <linux/skbuff.h>4 5#include "hnae3.h"6#include "hclge_comm_cmd.h"7#include "hclge_comm_rss.h"8 9static const u8 hclge_comm_hash_key[] = {10	0x6D, 0x5A, 0x56, 0xDA, 0x25, 0x5B, 0x0E, 0xC2,11	0x41, 0x67, 0x25, 0x3D, 0x43, 0xA3, 0x8F, 0xB0,12	0xD0, 0xCA, 0x2B, 0xCB, 0xAE, 0x7B, 0x30, 0xB4,13	0x77, 0xCB, 0x2D, 0xA3, 0x80, 0x30, 0xF2, 0x0C,14	0x6A, 0x42, 0xB7, 0x3B, 0xBE, 0xAC, 0x01, 0xFA15};16 17static void18hclge_comm_init_rss_tuple(struct hnae3_ae_dev *ae_dev,19			  struct hclge_comm_rss_tuple_cfg *rss_tuple_cfg)20{21	rss_tuple_cfg->ipv4_tcp_en = HCLGE_COMM_RSS_INPUT_TUPLE_OTHER;22	rss_tuple_cfg->ipv4_udp_en = HCLGE_COMM_RSS_INPUT_TUPLE_OTHER;23	rss_tuple_cfg->ipv4_sctp_en = HCLGE_COMM_RSS_INPUT_TUPLE_SCTP;24	rss_tuple_cfg->ipv4_fragment_en = HCLGE_COMM_RSS_INPUT_TUPLE_OTHER;25	rss_tuple_cfg->ipv6_tcp_en = HCLGE_COMM_RSS_INPUT_TUPLE_OTHER;26	rss_tuple_cfg->ipv6_udp_en = HCLGE_COMM_RSS_INPUT_TUPLE_OTHER;27	rss_tuple_cfg->ipv6_sctp_en =28		ae_dev->dev_version <= HNAE3_DEVICE_VERSION_V2 ?29		HCLGE_COMM_RSS_INPUT_TUPLE_SCTP_NO_PORT :30		HCLGE_COMM_RSS_INPUT_TUPLE_SCTP;31	rss_tuple_cfg->ipv6_fragment_en = HCLGE_COMM_RSS_INPUT_TUPLE_OTHER;32}33 34int hclge_comm_rss_init_cfg(struct hnae3_handle *nic,35			    struct hnae3_ae_dev *ae_dev,36			    struct hclge_comm_rss_cfg *rss_cfg)37{38	u16 rss_ind_tbl_size = ae_dev->dev_specs.rss_ind_tbl_size;39	int rss_algo = HCLGE_COMM_RSS_HASH_ALGO_TOEPLITZ;40	u16 *rss_ind_tbl;41 42	if (nic->flags & HNAE3_SUPPORT_VF)43		rss_cfg->rss_size = nic->kinfo.rss_size;44 45	if (ae_dev->dev_version >= HNAE3_DEVICE_VERSION_V2)46		rss_algo = HCLGE_COMM_RSS_HASH_ALGO_SIMPLE;47 48	hclge_comm_init_rss_tuple(ae_dev, &rss_cfg->rss_tuple_sets);49 50	rss_cfg->rss_algo = rss_algo;51 52	rss_ind_tbl = devm_kcalloc(&ae_dev->pdev->dev, rss_ind_tbl_size,53				   sizeof(*rss_ind_tbl), GFP_KERNEL);54	if (!rss_ind_tbl)55		return -ENOMEM;56 57	rss_cfg->rss_indirection_tbl = rss_ind_tbl;58	memcpy(rss_cfg->rss_hash_key, hclge_comm_hash_key,59	       HCLGE_COMM_RSS_KEY_SIZE);60 61	hclge_comm_rss_indir_init_cfg(ae_dev, rss_cfg);62 63	return 0;64}65EXPORT_SYMBOL_GPL(hclge_comm_rss_init_cfg);66 67void hclge_comm_get_rss_tc_info(u16 rss_size, u8 hw_tc_map, u16 *tc_offset,68				u16 *tc_valid, u16 *tc_size)69{70	u16 roundup_size;71	u32 i;72 73	roundup_size = roundup_pow_of_two(rss_size);74	roundup_size = ilog2(roundup_size);75 76	for (i = 0; i < HCLGE_COMM_MAX_TC_NUM; i++) {77		tc_valid[i] = 1;78		tc_size[i] = roundup_size;79		tc_offset[i] = (hw_tc_map & BIT(i)) ? rss_size * i : 0;80	}81}82EXPORT_SYMBOL_GPL(hclge_comm_get_rss_tc_info);83 84int hclge_comm_set_rss_tc_mode(struct hclge_comm_hw *hw, u16 *tc_offset,85			       u16 *tc_valid, u16 *tc_size)86{87	struct hclge_comm_rss_tc_mode_cmd *req;88	struct hclge_desc desc;89	unsigned int i;90	int ret;91 92	req = (struct hclge_comm_rss_tc_mode_cmd *)desc.data;93 94	hclge_comm_cmd_setup_basic_desc(&desc, HCLGE_OPC_RSS_TC_MODE, false);95	for (i = 0; i < HCLGE_COMM_MAX_TC_NUM; i++) {96		u16 mode = 0;97 98		hnae3_set_bit(mode, HCLGE_COMM_RSS_TC_VALID_B,99			      (tc_valid[i] & 0x1));100		hnae3_set_field(mode, HCLGE_COMM_RSS_TC_SIZE_M,101				HCLGE_COMM_RSS_TC_SIZE_S, tc_size[i]);102		hnae3_set_bit(mode, HCLGE_COMM_RSS_TC_SIZE_MSB_B,103			      tc_size[i] >> HCLGE_COMM_RSS_TC_SIZE_MSB_OFFSET &104			      0x1);105		hnae3_set_field(mode, HCLGE_COMM_RSS_TC_OFFSET_M,106				HCLGE_COMM_RSS_TC_OFFSET_S, tc_offset[i]);107 108		req->rss_tc_mode[i] = cpu_to_le16(mode);109	}110 111	ret = hclge_comm_cmd_send(hw, &desc, 1);112	if (ret)113		dev_err(&hw->cmq.csq.pdev->dev,114			"failed to set rss tc mode, ret = %d.\n", ret);115 116	return ret;117}118EXPORT_SYMBOL_GPL(hclge_comm_set_rss_tc_mode);119 120int hclge_comm_set_rss_hash_key(struct hclge_comm_rss_cfg *rss_cfg,121				struct hclge_comm_hw *hw, const u8 *key,122				const u8 hfunc)123{124	u8 hash_algo;125	int ret;126 127	ret = hclge_comm_parse_rss_hfunc(rss_cfg, hfunc, &hash_algo);128	if (ret)129		return ret;130 131	/* Set the RSS Hash Key if specififed by the user */132	if (key) {133		ret = hclge_comm_set_rss_algo_key(hw, hash_algo, key);134		if (ret)135			return ret;136 137		/* Update the shadow RSS key with user specified qids */138		memcpy(rss_cfg->rss_hash_key, key, HCLGE_COMM_RSS_KEY_SIZE);139	} else {140		ret = hclge_comm_set_rss_algo_key(hw, hash_algo,141						  rss_cfg->rss_hash_key);142		if (ret)143			return ret;144	}145	rss_cfg->rss_algo = hash_algo;146 147	return 0;148}149EXPORT_SYMBOL_GPL(hclge_comm_set_rss_hash_key);150 151int hclge_comm_set_rss_tuple(struct hnae3_ae_dev *ae_dev,152			     struct hclge_comm_hw *hw,153			     struct hclge_comm_rss_cfg *rss_cfg,154			     struct ethtool_rxnfc *nfc)155{156	struct hclge_comm_rss_input_tuple_cmd *req;157	struct hclge_desc desc;158	int ret;159 160	if (nfc->data &161	    ~(RXH_IP_SRC | RXH_IP_DST | RXH_L4_B_0_1 | RXH_L4_B_2_3))162		return -EINVAL;163 164	req = (struct hclge_comm_rss_input_tuple_cmd *)desc.data;165	hclge_comm_cmd_setup_basic_desc(&desc, HCLGE_OPC_RSS_INPUT_TUPLE,166					false);167 168	ret = hclge_comm_init_rss_tuple_cmd(rss_cfg, nfc, ae_dev, req);169	if (ret) {170		dev_err(&hw->cmq.csq.pdev->dev,171			"failed to init rss tuple cmd, ret = %d.\n", ret);172		return ret;173	}174 175	ret = hclge_comm_cmd_send(hw, &desc, 1);176	if (ret) {177		dev_err(&hw->cmq.csq.pdev->dev,178			"failed to set rss tuple, ret = %d.\n", ret);179		return ret;180	}181 182	rss_cfg->rss_tuple_sets.ipv4_tcp_en = req->ipv4_tcp_en;183	rss_cfg->rss_tuple_sets.ipv4_udp_en = req->ipv4_udp_en;184	rss_cfg->rss_tuple_sets.ipv4_sctp_en = req->ipv4_sctp_en;185	rss_cfg->rss_tuple_sets.ipv4_fragment_en = req->ipv4_fragment_en;186	rss_cfg->rss_tuple_sets.ipv6_tcp_en = req->ipv6_tcp_en;187	rss_cfg->rss_tuple_sets.ipv6_udp_en = req->ipv6_udp_en;188	rss_cfg->rss_tuple_sets.ipv6_sctp_en = req->ipv6_sctp_en;189	rss_cfg->rss_tuple_sets.ipv6_fragment_en = req->ipv6_fragment_en;190	return 0;191}192EXPORT_SYMBOL_GPL(hclge_comm_set_rss_tuple);193 194u32 hclge_comm_get_rss_key_size(struct hnae3_handle *handle)195{196	return HCLGE_COMM_RSS_KEY_SIZE;197}198EXPORT_SYMBOL_GPL(hclge_comm_get_rss_key_size);199 200int hclge_comm_parse_rss_hfunc(struct hclge_comm_rss_cfg *rss_cfg,201			       const u8 hfunc, u8 *hash_algo)202{203	switch (hfunc) {204	case ETH_RSS_HASH_TOP:205		*hash_algo = HCLGE_COMM_RSS_HASH_ALGO_TOEPLITZ;206		return 0;207	case ETH_RSS_HASH_XOR:208		*hash_algo = HCLGE_COMM_RSS_HASH_ALGO_SIMPLE;209		return 0;210	case ETH_RSS_HASH_NO_CHANGE:211		*hash_algo = rss_cfg->rss_algo;212		return 0;213	default:214		return -EINVAL;215	}216}217 218void hclge_comm_rss_indir_init_cfg(struct hnae3_ae_dev *ae_dev,219				   struct hclge_comm_rss_cfg *rss_cfg)220{221	u16 i;222	/* Initialize RSS indirect table */223	for (i = 0; i < ae_dev->dev_specs.rss_ind_tbl_size; i++)224		rss_cfg->rss_indirection_tbl[i] = i % rss_cfg->rss_size;225}226EXPORT_SYMBOL_GPL(hclge_comm_rss_indir_init_cfg);227 228int hclge_comm_get_rss_tuple(struct hclge_comm_rss_cfg *rss_cfg, int flow_type,229			     u8 *tuple_sets)230{231	switch (flow_type) {232	case TCP_V4_FLOW:233		*tuple_sets = rss_cfg->rss_tuple_sets.ipv4_tcp_en;234		break;235	case UDP_V4_FLOW:236		*tuple_sets = rss_cfg->rss_tuple_sets.ipv4_udp_en;237		break;238	case TCP_V6_FLOW:239		*tuple_sets = rss_cfg->rss_tuple_sets.ipv6_tcp_en;240		break;241	case UDP_V6_FLOW:242		*tuple_sets = rss_cfg->rss_tuple_sets.ipv6_udp_en;243		break;244	case SCTP_V4_FLOW:245		*tuple_sets = rss_cfg->rss_tuple_sets.ipv4_sctp_en;246		break;247	case SCTP_V6_FLOW:248		*tuple_sets = rss_cfg->rss_tuple_sets.ipv6_sctp_en;249		break;250	case IPV4_FLOW:251	case IPV6_FLOW:252		*tuple_sets = HCLGE_COMM_S_IP_BIT | HCLGE_COMM_D_IP_BIT;253		break;254	default:255		return -EINVAL;256	}257 258	return 0;259}260EXPORT_SYMBOL_GPL(hclge_comm_get_rss_tuple);261 262static void263hclge_comm_append_rss_msb_info(struct hclge_comm_rss_ind_tbl_cmd *req,264			       u16 qid, u32 j)265{266	u8 rss_msb_oft;267	u8 rss_msb_val;268 269	rss_msb_oft =270		j * HCLGE_COMM_RSS_CFG_TBL_BW_H / BITS_PER_BYTE;271	rss_msb_val = (qid >> HCLGE_COMM_RSS_CFG_TBL_BW_L & 0x1) <<272		(j * HCLGE_COMM_RSS_CFG_TBL_BW_H % BITS_PER_BYTE);273	req->rss_qid_h[rss_msb_oft] |= rss_msb_val;274}275 276int hclge_comm_set_rss_indir_table(struct hnae3_ae_dev *ae_dev,277				   struct hclge_comm_hw *hw, const u16 *indir)278{279	struct hclge_comm_rss_ind_tbl_cmd *req;280	struct hclge_desc desc;281	u16 rss_cfg_tbl_num;282	int ret;283	u16 qid;284	u16 i;285	u32 j;286 287	req = (struct hclge_comm_rss_ind_tbl_cmd *)desc.data;288	rss_cfg_tbl_num = ae_dev->dev_specs.rss_ind_tbl_size /289			  HCLGE_COMM_RSS_CFG_TBL_SIZE;290 291	for (i = 0; i < rss_cfg_tbl_num; i++) {292		hclge_comm_cmd_setup_basic_desc(&desc,293						HCLGE_OPC_RSS_INDIR_TABLE,294						false);295 296		req->start_table_index =297			cpu_to_le16(i * HCLGE_COMM_RSS_CFG_TBL_SIZE);298		req->rss_set_bitmap =299			cpu_to_le16(HCLGE_COMM_RSS_SET_BITMAP_MSK);300		for (j = 0; j < HCLGE_COMM_RSS_CFG_TBL_SIZE; j++) {301			qid = indir[i * HCLGE_COMM_RSS_CFG_TBL_SIZE + j];302			req->rss_qid_l[j] = qid & 0xff;303			hclge_comm_append_rss_msb_info(req, qid, j);304		}305		ret = hclge_comm_cmd_send(hw, &desc, 1);306		if (ret) {307			dev_err(&hw->cmq.csq.pdev->dev,308				"failed to configure rss table, ret = %d.\n",309				ret);310			return ret;311		}312	}313	return 0;314}315EXPORT_SYMBOL_GPL(hclge_comm_set_rss_indir_table);316 317int hclge_comm_set_rss_input_tuple(struct hclge_comm_hw *hw,318				   struct hclge_comm_rss_cfg *rss_cfg)319{320	struct hclge_comm_rss_input_tuple_cmd *req;321	struct hclge_desc desc;322	int ret;323 324	hclge_comm_cmd_setup_basic_desc(&desc, HCLGE_OPC_RSS_INPUT_TUPLE,325					false);326 327	req = (struct hclge_comm_rss_input_tuple_cmd *)desc.data;328 329	req->ipv4_tcp_en = rss_cfg->rss_tuple_sets.ipv4_tcp_en;330	req->ipv4_udp_en = rss_cfg->rss_tuple_sets.ipv4_udp_en;331	req->ipv4_sctp_en = rss_cfg->rss_tuple_sets.ipv4_sctp_en;332	req->ipv4_fragment_en = rss_cfg->rss_tuple_sets.ipv4_fragment_en;333	req->ipv6_tcp_en = rss_cfg->rss_tuple_sets.ipv6_tcp_en;334	req->ipv6_udp_en = rss_cfg->rss_tuple_sets.ipv6_udp_en;335	req->ipv6_sctp_en = rss_cfg->rss_tuple_sets.ipv6_sctp_en;336	req->ipv6_fragment_en = rss_cfg->rss_tuple_sets.ipv6_fragment_en;337 338	ret = hclge_comm_cmd_send(hw, &desc, 1);339	if (ret)340		dev_err(&hw->cmq.csq.pdev->dev,341			"failed to configure rss input, ret = %d.\n", ret);342	return ret;343}344EXPORT_SYMBOL_GPL(hclge_comm_set_rss_input_tuple);345 346void hclge_comm_get_rss_hash_info(struct hclge_comm_rss_cfg *rss_cfg, u8 *key,347				  u8 *hfunc)348{349	/* Get hash algorithm */350	if (hfunc) {351		switch (rss_cfg->rss_algo) {352		case HCLGE_COMM_RSS_HASH_ALGO_TOEPLITZ:353			*hfunc = ETH_RSS_HASH_TOP;354			break;355		case HCLGE_COMM_RSS_HASH_ALGO_SIMPLE:356			*hfunc = ETH_RSS_HASH_XOR;357			break;358		default:359			*hfunc = ETH_RSS_HASH_UNKNOWN;360			break;361		}362	}363 364	/* Get the RSS Key required by the user */365	if (key)366		memcpy(key, rss_cfg->rss_hash_key, HCLGE_COMM_RSS_KEY_SIZE);367}368EXPORT_SYMBOL_GPL(hclge_comm_get_rss_hash_info);369 370void hclge_comm_get_rss_indir_tbl(struct hclge_comm_rss_cfg *rss_cfg,371				  u32 *indir, u16 rss_ind_tbl_size)372{373	u16 i;374 375	if (!indir)376		return;377 378	for (i = 0; i < rss_ind_tbl_size; i++)379		indir[i] = rss_cfg->rss_indirection_tbl[i];380}381EXPORT_SYMBOL_GPL(hclge_comm_get_rss_indir_tbl);382 383int hclge_comm_set_rss_algo_key(struct hclge_comm_hw *hw, const u8 hfunc,384				const u8 *key)385{386	struct hclge_comm_rss_config_cmd *req;387	unsigned int key_offset = 0;388	struct hclge_desc desc;389	int key_counts;390	int key_size;391	int ret;392 393	key_counts = HCLGE_COMM_RSS_KEY_SIZE;394	req = (struct hclge_comm_rss_config_cmd *)desc.data;395 396	while (key_counts) {397		hclge_comm_cmd_setup_basic_desc(&desc,398						HCLGE_OPC_RSS_GENERIC_CONFIG,399						false);400 401		req->hash_config |= (hfunc & HCLGE_COMM_RSS_HASH_ALGO_MASK);402		req->hash_config |=403			(key_offset << HCLGE_COMM_RSS_HASH_KEY_OFFSET_B);404 405		key_size = min(HCLGE_COMM_RSS_HASH_KEY_NUM, key_counts);406		memcpy(req->hash_key,407		       key + key_offset * HCLGE_COMM_RSS_HASH_KEY_NUM,408		       key_size);409 410		key_counts -= key_size;411		key_offset++;412		ret = hclge_comm_cmd_send(hw, &desc, 1);413		if (ret) {414			dev_err(&hw->cmq.csq.pdev->dev,415				"failed to configure RSS key, ret = %d.\n",416				ret);417			return ret;418		}419	}420 421	return 0;422}423EXPORT_SYMBOL_GPL(hclge_comm_set_rss_algo_key);424 425static u8 hclge_comm_get_rss_hash_bits(struct ethtool_rxnfc *nfc)426{427	u8 hash_sets = nfc->data & RXH_L4_B_0_1 ? HCLGE_COMM_S_PORT_BIT : 0;428 429	if (nfc->data & RXH_L4_B_2_3)430		hash_sets |= HCLGE_COMM_D_PORT_BIT;431	else432		hash_sets &= ~HCLGE_COMM_D_PORT_BIT;433 434	if (nfc->data & RXH_IP_SRC)435		hash_sets |= HCLGE_COMM_S_IP_BIT;436	else437		hash_sets &= ~HCLGE_COMM_S_IP_BIT;438 439	if (nfc->data & RXH_IP_DST)440		hash_sets |= HCLGE_COMM_D_IP_BIT;441	else442		hash_sets &= ~HCLGE_COMM_D_IP_BIT;443 444	if (nfc->flow_type == SCTP_V4_FLOW || nfc->flow_type == SCTP_V6_FLOW)445		hash_sets |= HCLGE_COMM_V_TAG_BIT;446 447	return hash_sets;448}449 450int hclge_comm_init_rss_tuple_cmd(struct hclge_comm_rss_cfg *rss_cfg,451				  struct ethtool_rxnfc *nfc,452				  struct hnae3_ae_dev *ae_dev,453				  struct hclge_comm_rss_input_tuple_cmd *req)454{455	u8 tuple_sets;456 457	req->ipv4_tcp_en = rss_cfg->rss_tuple_sets.ipv4_tcp_en;458	req->ipv4_udp_en = rss_cfg->rss_tuple_sets.ipv4_udp_en;459	req->ipv4_sctp_en = rss_cfg->rss_tuple_sets.ipv4_sctp_en;460	req->ipv4_fragment_en = rss_cfg->rss_tuple_sets.ipv4_fragment_en;461	req->ipv6_tcp_en = rss_cfg->rss_tuple_sets.ipv6_tcp_en;462	req->ipv6_udp_en = rss_cfg->rss_tuple_sets.ipv6_udp_en;463	req->ipv6_sctp_en = rss_cfg->rss_tuple_sets.ipv6_sctp_en;464	req->ipv6_fragment_en = rss_cfg->rss_tuple_sets.ipv6_fragment_en;465 466	tuple_sets = hclge_comm_get_rss_hash_bits(nfc);467	switch (nfc->flow_type) {468	case TCP_V4_FLOW:469		req->ipv4_tcp_en = tuple_sets;470		break;471	case TCP_V6_FLOW:472		req->ipv6_tcp_en = tuple_sets;473		break;474	case UDP_V4_FLOW:475		req->ipv4_udp_en = tuple_sets;476		break;477	case UDP_V6_FLOW:478		req->ipv6_udp_en = tuple_sets;479		break;480	case SCTP_V4_FLOW:481		req->ipv4_sctp_en = tuple_sets;482		break;483	case SCTP_V6_FLOW:484		if (ae_dev->dev_version <= HNAE3_DEVICE_VERSION_V2 &&485		    (nfc->data & (RXH_L4_B_0_1 | RXH_L4_B_2_3)))486			return -EINVAL;487 488		req->ipv6_sctp_en = tuple_sets;489		break;490	case IPV4_FLOW:491		req->ipv4_fragment_en = HCLGE_COMM_RSS_INPUT_TUPLE_OTHER;492		break;493	case IPV6_FLOW:494		req->ipv6_fragment_en = HCLGE_COMM_RSS_INPUT_TUPLE_OTHER;495		break;496	default:497		return -EINVAL;498	}499 500	return 0;501}502 503u64 hclge_comm_convert_rss_tuple(u8 tuple_sets)504{505	u64 tuple_data = 0;506 507	if (tuple_sets & HCLGE_COMM_D_PORT_BIT)508		tuple_data |= RXH_L4_B_2_3;509	if (tuple_sets & HCLGE_COMM_S_PORT_BIT)510		tuple_data |= RXH_L4_B_0_1;511	if (tuple_sets & HCLGE_COMM_D_IP_BIT)512		tuple_data |= RXH_IP_DST;513	if (tuple_sets & HCLGE_COMM_S_IP_BIT)514		tuple_data |= RXH_IP_SRC;515 516	return tuple_data;517}518EXPORT_SYMBOL_GPL(hclge_comm_convert_rss_tuple);519