@@ -358,6 +358,8 @@ struct ath11k_vif {
#ifdef CONFIG_ATH11K_DEBUGFS
struct dentry *debugfs_twt;
#endif /* CONFIG_ATH11K_DEBUGFS */
+
+ u8 nontransmitting_vif_count;
};
struct ath11k_vif_iter {
@@ -1425,9 +1425,13 @@ static void ath11k_control_beaconing(struct ath11k_vif *arvif,
struct ieee80211_bss_conf *info)
{
struct ath11k *ar = arvif->ar;
+ struct ath11k_vif *tx_arvif = NULL;
int ret = 0;
struct vdev_up_params params = { 0 };
+ if (arvif->vif->mbssid_tx_vif)
+ tx_arvif = (void *)arvif->vif->mbssid_tx_vif->drv_priv;
+
lockdep_assert_held(&arvif->ar->conf_mutex);
if (!info->enable_beacon) {
@@ -1437,6 +1441,9 @@ static void ath11k_control_beaconing(struct ath11k_vif *arvif,
arvif->vdev_id, ret);
arvif->is_up = false;
+ if (tx_arvif)
+ tx_arvif->nontransmitting_vif_count = 0;
+
return;
}
@@ -1457,6 +1464,13 @@ static void ath11k_control_beaconing(struct ath11k_vif *arvif,
params.vdev_id = arvif->vdev_id;
params.aid = arvif->aid;
params.bssid = arvif->bssid;
+ if (tx_arvif) {
+ params.tx_bssid = tx_arvif->bssid;
+ params.profile_idx = info->bssid_index;
+ if (params.profile_idx >= tx_arvif->nontransmitting_vif_count)
+ tx_arvif->nontransmitting_vif_count = params.profile_idx;
+ params.profile_cnt = tx_arvif->nontransmitting_vif_count;
+ }
ret = ath11k_wmi_vdev_up(arvif->ar, ¶ms);
if (ret) {
ath11k_warn(ar->ab, "failed to bring up vdev %d: %i\n",
@@ -2818,7 +2832,7 @@ static void ath11k_bss_disassoc(struct ieee80211_hw *hw,
struct ieee80211_vif *vif)
{
struct ath11k *ar = hw->priv;
- struct ath11k_vif *arvif = (void *)vif->drv_priv;
+ struct ath11k_vif *arvif = (void *)vif->drv_priv, *tx_arvif;
int ret;
lockdep_assert_held(&ar->conf_mutex);
@@ -2832,6 +2846,11 @@ static void ath11k_bss_disassoc(struct ieee80211_hw *hw,
arvif->vdev_id, ret);
arvif->is_up = false;
+ if (arvif->vif->mbssid_tx_vif) {
+ tx_arvif = (void *)arvif->vif->mbssid_tx_vif->drv_priv;
+ if (tx_arvif != arvif)
+ tx_arvif->nontransmitting_vif_count--;
+ }
memset(&arvif->rekey_data, 0, sizeof(arvif->rekey_data));
@@ -3383,7 +3402,8 @@ static void ath11k_mac_op_bss_info_changed(struct ieee80211_hw *hw,
ret = ath11k_wmi_send_obss_color_collision_cfg_cmd(
ar, arvif->vdev_id, info->he_bss_color.color,
ATH11K_BSS_COLOR_COLLISION_DETECTION_AP_PERIOD_MS,
- info->he_bss_color.enabled);
+ arvif->vif->bss_conf.nontransmitted ?
+ 0 : info->he_bss_color.enabled);
if (ret)
ath11k_warn(ar->ab, "failed to set bss color collision on vdev %i: %d\n",
arvif->vdev_id, ret);
@@ -7007,7 +7027,7 @@ ath11k_mac_update_vif_chan(struct ath11k *ar,
int n_vifs)
{
struct ath11k_base *ab = ar->ab;
- struct ath11k_vif *arvif;
+ struct ath11k_vif *arvif, *tx_arvif;
int ret;
int i;
bool monitor_vif = false;
@@ -7066,6 +7086,12 @@ ath11k_mac_update_vif_chan(struct ath11k *ar,
params.vdev_id = arvif->vdev_id;
params.aid = arvif->aid;
params.bssid = arvif->bssid;
+ if (arvif->vif->mbssid_tx_vif) {
+ tx_arvif = (void *)arvif->vif->mbssid_tx_vif->drv_priv;
+ params.tx_bssid = tx_arvif->bssid;
+ params.profile_idx = arvif->vif->bss_conf.bssid_index;
+ params.profile_cnt = tx_arvif->nontransmitting_vif_count;
+ }
ret = ath11k_wmi_vdev_up(arvif->ar, ¶ms);
if (ret) {
ath11k_warn(ab, "failed to bring vdev up %d: %d\n",
@@ -1017,6 +1017,11 @@ int ath11k_wmi_vdev_up(struct ath11k *ar, struct vdev_up_params *params)
ether_addr_copy(cmd->vdev_bssid.addr, params->bssid);
+ cmd->profile_idx = params->profile_idx;
+ cmd->profile_cnt = params->profile_cnt;
+ if (params->tx_bssid)
+ ether_addr_copy(cmd->tx_vdev_bssid.addr, params->tx_bssid);
+
if (arvif && arvif->vif->type == NL80211_IFTYPE_STATION) {
bss_conf = &arvif->vif->bss_conf;
@@ -2616,6 +2616,9 @@ struct vdev_up_params {
u32 vdev_id;
u32 aid;
const u8 *bssid;
+ u32 profile_idx;
+ u32 profile_cnt;
+ u8 *tx_bssid;
};
struct wmi_vdev_up_cmd {