net/octeontx2: extend RSS supported offload types
[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_L3_SRC_ONLY)
214                 flowkey_cfg |= FLOW_KEY_TYPE_L3_SRC;
215
216         if (ethdev_rss & ETH_RSS_L3_DST_ONLY)
217                 flowkey_cfg |= FLOW_KEY_TYPE_L3_DST;
218
219         if (ethdev_rss & ETH_RSS_L4_SRC_ONLY)
220                 flowkey_cfg |= FLOW_KEY_TYPE_L4_SRC;
221
222         if (ethdev_rss & ETH_RSS_L4_DST_ONLY)
223                 flowkey_cfg |= FLOW_KEY_TYPE_L4_DST;
224
225         if (ethdev_rss & RSS_IPV4_ENABLE)
226                 flowkey_cfg |= flow_key_type[rss_level][RSS_IPV4_INDEX];
227
228         if (ethdev_rss & RSS_IPV6_ENABLE)
229                 flowkey_cfg |= flow_key_type[rss_level][RSS_IPV6_INDEX];
230
231         if (ethdev_rss & ETH_RSS_TCP)
232                 flowkey_cfg |= flow_key_type[rss_level][RSS_TCP_INDEX];
233
234         if (ethdev_rss & ETH_RSS_UDP)
235                 flowkey_cfg |= flow_key_type[rss_level][RSS_UDP_INDEX];
236
237         if (ethdev_rss & ETH_RSS_SCTP)
238                 flowkey_cfg |= flow_key_type[rss_level][RSS_SCTP_INDEX];
239
240         if (ethdev_rss & ETH_RSS_L2_PAYLOAD)
241                 flowkey_cfg |= flow_key_type[rss_level][RSS_DMAC_INDEX];
242
243         if (ethdev_rss & RSS_IPV6_EX_ENABLE)
244                 flowkey_cfg |= FLOW_KEY_TYPE_IPV6_EXT;
245
246         if (ethdev_rss & ETH_RSS_PORT)
247                 flowkey_cfg |= FLOW_KEY_TYPE_PORT;
248
249         if (ethdev_rss & ETH_RSS_NVGRE)
250                 flowkey_cfg |= FLOW_KEY_TYPE_NVGRE;
251
252         if (ethdev_rss & ETH_RSS_VXLAN)
253                 flowkey_cfg |= FLOW_KEY_TYPE_VXLAN;
254
255         if (ethdev_rss & ETH_RSS_GENEVE)
256                 flowkey_cfg |= FLOW_KEY_TYPE_GENEVE;
257
258         if (ethdev_rss & ETH_RSS_GTPU)
259                 flowkey_cfg |= FLOW_KEY_TYPE_GTPU;
260
261         return flowkey_cfg;
262 }
263
264 int
265 otx2_rss_set_hf(struct otx2_eth_dev *dev, uint32_t flowkey_cfg,
266                 uint8_t *alg_idx, uint8_t group, int mcam_index)
267 {
268         struct nix_rss_flowkey_cfg_rsp *rss_rsp;
269         struct otx2_mbox *mbox = dev->mbox;
270         struct nix_rss_flowkey_cfg *cfg;
271         int rc;
272
273         rc = -EINVAL;
274
275         dev->rss_info.flowkey_cfg = flowkey_cfg;
276
277         cfg = otx2_mbox_alloc_msg_nix_rss_flowkey_cfg(mbox);
278
279         cfg->flowkey_cfg = flowkey_cfg;
280         cfg->mcam_index = mcam_index; /* -1 indicates default group */
281         cfg->group = group; /* 0 is default group */
282
283         rc = otx2_mbox_process_msg(mbox, (void *)&rss_rsp);
284         if (rc)
285                 return rc;
286
287         if (alg_idx)
288                 *alg_idx = rss_rsp->alg_idx;
289
290         return rc;
291 }
292
293 int
294 otx2_nix_rss_hash_update(struct rte_eth_dev *eth_dev,
295                          struct rte_eth_rss_conf *rss_conf)
296 {
297         struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
298         uint32_t flowkey_cfg;
299         uint8_t alg_idx;
300         int rc;
301
302         rc = -EINVAL;
303
304         if (rss_conf->rss_key && rss_conf->rss_key_len != NIX_HASH_KEY_SIZE) {
305                 otx2_err("Hash key size mismatch %d vs %d",
306                          rss_conf->rss_key_len, NIX_HASH_KEY_SIZE);
307                 goto fail;
308         }
309
310         if (rss_conf->rss_key)
311                 otx2_nix_rss_set_key(dev, rss_conf->rss_key,
312                                      (uint32_t)rss_conf->rss_key_len);
313
314         flowkey_cfg = otx2_rss_ethdev_to_nix(dev, rss_conf->rss_hf, 0);
315
316         rc = otx2_rss_set_hf(dev, flowkey_cfg, &alg_idx,
317                              NIX_DEFAULT_RSS_CTX_GROUP,
318                              NIX_DEFAULT_RSS_MCAM_IDX);
319         if (rc) {
320                 otx2_err("Failed to set RSS hash function rc=%d", rc);
321                 return rc;
322         }
323
324         dev->rss_info.alg_idx = alg_idx;
325
326 fail:
327         return rc;
328 }
329
330 int
331 otx2_nix_rss_hash_conf_get(struct rte_eth_dev *eth_dev,
332                            struct rte_eth_rss_conf *rss_conf)
333 {
334         struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
335
336         if (rss_conf->rss_key)
337                 rss_get_key(dev, rss_conf->rss_key);
338
339         rss_conf->rss_key_len = NIX_HASH_KEY_SIZE;
340         rss_conf->rss_hf = dev->rss_info.nix_rss;
341
342         return 0;
343 }
344
345 int
346 otx2_nix_rss_config(struct rte_eth_dev *eth_dev)
347 {
348         struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
349         uint32_t idx, qcnt = eth_dev->data->nb_rx_queues;
350         uint32_t flowkey_cfg;
351         uint64_t rss_hf;
352         uint8_t alg_idx;
353         int rc;
354
355         /* Skip further configuration if selected mode is not RSS */
356         if (eth_dev->data->dev_conf.rxmode.mq_mode != ETH_MQ_RX_RSS)
357                 return 0;
358
359         /* Update default RSS key and cfg */
360         otx2_nix_rss_set_key(dev, NULL, 0);
361
362         /* Update default RSS RETA */
363         for (idx = 0; idx < dev->rss_info.rss_size; idx++)
364                 dev->rss_info.ind_tbl[idx] = idx % qcnt;
365
366         /* Init RSS table context */
367         rc = otx2_nix_rss_tbl_init(dev, 0, dev->rss_info.ind_tbl);
368         if (rc) {
369                 otx2_err("Failed to init RSS table rc=%d", rc);
370                 return rc;
371         }
372
373         rss_hf = eth_dev->data->dev_conf.rx_adv_conf.rss_conf.rss_hf;
374         flowkey_cfg = otx2_rss_ethdev_to_nix(dev, rss_hf, 0);
375
376         rc = otx2_rss_set_hf(dev, flowkey_cfg, &alg_idx,
377                              NIX_DEFAULT_RSS_CTX_GROUP,
378                              NIX_DEFAULT_RSS_MCAM_IDX);
379         if (rc) {
380                 otx2_err("Failed to set RSS hash function rc=%d", rc);
381                 return rc;
382         }
383
384         dev->rss_info.alg_idx = alg_idx;
385
386         return 0;
387 }