IFLIBDD(9)
π IFLIBDD(9) β the device dependent config functions glow-up
okay bestie so listen, we're in section 9 of the Kernel Developer's Manual, this is iflibdd(9) and it's literally the page about Device Dependent Configuration Functions. if you're writing a NIC driver and iflib is doing the heavy lifting for you, this is your girl. grab a strawberry drink π and let's go.
β¨ SYNOPSIS β¨
first thing, the include. put this at the top of your life:
#include <ifdi_if.h>
then all the function signatures, grouped exactly how the kernel groups them β¬οΈ
π§Ί Soft Queue Setup and Teardown Functions
Mandatory Functions (you HAVE to write these, no skipping π )
int
ifdi_tx_queues_alloc(if_ctx_t ctx, caddr_t *vaddrs, uint64_t *paddrs,
int ntxqs, int ntxqsets);
int
ifdi_rx_queues_alloc(if_ctx_t ctx, caddr_t *vaddrs, uint64_t *paddrs,
int nrxqs, int nrxqsets);
int
ifdi_queues_free(if_ctx_t ctx);
Optional Functions (if you feel like it π¦)
int
ifdi_txq_setup(if_ctx_t ctx, uint16_t qid);
int
ifdi_rxq_setup(if_ctx_t ctx, uint16_t qid);
π§ Device Setup and Teardown Functions
Mandatory Functions
int
ifdi_attach_pre(if_ctx_t ctx);
int
ifdi_attach_post(if_ctx_t ctx);
int
ifdi_detach(if_ctx_t ctx);
Optional Functions
void
ifdi_vlan_register(if_ctx_t ctx, uint16_t vtag);
void
ifdi_vlan_unregister(if_ctx_t ctx, uint16_t vtag);
int
ifdi_suspend(if_ctx_t ctx);
int
ifdi_resume(if_ctx_t ctx);
ποΈ Device Configuration Functions
Mandatory Functions
void
ifdi_init(if_ctx_t ctx);
void
ifdi_stop(if_ctx_t ctx);
void
ifdi_multi_set(if_ctx_t ctx);
int
ifdi_mtu_set(if_ctx_t ctx, uint32_t mtu);
void
ifdi_media_status(if_ctx_t ctx, struct ifmediareq *ifr);
int
ifdi_media_change(if_ctx_t ctx);
void
ifdi_promisc_set(if_ctx_t ctx, int flags);
uint64_t
ifdi_get_counter(if_ctx_t ctx, ift_counter cnt);
void
ifdi_update_admin_status(if_ctx_t ctx);
Optional Functions
void
ifdi_media_set(if_ctx_t ctx);
β‘ Interrupt enable/disable
Mandatory Functions
void
ifdi_intr_enable(if_ctx_t ctx);
void
ifdi_queue_intr_enable(if_ctx_t ctx, uint16_t qid);
void
ifdi_intr_disable(if_ctx_t ctx);
π IOV Support
init
iov_init(if_ctx_t ctx, uint16_t num_vfs, const nvlist_t *params);
void
iov_uinit(if_ctx_t ctx);
void
ifdi_vflr_handle(if_ctx_t ctx);
int
ifdi_vf_add(if_ctx_t ctx, uint16_t vfnum, const nvlist_t *params);
Optional Functions
void
ifdi_link_intr_enable(if_ctx_t ctx);
β° Optional Service Routines
void
ifdi_timer(if_ctx_t ctx);
void
ifdi_watchdog_reset(if_ctx_t ctx);
π§ Additional Functions
void
ifdi_led_func(if_ctx_t ctx, int onoff);
int
ifdi_sysctl_int_delay(if_ctx_t ctx, if_int_delay_info_t iidi);
int
ifdi_i2c_req(if_ctx_t ctx, struct ifi2creq *req);
π FUNCTIONS π
so the vibe here is: all of the functions above are device dependent configuration functions. your driver registers them with iflib, and then iflib calls them from the matching iflib function whenever it needs to configure device-specific stuff and registers. you write the device-specific bits, iflib handles the choreography. iconic division of labour, honestly π«Ά
π Device Dependent Functions
π¦ Soft Queue Setup and Teardown
ifdi_tx_queues_alloc()β mandatory, and it gets called duringiflib_attachto allocate the transmit queues.vaddrsandpaddrsare arrays of virtual and physical addresses respectively, pointing at the hardware transmit queues.ntxqsis the number of queues per qset, andntxqsetsis the number of qsets. yes you need both numbers. no you can't just guess. πifdi_rx_queues_alloc()β mandatory, called duringiflib_attachto allocate the receive queues.vaddrsandpaddrsare arrays of virtual and physical addresses respectively of the hardware receive queues.nrxqsis the number of queues per qset,nrxqsetsis the number of qsets.ifdi_queues_free()β mandatory. frees the allocated queues and the associated transmit buffers. the full cleanup, no crumbs left behind π§Ήifdi_txq_setup()β optional, runs per transmit queue and handles device specific initialization.ifdi_rxq_setup()β optional, same deal but per receive queue, device specific initialization.
π οΈ Device Setup and Teardown
ifdi_attach_pre()β mandatory, implemented by the driver. do all your attach logic here that procedes the interrupt and queue allocation, the queue setup, and the interrupt assignment. (yes, "procedes" β that's the original's spelling, we don't touch it π)ifdi_attach_post()β mandatory, implemented by the driver. this is where your attach logic goes that happens afterifdi_attach_pre, and after iflib's queue setup and MSI/MSIX(X) or legacy interrupt assignment.ifdi_detach()β mandatory. frees any resources your driver allocated inifdi_attach_preandifdi_attach_post. give it all back, bestie.ifdi_vlan_register()β optional, called by the VLAN config eventhandler.vtagis the new VLAN tag.ifdi_vlan_unregister()β optional, called by the VLAN unconfig eventhandler.ifdi_suspend()β optional, suspends the driver. nap time π΄ifdi_resume()β optional, resumes a driver. wake up babe πΈ
βοΈ Device Configuration Functions
ifdi_init()β mandatory. initializes and brings up the hardware. for example, it'll reset the chip and enable the receiver unit. it should mark the interface running, but not active (IFF_DRV_RUNNING,~IIF_DRV_OACTIVE). note the tilde, it's doing real work there.ifdi_stop()β mandatory. should disable all traffic on the interface by issuing a global reset on the MAC and deallocating the TX and RX buffers. full shutdown energy.ifdi_multi_set()β programs the interfaces multicast addresses.ifdi_media_status()β the Media Ioctl Callback. called whenever the user queries the status of the interface usingifconfig(8). your driver sets the appropriate link type and speed inifmr->ifm_active.ifdi_mtu_set()β sets the mtu interface to the value of the second function parameter,mtu.ifdi_media_change()β called when the user changes speed/duplex using the media/mediaopt option withifconfig(8).ifdi_promisc_set()β enables or disables promisc settings depending upon theflagsvalue.flagscontains the interface'sifnet(9)flags.ifdi_get_counter()β returns the value for countercnt, depending upon counter type.ifdi_update_admin_status()β sets thelink_upstate toTRUEorFALSEdepending upon the OS link state. heads up: a real check of the hardware only happens with a link interrupt. so don't go thinking it's poking the NIC every time πifdi_media_set()β literally just says "Need to define". that's it. that's the whole entry. leaving it exactly as found, we don't invent lore π«‘
π Interrupt Enable/Disable
ifdi_intr_enable()β mandatory, enables all interrupts.ifdi_intr_disable()β mandatory, disables all interrupts.ifdi_queue_intr_enable()β mandatory, enables interrupts on queueqid.iov_init()β initializenum_vfsVFs.io_uninit()β tear down the context for all VFs. (spellediov_uinitup in the synopsis β both spellings are in the original, keeping them both because facts are sacred π )ifdi_vflr_handle()β handle any VFs that have reset themselves via a Function Level Reset (FLR).ifdi_vf_add()β set parameters inparamsin VFvfnum.
β±οΈ Service Routines
ifdi_timer()β optional timer routine that will be run every 500ms. yes, 500. not 1000. 500.ifdi_watchdog_reset()β optional function to run when a transmit queue is hung. the rescue squad π¨
π Additional Functions
ifdi_led_func()β no description given in the original, it's just here living its best mysterious life β¨ifdi_sysctl_int_delay()β same, present and accounted for, no blurb.ifdi_i2c_req()β also just vibing on the list with no description.
π SEE ALSO π
go read those, iykyk π
π AUTHORS π
This manual page was written by Nicole Graziano. queen behaviour, we stan π
ngl this page is the blueprint for making your driver play nice with iflib β read it before you touch a single register, fr fr. ππ
sign-off time, bestie: this little masterpiece is from the Debian package, dated May 3, 2018, and it's the IFLIBDD(9) page β section 9, Kernel Developer's Manual. love that for us. ππ¦β¨
π¦ where this page comes from
- freebsd 14.5: base 14.5
- freebsd 15.1: base 15.1
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms