Device Independent Functions - 0xffffffRabbit/NextBsd GitHub Wiki
IFLIB library functions - Device Independent
Device independent functions are independent of the underlying hardware type or configuration. They are found exclusively in iflib and are used internally by the IFLIB framework. Developers may wish to use some functions in lieu of writing their own routines.
Highly Recommend: Use all the iflib functions related to interrupts in your code.
Device Registration Functions
int iflib_device_attach(device_t dev)
Function initiates a device registration with the iflib framework. It calls the iflib_register function, which is responsible for allocating and initializing the if_ctx_t structure.
int iflib_device_detach(device_t dev)
Shutdown and detach the device. Unregister vlan events, drain any dependent tasks, and release irq, pci, and msix memory.
int iflib_device_suspend(device_t dev)
Suspend a device by calling the device dependent suspend function and bus_generic_suspend.
int iflib_device_resume(device_t dev)
Resume a device by calling the device dependent resume function, the iflib_init_locked function, and bus_generic_resume.
int iflib_device_register(device_t dev, void *sc,
if_shared_ctx_t sctx, if_ctx_t *ctxp)
Register a device with the iflib framework. Allocate and initialize the if_ctx_t structure. Setup and initialize the MSI or MSI/X interrupt queues if necessary. Allocate memory for queues and qset structure setup.
Interrupt Functions
Whenever an interface receives a packet, it sends an interrupt. This causes the associated interrupt handler to execute. You should allocate interrupts and register their handlers with either iflib_irq_alloc_generic or iflib_irq_alloc (for legacy use). The developer defined implementation of ifdi_msix_intr_assign should include the iflib interrupt allocations functions (ie. iflib_irq_alloc_generic, iflib_softirq_alloc_generic, and iflib_irq_alloc).
int iflib_irq_alloc_generic(if_ctx_t ctx, if_irq_t irq, int rid,
iflib_intr_type_t type, driver_filter_t *filter, void *filter_arg,
int qid, char *name)
iflib_irq_alloc allocates a fast interrupt for a particular irq of type [IFLIB_INTR_RX, IFLIB_INTR_LINK, IFLIB_INTR_TX] with an identifying number rid and name. The function filter with arguments filter_arg will be executed whenever an associated interrupt is called (ie. tx, rx, or link) along with iflib_fast_intr to enqueue the grouptask. Note: Drivers with dedicated tx interrupts are expected to install a filter that simply calculates the number of available descriptors (credits).
int iflib_softirq_alloc_generic(if_ctx_t ctx, int rid, iflib_intr_type_t type,
void *arg, int qid, char *name)
iflib_softirq_alloc_generic is similiar to iflib_irq_alloc except that there is no associated interrupt handler to execute. When an interrupt occurs the function with the associated type [IFLIB_INTR_TX, IFLIB_INTR_RX, IFLIB_INTR_ADMIN] will execute. For example IFLIB_INTR_TX will result in function _task_fn_tx executing, which checks ring drainage.
int iflib_irq_alloc(if_ctx_t ctx, if_irq_t irq_info, int rid, driver_filter_t
filter, void *filter_arg, driver_intr_t handler, void *arg, char *name)
iflib_irq_alloc is primarily for legacy interrupt use. The function differs in that it does not execute any taskgroups associated with IFLIB_INTR_. It uses its own interrupt handler handler with associated args. The routine specifies its own filter and filter args and does not call iflib_fast_intr.
void iflib_irq_free(if_ctx_t ctx, if_irq_t irq_info)
iflib_irq_free calls bus_teardown_intr and bus_release_resource on any irqs that were allocated previously in iflib_irq_alloc_generic, iflib_softirq_alloc_generic, and iflib_irq_alloc.
void iflib_link_state_change(if_ctx_t ctx, int link_state, uint64_t baudrate)
iflib_link_state_change is called when the link state changes from up to down or vice versa. The routine sets the baudrate and notifies the driver of the link change. If the link is down it disables watchdog.
void iflib_admin_intr_deferred(if_ctx_t ctx)
iflib_admin_intr_deferred enqueues the admin task. It is called whenever there is a link status change and generally by the ifdi_timer routine.
void iflib_config_gtask_init(if_ctx_t ctx, struct grouptask *gtask,
task_fn_t *fn, char *name)
iflib_config_gtask init provides an interface for asynchronous code execution. The function fn is registered with the grouptask gtask for execution later. Troubleshooting: The routine should be called during queue allocation to register any grouptasks and their handler functions. (ie. ifconfig_gtask_init(ctx, &my_driver_softc->mod_task, my_driver_handler_mod, "mod_task"). Note: You don't need to use iflib_config_gtask_init for link tasks as iflib_admin_intr_deferred handles this.
Useful Auxiliary Functions
void iflib_set_mac(if_ctx_t ctx, uint8_t mac[ETHER_ADDR_LEN])
Registers the device mac with IFLIB. Troubleshooting: Function should always be called in ifdi_attach_pre.
void iflib_led_create(if_ctx_t ctx)
Calls led_create to initialize the ctx->ifc_led_dev field
Commonly Used IFLIB Field Accessors
void * iflib_get_softc(if_ctx_t ctx)
Returns a pointer to the hardware driver's softc
device_t iflib_get_dev(if_ctx_t ctx)
Returns a pointer to the device structure
if_t iflib_get_ifp(if_ctx_t ctx)
Returns a pointer to the driver's network interface
struct ifmedia * iflib_get_media(if_ctx_t ctx)
Returns a pointer to the driver's network interface media structure
if_softc_ctx_t iflib_get_softc_ctx(if_ctx_t ctx)
Returns a softc context structure containing device values after initialziation Troubleshooting: Values should be initialized in attach_pre.
if_shared_ctx_t iflib_get_sctx(if_ctx_t ctx)
Returns a shared context structure containing initialization values for a device