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