net/octeontx2: add devargs to lock Rx/Tx contexts
[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                 if (!dev->lock_rx_ctx)
38                         continue;
39
40                 req = otx2_mbox_alloc_msg_nix_aq_enq(mbox);
41                 if (!req) {
42                         /* The shared memory buffer can be full.
43                          * Flush it and retry
44                          */
45                         otx2_mbox_msg_send(mbox, 0);
46                         rc = otx2_mbox_wait_for_rsp(mbox, 0);
47                         if (rc < 0)
48                                 return rc;
49
50                         req = otx2_mbox_alloc_msg_nix_aq_enq(mbox);
51                         if (!req)
52                                 return -ENOMEM;
53                 }
54                 req->rss.rq = ind_tbl[idx];
55                 /* Fill AQ info */
56                 req->qidx = (group * rss->rss_size) + idx;
57                 req->ctype = NIX_AQ_CTYPE_RSS;
58                 req->op = NIX_AQ_INSTOP_LOCK;
59         }
60
61         otx2_mbox_msg_send(mbox, 0);
62         rc = otx2_mbox_wait_for_rsp(mbox, 0);
63         if (rc < 0)
64                 return rc;
65
66         return 0;
67 }
68
69 int
70 otx2_nix_dev_reta_update(struct rte_eth_dev *eth_dev,
71                          struct rte_eth_rss_reta_entry64 *reta_conf,
72                          uint16_t reta_size)
73 {
74         struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
75         struct otx2_rss_info *rss = &dev->rss_info;
76         int rc, i, j;
77         int idx = 0;
78
79         rc = -EINVAL;
80         if (reta_size != dev->rss_info.rss_size) {
81                 otx2_err("Size of hash lookup table configured "
82                 "(%d) doesn't match the number hardware can supported "
83                 "(%d)", reta_size, dev->rss_info.rss_size);
84                 goto fail;
85         }
86
87         /* Copy RETA table */
88         for (i = 0; i < (dev->rss_info.rss_size / RTE_RETA_GROUP_SIZE); i++) {
89                 for (j = 0; j < RTE_RETA_GROUP_SIZE; j++) {
90                         if ((reta_conf[i].mask >> j) & 0x01)
91                                 rss->ind_tbl[idx] = reta_conf[i].reta[j];
92                         idx++;
93                 }
94         }
95
96         return otx2_nix_rss_tbl_init(dev, 0, dev->rss_info.ind_tbl);
97
98 fail:
99         return rc;
100 }
101
102 int
103 otx2_nix_dev_reta_query(struct rte_eth_dev *eth_dev,
104                         struct rte_eth_rss_reta_entry64 *reta_conf,
105                         uint16_t reta_size)
106 {
107         struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
108         struct otx2_rss_info *rss = &dev->rss_info;
109         int rc, i, j;
110
111         rc = -EINVAL;
112
113         if (reta_size != dev->rss_info.rss_size) {
114                 otx2_err("Size of hash lookup table configured "
115                         "(%d) doesn't match the number hardware can supported "
116                         "(%d)", reta_size, dev->rss_info.rss_size);
117                 goto fail;
118         }
119
120         /* Copy RETA table */
121         for (i = 0; i < (dev->rss_info.rss_size / RTE_RETA_GROUP_SIZE); i++) {
122                 for (j = 0; j < RTE_RETA_GROUP_SIZE; j++)
123                         if ((reta_conf[i].mask >> j) & 0x01)
124                                 reta_conf[i].reta[j] = rss->ind_tbl[j];
125         }
126
127         return 0;
128
129 fail:
130         return rc;
131 }
132
133 void
134 otx2_nix_rss_set_key(struct otx2_eth_dev *dev, uint8_t *key,
135                      uint32_t key_len)
136 {
137         const uint8_t default_key[NIX_HASH_KEY_SIZE] = {
138                 0xFE, 0xED, 0x0B, 0xAD, 0xFE, 0xED, 0x0B, 0xAD,
139                 0xFE, 0xED, 0x0B, 0xAD, 0xFE, 0xED, 0x0B, 0xAD,
140                 0xFE, 0xED, 0x0B, 0xAD, 0xFE, 0xED, 0x0B, 0xAD,
141                 0xFE, 0xED, 0x0B, 0xAD, 0xFE, 0xED, 0x0B, 0xAD,
142                 0xFE, 0xED, 0x0B, 0xAD, 0xFE, 0xED, 0x0B, 0xAD,
143                 0xFE, 0xED, 0x0B, 0xAD, 0xFE, 0xED, 0x0B, 0xAD
144         };
145         struct otx2_rss_info *rss = &dev->rss_info;
146         uint64_t *keyptr;
147         uint64_t val;
148         uint32_t idx;
149
150         if (key == NULL || key == 0) {
151                 keyptr = (uint64_t *)(uintptr_t)default_key;
152                 key_len = NIX_HASH_KEY_SIZE;
153                 memset(rss->key, 0, key_len);
154         } else {
155                 memcpy(rss->key, key, key_len);
156                 keyptr = (uint64_t *)rss->key;
157         }
158
159         for (idx = 0; idx < (key_len >> 3); idx++) {
160                 val = rte_cpu_to_be_64(*keyptr);
161                 otx2_write64(val, dev->base + NIX_LF_RX_SECRETX(idx));
162                 keyptr++;
163         }
164 }
165
166 static void
167 rss_get_key(struct otx2_eth_dev *dev, uint8_t *key)
168 {
169         uint64_t *keyptr = (uint64_t *)key;
170         uint64_t val;
171         int idx;
172
173         for (idx = 0; idx < (NIX_HASH_KEY_SIZE >> 3); idx++) {
174                 val = otx2_read64(dev->base + NIX_LF_RX_SECRETX(idx));
175                 *keyptr = rte_be_to_cpu_64(val);
176                 keyptr++;
177         }
178 }
179
180 #define RSS_IPV4_ENABLE ( \
181                           ETH_RSS_IPV4 | \
182                           ETH_RSS_FRAG_IPV4 | \
183                           ETH_RSS_NONFRAG_IPV4_UDP | \
184                           ETH_RSS_NONFRAG_IPV4_TCP | \
185                           ETH_RSS_NONFRAG_IPV4_SCTP)
186
187 #define RSS_IPV6_ENABLE ( \
188                           ETH_RSS_IPV6 | \
189                           ETH_RSS_FRAG_IPV6 | \
190                           ETH_RSS_NONFRAG_IPV6_UDP | \
191                           ETH_RSS_NONFRAG_IPV6_TCP | \
192                           ETH_RSS_NONFRAG_IPV6_SCTP)
193
194 #define RSS_IPV6_EX_ENABLE ( \
195                              ETH_RSS_IPV6_EX | \
196                              ETH_RSS_IPV6_TCP_EX | \
197                              ETH_RSS_IPV6_UDP_EX)
198
199 #define RSS_MAX_LEVELS   3
200
201 #define RSS_IPV4_INDEX   0
202 #define RSS_IPV6_INDEX   1
203 #define RSS_TCP_INDEX    2
204 #define RSS_UDP_INDEX    3
205 #define RSS_SCTP_INDEX   4
206 #define RSS_DMAC_INDEX   5
207
208 uint32_t
209 otx2_rss_ethdev_to_nix(struct otx2_eth_dev *dev, uint64_t ethdev_rss,
210                        uint8_t rss_level)
211 {
212         uint32_t flow_key_type[RSS_MAX_LEVELS][6] = {
213                 {
214                         FLOW_KEY_TYPE_IPV4, FLOW_KEY_TYPE_IPV6,
215                         FLOW_KEY_TYPE_TCP, FLOW_KEY_TYPE_UDP,
216                         FLOW_KEY_TYPE_SCTP, FLOW_KEY_TYPE_ETH_DMAC
217                 },
218                 {
219                         FLOW_KEY_TYPE_INNR_IPV4, FLOW_KEY_TYPE_INNR_IPV6,
220                         FLOW_KEY_TYPE_INNR_TCP, FLOW_KEY_TYPE_INNR_UDP,
221                         FLOW_KEY_TYPE_INNR_SCTP, FLOW_KEY_TYPE_INNR_ETH_DMAC
222                 },
223                 {
224                         FLOW_KEY_TYPE_IPV4 | FLOW_KEY_TYPE_INNR_IPV4,
225                         FLOW_KEY_TYPE_IPV6 | FLOW_KEY_TYPE_INNR_IPV6,
226                         FLOW_KEY_TYPE_TCP | FLOW_KEY_TYPE_INNR_TCP,
227                         FLOW_KEY_TYPE_UDP | FLOW_KEY_TYPE_INNR_UDP,
228                         FLOW_KEY_TYPE_SCTP | FLOW_KEY_TYPE_INNR_SCTP,
229                         FLOW_KEY_TYPE_ETH_DMAC | FLOW_KEY_TYPE_INNR_ETH_DMAC
230                 }
231         };
232         uint32_t flowkey_cfg = 0;
233
234         dev->rss_info.nix_rss = ethdev_rss;
235
236         if (ethdev_rss & ETH_RSS_L2_PAYLOAD &&
237             dev->npc_flow.switch_header_type == OTX2_PRIV_FLAGS_LEN_90B) {
238                 flowkey_cfg |= FLOW_KEY_TYPE_CH_LEN_90B;
239         }
240
241         if (ethdev_rss & ETH_RSS_L3_SRC_ONLY)
242                 flowkey_cfg |= FLOW_KEY_TYPE_L3_SRC;
243
244         if (ethdev_rss & ETH_RSS_L3_DST_ONLY)
245                 flowkey_cfg |= FLOW_KEY_TYPE_L3_DST;
246
247         if (ethdev_rss & ETH_RSS_L4_SRC_ONLY)
248                 flowkey_cfg |= FLOW_KEY_TYPE_L4_SRC;
249
250         if (ethdev_rss & ETH_RSS_L4_DST_ONLY)
251                 flowkey_cfg |= FLOW_KEY_TYPE_L4_DST;
252
253         if (ethdev_rss & RSS_IPV4_ENABLE)
254                 flowkey_cfg |= flow_key_type[rss_level][RSS_IPV4_INDEX];
255
256         if (ethdev_rss & RSS_IPV6_ENABLE)
257                 flowkey_cfg |= flow_key_type[rss_level][RSS_IPV6_INDEX];
258
259         if (ethdev_rss & ETH_RSS_TCP)
260                 flowkey_cfg |= flow_key_type[rss_level][RSS_TCP_INDEX];
261
262         if (ethdev_rss & ETH_RSS_UDP)
263                 flowkey_cfg |= flow_key_type[rss_level][RSS_UDP_INDEX];
264
265         if (ethdev_rss & ETH_RSS_SCTP)
266                 flowkey_cfg |= flow_key_type[rss_level][RSS_SCTP_INDEX];
267
268         if (ethdev_rss & ETH_RSS_L2_PAYLOAD)
269                 flowkey_cfg |= flow_key_type[rss_level][RSS_DMAC_INDEX];
270
271         if (ethdev_rss & RSS_IPV6_EX_ENABLE)
272                 flowkey_cfg |= FLOW_KEY_TYPE_IPV6_EXT;
273
274         if (ethdev_rss & ETH_RSS_PORT)
275                 flowkey_cfg |= FLOW_KEY_TYPE_PORT;
276
277         if (ethdev_rss & ETH_RSS_NVGRE)
278                 flowkey_cfg |= FLOW_KEY_TYPE_NVGRE;
279
280         if (ethdev_rss & ETH_RSS_VXLAN)
281                 flowkey_cfg |= FLOW_KEY_TYPE_VXLAN;
282
283         if (ethdev_rss & ETH_RSS_GENEVE)
284                 flowkey_cfg |= FLOW_KEY_TYPE_GENEVE;
285
286         if (ethdev_rss & ETH_RSS_GTPU)
287                 flowkey_cfg |= FLOW_KEY_TYPE_GTPU;
288
289         return flowkey_cfg;
290 }
291
292 int
293 otx2_rss_set_hf(struct otx2_eth_dev *dev, uint32_t flowkey_cfg,
294                 uint8_t *alg_idx, uint8_t group, int mcam_index)
295 {
296         struct nix_rss_flowkey_cfg_rsp *rss_rsp;
297         struct otx2_mbox *mbox = dev->mbox;
298         struct nix_rss_flowkey_cfg *cfg;
299         int rc;
300
301         rc = -EINVAL;
302
303         dev->rss_info.flowkey_cfg = flowkey_cfg;
304
305         cfg = otx2_mbox_alloc_msg_nix_rss_flowkey_cfg(mbox);
306
307         cfg->flowkey_cfg = flowkey_cfg;
308         cfg->mcam_index = mcam_index; /* -1 indicates default group */
309         cfg->group = group; /* 0 is default group */
310
311         rc = otx2_mbox_process_msg(mbox, (void *)&rss_rsp);
312         if (rc)
313                 return rc;
314
315         if (alg_idx)
316                 *alg_idx = rss_rsp->alg_idx;
317
318         return rc;
319 }
320
321 int
322 otx2_nix_rss_hash_update(struct rte_eth_dev *eth_dev,
323                          struct rte_eth_rss_conf *rss_conf)
324 {
325         struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
326         uint32_t flowkey_cfg;
327         uint8_t alg_idx;
328         int rc;
329
330         rc = -EINVAL;
331
332         if (rss_conf->rss_key && rss_conf->rss_key_len != NIX_HASH_KEY_SIZE) {
333                 otx2_err("Hash key size mismatch %d vs %d",
334                          rss_conf->rss_key_len, NIX_HASH_KEY_SIZE);
335                 goto fail;
336         }
337
338         if (rss_conf->rss_key)
339                 otx2_nix_rss_set_key(dev, rss_conf->rss_key,
340                                      (uint32_t)rss_conf->rss_key_len);
341
342         flowkey_cfg = otx2_rss_ethdev_to_nix(dev, rss_conf->rss_hf, 0);
343
344         rc = otx2_rss_set_hf(dev, flowkey_cfg, &alg_idx,
345                              NIX_DEFAULT_RSS_CTX_GROUP,
346                              NIX_DEFAULT_RSS_MCAM_IDX);
347         if (rc) {
348                 otx2_err("Failed to set RSS hash function rc=%d", rc);
349                 return rc;
350         }
351
352         dev->rss_info.alg_idx = alg_idx;
353
354 fail:
355         return rc;
356 }
357
358 int
359 otx2_nix_rss_hash_conf_get(struct rte_eth_dev *eth_dev,
360                            struct rte_eth_rss_conf *rss_conf)
361 {
362         struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
363
364         if (rss_conf->rss_key)
365                 rss_get_key(dev, rss_conf->rss_key);
366
367         rss_conf->rss_key_len = NIX_HASH_KEY_SIZE;
368         rss_conf->rss_hf = dev->rss_info.nix_rss;
369
370         return 0;
371 }
372
373 int
374 otx2_nix_rss_config(struct rte_eth_dev *eth_dev)
375 {
376         struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
377         uint32_t idx, qcnt = eth_dev->data->nb_rx_queues;
378         uint32_t flowkey_cfg;
379         uint64_t rss_hf;
380         uint8_t alg_idx;
381         int rc;
382
383         /* Skip further configuration if selected mode is not RSS */
384         if (eth_dev->data->dev_conf.rxmode.mq_mode != ETH_MQ_RX_RSS || !qcnt)
385                 return 0;
386
387         /* Update default RSS key and cfg */
388         otx2_nix_rss_set_key(dev, NULL, 0);
389
390         /* Update default RSS RETA */
391         for (idx = 0; idx < dev->rss_info.rss_size; idx++)
392                 dev->rss_info.ind_tbl[idx] = idx % qcnt;
393
394         /* Init RSS table context */
395         rc = otx2_nix_rss_tbl_init(dev, 0, dev->rss_info.ind_tbl);
396         if (rc) {
397                 otx2_err("Failed to init RSS table rc=%d", rc);
398                 return rc;
399         }
400
401         rss_hf = eth_dev->data->dev_conf.rx_adv_conf.rss_conf.rss_hf;
402         flowkey_cfg = otx2_rss_ethdev_to_nix(dev, rss_hf, 0);
403
404         rc = otx2_rss_set_hf(dev, flowkey_cfg, &alg_idx,
405                              NIX_DEFAULT_RSS_CTX_GROUP,
406                              NIX_DEFAULT_RSS_MCAM_IDX);
407         if (rc) {
408                 otx2_err("Failed to set RSS hash function rc=%d", rc);
409                 return rc;
410         }
411
412         dev->rss_info.alg_idx = alg_idx;
413
414         return 0;
415 }