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>
This commit is contained in:
Srikanth, Jampala 2018-11-21 09:52:24 +00:00 committed by Herbert Xu
parent 4bede34c1a
commit 7a027b57f9
4 changed files with 142 additions and 10 deletions

View File

@ -103,6 +103,16 @@ struct nitrox_q_vector {
};
};
/**
* struct nitrox_iov - SR-IOV information
* @num_vfs: number of VF(s) enabled
* @msix: MSI-X for PF in SR-IOV case
*/
struct nitrox_iov {
int num_vfs;
struct msix_entry msix;
};
/*
* NITROX Device states
*/
@ -150,6 +160,9 @@ enum vf_mode {
* @ctx_pool: DMA pool for crypto context
* @pkt_inq: Packet input rings
* @qvec: MSI-X queue vectors information
* @iov: SR-IOV informatin
* @num_vecs: number of MSI-X vectors
* @stats: request statistics
* @hw: hardware information
* @debugfs_dir: debugfs directory
*/
@ -168,13 +181,13 @@ struct nitrox_device {
int node;
u16 qlen;
u16 nr_queues;
int num_vfs;
enum vf_mode mode;
struct dma_pool *ctx_pool;
struct nitrox_cmdq *pkt_inq;
struct nitrox_q_vector *qvec;
struct nitrox_iov iov;
int num_vecs;
struct nitrox_stats stats;

View File

@ -13,6 +13,7 @@
* - NPS packet ring, AQMQ ring and ZQMQ ring
*/
#define NR_RING_VECTORS 3
#define NR_NON_RING_VECTORS 1
/* base entry for packet ring/port */
#define PKT_RING_MSIX_BASE 0
#define NON_RING_MSIX_BASE 192
@ -275,6 +276,7 @@ void nitrox_unregister_interrupts(struct nitrox_device *ndev)
qvec->valid = false;
}
kfree(ndev->qvec);
ndev->qvec = NULL;
pci_free_irq_vectors(pdev);
}
@ -321,6 +323,7 @@ int nitrox_register_interrupts(struct nitrox_device *ndev)
if (qvec->ring >= ndev->nr_queues)
break;
qvec->cmdq = &ndev->pkt_inq[qvec->ring];
snprintf(qvec->name, IRQ_NAMESZ, "nitrox-pkt%d", qvec->ring);
/* get the vector number */
vec = pci_irq_vector(pdev, i);
@ -335,13 +338,13 @@ int nitrox_register_interrupts(struct nitrox_device *ndev)
tasklet_init(&qvec->resp_tasklet, pkt_slc_resp_tasklet,
(unsigned long)qvec);
qvec->cmdq = &ndev->pkt_inq[qvec->ring];
qvec->valid = true;
}
/* request irqs for non ring vectors */
i = NON_RING_MSIX_BASE;
qvec = &ndev->qvec[i];
qvec->ndev = ndev;
snprintf(qvec->name, IRQ_NAMESZ, "nitrox-core-int%d", i);
/* get the vector number */
@ -356,7 +359,6 @@ int nitrox_register_interrupts(struct nitrox_device *ndev)
tasklet_init(&qvec->resp_tasklet, nps_core_int_tasklet,
(unsigned long)qvec);
qvec->ndev = ndev;
qvec->valid = true;
return 0;
@ -365,3 +367,81 @@ int nitrox_register_interrupts(struct nitrox_device *ndev)
nitrox_unregister_interrupts(ndev);
return ret;
}
void nitrox_sriov_unregister_interrupts(struct nitrox_device *ndev)
{
struct pci_dev *pdev = ndev->pdev;
int i;
for (i = 0; i < ndev->num_vecs; i++) {
struct nitrox_q_vector *qvec;
int vec;
qvec = ndev->qvec + i;
if (!qvec->valid)
continue;
vec = ndev->iov.msix.vector;
irq_set_affinity_hint(vec, NULL);
free_irq(vec, qvec);
tasklet_disable(&qvec->resp_tasklet);
tasklet_kill(&qvec->resp_tasklet);
qvec->valid = false;
}
kfree(ndev->qvec);
ndev->qvec = NULL;
pci_disable_msix(pdev);
}
int nitrox_sriov_register_interupts(struct nitrox_device *ndev)
{
struct pci_dev *pdev = ndev->pdev;
struct nitrox_q_vector *qvec;
int vec, cpu;
int ret;
/**
* only non ring vectors i.e Entry 192 is available
* for PF in SR-IOV mode.
*/
ndev->iov.msix.entry = NON_RING_MSIX_BASE;
ret = pci_enable_msix_exact(pdev, &ndev->iov.msix, NR_NON_RING_VECTORS);
if (ret) {
dev_err(DEV(ndev), "failed to allocate nps-core-int%d\n",
NON_RING_MSIX_BASE);
return ret;
}
qvec = kcalloc(NR_NON_RING_VECTORS, sizeof(*qvec), GFP_KERNEL);
if (!qvec) {
pci_disable_msix(pdev);
return -ENOMEM;
}
qvec->ndev = ndev;
ndev->qvec = qvec;
ndev->num_vecs = NR_NON_RING_VECTORS;
snprintf(qvec->name, IRQ_NAMESZ, "nitrox-core-int%d",
NON_RING_MSIX_BASE);
vec = ndev->iov.msix.vector;
ret = request_irq(vec, nps_core_int_isr, 0, qvec->name, qvec);
if (ret) {
dev_err(DEV(ndev), "irq failed for nitrox-core-int%d\n",
NON_RING_MSIX_BASE);
goto iov_irq_fail;
}
cpu = num_online_cpus();
irq_set_affinity_hint(vec, get_cpu_mask(cpu));
tasklet_init(&qvec->resp_tasklet, nps_core_int_tasklet,
(unsigned long)qvec);
qvec->valid = true;
return 0;
iov_irq_fail:
nitrox_sriov_unregister_interrupts(ndev);
return ret;
}

View File

@ -6,5 +6,7 @@
int nitrox_register_interrupts(struct nitrox_device *ndev);
void nitrox_unregister_interrupts(struct nitrox_device *ndev);
int nitrox_sriov_register_interupts(struct nitrox_device *ndev);
void nitrox_sriov_unregister_interrupts(struct nitrox_device *ndev);
#endif /* __NITROX_ISR_H */

View File

@ -7,6 +7,10 @@
#include "nitrox_common.h"
#include "nitrox_isr.h"
/**
* num_vfs_valid - validate VF count
* @num_vfs: number of VF(s)
*/
static inline bool num_vfs_valid(int num_vfs)
{
bool valid = false;
@ -48,7 +52,7 @@ static inline enum vf_mode num_vfs_to_mode(int num_vfs)
return mode;
}
static void pf_sriov_cleanup(struct nitrox_device *ndev)
static void nitrox_pf_cleanup(struct nitrox_device *ndev)
{
/* PF has no queues in SR-IOV mode */
atomic_set(&ndev->state, __NDEV_NOT_READY);
@ -60,7 +64,11 @@ static void pf_sriov_cleanup(struct nitrox_device *ndev)
nitrox_common_sw_cleanup(ndev);
}
static int pf_sriov_init(struct nitrox_device *ndev)
/**
* nitrox_pf_reinit - re-initialize PF resources once SR-IOV is disabled
* @ndev: NITROX device
*/
static int nitrox_pf_reinit(struct nitrox_device *ndev)
{
int err;
@ -86,6 +94,18 @@ static int pf_sriov_init(struct nitrox_device *ndev)
return nitrox_crypto_register();
}
static int nitrox_sriov_init(struct nitrox_device *ndev)
{
/* register interrupts for PF in SR-IOV */
return nitrox_sriov_register_interupts(ndev);
}
static void nitrox_sriov_cleanup(struct nitrox_device *ndev)
{
/* unregister interrupts for PF in SR-IOV */
nitrox_sriov_unregister_interrupts(ndev);
}
static int nitrox_sriov_enable(struct pci_dev *pdev, int num_vfs)
{
struct nitrox_device *ndev = pci_get_drvdata(pdev);
@ -106,17 +126,31 @@ static int nitrox_sriov_enable(struct pci_dev *pdev, int num_vfs)
}
dev_info(DEV(ndev), "Enabled VF(s) %d\n", num_vfs);
ndev->num_vfs = num_vfs;
ndev->iov.num_vfs = num_vfs;
ndev->mode = num_vfs_to_mode(num_vfs);
/* set bit in flags */
set_bit(__NDEV_SRIOV_BIT, &ndev->flags);
/* cleanup PF resources */
pf_sriov_cleanup(ndev);
nitrox_pf_cleanup(ndev);
/* PF SR-IOV mode initialization */
err = nitrox_sriov_init(ndev);
if (err)
goto iov_fail;
config_nps_core_vfcfg_mode(ndev, ndev->mode);
return num_vfs;
iov_fail:
pci_disable_sriov(pdev);
/* clear bit in flags */
clear_bit(__NDEV_SRIOV_BIT, &ndev->flags);
ndev->iov.num_vfs = 0;
ndev->mode = __NDEV_MODE_PF;
/* reset back to working mode in PF */
nitrox_pf_reinit(ndev);
return err;
}
static int nitrox_sriov_disable(struct pci_dev *pdev)
@ -134,12 +168,15 @@ static int nitrox_sriov_disable(struct pci_dev *pdev)
/* clear bit in flags */
clear_bit(__NDEV_SRIOV_BIT, &ndev->flags);
ndev->num_vfs = 0;
ndev->iov.num_vfs = 0;
ndev->mode = __NDEV_MODE_PF;
/* cleanup PF SR-IOV resources */
nitrox_sriov_cleanup(ndev);
config_nps_core_vfcfg_mode(ndev, ndev->mode);
return pf_sriov_init(ndev);
return nitrox_pf_reinit(ndev);
}
int nitrox_sriov_configure(struct pci_dev *pdev, int num_vfs)