5e3f866819800d4e4c8a986fce662d47f47bbd86
[dpdk.git] / drivers / net / octeontx2 / otx2_rss.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(C) 2019 Marvell International Ltd.
3  */
4
5 #include "otx2_ethdev.h"
6
7 int
8 otx2_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
46 int
47 otx2_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
75 fail:
76         return rc;
77 }
78
79 int
80 otx2_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
106 fail:
107         return rc;
108 }
109
110 void
111 otx2_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
143 static void
144 rss_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
185 uint32_t
186 otx2_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
269 int
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)
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
298 int
299 otx2_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
331 fail:
332         return rc;
333 }
334
335 int
336 otx2_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
350 int
351 otx2_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 }