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 & RSS_IPV4_ENABLE)
214 flowkey_cfg |= flow_key_type[rss_level][RSS_IPV4_INDEX];
216 if (ethdev_rss & RSS_IPV6_ENABLE)
217 flowkey_cfg |= flow_key_type[rss_level][RSS_IPV6_INDEX];
219 if (ethdev_rss & ETH_RSS_TCP)
220 flowkey_cfg |= flow_key_type[rss_level][RSS_TCP_INDEX];
222 if (ethdev_rss & ETH_RSS_UDP)
223 flowkey_cfg |= flow_key_type[rss_level][RSS_UDP_INDEX];
225 if (ethdev_rss & ETH_RSS_SCTP)
226 flowkey_cfg |= flow_key_type[rss_level][RSS_SCTP_INDEX];
228 if (ethdev_rss & ETH_RSS_L2_PAYLOAD)
229 flowkey_cfg |= flow_key_type[rss_level][RSS_DMAC_INDEX];
231 if (ethdev_rss & RSS_IPV6_EX_ENABLE)
232 flowkey_cfg |= FLOW_KEY_TYPE_IPV6_EXT;
234 if (ethdev_rss & ETH_RSS_PORT)
235 flowkey_cfg |= FLOW_KEY_TYPE_PORT;
237 if (ethdev_rss & ETH_RSS_NVGRE)
238 flowkey_cfg |= FLOW_KEY_TYPE_NVGRE;
240 if (ethdev_rss & ETH_RSS_VXLAN)
241 flowkey_cfg |= FLOW_KEY_TYPE_VXLAN;
243 if (ethdev_rss & ETH_RSS_GENEVE)
244 flowkey_cfg |= FLOW_KEY_TYPE_GENEVE;
246 if (ethdev_rss & ETH_RSS_GTPU)
247 flowkey_cfg |= FLOW_KEY_TYPE_GTPU;
253 otx2_rss_set_hf(struct otx2_eth_dev *dev, uint32_t flowkey_cfg,
254 uint8_t *alg_idx, uint8_t group, int mcam_index)
256 struct nix_rss_flowkey_cfg_rsp *rss_rsp;
257 struct otx2_mbox *mbox = dev->mbox;
258 struct nix_rss_flowkey_cfg *cfg;
263 dev->rss_info.flowkey_cfg = flowkey_cfg;
265 cfg = otx2_mbox_alloc_msg_nix_rss_flowkey_cfg(mbox);
267 cfg->flowkey_cfg = flowkey_cfg;
268 cfg->mcam_index = mcam_index; /* -1 indicates default group */
269 cfg->group = group; /* 0 is default group */
271 rc = otx2_mbox_process_msg(mbox, (void *)&rss_rsp);
276 *alg_idx = rss_rsp->alg_idx;
282 otx2_nix_rss_hash_update(struct rte_eth_dev *eth_dev,
283 struct rte_eth_rss_conf *rss_conf)
285 struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
286 uint32_t flowkey_cfg;
292 if (rss_conf->rss_key && rss_conf->rss_key_len != NIX_HASH_KEY_SIZE) {
293 otx2_err("Hash key size mismatch %d vs %d",
294 rss_conf->rss_key_len, NIX_HASH_KEY_SIZE);
298 if (rss_conf->rss_key)
299 otx2_nix_rss_set_key(dev, rss_conf->rss_key,
300 (uint32_t)rss_conf->rss_key_len);
302 flowkey_cfg = otx2_rss_ethdev_to_nix(dev, rss_conf->rss_hf, 0);
304 rc = otx2_rss_set_hf(dev, flowkey_cfg, &alg_idx,
305 NIX_DEFAULT_RSS_CTX_GROUP,
306 NIX_DEFAULT_RSS_MCAM_IDX);
308 otx2_err("Failed to set RSS hash function rc=%d", rc);
312 dev->rss_info.alg_idx = alg_idx;
319 otx2_nix_rss_hash_conf_get(struct rte_eth_dev *eth_dev,
320 struct rte_eth_rss_conf *rss_conf)
322 struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
324 if (rss_conf->rss_key)
325 rss_get_key(dev, rss_conf->rss_key);
327 rss_conf->rss_key_len = NIX_HASH_KEY_SIZE;
328 rss_conf->rss_hf = dev->rss_info.nix_rss;
334 otx2_nix_rss_config(struct rte_eth_dev *eth_dev)
336 struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
337 uint32_t idx, qcnt = eth_dev->data->nb_rx_queues;
338 uint32_t flowkey_cfg;
343 /* Skip further configuration if selected mode is not RSS */
344 if (eth_dev->data->dev_conf.rxmode.mq_mode != ETH_MQ_RX_RSS)
347 /* Update default RSS key and cfg */
348 otx2_nix_rss_set_key(dev, NULL, 0);
350 /* Update default RSS RETA */
351 for (idx = 0; idx < dev->rss_info.rss_size; idx++)
352 dev->rss_info.ind_tbl[idx] = idx % qcnt;
354 /* Init RSS table context */
355 rc = otx2_nix_rss_tbl_init(dev, 0, dev->rss_info.ind_tbl);
357 otx2_err("Failed to init RSS table rc=%d", rc);
361 rss_hf = eth_dev->data->dev_conf.rx_adv_conf.rss_conf.rss_hf;
362 flowkey_cfg = otx2_rss_ethdev_to_nix(dev, rss_hf, 0);
364 rc = otx2_rss_set_hf(dev, flowkey_cfg, &alg_idx,
365 NIX_DEFAULT_RSS_CTX_GROUP,
366 NIX_DEFAULT_RSS_MCAM_IDX);
368 otx2_err("Failed to set RSS hash function rc=%d", rc);
372 dev->rss_info.alg_idx = alg_idx;