]> git.proxmox.com Git - ceph.git/blame - ceph/src/spdk/dpdk/drivers/net/octeontx2/otx2_rss.c
update source to Ceph Pacific 16.2.2
[ceph.git] / ceph / src / spdk / dpdk / drivers / net / octeontx2 / otx2_rss.c
CommitLineData
f67539c2
TL
1/* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(C) 2019 Marvell International Ltd.
3 */
4
5#include "otx2_ethdev.h"
6
7int
8otx2_nix_rss_tbl_init(struct otx2_eth_dev *dev,
9 uint8_t group, uint16_t *ind_tbl)
10{
11 struct otx2_rss_info *rss = &dev->rss_info;
12 struct otx2_mbox *mbox = dev->mbox;
13 struct nix_aq_enq_req *req;
14 int rc, idx;
15
16 for (idx = 0; idx < rss->rss_size; idx++) {
17 req = otx2_mbox_alloc_msg_nix_aq_enq(mbox);
18 if (!req) {
19 /* The shared memory buffer can be full.
20 * Flush it and retry
21 */
22 otx2_mbox_msg_send(mbox, 0);
23 rc = otx2_mbox_wait_for_rsp(mbox, 0);
24 if (rc < 0)
25 return rc;
26
27 req = otx2_mbox_alloc_msg_nix_aq_enq(mbox);
28 if (!req)
29 return -ENOMEM;
30 }
31 req->rss.rq = ind_tbl[idx];
32 /* Fill AQ info */
33 req->qidx = (group * rss->rss_size) + idx;
34 req->ctype = NIX_AQ_CTYPE_RSS;
35 req->op = NIX_AQ_INSTOP_INIT;
36 }
37
38 otx2_mbox_msg_send(mbox, 0);
39 rc = otx2_mbox_wait_for_rsp(mbox, 0);
40 if (rc < 0)
41 return rc;
42
43 return 0;
44}
45
46int
47otx2_nix_dev_reta_update(struct rte_eth_dev *eth_dev,
48 struct rte_eth_rss_reta_entry64 *reta_conf,
49 uint16_t reta_size)
50{
51 struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
52 struct otx2_rss_info *rss = &dev->rss_info;
53 int rc, i, j;
54 int idx = 0;
55
56 rc = -EINVAL;
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);
61 goto fail;
62 }
63
64 /* Copy RETA table */
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];
69 idx++;
70 }
71 }
72
73 return otx2_nix_rss_tbl_init(dev, 0, dev->rss_info.ind_tbl);
74
75fail:
76 return rc;
77}
78
79int
80otx2_nix_dev_reta_query(struct rte_eth_dev *eth_dev,
81 struct rte_eth_rss_reta_entry64 *reta_conf,
82 uint16_t reta_size)
83{
84 struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
85 struct otx2_rss_info *rss = &dev->rss_info;
86 int rc, i, j;
87
88 rc = -EINVAL;
89
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);
94 goto fail;
95 }
96
97 /* Copy RETA table */
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];
102 }
103
104 return 0;
105
106fail:
107 return rc;
108}
109
110void
111otx2_nix_rss_set_key(struct otx2_eth_dev *dev, uint8_t *key,
112 uint32_t key_len)
113{
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
121 };
122 struct otx2_rss_info *rss = &dev->rss_info;
123 uint64_t *keyptr;
124 uint64_t val;
125 uint32_t idx;
126
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);
131 } else {
132 memcpy(rss->key, key, key_len);
133 keyptr = (uint64_t *)rss->key;
134 }
135
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));
139 keyptr++;
140 }
141}
142
143static void
144rss_get_key(struct otx2_eth_dev *dev, uint8_t *key)
145{
146 uint64_t *keyptr = (uint64_t *)key;
147 uint64_t val;
148 int idx;
149
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);
153 keyptr++;
154 }
155}
156
157#define RSS_IPV4_ENABLE ( \
158 ETH_RSS_IPV4 | \
159 ETH_RSS_FRAG_IPV4 | \
160 ETH_RSS_NONFRAG_IPV4_UDP | \
161 ETH_RSS_NONFRAG_IPV4_TCP | \
162 ETH_RSS_NONFRAG_IPV4_SCTP)
163
164#define RSS_IPV6_ENABLE ( \
165 ETH_RSS_IPV6 | \
166 ETH_RSS_FRAG_IPV6 | \
167 ETH_RSS_NONFRAG_IPV6_UDP | \
168 ETH_RSS_NONFRAG_IPV6_TCP | \
169 ETH_RSS_NONFRAG_IPV6_SCTP)
170
171#define RSS_IPV6_EX_ENABLE ( \
172 ETH_RSS_IPV6_EX | \
173 ETH_RSS_IPV6_TCP_EX | \
174 ETH_RSS_IPV6_UDP_EX)
175
176#define RSS_MAX_LEVELS 3
177
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
184
185uint32_t
186otx2_rss_ethdev_to_nix(struct otx2_eth_dev *dev, uint64_t ethdev_rss,
187 uint8_t rss_level)
188{
189 uint32_t flow_key_type[RSS_MAX_LEVELS][6] = {
190 {
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
194 },
195 {
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
199 },
200 {
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
207 }
208 };
209 uint32_t flowkey_cfg = 0;
210
211 dev->rss_info.nix_rss = ethdev_rss;
212
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;
216 }
217
218 if (ethdev_rss & ETH_RSS_L3_SRC_ONLY)
219 flowkey_cfg |= FLOW_KEY_TYPE_L3_SRC;
220
221 if (ethdev_rss & ETH_RSS_L3_DST_ONLY)
222 flowkey_cfg |= FLOW_KEY_TYPE_L3_DST;
223
224 if (ethdev_rss & ETH_RSS_L4_SRC_ONLY)
225 flowkey_cfg |= FLOW_KEY_TYPE_L4_SRC;
226
227 if (ethdev_rss & ETH_RSS_L4_DST_ONLY)
228 flowkey_cfg |= FLOW_KEY_TYPE_L4_DST;
229
230 if (ethdev_rss & RSS_IPV4_ENABLE)
231 flowkey_cfg |= flow_key_type[rss_level][RSS_IPV4_INDEX];
232
233 if (ethdev_rss & RSS_IPV6_ENABLE)
234 flowkey_cfg |= flow_key_type[rss_level][RSS_IPV6_INDEX];
235
236 if (ethdev_rss & ETH_RSS_TCP)
237 flowkey_cfg |= flow_key_type[rss_level][RSS_TCP_INDEX];
238
239 if (ethdev_rss & ETH_RSS_UDP)
240 flowkey_cfg |= flow_key_type[rss_level][RSS_UDP_INDEX];
241
242 if (ethdev_rss & ETH_RSS_SCTP)
243 flowkey_cfg |= flow_key_type[rss_level][RSS_SCTP_INDEX];
244
245 if (ethdev_rss & ETH_RSS_L2_PAYLOAD)
246 flowkey_cfg |= flow_key_type[rss_level][RSS_DMAC_INDEX];
247
248 if (ethdev_rss & RSS_IPV6_EX_ENABLE)
249 flowkey_cfg |= FLOW_KEY_TYPE_IPV6_EXT;
250
251 if (ethdev_rss & ETH_RSS_PORT)
252 flowkey_cfg |= FLOW_KEY_TYPE_PORT;
253
254 if (ethdev_rss & ETH_RSS_NVGRE)
255 flowkey_cfg |= FLOW_KEY_TYPE_NVGRE;
256
257 if (ethdev_rss & ETH_RSS_VXLAN)
258 flowkey_cfg |= FLOW_KEY_TYPE_VXLAN;
259
260 if (ethdev_rss & ETH_RSS_GENEVE)
261 flowkey_cfg |= FLOW_KEY_TYPE_GENEVE;
262
263 if (ethdev_rss & ETH_RSS_GTPU)
264 flowkey_cfg |= FLOW_KEY_TYPE_GTPU;
265
266 return flowkey_cfg;
267}
268
269int
270otx2_rss_set_hf(struct otx2_eth_dev *dev, uint32_t flowkey_cfg,
271 uint8_t *alg_idx, uint8_t group, int mcam_index)
272{
273 struct nix_rss_flowkey_cfg_rsp *rss_rsp;
274 struct otx2_mbox *mbox = dev->mbox;
275 struct nix_rss_flowkey_cfg *cfg;
276 int rc;
277
278 rc = -EINVAL;
279
280 dev->rss_info.flowkey_cfg = flowkey_cfg;
281
282 cfg = otx2_mbox_alloc_msg_nix_rss_flowkey_cfg(mbox);
283
284 cfg->flowkey_cfg = flowkey_cfg;
285 cfg->mcam_index = mcam_index; /* -1 indicates default group */
286 cfg->group = group; /* 0 is default group */
287
288 rc = otx2_mbox_process_msg(mbox, (void *)&rss_rsp);
289 if (rc)
290 return rc;
291
292 if (alg_idx)
293 *alg_idx = rss_rsp->alg_idx;
294
295 return rc;
296}
297
298int
299otx2_nix_rss_hash_update(struct rte_eth_dev *eth_dev,
300 struct rte_eth_rss_conf *rss_conf)
301{
302 struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
303 uint32_t flowkey_cfg;
304 uint8_t alg_idx;
305 int rc;
306
307 rc = -EINVAL;
308
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);
312 goto fail;
313 }
314
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);
318
319 flowkey_cfg = otx2_rss_ethdev_to_nix(dev, rss_conf->rss_hf, 0);
320
321 rc = otx2_rss_set_hf(dev, flowkey_cfg, &alg_idx,
322 NIX_DEFAULT_RSS_CTX_GROUP,
323 NIX_DEFAULT_RSS_MCAM_IDX);
324 if (rc) {
325 otx2_err("Failed to set RSS hash function rc=%d", rc);
326 return rc;
327 }
328
329 dev->rss_info.alg_idx = alg_idx;
330
331fail:
332 return rc;
333}
334
335int
336otx2_nix_rss_hash_conf_get(struct rte_eth_dev *eth_dev,
337 struct rte_eth_rss_conf *rss_conf)
338{
339 struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
340
341 if (rss_conf->rss_key)
342 rss_get_key(dev, rss_conf->rss_key);
343
344 rss_conf->rss_key_len = NIX_HASH_KEY_SIZE;
345 rss_conf->rss_hf = dev->rss_info.nix_rss;
346
347 return 0;
348}
349
350int
351otx2_nix_rss_config(struct rte_eth_dev *eth_dev)
352{
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;
356 uint64_t rss_hf;
357 uint8_t alg_idx;
358 int rc;
359
360 /* Skip further configuration if selected mode is not RSS */
361 if (eth_dev->data->dev_conf.rxmode.mq_mode != ETH_MQ_RX_RSS || !qcnt)
362 return 0;
363
364 /* Update default RSS key and cfg */
365 otx2_nix_rss_set_key(dev, NULL, 0);
366
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;
370
371 /* Init RSS table context */
372 rc = otx2_nix_rss_tbl_init(dev, 0, dev->rss_info.ind_tbl);
373 if (rc) {
374 otx2_err("Failed to init RSS table rc=%d", rc);
375 return rc;
376 }
377
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);
380
381 rc = otx2_rss_set_hf(dev, flowkey_cfg, &alg_idx,
382 NIX_DEFAULT_RSS_CTX_GROUP,
383 NIX_DEFAULT_RSS_MCAM_IDX);
384 if (rc) {
385 otx2_err("Failed to set RSS hash function rc=%d", rc);
386 return rc;
387 }
388
389 dev->rss_info.alg_idx = alg_idx;
390
391 return 0;
392}