Skip to content

Commit 729cad3

Browse files
Tamizh Chelvam Rajajeff-t-johnson
authored andcommitted
wifi: ath12k: Add 4-address mode support for eth offload
Currently driver does not enable the hardware/firmware support for handling 4-address multicast frames in the Tx/Rx path when 8023_ENCAP_OFFLOAD is enabled. Add the required support to ensure correct processing of multicast traffic in 4-address mode. Enable this functionality by setting the WMI_VDEV_PARAM_AP_ENABLE_NAWDS vdev parameter when the 8023_ENCAP_OFFLOAD feature is active. Override peer metadata values for 4-address multicast packet transmission by using the station's ast_hash and ast_idx instead of vdev-level metadata, and set HAL_TCL_DATA_CMD_INFO4_IDX_LOOKUP_OVERRIDE to indicate this override. Suppress firmware peer-map events for 4-address frames by setting the WMI_RSRC_CFG_FLAGS2_FW_AST_INDICATION_DISABLE flag during WMI initialization. This prevents inconsistencies in the host's peer list. Add the IEEE80211_OFFLOAD_ENCAP_4ADDR VIF offload flag to notify mac80211 that 4-address Ethernet encapsulation offload is supported. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.6-01243-QCAHKSWPL_SILICONZ-1 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-4-tamizh.raja@oss.qualcomm.com Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
1 parent 2f57f73 commit 729cad3

8 files changed

Lines changed: 72 additions & 13 deletions

File tree

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -355,6 +355,7 @@ struct ath12k_link_vif {
355355
struct wiphy_work bcn_tx_work;
356356

357357
bool set_wds_vdev_param;
358+
bool nawds_enabled;
358359
};
359360

360361
struct ath12k_vif {
@@ -495,6 +496,8 @@ struct ath12k_link_sta {
495496
u8 addr[ETH_ALEN];
496497

497498
u16 tcl_metadata;
499+
u16 ast_hash;
500+
u16 ast_idx;
498501

499502
/* the following are protected by ar->data_lock */
500503
u32 changed; /* IEEE80211_RC_* */

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

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6576,6 +6576,7 @@ static int ath12k_mac_sta_set_4addr(struct wiphy *wiphy, struct ath12k_sta *ahst
65766576
struct ath12k_dp_link_peer *peer;
65776577
struct ath12k_link_vif *arvif;
65786578
struct ath12k_link_sta *arsta;
6579+
struct ath12k_vif *ahvif;
65796580
struct ath12k_dp *dp;
65806581
unsigned long links;
65816582
struct ath12k *ar;
@@ -6589,10 +6590,11 @@ static int ath12k_mac_sta_set_4addr(struct wiphy *wiphy, struct ath12k_sta *ahst
65896590
continue;
65906591

65916592
arvif = arsta->arvif;
6593+
ahvif = arvif->ahvif;
65926594
ar = arvif->ar;
65936595

65946596
if (arvif->set_wds_vdev_param)
6595-
goto skip_use_4addr;
6597+
goto skip_nawds;
65966598

65976599
ath12k_dbg(ar->ab, ATH12K_DBG_MAC,
65986600
"setting USE_4ADDR for peer %pM\n", arsta->addr);
@@ -6607,7 +6609,21 @@ static int ath12k_mac_sta_set_4addr(struct wiphy *wiphy, struct ath12k_sta *ahst
66076609
return ret;
66086610
}
66096611

6610-
skip_use_4addr:
6612+
if (ahvif->dp_vif.tx_encap_type != ATH12K_HW_TXRX_ETHERNET)
6613+
goto skip_nawds;
6614+
6615+
ret = ath12k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id,
6616+
WMI_VDEV_PARAM_AP_ENABLE_NAWDS,
6617+
WDS_EXT_ENABLE);
6618+
if (ret) {
6619+
ath12k_warn(ar->ab, "failed to set vdev %d nawds parameter: %d\n",
6620+
arvif->vdev_id, ret);
6621+
return ret;
6622+
}
6623+
6624+
arvif->nawds_enabled = true;
6625+
6626+
skip_nawds:
66116627
dp = ath12k_ab_to_dp(ar->ab);
66126628
spin_lock_bh(&dp->dp_lock);
66136629
peer = ath12k_dp_link_peer_find_by_vdev_and_addr(dp, arvif->vdev_id,
@@ -10098,12 +10114,14 @@ static void ath12k_mac_update_vif_offload(struct ath12k_link_vif *arvif)
1009810114
vif->offload_flags &= ~(IEEE80211_OFFLOAD_ENCAP_ENABLED |
1009910115
IEEE80211_OFFLOAD_DECAP_ENABLED);
1010010116

10101-
if (vif->offload_flags & IEEE80211_OFFLOAD_ENCAP_ENABLED)
10117+
if (vif->offload_flags & IEEE80211_OFFLOAD_ENCAP_ENABLED) {
1010210118
ahvif->dp_vif.tx_encap_type = ATH12K_HW_TXRX_ETHERNET;
10103-
else if (test_bit(ATH12K_FLAG_RAW_MODE, &ab->dev_flags))
10119+
vif->offload_flags |= IEEE80211_OFFLOAD_ENCAP_4ADDR;
10120+
} else if (test_bit(ATH12K_FLAG_RAW_MODE, &ab->dev_flags)) {
1010410121
ahvif->dp_vif.tx_encap_type = ATH12K_HW_TXRX_RAW;
10105-
else
10122+
} else {
1010610123
ahvif->dp_vif.tx_encap_type = ATH12K_HW_TXRX_NATIVE_WIFI;
10124+
}
1010710125

1010810126
ret = ath12k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id,
1010910127
param_id, ahvif->dp_vif.tx_encap_type);

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,8 @@ int ath12k_peer_create(struct ath12k *ar, struct ath12k_link_vif *arvif,
224224
HTT_TCL_META_DATA_PEER_ID) |
225225
u16_encode_bits(0,
226226
HTT_TCL_META_DATA_VALID_HTT);
227+
arsta->ast_hash = peer->ast_hash;
228+
arsta->ast_idx = peer->hw_peer_id;
227229
peer->link_id = arsta->link_id;
228230

229231
/* Fill ML info into created peer */

drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,8 @@ static int ath12k_wifi7_dp_prepare_htt_metadata(struct sk_buff *skb)
5757
return 0;
5858
}
5959

60+
#define ATH12K_AST_HASH_MASK 0xF
61+
6062
/* TODO: Remove the export once this file is built with wifi7 ko */
6163
int ath12k_wifi7_dp_tx(struct ath12k_pdev_dp *dp_pdev, struct ath12k_link_vif *arvif,
6264
struct ath12k_link_sta *arsta, struct sk_buff *skb,
@@ -78,6 +80,7 @@ int ath12k_wifi7_dp_tx(struct ath12k_pdev_dp *dp_pdev, struct ath12k_link_vif *a
7880
struct ath12k_dp_vif *dp_vif = &ahvif->dp_vif;
7981
struct ath12k_dp_link_vif *dp_link_vif;
8082
struct dp_tx_ring *tx_ring;
83+
struct ethhdr *eth = NULL;
8184
u8 pool_id;
8285
u8 hal_ring_id;
8386
int ret;
@@ -96,6 +99,9 @@ int ath12k_wifi7_dp_tx(struct ath12k_pdev_dp *dp_pdev, struct ath12k_link_vif *a
9699
!ieee80211_is_data(hdr->frame_control))
97100
return -EOPNOTSUPP;
98101

102+
if (skb_cb->flags & ATH12K_SKB_HW_80211_ENCAP)
103+
eth = (struct ethhdr *)skb->data;
104+
99105
pool_id = skb_get_queue_mapping(skb) & (ATH12K_HW_MAX_QUEUES - 1);
100106

101107
/* Let the default ring selection be based on current processor
@@ -124,9 +130,16 @@ int ath12k_wifi7_dp_tx(struct ath12k_pdev_dp *dp_pdev, struct ath12k_link_vif *a
124130

125131
ti.bank_id = dp_link_vif->bank_id;
126132
ti.meta_data_flags = dp_link_vif->tcl_metadata;
133+
ti.bss_ast_hash = dp_link_vif->ast_hash;
134+
ti.bss_ast_idx = dp_link_vif->ast_idx;
127135

128-
if (ieee80211_has_a4(hdr->frame_control) &&
129-
is_multicast_ether_addr(hdr->addr3) && arsta) {
136+
if (eth && is_multicast_ether_addr(eth->h_dest) && arsta) {
137+
ti.meta_data_flags = arsta->tcl_metadata;
138+
ti.bss_ast_hash = arsta->ast_hash & ATH12K_AST_HASH_MASK;
139+
ti.bss_ast_idx = arsta->ast_idx;
140+
ti.lookup_override = true;
141+
} else if (!eth && ieee80211_has_a4(hdr->frame_control) &&
142+
is_multicast_ether_addr(hdr->addr3) && arsta) {
130143
ti.meta_data_flags = arsta->tcl_metadata;
131144
ti.flags0 |= u32_encode_bits(1, HAL_TCL_DATA_CMD_INFO2_TO_FW);
132145
}
@@ -146,14 +159,22 @@ int ath12k_wifi7_dp_tx(struct ath12k_pdev_dp *dp_pdev, struct ath12k_link_vif *a
146159
msdu_ext_desc = true;
147160
}
148161

149-
if (gsn_valid) {
162+
if (gsn_valid && !ti.lookup_override) {
150163
/* Reset and Initialize meta_data_flags with Global Sequence
151164
* Number (GSN) info.
152165
*/
153166
ti.meta_data_flags =
154167
u32_encode_bits(HTT_TCL_META_DATA_TYPE_GLOBAL_SEQ_NUM,
155168
HTT_TCL_META_DATA_TYPE) |
156169
u32_encode_bits(mcbc_gsn, HTT_TCL_META_DATA_GLOBAL_SEQ_NUM);
170+
171+
/*
172+
* Since NAWDS enabled for this vdev firmware expects
173+
* this flag to be set for sending 3-address multicast frame.
174+
*/
175+
ti.meta_data_flags |=
176+
u32_encode_bits(arvif->nawds_enabled,
177+
HTT_TCL_META_DATA_GLOBAL_SEQ_HOST_INSPECTED);
157178
}
158179

159180
ti.encap_type = ath12k_dp_tx_get_encap_type(ab, skb);
@@ -164,11 +185,13 @@ int ath12k_wifi7_dp_tx(struct ath12k_pdev_dp *dp_pdev, struct ath12k_link_vif *a
164185
ti.lmac_id = dp_link_vif->lmac_id;
165186

166187
ti.vdev_id = dp_link_vif->vdev_id;
167-
if (gsn_valid)
188+
189+
if (gsn_valid && !ti.lookup_override)
168190
ti.vdev_id += HTT_TX_MLO_MCAST_HOST_REINJECT_BASE_VDEV_ID;
191+
else if (arvif->nawds_enabled && is_mcast && !ti.lookup_override)
192+
ti.meta_data_flags |=
193+
u32_encode_bits(1, HTT_TCL_META_DATA_HOST_INSPECTED_MISSION);
169194

170-
ti.bss_ast_hash = dp_link_vif->ast_hash;
171-
ti.bss_ast_idx = dp_link_vif->ast_idx;
172195
ti.dscp_tid_tbl_idx = 0;
173196

174197
if (skb->ip_summed == CHECKSUM_PARTIAL &&

drivers/net/wireless/ath/ath12k/wifi7/hal_tx.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,9 @@ void ath12k_wifi7_hal_tx_cmd_desc_setup(struct ath12k_base *ab,
5959
le32_encode_bits(ti->lmac_id, HAL_TCL_DATA_CMD_INFO3_PMAC_ID) |
6060
le32_encode_bits(ti->vdev_id, HAL_TCL_DATA_CMD_INFO3_VDEV_ID);
6161

62-
tcl_cmd->info4 = le32_encode_bits(ti->bss_ast_idx,
62+
tcl_cmd->info4 = le32_encode_bits(ti->lookup_override,
63+
HAL_TCL_DATA_CMD_INFO4_IDX_LOOKUP_OVERRIDE) |
64+
le32_encode_bits(ti->bss_ast_idx,
6365
HAL_TCL_DATA_CMD_INFO4_SEARCH_INDEX) |
6466
le32_encode_bits(ti->bss_ast_hash,
6567
HAL_TCL_DATA_CMD_INFO4_CACHE_SET_NUM);

drivers/net/wireless/ath/ath12k/wifi7/hal_tx.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ struct hal_tx_info {
3434
u8 dscp_tid_tbl_idx;
3535
bool enable_mesh;
3636
int bank_id;
37+
bool lookup_override;
3738
};
3839

3940
/* TODO: Check if the actual desc macros can be used instead */

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4192,7 +4192,8 @@ ath12k_wmi_copy_resource_config(struct ath12k_base *ab,
41924192
cpu_to_le32(1 << WMI_RSRC_CFG_HOST_SVC_FLAG_REO_QREF_SUPPORT_BIT);
41934193
wmi_cfg->ema_max_vap_cnt = cpu_to_le32(tg_cfg->ema_max_vap_cnt);
41944194
wmi_cfg->ema_max_profile_period = cpu_to_le32(tg_cfg->ema_max_profile_period);
4195-
wmi_cfg->flags2 |= cpu_to_le32(WMI_RSRC_CFG_FLAGS2_CALC_NEXT_DTIM_COUNT_SET);
4195+
wmi_cfg->flags2 |= cpu_to_le32(WMI_RSRC_CFG_FLAGS2_CALC_NEXT_DTIM_COUNT_SET |
4196+
WMI_RSRC_CFG_FLAGS2_FW_AST_INDICATION_DISABLE);
41964197
}
41974198

41984199
static int ath12k_init_cmd_send(struct ath12k_wmi_pdev *wmi,

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

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2334,6 +2334,14 @@ enum wmi_preamble {
23342334
WMI_VDEV_PREAMBLE_SHORT = 2,
23352335
};
23362336

2337+
/*
2338+
* This will be used to set for WMI_VDEV_PARAM_AP_ENABLE_NAWDS
2339+
* whenever 4addr station connects in wds offload case.
2340+
* This is for enabling multicast to unicast conversion support in
2341+
* firmware
2342+
*/
2343+
#define WDS_EXT_ENABLE 1
2344+
23372345
enum wmi_peer_4addr_allow_frame {
23382346
WMI_PEER_4ADDR_ALLOW_DATA_FRAME = 1,
23392347
WMI_PEER_4ADDR_ALLOW_EAPOL_DATA_FRAME = 2,
@@ -2559,6 +2567,7 @@ struct wmi_init_cmd {
25592567
#define WMI_RSRC_CFG_FLAGS2_RX_PEER_METADATA_VERSION GENMASK(5, 4)
25602568
#define WMI_RSRC_CFG_FLAG1_BSS_CHANNEL_INFO_64 BIT(5)
25612569
#define WMI_RSRC_CFG_FLAGS2_CALC_NEXT_DTIM_COUNT_SET BIT(9)
2570+
#define WMI_RSRC_CFG_FLAGS2_FW_AST_INDICATION_DISABLE BIT(18)
25622571
#define WMI_RSRC_CFG_FLAG1_ACK_RSSI BIT(18)
25632572

25642573
struct ath12k_wmi_resource_config_params {

0 commit comments

Comments
 (0)