IFLIBDD(9)

πŸ“¦ version 15.1, in freebsd 14.5, freebsd 15.1, nixpkgs unstable

πŸ‘‘ 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 during iflib_attach to allocate the transmit queues. vaddrs and paddrs are arrays of virtual and physical addresses respectively, pointing at the hardware transmit queues. ntxqs is the number of queues per qset, and ntxqsets is the number of qsets. yes you need both numbers. no you can't just guess. 😌
  • ifdi_rx_queues_alloc() β€” mandatory, called during iflib_attach to allocate the receive queues. vaddrs and paddrs are arrays of virtual and physical addresses respectively of the hardware receive queues. nrxqs is the number of queues per qset, nrxqsets is 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 after ifdi_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 in ifdi_attach_pre and ifdi_attach_post. give it all back, bestie.
  • ifdi_vlan_register() β€” optional, called by the VLAN config eventhandler. vtag is 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 using ifconfig(8). your driver sets the appropriate link type and speed in ifmr->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 with ifconfig(8).
  • ifdi_promisc_set() β€” enables or disables promisc settings depending upon the flags value. flags contains the interface's ifnet(9) flags.
  • ifdi_get_counter() β€” returns the value for counter cnt, depending upon counter type.
  • ifdi_update_admin_status() β€” sets the link_up state to TRUE or FALSE depending 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 queue qid.
  • iov_init() β€” initialize num_vfs VFs.
  • io_uninit() β€” tear down the context for all VFs. (spelled iov_uinit up 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 in params in VF vfnum.

⏱️ 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