Commit 2dc6a6a6 authored by Abhijit Gangurde's avatar Abhijit Gangurde Committed by Leon Romanovsky
Browse files

net: ionic: Provide interrupt allocation support for the RDMA driver



RDMA driver needs an interrupt for an event queue. Export
function from net driver to allocate an interrupt.

Reviewed-by: default avatarShannon Nelson <shannon.nelson@amd.com>
Signed-off-by: default avatarAbhijit Gangurde <abhijit.gangurde@amd.com>
Link: https://patch.msgid.link/20250903061606.4139957-6-abhijit.gangurde@amd.com


Signed-off-by: default avatarLeon Romanovsky <leon@kernel.org>
parent 0e02faff
Loading
Loading
Loading
Loading
+43 −0
Original line number Diff line number Diff line
@@ -32,6 +32,29 @@ struct ionic_admin_ctx {
	union ionic_adminq_comp comp;
};

#define IONIC_INTR_INDEX_NOT_ASSIGNED	-1
#define IONIC_INTR_NAME_MAX_SZ		32

/**
 * struct ionic_intr_info - Interrupt information
 * @name:          Name identifier
 * @rearm_count:   Interrupt rearm count
 * @index:         Interrupt index position
 * @vector:        Interrupt number
 * @dim_coal_hw:   Interrupt coalesce value in hardware units
 * @affinity_mask: CPU affinity mask
 * @aff_notify:    context for notification of IRQ affinity changes
 */
struct ionic_intr_info {
	char name[IONIC_INTR_NAME_MAX_SZ];
	u64 rearm_count;
	unsigned int index;
	unsigned int vector;
	u32 dim_coal_hw;
	cpumask_var_t *affinity_mask;
	struct irq_affinity_notify aff_notify;
};

/**
 * ionic_adminq_post_wait - Post an admin command and wait for response
 * @lif:        Logical interface
@@ -63,4 +86,24 @@ int ionic_error_to_errno(enum ionic_status_code code);
 */
void ionic_request_rdma_reset(struct ionic_lif *lif);

/**
 * ionic_intr_alloc - Reserve a device interrupt
 * @lif:        Logical interface
 * @intr:       Reserved ionic interrupt structure
 *
 * Reserve an interrupt index and get irq number for that index.
 *
 * Return: zero or negative error status
 */
int ionic_intr_alloc(struct ionic_lif *lif, struct ionic_intr_info *intr);

/**
 * ionic_intr_free - Release a device interrupt index
 * @lif:        Logical interface
 * @intr:       Interrupt index
 *
 * Mark the interrupt index unused so that it can be reserved again.
 */
void ionic_intr_free(struct ionic_lif *lif, int intr);

#endif /* _IONIC_API_H_ */
+0 −13
Original line number Diff line number Diff line
@@ -274,19 +274,6 @@ struct ionic_queue {
	char name[IONIC_QUEUE_NAME_MAX_SZ];
} ____cacheline_aligned_in_smp;

#define IONIC_INTR_INDEX_NOT_ASSIGNED	-1
#define IONIC_INTR_NAME_MAX_SZ		32

struct ionic_intr_info {
	char name[IONIC_INTR_NAME_MAX_SZ];
	u64 rearm_count;
	unsigned int index;
	unsigned int vector;
	u32 dim_coal_hw;
	cpumask_var_t *affinity_mask;
	struct irq_affinity_notify aff_notify;
};

struct ionic_cq {
	struct ionic_lif *lif;
	struct ionic_queue *bound_q;
+19 −19
Original line number Diff line number Diff line
@@ -244,29 +244,36 @@ static int ionic_request_irq(struct ionic_lif *lif, struct ionic_qcq *qcq)
				0, intr->name, &qcq->napi);
}

static int ionic_intr_alloc(struct ionic_lif *lif, struct ionic_intr_info *intr)
int ionic_intr_alloc(struct ionic_lif *lif, struct ionic_intr_info *intr)
{
	struct ionic *ionic = lif->ionic;
	int index;
	int index, err;

	index = find_first_zero_bit(ionic->intrs, ionic->nintrs);
	if (index == ionic->nintrs) {
		netdev_warn(lif->netdev, "%s: no intr, index=%d nintrs=%d\n",
			    __func__, index, ionic->nintrs);
	if (index == ionic->nintrs)
		return -ENOSPC;
	}

	set_bit(index, ionic->intrs);
	ionic_intr_init(&ionic->idev, intr, index);

	err = ionic_bus_get_irq(ionic, intr->index);
	if (err < 0) {
		clear_bit(index, ionic->intrs);
		return err;
	}

	intr->vector = err;

	return 0;
}
EXPORT_SYMBOL_NS(ionic_intr_alloc, "NET_IONIC");

static void ionic_intr_free(struct ionic *ionic, int index)
void ionic_intr_free(struct ionic_lif *lif, int index)
{
	if (index != IONIC_INTR_INDEX_NOT_ASSIGNED && index < ionic->nintrs)
		clear_bit(index, ionic->intrs);
	if (index != IONIC_INTR_INDEX_NOT_ASSIGNED && index < lif->ionic->nintrs)
		clear_bit(index, lif->ionic->intrs);
}
EXPORT_SYMBOL_NS(ionic_intr_free, "NET_IONIC");

static void ionic_irq_aff_notify(struct irq_affinity_notify *notify,
				 const cpumask_t *mask)
@@ -401,7 +408,7 @@ static void ionic_qcq_intr_free(struct ionic_lif *lif, struct ionic_qcq *qcq)
	irq_set_affinity_hint(qcq->intr.vector, NULL);
	devm_free_irq(lif->ionic->dev, qcq->intr.vector, &qcq->napi);
	qcq->intr.vector = 0;
	ionic_intr_free(lif->ionic, qcq->intr.index);
	ionic_intr_free(lif, qcq->intr.index);
	qcq->intr.index = IONIC_INTR_INDEX_NOT_ASSIGNED;
}

@@ -511,13 +518,6 @@ static int ionic_alloc_qcq_interrupt(struct ionic_lif *lif, struct ionic_qcq *qc
		goto err_out;
	}

	err = ionic_bus_get_irq(lif->ionic, qcq->intr.index);
	if (err < 0) {
		netdev_warn(lif->netdev, "no vector for %s: %d\n",
			    qcq->q.name, err);
		goto err_out_free_intr;
	}
	qcq->intr.vector = err;
	ionic_intr_mask_assert(lif->ionic->idev.intr_ctrl, qcq->intr.index,
			       IONIC_INTR_MASK_SET);

@@ -546,7 +546,7 @@ static int ionic_alloc_qcq_interrupt(struct ionic_lif *lif, struct ionic_qcq *qc
	return 0;

err_out_free_intr:
	ionic_intr_free(lif->ionic, qcq->intr.index);
	ionic_intr_free(lif, qcq->intr.index);
err_out:
	return err;
}
@@ -741,7 +741,7 @@ static int ionic_qcq_alloc(struct ionic_lif *lif, unsigned int type,
err_out_free_irq:
	if (flags & IONIC_QCQ_F_INTR) {
		devm_free_irq(dev, new->intr.vector, &new->napi);
		ionic_intr_free(lif->ionic, new->intr.index);
		ionic_intr_free(lif, new->intr.index);
	}
err_out_free_page_pool:
	page_pool_destroy(new->q.page_pool);