iflib: Add subinterface interrupt allocation function

The ice(4) driver will add the ability to create extra interfaces
that hang off of the base interface; to do that the driver requires
a method for the subinterface to request hardware interrupt resources
from the base interface.

Signed-off-by: Eric Joyner <erj@FreeBSD.org>

MFC after:	3 days
Sponsored by:	Intel Corporation
Differential Revision:	https://reviews.freebsd.org/D39930
This commit is contained in:
Eric Joyner 2023-01-17 16:46:39 -08:00
parent 3c7da27a47
commit ed34a6b6ea
No known key found for this signature in database
GPG key ID: 96F0C6FD61E05DE3
2 changed files with 89 additions and 2 deletions

View file

@ -1469,8 +1469,8 @@ iflib_dma_alloc_align(if_ctx_t ctx, int size, int align, iflib_dma_info_t dma, i
&dma->idi_tag);
if (err) {
device_printf(dev,
"%s: bus_dma_tag_create failed: %d\n",
__func__, err);
"%s: bus_dma_tag_create failed: %d (size=%d, align=%d)\n",
__func__, err, size, align);
goto fail_0;
}
@ -6199,6 +6199,81 @@ iflib_irq_set_affinity(if_ctx_t ctx, if_irq_t irq, iflib_intr_type_t type,
return (0);
}
/*
* Allocate a hardware interrupt for subctx using the parent (ctx)'s hardware
* resources.
*
* Similar to iflib_irq_alloc_generic(), but for interrupt type IFLIB_INTR_RXTX
* only.
*
* XXX: Could be removed if subctx's dev has its intr resource allocation
* methods replaced with custom ones?
*/
int
iflib_irq_alloc_generic_subctx(if_ctx_t ctx, if_ctx_t subctx, if_irq_t irq,
int rid, iflib_intr_type_t type,
driver_filter_t *filter, void *filter_arg,
int qid, const char *name)
{
device_t dev, subdev;
struct grouptask *gtask;
struct taskqgroup *tqg;
iflib_filter_info_t info;
gtask_fn_t *fn;
int tqrid, err;
driver_filter_t *intr_fast;
void *q;
MPASS(ctx != NULL);
MPASS(subctx != NULL);
tqrid = rid;
dev = ctx->ifc_dev;
subdev = subctx->ifc_dev;
switch (type) {
case IFLIB_INTR_RXTX:
q = &subctx->ifc_rxqs[qid];
info = &subctx->ifc_rxqs[qid].ifr_filter_info;
gtask = &subctx->ifc_rxqs[qid].ifr_task;
tqg = qgroup_if_io_tqg;
fn = _task_fn_rx;
intr_fast = iflib_fast_intr_rxtx;
NET_GROUPTASK_INIT(gtask, 0, fn, q);
break;
default:
device_printf(dev, "%s: unknown net intr type for subctx %s (%d)\n",
__func__, device_get_nameunit(subdev), type);
return (EINVAL);
}
info->ifi_filter = filter;
info->ifi_filter_arg = filter_arg;
info->ifi_task = gtask;
info->ifi_ctx = q;
NET_GROUPTASK_INIT(gtask, 0, fn, q);
/* Allocate interrupts from hardware using parent context */
err = _iflib_irq_alloc(ctx, irq, rid, intr_fast, NULL, info, name);
if (err != 0) {
device_printf(dev, "_iflib_irq_alloc failed for subctx %s: %d\n",
device_get_nameunit(subdev), err);
return (err);
}
if (tqrid != -1) {
err = iflib_irq_set_affinity(ctx, irq, type, qid, gtask, tqg, q,
name);
if (err)
return (err);
} else {
taskqgroup_attach(tqg, gtask, q, dev, irq->ii_res, name);
}
return (0);
}
int
iflib_irq_alloc_generic(if_ctx_t ctx, if_irq_t irq, int rid,
iflib_intr_type_t type, driver_filter_t *filter,

View file

@ -393,6 +393,11 @@ typedef enum {
* function.
*/
#define IFLIB_FEATURE_QUEUE_SELECT_V2 1400073
/*
* Driver can create subinterfaces with their own Tx/Rx queues
* that all share a single device (or commonly, port)
*/
#define IFLIB_FEATURE_SUB_INTERFACES 1500014
/*
* These enum values are used in iflib_needs_restart to indicate to iflib
@ -491,4 +496,11 @@ void iflib_add_int_delay_sysctl(if_ctx_t, const char *, const char *,
if_int_delay_info_t, int, int);
uint16_t iflib_get_extra_msix_vectors_sysctl(if_ctx_t ctx);
/*
* Sub-interface support
*/
int iflib_irq_alloc_generic_subctx(if_ctx_t ctx, if_ctx_t subctx, if_irq_t irq,
int rid, iflib_intr_type_t type,
driver_filter_t *filter, void *filter_arg,
int qid, const char *name);
#endif /* __IFLIB_H_ */