1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(C) 2019 Marvell International Ltd.
5 #include "otx2_ethdev.h"
8 otx2_nix_rss_tbl_init(struct otx2_eth_dev *dev,
9 uint8_t group, uint16_t *ind_tbl)
11 struct otx2_rss_info *rss = &dev->rss_info;
12 struct otx2_mbox *mbox = dev->mbox;
13 struct nix_aq_enq_req *req;
16 for (idx = 0; idx < rss->rss_size; idx++) {
17 req = otx2_mbox_alloc_msg_nix_aq_enq(mbox);
19 /* The shared memory buffer can be full.
22 otx2_mbox_msg_send(mbox, 0);
23 rc = otx2_mbox_wait_for_rsp(mbox, 0);
27 req = otx2_mbox_alloc_msg_nix_aq_enq(mbox);
31 req->rss.rq = ind_tbl[idx];
33 req->qidx = (group * rss->rss_size) + idx;
34 req->ctype = NIX_AQ_CTYPE_RSS;
35 req->op = NIX_AQ_INSTOP_INIT;
38 otx2_mbox_msg_send(mbox, 0);
39 rc = otx2_mbox_wait_for_rsp(mbox, 0);
47 otx2_nix_dev_reta_update(struct rte_eth_dev *eth_dev,
48 struct rte_eth_rss_reta_entry64 *reta_conf,
51 struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
52 struct otx2_rss_info *rss = &dev->rss_info;
57 if (reta_size != dev->rss_info.rss_size) {
58 otx2_err("Size of hash lookup table configured "
59 "(%d) doesn't match the number hardware can supported "
60 "(%d)", reta_size, dev->rss_info.rss_size);
65 for (i = 0; i < (dev->rss_info.rss_size / RTE_RETA_GROUP_SIZE); i++) {
66 for (j = 0; j < RTE_RETA_GROUP_SIZE; j++) {
67 if ((reta_conf[i].mask >> j) & 0x01)
68 rss->ind_tbl[idx] = reta_conf[i].reta[j];
73 return otx2_nix_rss_tbl_init(dev, 0, dev->rss_info.ind_tbl);
80 otx2_nix_dev_reta_query(struct rte_eth_dev *eth_dev,
81 struct rte_eth_rss_reta_entry64 *reta_conf,
84 struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
85 struct otx2_rss_info *rss = &dev->rss_info;
90 if (reta_size != dev->rss_info.rss_size) {
91 otx2_err("Size of hash lookup table configured "
92 "(%d) doesn't match the number hardware can supported "
93 "(%d)", reta_size, dev->rss_info.rss_size);
98 for (i = 0; i < (dev->rss_info.rss_size / RTE_RETA_GROUP_SIZE); i++) {
99 for (j = 0; j < RTE_RETA_GROUP_SIZE; j++)
100 if ((reta_conf[i].mask >> j) & 0x01)
101 reta_conf[i].reta[j] = rss->ind_tbl[j];
111 otx2_nix_rss_set_key(struct otx2_eth_dev *dev, uint8_t *key,
114 const uint8_t default_key[NIX_HASH_KEY_SIZE] = {
115 0xFE, 0xED, 0x0B, 0xAD, 0xFE, 0xED, 0x0B, 0xAD,
116 0xFE, 0xED, 0x0B, 0xAD, 0xFE, 0xED, 0x0B, 0xAD,
117 0xFE, 0xED, 0x0B, 0xAD, 0xFE, 0xED, 0x0B, 0xAD,
118 0xFE, 0xED, 0x0B, 0xAD, 0xFE, 0xED, 0x0B, 0xAD,
119 0xFE, 0xED, 0x0B, 0xAD, 0xFE, 0xED, 0x0B, 0xAD,
120 0xFE, 0xED, 0x0B, 0xAD, 0xFE, 0xED, 0x0B, 0xAD
122 struct otx2_rss_info *rss = &dev->rss_info;
127 if (key == NULL || key == 0) {
128 keyptr = (uint64_t *)(uintptr_t)default_key;
129 key_len = NIX_HASH_KEY_SIZE;
130 memset(rss->key, 0, key_len);
132 memcpy(rss->key, key, key_len);
133 keyptr = (uint64_t *)rss->key;
136 for (idx = 0; idx < (key_len >> 3); idx++) {
137 val = rte_cpu_to_be_64(*keyptr);
138 otx2_write64(val, dev->base + NIX_LF_RX_SECRETX(idx));
144 rss_get_key(struct otx2_eth_dev *dev, uint8_t *key)
146 uint64_t *keyptr = (uint64_t *)key;
150 for (idx = 0; idx < (NIX_HASH_KEY_SIZE >> 3); idx++) {
151 val = otx2_read64(dev->base + NIX_LF_RX_SECRETX(idx));
152 *keyptr = rte_be_to_cpu_64(val);
157 #define RSS_IPV4_ENABLE ( \
159 ETH_RSS_FRAG_IPV4 | \
160 ETH_RSS_NONFRAG_IPV4_UDP | \
161 ETH_RSS_NONFRAG_IPV4_TCP | \
162 ETH_RSS_NONFRAG_IPV4_SCTP)
164 #define RSS_IPV6_ENABLE ( \
166 ETH_RSS_FRAG_IPV6 | \
167 ETH_RSS_NONFRAG_IPV6_UDP | \
168 ETH_RSS_NONFRAG_IPV6_TCP | \
169 ETH_RSS_NONFRAG_IPV6_SCTP)
171 #define RSS_IPV6_EX_ENABLE ( \
173 ETH_RSS_IPV6_TCP_EX | \
176 #define RSS_MAX_LEVELS 3
178 #define RSS_IPV4_INDEX 0
179 #define RSS_IPV6_INDEX 1
180 #define RSS_TCP_INDEX 2
181 #define RSS_UDP_INDEX 3
182 #define RSS_SCTP_INDEX 4
183 #define RSS_DMAC_INDEX 5
186 otx2_rss_ethdev_to_nix(struct otx2_eth_dev *dev, uint64_t ethdev_rss,
189 uint32_t flow_key_type[RSS_MAX_LEVELS][6] = {
191 FLOW_KEY_TYPE_IPV4, FLOW_KEY_TYPE_IPV6,
192 FLOW_KEY_TYPE_TCP, FLOW_KEY_TYPE_UDP,
193 FLOW_KEY_TYPE_SCTP, FLOW_KEY_TYPE_ETH_DMAC
196 FLOW_KEY_TYPE_INNR_IPV4, FLOW_KEY_TYPE_INNR_IPV6,
197 FLOW_KEY_TYPE_INNR_TCP, FLOW_KEY_TYPE_INNR_UDP,
198 FLOW_KEY_TYPE_INNR_SCTP, FLOW_KEY_TYPE_INNR_ETH_DMAC
201 FLOW_KEY_TYPE_IPV4 | FLOW_KEY_TYPE_INNR_IPV4,
202 FLOW_KEY_TYPE_IPV6 | FLOW_KEY_TYPE_INNR_IPV6,
203 FLOW_KEY_TYPE_TCP | FLOW_KEY_TYPE_INNR_TCP,
204 FLOW_KEY_TYPE_UDP | FLOW_KEY_TYPE_INNR_UDP,
205 FLOW_KEY_TYPE_SCTP | FLOW_KEY_TYPE_INNR_SCTP,
206 FLOW_KEY_TYPE_ETH_DMAC | FLOW_KEY_TYPE_INNR_ETH_DMAC
209 uint32_t flowkey_cfg = 0;
211 dev->rss_info.nix_rss = ethdev_rss;
213 if (ethdev_rss & ETH_RSS_L2_PAYLOAD &&
214 dev->npc_flow.switch_header_type == OTX2_PRIV_FLAGS_LEN_90B) {
215 flowkey_cfg |= FLOW_KEY_TYPE_CH_LEN_90B;
218 if (ethdev_rss & ETH_RSS_L3_SRC_ONLY)
219 flowkey_cfg |= FLOW_KEY_TYPE_L3_SRC;
221 if (ethdev_rss & ETH_RSS_L3_DST_ONLY)
222 flowkey_cfg |= FLOW_KEY_TYPE_L3_DST;
224 if (ethdev_rss & ETH_RSS_L4_SRC_ONLY)
225 flowkey_cfg |= FLOW_KEY_TYPE_L4_SRC;
227 if (ethdev_rss & ETH_RSS_L4_DST_ONLY)
228 flowkey_cfg |= FLOW_KEY_TYPE_L4_DST;
230 if (ethdev_rss & RSS_IPV4_ENABLE)
231 flowkey_cfg |= flow_key_type[rss_level][RSS_IPV4_INDEX];
233 if (ethdev_rss & RSS_IPV6_ENABLE)
234 flowkey_cfg |= flow_key_type[rss_level][RSS_IPV6_INDEX];
236 if (ethdev_rss & ETH_RSS_TCP)
237 flowkey_cfg |= flow_key_type[rss_level][RSS_TCP_INDEX];
239 if (ethdev_rss & ETH_RSS_UDP)
240 flowkey_cfg |= flow_key_type[rss_level][RSS_UDP_INDEX];
242 if (ethdev_rss & ETH_RSS_SCTP)
243 flowkey_cfg |= flow_key_type[rss_level][RSS_SCTP_INDEX];
245 if (ethdev_rss & ETH_RSS_L2_PAYLOAD)
246 flowkey_cfg |= flow_key_type[rss_level][RSS_DMAC_INDEX];
248 if (ethdev_rss & RSS_IPV6_EX_ENABLE)
249 flowkey_cfg |= FLOW_KEY_TYPE_IPV6_EXT;
251 if (ethdev_rss & ETH_RSS_PORT)
252 flowkey_cfg |= FLOW_KEY_TYPE_PORT;
254 if (ethdev_rss & ETH_RSS_NVGRE)
255 flowkey_cfg |= FLOW_KEY_TYPE_NVGRE;
257 if (ethdev_rss & ETH_RSS_VXLAN)
258 flowkey_cfg |= FLOW_KEY_TYPE_VXLAN;
260 if (ethdev_rss & ETH_RSS_GENEVE)
261 flowkey_cfg |= FLOW_KEY_TYPE_GENEVE;
263 if (ethdev_rss & ETH_RSS_GTPU)
264 flowkey_cfg |= FLOW_KEY_TYPE_GTPU;
270 otx2_rss_set_hf(struct otx2_eth_dev *dev, uint32_t flowkey_cfg,
271 uint8_t *alg_idx, uint8_t group, int mcam_index)
273 struct nix_rss_flowkey_cfg_rsp *rss_rsp;
274 struct otx2_mbox *mbox = dev->mbox;
275 struct nix_rss_flowkey_cfg *cfg;
280 dev->rss_info.flowkey_cfg = flowkey_cfg;
282 cfg = otx2_mbox_alloc_msg_nix_rss_flowkey_cfg(mbox);
284 cfg->flowkey_cfg = flowkey_cfg;
285 cfg->mcam_index = mcam_index; /* -1 indicates default group */
286 cfg->group = group; /* 0 is default group */
288 rc = otx2_mbox_process_msg(mbox, (void *)&rss_rsp);
293 *alg_idx = rss_rsp->alg_idx;
299 otx2_nix_rss_hash_update(struct rte_eth_dev *eth_dev,
300 struct rte_eth_rss_conf *rss_conf)
302 struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
303 uint32_t flowkey_cfg;
309 if (rss_conf->rss_key && rss_conf->rss_key_len != NIX_HASH_KEY_SIZE) {
310 otx2_err("Hash key size mismatch %d vs %d",
311 rss_conf->rss_key_len, NIX_HASH_KEY_SIZE);
315 if (rss_conf->rss_key)
316 otx2_nix_rss_set_key(dev, rss_conf->rss_key,
317 (uint32_t)rss_conf->rss_key_len);
319 flowkey_cfg = otx2_rss_ethdev_to_nix(dev, rss_conf->rss_hf, 0);
321 rc = otx2_rss_set_hf(dev, flowkey_cfg, &alg_idx,
322 NIX_DEFAULT_RSS_CTX_GROUP,
323 NIX_DEFAULT_RSS_MCAM_IDX);
325 otx2_err("Failed to set RSS hash function rc=%d", rc);
329 dev->rss_info.alg_idx = alg_idx;
336 otx2_nix_rss_hash_conf_get(struct rte_eth_dev *eth_dev,
337 struct rte_eth_rss_conf *rss_conf)
339 struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
341 if (rss_conf->rss_key)
342 rss_get_key(dev, rss_conf->rss_key);
344 rss_conf->rss_key_len = NIX_HASH_KEY_SIZE;
345 rss_conf->rss_hf = dev->rss_info.nix_rss;
351 otx2_nix_rss_config(struct rte_eth_dev *eth_dev)
353 struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
354 uint32_t idx, qcnt = eth_dev->data->nb_rx_queues;
355 uint32_t flowkey_cfg;
360 /* Skip further configuration if selected mode is not RSS */
361 if (eth_dev->data->dev_conf.rxmode.mq_mode != ETH_MQ_RX_RSS)
364 /* Update default RSS key and cfg */
365 otx2_nix_rss_set_key(dev, NULL, 0);
367 /* Update default RSS RETA */
368 for (idx = 0; idx < dev->rss_info.rss_size; idx++)
369 dev->rss_info.ind_tbl[idx] = idx % qcnt;
371 /* Init RSS table context */
372 rc = otx2_nix_rss_tbl_init(dev, 0, dev->rss_info.ind_tbl);
374 otx2_err("Failed to init RSS table rc=%d", rc);
378 rss_hf = eth_dev->data->dev_conf.rx_adv_conf.rss_conf.rss_hf;
379 flowkey_cfg = otx2_rss_ethdev_to_nix(dev, rss_hf, 0);
381 rc = otx2_rss_set_hf(dev, flowkey_cfg, &alg_idx,
382 NIX_DEFAULT_RSS_CTX_GROUP,
383 NIX_DEFAULT_RSS_MCAM_IDX);
385 otx2_err("Failed to set RSS hash function rc=%d", rc);
389 dev->rss_info.alg_idx = alg_idx;