mirror of
https://github.com/torvalds/linux.git
synced 2026-07-28 01:55:51 +02:00
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>
This commit is contained in:
parent
2f57f737db
commit
729cad3c3c
|
|
@ -355,6 +355,7 @@ struct ath12k_link_vif {
|
|||
struct wiphy_work bcn_tx_work;
|
||||
|
||||
bool set_wds_vdev_param;
|
||||
bool nawds_enabled;
|
||||
};
|
||||
|
||||
struct ath12k_vif {
|
||||
|
|
@ -495,6 +496,8 @@ struct ath12k_link_sta {
|
|||
u8 addr[ETH_ALEN];
|
||||
|
||||
u16 tcl_metadata;
|
||||
u16 ast_hash;
|
||||
u16 ast_idx;
|
||||
|
||||
/* the following are protected by ar->data_lock */
|
||||
u32 changed; /* IEEE80211_RC_* */
|
||||
|
|
|
|||
|
|
@ -6576,6 +6576,7 @@ static int ath12k_mac_sta_set_4addr(struct wiphy *wiphy, struct ath12k_sta *ahst
|
|||
struct ath12k_dp_link_peer *peer;
|
||||
struct ath12k_link_vif *arvif;
|
||||
struct ath12k_link_sta *arsta;
|
||||
struct ath12k_vif *ahvif;
|
||||
struct ath12k_dp *dp;
|
||||
unsigned long links;
|
||||
struct ath12k *ar;
|
||||
|
|
@ -6589,10 +6590,11 @@ static int ath12k_mac_sta_set_4addr(struct wiphy *wiphy, struct ath12k_sta *ahst
|
|||
continue;
|
||||
|
||||
arvif = arsta->arvif;
|
||||
ahvif = arvif->ahvif;
|
||||
ar = arvif->ar;
|
||||
|
||||
if (arvif->set_wds_vdev_param)
|
||||
goto skip_use_4addr;
|
||||
goto skip_nawds;
|
||||
|
||||
ath12k_dbg(ar->ab, ATH12K_DBG_MAC,
|
||||
"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
|
|||
return ret;
|
||||
}
|
||||
|
||||
skip_use_4addr:
|
||||
if (ahvif->dp_vif.tx_encap_type != ATH12K_HW_TXRX_ETHERNET)
|
||||
goto skip_nawds;
|
||||
|
||||
ret = ath12k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id,
|
||||
WMI_VDEV_PARAM_AP_ENABLE_NAWDS,
|
||||
WDS_EXT_ENABLE);
|
||||
if (ret) {
|
||||
ath12k_warn(ar->ab, "failed to set vdev %d nawds parameter: %d\n",
|
||||
arvif->vdev_id, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
arvif->nawds_enabled = true;
|
||||
|
||||
skip_nawds:
|
||||
dp = ath12k_ab_to_dp(ar->ab);
|
||||
spin_lock_bh(&dp->dp_lock);
|
||||
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)
|
|||
vif->offload_flags &= ~(IEEE80211_OFFLOAD_ENCAP_ENABLED |
|
||||
IEEE80211_OFFLOAD_DECAP_ENABLED);
|
||||
|
||||
if (vif->offload_flags & IEEE80211_OFFLOAD_ENCAP_ENABLED)
|
||||
if (vif->offload_flags & IEEE80211_OFFLOAD_ENCAP_ENABLED) {
|
||||
ahvif->dp_vif.tx_encap_type = ATH12K_HW_TXRX_ETHERNET;
|
||||
else if (test_bit(ATH12K_FLAG_RAW_MODE, &ab->dev_flags))
|
||||
vif->offload_flags |= IEEE80211_OFFLOAD_ENCAP_4ADDR;
|
||||
} else if (test_bit(ATH12K_FLAG_RAW_MODE, &ab->dev_flags)) {
|
||||
ahvif->dp_vif.tx_encap_type = ATH12K_HW_TXRX_RAW;
|
||||
else
|
||||
} else {
|
||||
ahvif->dp_vif.tx_encap_type = ATH12K_HW_TXRX_NATIVE_WIFI;
|
||||
}
|
||||
|
||||
ret = ath12k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id,
|
||||
param_id, ahvif->dp_vif.tx_encap_type);
|
||||
|
|
|
|||
|
|
@ -224,6 +224,8 @@ int ath12k_peer_create(struct ath12k *ar, struct ath12k_link_vif *arvif,
|
|||
HTT_TCL_META_DATA_PEER_ID) |
|
||||
u16_encode_bits(0,
|
||||
HTT_TCL_META_DATA_VALID_HTT);
|
||||
arsta->ast_hash = peer->ast_hash;
|
||||
arsta->ast_idx = peer->hw_peer_id;
|
||||
peer->link_id = arsta->link_id;
|
||||
|
||||
/* Fill ML info into created peer */
|
||||
|
|
|
|||
|
|
@ -57,6 +57,8 @@ static int ath12k_wifi7_dp_prepare_htt_metadata(struct sk_buff *skb)
|
|||
return 0;
|
||||
}
|
||||
|
||||
#define ATH12K_AST_HASH_MASK 0xF
|
||||
|
||||
/* TODO: Remove the export once this file is built with wifi7 ko */
|
||||
int ath12k_wifi7_dp_tx(struct ath12k_pdev_dp *dp_pdev, struct ath12k_link_vif *arvif,
|
||||
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
|
|||
struct ath12k_dp_vif *dp_vif = &ahvif->dp_vif;
|
||||
struct ath12k_dp_link_vif *dp_link_vif;
|
||||
struct dp_tx_ring *tx_ring;
|
||||
struct ethhdr *eth = NULL;
|
||||
u8 pool_id;
|
||||
u8 hal_ring_id;
|
||||
int ret;
|
||||
|
|
@ -96,6 +99,9 @@ int ath12k_wifi7_dp_tx(struct ath12k_pdev_dp *dp_pdev, struct ath12k_link_vif *a
|
|||
!ieee80211_is_data(hdr->frame_control))
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
if (skb_cb->flags & ATH12K_SKB_HW_80211_ENCAP)
|
||||
eth = (struct ethhdr *)skb->data;
|
||||
|
||||
pool_id = skb_get_queue_mapping(skb) & (ATH12K_HW_MAX_QUEUES - 1);
|
||||
|
||||
/* 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
|
|||
|
||||
ti.bank_id = dp_link_vif->bank_id;
|
||||
ti.meta_data_flags = dp_link_vif->tcl_metadata;
|
||||
ti.bss_ast_hash = dp_link_vif->ast_hash;
|
||||
ti.bss_ast_idx = dp_link_vif->ast_idx;
|
||||
|
||||
if (ieee80211_has_a4(hdr->frame_control) &&
|
||||
is_multicast_ether_addr(hdr->addr3) && arsta) {
|
||||
if (eth && is_multicast_ether_addr(eth->h_dest) && arsta) {
|
||||
ti.meta_data_flags = arsta->tcl_metadata;
|
||||
ti.bss_ast_hash = arsta->ast_hash & ATH12K_AST_HASH_MASK;
|
||||
ti.bss_ast_idx = arsta->ast_idx;
|
||||
ti.lookup_override = true;
|
||||
} else if (!eth && ieee80211_has_a4(hdr->frame_control) &&
|
||||
is_multicast_ether_addr(hdr->addr3) && arsta) {
|
||||
ti.meta_data_flags = arsta->tcl_metadata;
|
||||
ti.flags0 |= u32_encode_bits(1, HAL_TCL_DATA_CMD_INFO2_TO_FW);
|
||||
}
|
||||
|
|
@ -146,7 +159,7 @@ int ath12k_wifi7_dp_tx(struct ath12k_pdev_dp *dp_pdev, struct ath12k_link_vif *a
|
|||
msdu_ext_desc = true;
|
||||
}
|
||||
|
||||
if (gsn_valid) {
|
||||
if (gsn_valid && !ti.lookup_override) {
|
||||
/* Reset and Initialize meta_data_flags with Global Sequence
|
||||
* Number (GSN) info.
|
||||
*/
|
||||
|
|
@ -154,6 +167,14 @@ int ath12k_wifi7_dp_tx(struct ath12k_pdev_dp *dp_pdev, struct ath12k_link_vif *a
|
|||
u32_encode_bits(HTT_TCL_META_DATA_TYPE_GLOBAL_SEQ_NUM,
|
||||
HTT_TCL_META_DATA_TYPE) |
|
||||
u32_encode_bits(mcbc_gsn, HTT_TCL_META_DATA_GLOBAL_SEQ_NUM);
|
||||
|
||||
/*
|
||||
* Since NAWDS enabled for this vdev firmware expects
|
||||
* this flag to be set for sending 3-address multicast frame.
|
||||
*/
|
||||
ti.meta_data_flags |=
|
||||
u32_encode_bits(arvif->nawds_enabled,
|
||||
HTT_TCL_META_DATA_GLOBAL_SEQ_HOST_INSPECTED);
|
||||
}
|
||||
|
||||
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
|
|||
ti.lmac_id = dp_link_vif->lmac_id;
|
||||
|
||||
ti.vdev_id = dp_link_vif->vdev_id;
|
||||
if (gsn_valid)
|
||||
ti.vdev_id += HTT_TX_MLO_MCAST_HOST_REINJECT_BASE_VDEV_ID;
|
||||
|
||||
ti.bss_ast_hash = dp_link_vif->ast_hash;
|
||||
ti.bss_ast_idx = dp_link_vif->ast_idx;
|
||||
if (gsn_valid && !ti.lookup_override)
|
||||
ti.vdev_id += HTT_TX_MLO_MCAST_HOST_REINJECT_BASE_VDEV_ID;
|
||||
else if (arvif->nawds_enabled && is_mcast && !ti.lookup_override)
|
||||
ti.meta_data_flags |=
|
||||
u32_encode_bits(1, HTT_TCL_META_DATA_HOST_INSPECTED_MISSION);
|
||||
|
||||
ti.dscp_tid_tbl_idx = 0;
|
||||
|
||||
if (skb->ip_summed == CHECKSUM_PARTIAL &&
|
||||
|
|
|
|||
|
|
@ -59,7 +59,9 @@ void ath12k_wifi7_hal_tx_cmd_desc_setup(struct ath12k_base *ab,
|
|||
le32_encode_bits(ti->lmac_id, HAL_TCL_DATA_CMD_INFO3_PMAC_ID) |
|
||||
le32_encode_bits(ti->vdev_id, HAL_TCL_DATA_CMD_INFO3_VDEV_ID);
|
||||
|
||||
tcl_cmd->info4 = le32_encode_bits(ti->bss_ast_idx,
|
||||
tcl_cmd->info4 = le32_encode_bits(ti->lookup_override,
|
||||
HAL_TCL_DATA_CMD_INFO4_IDX_LOOKUP_OVERRIDE) |
|
||||
le32_encode_bits(ti->bss_ast_idx,
|
||||
HAL_TCL_DATA_CMD_INFO4_SEARCH_INDEX) |
|
||||
le32_encode_bits(ti->bss_ast_hash,
|
||||
HAL_TCL_DATA_CMD_INFO4_CACHE_SET_NUM);
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@ struct hal_tx_info {
|
|||
u8 dscp_tid_tbl_idx;
|
||||
bool enable_mesh;
|
||||
int bank_id;
|
||||
bool lookup_override;
|
||||
};
|
||||
|
||||
/* TODO: Check if the actual desc macros can be used instead */
|
||||
|
|
|
|||
|
|
@ -4192,7 +4192,8 @@ ath12k_wmi_copy_resource_config(struct ath12k_base *ab,
|
|||
cpu_to_le32(1 << WMI_RSRC_CFG_HOST_SVC_FLAG_REO_QREF_SUPPORT_BIT);
|
||||
wmi_cfg->ema_max_vap_cnt = cpu_to_le32(tg_cfg->ema_max_vap_cnt);
|
||||
wmi_cfg->ema_max_profile_period = cpu_to_le32(tg_cfg->ema_max_profile_period);
|
||||
wmi_cfg->flags2 |= cpu_to_le32(WMI_RSRC_CFG_FLAGS2_CALC_NEXT_DTIM_COUNT_SET);
|
||||
wmi_cfg->flags2 |= cpu_to_le32(WMI_RSRC_CFG_FLAGS2_CALC_NEXT_DTIM_COUNT_SET |
|
||||
WMI_RSRC_CFG_FLAGS2_FW_AST_INDICATION_DISABLE);
|
||||
}
|
||||
|
||||
static int ath12k_init_cmd_send(struct ath12k_wmi_pdev *wmi,
|
||||
|
|
|
|||
|
|
@ -2334,6 +2334,14 @@ enum wmi_preamble {
|
|||
WMI_VDEV_PREAMBLE_SHORT = 2,
|
||||
};
|
||||
|
||||
/*
|
||||
* This will be used to set for WMI_VDEV_PARAM_AP_ENABLE_NAWDS
|
||||
* whenever 4addr station connects in wds offload case.
|
||||
* This is for enabling multicast to unicast conversion support in
|
||||
* firmware
|
||||
*/
|
||||
#define WDS_EXT_ENABLE 1
|
||||
|
||||
enum wmi_peer_4addr_allow_frame {
|
||||
WMI_PEER_4ADDR_ALLOW_DATA_FRAME = 1,
|
||||
WMI_PEER_4ADDR_ALLOW_EAPOL_DATA_FRAME = 2,
|
||||
|
|
@ -2559,6 +2567,7 @@ struct wmi_init_cmd {
|
|||
#define WMI_RSRC_CFG_FLAGS2_RX_PEER_METADATA_VERSION GENMASK(5, 4)
|
||||
#define WMI_RSRC_CFG_FLAG1_BSS_CHANNEL_INFO_64 BIT(5)
|
||||
#define WMI_RSRC_CFG_FLAGS2_CALC_NEXT_DTIM_COUNT_SET BIT(9)
|
||||
#define WMI_RSRC_CFG_FLAGS2_FW_AST_INDICATION_DISABLE BIT(18)
|
||||
#define WMI_RSRC_CFG_FLAG1_ACK_RSSI BIT(18)
|
||||
|
||||
struct ath12k_wmi_resource_config_params {
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user