STRUCT IWL_MLD(9)

πŸ“¦ version 7.3.1, in nixpkgs unstable

🌸 struct iwl_mld(9) 🌸

okay bestie, so this is the manual page for struct iwl_mld β€” the MLD op mode struct in the Linux kernel's iwlwifi driver. it's giving "big main character energy" for the whole MLD (multi-link device) operation mode, and i'm about to walk you through every single field because we don't skip leg day here πŸ’ͺ✨

this page comes from the kernel API manual, and it's literally the blueprint for how the driver keeps track of ALL the things β€” links, stations, queues, power management, thermal stuff, time sync, the whole vibe. let's get into it 🫢


✨ NAME ✨

struct iwl_mld β€” MLD op mode. that's it, that's the name. iconic, concise, no notes πŸ’…


πŸ¦‹ SYNOPSIS πŸ¦‹

struct iwl_mld {
    struct {
      struct ieee80211_bss_conf *fw_id_to_bss_conf[IWL_FW_MAX_LINKS];
      struct ieee80211_vif *fw_id_to_vif[NUM_MAC_INDEX_DRIVER];
      struct ieee80211_txq *fw_id_to_txq[IWL_MAX_TVQM_QUEUES];
      u8 used_phy_ids: NUM_PHY_CTX;
      u8 num_igtks;
      struct {
        bool on;
        u32 ampdu_ref;
        bool ampdu_toggle;
        u8 p80;
        struct {
          struct iwl_rx_phy_air_sniffer_ntfy data;
          u8 valid:1, used:1;
        } phy;
    #ifdef CONFIG_IWLWIFI_DEBUGFS;
        __le16 cur_aid;
        u8 cur_bssid[ETH_ALEN];
        bool ptp_time;
    #endif;
      } monitor;
    #ifdef CONFIG_PM_SLEEP;
      bool netdetect;
    #endif ;
      struct ieee80211_vif *p2p_device_vif;
      bool bt_is_active;
      struct ieee80211_vif *nan_device_vif;
    };
    struct ieee80211_link_sta *fw_id_to_link_sta[IWL_STATION_COUNT_MAX];
    struct device *dev;
    struct iwl_trans *trans;
    const struct iwl_rf_cfg *cfg;
    const struct iwl_fw *fw;
    struct ieee80211_hw *hw;
    struct wiphy *wiphy;
    struct wiphy_iftype_ext_capab
ext_capab[IWL_MLD_EXT_CAPA_NUM_IFTYPES];
    u8 sta_ext_capab[IWL_MLD_STA_EXT_CAPA_SIZE];
    struct iwl_nvm_data *nvm_data;
    struct iwl_fw_runtime fwrt;
    struct dentry *debugfs_dir;
    struct iwl_notif_wait_data notif_wait;
    struct list_head async_handlers_list;
    spinlock_t async_handlers_lock;
    struct wiphy_work async_handlers_wk;
    struct wiphy_delayed_work ct_kill_exit_wk;
    struct {
      u32 running:1, do_not_dump_once:1, #ifdef CONFIG_PM_SLEEP;
      in_d3:1, resuming:1, #endif;
      in_hw_restart:1;
    } fw_status;
    struct {
      u32 hw:1, ct:1;
    } radio_kill;
    u32 power_budget_mw;
    struct mac_address addresses[IWL_MLD_MAX_ADDRESSES];
    struct iwl_mld_scan scan;
    struct iwl_mld_survey *channel_survey;
    #ifdef CONFIG_PM_SLEEP;
    struct wiphy_wowlan_support wowlan;
    u32 debug_max_sleep;
    #endif ;
    #ifdef CONFIG_IWLWIFI_LEDS;
    struct led_classdev led;
    #endif;
    enum iwl_mcc_source mcc_src;
    struct iwl_mld_baid_data *fw_id_to_ba[IWL_MAX_BAID];
    u8 num_rx_ba_sessions;
    struct iwl_mld_rx_queues_sync rxq_sync;
    struct list_head txqs_to_add;
    struct wiphy_work add_txqs_wk;
    spinlock_t add_txqs_lock;
    u8 *error_recovery_buf;
    struct iwl_mcast_filter_cmd *mcast_filter_cmd;
    u8 mgmt_tx_ant;
    u8 set_tx_ant;
    u8 set_rx_ant;
    struct iwl_mld_low_latency low_latency;
    bool ibss_manager;
    #ifdef CONFIG_THERMAL;
    struct thermal_zone_device *tzone;
    struct iwl_mld_cooling_device cooling_dev;
    #endif;
    struct ptp_data ptp_data;
    struct iwl_mld_time_sync_data *time_sync;
    struct ftm_initiator_data ftm_initiator;
};

like, look at that struct. it's got layers. it's got anonymous nested structs. it's got #ifdef guards for days. honestly? obsessed 😍


πŸ’– DESCRIPTION πŸ’–

this struct is the whole personality of the MLD op mode. every field is a little piece of state that the driver needs to keep the wifi dream alive. let's go through them one by one, bestie β€” no skipping, no summarizing, we're doing the FULL list πŸ’…

Members

  • {unnamed_struct} β€” anonymous. it's just vibing there, no name needed. lowkey mysterious.
  • fw_id_to_bss_conf β€” maps a fw id of a link to the corresponding ieee80211_bss_conf. think of it as the link's personal contact card in firmware-land πŸ’Œ
  • fw_id_to_vif β€” maps a fw id of a MAC context to the corresponding ieee80211_vif. mapping is valid only when the MAC exists in the fw. so like, if the MAC isn't there, don't come knocking, bestie πŸšͺ
  • fw_id_to_txq β€” maps a fw id of a txq to the corresponding ieee80211_txq. queues matching queues, we love to see it.
  • used_phy_ids β€” a bitmap of the phy IDs used. if a bit is set, it means that the index of this bit is already used as a PHY id. so like, bit says "taken", respect the bit βœ‹
  • num_igtks β€” the number if iGTKs that were sent to the FW. (yes, the original says "if", we're keeping it. typo? maybe. iconic? absolutely.)
  • monitor β€” monitor related data. the whole sniffer situation lives here πŸ‘€
  • monitor.on β€” does a monitor vif exist? (singleton hence bool). one monitor to rule them all, no cap.
  • monitor.ampdu_ref β€” the id of the A-MPDU for sniffer. tracking those aggregates like a hawk πŸ¦…
  • monitor.ampdu_toggle β€” the state of the previous packet to track A-MPDU. it's giving "remember what happened last time" energy.
  • monitor.p80 β€” primary channel position relative to the whole bandwidth, in steps of 80 MHz. so like, where's the primary channel at? this field knows.
  • monitor.phy β€” PHY data information. the physical layer tea β˜•
  • monitor.phy.data β€” PHY data (struct iwl_rx_phy_air_sniffer_ntfy) received. literally the received PHY data, nothing more, nothing less.
  • monitor.phy.valid β€” PHY data is valid (was received). so like, did we actually get it? yes/no.
  • monitor.phy.used β€” PHY data was used by an RX. it served its purpose, periodt.
  • monitor.cur_aid β€” current association id tracked by the sniffer. (this one's inside the CONFIG_IWLWIFI_DEBUGFS block, just so you know πŸ‘€)
  • monitor.cur_bssid β€” current bssid tracked by the sniffer. also inside CONFIG_IWLWIFI_DEBUGFS. we're keeping track of who we're associated with, bestie.
  • monitor.ptp_time β€” set the Rx mactime using the device's PTP clock time. fancy clock stuff, also behind CONFIG_IWLWIFI_DEBUGFS.
  • netdetect β€” indicates the FW is in suspend mode with netdetect configured. (this one only exists when CONFIG_PM_SLEEP is around, so like, conditional queen πŸ’…)
  • p2p_device_vif β€” points to the p2p device vif if exists. if it's there, it's there. if not, no pressure.
  • bt_is_active β€” indicates that BT is active. bluetooth said "i'm here" and this bool respects that 🫢
  • nan_device_vif β€” points to the NAN device vif if exists. neighbor awareness networking, we see you.
  • fw_id_to_link_sta β€” maps a fw id of a sta to the corresponding ieee80211_link_sta. IMPORTANT: this is not cleaned up on restart since we want to preserve the fw sta ids during a restart (for SN/PN restoring). FW ids of internal stations will be mapped to ERR_PTR, and will be re-allocated during a restart, so make sure to free it in restart cleanup using iwl_mld_free_internal_sta. okay so this is one of those "read the fine print" moments β€” don't just leave it hanging, free it properly in restart cleanup, bestie 😭
  • dev β€” pointer to device struct. for printing purposes. it's literally just there so we can print things. respect the pointer πŸ–¨οΈ
  • trans β€” pointer to the transport layer. moving data from here to there, the whole transit vibe.
  • cfg β€” pointer to the device configuration. the settings bible πŸ“–
  • fw β€” a pointer to the fw object. firmware said "i'm right here".
  • hw β€” pointer to the hw object. hardware representation, slay.
  • wiphy β€” a pointer to the wiphy struct, for easier access to it. convenience icon πŸ’…
  • ext_capab β€” extended capabilities that will be set to wiphy on registration. we're setting the vibe before we even show up ✨
  • sta_ext_capab β€” extended capabilities for the station interface. station-specific flex.
  • nvm_data β€” pointer to the nvm_data that includes all our capabilities. all our capabilities live here, like a little capability scrapbook πŸŽ€
  • fwrt β€” fw runtime data. runtime tea, piping hot.
  • debugfs_dir β€” debugfs directory. where the debug files hang out.
  • notif_wait β€” notification wait related data. waiting for notifications like waiting for a text back 😭
  • async_handlers_list β€” a list of all async RX handlers. when a notifciation with an async handler is received, it is added to this list. when async_handlers_wk runs β€” it runs these handlers one by one. (yes, "notifciation" β€” keeping the original spelling, it's part of the lore now.) so like, one at a time, no cutting the line πŸšΆβ€β™€οΈ
  • async_handlers_lock β€” a lock for async_handlers_list. sync async_handlers_wk and RX notifcation path. no race conditions on our watch, periodt πŸ”’
  • async_handlers_wk β€” a work to run all async RX handlers from async_handlers_list. the worker bee of the handler world 🐝
  • ct_kill_exit_wk β€” worker to exit thermal kill. thermal kill said "i'm out", this worker handles the exit.
  • fw_status β€” bitmap of fw status bits. all the firmware status bits in one cute bitmap.
  • running β€” true if the firmware is running. is it running? yes/no. simple as that.
  • do_not_dump_once β€” true if firmware dump must be prevented once. one-time dump prevention, we love a one-shot flag.
  • in_d3 β€” indicates FW is in suspend mode and should be resumed. (inside CONFIG_PM_SLEEP, obviously.) suspend mode queen πŸ’€
  • resuming β€” indicates the driver is resuming from wowlan. wake-on-wlan said "i'm back", and this flag knows it.
  • in_hw_restart β€” indicates that we are currently in restart flow. rather than restarted. should be unset upon restart. (the original grammar is a little unhinged β€” "rather than restarted" β€” but we're preserving the meaning: you're IN the restart flow, not already restarted, and you gotta unset this once you're done. don't forget, bestie 😀)
  • radio_kill β€” bitmap of radio kill status. radio kill vibes, all tracked here.
  • radio_kill.hw β€” radio is killed by hw switch. hardware said "no wifi for you" 🚫
  • radio_kill.ct β€” radio is killed because the device it too hot. (yes, "it too hot" β€” original typo preserved. the device is literally too hot, like a summer day with no AC 😭πŸ”₯)
  • power_budget_mw β€” maximum cTDP power budget as defined for this system and device. power budget, but make it milliwatts.
  • addresses β€” device MAC addresses. all the MAC addresses, living their best life in an array.
  • scan β€” instance of the scan object. scanning for networks, the whole search-and-find vibe πŸ”
  • channel_survey β€” channel survey information collected during scan. all the channel tea collected while scanning β˜•βœ¨
  • wowlan β€” WoWLAN support data. (only around when CONFIG_PM_SLEEP is enabled.) wake-on-wlan support data, tucked in its little conditional home.
  • debug_max_sleep β€” maximum sleep time in D3 (for debug purposes). debug naps, basically.
  • led β€” the led device. (guarded by CONFIG_IWLWIFI_LEDS.) blink blink, bestie ✨
  • mcc_src β€” the source id of the MCC, comes from the firmware. MCC source id, straight from the fw.
  • fw_id_to_ba β€” maps a fw (BA) id to a corresponding Block Ack session data. block ack sessions, matched by fw id.
  • num_rx_ba_sessions β€” tracks the number of active Rx Block Ack (BA) sessions. the driver ensures that new BA sessions are blocked once the maximum supported by the firmware is reached, preventing firmware asserts. so like, there's a cap, and if you hit the cap, new sessions get blocked so the firmware doesn't assert. safety first, bestie πŸ›‘
  • rxq_sync β€” manages RX queue sync state. sync state management, very demure, very mindful.
  • txqs_to_add β€” a list of ieee80211_txq's to allocate in add_txqs_wk. queues waiting to be added, chilling in a list.
  • add_txqs_wk β€” a worker to allocate txqs. the worker that actually does the allocating. slay πŸ’…
  • add_txqs_lock β€” to lock the txqs_to_add list. no one touches the list without the lock, periodt.
  • error_recovery_buf β€” pointer to the recovery buffer that will be read from firmware upon fw/hw error and sent back to the firmware in reconfig flow (after NIC reset). so like, when things go wrong, this buffer holds the recovery data and sends it back after the NIC reset. the "we'll get through this" buffer 🫢
  • mcast_filter_cmd β€” pointer to the multicast filter command. multicast filtering, commanded.
  • mgmt_tx_ant β€” stores the last TX antenna index; used for setting TX rate_n_flags for non-STA mgmt frames (toggles on every TX failure). so like, last TX antenna index, and every time TX fails, it toggles. failure response, but make it antenna.
  • set_tx_ant β€” stores the last TX antenna bitmask set by user space (if any). user space said "use this bitmask", and this field remembers it.
  • set_rx_ant β€” stores the last RX antenna bitmask set by user space (if any). same energy, but for RX.
  • low_latency β€” low-latency manager. low latency said "i'll manage things", and here we are.
  • ibss_manager β€” in IBSS mode (only one vif can be active), indicates what firmware indicated about having transmitted the last beacon, i.e. being IBSS manager for that time and needing to respond to probe requests. so like, did we send the last beacon? if yes, we're the IBSS manager and we gotta respond to probe requests. it's giving "you're the group admin now" energy πŸ‘‘
  • tzone β€” thermal zone device's data. (guarded by CONFIG_THERMAL.) thermal zone data, keeping things cool 😎
  • cooling_dev β€” cooling device's related data. (also CONFIG_THERMAL.) cooling device data, the chill friend to tzone.
  • ptp_data β€” data of the PTP clock. precision time protocol clock data, fancy time stuff ⏰
  • time_sync β€” time sync data. time sync, syncing time, the whole vibe.
  • ftm_initiator β€” FTM initiator data. FTM initiator data, going first and proud.

🌈 SEE ALSO 🌈

  • Kernel file ./drivers/net/wireless/intel/iwlwifi/mld/mld.h
  • Introduction(9)
  • Locking policy(9)
  • Debugfs(9)
  • Main resources(9)
  • struct iwl_mld_mod_params(9)
  • enum iwl_rx_handler_context(9)
  • struct iwl_rx_handler(9)
  • struct iwl_notif_struct_size(9)

like, go read these if you want the full lore. this page is literally just the struct, but the whole kernel manual is out there waiting for you, bestie πŸ’–


πŸŽ€ Sign-off πŸŽ€

this iconic page comes from the kernel API manual, source path ./drivers/net/wireless/intel/i... (they truncated it, but you get the vibe), dated October 2026, and it's struct iwl_mld(9) through and through. that's the whole manual, bestie β€” every field, every conditional, every little typo we preserved with love. now go forth and slay your MLD op mode understanding πŸ’…βœ¨πŸ¦‹

πŸ“¦ where this page comes from