From 6b4d09abe7db56e59dbdac6d7318acafaf8c8c09 Mon Sep 17 00:00:00 2001 From: Aloka Dixit Date: Thu, 20 Jan 2022 18:33:05 -0800 Subject: [PATCH 05/14] ath12k: MBSSID configuration during vdev create/start Configure multiple BSSID flags and index of the transmitting interface in vdev create/start commands depending on the service bit WMI_TLV_SERVICE_MBSS_PARAM_IN_VDEV_START_SUPPORT. Signed-off-by: Aloka Dixit --- drivers/net/wireless/ath/ath12k/mac.c | 70 +++++++++++++++++++++++++-- drivers/net/wireless/ath/ath12k/wmi.c | 5 ++ drivers/net/wireless/ath/ath12k/wmi.h | 25 ++++++++-- 3 files changed, 91 insertions(+), 9 deletions(-) --- a/drivers/net/wireless/ath/ath12k/mac.c +++ b/drivers/net/wireless/ath/ath12k/mac.c @@ -6159,17 +6159,62 @@ ath12k_mac_get_vdev_stats_id(struct ath1 return vdev_stats_id; } -static void -ath12k_mac_setup_vdev_create_params(struct ath12k_vif *arvif, - struct vdev_create_params *params) +static int ath12k_mac_setup_vdev_params_mbssid(struct ath12k_vif *arvif, + u32 *flags, u32 *tx_vdev_id) +{ + struct ath12k *ar = arvif->ar; + struct ath12k_vif *tx_arvif; + struct ieee80211_vif *tx_vif; + + *tx_vdev_id = 0; + tx_vif = arvif->vif->mbssid_tx_vif; + if (!tx_vif) { + *flags = WMI_HOST_VDEV_FLAGS_NON_MBSSID_AP; + return 0; + } + + tx_arvif = (void *)tx_vif->drv_priv; + + if (arvif->vif->bss_conf.nontransmitted) { + if (ar->hw->wiphy != ieee80211_vif_to_wdev(tx_vif)->wiphy) + return -EINVAL; + + *flags = WMI_HOST_VDEV_FLAGS_NON_TRANSMIT_AP; + *tx_vdev_id = ath12k_vif_to_arvif(tx_vif)->vdev_id; + } else if (tx_arvif == arvif) { + *flags = WMI_HOST_VDEV_FLAGS_TRANSMIT_AP; + } else { + return -EINVAL; + } + + if (arvif->vif->bss_conf.ema_ap) + *flags |= WMI_HOST_VDEV_FLAGS_EMA_MODE; + + return 0; +} + +static int ath12k_mac_setup_vdev_create_params(struct ath12k_vif *arvif, + struct vdev_create_params *params) { struct ath12k *ar = arvif->ar; struct ath12k_pdev *pdev = ar->pdev; + int ret; params->if_id = arvif->vdev_id; params->type = arvif->vdev_type; params->subtype = arvif->vdev_subtype; params->pdev_id = pdev->pdev_id; + params->mbssid_flags = 0; + params->mbssid_tx_vdev_id = 0; + + if (!test_bit(WMI_TLV_SERVICE_MBSS_PARAM_IN_VDEV_START_SUPPORT, + ar->ab->wmi_ab.svc_map)) { + ret = ath12k_mac_setup_vdev_params_mbssid(arvif, + ¶ms->mbssid_flags, + ¶ms->mbssid_tx_vdev_id); + if (ret) + return ret; + } if (pdev->cap.supported_bands & WMI_HOST_WLAN_2G_CAP) { params->chains[NL80211_BAND_2GHZ].tx = ar->num_tx_chains; @@ -6186,6 +6231,7 @@ ath12k_mac_setup_vdev_create_params(stru } params->if_stats_id = ath12k_mac_get_vdev_stats_id(arvif); + return 0; } static void ath12k_mac_op_update_vif_offload(struct ieee80211_hw *hw, @@ -6326,7 +6372,12 @@ static int ath12k_mac_op_add_interface(s for (i = 0; i < ARRAY_SIZE(vif->hw_queue); i++) vif->hw_queue[i] = i % (ATH12K_HW_MAX_QUEUES - 1); - ath12k_mac_setup_vdev_create_params(arvif, &vdev_param); + ret = ath12k_mac_setup_vdev_create_params(arvif, &vdev_param); + if (ret) { + ath12k_warn(ab, "failed to create vdev parameters %d: %d\n", + arvif->vdev_id, ret); + goto err; + } ret = ath12k_wmi_vdev_create(ar, vif->addr, &vdev_param); if (ret) { @@ -6740,6 +6791,17 @@ ath12k_mac_vdev_start_restart(struct ath arg.pref_tx_streams = ar->num_tx_chains; arg.pref_rx_streams = ar->num_rx_chains; + arg.mbssid_flags = 0; + arg.mbssid_tx_vdev_id = 0; + if (test_bit(WMI_TLV_SERVICE_MBSS_PARAM_IN_VDEV_START_SUPPORT, + ar->ab->wmi_ab.svc_map)) { + ret = ath12k_mac_setup_vdev_params_mbssid(arvif, + &arg.mbssid_flags, + &arg.mbssid_tx_vdev_id); + if (ret) + return ret; + } + if (arvif->vdev_type == WMI_VDEV_TYPE_AP) { arg.ssid = arvif->u.ap.ssid; arg.ssid_len = arvif->u.ap.ssid_len; --- a/drivers/net/wireless/ath/ath12k/wmi.c +++ b/drivers/net/wireless/ath/ath12k/wmi.c @@ -774,6 +774,9 @@ int ath12k_wmi_vdev_create(struct ath12k cmd->num_cfg_txrx_streams = cpu_to_le32(WMI_NUM_SUPPORTED_BAND_MAX); cmd->pdev_id = cpu_to_le32(param->pdev_id); cmd->vdev_stats_id = cpu_to_le32(param->if_stats_id); + cmd->mbssid_flags = cpu_to_le32(param->mbssid_flags); + cmd->mbssid_tx_vdev_id = cpu_to_le32(param->mbssid_tx_vdev_id); + ether_addr_copy(cmd->vdev_macaddr.addr, macaddr); ptr = skb->data + sizeof(*cmd); @@ -985,6 +988,8 @@ int ath12k_wmi_vdev_start(struct ath12k cmd->cac_duration_ms = cpu_to_le32(arg->cac_duration_ms); cmd->regdomain = cpu_to_le32(arg->regdomain); cmd->he_ops = cpu_to_le32(arg->he_ops); + cmd->mbssid_flags = cpu_to_le32(arg->mbssid_flags); + cmd->mbssid_tx_vdev_id = cpu_to_le32(arg->mbssid_tx_vdev_id); cmd->ru_punct_bitmap = cpu_to_le32(arg->ru_punct_bitmap); if (!restart) { --- a/drivers/net/wireless/ath/ath12k/wmi.h +++ b/drivers/net/wireless/ath/ath12k/wmi.h @@ -2093,6 +2093,7 @@ enum wmi_tlv_service { WMI_TLV_SERVICE_EXT2_MSG = 220, WMI_TLV_SERVICE_SRG_SRP_SPATIAL_REUSE_SUPPORT = 249, + WMI_TLV_SERVICE_MBSS_PARAM_IN_VDEV_START_SUPPORT = 253, WMI_MAX_EXT_SERVICE = 256, WMI_TLV_SERVICE_REG_CC_EXT_EVENT_SUPPORT = 281, @@ -2240,6 +2241,14 @@ struct ath12k_hal_reg_capabilities_ext { #define WMI_MAX_EHTCAP_PHY_SIZE 3 #define WMI_MAX_EHTCAP_RATE_SET 3 +enum { + WMI_HOST_VDEV_FLAGS_NON_MBSSID_AP = 0x00000001, + WMI_HOST_VDEV_FLAGS_TRANSMIT_AP = 0x00000002, + WMI_HOST_VDEV_FLAGS_NON_TRANSMIT_AP = 0x00000004, + WMI_HOST_VDEV_FLAGS_EMA_MODE = 0x00000008, + WMI_HOST_VDEV_FLAGS_SCAN_MODE_VAP = 0x00000010, +}; + /* * 0 – index indicated EHT-MCS map for 20Mhz only sta (4 bytes valid) * 1 – index for <= 80MHz bw (only 3 bytes are valid and other is reserved) @@ -2668,6 +2677,8 @@ struct vdev_create_params { u8 rx; } chains[NUM_NL80211_BANDS]; u32 pdev_id; + u32 mbssid_flags; + u32 mbssid_tx_vdev_id; u8 if_stats_id; }; @@ -2682,8 +2693,8 @@ struct wmi_vdev_create_cmd { struct wmi_mac_addr vdev_macaddr; __le32 num_cfg_txrx_streams; __le32 pdev_id; - __le32 flags; - __le32 vdevid_trans; + __le32 mbssid_flags; + __le32 mbssid_tx_vdev_id; __le32 vdev_stats_id_valid; __le32 vdev_stats_id; } __packed; @@ -2749,8 +2760,8 @@ struct wmi_vdev_start_request_cmd { __le32 cac_duration_ms; __le32 regdomain; __le32 min_data_rate; - __le32 mbss_capability_flags; - __le32 vdevid_trans; + __le32 mbssid_flags; + __le32 mbssid_tx_vdev_id; __le32 eht_ops; __le32 ru_punct_bitmap; } __packed; @@ -2949,6 +2960,9 @@ struct wmi_vdev_start_req_arg { u32 pref_rx_streams; u32 pref_tx_streams; u32 num_noa_descriptors; + u32 min_data_rate; + u32 mbssid_flags; + u32 mbssid_tx_vdev_id; u32 ru_punct_bitmap; }; @@ -4635,6 +4649,8 @@ struct wmi_pdev_temperature_event { /* temperature value in Celcius degree */ s32 temp; u32 pdev_id; + u32 mbssid_flags; + u32 mbssid_tx_vdev_id; } __packed; #define WMI_AC_BE 0