mirror of
https://github.com/torvalds/linux.git
synced 2024-12-01 16:41:39 +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
|
* NITROX Device states
|
||||||
*/
|
*/
|
||||||
@ -150,6 +160,9 @@ enum vf_mode {
|
|||||||
* @ctx_pool: DMA pool for crypto context
|
* @ctx_pool: DMA pool for crypto context
|
||||||
* @pkt_inq: Packet input rings
|
* @pkt_inq: Packet input rings
|
||||||
* @qvec: MSI-X queue vectors information
|
* @qvec: MSI-X queue vectors information
|
||||||
|
* @iov: SR-IOV informatin
|
||||||
|
* @num_vecs: number of MSI-X vectors
|
||||||
|
* @stats: request statistics
|
||||||
* @hw: hardware information
|
* @hw: hardware information
|
||||||
* @debugfs_dir: debugfs directory
|
* @debugfs_dir: debugfs directory
|
||||||
*/
|
*/
|
||||||
@ -168,13 +181,13 @@ struct nitrox_device {
|
|||||||
int node;
|
int node;
|
||||||
u16 qlen;
|
u16 qlen;
|
||||||
u16 nr_queues;
|
u16 nr_queues;
|
||||||
int num_vfs;
|
|
||||||
enum vf_mode mode;
|
enum vf_mode mode;
|
||||||
|
|
||||||
struct dma_pool *ctx_pool;
|
struct dma_pool *ctx_pool;
|
||||||
struct nitrox_cmdq *pkt_inq;
|
struct nitrox_cmdq *pkt_inq;
|
||||||
|
|
||||||
struct nitrox_q_vector *qvec;
|
struct nitrox_q_vector *qvec;
|
||||||
|
struct nitrox_iov iov;
|
||||||
int num_vecs;
|
int num_vecs;
|
||||||
|
|
||||||
struct nitrox_stats stats;
|
struct nitrox_stats stats;
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
* - NPS packet ring, AQMQ ring and ZQMQ ring
|
* - NPS packet ring, AQMQ ring and ZQMQ ring
|
||||||
*/
|
*/
|
||||||
#define NR_RING_VECTORS 3
|
#define NR_RING_VECTORS 3
|
||||||
|
#define NR_NON_RING_VECTORS 1
|
||||||
/* base entry for packet ring/port */
|
/* base entry for packet ring/port */
|
||||||
#define PKT_RING_MSIX_BASE 0
|
#define PKT_RING_MSIX_BASE 0
|
||||||
#define NON_RING_MSIX_BASE 192
|
#define NON_RING_MSIX_BASE 192
|
||||||
@ -275,6 +276,7 @@ void nitrox_unregister_interrupts(struct nitrox_device *ndev)
|
|||||||
qvec->valid = false;
|
qvec->valid = false;
|
||||||
}
|
}
|
||||||
kfree(ndev->qvec);
|
kfree(ndev->qvec);
|
||||||
|
ndev->qvec = NULL;
|
||||||
pci_free_irq_vectors(pdev);
|
pci_free_irq_vectors(pdev);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -321,6 +323,7 @@ int nitrox_register_interrupts(struct nitrox_device *ndev)
|
|||||||
if (qvec->ring >= ndev->nr_queues)
|
if (qvec->ring >= ndev->nr_queues)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
qvec->cmdq = &ndev->pkt_inq[qvec->ring];
|
||||||
snprintf(qvec->name, IRQ_NAMESZ, "nitrox-pkt%d", qvec->ring);
|
snprintf(qvec->name, IRQ_NAMESZ, "nitrox-pkt%d", qvec->ring);
|
||||||
/* get the vector number */
|
/* get the vector number */
|
||||||
vec = pci_irq_vector(pdev, i);
|
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,
|
tasklet_init(&qvec->resp_tasklet, pkt_slc_resp_tasklet,
|
||||||
(unsigned long)qvec);
|
(unsigned long)qvec);
|
||||||
qvec->cmdq = &ndev->pkt_inq[qvec->ring];
|
|
||||||
qvec->valid = true;
|
qvec->valid = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* request irqs for non ring vectors */
|
/* request irqs for non ring vectors */
|
||||||
i = NON_RING_MSIX_BASE;
|
i = NON_RING_MSIX_BASE;
|
||||||
qvec = &ndev->qvec[i];
|
qvec = &ndev->qvec[i];
|
||||||
|
qvec->ndev = ndev;
|
||||||
|
|
||||||
snprintf(qvec->name, IRQ_NAMESZ, "nitrox-core-int%d", i);
|
snprintf(qvec->name, IRQ_NAMESZ, "nitrox-core-int%d", i);
|
||||||
/* get the vector number */
|
/* 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,
|
tasklet_init(&qvec->resp_tasklet, nps_core_int_tasklet,
|
||||||
(unsigned long)qvec);
|
(unsigned long)qvec);
|
||||||
qvec->ndev = ndev;
|
|
||||||
qvec->valid = true;
|
qvec->valid = true;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -365,3 +367,81 @@ irq_fail:
|
|||||||
nitrox_unregister_interrupts(ndev);
|
nitrox_unregister_interrupts(ndev);
|
||||||
return ret;
|
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);
|
int nitrox_register_interrupts(struct nitrox_device *ndev);
|
||||||
void nitrox_unregister_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 */
|
#endif /* __NITROX_ISR_H */
|
||||||
|
@ -7,6 +7,10 @@
|
|||||||
#include "nitrox_common.h"
|
#include "nitrox_common.h"
|
||||||
#include "nitrox_isr.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)
|
static inline bool num_vfs_valid(int num_vfs)
|
||||||
{
|
{
|
||||||
bool valid = false;
|
bool valid = false;
|
||||||
@ -48,7 +52,7 @@ static inline enum vf_mode num_vfs_to_mode(int num_vfs)
|
|||||||
return mode;
|
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 */
|
/* PF has no queues in SR-IOV mode */
|
||||||
atomic_set(&ndev->state, __NDEV_NOT_READY);
|
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);
|
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;
|
int err;
|
||||||
|
|
||||||
@ -86,6 +94,18 @@ static int pf_sriov_init(struct nitrox_device *ndev)
|
|||||||
return nitrox_crypto_register();
|
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)
|
static int nitrox_sriov_enable(struct pci_dev *pdev, int num_vfs)
|
||||||
{
|
{
|
||||||
struct nitrox_device *ndev = pci_get_drvdata(pdev);
|
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);
|
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);
|
ndev->mode = num_vfs_to_mode(num_vfs);
|
||||||
/* set bit in flags */
|
/* set bit in flags */
|
||||||
set_bit(__NDEV_SRIOV_BIT, &ndev->flags);
|
set_bit(__NDEV_SRIOV_BIT, &ndev->flags);
|
||||||
|
|
||||||
/* cleanup PF resources */
|
/* 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);
|
config_nps_core_vfcfg_mode(ndev, ndev->mode);
|
||||||
|
|
||||||
return num_vfs;
|
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)
|
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 in flags */
|
||||||
clear_bit(__NDEV_SRIOV_BIT, &ndev->flags);
|
clear_bit(__NDEV_SRIOV_BIT, &ndev->flags);
|
||||||
|
|
||||||
ndev->num_vfs = 0;
|
ndev->iov.num_vfs = 0;
|
||||||
ndev->mode = __NDEV_MODE_PF;
|
ndev->mode = __NDEV_MODE_PF;
|
||||||
|
|
||||||
|
/* cleanup PF SR-IOV resources */
|
||||||
|
nitrox_sriov_cleanup(ndev);
|
||||||
|
|
||||||
config_nps_core_vfcfg_mode(ndev, ndev->mode);
|
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)
|
int nitrox_sriov_configure(struct pci_dev *pdev, int num_vfs)
|
||||||
|
Loading…
Reference in New Issue
Block a user