X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=drivers%2Fnet%2Fhns3%2Fhns3_rss.c;h=5b515122d252020ce1651251c1e485019b776f7d;hb=dc89abe5a9382147e3b2e1f713d46b0a0f3cd0b2;hp=95a637ddc22e1924179ae99b45fcc2df78ef6bcd;hpb=5e782bc2570c5746b8190d1b5c717de8ee77d0bd;p=dpdk.git diff --git a/drivers/net/hns3/hns3_rss.c b/drivers/net/hns3/hns3_rss.c index 95a637ddc2..5b515122d2 100644 --- a/drivers/net/hns3/hns3_rss.c +++ b/drivers/net/hns3/hns3_rss.c @@ -23,12 +23,172 @@ static const uint8_t hns3_hash_key[] = { 0x6A, 0x42, 0xB7, 0x3B, 0xBE, 0xAC, 0x01, 0xFA }; +enum hns3_tuple_field { + /* IPV4_TCP ENABLE FIELD */ + HNS3_RSS_FIELD_IPV4_TCP_EN_TCP_D = 0, + HNS3_RSS_FIELD_IPV4_TCP_EN_TCP_S, + HNS3_RSS_FIELD_IPV4_TCP_EN_IP_D, + HNS3_RSS_FIELD_IPV4_TCP_EN_IP_S, + + /* IPV4_UDP ENABLE FIELD */ + HNS3_RSS_FIELD_IPV4_UDP_EN_UDP_D = 8, + HNS3_RSS_FIELD_IPV4_UDP_EN_UDP_S, + HNS3_RSS_FIELD_IPV4_UDP_EN_IP_D, + HNS3_RSS_FIELD_IPV4_UDP_EN_IP_S, + + /* IPV4_SCTP ENABLE FIELD */ + HNS3_RSS_FIELD_IPV4_SCTP_EN_SCTP_D = 16, + HNS3_RSS_FIELD_IPV4_SCTP_EN_SCTP_S, + HNS3_RSS_FIELD_IPV4_SCTP_EN_IP_D, + HNS3_RSS_FIELD_IPV4_SCTP_EN_IP_S, + HNS3_RSS_FIELD_IPV4_SCTP_EN_SCTP_VER, + + /* IPV4 ENABLE FIELD */ + HNS3_RSS_FIELD_IPV4_EN_NONFRAG_IP_D = 24, + HNS3_RSS_FIELD_IPV4_EN_NONFRAG_IP_S, + HNS3_RSS_FIELD_IPV4_EN_FRAG_IP_D, + HNS3_RSS_FIELD_IPV4_EN_FRAG_IP_S, + + /* IPV6_TCP ENABLE FIELD */ + HNS3_RSS_FIELD_IPV6_TCP_EN_TCP_D = 32, + HNS3_RSS_FIELD_IPV6_TCP_EN_TCP_S, + HNS3_RSS_FIELD_IPV6_TCP_EN_IP_D, + HNS3_RSS_FIELD_IPV6_TCP_EN_IP_S, + + /* IPV6_UDP ENABLE FIELD */ + HNS3_RSS_FIELD_IPV6_UDP_EN_UDP_D = 40, + HNS3_RSS_FIELD_IPV6_UDP_EN_UDP_S, + HNS3_RSS_FIELD_IPV6_UDP_EN_IP_D, + HNS3_RSS_FIELD_IPV6_UDP_EN_IP_S, + + /* IPV6_UDP ENABLE FIELD */ + HNS3_RSS_FIELD_IPV6_SCTP_EN_IP_D = 50, + HNS3_RSS_FIELD_IPV6_SCTP_EN_IP_S, + HNS3_RSS_FIELD_IPV6_SCTP_EN_SCTP_VER, + + /* IPV6 ENABLE FIELD */ + HNS3_RSS_FIELD_IPV6_NONFRAG_IP_D = 56, + HNS3_RSS_FIELD_IPV6_NONFRAG_IP_S, + HNS3_RSS_FIELD_IPV6_FRAG_IP_D, + HNS3_RSS_FIELD_IPV6_FRAG_IP_S +}; + +static const struct { + uint64_t rss_types; + uint64_t rss_field; +} hns3_set_tuple_table[] = { + { ETH_RSS_FRAG_IPV4 | ETH_RSS_L3_SRC_ONLY, + BIT_ULL(HNS3_RSS_FIELD_IPV4_EN_FRAG_IP_S) }, + { ETH_RSS_FRAG_IPV4 | ETH_RSS_L3_DST_ONLY, + BIT_ULL(HNS3_RSS_FIELD_IPV4_EN_FRAG_IP_D) }, + { ETH_RSS_NONFRAG_IPV4_TCP | ETH_RSS_L3_SRC_ONLY, + BIT_ULL(HNS3_RSS_FIELD_IPV4_TCP_EN_IP_S) }, + { ETH_RSS_NONFRAG_IPV4_TCP | ETH_RSS_L3_DST_ONLY, + BIT_ULL(HNS3_RSS_FIELD_IPV4_TCP_EN_IP_D) }, + { ETH_RSS_NONFRAG_IPV4_TCP | ETH_RSS_L4_SRC_ONLY, + BIT_ULL(HNS3_RSS_FIELD_IPV4_TCP_EN_TCP_S) }, + { ETH_RSS_NONFRAG_IPV4_TCP | ETH_RSS_L4_DST_ONLY, + BIT_ULL(HNS3_RSS_FIELD_IPV4_TCP_EN_TCP_D) }, + { ETH_RSS_NONFRAG_IPV4_UDP | ETH_RSS_L3_SRC_ONLY, + BIT_ULL(HNS3_RSS_FIELD_IPV4_UDP_EN_IP_S) }, + { ETH_RSS_NONFRAG_IPV4_UDP | ETH_RSS_L3_DST_ONLY, + BIT_ULL(HNS3_RSS_FIELD_IPV4_UDP_EN_IP_D) }, + { ETH_RSS_NONFRAG_IPV4_UDP | ETH_RSS_L4_SRC_ONLY, + BIT_ULL(HNS3_RSS_FIELD_IPV4_UDP_EN_UDP_S) }, + { ETH_RSS_NONFRAG_IPV4_UDP | ETH_RSS_L4_DST_ONLY, + BIT_ULL(HNS3_RSS_FIELD_IPV4_UDP_EN_UDP_D) }, + { ETH_RSS_NONFRAG_IPV4_SCTP | ETH_RSS_L3_SRC_ONLY, + BIT_ULL(HNS3_RSS_FIELD_IPV4_SCTP_EN_IP_S) }, + { ETH_RSS_NONFRAG_IPV4_SCTP | ETH_RSS_L3_DST_ONLY, + BIT_ULL(HNS3_RSS_FIELD_IPV4_SCTP_EN_IP_D) }, + { ETH_RSS_NONFRAG_IPV4_SCTP | ETH_RSS_L4_SRC_ONLY, + BIT_ULL(HNS3_RSS_FIELD_IPV4_SCTP_EN_SCTP_S) }, + { ETH_RSS_NONFRAG_IPV4_SCTP | ETH_RSS_L4_DST_ONLY, + BIT_ULL(HNS3_RSS_FIELD_IPV4_SCTP_EN_SCTP_D) }, + { ETH_RSS_NONFRAG_IPV4_OTHER | ETH_RSS_L3_SRC_ONLY, + BIT_ULL(HNS3_RSS_FIELD_IPV4_EN_NONFRAG_IP_S) }, + { ETH_RSS_NONFRAG_IPV4_OTHER | ETH_RSS_L3_DST_ONLY, + BIT_ULL(HNS3_RSS_FIELD_IPV4_EN_NONFRAG_IP_D) }, + { ETH_RSS_FRAG_IPV6 | ETH_RSS_L3_SRC_ONLY, + BIT_ULL(HNS3_RSS_FIELD_IPV6_FRAG_IP_S) }, + { ETH_RSS_FRAG_IPV6 | ETH_RSS_L3_DST_ONLY, + BIT_ULL(HNS3_RSS_FIELD_IPV6_FRAG_IP_D) }, + { ETH_RSS_NONFRAG_IPV6_TCP | ETH_RSS_L3_SRC_ONLY, + BIT_ULL(HNS3_RSS_FIELD_IPV6_TCP_EN_IP_S) }, + { ETH_RSS_NONFRAG_IPV6_TCP | ETH_RSS_L3_DST_ONLY, + BIT_ULL(HNS3_RSS_FIELD_IPV6_TCP_EN_IP_D) }, + { ETH_RSS_NONFRAG_IPV6_TCP | ETH_RSS_L4_SRC_ONLY, + BIT_ULL(HNS3_RSS_FIELD_IPV6_TCP_EN_TCP_S) }, + { ETH_RSS_NONFRAG_IPV6_TCP | ETH_RSS_L4_DST_ONLY, + BIT_ULL(HNS3_RSS_FIELD_IPV6_TCP_EN_TCP_D) }, + { ETH_RSS_NONFRAG_IPV6_UDP | ETH_RSS_L3_SRC_ONLY, + BIT_ULL(HNS3_RSS_FIELD_IPV6_UDP_EN_IP_S) }, + { ETH_RSS_NONFRAG_IPV6_UDP | ETH_RSS_L3_DST_ONLY, + BIT_ULL(HNS3_RSS_FIELD_IPV6_UDP_EN_IP_D) }, + { ETH_RSS_NONFRAG_IPV6_UDP | ETH_RSS_L4_SRC_ONLY, + BIT_ULL(HNS3_RSS_FIELD_IPV6_UDP_EN_UDP_S) }, + { ETH_RSS_NONFRAG_IPV6_UDP | ETH_RSS_L4_DST_ONLY, + BIT_ULL(HNS3_RSS_FIELD_IPV6_UDP_EN_UDP_D) }, + { ETH_RSS_NONFRAG_IPV6_SCTP | ETH_RSS_L3_SRC_ONLY, + BIT_ULL(HNS3_RSS_FIELD_IPV6_SCTP_EN_IP_S) }, + { ETH_RSS_NONFRAG_IPV6_SCTP | ETH_RSS_L3_DST_ONLY, + BIT_ULL(HNS3_RSS_FIELD_IPV6_SCTP_EN_IP_D) }, + { ETH_RSS_NONFRAG_IPV6_OTHER | ETH_RSS_L3_SRC_ONLY, + BIT_ULL(HNS3_RSS_FIELD_IPV6_NONFRAG_IP_S) }, + { ETH_RSS_NONFRAG_IPV6_OTHER | ETH_RSS_L3_DST_ONLY, + BIT_ULL(HNS3_RSS_FIELD_IPV6_NONFRAG_IP_D) }, +}; + +static const struct { + uint64_t rss_types; + uint64_t rss_field; +} hns3_set_rss_types[] = { + { ETH_RSS_FRAG_IPV4, BIT_ULL(HNS3_RSS_FIELD_IPV4_EN_FRAG_IP_D) | + BIT_ULL(HNS3_RSS_FIELD_IPV4_EN_FRAG_IP_S) }, + { ETH_RSS_NONFRAG_IPV4_TCP, BIT_ULL(HNS3_RSS_FIELD_IPV4_TCP_EN_IP_S) | + BIT_ULL(HNS3_RSS_FIELD_IPV4_TCP_EN_IP_D) | + BIT_ULL(HNS3_RSS_FIELD_IPV4_TCP_EN_TCP_S) | + BIT_ULL(HNS3_RSS_FIELD_IPV4_TCP_EN_TCP_D) }, + { ETH_RSS_NONFRAG_IPV4_TCP, BIT_ULL(HNS3_RSS_FIELD_IPV4_TCP_EN_IP_S) | + BIT_ULL(HNS3_RSS_FIELD_IPV4_TCP_EN_IP_D) | + BIT_ULL(HNS3_RSS_FIELD_IPV4_TCP_EN_TCP_S) | + BIT_ULL(HNS3_RSS_FIELD_IPV4_TCP_EN_TCP_D) }, + { ETH_RSS_NONFRAG_IPV4_UDP, BIT_ULL(HNS3_RSS_FIELD_IPV4_UDP_EN_IP_S) | + BIT_ULL(HNS3_RSS_FIELD_IPV4_UDP_EN_IP_D) | + BIT_ULL(HNS3_RSS_FIELD_IPV4_UDP_EN_UDP_S) | + BIT_ULL(HNS3_RSS_FIELD_IPV4_UDP_EN_UDP_D) }, + { ETH_RSS_NONFRAG_IPV4_SCTP, BIT_ULL(HNS3_RSS_FIELD_IPV4_SCTP_EN_IP_S) | + BIT_ULL(HNS3_RSS_FIELD_IPV4_SCTP_EN_IP_D) | + BIT_ULL(HNS3_RSS_FIELD_IPV4_SCTP_EN_SCTP_S) | + BIT_ULL(HNS3_RSS_FIELD_IPV4_SCTP_EN_SCTP_D) | + BIT_ULL(HNS3_RSS_FIELD_IPV4_SCTP_EN_SCTP_VER) }, + { ETH_RSS_NONFRAG_IPV4_OTHER, + BIT_ULL(HNS3_RSS_FIELD_IPV4_EN_NONFRAG_IP_S) | + BIT_ULL(HNS3_RSS_FIELD_IPV4_EN_NONFRAG_IP_D) }, + { ETH_RSS_FRAG_IPV6, BIT_ULL(HNS3_RSS_FIELD_IPV6_FRAG_IP_S) | + BIT_ULL(HNS3_RSS_FIELD_IPV6_FRAG_IP_D) }, + { ETH_RSS_NONFRAG_IPV6_TCP, BIT_ULL(HNS3_RSS_FIELD_IPV6_TCP_EN_IP_S) | + BIT_ULL(HNS3_RSS_FIELD_IPV6_TCP_EN_IP_D) | + BIT_ULL(HNS3_RSS_FIELD_IPV6_TCP_EN_TCP_S) | + BIT_ULL(HNS3_RSS_FIELD_IPV6_TCP_EN_TCP_D) }, + { ETH_RSS_NONFRAG_IPV6_UDP, BIT_ULL(HNS3_RSS_FIELD_IPV6_UDP_EN_IP_S) | + BIT_ULL(HNS3_RSS_FIELD_IPV6_UDP_EN_IP_D) | + BIT_ULL(HNS3_RSS_FIELD_IPV6_UDP_EN_UDP_S) | + BIT_ULL(HNS3_RSS_FIELD_IPV6_UDP_EN_UDP_D) }, + { ETH_RSS_NONFRAG_IPV6_SCTP, BIT_ULL(HNS3_RSS_FIELD_IPV6_SCTP_EN_IP_S) | + BIT_ULL(HNS3_RSS_FIELD_IPV6_SCTP_EN_IP_D) | + BIT_ULL(HNS3_RSS_FIELD_IPV6_SCTP_EN_SCTP_VER) }, + { ETH_RSS_NONFRAG_IPV6_OTHER, + BIT_ULL(HNS3_RSS_FIELD_IPV6_NONFRAG_IP_S) | + BIT_ULL(HNS3_RSS_FIELD_IPV6_NONFRAG_IP_D) } +}; + /* * rss_generic_config command function, opcode:0x0D01. * Used to set algorithm, key_offset and hash key of rss. */ int -hns3_set_rss_algo_key(struct hns3_hw *hw, uint8_t hash_algo, const uint8_t *key) +hns3_set_rss_algo_key(struct hns3_hw *hw, const uint8_t *key) { #define HNS3_KEY_OFFSET_MAX 3 #define HNS3_SET_HASH_KEY_BYTE_FOUR 2 @@ -51,7 +211,8 @@ hns3_set_rss_algo_key(struct hns3_hw *hw, uint8_t hash_algo, const uint8_t *key) hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_RSS_GENERIC_CONFIG, false); - req->hash_config |= (hash_algo & HNS3_RSS_HASH_ALGO_MASK); + req->hash_config |= + (hw->rss_info.hash_algo & HNS3_RSS_HASH_ALGO_MASK); req->hash_config |= (key_offset << HNS3_RSS_HASH_KEY_OFFSET_B); if (key_offset == HNS3_SET_HASH_KEY_BYTE_FOUR) @@ -90,14 +251,8 @@ hns3_set_rss_input_tuple(struct hns3_hw *hw) req = (struct hns3_rss_input_tuple_cmd *)desc_tuple.data; - req->ipv4_tcp_en = rss_config->rss_tuple_sets.ipv4_tcp_en; - req->ipv4_udp_en = rss_config->rss_tuple_sets.ipv4_udp_en; - req->ipv4_sctp_en = rss_config->rss_tuple_sets.ipv4_sctp_en; - req->ipv4_fragment_en = rss_config->rss_tuple_sets.ipv4_fragment_en; - req->ipv6_tcp_en = rss_config->rss_tuple_sets.ipv6_tcp_en; - req->ipv6_udp_en = rss_config->rss_tuple_sets.ipv6_udp_en; - req->ipv6_sctp_en = rss_config->rss_tuple_sets.ipv6_sctp_en; - req->ipv6_fragment_en = rss_config->rss_tuple_sets.ipv6_fragment_en; + req->tuple_field = + rte_cpu_to_le_64(rss_config->rss_tuple_sets.rss_tuple_fields); ret = hns3_cmd_send(hw, &desc_tuple, 1); if (ret) @@ -170,6 +325,7 @@ hns3_set_rss_tuple_by_rss_hf(struct hns3_hw *hw, { struct hns3_rss_input_tuple_cmd *req; struct hns3_cmd_desc desc; + uint32_t fields_count = 0; /* count times for setting tuple fields */ uint32_t i; int ret; @@ -177,46 +333,30 @@ hns3_set_rss_tuple_by_rss_hf(struct hns3_hw *hw, req = (struct hns3_rss_input_tuple_cmd *)desc.data; - /* Enable ipv4 or ipv6 tuple by flow type */ - for (i = 0; i < RTE_ETH_FLOW_MAX; i++) { - switch (rss_hf & (1ULL << i)) { - case ETH_RSS_NONFRAG_IPV4_TCP: - req->ipv4_tcp_en = HNS3_RSS_INPUT_TUPLE_OTHER; - break; - case ETH_RSS_NONFRAG_IPV4_UDP: - req->ipv4_udp_en = HNS3_RSS_INPUT_TUPLE_OTHER; - break; - case ETH_RSS_NONFRAG_IPV4_SCTP: - req->ipv4_sctp_en = HNS3_RSS_INPUT_TUPLE_SCTP; - break; - case ETH_RSS_FRAG_IPV4: - req->ipv4_fragment_en |= HNS3_IP_FRAG_BIT_MASK; - break; - case ETH_RSS_NONFRAG_IPV4_OTHER: - req->ipv4_fragment_en |= HNS3_IP_OTHER_BIT_MASK; - break; - case ETH_RSS_NONFRAG_IPV6_TCP: - req->ipv6_tcp_en = HNS3_RSS_INPUT_TUPLE_OTHER; - break; - case ETH_RSS_NONFRAG_IPV6_UDP: - req->ipv6_udp_en = HNS3_RSS_INPUT_TUPLE_OTHER; - break; - case ETH_RSS_NONFRAG_IPV6_SCTP: - req->ipv6_sctp_en = HNS3_RSS_INPUT_TUPLE_SCTP; - break; - case ETH_RSS_FRAG_IPV6: - req->ipv6_fragment_en |= HNS3_IP_FRAG_BIT_MASK; - break; - case ETH_RSS_NONFRAG_IPV6_OTHER: - req->ipv6_fragment_en |= HNS3_IP_OTHER_BIT_MASK; - break; - default: - /* - * rss_hf doesn't include unsupported flow types - * because the API framework has checked it, and - * this branch will never go unless rss_hf is zero. - */ - break; + for (i = 0; i < RTE_DIM(hns3_set_tuple_table); i++) { + if ((rss_hf & hns3_set_tuple_table[i].rss_types) == + hns3_set_tuple_table[i].rss_types) { + req->tuple_field |= + rte_cpu_to_le_64(hns3_set_tuple_table[i].rss_field); + fields_count++; + } + } + + /* + * When user does not specify the following types or a combination of + * the following types, it enables all fields for the supported RSS + * types. the following types as: + * - ETH_RSS_L3_SRC_ONLY + * - ETH_RSS_L3_DST_ONLY + * - ETH_RSS_L4_SRC_ONLY + * - ETH_RSS_L4_DST_ONLY + */ + if (fields_count == 0) { + for (i = 0; i < RTE_DIM(hns3_set_rss_types); i++) { + if ((rss_hf & hns3_set_rss_types[i].rss_types) == + hns3_set_rss_types[i].rss_types) + req->tuple_field |= rte_cpu_to_le_64( + hns3_set_rss_types[i].rss_field); } } @@ -226,14 +366,7 @@ hns3_set_rss_tuple_by_rss_hf(struct hns3_hw *hw, return ret; } - tuple->ipv4_tcp_en = req->ipv4_tcp_en; - tuple->ipv4_udp_en = req->ipv4_udp_en; - tuple->ipv4_sctp_en = req->ipv4_sctp_en; - tuple->ipv4_fragment_en = req->ipv4_fragment_en; - tuple->ipv6_tcp_en = req->ipv6_tcp_en; - tuple->ipv6_udp_en = req->ipv6_udp_en; - tuple->ipv6_sctp_en = req->ipv6_sctp_en; - tuple->ipv6_fragment_en = req->ipv6_fragment_en; + tuple->rss_tuple_fields = rte_le_to_cpu_64(req->tuple_field); return 0; } @@ -256,7 +389,6 @@ hns3_dev_rss_hash_update(struct rte_eth_dev *dev, struct hns3_rss_tuple_cfg *tuple = &hw->rss_info.rss_tuple_sets; struct hns3_rss_conf *rss_cfg = &hw->rss_info; uint8_t key_len = rss_conf->rss_key_len; - uint8_t algo; uint64_t rss_hf = rss_conf->rss_hf; uint8_t *key = rss_conf->rss_key; int ret; @@ -292,9 +424,7 @@ hns3_dev_rss_hash_update(struct rte_eth_dev *dev, ret = -EINVAL; goto conf_err; } - algo = rss_cfg->conf.func == RTE_ETH_HASH_FUNCTION_SIMPLE_XOR ? - HNS3_RSS_HASH_ALGO_SIMPLE : HNS3_RSS_HASH_ALGO_TOEPLITZ; - ret = hns3_set_rss_algo_key(hw, algo, key); + ret = hns3_set_rss_algo_key(hw, key); if (ret) goto conf_err; } @@ -328,8 +458,10 @@ hns3_dev_rss_hash_conf_get(struct rte_eth_dev *dev, rss_conf->rss_hf = rss_cfg->conf.types; /* Get the RSS Key required by the user */ - if (rss_conf->rss_key) + if (rss_conf->rss_key && rss_conf->rss_key_len >= HNS3_RSS_KEY_SIZE) { memcpy(rss_conf->rss_key, rss_cfg->key, HNS3_RSS_KEY_SIZE); + rss_conf->rss_key_len = HNS3_RSS_KEY_SIZE; + } rte_spinlock_unlock(&hw->lock); return 0; @@ -527,20 +659,29 @@ hns3_config_rss(struct hns3_adapter *hns) { struct hns3_hw *hw = &hns->hw; struct hns3_rss_conf *rss_cfg = &hw->rss_info; - uint8_t hash_algo = - (hw->rss_info.conf.func == RTE_ETH_HASH_FUNCTION_TOEPLITZ ? - HNS3_RSS_HASH_ALGO_TOEPLITZ : HNS3_RSS_HASH_ALGO_SIMPLE); uint8_t *hash_key = rss_cfg->key; int ret, ret1; enum rte_eth_rx_mq_mode mq_mode = hw->data->dev_conf.rxmode.mq_mode; + switch (hw->rss_info.conf.func) { + case RTE_ETH_HASH_FUNCTION_SIMPLE_XOR: + hw->rss_info.hash_algo = HNS3_RSS_HASH_ALGO_SIMPLE; + break; + case RTE_ETH_HASH_FUNCTION_SYMMETRIC_TOEPLITZ: + hw->rss_info.hash_algo = HNS3_RSS_HASH_ALGO_SYMMETRIC_TOEP; + break; + default: + hw->rss_info.hash_algo = HNS3_RSS_HASH_ALGO_TOEPLITZ; + break; + } + /* When RSS is off, redirect the packet queue 0 */ if (((uint32_t)mq_mode & ETH_MQ_RX_RSS_FLAG) == 0) hns3_rss_uninit(hns); /* Configure RSS hash algorithm and hash key offset */ - ret = hns3_set_rss_algo_key(hw, hash_algo, hash_key); + ret = hns3_set_rss_algo_key(hw, hash_key); if (ret) return ret;