Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

crypto: cavium/nitrox - Enable interrups for PF in SR-IOV mode.

Enable the available interrupt vectors for PF in SR-IOV Mode.
Only single vector entry 192 is valid of PF. This is used to
notify any hardware errors and mailbox messages from VF(s).

Signed-off-by: Srikanth Jampala <Jampala.Srikanth@cavium.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

authored by

Srikanth, Jampala and committed by
Herbert Xu
7a027b57 4bede34c

+142 -10
+14 -1
drivers/crypto/cavium/nitrox/nitrox_dev.h
··· 103 103 }; 104 104 }; 105 105 106 + /** 107 + * struct nitrox_iov - SR-IOV information 108 + * @num_vfs: number of VF(s) enabled 109 + * @msix: MSI-X for PF in SR-IOV case 110 + */ 111 + struct nitrox_iov { 112 + int num_vfs; 113 + struct msix_entry msix; 114 + }; 115 + 106 116 /* 107 117 * NITROX Device states 108 118 */ ··· 160 150 * @ctx_pool: DMA pool for crypto context 161 151 * @pkt_inq: Packet input rings 162 152 * @qvec: MSI-X queue vectors information 153 + * @iov: SR-IOV informatin 154 + * @num_vecs: number of MSI-X vectors 155 + * @stats: request statistics 163 156 * @hw: hardware information 164 157 * @debugfs_dir: debugfs directory 165 158 */ ··· 181 168 int node; 182 169 u16 qlen; 183 170 u16 nr_queues; 184 - int num_vfs; 185 171 enum vf_mode mode; 186 172 187 173 struct dma_pool *ctx_pool; 188 174 struct nitrox_cmdq *pkt_inq; 189 175 190 176 struct nitrox_q_vector *qvec; 177 + struct nitrox_iov iov; 191 178 int num_vecs; 192 179 193 180 struct nitrox_stats stats;
+82 -2
drivers/crypto/cavium/nitrox/nitrox_isr.c
··· 13 13 * - NPS packet ring, AQMQ ring and ZQMQ ring 14 14 */ 15 15 #define NR_RING_VECTORS 3 16 + #define NR_NON_RING_VECTORS 1 16 17 /* base entry for packet ring/port */ 17 18 #define PKT_RING_MSIX_BASE 0 18 19 #define NON_RING_MSIX_BASE 192 ··· 276 275 qvec->valid = false; 277 276 } 278 277 kfree(ndev->qvec); 278 + ndev->qvec = NULL; 279 279 pci_free_irq_vectors(pdev); 280 280 } 281 281 ··· 323 321 if (qvec->ring >= ndev->nr_queues) 324 322 break; 325 323 324 + qvec->cmdq = &ndev->pkt_inq[qvec->ring]; 326 325 snprintf(qvec->name, IRQ_NAMESZ, "nitrox-pkt%d", qvec->ring); 327 326 /* get the vector number */ 328 327 vec = pci_irq_vector(pdev, i); ··· 338 335 339 336 tasklet_init(&qvec->resp_tasklet, pkt_slc_resp_tasklet, 340 337 (unsigned long)qvec); 341 - qvec->cmdq = &ndev->pkt_inq[qvec->ring]; 342 338 qvec->valid = true; 343 339 } 344 340 345 341 /* request irqs for non ring vectors */ 346 342 i = NON_RING_MSIX_BASE; 347 343 qvec = &ndev->qvec[i]; 344 + qvec->ndev = ndev; 348 345 349 346 snprintf(qvec->name, IRQ_NAMESZ, "nitrox-core-int%d", i); 350 347 /* get the vector number */ ··· 359 356 360 357 tasklet_init(&qvec->resp_tasklet, nps_core_int_tasklet, 361 358 (unsigned long)qvec); 362 - qvec->ndev = ndev; 363 359 qvec->valid = true; 364 360 365 361 return 0; 366 362 367 363 irq_fail: 368 364 nitrox_unregister_interrupts(ndev); 365 + return ret; 366 + } 367 + 368 + void nitrox_sriov_unregister_interrupts(struct nitrox_device *ndev) 369 + { 370 + struct pci_dev *pdev = ndev->pdev; 371 + int i; 372 + 373 + for (i = 0; i < ndev->num_vecs; i++) { 374 + struct nitrox_q_vector *qvec; 375 + int vec; 376 + 377 + qvec = ndev->qvec + i; 378 + if (!qvec->valid) 379 + continue; 380 + 381 + vec = ndev->iov.msix.vector; 382 + irq_set_affinity_hint(vec, NULL); 383 + free_irq(vec, qvec); 384 + 385 + tasklet_disable(&qvec->resp_tasklet); 386 + tasklet_kill(&qvec->resp_tasklet); 387 + qvec->valid = false; 388 + } 389 + kfree(ndev->qvec); 390 + ndev->qvec = NULL; 391 + pci_disable_msix(pdev); 392 + } 393 + 394 + int nitrox_sriov_register_interupts(struct nitrox_device *ndev) 395 + { 396 + struct pci_dev *pdev = ndev->pdev; 397 + struct nitrox_q_vector *qvec; 398 + int vec, cpu; 399 + int ret; 400 + 401 + /** 402 + * only non ring vectors i.e Entry 192 is available 403 + * for PF in SR-IOV mode. 404 + */ 405 + ndev->iov.msix.entry = NON_RING_MSIX_BASE; 406 + ret = pci_enable_msix_exact(pdev, &ndev->iov.msix, NR_NON_RING_VECTORS); 407 + if (ret) { 408 + dev_err(DEV(ndev), "failed to allocate nps-core-int%d\n", 409 + NON_RING_MSIX_BASE); 410 + return ret; 411 + } 412 + 413 + qvec = kcalloc(NR_NON_RING_VECTORS, sizeof(*qvec), GFP_KERNEL); 414 + if (!qvec) { 415 + pci_disable_msix(pdev); 416 + return -ENOMEM; 417 + } 418 + qvec->ndev = ndev; 419 + 420 + ndev->qvec = qvec; 421 + ndev->num_vecs = NR_NON_RING_VECTORS; 422 + snprintf(qvec->name, IRQ_NAMESZ, "nitrox-core-int%d", 423 + NON_RING_MSIX_BASE); 424 + 425 + vec = ndev->iov.msix.vector; 426 + ret = request_irq(vec, nps_core_int_isr, 0, qvec->name, qvec); 427 + if (ret) { 428 + dev_err(DEV(ndev), "irq failed for nitrox-core-int%d\n", 429 + NON_RING_MSIX_BASE); 430 + goto iov_irq_fail; 431 + } 432 + cpu = num_online_cpus(); 433 + irq_set_affinity_hint(vec, get_cpu_mask(cpu)); 434 + 435 + tasklet_init(&qvec->resp_tasklet, nps_core_int_tasklet, 436 + (unsigned long)qvec); 437 + qvec->valid = true; 438 + 439 + return 0; 440 + 441 + iov_irq_fail: 442 + nitrox_sriov_unregister_interrupts(ndev); 369 443 return ret; 370 444 }
+2
drivers/crypto/cavium/nitrox/nitrox_isr.h
··· 6 6 7 7 int nitrox_register_interrupts(struct nitrox_device *ndev); 8 8 void nitrox_unregister_interrupts(struct nitrox_device *ndev); 9 + int nitrox_sriov_register_interupts(struct nitrox_device *ndev); 10 + void nitrox_sriov_unregister_interrupts(struct nitrox_device *ndev); 9 11 10 12 #endif /* __NITROX_ISR_H */
+44 -7
drivers/crypto/cavium/nitrox/nitrox_sriov.c
··· 7 7 #include "nitrox_common.h" 8 8 #include "nitrox_isr.h" 9 9 10 + /** 11 + * num_vfs_valid - validate VF count 12 + * @num_vfs: number of VF(s) 13 + */ 10 14 static inline bool num_vfs_valid(int num_vfs) 11 15 { 12 16 bool valid = false; ··· 52 48 return mode; 53 49 } 54 50 55 - static void pf_sriov_cleanup(struct nitrox_device *ndev) 51 + static void nitrox_pf_cleanup(struct nitrox_device *ndev) 56 52 { 57 53 /* PF has no queues in SR-IOV mode */ 58 54 atomic_set(&ndev->state, __NDEV_NOT_READY); ··· 64 60 nitrox_common_sw_cleanup(ndev); 65 61 } 66 62 67 - static int pf_sriov_init(struct nitrox_device *ndev) 63 + /** 64 + * nitrox_pf_reinit - re-initialize PF resources once SR-IOV is disabled 65 + * @ndev: NITROX device 66 + */ 67 + static int nitrox_pf_reinit(struct nitrox_device *ndev) 68 68 { 69 69 int err; 70 70 ··· 94 86 return nitrox_crypto_register(); 95 87 } 96 88 89 + static int nitrox_sriov_init(struct nitrox_device *ndev) 90 + { 91 + /* register interrupts for PF in SR-IOV */ 92 + return nitrox_sriov_register_interupts(ndev); 93 + } 94 + 95 + static void nitrox_sriov_cleanup(struct nitrox_device *ndev) 96 + { 97 + /* unregister interrupts for PF in SR-IOV */ 98 + nitrox_sriov_unregister_interrupts(ndev); 99 + } 100 + 97 101 static int nitrox_sriov_enable(struct pci_dev *pdev, int num_vfs) 98 102 { 99 103 struct nitrox_device *ndev = pci_get_drvdata(pdev); ··· 126 106 } 127 107 dev_info(DEV(ndev), "Enabled VF(s) %d\n", num_vfs); 128 108 129 - ndev->num_vfs = num_vfs; 109 + ndev->iov.num_vfs = num_vfs; 130 110 ndev->mode = num_vfs_to_mode(num_vfs); 131 111 /* set bit in flags */ 132 112 set_bit(__NDEV_SRIOV_BIT, &ndev->flags); 133 113 134 114 /* cleanup PF resources */ 135 - pf_sriov_cleanup(ndev); 115 + nitrox_pf_cleanup(ndev); 116 + 117 + /* PF SR-IOV mode initialization */ 118 + err = nitrox_sriov_init(ndev); 119 + if (err) 120 + goto iov_fail; 136 121 137 122 config_nps_core_vfcfg_mode(ndev, ndev->mode); 138 - 139 123 return num_vfs; 124 + 125 + iov_fail: 126 + pci_disable_sriov(pdev); 127 + /* clear bit in flags */ 128 + clear_bit(__NDEV_SRIOV_BIT, &ndev->flags); 129 + ndev->iov.num_vfs = 0; 130 + ndev->mode = __NDEV_MODE_PF; 131 + /* reset back to working mode in PF */ 132 + nitrox_pf_reinit(ndev); 133 + return err; 140 134 } 141 135 142 136 static int nitrox_sriov_disable(struct pci_dev *pdev) ··· 168 134 /* clear bit in flags */ 169 135 clear_bit(__NDEV_SRIOV_BIT, &ndev->flags); 170 136 171 - ndev->num_vfs = 0; 137 + ndev->iov.num_vfs = 0; 172 138 ndev->mode = __NDEV_MODE_PF; 139 + 140 + /* cleanup PF SR-IOV resources */ 141 + nitrox_sriov_cleanup(ndev); 173 142 174 143 config_nps_core_vfcfg_mode(ndev, ndev->mode); 175 144 176 - return pf_sriov_init(ndev); 145 + return nitrox_pf_reinit(ndev); 177 146 } 178 147 179 148 int nitrox_sriov_configure(struct pci_dev *pdev, int num_vfs)