common/cnxk: support merging base steering rule
[dpdk.git] / drivers / common / cnxk / roc_nix_rss.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(C) 2021 Marvell.
3  */
4
5 #include "roc_api.h"
6 #include "roc_priv.h"
7
8 void
9 roc_nix_rss_key_default_fill(struct roc_nix *roc_nix,
10                              uint8_t key[ROC_NIX_RSS_KEY_LEN])
11 {
12         PLT_SET_USED(roc_nix);
13         const uint8_t default_key[ROC_NIX_RSS_KEY_LEN] = {
14                 0xFE, 0xED, 0x0B, 0xAD, 0xFE, 0xED, 0x0B, 0xAD, 0xFE, 0xED,
15                 0x0B, 0xAD, 0xFE, 0xED, 0x0B, 0xAD, 0xFE, 0xED, 0x0B, 0xAD,
16                 0xFE, 0xED, 0x0B, 0xAD, 0xFE, 0xED, 0x0B, 0xAD, 0xFE, 0xED,
17                 0x0B, 0xAD, 0xFE, 0xED, 0x0B, 0xAD, 0xFE, 0xED, 0x0B, 0xAD,
18                 0xFE, 0xED, 0x0B, 0xAD, 0xFE, 0xED, 0x0B, 0xAD};
19
20         memcpy(key, default_key, ROC_NIX_RSS_KEY_LEN);
21 }
22
23 void
24 roc_nix_rss_key_set(struct roc_nix *roc_nix,
25                     const uint8_t key[ROC_NIX_RSS_KEY_LEN])
26 {
27         struct nix *nix = roc_nix_to_nix_priv(roc_nix);
28         const uint64_t *keyptr;
29         uint64_t val;
30         uint32_t idx;
31
32         keyptr = (const uint64_t *)key;
33         for (idx = 0; idx < (ROC_NIX_RSS_KEY_LEN >> 3); idx++) {
34                 val = plt_cpu_to_be_64(keyptr[idx]);
35                 plt_write64(val, nix->base + NIX_LF_RX_SECRETX(idx));
36         }
37 }
38
39 void
40 roc_nix_rss_key_get(struct roc_nix *roc_nix, uint8_t key[ROC_NIX_RSS_KEY_LEN])
41 {
42         struct nix *nix = roc_nix_to_nix_priv(roc_nix);
43         uint64_t *keyptr = (uint64_t *)key;
44         uint64_t val;
45         uint32_t idx;
46
47         for (idx = 0; idx < (ROC_NIX_RSS_KEY_LEN >> 3); idx++) {
48                 val = plt_read64(nix->base + NIX_LF_RX_SECRETX(idx));
49                 keyptr[idx] = plt_be_to_cpu_64(val);
50         }
51 }
52
53 static int
54 nix_cn9k_rss_reta_set(struct nix *nix, uint8_t group,
55                       uint16_t reta[ROC_NIX_RSS_RETA_MAX], uint8_t lock_rx_ctx)
56 {
57         struct mbox *mbox = (&nix->dev)->mbox;
58         struct nix_aq_enq_req *req;
59         uint16_t idx;
60         int rc;
61
62         for (idx = 0; idx < nix->reta_sz; idx++) {
63                 req = mbox_alloc_msg_nix_aq_enq(mbox);
64                 if (!req) {
65                         /* The shared memory buffer can be full.
66                          * Flush it and retry
67                          */
68                         rc = mbox_process(mbox);
69                         if (rc < 0)
70                                 return rc;
71                         req = mbox_alloc_msg_nix_aq_enq(mbox);
72                         if (!req)
73                                 return NIX_ERR_NO_MEM;
74                 }
75                 req->rss.rq = reta[idx];
76                 /* Fill AQ info */
77                 req->qidx = (group * nix->reta_sz) + idx;
78                 req->ctype = NIX_AQ_CTYPE_RSS;
79                 req->op = NIX_AQ_INSTOP_INIT;
80
81                 if (!lock_rx_ctx)
82                         continue;
83
84                 req = mbox_alloc_msg_nix_aq_enq(mbox);
85                 if (!req) {
86                         /* The shared memory buffer can be full.
87                          * Flush it and retry
88                          */
89                         rc = mbox_process(mbox);
90                         if (rc < 0)
91                                 return rc;
92                         req = mbox_alloc_msg_nix_aq_enq(mbox);
93                         if (!req)
94                                 return NIX_ERR_NO_MEM;
95                 }
96                 req->rss.rq = reta[idx];
97                 /* Fill AQ info */
98                 req->qidx = (group * nix->reta_sz) + idx;
99                 req->ctype = NIX_AQ_CTYPE_RSS;
100                 req->op = NIX_AQ_INSTOP_LOCK;
101         }
102
103         rc = mbox_process(mbox);
104         if (rc < 0)
105                 return rc;
106
107         return 0;
108 }
109
110 static int
111 nix_rss_reta_set(struct nix *nix, uint8_t group,
112                  uint16_t reta[ROC_NIX_RSS_RETA_MAX], uint8_t lock_rx_ctx)
113 {
114         struct mbox *mbox = (&nix->dev)->mbox;
115         struct nix_cn10k_aq_enq_req *req;
116         uint16_t idx;
117         int rc;
118
119         for (idx = 0; idx < nix->reta_sz; idx++) {
120                 req = mbox_alloc_msg_nix_cn10k_aq_enq(mbox);
121                 if (!req) {
122                         /* The shared memory buffer can be full.
123                          * Flush it and retry
124                          */
125                         rc = mbox_process(mbox);
126                         if (rc < 0)
127                                 return rc;
128                         req = mbox_alloc_msg_nix_cn10k_aq_enq(mbox);
129                         if (!req)
130                                 return NIX_ERR_NO_MEM;
131                 }
132                 req->rss.rq = reta[idx];
133                 /* Fill AQ info */
134                 req->qidx = (group * nix->reta_sz) + idx;
135                 req->ctype = NIX_AQ_CTYPE_RSS;
136                 req->op = NIX_AQ_INSTOP_INIT;
137
138                 if (!lock_rx_ctx)
139                         continue;
140
141                 req = mbox_alloc_msg_nix_cn10k_aq_enq(mbox);
142                 if (!req) {
143                         /* The shared memory buffer can be full.
144                          * Flush it and retry
145                          */
146                         rc = mbox_process(mbox);
147                         if (rc < 0)
148                                 return rc;
149                         req = mbox_alloc_msg_nix_cn10k_aq_enq(mbox);
150                         if (!req)
151                                 return NIX_ERR_NO_MEM;
152                 }
153                 req->rss.rq = reta[idx];
154                 /* Fill AQ info */
155                 req->qidx = (group * nix->reta_sz) + idx;
156                 req->ctype = NIX_AQ_CTYPE_RSS;
157                 req->op = NIX_AQ_INSTOP_LOCK;
158         }
159
160         rc = mbox_process(mbox);
161         if (rc < 0)
162                 return rc;
163
164         return 0;
165 }
166
167 int
168 roc_nix_rss_reta_set(struct roc_nix *roc_nix, uint8_t group,
169                      uint16_t reta[ROC_NIX_RSS_RETA_MAX])
170 {
171         struct nix *nix = roc_nix_to_nix_priv(roc_nix);
172         int rc;
173
174         if (group >= ROC_NIX_RSS_GRPS)
175                 return NIX_ERR_PARAM;
176
177         if (roc_model_is_cn9k())
178                 rc = nix_cn9k_rss_reta_set(nix, group, reta,
179                                            roc_nix->lock_rx_ctx);
180         else
181                 rc = nix_rss_reta_set(nix, group, reta, roc_nix->lock_rx_ctx);
182         if (rc)
183                 return rc;
184
185         memcpy(&nix->reta[group], reta, ROC_NIX_RSS_RETA_MAX);
186         return 0;
187 }
188
189 int
190 roc_nix_rss_reta_get(struct roc_nix *roc_nix, uint8_t group,
191                      uint16_t reta[ROC_NIX_RSS_RETA_MAX])
192 {
193         struct nix *nix = roc_nix_to_nix_priv(roc_nix);
194
195         if (group >= ROC_NIX_RSS_GRPS)
196                 return NIX_ERR_PARAM;
197
198         memcpy(reta, &nix->reta[group], ROC_NIX_RSS_RETA_MAX);
199         return 0;
200 }
201
202 int
203 roc_nix_rss_flowkey_set(struct roc_nix *roc_nix, uint8_t *alg_idx,
204                         uint32_t flowkey, uint8_t group, int mcam_index)
205 {
206         struct nix *nix = roc_nix_to_nix_priv(roc_nix);
207         struct nix_rss_flowkey_cfg_rsp *rss_rsp;
208         struct mbox *mbox = (&nix->dev)->mbox;
209         struct nix_rss_flowkey_cfg *cfg;
210         int rc = -ENOSPC;
211
212         if (group >= ROC_NIX_RSS_GRPS)
213                 return NIX_ERR_PARAM;
214
215         cfg = mbox_alloc_msg_nix_rss_flowkey_cfg(mbox);
216         if (cfg == NULL)
217                 return rc;
218         cfg->flowkey_cfg = flowkey;
219         cfg->mcam_index = mcam_index; /* -1 indicates default group */
220         cfg->group = group;           /* 0 is default group */
221         rc = mbox_process_msg(mbox, (void *)&rss_rsp);
222         if (rc)
223                 return rc;
224         if (alg_idx)
225                 *alg_idx = rss_rsp->alg_idx;
226
227         return rc;
228 }
229
230 int
231 roc_nix_rss_default_setup(struct roc_nix *roc_nix, uint32_t flowkey)
232 {
233         struct nix *nix = roc_nix_to_nix_priv(roc_nix);
234         uint16_t idx, qcnt = nix->nb_rx_queues;
235         uint16_t reta[ROC_NIX_RSS_RETA_MAX];
236         uint8_t key[ROC_NIX_RSS_KEY_LEN];
237         uint8_t alg_idx;
238         int rc;
239
240         roc_nix_rss_key_default_fill(roc_nix, key);
241         roc_nix_rss_key_set(roc_nix, key);
242
243         /* Update default RSS RETA */
244         for (idx = 0; idx < nix->reta_sz; idx++)
245                 reta[idx] = idx % qcnt;
246         rc = roc_nix_rss_reta_set(roc_nix, 0, reta);
247         if (rc) {
248                 plt_err("Failed to set RSS reta table rc=%d", rc);
249                 goto fail;
250         }
251
252         /* Update the default flowkey */
253         rc = roc_nix_rss_flowkey_set(roc_nix, &alg_idx, flowkey,
254                                      ROC_NIX_RSS_GROUP_DEFAULT, -1);
255         if (rc) {
256                 plt_err("Failed to set RSS flowkey rc=%d", rc);
257                 goto fail;
258         }
259
260         nix->rss_alg_idx = alg_idx;
261 fail:
262         return rc;
263 }