|
@@ -2676,12 +2676,68 @@ static void ath10k_config_chan(struct ath10k *ar)
|
|
ath10k_monitor_recalc(ar);
|
|
ath10k_monitor_recalc(ar);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static int ath10k_mac_txpower_setup(struct ath10k *ar, int txpower)
|
|
|
|
+{
|
|
|
|
+ int ret;
|
|
|
|
+ u32 param;
|
|
|
|
+
|
|
|
|
+ lockdep_assert_held(&ar->conf_mutex);
|
|
|
|
+
|
|
|
|
+ ath10k_dbg(ar, ATH10K_DBG_MAC, "mac txpower %d\n", txpower);
|
|
|
|
+
|
|
|
|
+ param = ar->wmi.pdev_param->txpower_limit2g;
|
|
|
|
+ ret = ath10k_wmi_pdev_set_param(ar, param, txpower * 2);
|
|
|
|
+ if (ret) {
|
|
|
|
+ ath10k_warn(ar, "failed to set 2g txpower %d: %d\n",
|
|
|
|
+ txpower, ret);
|
|
|
|
+ return ret;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ param = ar->wmi.pdev_param->txpower_limit5g;
|
|
|
|
+ ret = ath10k_wmi_pdev_set_param(ar, param, txpower * 2);
|
|
|
|
+ if (ret) {
|
|
|
|
+ ath10k_warn(ar, "failed to set 5g txpower %d: %d\n",
|
|
|
|
+ txpower, ret);
|
|
|
|
+ return ret;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return 0;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static int ath10k_mac_txpower_recalc(struct ath10k *ar)
|
|
|
|
+{
|
|
|
|
+ struct ath10k_vif *arvif;
|
|
|
|
+ int ret, txpower = -1;
|
|
|
|
+
|
|
|
|
+ lockdep_assert_held(&ar->conf_mutex);
|
|
|
|
+
|
|
|
|
+ list_for_each_entry(arvif, &ar->arvifs, list) {
|
|
|
|
+ WARN_ON(arvif->txpower < 0);
|
|
|
|
+
|
|
|
|
+ if (txpower == -1)
|
|
|
|
+ txpower = arvif->txpower;
|
|
|
|
+ else
|
|
|
|
+ txpower = min(txpower, arvif->txpower);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (WARN_ON(txpower == -1))
|
|
|
|
+ return -EINVAL;
|
|
|
|
+
|
|
|
|
+ ret = ath10k_mac_txpower_setup(ar, txpower);
|
|
|
|
+ if (ret) {
|
|
|
|
+ ath10k_warn(ar, "failed to setup tx power %d: %d\n",
|
|
|
|
+ txpower, ret);
|
|
|
|
+ return ret;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return 0;
|
|
|
|
+}
|
|
|
|
+
|
|
static int ath10k_config(struct ieee80211_hw *hw, u32 changed)
|
|
static int ath10k_config(struct ieee80211_hw *hw, u32 changed)
|
|
{
|
|
{
|
|
struct ath10k *ar = hw->priv;
|
|
struct ath10k *ar = hw->priv;
|
|
struct ieee80211_conf *conf = &hw->conf;
|
|
struct ieee80211_conf *conf = &hw->conf;
|
|
int ret = 0;
|
|
int ret = 0;
|
|
- u32 param;
|
|
|
|
|
|
|
|
mutex_lock(&ar->conf_mutex);
|
|
mutex_lock(&ar->conf_mutex);
|
|
|
|
|
|
@@ -2705,25 +2761,6 @@ static int ath10k_config(struct ieee80211_hw *hw, u32 changed)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- if (changed & IEEE80211_CONF_CHANGE_POWER) {
|
|
|
|
- ath10k_dbg(ar, ATH10K_DBG_MAC, "mac config power %d\n",
|
|
|
|
- hw->conf.power_level);
|
|
|
|
-
|
|
|
|
- param = ar->wmi.pdev_param->txpower_limit2g;
|
|
|
|
- ret = ath10k_wmi_pdev_set_param(ar, param,
|
|
|
|
- hw->conf.power_level * 2);
|
|
|
|
- if (ret)
|
|
|
|
- ath10k_warn(ar, "failed to set 2g txpower %d: %d\n",
|
|
|
|
- hw->conf.power_level, ret);
|
|
|
|
-
|
|
|
|
- param = ar->wmi.pdev_param->txpower_limit5g;
|
|
|
|
- ret = ath10k_wmi_pdev_set_param(ar, param,
|
|
|
|
- hw->conf.power_level * 2);
|
|
|
|
- if (ret)
|
|
|
|
- ath10k_warn(ar, "failed to set 5g txpower %d: %d\n",
|
|
|
|
- hw->conf.power_level, ret);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
if (changed & IEEE80211_CONF_CHANGE_PS)
|
|
if (changed & IEEE80211_CONF_CHANGE_PS)
|
|
ath10k_config_ps(ar);
|
|
ath10k_config_ps(ar);
|
|
|
|
|
|
@@ -2932,6 +2969,13 @@ static int ath10k_add_interface(struct ieee80211_hw *hw,
|
|
goto err_peer_delete;
|
|
goto err_peer_delete;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ arvif->txpower = vif->bss_conf.txpower;
|
|
|
|
+ ret = ath10k_mac_txpower_recalc(ar);
|
|
|
|
+ if (ret) {
|
|
|
|
+ ath10k_warn(ar, "failed to recalc tx power: %d\n", ret);
|
|
|
|
+ goto err_peer_delete;
|
|
|
|
+ }
|
|
|
|
+
|
|
mutex_unlock(&ar->conf_mutex);
|
|
mutex_unlock(&ar->conf_mutex);
|
|
return 0;
|
|
return 0;
|
|
|
|
|
|
@@ -3168,6 +3212,16 @@ static void ath10k_bss_info_changed(struct ieee80211_hw *hw,
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ if (changed & BSS_CHANGED_TXPOWER) {
|
|
|
|
+ ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev_id %i txpower %d\n",
|
|
|
|
+ arvif->vdev_id, info->txpower);
|
|
|
|
+
|
|
|
|
+ arvif->txpower = info->txpower;
|
|
|
|
+ ret = ath10k_mac_txpower_recalc(ar);
|
|
|
|
+ if (ret)
|
|
|
|
+ ath10k_warn(ar, "failed to recalc tx power: %d\n", ret);
|
|
|
|
+ }
|
|
|
|
+
|
|
mutex_unlock(&ar->conf_mutex);
|
|
mutex_unlock(&ar->conf_mutex);
|
|
}
|
|
}
|
|
|
|
|