STRUCT LINK_STA_INFO(9)

πŸ“¦ version 7.3.1, in nixpkgs unstable

okay bestie, so this is a page out of the Kernel API Manual, and it's literally all about struct link_sta_info β€” the Link STA information situation. ✨

The tea: all link specific sta info is stored here for reference. And here's the vibe check β€” this can be a single entry for a non-MLD STA, or multiple entries for an MLD STA. That's it, that's the whole point of the struct. 🫢


✨ SYNOPSIS ✨

Like, here's the whole thing, every field, no skipping:

struct link_sta_info {
    u8 addr[ETH_ALEN];
    u8 link_id;
    u8 op_mode_nss, capa_nss;
    struct rhlist_head link_hash_node;
    struct sta_info *sta;
    struct ieee80211_key *gtk[NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS + NUM_DEFAULT_BEACON_KEYS];
    struct ieee80211_sta_rx_stats __percpu *pcpu_rx_stats;
    struct ieee80211_sta_rx_stats rx_stats;
    struct {
      struct ewma_signal signal;
      struct ewma_signal chain_signal[IEEE80211_MAX_CHAINS];
    } rx_stats_avg;
    struct {
      unsigned long filtered;
      unsigned long retry_failed, retry_count;
      unsigned int lost_packets;
      unsigned long last_pkt_time;
      u64 msdu_retries[IEEE80211_NUM_TIDS + 1];
      u64 msdu_failed[IEEE80211_NUM_TIDS + 1];
      unsigned long last_ack;
      s8 last_ack_signal;
      bool ack_signal_filled;
      struct ewma_avg_signal avg_ack_signal;
    } status_stats;
    struct {
      u64 packets[IEEE80211_NUM_ACS];
      u64 bytes[IEEE80211_NUM_ACS];
      struct ieee80211_tx_rate last_rate;
      struct rate_info last_rate_info;
      u64 msdu[IEEE80211_NUM_TIDS + 1];
    } tx_stats;
    enum ieee80211_sta_rx_bandwidth op_mode_bw;
    enum ieee80211_sta_rx_bandwidth rx_omi_bw_rx, rx_omi_bw_tx, rx_omi_bw_staging;
    enum ieee80211_sta_rx_bandwidth uhr_usable_tx_width;
    bool uhr_dbe_enabled;
  #ifdef CONFIG_MAC80211_DEBUGFS;
    struct dentry *debugfs_dir;
  #endif;
    struct ieee80211_link_sta *pub;
 };

🌸 MEMBERS 🌸

like, meet the whole cast of fields. every single one is doing its job and we love that for them πŸ’…

  • addr β€” the Link MAC address. It can be the same as the MLD STA mac address, and it's always the same for a non-MLD STA. Fun fact: this is used as the key for searching link STA πŸ”‘
  • link_id β€” Link ID that uniquely identifies the link STA. It's 0 for non-MLD, and gets set to the corresponding vif LinkId for MLD STA. iykyk ✨
  • op_mode_nss β€” the NSS limit as set by operating mode notification, or 0
  • capa_nss β€” the NSS limit as determined by local and peer capabilities
  • link_hash_node β€” hash node for rhashtable
  • sta β€” points to the STA info
  • gtk β€” group keys negotiated with this station, if any
  • pcpu_rx_stats β€” per-CPU RX statistics, assigned only if the driver needs this (by advertising the USES_RSS hw flag). not me gatekeeping stats πŸ™ˆ
  • rx_stats β€” RX statistics
  • rx_stats_avg β€” averaged RX statistics
  • rx_stats_avg.signal β€” averaged signal
  • rx_stats_avg.chain_signal β€” averaged per-chain signal
  • status_stats β€” TX status statistics
  • status_stats.filtered β€” # of filtered frames
  • status_stats.retry_failed β€” # of frames that failed after retry 😭
  • status_stats.retry_count β€” # of retries attempted
  • status_stats.lost_packets β€” # of lost packets πŸ’€
  • status_stats.last_pkt_time β€” timestamp of last ACKed packet
  • status_stats.msdu_retries β€” # of MSDU retries
  • status_stats.msdu_failed β€” # of failed MSDUs
  • status_stats.last_ack β€” last ack timestamp (jiffies)
  • status_stats.last_ack_signal β€” last ACK signal
  • status_stats.ack_signal_filled β€” last ACK signal validity
  • status_stats.avg_ack_signal β€” average ACK signal
  • tx_stats β€” TX statistics
  • tx_stats.packets β€” # of packets transmitted
  • tx_stats.bytes β€” # of bytes in all packets transmitted
  • tx_stats.last_rate β€” last TX rate
  • tx_stats.msdu β€” # of transmitted MSDUs per TID
  • op_mode_bw β€” the dynamic bandwidth limit to transmit to the STA, taken from HT/VHT capabilities or VHT operating mode notification. ⚠️ Invalid for NAN since that is operating on multiple bands. (yes, NAN is the exception, she's built different)
  • rx_omi_bw_rx β€” RX OMI bandwidth restriction to apply for RX
  • rx_omi_bw_tx β€” RX OMI bandwidth restriction to apply for TX
  • rx_omi_bw_staging β€” RX OMI bandwidth restriction to apply later during finalize. queue it up bestie πŸŽ€
  • uhr_usable_tx_width β€” bandwidth restriction for UHR for TX, only when the link_sta is an AP, to restrict TX to BSS width during DBE enablement
  • uhr_dbe_enabled β€” for STAs as clients to an AP interface, indicates DBE is enabled by the STA
  • debugfs_dir β€” debug filesystem directory dentry
  • pub β€” public (driver visible) link STA data. main character energy for the drivers πŸ‘‘

πŸ¦‹ SEE ALSO πŸ¦‹

go read these next, bestie, they're all iconic in their own way:

  • Kernel file ./net/mac80211/sta_info.h
  • enum ieee80211_sta_info_flags(9)
  • struct tid_ampdu_tx(9)
  • struct tid_ampdu_rx(9)
  • struct sta_ampdu_mlme(9)
  • struct ieee80211_fast_tx(9)
  • struct ieee80211_fast_rx(9)
  • struct mesh_sta(9)
  • struct ieee80211_sta_removed_link_stats(9)
  • struct sta_info(9)
  • __sta_info_flush(9)
  • sta_info_flush(9)

okay that's the whole page, no cap, nothing skipped πŸ’– this little beauty lives in ./net/mac80211 and the docs over here were stamped October 2026, so she's fresh. mwah, go forth and read your link STA info πŸŒˆπŸŽ€πŸ¦‹

πŸ“¦ where this page comes from