common/cnxk: support CPT CTX write through microcode op
[dpdk.git] / drivers / common / cnxk / roc_nix.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 bool
9 roc_nix_is_lbk(struct roc_nix *roc_nix)
10 {
11         struct nix *nix = roc_nix_to_nix_priv(roc_nix);
12
13         return nix->lbk_link;
14 }
15
16 int
17 roc_nix_get_base_chan(struct roc_nix *roc_nix)
18 {
19         struct nix *nix = roc_nix_to_nix_priv(roc_nix);
20
21         return nix->rx_chan_base;
22 }
23
24 uint16_t
25 roc_nix_get_vwqe_interval(struct roc_nix *roc_nix)
26 {
27         struct nix *nix = roc_nix_to_nix_priv(roc_nix);
28
29         return nix->vwqe_interval;
30 }
31
32 bool
33 roc_nix_is_sdp(struct roc_nix *roc_nix)
34 {
35         struct nix *nix = roc_nix_to_nix_priv(roc_nix);
36
37         return nix->sdp_link;
38 }
39
40 bool
41 roc_nix_is_pf(struct roc_nix *roc_nix)
42 {
43         struct nix *nix = roc_nix_to_nix_priv(roc_nix);
44
45         return !dev_is_vf(&nix->dev);
46 }
47
48 int
49 roc_nix_get_pf(struct roc_nix *roc_nix)
50 {
51         struct nix *nix = roc_nix_to_nix_priv(roc_nix);
52         struct dev *dev = &nix->dev;
53
54         return dev_get_pf(dev->pf_func);
55 }
56
57 int
58 roc_nix_get_vf(struct roc_nix *roc_nix)
59 {
60         struct nix *nix = roc_nix_to_nix_priv(roc_nix);
61         struct dev *dev = &nix->dev;
62
63         return dev_get_vf(dev->pf_func);
64 }
65
66 bool
67 roc_nix_is_vf_or_sdp(struct roc_nix *roc_nix)
68 {
69         struct nix *nix = roc_nix_to_nix_priv(roc_nix);
70
71         return (dev_is_vf(&nix->dev) != 0) || roc_nix_is_sdp(roc_nix);
72 }
73
74 uint16_t
75 roc_nix_get_pf_func(struct roc_nix *roc_nix)
76 {
77         struct nix *nix = roc_nix_to_nix_priv(roc_nix);
78         struct dev *dev = &nix->dev;
79
80         return dev->pf_func;
81 }
82
83 int
84 roc_nix_lf_inl_ipsec_cfg(struct roc_nix *roc_nix, struct roc_nix_ipsec_cfg *cfg,
85                          bool enb)
86 {
87         struct nix *nix = roc_nix_to_nix_priv(roc_nix);
88         struct nix_inline_ipsec_lf_cfg *lf_cfg;
89         struct mbox *mbox = (&nix->dev)->mbox;
90
91         lf_cfg = mbox_alloc_msg_nix_inline_ipsec_lf_cfg(mbox);
92         if (lf_cfg == NULL)
93                 return -ENOSPC;
94
95         if (enb) {
96                 lf_cfg->enable = 1;
97                 lf_cfg->sa_base_addr = cfg->iova;
98                 lf_cfg->ipsec_cfg1.sa_idx_w = plt_log2_u32(cfg->max_sa);
99                 lf_cfg->ipsec_cfg0.lenm1_max = roc_nix_max_pkt_len(roc_nix) - 1;
100                 lf_cfg->ipsec_cfg1.sa_idx_max = cfg->max_sa - 1;
101                 lf_cfg->ipsec_cfg0.sa_pow2_size = plt_log2_u32(cfg->sa_size);
102                 lf_cfg->ipsec_cfg0.tag_const = cfg->tag_const;
103                 lf_cfg->ipsec_cfg0.tt = cfg->tt;
104         } else {
105                 lf_cfg->enable = 0;
106         }
107
108         return mbox_process(mbox);
109 }
110
111 int
112 roc_nix_max_pkt_len(struct roc_nix *roc_nix)
113 {
114         struct nix *nix = roc_nix_to_nix_priv(roc_nix);
115
116         if (roc_nix_is_sdp(roc_nix))
117                 return NIX_SDP_MAX_HW_FRS;
118
119         if (roc_model_is_cn9k())
120                 return NIX_CN9K_MAX_HW_FRS;
121
122         if (nix->lbk_link)
123                 return NIX_LBK_MAX_HW_FRS;
124
125         return NIX_RPM_MAX_HW_FRS;
126 }
127
128 int
129 roc_nix_lf_alloc(struct roc_nix *roc_nix, uint32_t nb_rxq, uint32_t nb_txq,
130                  uint64_t rx_cfg)
131 {
132         struct nix *nix = roc_nix_to_nix_priv(roc_nix);
133         struct mbox *mbox = (&nix->dev)->mbox;
134         struct nix_lf_alloc_req *req;
135         struct nix_lf_alloc_rsp *rsp;
136         int rc = -ENOSPC;
137
138         req = mbox_alloc_msg_nix_lf_alloc(mbox);
139         if (req == NULL)
140                 return rc;
141         req->rq_cnt = nb_rxq;
142         req->sq_cnt = nb_txq;
143         req->cq_cnt = nb_rxq;
144         /* XQESZ can be W64 or W16 */
145         req->xqe_sz = NIX_XQESZ_W16;
146         req->rss_sz = nix->reta_sz;
147         req->rss_grps = ROC_NIX_RSS_GRPS;
148         req->npa_func = idev_npa_pffunc_get();
149         req->sso_func = idev_sso_pffunc_get();
150         req->rx_cfg = rx_cfg;
151         if (roc_nix_is_lbk(roc_nix) && roc_nix->enable_loop &&
152             roc_model_is_cn98xx())
153                 req->flags = NIX_LF_LBK_BLK_SEL;
154
155         if (!roc_nix->rss_tag_as_xor)
156                 req->flags |= NIX_LF_RSS_TAG_LSB_AS_ADDER;
157
158         rc = mbox_process_msg(mbox, (void *)&rsp);
159         if (rc)
160                 goto fail;
161
162         nix->sqb_size = rsp->sqb_size;
163         nix->tx_chan_base = rsp->tx_chan_base;
164         nix->rx_chan_base = rsp->rx_chan_base;
165         if (roc_nix_is_lbk(roc_nix) && roc_nix->enable_loop)
166                 nix->tx_chan_base = rsp->rx_chan_base;
167         nix->rx_chan_cnt = rsp->rx_chan_cnt;
168         nix->tx_chan_cnt = rsp->tx_chan_cnt;
169         nix->lso_tsov4_idx = rsp->lso_tsov4_idx;
170         nix->lso_tsov6_idx = rsp->lso_tsov6_idx;
171         nix->lf_tx_stats = rsp->lf_tx_stats;
172         nix->lf_rx_stats = rsp->lf_rx_stats;
173         nix->cints = rsp->cints;
174         roc_nix->cints = rsp->cints;
175         nix->qints = rsp->qints;
176         nix->ptp_en = rsp->hw_rx_tstamp_en;
177         roc_nix->rx_ptp_ena = rsp->hw_rx_tstamp_en;
178         nix->cgx_links = rsp->cgx_links;
179         nix->lbk_links = rsp->lbk_links;
180         nix->sdp_links = rsp->sdp_links;
181         nix->tx_link = rsp->tx_link;
182         nix->nb_rx_queues = nb_rxq;
183         nix->nb_tx_queues = nb_txq;
184         nix->sqs = plt_zmalloc(sizeof(struct roc_nix_sq *) * nb_txq, 0);
185         if (!nix->sqs)
186                 return -ENOMEM;
187
188         nix_tel_node_add(roc_nix);
189 fail:
190         return rc;
191 }
192
193 int
194 roc_nix_lf_free(struct roc_nix *roc_nix)
195 {
196         struct nix *nix = roc_nix_to_nix_priv(roc_nix);
197         struct mbox *mbox = (&nix->dev)->mbox;
198         struct nix_lf_free_req *req;
199         struct ndc_sync_op *ndc_req;
200         int rc = -ENOSPC;
201
202         plt_free(nix->sqs);
203         nix->sqs = NULL;
204
205         /* Sync NDC-NIX for LF */
206         ndc_req = mbox_alloc_msg_ndc_sync_op(mbox);
207         if (ndc_req == NULL)
208                 return rc;
209         ndc_req->nix_lf_tx_sync = 1;
210         ndc_req->nix_lf_rx_sync = 1;
211         rc = mbox_process(mbox);
212         if (rc)
213                 plt_err("Error on NDC-NIX-[TX, RX] LF sync, rc %d", rc);
214
215         req = mbox_alloc_msg_nix_lf_free(mbox);
216         if (req == NULL)
217                 return -ENOSPC;
218         /* Let AF driver free all this nix lf's
219          * NPC entries allocated using NPC MBOX.
220          */
221         req->flags = 0;
222
223         return mbox_process(mbox);
224 }
225
226 static inline int
227 nix_lf_attach(struct dev *dev)
228 {
229         struct mbox *mbox = dev->mbox;
230         struct rsrc_attach_req *req;
231         int rc = -ENOSPC;
232
233         /* Attach NIX(lf) */
234         req = mbox_alloc_msg_attach_resources(mbox);
235         if (req == NULL)
236                 return rc;
237         req->modify = true;
238         req->nixlf = true;
239
240         return mbox_process(mbox);
241 }
242
243 static inline int
244 nix_lf_get_msix_offset(struct dev *dev, struct nix *nix)
245 {
246         struct msix_offset_rsp *msix_rsp;
247         struct mbox *mbox = dev->mbox;
248         int rc;
249
250         /* Get MSIX vector offsets */
251         mbox_alloc_msg_msix_offset(mbox);
252         rc = mbox_process_msg(mbox, (void *)&msix_rsp);
253         if (rc == 0)
254                 nix->msixoff = msix_rsp->nix_msixoff;
255
256         return rc;
257 }
258
259 static inline int
260 nix_lf_detach(struct nix *nix)
261 {
262         struct mbox *mbox = (&nix->dev)->mbox;
263         struct rsrc_detach_req *req;
264         int rc = -ENOSPC;
265
266         req = mbox_alloc_msg_detach_resources(mbox);
267         if (req == NULL)
268                 return rc;
269         req->partial = true;
270         req->nixlf = true;
271
272         return mbox_process(mbox);
273 }
274
275 static int
276 roc_nix_get_hw_info(struct roc_nix *roc_nix)
277 {
278         struct nix *nix = roc_nix_to_nix_priv(roc_nix);
279         struct mbox *mbox = (&nix->dev)->mbox;
280         struct nix_hw_info *hw_info;
281         int rc;
282
283         mbox_alloc_msg_nix_get_hw_info(mbox);
284         rc = mbox_process_msg(mbox, (void *)&hw_info);
285         if (rc == 0)
286                 nix->vwqe_interval = hw_info->vwqe_delay;
287
288         return rc;
289 }
290
291 static void
292 sdp_lbk_id_update(struct plt_pci_device *pci_dev, struct nix *nix)
293 {
294         nix->sdp_link = false;
295         nix->lbk_link = false;
296
297         /* Update SDP/LBK link based on PCI device id */
298         switch (pci_dev->id.device_id) {
299         case PCI_DEVID_CNXK_RVU_SDP_PF:
300         case PCI_DEVID_CNXK_RVU_SDP_VF:
301                 nix->sdp_link = true;
302                 break;
303         case PCI_DEVID_CNXK_RVU_AF_VF:
304                 nix->lbk_link = true;
305                 break;
306         default:
307                 break;
308         }
309 }
310
311 uint64_t
312 nix_get_blkaddr(struct dev *dev)
313 {
314         uint64_t reg;
315
316         /* Reading the discovery register to know which NIX is the LF
317          * attached to.
318          */
319         reg = plt_read64(dev->bar2 +
320                          RVU_PF_BLOCK_ADDRX_DISC(RVU_BLOCK_ADDR_NIX0));
321
322         return reg & 0x1FFULL ? RVU_BLOCK_ADDR_NIX0 : RVU_BLOCK_ADDR_NIX1;
323 }
324
325 int
326 roc_nix_dev_init(struct roc_nix *roc_nix)
327 {
328         enum roc_nix_rss_reta_sz reta_sz;
329         struct plt_pci_device *pci_dev;
330         uint16_t max_sqb_count;
331         uint64_t blkaddr;
332         struct dev *dev;
333         struct nix *nix;
334         int rc;
335
336         if (roc_nix == NULL || roc_nix->pci_dev == NULL)
337                 return NIX_ERR_PARAM;
338
339         reta_sz = roc_nix->reta_sz;
340         if (reta_sz != 0 && reta_sz != 64 && reta_sz != 128 && reta_sz != 256)
341                 return NIX_ERR_PARAM;
342
343         if (reta_sz == 0)
344                 reta_sz = ROC_NIX_RSS_RETA_SZ_64;
345
346         max_sqb_count = roc_nix->max_sqb_count;
347         max_sqb_count = PLT_MIN(max_sqb_count, NIX_MAX_SQB);
348         max_sqb_count = PLT_MAX(max_sqb_count, NIX_MIN_SQB);
349         roc_nix->max_sqb_count = max_sqb_count;
350
351         PLT_STATIC_ASSERT(sizeof(struct nix) <= ROC_NIX_MEM_SZ);
352         nix = roc_nix_to_nix_priv(roc_nix);
353         pci_dev = roc_nix->pci_dev;
354         dev = &nix->dev;
355
356         if (nix->dev.drv_inited)
357                 return 0;
358
359         if (dev->mbox_active)
360                 goto skip_dev_init;
361
362         memset(nix, 0, sizeof(*nix));
363         /* Initialize device  */
364         rc = dev_init(dev, pci_dev);
365         if (rc) {
366                 plt_err("Failed to init roc device");
367                 goto fail;
368         }
369
370 skip_dev_init:
371         dev->roc_nix = roc_nix;
372
373         nix->lmt_base = dev->lmt_base;
374         /* Expose base LMT line address for
375          * "Per Core LMT line" mode.
376          */
377         roc_nix->lmt_base = dev->lmt_base;
378
379         /* Attach NIX LF */
380         rc = nix_lf_attach(dev);
381         if (rc)
382                 goto dev_fini;
383
384         blkaddr = nix_get_blkaddr(dev);
385         nix->is_nix1 = (blkaddr == RVU_BLOCK_ADDR_NIX1);
386
387         /* Calculating base address based on which NIX block LF
388          * is attached to.
389          */
390         nix->base = dev->bar2 + (blkaddr << 20);
391
392         /* Get NIX MSIX offset */
393         rc = nix_lf_get_msix_offset(dev, nix);
394         if (rc)
395                 goto lf_detach;
396
397         /* Update nix context */
398         sdp_lbk_id_update(pci_dev, nix);
399         nix->pci_dev = pci_dev;
400         nix->reta_sz = reta_sz;
401         nix->mtu = ROC_NIX_DEFAULT_HW_FRS;
402
403         /* Register error and ras interrupts */
404         rc = nix_register_irqs(nix);
405         if (rc)
406                 goto lf_detach;
407
408         rc = nix_tm_conf_init(roc_nix);
409         if (rc)
410                 goto unregister_irqs;
411
412         /* Get NIX HW info */
413         roc_nix_get_hw_info(roc_nix);
414         nix->dev.drv_inited = true;
415
416         return 0;
417 unregister_irqs:
418         nix_unregister_irqs(nix);
419 lf_detach:
420         nix_lf_detach(nix);
421 dev_fini:
422         rc |= dev_fini(dev, pci_dev);
423 fail:
424         nix_tel_node_del(roc_nix);
425         return rc;
426 }
427
428 int
429 roc_nix_dev_fini(struct roc_nix *roc_nix)
430 {
431         struct nix *nix = roc_nix_to_nix_priv(roc_nix);
432         int rc = 0;
433
434         if (nix == NULL)
435                 return NIX_ERR_PARAM;
436
437         if (!nix->dev.drv_inited)
438                 goto fini;
439
440         nix_tm_conf_fini(roc_nix);
441         nix_unregister_irqs(nix);
442
443         rc = nix_lf_detach(nix);
444         nix->dev.drv_inited = false;
445 fini:
446         rc |= dev_fini(&nix->dev, nix->pci_dev);
447         return rc;
448 }