mirror of
https://github.com/torvalds/linux.git
synced 2024-11-29 07:31:29 +00:00
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:
parent
4bede34c1a
commit
7a027b57f9
@ -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;
|
||||
|
@ -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 @@ irq_fail:
|
||||
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;
|
||||
}
|
||||
|
@ -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 */
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user