net/mlx5: add VLAN push/pop DR commands to glue
[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         return flowkey_cfg;
247 }
248
249 int
250 otx2_rss_set_hf(struct otx2_eth_dev *dev, uint32_t flowkey_cfg,
251                 uint8_t *alg_idx, uint8_t group, int mcam_index)
252 {
253         struct nix_rss_flowkey_cfg_rsp *rss_rsp;
254         struct otx2_mbox *mbox = dev->mbox;
255         struct nix_rss_flowkey_cfg *cfg;
256         int rc;
257
258         rc = -EINVAL;
259
260         dev->rss_info.flowkey_cfg = flowkey_cfg;
261
262         cfg = otx2_mbox_alloc_msg_nix_rss_flowkey_cfg(mbox);
263
264         cfg->flowkey_cfg = flowkey_cfg;
265         cfg->mcam_index = mcam_index; /* -1 indicates default group */
266         cfg->group = group; /* 0 is default group */
267
268         rc = otx2_mbox_process_msg(mbox, (void *)&rss_rsp);
269         if (rc)
270                 return rc;
271
272         if (alg_idx)
273                 *alg_idx = rss_rsp->alg_idx;
274
275         return rc;
276 }
277
278 int
279 otx2_nix_rss_hash_update(struct rte_eth_dev *eth_dev,
280                          struct rte_eth_rss_conf *rss_conf)
281 {
282         struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
283         uint32_t flowkey_cfg;
284         uint8_t alg_idx;
285         int rc;
286
287         rc = -EINVAL;
288
289         if (rss_conf->rss_key && rss_conf->rss_key_len != NIX_HASH_KEY_SIZE) {
290                 otx2_err("Hash key size mismatch %d vs %d",
291                          rss_conf->rss_key_len, NIX_HASH_KEY_SIZE);
292                 goto fail;
293         }
294
295         if (rss_conf->rss_key)
296                 otx2_nix_rss_set_key(dev, rss_conf->rss_key,
297                                      (uint32_t)rss_conf->rss_key_len);
298
299         flowkey_cfg = otx2_rss_ethdev_to_nix(dev, rss_conf->rss_hf, 0);
300
301         rc = otx2_rss_set_hf(dev, flowkey_cfg, &alg_idx,
302                              NIX_DEFAULT_RSS_CTX_GROUP,
303                              NIX_DEFAULT_RSS_MCAM_IDX);
304         if (rc) {
305                 otx2_err("Failed to set RSS hash function rc=%d", rc);
306                 return rc;
307         }
308
309         dev->rss_info.alg_idx = alg_idx;
310
311 fail:
312         return rc;
313 }
314
315 int
316 otx2_nix_rss_hash_conf_get(struct rte_eth_dev *eth_dev,
317                            struct rte_eth_rss_conf *rss_conf)
318 {
319         struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
320
321         if (rss_conf->rss_key)
322                 rss_get_key(dev, rss_conf->rss_key);
323
324         rss_conf->rss_key_len = NIX_HASH_KEY_SIZE;
325         rss_conf->rss_hf = dev->rss_info.nix_rss;
326
327         return 0;
328 }
329
330 int
331 otx2_nix_rss_config(struct rte_eth_dev *eth_dev)
332 {
333         struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
334         uint32_t idx, qcnt = eth_dev->data->nb_rx_queues;
335         uint32_t flowkey_cfg;
336         uint64_t rss_hf;
337         uint8_t alg_idx;
338         int rc;
339
340         /* Skip further configuration if selected mode is not RSS */
341         if (eth_dev->data->dev_conf.rxmode.mq_mode != ETH_MQ_RX_RSS)
342                 return 0;
343
344         /* Update default RSS key and cfg */
345         otx2_nix_rss_set_key(dev, NULL, 0);
346
347         /* Update default RSS RETA */
348         for (idx = 0; idx < dev->rss_info.rss_size; idx++)
349                 dev->rss_info.ind_tbl[idx] = idx % qcnt;
350
351         /* Init RSS table context */
352         rc = otx2_nix_rss_tbl_init(dev, 0, dev->rss_info.ind_tbl);
353         if (rc) {
354                 otx2_err("Failed to init RSS table rc=%d", rc);
355                 return rc;
356         }
357
358         rss_hf = eth_dev->data->dev_conf.rx_adv_conf.rss_conf.rss_hf;
359         flowkey_cfg = otx2_rss_ethdev_to_nix(dev, rss_hf, 0);
360
361         rc = otx2_rss_set_hf(dev, flowkey_cfg, &alg_idx,
362                              NIX_DEFAULT_RSS_CTX_GROUP,
363                              NIX_DEFAULT_RSS_MCAM_IDX);
364         if (rc) {
365                 otx2_err("Failed to set RSS hash function rc=%d", rc);
366                 return rc;
367         }
368
369         dev->rss_info.alg_idx = alg_idx;
370
371         return 0;
372 }