Skip to content

Commit 6d0572f

Browse files
Tamizh Chelvam Rajajeff-t-johnson
authored andcommitted
wifi: ath12k: Add support for 4-address NULL frame handling
Currently, the firmware processes all NULL frames internally and does not forward them to the host. As a result, the host never receives 4-address NULL frames sent by a 4-address station. These 4-address NULL frames are sent by the station to indicate to the AP that it is operating in 4-address mode. Enable WMI_RSRC_CFG_FLAGS2_WDS_NULL_FRAME_SUPPORT flag during WMI initialization after verifying the WMI_SERVICE_WDS_NULL_FRAME_SUPPORT service capability. This enables the firmware to forward all NULL frames to the host. Add host-side handling to parse 4-address NULL frames and forward them to mac80211 to support proper AP_VLAN interface creation. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.6-01243-QCAHKSWPL_SILICONZ-1 Co-developed-by: Sarika Sharma <sarika.sharma@oss.qualcomm.com> Signed-off-by: Sarika Sharma <sarika.sharma@oss.qualcomm.com> Signed-off-by: Tamizh Chelvam Raja <tamizh.raja@oss.qualcomm.com> Reviewed-by: Rameshkumar Sundaram <rameshkumar.sundaram@oss.qualcomm.com> Reviewed-by: Baochen Qiang <baochen.qiang@oss.qualcomm.com> Link: https://patch.msgid.link/20260525110942.2890212-5-tamizh.raja@oss.qualcomm.com Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
1 parent 729cad3 commit 6d0572f

3 files changed

Lines changed: 50 additions & 4 deletions

File tree

drivers/net/wireless/ath/ath12k/peer.c

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -220,10 +220,9 @@ int ath12k_peer_create(struct ath12k *ar, struct ath12k_link_vif *arvif,
220220
ahsta->link[link_id]);
221221
/* TODO: Split DP related field usage to DP peer structure */
222222
arsta->tcl_metadata = u16_encode_bits(0, HTT_TCL_META_DATA_TYPE) |
223-
u16_encode_bits(peer->peer_id,
224-
HTT_TCL_META_DATA_PEER_ID) |
225-
u16_encode_bits(0,
226-
HTT_TCL_META_DATA_VALID_HTT);
223+
u16_encode_bits(peer->peer_id,
224+
HTT_TCL_META_DATA_PEER_ID) |
225+
u16_encode_bits(0, HTT_TCL_META_DATA_VALID_HTT);
227226
arsta->ast_hash = peer->ast_hash;
228227
arsta->ast_idx = peer->hw_peer_id;
229228
peer->link_id = arsta->link_id;

drivers/net/wireless/ath/ath12k/wmi.c

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4194,6 +4194,10 @@ ath12k_wmi_copy_resource_config(struct ath12k_base *ab,
41944194
wmi_cfg->ema_max_profile_period = cpu_to_le32(tg_cfg->ema_max_profile_period);
41954195
wmi_cfg->flags2 |= cpu_to_le32(WMI_RSRC_CFG_FLAGS2_CALC_NEXT_DTIM_COUNT_SET |
41964196
WMI_RSRC_CFG_FLAGS2_FW_AST_INDICATION_DISABLE);
4197+
4198+
if (tg_cfg->is_wds_null_frame_supported)
4199+
wmi_cfg->flags2 |=
4200+
cpu_to_le32(WMI_RSRC_CFG_FLAGS2_WDS_NULL_FRAME_SUPPORT);
41974201
}
41984202

41994203
static int ath12k_init_cmd_send(struct ath12k_wmi_pdev *wmi,
@@ -4403,6 +4407,9 @@ int ath12k_wmi_cmd_init(struct ath12k_base *ab)
44034407
ab->wmi_ab.svc_map))
44044408
arg.res_cfg.is_reg_cc_ext_event_supported = true;
44054409

4410+
if (test_bit(WMI_TLV_SERVICE_WDS_NULL_FRAME_SUPPORT, ab->wmi_ab.svc_map))
4411+
arg.res_cfg.is_wds_null_frame_supported = true;
4412+
44064413
ab->hw_params->wmi_init(ab, &arg.res_cfg);
44074414
ab->wow.wmi_conf_rx_decap_mode = arg.res_cfg.rx_decap_mode;
44084415

@@ -7224,7 +7231,11 @@ static void ath12k_mgmt_rx_event(struct ath12k_base *ab, struct sk_buff *skb)
72247231
struct ath12k_wmi_mgmt_rx_arg rx_ev = {};
72257232
struct ath12k *ar;
72267233
struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
7234+
struct ieee80211_sta *pubsta = NULL;
7235+
struct ath12k_dp_link_peer *peer;
72277236
struct ieee80211_hdr *hdr;
7237+
bool is_4addr_null_pkt;
7238+
struct ath12k_dp *dp;
72287239
u16 fc;
72297240
struct ieee80211_supported_band *sband;
72307241
s32 noise_floor;
@@ -7299,6 +7310,38 @@ static void ath12k_mgmt_rx_event(struct ath12k_base *ab, struct sk_buff *skb)
72997310
hdr = (struct ieee80211_hdr *)skb->data;
73007311
fc = le16_to_cpu(hdr->frame_control);
73017312

7313+
is_4addr_null_pkt = (ieee80211_is_nullfunc(hdr->frame_control) ||
7314+
ieee80211_is_qos_nullfunc(hdr->frame_control)) &&
7315+
ieee80211_has_a4(hdr->frame_control);
7316+
7317+
/*
7318+
* Add check to drop frames other than 4-address NULL frame. Since
7319+
* firmware sends all NULL frames in this path (3-address and 4-address)
7320+
*/
7321+
if (ieee80211_is_data(hdr->frame_control) && !is_4addr_null_pkt) {
7322+
dev_kfree_skb(skb);
7323+
goto exit;
7324+
}
7325+
7326+
if (is_4addr_null_pkt) {
7327+
dp = ath12k_ab_to_dp(ar->ab);
7328+
spin_lock_bh(&dp->dp_lock);
7329+
peer = ath12k_dp_link_peer_find_by_pdev_and_addr(dp, ar->pdev_idx,
7330+
hdr->addr2);
7331+
if (!peer) {
7332+
spin_unlock_bh(&dp->dp_lock);
7333+
dev_kfree_skb(skb);
7334+
goto exit;
7335+
}
7336+
pubsta = peer->sta;
7337+
if (pubsta && pubsta->valid_links) {
7338+
status->link_valid = 1;
7339+
status->link_id = peer->link_id;
7340+
}
7341+
spin_unlock_bh(&dp->dp_lock);
7342+
goto send_rx;
7343+
}
7344+
73027345
/* Firmware is guaranteed to report all essential management frames via
73037346
* WMI while it can deliver some extra via HTT. Since there can be
73047347
* duplicates split the reporting wrt monitor/sniffing.
@@ -7322,6 +7365,7 @@ static void ath12k_mgmt_rx_event(struct ath12k_base *ab, struct sk_buff *skb)
73227365
if (ieee80211_is_beacon(hdr->frame_control))
73237366
ath12k_mac_handle_beacon(ar, skb);
73247367

7368+
send_rx:
73257369
ath12k_dbg(ab, ATH12K_DBG_MGMT,
73267370
"event mgmt rx skb %p len %d ftype %02x stype %02x\n",
73277371
skb, skb->len,

drivers/net/wireless/ath/ath12k/wmi.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2278,6 +2278,7 @@ enum wmi_tlv_service {
22782278

22792279
WMI_TLV_SERVICE_PEER_METADATA_V1A_V1B_SUPPORT = 365,
22802280
WMI_TLV_SERVICE_THERM_THROT_POUT_REDUCTION = 410,
2281+
WMI_TLV_SERVICE_WDS_NULL_FRAME_SUPPORT = 421,
22812282
WMI_TLV_SERVICE_IS_TARGET_IPA = 425,
22822283
WMI_TLV_SERVICE_THERM_THROT_TX_CHAIN_MASK = 426,
22832284
WMI_TLV_SERVICE_THERM_THROT_5_LEVELS = 429,
@@ -2511,6 +2512,7 @@ struct ath12k_wmi_resource_config_arg {
25112512
u32 ema_max_vap_cnt;
25122513
u32 ema_max_profile_period;
25132514
bool is_reg_cc_ext_event_supported;
2515+
bool is_wds_null_frame_supported;
25142516
};
25152517

25162518
struct ath12k_wmi_init_cmd_arg {
@@ -2568,6 +2570,7 @@ struct wmi_init_cmd {
25682570
#define WMI_RSRC_CFG_FLAG1_BSS_CHANNEL_INFO_64 BIT(5)
25692571
#define WMI_RSRC_CFG_FLAGS2_CALC_NEXT_DTIM_COUNT_SET BIT(9)
25702572
#define WMI_RSRC_CFG_FLAGS2_FW_AST_INDICATION_DISABLE BIT(18)
2573+
#define WMI_RSRC_CFG_FLAGS2_WDS_NULL_FRAME_SUPPORT BIT(22)
25712574
#define WMI_RSRC_CFG_FLAG1_ACK_RSSI BIT(18)
25722575

25732576
struct ath12k_wmi_resource_config_params {

0 commit comments

Comments
 (0)