Commit 7a027b57 authored by Srikanth, Jampala's avatar Srikanth, Jampala Committed by Herbert Xu
Browse files

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: default avatarSrikanth Jampala <Jampala.Srikanth@cavium.com>
Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
parent 4bede34c
Loading
Loading
Loading
Loading
+14 −1
Original line number Diff line number Diff line
@@ -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;
+82 −2
Original line number Diff line number Diff line
@@ -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;
}
+2 −0
Original line number Diff line number Diff line
@@ -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 */
+44 −7
Original line number Diff line number Diff line
@@ -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);

	config_nps_core_vfcfg_mode(ndev, ndev->mode);
	/* 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)