octeontx2-af: cn10k: Setting up lmtst map table
[linux-2.6-microblaze.git] / drivers / net / ethernet / marvell / octeontx2 / af / rvu_cn10k.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*  Marvell RPM CN10K driver
3  *
4  * Copyright (C) 2020 Marvell.
5  */
6
7 #include <linux/bitfield.h>
8 #include <linux/pci.h>
9 #include "rvu.h"
10 #include "cgx.h"
11 #include "rvu_reg.h"
12
13 /* RVU LMTST */
14 #define LMT_TBL_OP_READ         0
15 #define LMT_TBL_OP_WRITE        1
16 #define LMT_MAP_TABLE_SIZE      (128 * 1024)
17 #define LMT_MAPTBL_ENTRY_SIZE   16
18
19 /* Function to perform operations (read/write) on lmtst map table */
20 static int lmtst_map_table_ops(struct rvu *rvu, u32 index, u64 *val,
21                                int lmt_tbl_op)
22 {
23         void __iomem *lmt_map_base;
24         u64 tbl_base;
25
26         tbl_base = rvu_read64(rvu, BLKADDR_APR, APR_AF_LMT_MAP_BASE);
27
28         lmt_map_base = ioremap_wc(tbl_base, LMT_MAP_TABLE_SIZE);
29         if (!lmt_map_base) {
30                 dev_err(rvu->dev, "Failed to setup lmt map table mapping!!\n");
31                 return -ENOMEM;
32         }
33
34         if (lmt_tbl_op == LMT_TBL_OP_READ) {
35                 *val = readq(lmt_map_base + index);
36         } else {
37                 writeq((*val), (lmt_map_base + index));
38                 /* Flushing the AP interceptor cache to make APR_LMT_MAP_ENTRY_S
39                  * changes effective. Write 1 for flush and read is being used as a
40                  * barrier and sets up a data dependency. Write to 0 after a write
41                  * to 1 to complete the flush.
42                  */
43                 rvu_write64(rvu, BLKADDR_APR, APR_AF_LMT_CTL, BIT_ULL(0));
44                 rvu_read64(rvu, BLKADDR_APR, APR_AF_LMT_CTL);
45                 rvu_write64(rvu, BLKADDR_APR, APR_AF_LMT_CTL, 0x00);
46         }
47
48         iounmap(lmt_map_base);
49         return 0;
50 }
51
52 static u32 rvu_get_lmtst_tbl_index(struct rvu *rvu, u16 pcifunc)
53 {
54         return ((rvu_get_pf(pcifunc) * rvu->hw->total_vfs) +
55                 (pcifunc & RVU_PFVF_FUNC_MASK)) * LMT_MAPTBL_ENTRY_SIZE;
56 }
57
58 int rvu_mbox_handler_lmtst_tbl_setup(struct rvu *rvu,
59                                      struct lmtst_tbl_setup_req *req,
60                                      struct msg_rsp *rsp)
61 {
62         struct rvu_pfvf *pfvf = rvu_get_pfvf(rvu, req->hdr.pcifunc);
63         u32 pri_tbl_idx, sec_tbl_idx;
64         int err = 0;
65         u64 val;
66
67         /* Reconfiguring lmtst map table in lmt region shared mode i.e. make
68          * multiple PF_FUNCs to share an LMTLINE region, so primary/base
69          * pcifunc (which is passed as an argument to mailbox) is the one
70          * whose lmt base address will be shared among other secondary
71          * pcifunc (will be the one who is calling this mailbox).
72          */
73         if (req->base_pcifunc) {
74                 /* Calculating the LMT table index equivalent to primary
75                  * pcifunc.
76                  */
77                 pri_tbl_idx = rvu_get_lmtst_tbl_index(rvu, req->base_pcifunc);
78
79                 /* Truncating secondary pcifunc to calculate the LMT table index
80                  * equivalent to secondary pcifunc.
81                  */
82                 sec_tbl_idx = rvu_get_lmtst_tbl_index(rvu, req->hdr.pcifunc);
83                 /* Read the base lmt addr of the secondary pcifunc */
84                 err = lmtst_map_table_ops(rvu, sec_tbl_idx, &val,
85                                           LMT_TBL_OP_READ);
86                 if (err) {
87                         dev_err(rvu->dev,
88                                 "Failed to read LMT map table: index 0x%x err %d\n",
89                                 sec_tbl_idx, err);
90                         goto error;
91                 }
92
93                 /* Storing the seondary's lmt base address as this needs to be
94                  * reverted in FLR. Also making sure this default value doesn't
95                  * get overwritten on multiple calls to this mailbox.
96                  */
97                 if (!pfvf->lmt_base_addr)
98                         pfvf->lmt_base_addr = val;
99
100                 /* Read the base lmt addr of the primary pcifunc */
101                 err = lmtst_map_table_ops(rvu, pri_tbl_idx, &val,
102                                           LMT_TBL_OP_READ);
103                 if (err) {
104                         dev_err(rvu->dev,
105                                 "Failed to read LMT map table: index 0x%x err %d\n",
106                                 pri_tbl_idx, err);
107                         goto error;
108                 }
109
110                 /* Update the base lmt addr of secondary with primary's base
111                  * lmt addr.
112                  */
113                 err = lmtst_map_table_ops(rvu, sec_tbl_idx, &val,
114                                           LMT_TBL_OP_WRITE);
115                 if (err) {
116                         dev_err(rvu->dev,
117                                 "Failed to update LMT map table: index 0x%x err %d\n",
118                                 sec_tbl_idx, err);
119                         goto error;
120                 }
121         }
122
123 error:
124         return err;
125 }
126
127 /* Resetting the lmtst map table to original base addresses */
128 void rvu_reset_lmt_map_tbl(struct rvu *rvu, u16 pcifunc)
129 {
130         struct rvu_pfvf *pfvf = rvu_get_pfvf(rvu, pcifunc);
131         u32 tbl_idx;
132         int err;
133
134         if (is_rvu_otx2(rvu))
135                 return;
136
137         if (pfvf->lmt_base_addr) {
138                 /* This corresponds to lmt map table index */
139                 tbl_idx = rvu_get_lmtst_tbl_index(rvu, pcifunc);
140                 /* Reverting back original lmt base addr for respective
141                  * pcifunc.
142                  */
143                 err = lmtst_map_table_ops(rvu, tbl_idx, &pfvf->lmt_base_addr,
144                                           LMT_TBL_OP_WRITE);
145                 if (err)
146                         dev_err(rvu->dev,
147                                 "Failed to update LMT map table: index 0x%x err %d\n",
148                                 tbl_idx, err);
149                 pfvf->lmt_base_addr = 0;
150         }
151 }
152
153 int rvu_set_channels_base(struct rvu *rvu)
154 {
155         struct rvu_hwinfo *hw = rvu->hw;
156         u16 cpt_chan_base;
157         u64 nix_const;
158         int blkaddr;
159
160         blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NIX, 0);
161         if (blkaddr < 0)
162                 return blkaddr;
163
164         nix_const = rvu_read64(rvu, blkaddr, NIX_AF_CONST);
165
166         hw->cgx = (nix_const >> 12) & 0xFULL;
167         hw->lmac_per_cgx = (nix_const >> 8) & 0xFULL;
168         hw->cgx_links = hw->cgx * hw->lmac_per_cgx;
169         hw->lbk_links = (nix_const >> 24) & 0xFULL;
170         hw->cpt_links = (nix_const >> 44) & 0xFULL;
171         hw->sdp_links = 1;
172
173         hw->cgx_chan_base = NIX_CHAN_CGX_LMAC_CHX(0, 0, 0);
174         hw->lbk_chan_base = NIX_CHAN_LBK_CHX(0, 0);
175         hw->sdp_chan_base = NIX_CHAN_SDP_CH_START;
176
177         /* No Programmable channels */
178         if (!(nix_const & BIT_ULL(60)))
179                 return 0;
180
181         hw->cap.programmable_chans = true;
182
183         /* If programmable channels are present then configure
184          * channels such that all channel numbers are contiguous
185          * leaving no holes. This way the new CPT channels can be
186          * accomodated. The order of channel numbers assigned is
187          * LBK, SDP, CGX and CPT.
188          */
189         hw->sdp_chan_base = hw->lbk_chan_base + hw->lbk_links *
190                                 ((nix_const >> 16) & 0xFFULL);
191         hw->cgx_chan_base = hw->sdp_chan_base + hw->sdp_links * SDP_CHANNELS;
192
193         cpt_chan_base = hw->cgx_chan_base + hw->cgx_links *
194                                 (nix_const & 0xFFULL);
195
196         /* Out of 4096 channels start CPT from 2048 so
197          * that MSB for CPT channels is always set
198          */
199         if (cpt_chan_base <= 0x800) {
200                 hw->cpt_chan_base = 0x800;
201         } else {
202                 dev_err(rvu->dev,
203                         "CPT channels could not fit in the range 2048-4095\n");
204                 return -EINVAL;
205         }
206
207         return 0;
208 }
209
210 #define LBK_CONNECT_NIXX(a)             (0x0 + (a))
211
212 static void __rvu_lbk_set_chans(struct rvu *rvu, void __iomem *base,
213                                 u64 offset, int lbkid, u16 chans)
214 {
215         struct rvu_hwinfo *hw = rvu->hw;
216         u64 cfg;
217
218         cfg = readq(base + offset);
219         cfg &= ~(LBK_LINK_CFG_RANGE_MASK |
220                  LBK_LINK_CFG_ID_MASK | LBK_LINK_CFG_BASE_MASK);
221         cfg |=  FIELD_PREP(LBK_LINK_CFG_RANGE_MASK, ilog2(chans));
222         cfg |=  FIELD_PREP(LBK_LINK_CFG_ID_MASK, lbkid);
223         cfg |=  FIELD_PREP(LBK_LINK_CFG_BASE_MASK, hw->lbk_chan_base);
224
225         writeq(cfg, base + offset);
226 }
227
228 static void rvu_lbk_set_channels(struct rvu *rvu)
229 {
230         struct pci_dev *pdev = NULL;
231         void __iomem *base;
232         u64 lbk_const;
233         u8 src, dst;
234         u16 chans;
235
236         /* To loopback packets between multiple NIX blocks
237          * mutliple LBK blocks are needed. With two NIX blocks,
238          * four LBK blocks are needed and each LBK block
239          * source and destination are as follows:
240          * LBK0 - source NIX0 and destination NIX1
241          * LBK1 - source NIX0 and destination NIX1
242          * LBK2 - source NIX1 and destination NIX0
243          * LBK3 - source NIX1 and destination NIX1
244          * As per the HRM channel numbers should be programmed as:
245          * P2X and X2P of LBK0 as same
246          * P2X and X2P of LBK3 as same
247          * P2X of LBK1 and X2P of LBK2 as same
248          * P2X of LBK2 and X2P of LBK1 as same
249          */
250         while (true) {
251                 pdev = pci_get_device(PCI_VENDOR_ID_CAVIUM,
252                                       PCI_DEVID_OCTEONTX2_LBK, pdev);
253                 if (!pdev)
254                         return;
255
256                 base = pci_ioremap_bar(pdev, 0);
257                 if (!base)
258                         goto err_put;
259
260                 lbk_const = readq(base + LBK_CONST);
261                 chans = FIELD_GET(LBK_CONST_CHANS, lbk_const);
262                 dst = FIELD_GET(LBK_CONST_DST, lbk_const);
263                 src = FIELD_GET(LBK_CONST_SRC, lbk_const);
264
265                 if (src == dst) {
266                         if (src == LBK_CONNECT_NIXX(0)) { /* LBK0 */
267                                 __rvu_lbk_set_chans(rvu, base, LBK_LINK_CFG_X2P,
268                                                     0, chans);
269                                 __rvu_lbk_set_chans(rvu, base, LBK_LINK_CFG_P2X,
270                                                     0, chans);
271                         } else if (src == LBK_CONNECT_NIXX(1)) { /* LBK3 */
272                                 __rvu_lbk_set_chans(rvu, base, LBK_LINK_CFG_X2P,
273                                                     1, chans);
274                                 __rvu_lbk_set_chans(rvu, base, LBK_LINK_CFG_P2X,
275                                                     1, chans);
276                         }
277                 } else {
278                         if (src == LBK_CONNECT_NIXX(0)) { /* LBK1 */
279                                 __rvu_lbk_set_chans(rvu, base, LBK_LINK_CFG_X2P,
280                                                     0, chans);
281                                 __rvu_lbk_set_chans(rvu, base, LBK_LINK_CFG_P2X,
282                                                     1, chans);
283                         } else if (src == LBK_CONNECT_NIXX(1)) { /* LBK2 */
284                                 __rvu_lbk_set_chans(rvu, base, LBK_LINK_CFG_X2P,
285                                                     1, chans);
286                                 __rvu_lbk_set_chans(rvu, base, LBK_LINK_CFG_P2X,
287                                                     0, chans);
288                         }
289                 }
290                 iounmap(base);
291         }
292 err_put:
293         pci_dev_put(pdev);
294 }
295
296 static void __rvu_nix_set_channels(struct rvu *rvu, int blkaddr)
297 {
298         u64 nix_const = rvu_read64(rvu, blkaddr, NIX_AF_CONST);
299         u16 cgx_chans, lbk_chans, sdp_chans, cpt_chans;
300         struct rvu_hwinfo *hw = rvu->hw;
301         int link, nix_link = 0;
302         u16 start;
303         u64 cfg;
304
305         cgx_chans = nix_const & 0xFFULL;
306         lbk_chans = (nix_const >> 16) & 0xFFULL;
307         sdp_chans = SDP_CHANNELS;
308         cpt_chans = (nix_const >> 32) & 0xFFFULL;
309
310         start = hw->cgx_chan_base;
311         for (link = 0; link < hw->cgx_links; link++, nix_link++) {
312                 cfg = rvu_read64(rvu, blkaddr, NIX_AF_LINKX_CFG(nix_link));
313                 cfg &= ~(NIX_AF_LINKX_BASE_MASK | NIX_AF_LINKX_RANGE_MASK);
314                 cfg |=  FIELD_PREP(NIX_AF_LINKX_RANGE_MASK, ilog2(cgx_chans));
315                 cfg |=  FIELD_PREP(NIX_AF_LINKX_BASE_MASK, start);
316                 rvu_write64(rvu, blkaddr, NIX_AF_LINKX_CFG(nix_link), cfg);
317                 start += cgx_chans;
318         }
319
320         start = hw->lbk_chan_base;
321         for (link = 0; link < hw->lbk_links; link++, nix_link++) {
322                 cfg = rvu_read64(rvu, blkaddr, NIX_AF_LINKX_CFG(nix_link));
323                 cfg &= ~(NIX_AF_LINKX_BASE_MASK | NIX_AF_LINKX_RANGE_MASK);
324                 cfg |=  FIELD_PREP(NIX_AF_LINKX_RANGE_MASK, ilog2(lbk_chans));
325                 cfg |=  FIELD_PREP(NIX_AF_LINKX_BASE_MASK, start);
326                 rvu_write64(rvu, blkaddr, NIX_AF_LINKX_CFG(nix_link), cfg);
327                 start += lbk_chans;
328         }
329
330         start = hw->sdp_chan_base;
331         for (link = 0; link < hw->sdp_links; link++, nix_link++) {
332                 cfg = rvu_read64(rvu, blkaddr, NIX_AF_LINKX_CFG(nix_link));
333                 cfg &= ~(NIX_AF_LINKX_BASE_MASK | NIX_AF_LINKX_RANGE_MASK);
334                 cfg |=  FIELD_PREP(NIX_AF_LINKX_RANGE_MASK, ilog2(sdp_chans));
335                 cfg |=  FIELD_PREP(NIX_AF_LINKX_BASE_MASK, start);
336                 rvu_write64(rvu, blkaddr, NIX_AF_LINKX_CFG(nix_link), cfg);
337                 start += sdp_chans;
338         }
339
340         start = hw->cpt_chan_base;
341         for (link = 0; link < hw->cpt_links; link++, nix_link++) {
342                 cfg = rvu_read64(rvu, blkaddr, NIX_AF_LINKX_CFG(nix_link));
343                 cfg &= ~(NIX_AF_LINKX_BASE_MASK | NIX_AF_LINKX_RANGE_MASK);
344                 cfg |=  FIELD_PREP(NIX_AF_LINKX_RANGE_MASK, ilog2(cpt_chans));
345                 cfg |=  FIELD_PREP(NIX_AF_LINKX_BASE_MASK, start);
346                 rvu_write64(rvu, blkaddr, NIX_AF_LINKX_CFG(nix_link), cfg);
347                 start += cpt_chans;
348         }
349 }
350
351 static void rvu_nix_set_channels(struct rvu *rvu)
352 {
353         int blkaddr = 0;
354
355         blkaddr = rvu_get_next_nix_blkaddr(rvu, blkaddr);
356         while (blkaddr) {
357                 __rvu_nix_set_channels(rvu, blkaddr);
358                 blkaddr = rvu_get_next_nix_blkaddr(rvu, blkaddr);
359         }
360 }
361
362 static void __rvu_rpm_set_channels(int cgxid, int lmacid, u16 base)
363 {
364         u64 cfg;
365
366         cfg = cgx_lmac_read(cgxid, lmacid, RPMX_CMRX_LINK_CFG);
367         cfg &= ~(RPMX_CMRX_LINK_BASE_MASK | RPMX_CMRX_LINK_RANGE_MASK);
368
369         /* There is no read-only constant register to read
370          * the number of channels for LMAC and it is always 16.
371          */
372         cfg |=  FIELD_PREP(RPMX_CMRX_LINK_RANGE_MASK, ilog2(16));
373         cfg |=  FIELD_PREP(RPMX_CMRX_LINK_BASE_MASK, base);
374         cgx_lmac_write(cgxid, lmacid, RPMX_CMRX_LINK_CFG, cfg);
375 }
376
377 static void rvu_rpm_set_channels(struct rvu *rvu)
378 {
379         struct rvu_hwinfo *hw = rvu->hw;
380         u16 base = hw->cgx_chan_base;
381         int cgx, lmac;
382
383         for (cgx = 0; cgx < rvu->cgx_cnt_max; cgx++) {
384                 for (lmac = 0; lmac < hw->lmac_per_cgx; lmac++) {
385                         __rvu_rpm_set_channels(cgx, lmac, base);
386                         base += 16;
387                 }
388         }
389 }
390
391 void rvu_program_channels(struct rvu *rvu)
392 {
393         struct rvu_hwinfo *hw = rvu->hw;
394
395         if (!hw->cap.programmable_chans)
396                 return;
397
398         rvu_nix_set_channels(rvu);
399         rvu_lbk_set_channels(rvu);
400         rvu_rpm_set_channels(rvu);
401 }