1 // SPDX-License-Identifier: GPL-2.0 2 /* Marvell RVU Admin Function driver 3 * 4 * Copyright (C) 2024 Marvell. 5 * 6 */ 7 8 #include <linux/interrupt.h> 9 #include <linux/irq.h> 10 11 #include "rvu_trace.h" 12 #include "mbox.h" 13 #include "reg.h" 14 #include "api.h" 15 16 static irqreturn_t cn20k_afvf_mbox_intr_handler(int irq, void *rvu_irq) 17 { 18 struct rvu_irq_data *rvu_irq_data = rvu_irq; 19 struct rvu *rvu = rvu_irq_data->rvu; 20 u64 intr; 21 22 /* Sync with mbox memory region */ 23 rmb(); 24 25 /* Clear interrupts */ 26 intr = rvupf_read64(rvu, rvu_irq_data->intr_status); 27 rvupf_write64(rvu, rvu_irq_data->intr_status, intr); 28 29 if (intr) 30 trace_otx2_msg_interrupt(rvu->pdev, "VF(s) to AF", intr); 31 32 rvu_irq_data->afvf_queue_work_hdlr(&rvu->afvf_wq_info, rvu_irq_data->start, 33 rvu_irq_data->mdevs, intr); 34 35 return IRQ_HANDLED; 36 } 37 38 int cn20k_register_afvf_mbox_intr(struct rvu *rvu, int pf_vec_start) 39 { 40 struct rvu_irq_data *irq_data; 41 int intr_vec, offset, vec = 0; 42 int err; 43 44 /* irq data for 4 VFPF intr vectors */ 45 irq_data = devm_kcalloc(rvu->dev, 4, 46 sizeof(struct rvu_irq_data), GFP_KERNEL); 47 if (!irq_data) 48 return -ENOMEM; 49 50 for (intr_vec = RVU_MBOX_PF_INT_VEC_VFPF_MBOX0; intr_vec <= 51 RVU_MBOX_PF_INT_VEC_VFPF1_MBOX1; 52 intr_vec++, vec++) { 53 switch (intr_vec) { 54 case RVU_MBOX_PF_INT_VEC_VFPF_MBOX0: 55 irq_data[vec].intr_status = 56 RVU_MBOX_PF_VFPF_INTX(0); 57 irq_data[vec].start = 0; 58 irq_data[vec].mdevs = 64; 59 break; 60 case RVU_MBOX_PF_INT_VEC_VFPF_MBOX1: 61 irq_data[vec].intr_status = 62 RVU_MBOX_PF_VFPF_INTX(1); 63 irq_data[vec].start = 64; 64 irq_data[vec].mdevs = 64; 65 break; 66 case RVU_MBOX_PF_INT_VEC_VFPF1_MBOX0: 67 irq_data[vec].intr_status = 68 RVU_MBOX_PF_VFPF1_INTX(0); 69 irq_data[vec].start = 0; 70 irq_data[vec].mdevs = 64; 71 break; 72 case RVU_MBOX_PF_INT_VEC_VFPF1_MBOX1: 73 irq_data[vec].intr_status = RVU_MBOX_PF_VFPF1_INTX(1); 74 irq_data[vec].start = 64; 75 irq_data[vec].mdevs = 64; 76 break; 77 } 78 irq_data[vec].afvf_queue_work_hdlr = 79 rvu_queue_work; 80 offset = pf_vec_start + intr_vec; 81 irq_data[vec].vec_num = offset; 82 irq_data[vec].rvu = rvu; 83 84 sprintf(&rvu->irq_name[offset * NAME_SIZE], "RVUAF VFAF%d Mbox%d", 85 vec / 2, vec % 2); 86 err = request_irq(pci_irq_vector(rvu->pdev, offset), 87 rvu->ng_rvu->rvu_mbox_ops->afvf_intr_handler, 0, 88 &rvu->irq_name[offset * NAME_SIZE], 89 &irq_data[vec]); 90 if (err) { 91 dev_err(rvu->dev, 92 "RVUAF: IRQ registration failed for AFVF mbox irq\n"); 93 return err; 94 } 95 rvu->irq_allocated[offset] = true; 96 } 97 98 return 0; 99 } 100 101 /* CN20K mbox PFx => AF irq handler */ 102 static irqreturn_t cn20k_mbox_pf_common_intr_handler(int irq, void *rvu_irq) 103 { 104 struct rvu_irq_data *rvu_irq_data = rvu_irq; 105 struct rvu *rvu = rvu_irq_data->rvu; 106 u64 intr; 107 108 /* Clear interrupts */ 109 intr = rvu_read64(rvu, BLKADDR_RVUM, rvu_irq_data->intr_status); 110 rvu_write64(rvu, BLKADDR_RVUM, rvu_irq_data->intr_status, intr); 111 112 if (intr) 113 trace_otx2_msg_interrupt(rvu->pdev, "PF(s) to AF", intr); 114 115 /* Sync with mbox memory region */ 116 rmb(); 117 118 rvu_irq_data->rvu_queue_work_hdlr(&rvu->afpf_wq_info, 119 rvu_irq_data->start, 120 rvu_irq_data->mdevs, intr); 121 122 return IRQ_HANDLED; 123 } 124 125 void cn20k_rvu_enable_mbox_intr(struct rvu *rvu) 126 { 127 struct rvu_hwinfo *hw = rvu->hw; 128 129 /* Clear spurious irqs, if any */ 130 rvu_write64(rvu, BLKADDR_RVUM, 131 RVU_MBOX_AF_PFAF_INT(0), INTR_MASK(hw->total_pfs)); 132 133 rvu_write64(rvu, BLKADDR_RVUM, 134 RVU_MBOX_AF_PFAF_INT(1), INTR_MASK(hw->total_pfs - 64)); 135 136 rvu_write64(rvu, BLKADDR_RVUM, 137 RVU_MBOX_AF_PFAF1_INT(0), INTR_MASK(hw->total_pfs)); 138 139 rvu_write64(rvu, BLKADDR_RVUM, 140 RVU_MBOX_AF_PFAF1_INT(1), INTR_MASK(hw->total_pfs - 64)); 141 142 /* Enable mailbox interrupt for all PFs except PF0 i.e AF itself */ 143 rvu_write64(rvu, BLKADDR_RVUM, RVU_MBOX_AF_PFAF_INT_ENA_W1S(0), 144 INTR_MASK(hw->total_pfs) & ~1ULL); 145 146 rvu_write64(rvu, BLKADDR_RVUM, RVU_MBOX_AF_PFAF_INT_ENA_W1S(1), 147 INTR_MASK(hw->total_pfs - 64)); 148 149 rvu_write64(rvu, BLKADDR_RVUM, RVU_MBOX_AF_PFAF1_INT_ENA_W1S(0), 150 INTR_MASK(hw->total_pfs) & ~1ULL); 151 152 rvu_write64(rvu, BLKADDR_RVUM, RVU_MBOX_AF_PFAF1_INT_ENA_W1S(1), 153 INTR_MASK(hw->total_pfs - 64)); 154 } 155 156 void cn20k_rvu_unregister_interrupts(struct rvu *rvu) 157 { 158 rvu_write64(rvu, BLKADDR_RVUM, RVU_MBOX_AF_PFAF_INT_ENA_W1C(0), 159 INTR_MASK(rvu->hw->total_pfs) & ~1ULL); 160 161 rvu_write64(rvu, BLKADDR_RVUM, RVU_MBOX_AF_PFAF_INT_ENA_W1C(1), 162 INTR_MASK(rvu->hw->total_pfs - 64)); 163 164 rvu_write64(rvu, BLKADDR_RVUM, RVU_MBOX_AF_PFAF1_INT_ENA_W1C(0), 165 INTR_MASK(rvu->hw->total_pfs) & ~1ULL); 166 167 rvu_write64(rvu, BLKADDR_RVUM, RVU_MBOX_AF_PFAF1_INT_ENA_W1C(1), 168 INTR_MASK(rvu->hw->total_pfs - 64)); 169 } 170 171 int cn20k_register_afpf_mbox_intr(struct rvu *rvu) 172 { 173 struct rvu_irq_data *irq_data; 174 int intr_vec, ret, vec = 0; 175 176 /* irq data for 4 PF intr vectors */ 177 irq_data = devm_kcalloc(rvu->dev, 4, 178 sizeof(struct rvu_irq_data), GFP_KERNEL); 179 if (!irq_data) 180 return -ENOMEM; 181 182 for (intr_vec = RVU_AF_CN20K_INT_VEC_PFAF_MBOX0; intr_vec <= 183 RVU_AF_CN20K_INT_VEC_PFAF1_MBOX1; intr_vec++, 184 vec++) { 185 switch (intr_vec) { 186 case RVU_AF_CN20K_INT_VEC_PFAF_MBOX0: 187 irq_data[vec].intr_status = 188 RVU_MBOX_AF_PFAF_INT(0); 189 irq_data[vec].start = 0; 190 irq_data[vec].mdevs = 64; 191 break; 192 case RVU_AF_CN20K_INT_VEC_PFAF_MBOX1: 193 irq_data[vec].intr_status = 194 RVU_MBOX_AF_PFAF_INT(1); 195 irq_data[vec].start = 64; 196 irq_data[vec].mdevs = 96; 197 break; 198 case RVU_AF_CN20K_INT_VEC_PFAF1_MBOX0: 199 irq_data[vec].intr_status = 200 RVU_MBOX_AF_PFAF1_INT(0); 201 irq_data[vec].start = 0; 202 irq_data[vec].mdevs = 64; 203 break; 204 case RVU_AF_CN20K_INT_VEC_PFAF1_MBOX1: 205 irq_data[vec].intr_status = 206 RVU_MBOX_AF_PFAF1_INT(1); 207 irq_data[vec].start = 64; 208 irq_data[vec].mdevs = 96; 209 break; 210 } 211 irq_data[vec].rvu_queue_work_hdlr = rvu_queue_work; 212 irq_data[vec].vec_num = intr_vec; 213 irq_data[vec].rvu = rvu; 214 215 /* Register mailbox interrupt handler */ 216 sprintf(&rvu->irq_name[intr_vec * NAME_SIZE], 217 "RVUAF PFAF%d Mbox%d", 218 vec / 2, vec % 2); 219 ret = request_irq(pci_irq_vector(rvu->pdev, intr_vec), 220 rvu->ng_rvu->rvu_mbox_ops->pf_intr_handler, 0, 221 &rvu->irq_name[intr_vec * NAME_SIZE], 222 &irq_data[vec]); 223 if (ret) 224 return ret; 225 226 rvu->irq_allocated[intr_vec] = true; 227 } 228 229 return 0; 230 } 231 232 int cn20k_rvu_get_mbox_regions(struct rvu *rvu, void **mbox_addr, 233 int num, int type, unsigned long *pf_bmap) 234 { 235 int region; 236 u64 bar; 237 238 if (type == TYPE_AFVF) { 239 for (region = 0; region < num; region++) { 240 if (!test_bit(region, pf_bmap)) 241 continue; 242 243 bar = (u64)phys_to_virt((u64)rvu->ng_rvu->vf_mbox_addr->base); 244 bar += region * MBOX_SIZE; 245 mbox_addr[region] = (void *)bar; 246 247 if (!mbox_addr[region]) 248 return -ENOMEM; 249 } 250 return 0; 251 } 252 253 for (region = 0; region < num; region++) { 254 if (!test_bit(region, pf_bmap)) 255 continue; 256 257 bar = (u64)phys_to_virt((u64)rvu->ng_rvu->pf_mbox_addr->base); 258 bar += region * MBOX_SIZE; 259 260 mbox_addr[region] = (void *)bar; 261 262 if (!mbox_addr[region]) 263 return -ENOMEM; 264 } 265 return 0; 266 } 267 268 static int rvu_alloc_mbox_memory(struct rvu *rvu, int type, 269 int ndevs, int mbox_size) 270 { 271 struct qmem *mbox_addr; 272 dma_addr_t iova; 273 int pf, err; 274 275 /* Allocate contiguous memory for mailbox communication. 276 * eg: AF <=> PFx mbox memory 277 * This allocated memory is split into chunks of MBOX_SIZE 278 * and setup into each of the RVU PFs. In HW this memory will 279 * get aliased to an offset within BAR2 of those PFs. 280 * 281 * AF will access mbox memory using direct physical addresses 282 * and PFs will access the same shared memory from BAR2. 283 * 284 * PF <=> VF mbox memory also works in the same fashion. 285 * AFPF, PFVF requires IOVA to be used to maintain the mailbox msgs 286 */ 287 288 err = qmem_alloc(rvu->dev, &mbox_addr, ndevs, mbox_size); 289 if (err) 290 return -ENOMEM; 291 292 switch (type) { 293 case TYPE_AFPF: 294 rvu->ng_rvu->pf_mbox_addr = mbox_addr; 295 iova = (u64)mbox_addr->iova; 296 for (pf = 0; pf < ndevs; pf++) { 297 rvu_write64(rvu, BLKADDR_RVUM, RVU_MBOX_AF_PFX_ADDR(pf), 298 (u64)iova); 299 iova += mbox_size; 300 } 301 break; 302 case TYPE_AFVF: 303 rvu->ng_rvu->vf_mbox_addr = mbox_addr; 304 rvupf_write64(rvu, RVU_PF_VF_MBOX_ADDR, (u64)mbox_addr->iova); 305 break; 306 default: 307 return 0; 308 } 309 310 return 0; 311 } 312 313 static struct mbox_ops cn20k_mbox_ops = { 314 .pf_intr_handler = cn20k_mbox_pf_common_intr_handler, 315 .afvf_intr_handler = cn20k_afvf_mbox_intr_handler, 316 }; 317 318 int cn20k_rvu_mbox_init(struct rvu *rvu, int type, int ndevs) 319 { 320 int dev; 321 322 if (!is_cn20k(rvu->pdev)) 323 return 0; 324 325 rvu->ng_rvu->rvu_mbox_ops = &cn20k_mbox_ops; 326 327 if (type == TYPE_AFVF) { 328 rvu_write64(rvu, BLKADDR_RVUM, RVU_MBOX_PF_VF_CFG, ilog2(MBOX_SIZE)); 329 } else { 330 for (dev = 0; dev < ndevs; dev++) 331 rvu_write64(rvu, BLKADDR_RVUM, 332 RVU_MBOX_AF_PFX_CFG(dev), ilog2(MBOX_SIZE)); 333 } 334 335 return rvu_alloc_mbox_memory(rvu, type, ndevs, MBOX_SIZE); 336 } 337 338 void cn20k_free_mbox_memory(struct rvu *rvu) 339 { 340 if (!is_cn20k(rvu->pdev)) 341 return; 342 343 qmem_free(rvu->dev, rvu->ng_rvu->pf_mbox_addr); 344 qmem_free(rvu->dev, rvu->ng_rvu->vf_mbox_addr); 345 } 346 347 void cn20k_rvu_disable_afvf_intr(struct rvu *rvu, int vfs) 348 { 349 rvupf_write64(rvu, RVU_MBOX_PF_VFPF_INT_ENA_W1CX(0), INTR_MASK(vfs)); 350 rvupf_write64(rvu, RVU_MBOX_PF_VFPF1_INT_ENA_W1CX(0), INTR_MASK(vfs)); 351 rvupf_write64(rvu, RVU_PF_VFFLR_INT_ENA_W1CX(0), INTR_MASK(vfs)); 352 rvupf_write64(rvu, RVU_PF_VFME_INT_ENA_W1CX(0), INTR_MASK(vfs)); 353 354 if (vfs <= 64) 355 return; 356 357 rvupf_write64(rvu, RVU_MBOX_PF_VFPF_INT_ENA_W1CX(1), INTR_MASK(vfs - 64)); 358 rvupf_write64(rvu, RVU_MBOX_PF_VFPF1_INT_ENA_W1CX(1), INTR_MASK(vfs - 64)); 359 rvupf_write64(rvu, RVU_PF_VFFLR_INT_ENA_W1CX(1), INTR_MASK(vfs - 64)); 360 rvupf_write64(rvu, RVU_PF_VFME_INT_ENA_W1CX(1), INTR_MASK(vfs - 64)); 361 } 362 363 void cn20k_rvu_enable_afvf_intr(struct rvu *rvu, int vfs) 364 { 365 /* Clear any pending interrupts and enable AF VF interrupts for 366 * the first 64 VFs. 367 */ 368 rvupf_write64(rvu, RVU_MBOX_PF_VFPF_INTX(0), INTR_MASK(vfs)); 369 rvupf_write64(rvu, RVU_MBOX_PF_VFPF_INT_ENA_W1SX(0), INTR_MASK(vfs)); 370 rvupf_write64(rvu, RVU_MBOX_PF_VFPF1_INTX(0), INTR_MASK(vfs)); 371 rvupf_write64(rvu, RVU_MBOX_PF_VFPF1_INT_ENA_W1SX(0), INTR_MASK(vfs)); 372 373 /* FLR */ 374 rvupf_write64(rvu, RVU_PF_VFFLR_INTX(0), INTR_MASK(vfs)); 375 rvupf_write64(rvu, RVU_PF_VFFLR_INT_ENA_W1SX(0), INTR_MASK(vfs)); 376 377 /* Same for remaining VFs, if any. */ 378 if (vfs <= 64) 379 return; 380 381 rvupf_write64(rvu, RVU_MBOX_PF_VFPF_INTX(1), INTR_MASK(vfs - 64)); 382 rvupf_write64(rvu, RVU_MBOX_PF_VFPF_INT_ENA_W1SX(1), INTR_MASK(vfs - 64)); 383 rvupf_write64(rvu, RVU_MBOX_PF_VFPF1_INTX(1), INTR_MASK(vfs - 64)); 384 rvupf_write64(rvu, RVU_MBOX_PF_VFPF1_INT_ENA_W1SX(1), INTR_MASK(vfs - 64)); 385 386 rvupf_write64(rvu, RVU_PF_VFFLR_INTX(1), INTR_MASK(vfs - 64)); 387 rvupf_write64(rvu, RVU_PF_VFFLR_INT_ENA_W1SX(1), INTR_MASK(vfs - 64)); 388 rvupf_write64(rvu, RVU_PF_VFME_INT_ENA_W1SX(1), INTR_MASK(vfs - 64)); 389 } 390 391 int rvu_alloc_cint_qint_mem(struct rvu *rvu, struct rvu_pfvf *pfvf, 392 int blkaddr, int nixlf) 393 { 394 int qints, hwctx_size, err; 395 u64 cfg, ctx_cfg; 396 397 if (is_rvu_otx2(rvu) || is_cn20k(rvu->pdev)) 398 return 0; 399 400 ctx_cfg = rvu_read64(rvu, blkaddr, NIX_AF_CONST3); 401 /* Alloc memory for CQINT's HW contexts */ 402 cfg = rvu_read64(rvu, blkaddr, NIX_AF_CONST2); 403 qints = (cfg >> 24) & 0xFFF; 404 hwctx_size = 1UL << ((ctx_cfg >> 24) & 0xF); 405 err = qmem_alloc(rvu->dev, &pfvf->cq_ints_ctx, qints, hwctx_size); 406 if (err) 407 return -ENOMEM; 408 409 rvu_write64(rvu, blkaddr, NIX_AF_LFX_CINTS_BASE(nixlf), 410 (u64)pfvf->cq_ints_ctx->iova); 411 412 /* Alloc memory for QINT's HW contexts */ 413 cfg = rvu_read64(rvu, blkaddr, NIX_AF_CONST2); 414 qints = (cfg >> 12) & 0xFFF; 415 hwctx_size = 1UL << ((ctx_cfg >> 20) & 0xF); 416 err = qmem_alloc(rvu->dev, &pfvf->nix_qints_ctx, qints, hwctx_size); 417 if (err) 418 return -ENOMEM; 419 420 rvu_write64(rvu, blkaddr, NIX_AF_LFX_QINTS_BASE(nixlf), 421 (u64)pfvf->nix_qints_ctx->iova); 422 423 return 0; 424 } 425