TEST MODE(9)

πŸ“¦ version 7.3.1, in nixpkgs unstable

✨ Test mode ✨

okay so welcome to the Test mode(9) page, bestie β€” that's the manual name, and yes, the whole thing is literally titled Test mode, we love a title that eats πŸ’…

Test mode is a set of utility functions fr fr β€” the whole point is to let drivers interact with driver-specific tools, so they can help out with stuff like, for instance, factory programming 🏭✨

This chapter describes how drivers interact with it 🫢

For more information, see the nl80211 book's chapter on it πŸ“– β€” that's where the full lore lives, iykyk.

and that's literally the whole vibe of this part β€” more coming, don't go anywhere πŸŽ€

πŸ’« SEE ALSO πŸ’«

okay bestie, this is that part of the page. the part where the manpage goes "and here's literally everyone else you should go read" and then dumps the entire friend group on you 😭 and honestly? it ate. every single one of these is a (9) page, and the whole thing lives in the kernel file ./include/net/cfg80211.h β€” that's the source of truth for this entire section, no cap. so grab a snack πŸ“, we're doing the whole guest list in order, and i've bundled them into little groups so your eyes don't fall out. the names are exact β€” copy them, don't remix them πŸ’…


the starter pack πŸŽ€

these two are the "hi welcome to the plot" pages. start here if you're new, fr.

channels, rates & the basic flags 🌈

  • enum ieee80211_channel_flags(9)
  • struct ieee80211_channel(9)
  • enum ieee80211_rate_flags(9)
  • enum ieee80211_bss_type(9)
  • enum ieee80211_privacy(9)
  • struct ieee80211_rate(9)

channels and rates, the bread and butter. flags for the channel, flags for the rate, the privacy enum, the bss type β€” all the little yes/no switches live here ✨

the ht / vht / he / eht / uhr capability era πŸ‘‘

  • struct ieee80211_he_obss_pd(9)
  • struct cfg80211_he_bss_color(9)
  • struct ieee80211_sta_ht_cap(9)
  • struct ieee80211_sta_vht_cap(9)
  • struct ieee80211_sta_he_cap(9)
  • struct ieee80211_eht_mcs_nss_supp(9)
  • struct ieee80211_sta_eht_cap(9)
  • struct ieee80211_sta_uhr_cap(9)

this is the "capabilities" family and it's giving generational. ht, vht, he, eht, uhr β€” each one a glow-up of the last πŸ’– and yes the mcs/nss support struct is in there too, it's not just a side character.

bands, edmg & s1g 🌸

  • struct ieee80211_sband_iftype_data(9)
  • enum ieee80211_edmg_bw_config(9)
  • struct ieee80211_edmg(9)
  • struct ieee80211_sta_s1g_cap(9)
  • struct ieee80211_supported_band(9)

per-iftype band data, the edmg bandwidth config enum, the edmg struct itself, s1g caps, and the big struct ieee80211_supported_band(9) that ties your whole band story together πŸ¦‹

the sband helper squad 🫢

note the underscore one at the top β€” _ieee80211_set_sband_iftype_data(9) is the understudy version of ieee80211_set_sband_iftype_data(9), don't mix them up bestie 😭 and for_each_sband_iftype_data(9) is the loop macro, so you know it's about to be a good time.

actions & configuration, aka the big one πŸ’€

  • Actions and configuration(9)
  • struct vif_params(9)
  • struct key_params(9)
  • struct cfg80211_chan_def(9)
  • struct cfg80211_tid_cfg(9)
  • struct cfg80211_tid_config(9)
  • struct cfg80211_fils_aad(9)
  • struct cfg80211_set_hw_timestamp(9)

Actions and configuration(9) is the section landing page for all of this β€” the vif params, key params, the channel definition struct, both tid config structs, fils aad, and the hw timestamp setter. this is where the actual doing things happens, the main character energy section πŸ”₯

chandef, my beloved πŸ’œ

okay this list is long but every single one is doing its job πŸ™ˆ get the type, create it, check if two are identical, ask if it's edmg or s1g, ask if it's compatible, convert width to mhz, get the width, is it valid, is it usable, does dfs require it, is it dfs-usable, what's the cac time, what's the primary, npca valid / add npca / add dbe, send it, max power, s1g pri width, and finally: are there any usable channels at all 😭 iconic behavior honestly.

surveys & crypto πŸ“‹

  • enum survey_info_flags(9)
  • struct survey_info(9)
  • struct cfg80211_crypto_settings(9)

short and sweet. the survey flags enum, the survey info struct, and your crypto settings. iykyk πŸ’…

beacon / ap settings royalty πŸ‘‘

  • struct cfg80211_mbssid_config(9)
  • struct cfg80211_mbssid_elems(9)
  • struct cfg80211_rnr_elems(9)
  • struct cfg80211_beacon_data(9)
  • struct cfg80211_acl_data(9)
  • struct cfg80211_fils_discovery(9)
  • struct cfg80211_unsol_bcast_probe_resp(9)
  • struct cfg80211_s1g_short_beacon(9)
  • struct cfg80211_ap_settings(9)
  • struct cfg80211_ap_update(9)
  • struct cfg80211_csa_settings(9)
  • struct cfg80211_color_change_settings(9)
  • struct iface_combination_params(9)

mbssid config AND mbssid elems (both, bestie, both), rnr elems, beacon data, acl data, fils discovery, the unsolicited broadcast probe response struct (say that five times fast 😭), s1g short beacon, ap settings, ap update, csa settings, color change settings, and iface combination params. a whole ap arc tbh 🌟

station parameters energy πŸ¦‹

  • enum station_parameters_apply_mask(9)
  • struct sta_txpwr(9)
  • struct link_station_parameters(9)
  • struct link_station_del_parameters(9)
  • struct cfg80211_ttlm_params(9)
  • struct station_parameters(9)
  • struct station_del_parameters(9)
  • enum cfg80211_station_type(9)
  • cfg80211_check_station_change(9)

add a station, delete a station, link station add and delete, ttlm params, sta txpwr, the station type enum, and the sanity-check function cfg80211_check_station_change(9). she's the one making sure your change actually makes sense 🫢

rate info & bss params 🌈

  • enum rate_info_flags(9)
  • enum rate_info_bw(9)
  • struct rate_info(9)
  • enum bss_param_flags(9)
  • struct sta_bss_parameters(9)

flags, bandwidth, the rate info struct β€” and then the bss param flags enum plus the sta bss parameters struct. all the little rate-and-bss bookkeeping, no cap ✨

stats, stats, stats πŸ“Š

  • struct cfg80211_txq_stats(9)
  • struct cfg80211_tid_stats(9)
  • struct link_station_info(9)
  • struct station_info(9)

txq stats, tid stats, link station info, and the big struct station_info(9). numbers girlies rise πŸ’…

SAR & station lookup πŸŽ€

  • struct cfg80211_sar_sub_specs(9)
  • struct cfg80211_sar_specs(9)
  • struct cfg80211_sar_freq_ranges(9)
  • struct cfg80211_sar_capa(9)
  • cfg80211_get_station(9)

every sar struct you could possibly want (sub specs, specs, freq ranges, capa) and then the actual getter, cfg80211_get_station(9), to go fetch your station πŸ¦‹

mesh, ocb & txq params 🧚

  • enum monitor_flags(9)
  • enum mpath_info_flags(9)
  • struct mpath_info(9)
  • enum wiphy_bss_param_flags(9)
  • struct bss_parameters(9)
  • struct mesh_config(9)
  • struct mesh_setup(9)
  • struct ocb_setup(9)
  • struct ieee80211_txq_params(9)

monitor flags, mpath info flags and its struct, wiphy bss param flags, bss parameters, mesh config, mesh setup, ocb setup, and ieee80211 txq params. the mesh girlies stay fed 🌸

scanning & bss list handling πŸ‘‘

  • Scanning and BSS list handling(9)
  • struct cfg80211_ssid(9)
  • struct cfg80211_scan_info(9)
  • struct cfg80211_scan_6ghz_params(9)
  • struct cfg80211_scan_request(9)
  • struct cfg80211_match_set(9)
  • struct cfg80211_sched_scan_plan(9)
  • struct cfg80211_bss_select_adjust(9)
  • struct cfg80211_sched_scan_request(9)
  • enum cfg80211_signal_type(9)
  • struct cfg80211_inform_bss(9)
  • struct cfg80211_bss_ies(9)
  • struct cfg80211_bss(9)
  • ieee80211_bss_get_elem(9)
  • ieee80211_bss_get_ie(9)

Scanning and BSS list handling(9) is the section page, and then we've got the whole scan saga: ssid, scan info, the 6ghz scan params, the scan request itself, match set, sched scan plan, bss select adjust, sched scan request, the signal type enum, inform_bss, bss ies, and struct cfg80211_bss(9). oh and both getters β€” ieee80211_bss_get_elem(9) and the older-flavored ieee80211_bss_get_ie(9) 😌

auth, assoc & connect params πŸ’–

  • struct cfg80211_auth_request(9)
  • struct cfg80211_assoc_link(9)
  • struct cfg80211_ml_reconf_req(9)
  • enum cfg80211_assoc_req_flags(9)
  • struct cfg80211_assoc_request(9)
  • struct cfg80211_deauth_request(9)
  • struct cfg80211_disassoc_request(9)
  • struct cfg80211_ibss_params(9)
  • struct cfg80211_bss_selection(9)
  • struct cfg80211_connect_params(9)
  • enum cfg80211_connect_params_changed(9)
  • enum wiphy_params_flags(9)
  • struct cfg80211_pmksa(9)

the whole relationship arc: auth request, assoc link, ml reconf req, assoc req flags, assoc request, deauth request, disassoc request 😭 (breaking up is also a struct), ibss params, bss selection, connect params, the connect-params-changed enum, wiphy params flags, and pmksa. it's giving full lifecycle. periodt.

wowlan & all its little friends πŸŒ™

  • struct cfg80211_pkt_pattern(9)
  • struct cfg80211_wowlan_tcp(9)
  • struct cfg80211_wowlan(9)
  • struct cfg80211_coalesce_rules(9)
  • struct cfg80211_coalesce(9)
  • struct cfg80211_wowlan_nd_match(9)
  • struct cfg80211_wowlan_nd_info(9)
  • struct cfg80211_wowlan_wakeup(9)
  • struct cfg80211_gtk_rekey_data(9)
  • struct cfg80211_update_ft_ies_params(9)
  • struct cfg80211_mgmt_tx_params(9)
  • struct cfg80211_dscp_exception(9)
  • struct cfg80211_dscp_range(9)
  • struct cfg80211_qos_map(9)

wake-on-wlan with its tcp variant, pkt pattern, coalesce rules and coalesce, the nd match and nd info, the wakeup struct, gtk rekey data, update ft ies params, mgmt tx params, dscp exception, dscp range, and the qos map. yes there are two dscp structs, they're a matching set πŸŽ€

NAN (Neighbor Awareness Networking) πŸ’«

  • Neighbor Awareness Networking (NAN)(9)
  • struct cfg80211_nan_band_config(9)
  • struct cfg80211_nan_conf(9)
  • struct cfg80211_nan_channel(9)
  • struct cfg80211_nan_local_sched(9)
  • struct cfg80211_nan_peer_map(9)
  • struct cfg80211_nan_peer_sched(9)
  • enum cfg80211_nan_conf_changes(9)
  • struct cfg80211_nan_func_filter(9)
  • struct cfg80211_nan_func(9)

Neighbor Awareness Networking (NAN)(9) is the section page (yes the page name literally has the parenthetical in it, keep it exactly like that 🫢) and then every nan struct: band config, conf, channel, local sched, peer map, peer sched, the conf changes enum, func filter, and func. nan stans we are so back 🌈

pmk, external auth & ftm 🧚

  • struct cfg80211_pmk_conf(9)
  • struct cfg80211_external_auth_params(9)
  • struct cfg80211_ftm_responder_stats(9)
  • struct cfg80211_pmsr_ftm_result(9)
  • struct cfg80211_pmsr_result(9)
  • struct cfg80211_pmsr_ftm_request_peer(9)
  • struct cfg80211_pmsr_request_peer(9)
  • struct cfg80211_pmsr_request(9)
  • struct cfg80211_update_owe_info(9)
  • struct mgmt_frame_regs(9)

pmk conf, external auth params, ftm responder stats, then the whole pmsr family β€” ftm result, result, ftm request peer, request peer, request β€” plus update owe info and mgmt frame regs. ranging nerds, this is your moment πŸ“‘

ops, wiphy & all the capability structs πŸ‘‘

  • struct cfg80211_ops(9)
  • enum wiphy_flags(9)
  • struct ieee80211_iface_limit(9)
  • struct ieee80211_iface_combination(9)
  • enum wiphy_wowlan_support_flags(9)
  • struct wiphy_wowlan_support(9)
  • struct wiphy_coalesce_support(9)
  • enum wiphy_vendor_command_flags(9)
  • enum wiphy_opmode_flag(9)
  • struct sta_opmode_info(9)
  • struct wiphy_vendor_command(9)
  • struct wiphy_iftype_ext_capab(9)
  • cfg80211_get_iftype_ext_capa(9)
  • struct cfg80211_pmsr_capabilities(9)
  • struct wiphy_iftype_akm_suites(9)
  • struct wiphy_radio_cfg(9)
  • struct wiphy_radio_freq_range(9)
  • struct wiphy_radio(9)
  • enum wiphy_nan_flags(9)
  • struct wiphy_nan_capa(9)
  • struct wiphy(9)

big block, but it's all the driver-facing stuff: the ops struct, wiphy flags, iface limit + iface combination, wowlan support flags + support struct, coalesce support, vendor command flags + command struct, opmode flag + sta opmode info, iftype ext capab + the cfg80211_get_iftype_ext_capa(9) getter, pmsr capabilities, iftype akm suites, radio cfg + radio freq range + radio, nan flags + nan capa, and finally the big one, struct wiphy(9). absolute royalty πŸ‘‘πŸ’œ

wiphy lifecycle & locking πŸ”§

get the private data, get the wiphy back from it, set the dev, get the dev, get the name, new_nm and new (nm is the one where you name it yourself, and wiphy_new(9) is the plain one ✨), register it, the two rcu deref helpers, get the regdom, unregister, free β€” and lock/unlock for when you need to be a responsible adult. please lock before you touch. bestie behavior 🫢

work & hrtimer work scheduling ⏰

three flavors of work: plain wiphy_work_*, wiphy_delayed_work_* (which gets pending as a bonus), and wiphy_hrtimer_work_*. each family has its queue / cancel / flush and the timer ones have pending too. queue it, cancel it, flush it, check it β€” iconic quartet πŸ’…

wireless dev basics πŸ’œ

the ap reg power enum, the struct wireless_dev(9) itself, and the two handy getters β€” priv and chandef. small section, huge importance πŸŽ€

utility functions 🌸

Utility functions(9) opens the section, then it's conversion city: channel to khz, channel to freq khz, channel to frequency, freq khz to channel, frequency to channel, get channel by khz, get channel β€” both directions, both units, all the combos 😭 plus channel_equal, is_psc, radio freq range valid, radio chandef valid, wdev channel allowed, response rate, mandatory rates, the radiotap iterator struct, and three header length helpers: from skb, plain hdrlen, and mesh hdrlen. she does it all ✨

data path helpers 🌈

Data path helpers(9) is the landing page, then 8023 conversion (with and without exthdr), amsdu validity + conversion, tunnel proto getter, mesh hdr strip, 8021d classify, and then the finder family β€” element match, ie match, elem, ie, ext elem, ext ie, vendor elem, vendor ie β€” note the pairs: every "elem" has an "ie" sibling, they come as a set bestie πŸ’– then the rnr iter return enum, cfg80211_iter_rnr(9), defragment_element, and send_layer2_update. the whole data path buffet πŸ”₯

regulatory enforcement infrastructure πŸ›οΈ

the section page, then hint, set regd (and its _sync twin β€” don't forget the sync one, it's a different function 😌), apply custom regulatory, freq_reg_info, initiator name, and pre-cac allowed. then the internal page β€” Internal regulatory db functions(9) β€” and reg_query_regdb_wmm(9). legal girlies, this is your department 🌍

bss & mlme notify city πŸ“£

huge block, deep breath 🌬️ β€” scan done, sched scan results, sched scan stopped (and the _locked variant, which is a separate function, respect it), inform bss frame data, gen new bssid, is element inherited, merge profile, the bss frame type enum, get ies channel number, ssid eq, inform bss data, the double-underscore __cfg80211_get_bss(9) and the regular cfg80211_get_bss(9) (yes both, the underscore one is the internal one, iykyk), ref bss, put bss, unlink bss, bss iter, rx mlme mgmt, auth timeout, struct cfg80211_rx_assoc_resp_data(9) and its function, struct cfg80211_assoc_failure(9) and its function, tx mlme mgmt, rx unprot mlme mgmt, michael mic failure, ibss joined, and notify new peer candidate. whew. she's thorough πŸ’€

rfkill integration πŸ“΄

the section page, then set hw state with a reason (the reason is part of the name, don't drop it 🫢), start polling, stop polling. short, but she said what she said.

vendor commands πŸ›οΈ

Vendor commands(9) is the heading, then vendor cmd alloc reply skb, vendor cmd reply, get sender, vendor event alloc, the ucast event alloc (different function, keep the _ucast πŸ’…), and vendor event. and then the testmode quartet β€” alloc reply skb, reply, alloc event skb, and event β€” which is basically the same shape but for testmode. sibling eras fr.

connect / roam / disconnect πŸ’”

fils resp params, connect resp params, connect done, connect bss, connect result, connect timeout 😭 (it happens to everyone), roam info, roamed, port authorized, and disconnected. the full emotional journey of a connection, honestly.

remain-on-channel 🌟

ready on channel, remain on channel expired, tx mgmt expired. three little timers, three little notifications ✨

station info plumbing 🫢

alloc tid stats (and the link variant, which is its own function, yes πŸŽ€), release content, new sta, del sta sinfo, del sta, and conn failed. remember to release what you alloc, bestie. the vibes will not save you from a leak πŸ’€

rx mgmt & tx status πŸ“‘

rx info struct, rx mgmt ext, rx mgmt khz, plain rx mgmt β€” three rx variants all present and accounted for 🌸 then tx status struct, mgmt tx status ext, mgmt tx status, control port tx status, and rx control port. the whole rx/tx mgmt pipeline, no skips.

cqm, radar & cac notifications 🚨

all four cqm notifies β€” rssi, pktloss, txe, beacon loss β€” that's the whole cqm set, don't sleep on txe 😀 then the double-underscore __cfg80211_radar_event(9) (internal one, note the underscores), sta opmode change notify, cac event, background cac abort, gtk rekey notify, and pmksa candidate notify. notifications girlies, this is your house 🏠

and the last little row πŸ“

spurious frame, unexpected 4addr frame (the "who invited you" of frames 😭), probe status, report obss beacon in khz and the plain one, and finally struct cfg80211_beaconing_check_config(9) closing out the guest list πŸ’œ


and that's literally every single cross-reference on this page, bestie β€” nothing skipped, nothing merged, not one name left behind. the page keeps going after this tho, so don't wander off yet 🌈

...and the rest of the squad, because the cross-reference list is lowkey the whole friend group πŸ’– β€” every single one of these is a real page, fr fr, no skips:


And that's a wrap, bestie!! πŸŽ€βœ¨ This whole masterpiece lives under ./include/net, it's dated October 2026, and it answers to the name Test mode(9) β€” go forth and read it, ily, bye πŸ’…πŸ«Ά

πŸ“¦ where this page comes from