| Seq | Timestamp | Type | Name | Duration |
|---|---|---|---|---|
| 0/0 | 2026/10/04 11:33 | flow | patch-triage |
0mArgs:null Results: {
"EnableConfigs": null,
"FocusSymbols": [],
"KMSANReasoning": "",
"NeedsKMSAN": false,
"Reasoning": "The changes are entirely contained within the Qualcomm ath11k Wi-Fi driver (drivers/net/wireless/ath/ath11k/). This driver supports Qualcomm 802.11ax chipsets over PCIe and AHB/platform buses, requiring physical Qualcomm ASICs/silicon not emulated in standard QEMU or virtualized fuzzing environments. Because the hardware is structurally unreachable in standard fuzzing environments, the modified code is not worth fuzzing.",
"WorthFuzzing": false
} |
| 1/1 | 2026/10/04 11:33 | action | read-patch-diff |
0mArgs:null Results: {
"PatchDiff": "commit f8a6991ee5f8b4595acb1a77ab0d87b199044bec\nAuthor: syz-cluster \u003ctriage@syzkaller.com\u003e\nDate: Sun Oct 4 11:33:35 2026 +0000\n\n syz-cluster: applied patch under review\n\ndiff --git a/drivers/net/wireless/ath/ath11k/core.h b/drivers/net/wireless/ath/ath11k/core.h\nindex a0d725923ef24..079376986d733 100644\n--- a/drivers/net/wireless/ath/ath11k/core.h\n+++ b/drivers/net/wireless/ath/ath11k/core.h\n@@ -541,6 +541,7 @@ struct ath11k_per_peer_cfr_capture {\n \n struct ath11k_sta {\n \tstruct ath11k_vif *arvif;\n+\tu16 airtime_weight;\n \n \t/* the following are protected by ar-\u003edata_lock */\n \tu32 changed; /* IEEE80211_RC_* */\ndiff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c\nindex c1fa42edd3630..58d222a8883d2 100644\n--- a/drivers/net/wireless/ath/ath11k/mac.c\n+++ b/drivers/net/wireless/ath/ath11k/mac.c\n@@ -3812,12 +3812,14 @@ static void ath11k_mac_op_bss_info_changed(struct ieee80211_hw *hw,\n \t\t\t\tath11k_warn(ar-\u003eab, \"failed to set bss color collision on vdev %i: %d\\n\",\n \t\t\t\t\t arvif-\u003evdev_id, ret);\n \n+\t\t\t/* A disabled color stays in the PPDUs the AP transmits\n+\t\t\t * (IEEE Std 802.11-2024, 26.11.4)\n+\t\t\t */\n \t\t\tparam_id = WMI_VDEV_PARAM_BSS_COLOR;\n-\t\t\tif (info-\u003ehe_bss_color.enabled)\n-\t\t\t\tparam_value = info-\u003ehe_bss_color.color \u003c\u003c\n-\t\t\t\t\t\tIEEE80211_HE_OPERATION_BSS_COLOR_OFFSET;\n-\t\t\telse\n-\t\t\t\tparam_value = IEEE80211_HE_OPERATION_BSS_COLOR_DISABLED;\n+\t\t\tparam_value = info-\u003ehe_bss_color.color \u003c\u003c\n+\t\t\t\t\tIEEE80211_HE_OPERATION_BSS_COLOR_OFFSET;\n+\t\t\tif (!info-\u003ehe_bss_color.enabled)\n+\t\t\t\tparam_value |= IEEE80211_HE_OPERATION_BSS_COLOR_DISABLED;\n \n \t\t\tret = ath11k_wmi_vdev_set_param_cmd(ar, arvif-\u003evdev_id,\n \t\t\t\t\t\t\t param_id,\n@@ -6685,6 +6687,15 @@ static int ath11k_mac_op_start(struct ieee80211_hw *hw)\n \t\tgoto err;\n \t}\n \n+\tif (test_bit(WMI_TLV_SERVICE_ATF, ab-\u003ewmi_ab.svc_map)) {\n+\t\tret = ath11k_wmi_pdev_set_param(ar, WMI_PDEV_PARAM_ATF_DYNAMIC_ENABLE,\n+\t\t\t\t\t\t1, pdev-\u003epdev_id);\n+\t\t/* Without it the radio still works, just without ATF */\n+\t\tif (ret)\n+\t\t\tath11k_warn(ab, \"failed to enable airtime fairness: %d\\n\",\n+\t\t\t\t ret);\n+\t}\n+\n \tret = ath11k_wmi_send_dfs_phyerr_offload_enable_cmd(ar, pdev-\u003epdev_id);\n \tif (ret) {\n \t\tath11k_err(ab, \"failed to offload radar detection: %d\\n\",\n@@ -9938,6 +9949,90 @@ static int ath11k_mac_station_remove(struct ath11k *ar,\n \treturn ret;\n }\n \n+#define ATH11K_ATF_PEERS_PER_CMD 32\n+\n+struct ath11k_mac_atf_iter {\n+\tstruct ath11k_wmi_atf_peer_arg *peers;\n+\tu16 *weights;\n+\tu32 num, max, total;\n+};\n+\n+static void ath11k_mac_atf_iter(void *data, struct ieee80211_sta *sta)\n+{\n+\tstruct ath11k_mac_atf_iter *it = data;\n+\tstruct ath11k_sta *arsta = ath11k_sta_to_arsta(sta);\n+\n+\tif (it-\u003enum == it-\u003emax || !arsta-\u003earvif ||\n+\t arsta-\u003earvif-\u003evdev_type != WMI_VDEV_TYPE_AP)\n+\t\treturn;\n+\n+\tether_addr_copy(it-\u003epeers[it-\u003enum].addr, sta-\u003eaddr);\n+\tit-\u003epeers[it-\u003enum].vdev_id = arsta-\u003earvif-\u003evdev_id;\n+\tit-\u003eweights[it-\u003enum] = arsta-\u003eairtime_weight;\n+\tit-\u003etotal += arsta-\u003eairtime_weight;\n+\tit-\u003enum++;\n+}\n+\n+/* Firmware airtime fairness: give every station of the radio its share of\n+ * the airtime, in proportion to its airtime weight. The firmware schedules\n+ * a station only by the share of its group, so group 0 (every station's)\n+ * gets the whole radio first.\n+ */\n+static int ath11k_mac_atf_update(struct ath11k *ar)\n+{\n+\tstruct ath11k_mac_atf_iter it = { .max = ar-\u003emax_num_stations };\n+\tu32 i, n;\n+\tint ret = 0;\n+\n+\tlockdep_assert_held(\u0026ar-\u003econf_mutex);\n+\n+\tif (!test_bit(WMI_TLV_SERVICE_ATF, ar-\u003eab-\u003ewmi_ab.svc_map))\n+\t\treturn 0;\n+\n+\tit.peers = kcalloc(it.max, sizeof(*it.peers), GFP_KERNEL);\n+\tit.weights = kcalloc(it.max, sizeof(*it.weights), GFP_KERNEL);\n+\tif (!it.peers || !it.weights) {\n+\t\tret = -ENOMEM;\n+\t\tgoto out;\n+\t}\n+\n+\tieee80211_iterate_stations_atomic(ar-\u003ehw, ath11k_mac_atf_iter, \u0026it);\n+\n+\tfor (i = 0; i \u003c it.num; i++)\n+\t\tit.peers[i].units = max_t(u32, 1, div_u64((u64)WMI_ATF_DENOMINATION *\n+\t\t\t\t\t\t\t it.weights[i], it.total));\n+\n+\tret = ath11k_wmi_send_atf_group(ar, 0, WMI_ATF_DENOMINATION);\n+\tif (ret)\n+\t\tgoto out;\n+\n+\tfor (i = 0; i \u003c it.num; i += n) {\n+\t\tn = min_t(u32, it.num - i, ATH11K_ATF_PEERS_PER_CMD);\n+\t\tret = ath11k_wmi_send_peer_atf_request(ar, \u0026it.peers[i], n,\n+\t\t\t\t\t\t i + n \u003c it.num);\n+\t\tif (ret)\n+\t\t\tbreak;\n+\t}\n+\n+out:\n+\tkfree(it.weights);\n+\tkfree(it.peers);\n+\treturn ret;\n+}\n+\n+static void ath11k_mac_op_sta_set_airtime_weight(struct ieee80211_hw *hw,\n+\t\t\t\t\t\t struct ieee80211_vif *vif,\n+\t\t\t\t\t\t struct ieee80211_sta *sta, u16 weight)\n+{\n+\tstruct ath11k_sta *arsta = ath11k_sta_to_arsta(sta);\n+\tstruct ath11k *ar = hw-\u003epriv;\n+\n+\tmutex_lock(\u0026ar-\u003econf_mutex);\n+\tarsta-\u003eairtime_weight = weight;\n+\tath11k_mac_atf_update(ar);\n+\tmutex_unlock(\u0026ar-\u003econf_mutex);\n+}\n+\n static int ath11k_mac_op_sta_state(struct ieee80211_hw *hw,\n \t\t\t\t struct ieee80211_vif *vif,\n \t\t\t\t struct ieee80211_sta *sta,\n@@ -9965,6 +10060,7 @@ static int ath11k_mac_op_sta_state(struct ieee80211_hw *hw,\n \t new_state == IEEE80211_STA_NONE) {\n \t\tmemset(arsta, 0, sizeof(*arsta));\n \t\tarsta-\u003earvif = arvif;\n+\t\tarsta-\u003eairtime_weight = IEEE80211_DEFAULT_AIRTIME_WEIGHT;\n \t\tarsta-\u003epeer_ps_state = WMI_PEER_PS_STATE_DISABLED;\n \t\tINIT_WORK(\u0026arsta-\u003eupdate_wk, ath11k_sta_rc_update_wk);\n \t\tINIT_WORK(\u0026arsta-\u003eset_4addr_wk, ath11k_sta_set_4addr_wk);\n@@ -9996,6 +10092,9 @@ static int ath11k_mac_op_sta_state(struct ieee80211_hw *hw,\n \t\tmutex_unlock(\u0026ar-\u003eab-\u003etbl_mtx_lock);\n \n \t\tath11k_cfr_decrement_peer_count(ar, arsta);\n+\n+\t\tif (vif-\u003etype == NL80211_IFTYPE_AP)\n+\t\t\tath11k_mac_atf_update(ar);\n \t} else if (old_state == IEEE80211_STA_AUTH \u0026\u0026\n \t\t new_state == IEEE80211_STA_ASSOC \u0026\u0026\n \t\t (vif-\u003etype == NL80211_IFTYPE_AP ||\n@@ -10005,6 +10104,8 @@ static int ath11k_mac_op_sta_state(struct ieee80211_hw *hw,\n \t\tif (ret)\n \t\t\tath11k_warn(ar-\u003eab, \"Failed to associate station: %pM\\n\",\n \t\t\t\t sta-\u003eaddr);\n+\t\telse if (vif-\u003etype == NL80211_IFTYPE_AP)\n+\t\t\tath11k_mac_atf_update(ar);\n \n \t\tspin_lock_bh(\u0026ar-\u003edata_lock);\n \t\t/* Set arsta bw and prev bw */\n@@ -10096,6 +10197,7 @@ static const struct ieee80211_ops ath11k_ops = {\n \t.sta_state = ath11k_mac_op_sta_state,\n \t.sta_set_4addr = ath11k_mac_op_sta_set_4addr,\n \t.sta_set_txpwr\t\t\t= ath11k_mac_op_sta_set_txpwr,\n+\t.sta_set_airtime_weight\t\t= ath11k_mac_op_sta_set_airtime_weight,\n \t.link_sta_rc_update\t\t= ath11k_mac_op_sta_rc_update,\n \t.conf_tx = ath11k_mac_op_conf_tx,\n \t.set_antenna\t\t\t= ath11k_mac_op_set_antenna,\n@@ -10633,6 +10735,10 @@ static int __ath11k_mac_register(struct ath11k *ar)\n \t\twiphy_ext_feature_set(ar-\u003ehw-\u003ewiphy,\n \t\t\t\t NL80211_EXT_FEATURE_ENABLE_FTM_RESPONDER);\n \n+\tif (test_bit(WMI_TLV_SERVICE_ATF, ar-\u003eab-\u003ewmi_ab.svc_map))\n+\t\twiphy_ext_feature_set(ar-\u003ehw-\u003ewiphy,\n+\t\t\t\t NL80211_EXT_FEATURE_AIRTIME_FAIRNESS);\n+\n \tar-\u003ehw-\u003ewiphy-\u003embssid_max_interfaces = TARGET_NUM_VDEVS(ab);\n \tar-\u003ehw-\u003ewiphy-\u003eema_max_profile_periodicity = TARGET_EMA_MAX_PROFILE_PERIOD;\n \ndiff --git a/drivers/net/wireless/ath/ath11k/wmi.c b/drivers/net/wireless/ath/ath11k/wmi.c\nindex 08fd6795ed9e7..ce793962b7e73 100644\n--- a/drivers/net/wireless/ath/ath11k/wmi.c\n+++ b/drivers/net/wireless/ath/ath11k/wmi.c\n@@ -4466,6 +4466,100 @@ int ath11k_wmi_set_hw_mode(struct ath11k_base *ab,\n \treturn 0;\n }\n \n+int ath11k_wmi_send_atf_group(struct ath11k *ar, u32 group_id, u32 units)\n+{\n+\tstruct ath11k_pdev_wmi *wmi = ar-\u003ewmi;\n+\tstruct wmi_atf_ssid_grp_request_cmd *cmd;\n+\tstruct wmi_atf_group_info *grp;\n+\tstruct wmi_tlv *tlv;\n+\tstruct sk_buff *skb;\n+\tint ret;\n+\n+\tskb = ath11k_wmi_alloc_skb(wmi-\u003ewmi_ab, sizeof(*cmd) + TLV_HDR_SIZE + sizeof(*grp));\n+\tif (!skb)\n+\t\treturn -ENOMEM;\n+\n+\tcmd = (struct wmi_atf_ssid_grp_request_cmd *)skb-\u003edata;\n+\tcmd-\u003etlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ATF_SSID_GRP_REQUEST) |\n+\t\t\t FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE);\n+\tcmd-\u003epdev_id = ar-\u003epdev-\u003epdev_id;\n+\n+\ttlv = (struct wmi_tlv *)(skb-\u003edata + sizeof(*cmd));\n+\ttlv-\u003eheader = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ARRAY_STRUCT) |\n+\t\t FIELD_PREP(WMI_TLV_LEN, sizeof(*grp));\n+\tgrp = (struct wmi_atf_group_info *)tlv-\u003evalue;\n+\tgrp-\u003etlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ATF_GROUP_INFO) |\n+\t\t\t FIELD_PREP(WMI_TLV_LEN, sizeof(*grp) - TLV_HDR_SIZE);\n+\tgrp-\u003eatf_group_id = group_id;\n+\tgrp-\u003eatf_group_units = units;\n+\tgrp-\u003eatf_group_flags = WMI_ATF_GROUP_POLICY_FAIR;\n+\n+\tret = ath11k_wmi_cmd_send(wmi, skb, WMI_ATF_SSID_GROUPING_REQUEST_CMDID);\n+\tif (ret) {\n+\t\tath11k_warn(ar-\u003eab, \"failed to send atf group request: %d\\n\", ret);\n+\t\tdev_kfree_skb(skb);\n+\t\treturn ret;\n+\t}\n+\n+\tath11k_dbg(ar-\u003eab, ATH11K_DBG_WMI, \"cmd atf group %u units %u\\n\", group_id, units);\n+\n+\treturn 0;\n+}\n+\n+int ath11k_wmi_send_peer_atf_request(struct ath11k *ar,\n+\t\t\t\t const struct ath11k_wmi_atf_peer_arg *peers,\n+\t\t\t\t u32 num_peers, bool more)\n+{\n+\tstruct ath11k_pdev_wmi *wmi = ar-\u003ewmi;\n+\tstruct wmi_peer_atf_request_cmd *cmd;\n+\tstruct wmi_atf_peer_info *info;\n+\tstruct wmi_tlv *tlv;\n+\tstruct sk_buff *skb;\n+\tu32 i, pdev_id = ar-\u003epdev-\u003epdev_id;\n+\tint ret, len;\n+\n+\tlen = sizeof(*cmd) + TLV_HDR_SIZE + num_peers * sizeof(*info);\n+\tskb = ath11k_wmi_alloc_skb(wmi-\u003ewmi_ab, len);\n+\tif (!skb)\n+\t\treturn -ENOMEM;\n+\n+\tcmd = (struct wmi_peer_atf_request_cmd *)skb-\u003edata;\n+\tcmd-\u003etlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_PEER_ATF_REQUEST) |\n+\t\t\t FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE);\n+\tcmd-\u003enum_peers = num_peers;\n+\tcmd-\u003epdev_id = pdev_id;\n+\tcmd-\u003eatf_flags = WMI_PEER_ATF_REQ_FLAG_FULL_UPDATE |\n+\t\t\t WMI_PEER_ATF_REQ_FLAG_PDEV_ID_VALID;\n+\tif (more)\n+\t\tcmd-\u003eatf_flags |= WMI_PEER_ATF_REQ_FLAG_PENDING_CMDS;\n+\n+\ttlv = (struct wmi_tlv *)(skb-\u003edata + sizeof(*cmd));\n+\ttlv-\u003eheader = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ARRAY_STRUCT) |\n+\t\t FIELD_PREP(WMI_TLV_LEN, num_peers * sizeof(*info));\n+\tinfo = (struct wmi_atf_peer_info *)tlv-\u003evalue;\n+\n+\tfor (i = 0; i \u003c num_peers; i++, info++) {\n+\t\tinfo-\u003etlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ATF_PEER_INFO) |\n+\t\t\t\t FIELD_PREP(WMI_TLV_LEN, sizeof(*info) - TLV_HDR_SIZE);\n+\t\tether_addr_copy(info-\u003epeer_macaddr.addr, peers[i].addr);\n+\t\tinfo-\u003eatf_units = peers[i].units;\n+\t\tinfo-\u003evdev_id = peers[i].vdev_id;\n+\t\tinfo-\u003epdev_id = pdev_id;\n+\t}\n+\n+\tret = ath11k_wmi_cmd_send(wmi, skb, WMI_PEER_ATF_REQUEST_CMDID);\n+\tif (ret) {\n+\t\tath11k_warn(ar-\u003eab, \"failed to send peer atf request: %d\\n\", ret);\n+\t\tdev_kfree_skb(skb);\n+\t\treturn ret;\n+\t}\n+\n+\tath11k_dbg(ar-\u003eab, ATH11K_DBG_WMI, \"cmd peer atf request pdev %u peers %u%s\\n\",\n+\t\t pdev_id, num_peers, more ? \" (more)\" : \"\");\n+\n+\treturn 0;\n+}\n+\n int ath11k_wmi_cmd_init(struct ath11k_base *ab)\n {\n \tstruct ath11k_wmi_base *wmi_ab = \u0026ab-\u003ewmi_ab;\n@@ -4481,6 +4575,9 @@ int ath11k_wmi_cmd_init(struct ath11k_base *ab)\n \t\t ab-\u003ewmi_ab.svc_map))\n \t\tconfig.is_reg_cc_ext_event_supported = 1;\n \n+\tif (test_bit(WMI_TLV_SERVICE_ATF, ab-\u003ewmi_ab.svc_map))\n+\t\tconfig.flag1 |= WMI_RSRC_CFG_FLAG1_ATF_CONFIG_ENABLE;\n+\n \tmemcpy(\u0026wmi_ab-\u003ewlan_resource_config, \u0026config, sizeof(config));\n \n \tinit_param.res_cfg = \u0026wmi_ab-\u003ewlan_resource_config;\ndiff --git a/drivers/net/wireless/ath/ath11k/wmi.h b/drivers/net/wireless/ath/ath11k/wmi.h\nindex b2dade0516ac7..df7fd2204848e 100644\n--- a/drivers/net/wireless/ath/ath11k/wmi.h\n+++ b/drivers/net/wireless/ath/ath11k/wmi.h\n@@ -212,6 +212,7 @@ enum wmi_cmd_group {\n \tWMI_GRP_TWT = 0x3e,\n \tWMI_GRP_MOTION_DET = 0x3f,\n \tWMI_GRP_SPATIAL_REUSE = 0x40,\n+\tWMI_GRP_ATM = 0x45,\n };\n \n #define WMI_CMD_GRP(grp_id) (((grp_id) \u003c\u003c 12) | 0x1)\n@@ -625,6 +626,7 @@ enum wmi_tlv_cmd_id {\n \tWMI_PDEV_OBSS_PD_SPATIAL_REUSE_CMDID =\n \t\t\t\tWMI_TLV_CMD(WMI_GRP_SPATIAL_REUSE),\n \tWMI_PDEV_OBSS_PD_SPATIAL_REUSE_SET_DEF_OBSS_THRESH_CMDID,\n+\tWMI_ATF_SSID_GROUPING_REQUEST_CMDID = WMI_TLV_CMD(WMI_GRP_ATM),\n };\n \n enum wmi_tlv_event_id {\n@@ -1892,6 +1894,8 @@ enum wmi_tlv_tag {\n \tWMI_TAG_PEER_CFR_CAPTURE_EVENT = 0x317,\n \tWMI_TAG_CFR_CAPTURE_PHASE_PARAM = 0x33b,\n \tWMI_TAG_FILS_DISCOVERY_TMPL_CMD = 0x344,\n+\tWMI_TAG_ATF_SSID_GRP_REQUEST = 0x346,\n+\tWMI_TAG_ATF_GROUP_INFO,\n \tWMI_TAG_PDEV_SRG_BSS_COLOR_BITMAP_CMD = 0x37b,\n \tWMI_TAG_PDEV_SRG_PARTIAL_BSSID_BITMAP_CMD,\n \tWMI_TAG_PDEV_SRG_OBSS_COLOR_ENABLE_BITMAP_CMD = 0x381,\n@@ -2353,6 +2357,7 @@ struct wmi_init_cmd {\n } __packed;\n \n #define WMI_RSRC_CFG_FLAG1_BSS_CHANNEL_INFO_64 BIT(5)\n+#define WMI_RSRC_CFG_FLAG1_ATF_CONFIG_ENABLE BIT(6)\n #define WMI_RSRC_CFG_FLAG2_CALC_NEXT_DTIM_COUNT_SET BIT(9)\n #define WMI_RSRC_CFG_FLAG1_ACK_RSSI BIT(18)\n \n@@ -3628,6 +3633,48 @@ struct ath11k_wmi_p2p_noa_info {\n #define WMI_EMA_FIRST_TMPL_SHIFT 16\n #define WMI_EMA_LAST_TMPL_SHIFT 24\n \n+/* Airtime fairness: a share is in parts per thousand of the radio's airtime */\n+#define WMI_ATF_DENOMINATION\t\t\t1000\n+#define WMI_PEER_ATF_REQ_FLAG_FULL_UPDATE\tBIT(0)\n+#define WMI_PEER_ATF_REQ_FLAG_PENDING_CMDS\tBIT(1)\n+#define WMI_PEER_ATF_REQ_FLAG_PDEV_ID_VALID\tBIT(2)\n+#define WMI_ATF_GROUP_POLICY_FAIR\t\t0\n+\n+struct wmi_atf_ssid_grp_request_cmd {\n+\tu32 tlv_header;\n+\tu32 pdev_id;\n+} __packed;\n+\n+struct wmi_atf_group_info {\n+\tu32 tlv_header;\n+\tu32 atf_group_id;\n+\tu32 atf_group_units;\n+\tu32 atf_group_flags;\n+} __packed;\n+\n+struct wmi_peer_atf_request_cmd {\n+\tu32 tlv_header;\n+\tu32 num_peers;\n+\tu32 pdev_id;\n+\tu32 atf_flags;\n+} __packed;\n+\n+struct wmi_atf_peer_info {\n+\tu32 tlv_header;\n+\tstruct wmi_mac_addr peer_macaddr;\n+\tu32 atf_units;\n+\tu32 atf_groupid;\n+\tu32 atf_units_reserved;\n+\tu32 vdev_id;\n+\tu32 pdev_id;\n+} __packed;\n+\n+struct ath11k_wmi_atf_peer_arg {\n+\tu8 addr[ETH_ALEN];\n+\tu32 vdev_id;\n+\tu32 units;\n+};\n+\n struct wmi_bcn_tmpl_cmd {\n \tu32 tlv_header;\n \tu32 vdev_id;\n@@ -6450,6 +6497,10 @@ int ath11k_wmi_vdev_start(struct ath11k *ar, struct wmi_vdev_start_req_arg *arg,\n \t\t\t bool restart);\n int ath11k_wmi_set_peer_param(struct ath11k *ar, const u8 *peer_addr,\n \t\t\t u32 vdev_id, u32 param_id, u32 param_val);\n+int ath11k_wmi_send_atf_group(struct ath11k *ar, u32 group_id, u32 units);\n+int ath11k_wmi_send_peer_atf_request(struct ath11k *ar,\n+\t\t\t\t const struct ath11k_wmi_atf_peer_arg *peers,\n+\t\t\t\t u32 num_peers, bool more);\n int ath11k_wmi_pdev_set_param(struct ath11k *ar, u32 param_id,\n \t\t\t u32 param_value, u8 pdev_id);\n int ath11k_wmi_pdev_set_ps_mode(struct ath11k *ar, int vdev_id,\n"
} |
| 2/1 | 2026/10/04 11:33 | agent | patch-evaluator |
0mModel:core Args: null Results: {
"EnableConfigs": null,
"FocusSymbols": [],
"Reasoning": "The changes are entirely contained within the Qualcomm ath11k Wi-Fi driver (drivers/net/wireless/ath/ath11k/). This driver supports Qualcomm 802.11ax chipsets over PCIe and AHB/platform buses, requiring physical Qualcomm ASICs/silicon not emulated in standard QEMU or virtualized fuzzing environments. Because the hardware is structurally unreachable in standard fuzzing environments, the modified code is not worth fuzzing.",
"WorthFuzzing": false
}Instruction: You are an expert Linux kernel maintainer and security engineer.
Your job is to review a provided patch series and evaluate whether it warrants fuzzing with syzkaller.
IMPORTANT: The changes have ALREADY been applied and committed as the HEAD commit in
your workspace. Do NOT rely on internal assumptions. You must actively use your code access
tools to inspect the actual source code, callers, and surrounding context.
================================================================================
1. CORE TRIAGE PHILOSOPHY
================================================================================
The goal of patch fuzzing is to discover crashes, regressions, exposed latent bugs,
and newly triggered assertions introduced by the patch series.
- REACHABILITY IS THE PRIMARY GATE:
Fuzzing can only discover bugs in code that can actually execute in standard virtualized
environments (GCE or QEMU, utilizing software-emulated devices like USB gadgets, netdev, tun/tap).
If the modified code is structurally unreachable (see Section 2), it MUST NOT be fuzzed,
regardless of whether it adds assertions or complex logic.
- DO NOT BLINDLY TRUST "NO FUNCTIONAL CHANGE" (NFCI) OR "REFACTORING" CLAIMS:
Patch authors routinely label changes as "cleanups", "refactorings", or state
"No functional change intended". Do NOT take these claims at face value.
Code refactorings that rearrange logic, introduce helper functions, or alter state management
in core subsystems frequently introduce subtle semantic shifts or uncover latent kernel bugs.
If reachable executable code is modified or refactored, it MUST be fuzzed.
- NEW OR MODIFIED ASSERTIONS IN REACHABLE CODE MUST BE FUZZED:
When a patch introduces or modifies runtime checks or assertions (e.g., WARN_ON*, VM_WARN_ON*,
BUG_ON*, lockdep_assert*) in reachable code paths, it enforces new or stricter invariants.
Even if the author believes the invariant always holds, fuzzing is essential to verify whether
an unusual sequence of operations can violate it.
================================================================================
2. WHEN TO RETURN WorthFuzzing=false (NEGATIVE CRITERIA)
================================================================================
Return WorthFuzzing=false ONLY IF all modified code falls strictly into one or more of these categories:
- Non-kernel and non-executable changes:
* Modifications to Documentation/, comments, or spelling fixes.
* User-space directories, self-tests, samples, or scripts (e.g., tools/, samples/, scripts/, usr/)
that do not affect the compiled kernel image (vmlinux) or kernel modules.
* Purely decorative logging (e.g., message strings in pr_err, printk, dev_info) or tracepoints
that do not alter control flow or data structures.
* Build system or Kconfig changes that do not alter compiled C logic.
- Structurally unreachable hardware:
* Vendor-specific PCIe switches, SmartNICs, or GPU drivers (e.g., mlxsw, pds_core, qed,
ionic, amdgpu) requiring physical ASIC/PCIe cards not emulated in standard QEMU.
- Unreachable execution paths:
* Driver teardown callbacks (.remove, .shutdown, pci_unregister_driver) executed only during
physical PCI hot-unplug or manual sysfs driver unbinding.
* Code paths exclusive to architectures other than the target architecture.
================================================================================
3. WHEN TO RETURN WorthFuzzing=true (POSITIVE CRITERIA)
================================================================================
Return WorthFuzzing=true whenever the patch touches reachable executable code, including:
- Core Subsystems:
* Any logic modifications in memory management (mm/), synchronization/locking (kernel/locking/),
BPF, scheduler, core networking, VFS, or syscall handling.
- Refactorings and Code Cleanups:
* Any restructuring of reachable data structures, helper abstractions, or algorithm flows.
- Runtime Assertions and Defensive Checks:
* Any introduction or alteration of assertions (WARN_ON*, VM_WARN_ON*, BUG_ON*, etc.) in reachable paths.
- Reachable Drivers and Protocols:
* Drivers accessible via virtual buses (virtio, USB gadget, loopback, netlink, binder, sockets, etc.).
================================================================================
4. EXTRACTING FocusSymbols (PREVENTING DILUTION)
================================================================================
When WorthFuzzing=true, you must extract specific kernel functions into FocusSymbols to guide the fuzzer:
- AVOID UBIQUITOUS LIFECYCLE HOT-PATHS:
Do NOT list generic, ubiquitous functions called by almost every program in the corpus
(including, but not limited to: general memory allocators and deallocators, page fault
and trap handlers, or core synchronization primitives; this is not an exhaustive list).
Listing ubiquitous functions causes the fuzzer to classify thousands of unrelated tests as "focused",
which severely dilutes fuzzing effort away from the actual changes.
- TARGET SPECIFIC FEATURE LOGIC AND ENTRYPOINTS:
List functions that specifically implement the logic being added or altered, or direct API entrypoints
for the subsystem feature under review.
- HANDLING STATIC INLINE FUNCTIONS IN HEADERS (.h):
Compiler-inlined static functions (such as static inlines in mm/*.h or include/linux/*.h) lack
distinct symbol addresses in vmlinux and cannot be targeted directly by symbol coverage filters.
If the changes are primarily in static inline helpers, identify non-static, feature-specific caller
functions in .c files that exercise them (avoiding ubiquitous lifecycle wrappers).
================================================================================
5. IDENTIFYING EnableConfigs
================================================================================
Identify any specific CONFIG_ options required to properly compile and reach the modified code:
- Inspect Kconfig files and #ifdef guards; do not make assumptions.
- Check "depends on" lines in Kconfig to include any non-standard parent subsystem configs needed.
- Strip any 'CONFIG_' prefix (e.g., return "NET_IPV4" instead of "CONFIG_NET_IPV4").
Prefer calling several tools at the same time to save round-trips.
Use set-results tool to provide results of the analysis.
It must be called exactly once before the final reply.
Ignore results of this tool.
Prompt: Target architecture: amd64
For your convenience, here is the diff of the changes:
commit f8a6991ee5f8b4595acb1a77ab0d87b199044bec
Author: syz-cluster <triage@syzkaller.com>
Date: Sun Oct 4 11:33:35 2026 +0000
syz-cluster: applied patch under review
diff --git a/drivers/net/wireless/ath/ath11k/core.h b/drivers/net/wireless/ath/ath11k/core.h
index a0d725923ef24..079376986d733 100644
--- a/drivers/net/wireless/ath/ath11k/core.h
+++ b/drivers/net/wireless/ath/ath11k/core.h
@@ -541,6 +541,7 @@ struct ath11k_per_peer_cfr_capture {
struct ath11k_sta {
struct ath11k_vif *arvif;
+ u16 airtime_weight;
/* the following are protected by ar->data_lock */
u32 changed; /* IEEE80211_RC_* */
diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c
index c1fa42edd3630..58d222a8883d2 100644
--- a/drivers/net/wireless/ath/ath11k/mac.c
+++ b/drivers/net/wireless/ath/ath11k/mac.c
@@ -3812,12 +3812,14 @@ static void ath11k_mac_op_bss_info_changed(struct ieee80211_hw *hw,
ath11k_warn(ar->ab, "failed to set bss color collision on vdev %i: %d\n",
arvif->vdev_id, ret);
+ /* A disabled color stays in the PPDUs the AP transmits
+ * (IEEE Std 802.11-2024, 26.11.4)
+ */
param_id = WMI_VDEV_PARAM_BSS_COLOR;
- if (info->he_bss_color.enabled)
- param_value = info->he_bss_color.color <<
- IEEE80211_HE_OPERATION_BSS_COLOR_OFFSET;
- else
- param_value = IEEE80211_HE_OPERATION_BSS_COLOR_DISABLED;
+ param_value = info->he_bss_color.color <<
+ IEEE80211_HE_OPERATION_BSS_COLOR_OFFSET;
+ if (!info->he_bss_color.enabled)
+ param_value |= IEEE80211_HE_OPERATION_BSS_COLOR_DISABLED;
ret = ath11k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id,
param_id,
@@ -6685,6 +6687,15 @@ static int ath11k_mac_op_start(struct ieee80211_hw *hw)
goto err;
}
+ if (test_bit(WMI_TLV_SERVICE_ATF, ab->wmi_ab.svc_map)) {
+ ret = ath11k_wmi_pdev_set_param(ar, WMI_PDEV_PARAM_ATF_DYNAMIC_ENABLE,
+ 1, pdev->pdev_id);
+ /* Without it the radio still works, just without ATF */
+ if (ret)
+ ath11k_warn(ab, "failed to enable airtime fairness: %d\n",
+ ret);
+ }
+
ret = ath11k_wmi_send_dfs_phyerr_offload_enable_cmd(ar, pdev->pdev_id);
if (ret) {
ath11k_err(ab, "failed to offload radar detection: %d\n",
@@ -9938,6 +9949,90 @@ static int ath11k_mac_station_remove(struct ath11k *ar,
return ret;
}
+#define ATH11K_ATF_PEERS_PER_CMD 32
+
+struct ath11k_mac_atf_iter {
+ struct ath11k_wmi_atf_peer_arg *peers;
+ u16 *weights;
+ u32 num, max, total;
+};
+
+static void ath11k_mac_atf_iter(void *data, struct ieee80211_sta *sta)
+{
+ struct ath11k_mac_atf_iter *it = data;
+ struct ath11k_sta *arsta = ath11k_sta_to_arsta(sta);
+
+ if (it->num == it->max || !arsta->arvif ||
+ arsta->arvif->vdev_type != WMI_VDEV_TYPE_AP)
+ return;
+
+ ether_addr_copy(it->peers[it->num].addr, sta->addr);
+ it->peers[it->num].vdev_id = arsta->arvif->vdev_id;
+ it->weights[it->num] = arsta->airtime_weight;
+ it->total += arsta->airtime_weight;
+ it->num++;
+}
+
+/* Firmware airtime fairness: give every station of the radio its share of
+ * the airtime, in proportion to its airtime weight. The firmware schedules
+ * a station only by the share of its group, so group 0 (every station's)
+ * gets the whole radio first.
+ */
+static int ath11k_mac_atf_update(struct ath11k *ar)
+{
+ struct ath11k_mac_atf_iter it = { .max = ar->max_num_stations };
+ u32 i, n;
+ int ret = 0;
+
+ lockdep_assert_held(&ar->conf_mutex);
+
+ if (!test_bit(WMI_TLV_SERVICE_ATF, ar->ab->wmi_ab.svc_map))
+ return 0;
+
+ it.peers = kcalloc(it.max, sizeof(*it.peers), GFP_KERNEL);
+ it.weights = kcalloc(it.max, sizeof(*it.weights), GFP_KERNEL);
+ if (!it.peers || !it.weights) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ ieee80211_iterate_stations_atomic(ar->hw, ath11k_mac_atf_iter, &it);
+
+ for (i = 0; i < it.num; i++)
+ it.peers[i].units = max_t(u32, 1, div_u64((u64)WMI_ATF_DENOMINATION *
+ it.weights[i], it.total));
+
+ ret = ath11k_wmi_send_atf_group(ar, 0, WMI_ATF_DENOMINATION);
+ if (ret)
+ goto out;
+
+ for (i = 0; i < it.num; i += n) {
+ n = min_t(u32, it.num - i, ATH11K_ATF_PEERS_PER_CMD);
+ ret = ath11k_wmi_send_peer_atf_request(ar, &it.peers[i], n,
+ i + n < it.num);
+ if (ret)
+ break;
+ }
+
+out:
+ kfree(it.weights);
+ kfree(it.peers);
+ return ret;
+}
+
+static void ath11k_mac_op_sta_set_airtime_weight(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ struct ieee80211_sta *sta, u16 weight)
+{
+ struct ath11k_sta *arsta = ath11k_sta_to_arsta(sta);
+ struct ath11k *ar = hw->priv;
+
+ mutex_lock(&ar->conf_mutex);
+ arsta->airtime_weight = weight;
+ ath11k_mac_atf_update(ar);
+ mutex_unlock(&ar->conf_mutex);
+}
+
static int ath11k_mac_op_sta_state(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
struct ieee80211_sta *sta,
@@ -9965,6 +10060,7 @@ static int ath11k_mac_op_sta_state(struct ieee80211_hw *hw,
new_state == IEEE80211_STA_NONE) {
memset(arsta, 0, sizeof(*arsta));
arsta->arvif = arvif;
+ arsta->airtime_weight = IEEE80211_DEFAULT_AIRTIME_WEIGHT;
arsta->peer_ps_state = WMI_PEER_PS_STATE_DISABLED;
INIT_WORK(&arsta->update_wk, ath11k_sta_rc_update_wk);
INIT_WORK(&arsta->set_4addr_wk, ath11k_sta_set_4addr_wk);
@@ -9996,6 +10092,9 @@ static int ath11k_mac_op_sta_state(struct ieee80211_hw *hw,
mutex_unlock(&ar->ab->tbl_mtx_lock);
ath11k_cfr_decrement_peer_count(ar, arsta);
+
+ if (vif->type == NL80211_IFTYPE_AP)
+ ath11k_mac_atf_update(ar);
} else if (old_state == IEEE80211_STA_AUTH &&
new_state == IEEE80211_STA_ASSOC &&
(vif->type == NL80211_IFTYPE_AP ||
@@ -10005,6 +10104,8 @@ static int ath11k_mac_op_sta_state(struct ieee80211_hw *hw,
if (ret)
ath11k_warn(ar->ab, "Failed to associate station: %pM\n",
sta->addr);
+ else if (vif->type == NL80211_IFTYPE_AP)
+ ath11k_mac_atf_update(ar);
spin_lock_bh(&ar->data_lock);
/* Set arsta bw and prev bw */
@@ -10096,6 +10197,7 @@ static const struct ieee80211_ops ath11k_ops = {
.sta_state = ath11k_mac_op_sta_state,
.sta_set_4addr = ath11k_mac_op_sta_set_4addr,
.sta_set_txpwr = ath11k_mac_op_sta_set_txpwr,
+ .sta_set_airtime_weight = ath11k_mac_op_sta_set_airtime_weight,
.link_sta_rc_update = ath11k_mac_op_sta_rc_update,
.conf_tx = ath11k_mac_op_conf_tx,
.set_antenna = ath11k_mac_op_set_antenna,
@@ -10633,6 +10735,10 @@ static int __ath11k_mac_register(struct ath11k *ar)
wiphy_ext_feature_set(ar->hw->wiphy,
NL80211_EXT_FEATURE_ENABLE_FTM_RESPONDER);
+ if (test_bit(WMI_TLV_SERVICE_ATF, ar->ab->wmi_ab.svc_map))
+ wiphy_ext_feature_set(ar->hw->wiphy,
+ NL80211_EXT_FEATURE_AIRTIME_FAIRNESS);
+
ar->hw->wiphy->mbssid_max_interfaces = TARGET_NUM_VDEVS(ab);
ar->hw->wiphy->ema_max_profile_periodicity = TARGET_EMA_MAX_PROFILE_PERIOD;
diff --git a/drivers/net/wireless/ath/ath11k/wmi.c b/drivers/net/wireless/ath/ath11k/wmi.c
index 08fd6795ed9e7..ce793962b7e73 100644
--- a/drivers/net/wireless/ath/ath11k/wmi.c
+++ b/drivers/net/wireless/ath/ath11k/wmi.c
@@ -4466,6 +4466,100 @@ int ath11k_wmi_set_hw_mode(struct ath11k_base *ab,
return 0;
}
+int ath11k_wmi_send_atf_group(struct ath11k *ar, u32 group_id, u32 units)
+{
+ struct ath11k_pdev_wmi *wmi = ar->wmi;
+ struct wmi_atf_ssid_grp_request_cmd *cmd;
+ struct wmi_atf_group_info *grp;
+ struct wmi_tlv *tlv;
+ struct sk_buff *skb;
+ int ret;
+
+ skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, sizeof(*cmd) + TLV_HDR_SIZE + sizeof(*grp));
+ if (!skb)
+ return -ENOMEM;
+
+ cmd = (struct wmi_atf_ssid_grp_request_cmd *)skb->data;
+ cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ATF_SSID_GRP_REQUEST) |
+ FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE);
+ cmd->pdev_id = ar->pdev->pdev_id;
+
+ tlv = (struct wmi_tlv *)(skb->data + sizeof(*cmd));
+ tlv->header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ARRAY_STRUCT) |
+ FIELD_PREP(WMI_TLV_LEN, sizeof(*grp));
+ grp = (struct wmi_atf_group_info *)tlv->value;
+ grp->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ATF_GROUP_INFO) |
+ FIELD_PREP(WMI_TLV_LEN, sizeof(*grp) - TLV_HDR_SIZE);
+ grp->atf_group_id = group_id;
+ grp->atf_group_units = units;
+ grp->atf_group_flags = WMI_ATF_GROUP_POLICY_FAIR;
+
+ ret = ath11k_wmi_cmd_send(wmi, skb, WMI_ATF_SSID_GROUPING_REQUEST_CMDID);
+ if (ret) {
+ ath11k_warn(ar->ab, "failed to send atf group request: %d\n", ret);
+ dev_kfree_skb(skb);
+ return ret;
+ }
+
+ ath11k_dbg(ar->ab, ATH11K_DBG_WMI, "cmd atf group %u units %u\n", group_id, units);
+
+ return 0;
+}
+
+int ath11k_wmi_send_peer_atf_request(struct ath11k *ar,
+ const struct ath11k_wmi_atf_peer_arg *peers,
+ u32 num_peers, bool more)
+{
+ struct ath11k_pdev_wmi *wmi = ar->wmi;
+ struct wmi_peer_atf_request_cmd *cmd;
+ struct wmi_atf_peer_info *info;
+ struct wmi_tlv *tlv;
+ struct sk_buff *skb;
+ u32 i, pdev_id = ar->pdev->pdev_id;
+ int ret, len;
+
+ len = sizeof(*cmd) + TLV_HDR_SIZE + num_peers * sizeof(*info);
+ skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, len);
+ if (!skb)
+ return -ENOMEM;
+
+ cmd = (struct wmi_peer_atf_request_cmd *)skb->data;
+ cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_PEER_ATF_REQUEST) |
+ FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE);
+ cmd->num_peers = num_peers;
+ cmd->pdev_id = pdev_id;
+ cmd->atf_flags = WMI_PEER_ATF_REQ_FLAG_FULL_UPDATE |
+ WMI_PEER_ATF_REQ_FLAG_PDEV_ID_VALID;
+ if (more)
+ cmd->atf_flags |= WMI_PEER_ATF_REQ_FLAG_PENDING_CMDS;
+
+ tlv = (struct wmi_tlv *)(skb->data + sizeof(*cmd));
+ tlv->header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ARRAY_STRUCT) |
+ FIELD_PREP(WMI_TLV_LEN, num_peers * sizeof(*info));
+ info = (struct wmi_atf_peer_info *)tlv->value;
+
+ for (i = 0; i < num_peers; i++, info++) {
+ info->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ATF_PEER_INFO) |
+ FIELD_PREP(WMI_TLV_LEN, sizeof(*info) - TLV_HDR_SIZE);
+ ether_addr_copy(info->peer_macaddr.addr, peers[i].addr);
+ info->atf_units = peers[i].units;
+ info->vdev_id = peers[i].vdev_id;
+ info->pdev_id = pdev_id;
+ }
+
+ ret = ath11k_wmi_cmd_send(wmi, skb, WMI_PEER_ATF_REQUEST_CMDID);
+ if (ret) {
+ ath11k_warn(ar->ab, "failed to send peer atf request: %d\n", ret);
+ dev_kfree_skb(skb);
+ return ret;
+ }
+
+ ath11k_dbg(ar->ab, ATH11K_DBG_WMI, "cmd peer atf request pdev %u peers %u%s\n",
+ pdev_id, num_peers, more ? " (more)" : "");
+
+ return 0;
+}
+
int ath11k_wmi_cmd_init(struct ath11k_base *ab)
{
struct ath11k_wmi_base *wmi_ab = &ab->wmi_ab;
@@ -4481,6 +4575,9 @@ int ath11k_wmi_cmd_init(struct ath11k_base *ab)
ab->wmi_ab.svc_map))
config.is_reg_cc_ext_event_supported = 1;
+ if (test_bit(WMI_TLV_SERVICE_ATF, ab->wmi_ab.svc_map))
+ config.flag1 |= WMI_RSRC_CFG_FLAG1_ATF_CONFIG_ENABLE;
+
memcpy(&wmi_ab->wlan_resource_config, &config, sizeof(config));
init_param.res_cfg = &wmi_ab->wlan_resource_config;
diff --git a/drivers/net/wireless/ath/ath11k/wmi.h b/drivers/net/wireless/ath/ath11k/wmi.h
index b2dade0516ac7..df7fd2204848e 100644
--- a/drivers/net/wireless/ath/ath11k/wmi.h
+++ b/drivers/net/wireless/ath/ath11k/wmi.h
@@ -212,6 +212,7 @@ enum wmi_cmd_group {
WMI_GRP_TWT = 0x3e,
WMI_GRP_MOTION_DET = 0x3f,
WMI_GRP_SPATIAL_REUSE = 0x40,
+ WMI_GRP_ATM = 0x45,
};
#define WMI_CMD_GRP(grp_id) (((grp_id) << 12) | 0x1)
@@ -625,6 +626,7 @@ enum wmi_tlv_cmd_id {
WMI_PDEV_OBSS_PD_SPATIAL_REUSE_CMDID =
WMI_TLV_CMD(WMI_GRP_SPATIAL_REUSE),
WMI_PDEV_OBSS_PD_SPATIAL_REUSE_SET_DEF_OBSS_THRESH_CMDID,
+ WMI_ATF_SSID_GROUPING_REQUEST_CMDID = WMI_TLV_CMD(WMI_GRP_ATM),
};
enum wmi_tlv_event_id {
@@ -1892,6 +1894,8 @@ enum wmi_tlv_tag {
WMI_TAG_PEER_CFR_CAPTURE_EVENT = 0x317,
WMI_TAG_CFR_CAPTURE_PHASE_PARAM = 0x33b,
WMI_TAG_FILS_DISCOVERY_TMPL_CMD = 0x344,
+ WMI_TAG_ATF_SSID_GRP_REQUEST = 0x346,
+ WMI_TAG_ATF_GROUP_INFO,
WMI_TAG_PDEV_SRG_BSS_COLOR_BITMAP_CMD = 0x37b,
WMI_TAG_PDEV_SRG_PARTIAL_BSSID_BITMAP_CMD,
WMI_TAG_PDEV_SRG_OBSS_COLOR_ENABLE_BITMAP_CMD = 0x381,
@@ -2353,6 +2357,7 @@ struct wmi_init_cmd {
} __packed;
#define WMI_RSRC_CFG_FLAG1_BSS_CHANNEL_INFO_64 BIT(5)
+#define WMI_RSRC_CFG_FLAG1_ATF_CONFIG_ENABLE BIT(6)
#define WMI_RSRC_CFG_FLAG2_CALC_NEXT_DTIM_COUNT_SET BIT(9)
#define WMI_RSRC_CFG_FLAG1_ACK_RSSI BIT(18)
@@ -3628,6 +3633,48 @@ struct ath11k_wmi_p2p_noa_info {
#define WMI_EMA_FIRST_TMPL_SHIFT 16
#define WMI_EMA_LAST_TMPL_SHIFT 24
+/* Airtime fairness: a share is in parts per thousand of the radio's airtime */
+#define WMI_ATF_DENOMINATION 1000
+#define WMI_PEER_ATF_REQ_FLAG_FULL_UPDATE BIT(0)
+#define WMI_PEER_ATF_REQ_FLAG_PENDING_CMDS BIT(1)
+#define WMI_PEER_ATF_REQ_FLAG_PDEV_ID_VALID BIT(2)
+#define WMI_ATF_GROUP_POLICY_FAIR 0
+
+struct wmi_atf_ssid_grp_request_cmd {
+ u32 tlv_header;
+ u32 pdev_id;
+} __packed;
+
+struct wmi_atf_group_info {
+ u32 tlv_header;
+ u32 atf_group_id;
+ u32 atf_group_units;
+ u32 atf_group_flags;
+} __packed;
+
+struct wmi_peer_atf_request_cmd {
+ u32 tlv_header;
+ u32 num_peers;
+ u32 pdev_id;
+ u32 atf_flags;
+} __packed;
+
+struct wmi_atf_peer_info {
+ u32 tlv_header;
+ struct wmi_mac_addr peer_macaddr;
+ u32 atf_units;
+ u32 atf_groupid;
+ u32 atf_units_reserved;
+ u32 vdev_id;
+ u32 pdev_id;
+} __packed;
+
+struct ath11k_wmi_atf_peer_arg {
+ u8 addr[ETH_ALEN];
+ u32 vdev_id;
+ u32 units;
+};
+
struct wmi_bcn_tmpl_cmd {
u32 tlv_header;
u32 vdev_id;
@@ -6450,6 +6497,10 @@ int ath11k_wmi_vdev_start(struct ath11k *ar, struct wmi_vdev_start_req_arg *arg,
bool restart);
int ath11k_wmi_set_peer_param(struct ath11k *ar, const u8 *peer_addr,
u32 vdev_id, u32 param_id, u32 param_val);
+int ath11k_wmi_send_atf_group(struct ath11k *ar, u32 group_id, u32 units);
+int ath11k_wmi_send_peer_atf_request(struct ath11k *ar,
+ const struct ath11k_wmi_atf_peer_arg *peers,
+ u32 num_peers, bool more);
int ath11k_wmi_pdev_set_param(struct ath11k *ar, u32 param_id,
u32 param_value, u8 pdev_id);
int ath11k_wmi_pdev_set_ps_mode(struct ath11k *ar, int vdev_id,
|
| 3/2 | 2026/10/04 11:33 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 9492 output: 37 thoughts: 278 Thoughts: **Analyzing the ath11k Patch** Okay, so this patch is touching `drivers/net/wireless/ath/ath11k/core.h`, `drivers/net/wireless/ath/ath11k/mac.c`, `drivers/net/wireless/ath/ath11k/wmi.c`, and `drivers/net/wireless/ath/ath11k/wmi.h`. That means it's definitely within the Qualcomm 802.11ax wireless driver, `ath11k`. I'm going to need to understand the implications of these changes, and the first question in my mind is: what hardware are we talking about here? Is this a physical PCI or AHB device? Can I easily emulate it for testing? Hmm, let's see. Section 2 of the instructions gives some clues. It mentions "structurally unreachable hardware" like vendor-specific PCIe switches, and then contrasts that with "Reachable Drivers." Okay, the key distinction seems to be physical ASIC/PCIe cards that are not emulated versus drivers accessible via virtual buses. Right, so I have to determine if this is a physical device or a virtual one. I need to quickly figure out if `ath11k` is a physical device driver. I'll grep for things like bus support and probe functions within the driver. That should give me the answer pretty quickly. |
| 4/2 | 2026/10/04 11:33 | tool | grepper |
0mArgs:{
"Expression": "config ATH11K",
"PathPrefix": "drivers/net/wireless/ath/ath11k"
}Results: {
"Output": "drivers/net/wireless/ath/ath11k/Kconfig-1-# SPDX-License-Identifier: BSD-3-Clause-Clear\ndrivers/net/wireless/ath/ath11k/Kconfig:2:config ATH11K\ndrivers/net/wireless/ath/ath11k/Kconfig-3-\ttristate \"Qualcomm 802.11ax chipset support\"\n--\ndrivers/net/wireless/ath/ath11k/Kconfig-12-\ndrivers/net/wireless/ath/ath11k/Kconfig:13:config ATH11K_AHB\ndrivers/net/wireless/ath/ath11k/Kconfig-14-\ttristate \"Atheros ath11k AHB support\"\n--\ndrivers/net/wireless/ath/ath11k/Kconfig-22-\ndrivers/net/wireless/ath/ath11k/Kconfig:23:config ATH11K_PCI\ndrivers/net/wireless/ath/ath11k/Kconfig-24-\ttristate \"Atheros ath11k PCI support\"\n--\ndrivers/net/wireless/ath/ath11k/Kconfig-32-\ndrivers/net/wireless/ath/ath11k/Kconfig:33:config ATH11K_DEBUG\ndrivers/net/wireless/ath/ath11k/Kconfig-34-\tbool \"QCA ath11k debugging\"\n--\ndrivers/net/wireless/ath/ath11k/Kconfig-40-\ndrivers/net/wireless/ath/ath11k/Kconfig:41:config ATH11K_DEBUGFS\ndrivers/net/wireless/ath/ath11k/Kconfig-42-\tbool \"QCA ath11k debugfs support\"\n--\ndrivers/net/wireless/ath/ath11k/Kconfig-48-\ndrivers/net/wireless/ath/ath11k/Kconfig:49:config ATH11K_TRACING\ndrivers/net/wireless/ath/ath11k/Kconfig-50-\tbool \"ath11k tracing support\"\n--\ndrivers/net/wireless/ath/ath11k/Kconfig-54-\ndrivers/net/wireless/ath/ath11k/Kconfig:55:config ATH11K_SPECTRAL\ndrivers/net/wireless/ath/ath11k/Kconfig-56-\tbool \"QCA ath11k spectral scan support\"\n--\ndrivers/net/wireless/ath/ath11k/Kconfig-63-\ndrivers/net/wireless/ath/ath11k/Kconfig:64:config ATH11K_CFR\ndrivers/net/wireless/ath/ath11k/Kconfig-65-\tbool \"ath11k channel frequency response support\"\n"
} |
| 5/2 | 2026/10/04 11:33 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 10789 output: 38 thoughts: 196 Thoughts: **Investigating ath11k Emulation Possibilities** Okay, so ath11k supports both AHB and PCI, got it. Now, the big question is, can I even *simulate* this in a standard QEMU setup or on GCE? Thinking logically, the answer is no. This isn't a generic thing; ath11k is specifically for those Qualcomm IPQ chips, so it's not going to be standard. And, since it's not USB, that rules that out right away. So, maybe I could leverage mac80211_hwsim or mac80211 for something here? No, those are completely separate, more generic, drivers. Ath11k is a vendor-specific driver. I need to think outside the box. Alright, what about a virtual bus or some kind of dummy driver to emulate ath11k's behavior? Perhaps some kind of emulation layer? I need to dig deeper. I'll scour the `tools/testing` directories and really any other relevant place for clues or mentions of this. Time to get searching! |
| 6/2 | 2026/10/04 11:33 | tool | grepper |
0mArgs:{
"Expression": "ath11k",
"PathPrefix": "drivers/net/wireless/ath/ath11k/Makefile"
}Results: {
"Output": "drivers/net/wireless/ath/ath11k/Makefile-1-# SPDX-License-Identifier: BSD-3-Clause-Clear\ndrivers/net/wireless/ath/ath11k/Makefile:2:obj-$(CONFIG_ATH11K) += ath11k.o\ndrivers/net/wireless/ath/ath11k/Makefile:3:ath11k-y += core.o \\\ndrivers/net/wireless/ath/ath11k/Makefile-4-\t hal.o \\\n--\ndrivers/net/wireless/ath/ath11k/Makefile-23-\ndrivers/net/wireless/ath/ath11k/Makefile:24:ath11k-$(CONFIG_ATH11K_DEBUGFS) += debugfs.o debugfs_htt_stats.o debugfs_sta.o\ndrivers/net/wireless/ath/ath11k/Makefile:25:ath11k-$(CONFIG_NL80211_TESTMODE) += testmode.o\ndrivers/net/wireless/ath/ath11k/Makefile:26:ath11k-$(CONFIG_ATH11K_TRACING) += trace.o\ndrivers/net/wireless/ath/ath11k/Makefile:27:ath11k-$(CONFIG_THERMAL) += thermal.o\ndrivers/net/wireless/ath/ath11k/Makefile:28:ath11k-$(CONFIG_ATH11K_SPECTRAL) += spectral.o\ndrivers/net/wireless/ath/ath11k/Makefile:29:ath11k-$(CONFIG_PM) += wow.o\ndrivers/net/wireless/ath/ath11k/Makefile:30:ath11k-$(CONFIG_DEV_COREDUMP) += coredump.o\ndrivers/net/wireless/ath/ath11k/Makefile:31:ath11k-$(CONFIG_ATH11K_CFR) += cfr.o\ndrivers/net/wireless/ath/ath11k/Makefile-32-\ndrivers/net/wireless/ath/ath11k/Makefile:33:obj-$(CONFIG_ATH11K_AHB) += ath11k_ahb.o\ndrivers/net/wireless/ath/ath11k/Makefile:34:ath11k_ahb-y += ahb.o\ndrivers/net/wireless/ath/ath11k/Makefile-35-\ndrivers/net/wireless/ath/ath11k/Makefile:36:obj-$(CONFIG_ATH11K_PCI) += ath11k_pci.o\ndrivers/net/wireless/ath/ath11k/Makefile:37:ath11k_pci-y += mhi.o pci.o\ndrivers/net/wireless/ath/ath11k/Makefile-38-\n"
} |
| 7/2 | 2026/10/04 11:33 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 11939 output: 41 thoughts: 396 Thoughts: **My Assessment of ath11k's Fuzzing Potential** Okay, so ath11k only seems to support two bus types: AHB, typically found on Qualcomm SoCs like IPQ8074, and PCI, used for devices like the QCA6390 and WCN6855 that utilize the MHI interface. The question then becomes, can we even fuzz this driver with syzkaller? Let's refer to the syzkaller guidelines. The relevant section, "WHEN TO RETURN WorthFuzzing=false," clearly states that we should *not* fuzz code if it falls into certain categories. Specifically, the "Structurally unreachable hardware" clause is the one to investigate. It mentions vendor-specific PCIe switches, SmartNICs, GPU drivers – things that require specific, un-emulated hardware. ath11k is a wireless driver from Qualcomm, designed for their IEEE 802.11ax chipsets. These chipsets interface either via PCIe or Qualcomm's AHB bus. Critically, this means it requires physical hardware: either an ASIC, a PCIe card, or the Qualcomm SoC itself. And, as far as I'm aware, neither standard QEMU nor GCE emulates the specific hardware required by ath11k. This immediately puts it under the "unreachable hardware" category. Unlike drivers for USB wireless adapters like ath9k_htc, rtl8192cu, rt2800usb or mt76x0u, which can be probed via USB gadget or Raw Gadget emulation, ath11k has no USB support. That further limits its potential accessibility. To be absolutely sure, let's verify that ath11k can't be instantiated without the required hardware, or through a virtual bus. My next step is to examine the driver's `pci.c` and `ahb.c` files for any clues, or any potential loopholes. |
| 8/2 | 2026/10/04 11:33 | tool | grepper |
0mArgs:{
"Expression": "ath11k_pci_probe",
"PathPrefix": "drivers/net/wireless/ath/ath11k"
}Results: {
"Output": "drivers/net/wireless/ath/ath11k/pci.c=940=static int ath11k_pci_set_irq_affinity_hint(struct ath11k_pci *ab_pci,\n--\ndrivers/net/wireless/ath/ath11k/pci.c-948-\ndrivers/net/wireless/ath/ath11k/pci.c:949:static int ath11k_pci_probe(struct pci_dev *pdev,\ndrivers/net/wireless/ath/ath11k/pci.c-950-\t\t\t const struct pci_device_id *pci_dev)\n--\ndrivers/net/wireless/ath/ath11k/pci.c=1296=static struct pci_driver ath11k_pci_driver = {\n--\ndrivers/net/wireless/ath/ath11k/pci.c-1298-\t.id_table = ath11k_pci_id_table,\ndrivers/net/wireless/ath/ath11k/pci.c:1299:\t.probe = ath11k_pci_probe,\ndrivers/net/wireless/ath/ath11k/pci.c-1300-\t.remove = ath11k_pci_remove,\n"
} |
| 9/2 | 2026/10/04 11:33 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 13132 output: 43 thoughts: 33 Thoughts: Here's my take on the thought process, as requested: **Diving into the ath11k_pci Binding** Alright, let's get down to brass tacks. I'm looking at the `ath11k_pci` driver and how it's interacting with the PCI bus. Specifically, I need to understand the ID table (`ath11k_pci_id_table`) which dictates which PCI devices this driver claims responsibility for. Time to investigate those PCI IDs to understand the exact scope of this driver's hardware support. What devices are we talking about here? |
| 10/2 | 2026/10/04 11:33 | tool | grepper |
0mArgs:{
"Expression": "ath11k_pci_id_table",
"PathPrefix": "drivers/net/wireless/ath/ath11k"
}Results: {
"Output": "drivers/net/wireless/ath/ath11k/pci.c-35-\ndrivers/net/wireless/ath/ath11k/pci.c:36:static const struct pci_device_id ath11k_pci_id_table[] = {\ndrivers/net/wireless/ath/ath11k/pci.c-37-\t{ PCI_VDEVICE(QCOM, QCA6390_DEVICE_ID) },\n--\ndrivers/net/wireless/ath/ath11k/pci.c-42-\ndrivers/net/wireless/ath/ath11k/pci.c:43:MODULE_DEVICE_TABLE(pci, ath11k_pci_id_table);\ndrivers/net/wireless/ath/ath11k/pci.c-44-\n--\ndrivers/net/wireless/ath/ath11k/pci.c=1296=static struct pci_driver ath11k_pci_driver = {\ndrivers/net/wireless/ath/ath11k/pci.c-1297-\t.name = \"ath11k_pci\",\ndrivers/net/wireless/ath/ath11k/pci.c:1298:\t.id_table = ath11k_pci_id_table,\ndrivers/net/wireless/ath/ath11k/pci.c-1299-\t.probe = ath11k_pci_probe,\n"
} |
| 11/2 | 2026/10/04 11:33 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 13709 output: 41 thoughts: 9 Thoughts: Okay, here's my attempt at summarizing the thought process, tailored for an expert audience, and written in the first person: **Analyzing the ath11k_ahb Driver** Right, so I'm looking at the `ath11k_ahb` driver here. Immediately, my mind jumps to the architectural implications. It's an AHB (Advanced High-performance Bus) based implementation, which means we're dealing with a specific set of constraints and performance characteristics right off the bat. The design choices made here are going to be heavily influenced by the bandwidth limitations and latency profile of AHB itself. I need to keep that context at the forefront. I'm mentally mapping the register layout, thinking about how the driver handles memory-mapped I/O. Are they using DMA effectively? Are there any potential bottlenecks in the interrupt handling paths? It's critical to determine if there's any unnecessary overhead there. Are they using scatter/gather lists? How is it handling the synchronization with the hardware to avoid data races? That's always a concern with concurrent access. I'm thinking about power management too. How does the driver interface with the power management framework? Does it implement any specific power-saving techniques relevant to the AHB bus – clock gating, etc.? The datasheet is obviously my next step, to get the absolute nitty gritty on how this bus is used on this particular SoC. I'm keen to examine how the driver handles different modes of operation – active, sleep, etc., and if there are any obvious opportunities for optimization. I'm already anticipating areas where DMA setup or completion might be overly complex or inefficient. I also need to verify that it's handling flow control correctly. From an expert perspective, I'm already anticipating the typical problems I've encountered with drivers that interact with AHB buses - bus contention issues, DMA coherency problems, and potentially, poorly optimized interrupt handlers that contribute to latency. I'm specifically looking for any indication of these issues. I want to see how these engineers accounted for AHB's limitations and if they addressed the inherent potential pitfalls. Ultimately, I'm expecting this driver to be performant, robust, and well-integrated within the existing system. |
| 12/2 | 2026/10/04 11:34 | tool | grepper |
0mArgs:{
"Expression": "ath11k_ahb_probe",
"PathPrefix": "drivers/net/wireless/ath/ath11k"
}Results: {
"Output": "drivers/net/wireless/ath/ath11k/ahb.c=1111=static int ath11k_ahb_fw_resource_deinit(struct ath11k_base *ab)\n--\ndrivers/net/wireless/ath/ath11k/ahb.c-1145-\ndrivers/net/wireless/ath/ath11k/ahb.c:1146:static int ath11k_ahb_probe(struct platform_device *pdev)\ndrivers/net/wireless/ath/ath11k/ahb.c-1147-{\n--\ndrivers/net/wireless/ath/ath11k/ahb.c=1343=static struct platform_driver ath11k_ahb_driver = {\n--\ndrivers/net/wireless/ath/ath11k/ahb.c-1347-\t},\ndrivers/net/wireless/ath/ath11k/ahb.c:1348:\t.probe = ath11k_ahb_probe,\ndrivers/net/wireless/ath/ath11k/ahb.c-1349-\t.remove = ath11k_ahb_remove,\n"
} |
| 13/2 | 2026/10/04 11:34 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 14528 output: 128 thoughts: 525 Thoughts: **Unreachable Code in Standard Fuzzing Environments** Okay, so looking at this patch, my initial assessment is that this `ath11k` code is essentially untouchable in typical fuzzing setups. It's exclusively for Qualcomm's 802.11ax hardware, specifically those devices hooked up via PCI or Qualcomm SoC AHB. Now, none of these devices are emulated by standard QEMU or GCE VMs. So, right off the bat, I see a clear indication of a structural unreachability issue in most fuzzing scenarios. Let's do a quick double-check on the file modifications. The patch touches these files: `drivers/net/wireless/ath/ath11k/core.h`, `drivers/net/wireless/ath/ath11k/mac.c`, `drivers/net/wireless/ath/ath11k/wmi.c`, and `drivers/net/wireless/ath/ath11k/wmi.h`. They are all *strictly* within `drivers/net/wireless/ath/ath11k/`. No interaction with the mac80211 core or netlink or any generic virtual wireless driver like mac80211_hwsim or virt_wifi here. This confirms that these changes are isolated to the Qualcomm ath11k driver. Now, let's circle back to the prompt's negative criteria. It mentions "Structurally unreachable hardware: * Vendor-specific PCIe switches, SmartNICs, or GPU drivers (e.g., mlxsw, pds_core, qed, ionic, amdgpu) requiring physical ASIC/PCIe cards not emulated in standard QEMU". This `ath11k` code fits that description perfectly: a vendor-specific Wi-Fi driver, requiring dedicated physical Qualcomm hardware over PCIe or AHB buses. Think QCA6390, WCN6855, IPQ8074, IPQ6018 – hardware that's simply not present in your average QEMU or GCE environment. Therefore, "WorthFuzzing" *must* be false. "FocusSymbols" will be empty because there's nothing to focus on, and "EnableConfigs" will also be empty. We have a clear and concise reason: the changes are confined to a driver designed for specific, non-emulated hardware. It's not worth fuzzing. |
| 14/2 | 2026/10/04 11:34 | tool | set-results |
0mArgs:{
"EnableConfigs": [],
"FocusSymbols": [],
"Reasoning": "The changes are entirely contained within the Qualcomm ath11k Wi-Fi driver (drivers/net/wireless/ath/ath11k/). This driver supports Qualcomm 802.11ax chipsets over PCIe and AHB/platform buses, requiring physical Qualcomm ASICs/silicon not emulated in standard QEMU or virtualized fuzzing environments. Because the hardware is structurally unreachable in standard fuzzing environments, the modified code is not worth fuzzing.",
"WorthFuzzing": false
}Results: {
"EnableConfigs": null,
"FocusSymbols": [],
"Reasoning": "The changes are entirely contained within the Qualcomm ath11k Wi-Fi driver (drivers/net/wireless/ath/ath11k/). This driver supports Qualcomm 802.11ax chipsets over PCIe and AHB/platform buses, requiring physical Qualcomm ASICs/silicon not emulated in standard QEMU or virtualized fuzzing environments. Because the hardware is structurally unreachable in standard fuzzing environments, the modified code is not worth fuzzing.",
"WorthFuzzing": false
} |
| 15/1 | 2026/10/04 11:34 | action | If |
0mArgs:{
"WorthFuzzing": false
}Results: null |
| Total Calls | Total Tokens | Avg Tokens | Total Duration (Seconds) | Avg Duration (Seconds) |
|---|
| Total Calls | Total Duration (Seconds) | Avg Duration (Seconds) |
|---|