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;
37 if (!dev->lock_rx_ctx)
40 req = otx2_mbox_alloc_msg_nix_aq_enq(mbox);
42 /* The shared memory buffer can be full.
45 otx2_mbox_msg_send(mbox, 0);
46 rc = otx2_mbox_wait_for_rsp(mbox, 0);
50 req = otx2_mbox_alloc_msg_nix_aq_enq(mbox);
54 req->rss.rq = ind_tbl[idx];
56 req->qidx = (group * rss->rss_size) + idx;
57 req->ctype = NIX_AQ_CTYPE_RSS;
58 req->op = NIX_AQ_INSTOP_LOCK;
61 otx2_mbox_msg_send(mbox, 0);
62 rc = otx2_mbox_wait_for_rsp(mbox, 0);
70 otx2_nix_dev_reta_update(struct rte_eth_dev *eth_dev,
71 struct rte_eth_rss_reta_entry64 *reta_conf,
74 struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
75 struct otx2_rss_info *rss = &dev->rss_info;
80 if (reta_size != dev->rss_info.rss_size) {
81 otx2_err("Size of hash lookup table configured "
82 "(%d) doesn't match the number hardware can supported "
83 "(%d)", reta_size, dev->rss_info.rss_size);
88 for (i = 0; i < (dev->rss_info.rss_size / RTE_RETA_GROUP_SIZE); i++) {
89 for (j = 0; j < RTE_RETA_GROUP_SIZE; j++) {
90 if ((reta_conf[i].mask >> j) & 0x01)
91 rss->ind_tbl[idx] = reta_conf[i].reta[j];
96 return otx2_nix_rss_tbl_init(dev, 0, dev->rss_info.ind_tbl);
103 otx2_nix_dev_reta_query(struct rte_eth_dev *eth_dev,
104 struct rte_eth_rss_reta_entry64 *reta_conf,
107 struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
108 struct otx2_rss_info *rss = &dev->rss_info;
113 if (reta_size != dev->rss_info.rss_size) {
114 otx2_err("Size of hash lookup table configured "
115 "(%d) doesn't match the number hardware can supported "
116 "(%d)", reta_size, dev->rss_info.rss_size);
120 /* Copy RETA table */
121 for (i = 0; i < (dev->rss_info.rss_size / RTE_RETA_GROUP_SIZE); i++) {
122 for (j = 0; j < RTE_RETA_GROUP_SIZE; j++)
123 if ((reta_conf[i].mask >> j) & 0x01)
124 reta_conf[i].reta[j] = rss->ind_tbl[j];
134 otx2_nix_rss_set_key(struct otx2_eth_dev *dev, uint8_t *key,
137 const uint8_t default_key[NIX_HASH_KEY_SIZE] = {
138 0xFE, 0xED, 0x0B, 0xAD, 0xFE, 0xED, 0x0B, 0xAD,
139 0xFE, 0xED, 0x0B, 0xAD, 0xFE, 0xED, 0x0B, 0xAD,
140 0xFE, 0xED, 0x0B, 0xAD, 0xFE, 0xED, 0x0B, 0xAD,
141 0xFE, 0xED, 0x0B, 0xAD, 0xFE, 0xED, 0x0B, 0xAD,
142 0xFE, 0xED, 0x0B, 0xAD, 0xFE, 0xED, 0x0B, 0xAD,
143 0xFE, 0xED, 0x0B, 0xAD, 0xFE, 0xED, 0x0B, 0xAD
145 struct otx2_rss_info *rss = &dev->rss_info;
150 if (key == NULL || key == 0) {
151 keyptr = (uint64_t *)(uintptr_t)default_key;
152 key_len = NIX_HASH_KEY_SIZE;
153 memset(rss->key, 0, key_len);
155 memcpy(rss->key, key, key_len);
156 keyptr = (uint64_t *)rss->key;
159 for (idx = 0; idx < (key_len >> 3); idx++) {
160 val = rte_cpu_to_be_64(*keyptr);
161 otx2_write64(val, dev->base + NIX_LF_RX_SECRETX(idx));
167 rss_get_key(struct otx2_eth_dev *dev, uint8_t *key)
169 uint64_t *keyptr = (uint64_t *)key;
173 for (idx = 0; idx < (NIX_HASH_KEY_SIZE >> 3); idx++) {
174 val = otx2_read64(dev->base + NIX_LF_RX_SECRETX(idx));
175 *keyptr = rte_be_to_cpu_64(val);
180 #define RSS_IPV4_ENABLE ( \
182 ETH_RSS_FRAG_IPV4 | \
183 ETH_RSS_NONFRAG_IPV4_UDP | \
184 ETH_RSS_NONFRAG_IPV4_TCP | \
185 ETH_RSS_NONFRAG_IPV4_SCTP)
187 #define RSS_IPV6_ENABLE ( \
189 ETH_RSS_FRAG_IPV6 | \
190 ETH_RSS_NONFRAG_IPV6_UDP | \
191 ETH_RSS_NONFRAG_IPV6_TCP | \
192 ETH_RSS_NONFRAG_IPV6_SCTP)
194 #define RSS_IPV6_EX_ENABLE ( \
196 ETH_RSS_IPV6_TCP_EX | \
199 #define RSS_MAX_LEVELS 3
201 #define RSS_IPV4_INDEX 0
202 #define RSS_IPV6_INDEX 1
203 #define RSS_TCP_INDEX 2
204 #define RSS_UDP_INDEX 3
205 #define RSS_SCTP_INDEX 4
206 #define RSS_DMAC_INDEX 5
209 otx2_rss_ethdev_to_nix(struct otx2_eth_dev *dev, uint64_t ethdev_rss,
212 uint32_t flow_key_type[RSS_MAX_LEVELS][6] = {
214 FLOW_KEY_TYPE_IPV4, FLOW_KEY_TYPE_IPV6,
215 FLOW_KEY_TYPE_TCP, FLOW_KEY_TYPE_UDP,
216 FLOW_KEY_TYPE_SCTP, FLOW_KEY_TYPE_ETH_DMAC
219 FLOW_KEY_TYPE_INNR_IPV4, FLOW_KEY_TYPE_INNR_IPV6,
220 FLOW_KEY_TYPE_INNR_TCP, FLOW_KEY_TYPE_INNR_UDP,
221 FLOW_KEY_TYPE_INNR_SCTP, FLOW_KEY_TYPE_INNR_ETH_DMAC
224 FLOW_KEY_TYPE_IPV4 | FLOW_KEY_TYPE_INNR_IPV4,
225 FLOW_KEY_TYPE_IPV6 | FLOW_KEY_TYPE_INNR_IPV6,
226 FLOW_KEY_TYPE_TCP | FLOW_KEY_TYPE_INNR_TCP,
227 FLOW_KEY_TYPE_UDP | FLOW_KEY_TYPE_INNR_UDP,
228 FLOW_KEY_TYPE_SCTP | FLOW_KEY_TYPE_INNR_SCTP,
229 FLOW_KEY_TYPE_ETH_DMAC | FLOW_KEY_TYPE_INNR_ETH_DMAC
232 uint32_t flowkey_cfg = 0;
234 dev->rss_info.nix_rss = ethdev_rss;
236 if (ethdev_rss & ETH_RSS_L2_PAYLOAD &&
237 dev->npc_flow.switch_header_type == OTX2_PRIV_FLAGS_LEN_90B) {
238 flowkey_cfg |= FLOW_KEY_TYPE_CH_LEN_90B;
241 if (ethdev_rss & ETH_RSS_L3_SRC_ONLY)
242 flowkey_cfg |= FLOW_KEY_TYPE_L3_SRC;
244 if (ethdev_rss & ETH_RSS_L3_DST_ONLY)
245 flowkey_cfg |= FLOW_KEY_TYPE_L3_DST;
247 if (ethdev_rss & ETH_RSS_L4_SRC_ONLY)
248 flowkey_cfg |= FLOW_KEY_TYPE_L4_SRC;
250 if (ethdev_rss & ETH_RSS_L4_DST_ONLY)
251 flowkey_cfg |= FLOW_KEY_TYPE_L4_DST;
253 if (ethdev_rss & RSS_IPV4_ENABLE)
254 flowkey_cfg |= flow_key_type[rss_level][RSS_IPV4_INDEX];
256 if (ethdev_rss & RSS_IPV6_ENABLE)
257 flowkey_cfg |= flow_key_type[rss_level][RSS_IPV6_INDEX];
259 if (ethdev_rss & ETH_RSS_TCP)
260 flowkey_cfg |= flow_key_type[rss_level][RSS_TCP_INDEX];
262 if (ethdev_rss & ETH_RSS_UDP)
263 flowkey_cfg |= flow_key_type[rss_level][RSS_UDP_INDEX];
265 if (ethdev_rss & ETH_RSS_SCTP)
266 flowkey_cfg |= flow_key_type[rss_level][RSS_SCTP_INDEX];
268 if (ethdev_rss & ETH_RSS_L2_PAYLOAD)
269 flowkey_cfg |= flow_key_type[rss_level][RSS_DMAC_INDEX];
271 if (ethdev_rss & RSS_IPV6_EX_ENABLE)
272 flowkey_cfg |= FLOW_KEY_TYPE_IPV6_EXT;
274 if (ethdev_rss & ETH_RSS_PORT)
275 flowkey_cfg |= FLOW_KEY_TYPE_PORT;
277 if (ethdev_rss & ETH_RSS_NVGRE)
278 flowkey_cfg |= FLOW_KEY_TYPE_NVGRE;
280 if (ethdev_rss & ETH_RSS_VXLAN)
281 flowkey_cfg |= FLOW_KEY_TYPE_VXLAN;
283 if (ethdev_rss & ETH_RSS_GENEVE)
284 flowkey_cfg |= FLOW_KEY_TYPE_GENEVE;
286 if (ethdev_rss & ETH_RSS_GTPU)
287 flowkey_cfg |= FLOW_KEY_TYPE_GTPU;
293 otx2_rss_set_hf(struct otx2_eth_dev *dev, uint32_t flowkey_cfg,
294 uint8_t *alg_idx, uint8_t group, int mcam_index)
296 struct nix_rss_flowkey_cfg_rsp *rss_rsp;
297 struct otx2_mbox *mbox = dev->mbox;
298 struct nix_rss_flowkey_cfg *cfg;
303 dev->rss_info.flowkey_cfg = flowkey_cfg;
305 cfg = otx2_mbox_alloc_msg_nix_rss_flowkey_cfg(mbox);
307 cfg->flowkey_cfg = flowkey_cfg;
308 cfg->mcam_index = mcam_index; /* -1 indicates default group */
309 cfg->group = group; /* 0 is default group */
311 rc = otx2_mbox_process_msg(mbox, (void *)&rss_rsp);
316 *alg_idx = rss_rsp->alg_idx;
322 otx2_nix_rss_hash_update(struct rte_eth_dev *eth_dev,
323 struct rte_eth_rss_conf *rss_conf)
325 struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
326 uint32_t flowkey_cfg;
332 if (rss_conf->rss_key && rss_conf->rss_key_len != NIX_HASH_KEY_SIZE) {
333 otx2_err("Hash key size mismatch %d vs %d",
334 rss_conf->rss_key_len, NIX_HASH_KEY_SIZE);
338 if (rss_conf->rss_key)
339 otx2_nix_rss_set_key(dev, rss_conf->rss_key,
340 (uint32_t)rss_conf->rss_key_len);
342 flowkey_cfg = otx2_rss_ethdev_to_nix(dev, rss_conf->rss_hf, 0);
344 rc = otx2_rss_set_hf(dev, flowkey_cfg, &alg_idx,
345 NIX_DEFAULT_RSS_CTX_GROUP,
346 NIX_DEFAULT_RSS_MCAM_IDX);
348 otx2_err("Failed to set RSS hash function rc=%d", rc);
352 dev->rss_info.alg_idx = alg_idx;
359 otx2_nix_rss_hash_conf_get(struct rte_eth_dev *eth_dev,
360 struct rte_eth_rss_conf *rss_conf)
362 struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
364 if (rss_conf->rss_key)
365 rss_get_key(dev, rss_conf->rss_key);
367 rss_conf->rss_key_len = NIX_HASH_KEY_SIZE;
368 rss_conf->rss_hf = dev->rss_info.nix_rss;
374 otx2_nix_rss_config(struct rte_eth_dev *eth_dev)
376 struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
377 uint32_t idx, qcnt = eth_dev->data->nb_rx_queues;
378 uint32_t flowkey_cfg;
383 /* Skip further configuration if selected mode is not RSS */
384 if (eth_dev->data->dev_conf.rxmode.mq_mode != ETH_MQ_RX_RSS || !qcnt)
387 /* Update default RSS key and cfg */
388 otx2_nix_rss_set_key(dev, NULL, 0);
390 /* Update default RSS RETA */
391 for (idx = 0; idx < dev->rss_info.rss_size; idx++)
392 dev->rss_info.ind_tbl[idx] = idx % qcnt;
394 /* Init RSS table context */
395 rc = otx2_nix_rss_tbl_init(dev, 0, dev->rss_info.ind_tbl);
397 otx2_err("Failed to init RSS table rc=%d", rc);
401 rss_hf = eth_dev->data->dev_conf.rx_adv_conf.rss_conf.rss_hf;
402 flowkey_cfg = otx2_rss_ethdev_to_nix(dev, rss_hf, 0);
404 rc = otx2_rss_set_hf(dev, flowkey_cfg, &alg_idx,
405 NIX_DEFAULT_RSS_CTX_GROUP,
406 NIX_DEFAULT_RSS_MCAM_IDX);
408 otx2_err("Failed to set RSS hash function rc=%d", rc);
412 dev->rss_info.alg_idx = alg_idx;