diff mbox

[v3] ath10k: add support for controlling tx power to a station

Message ID 1486555117-25196-1-git-send-email-arnagara@qti.qualcomm.com (mailing list archive)
State Changes Requested
Delegated to: Kalle Valo
Headers show

Commit Message

Ashok Raj Nagarajan Feb. 8, 2017, 11:58 a.m. UTC
This patch will add the support to control the transmit power for traffic
to a station associated with the AP. Userspace provide the transmit power
value in mBm units. ath10k firmware expects the value to be in dBm and
hence will convert the value from to dBm before passing down to firmware.

Underlying FW will enforce that the maximum tx power will be based on the
regulatory requirements. If the user given transmit power is greater than
the allowed tx power in the given channel, then the FW will use the maximum
tx power in the same channel.

When 0 is sent to the FW as tx power, it will revert to the automatic tx
power for the station.

Signed-off-by: Ashok Raj Nagarajan <arnagara@qti.qualcomm.com>
---
v3:
	- reword commit log
	- remove range check for the input from user. (Ben Greear)

 drivers/net/wireless/ath/ath10k/mac.c | 31 +++++++++++++++++++++++++++++++
 drivers/net/wireless/ath/ath10k/wmi.h |  1 +
 2 files changed, 32 insertions(+)

Comments

kernel test robot Feb. 12, 2017, 12:04 a.m. UTC | #1
Hi Ashok,

[auto build test ERROR on v4.9-rc8]
[cannot apply to ath6kl/ath-next next-20170210]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Ashok-Raj-Nagarajan/ath10k-add-support-for-controlling-tx-power-to-a-station/20170208-203305
config: i386-allyesconfig (attached as .config)
compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901
reproduce:
        # save the attached .config to linux build tree
        make ARCH=i386 

All errors (new ones prefixed by >>):

   drivers/net/wireless/ath/ath10k/mac.c: In function 'ath10k_sta_set_txpwr':
   drivers/net/wireless/ath/ath10k/mac.c:5900:15: error: 'struct ieee80211_sta' has no member named 'txpwr'
     txpwr = MBM_TO_DBM(sta->txpwr);
                  ^~
   drivers/net/wireless/ath/ath10k/mac.c: At top level:
   drivers/net/wireless/ath/ath10k/mac.c:7469:2: error: unknown field 'sta_set_txpwr' specified in initializer
     .sta_set_txpwr   = ath10k_sta_set_txpwr,
     ^
>> drivers/net/wireless/ath/ath10k/mac.c:7469:19: error: initialization from incompatible pointer type [-Werror=incompatible-pointer-types]
     .sta_set_txpwr   = ath10k_sta_set_txpwr,
                      ^~~~~~~~~~~~~~~~~~~~
   drivers/net/wireless/ath/ath10k/mac.c:7469:19: note: (near initialization for 'ath10k_ops.sta_pre_rcu_remove')
   drivers/net/wireless/ath/ath10k/mac.c: In function 'ath10k_mac_register':
   drivers/net/wireless/ath/ath10k/mac.c:8008:11: error: 'NL80211_EXT_FEATURE_STA_TX_PWR' undeclared (first use in this function)
              NL80211_EXT_FEATURE_STA_TX_PWR);
              ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   drivers/net/wireless/ath/ath10k/mac.c:8008:11: note: each undeclared identifier is reported only once for each function it appears in
   cc1: some warnings being treated as errors

vim +7469 drivers/net/wireless/ath/ath10k/mac.c

  7463		.bss_info_changed		= ath10k_bss_info_changed,
  7464		.hw_scan			= ath10k_hw_scan,
  7465		.cancel_hw_scan			= ath10k_cancel_hw_scan,
  7466		.set_key			= ath10k_set_key,
  7467		.set_default_unicast_key        = ath10k_set_default_unicast_key,
  7468		.sta_state			= ath10k_sta_state,
> 7469		.sta_set_txpwr			= ath10k_sta_set_txpwr,
  7470		.conf_tx			= ath10k_conf_tx,
  7471		.remain_on_channel		= ath10k_remain_on_channel,
  7472		.cancel_remain_on_channel	= ath10k_cancel_remain_on_channel,

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation
kernel test robot Feb. 12, 2017, 12:17 a.m. UTC | #2
Hi Ashok,

[auto build test ERROR on v4.9-rc8]
[cannot apply to ath6kl/ath-next next-20170210]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Ashok-Raj-Nagarajan/ath10k-add-support-for-controlling-tx-power-to-a-station/20170208-203305
config: x86_64-randconfig-in0-02120025 (attached as .config)
compiler: gcc-4.6 (Debian 4.6.4-7) 4.6.4
reproduce:
        # save the attached .config to linux build tree
        make ARCH=x86_64 

All errors (new ones prefixed by >>):

   drivers/net/wireless/ath/ath10k/mac.c: In function 'ath10k_sta_set_txpwr':
>> drivers/net/wireless/ath/ath10k/mac.c:5900:10: error: 'struct ieee80211_sta' has no member named 'txpwr'
   drivers/net/wireless/ath/ath10k/mac.c: At top level:
>> drivers/net/wireless/ath/ath10k/mac.c:7469:2: error: unknown field 'sta_set_txpwr' specified in initializer
   drivers/net/wireless/ath/ath10k/mac.c:7469:2: warning: initialization from incompatible pointer type [enabled by default]
   drivers/net/wireless/ath/ath10k/mac.c:7469:2: warning: (near initialization for 'ath10k_ops.sta_pre_rcu_remove') [enabled by default]
   drivers/net/wireless/ath/ath10k/mac.c: In function 'ath10k_mac_register':
>> drivers/net/wireless/ath/ath10k/mac.c:8008:11: error: 'NL80211_EXT_FEATURE_STA_TX_PWR' undeclared (first use in this function)
   drivers/net/wireless/ath/ath10k/mac.c:8008:11: note: each undeclared identifier is reported only once for each function it appears in

vim +5900 drivers/net/wireless/ath/ath10k/mac.c

  5894	{
  5895		struct ath10k *ar = hw->priv;
  5896		struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
  5897		int ret = 0;
  5898		u16 txpwr;
  5899	
> 5900		txpwr = MBM_TO_DBM(sta->txpwr);
  5901	
  5902		mutex_lock(&ar->conf_mutex);
  5903	

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation
Kalle Valo Feb. 14, 2017, 3:05 p.m. UTC | #3
kbuild test robot <lkp@intel.com> writes:

> Hi Ashok,
>
> [auto build test ERROR on v4.9-rc8]
> [cannot apply to ath6kl/ath-next next-20170210]
> [if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
>
> url:    https://github.com/0day-ci/linux/commits/Ashok-Raj-Nagarajan/ath10k-add-support-for-controlling-tx-power-to-a-station/20170208-203305
> config: x86_64-randconfig-in0-02120025 (attached as .config)
> compiler: gcc-4.6 (Debian 4.6.4-7) 4.6.4
> reproduce:
>         # save the attached .config to linux build tree
>         make ARCH=x86_64 
>
> All errors (new ones prefixed by >>):
>
>    drivers/net/wireless/ath/ath10k/mac.c: In function 'ath10k_sta_set_txpwr':
>>> drivers/net/wireless/ath/ath10k/mac.c:5900:10: error: 'struct
>>> ieee80211_sta' has no member named 'txpwr'
>    drivers/net/wireless/ath/ath10k/mac.c: At top level:
>>> drivers/net/wireless/ath/ath10k/mac.c:7469:2: error: unknown field
>>> 'sta_set_txpwr' specified in initializer
>    drivers/net/wireless/ath/ath10k/mac.c:7469:2: warning:
> initialization from incompatible pointer type [enabled by default]
>    drivers/net/wireless/ath/ath10k/mac.c:7469:2: warning: (near
> initialization for 'ath10k_ops.sta_pre_rcu_remove') [enabled by
> default]
>    drivers/net/wireless/ath/ath10k/mac.c: In function 'ath10k_mac_register':
>>> drivers/net/wireless/ath/ath10k/mac.c:8008:11: error:
>>> 'NL80211_EXT_FEATURE_STA_TX_PWR' undeclared (first use in this
>>> function)

These are expected as this depends on cfg80211 patch not yet applied.
Johannes Berg Feb. 15, 2017, 8 a.m. UTC | #4
On Wed, 2017-02-08 at 17:28 +0530, Ashok Raj Nagarajan wrote:
> This patch will add the support to control the transmit power for
> traffic
> to a station associated with the AP. Userspace provide the transmit
> power
> value in mBm units. ath10k firmware expects the value to be in dBm
> and
> hence will convert the value from to dBm before passing down to
> firmware.
> 
> Underlying FW will enforce that the maximum tx power will be based on
> the
> regulatory requirements. If the user given transmit power is greater
> than
> the allowed tx power in the given channel, then the FW will use the
> maximum
> tx power in the same channel.

The firmware command has a bit of a misleading name, but if this really
is the behaviour then all should be OK.

> When 0 is sent to the FW as tx power, it will revert to the automatic
> tx power for the station.

So this is where the 0 comes from, perhaps - but I think it'd be better
to do that translation in the driver.

Come to think of it, you're also missing range-checks entirely, so if I
give you some insane value you'd still send it down - no chance the
firmware will be unhappy?

Also, you should probably accept negative values for the TX power, and
make that an s32 instead of u32 across the patchset.

johannes

> Signed-off-by: Ashok Raj Nagarajan <arnagara@qti.qualcomm.com>
> ---
> v3:
> 	- reword commit log
> 	- remove range check for the input from user. (Ben Greear)
> 
>  drivers/net/wireless/ath/ath10k/mac.c | 31
> +++++++++++++++++++++++++++++++
>  drivers/net/wireless/ath/ath10k/wmi.h |  1 +
>  2 files changed, 32 insertions(+)
> 
> diff --git a/drivers/net/wireless/ath/ath10k/mac.c
> b/drivers/net/wireless/ath/ath10k/mac.c
> index 9977829..3b91468 100644
> --- a/drivers/net/wireless/ath/ath10k/mac.c
> +++ b/drivers/net/wireless/ath/ath10k/mac.c
> @@ -5985,6 +5985,32 @@ static int ath10k_mac_tdls_vifs_count(struct
> ieee80211_hw *hw)
>  	return num_tdls_vifs;
>  }
>  
> +static int ath10k_sta_set_txpwr(struct ieee80211_hw *hw,
> +				struct ieee80211_vif *vif,
> +				struct ieee80211_sta *sta)
> +{
> +	struct ath10k *ar = hw->priv;
> +	struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
> +	int ret = 0;
> +	u16 txpwr;
> +
> +	txpwr = MBM_TO_DBM(sta->txpwr);
> +
> +	mutex_lock(&ar->conf_mutex);
> +
> +	ret = ath10k_wmi_peer_set_param(ar, arvif->vdev_id, sta-
> >addr,
> +					WMI_PEER_USE_FIXED_PWR,
> txpwr);
> +	if (ret) {
> +		ath10k_warn(ar, "failed to set tx power for station
> ret: %d\n",
> +			    ret);
> +		goto out;
> +	}
> +
> +out:
> +	mutex_unlock(&ar->conf_mutex);
> +	return ret;
> +}
> +
>  static int ath10k_sta_state(struct ieee80211_hw *hw,
>  			    struct ieee80211_vif *vif,
>  			    struct ieee80211_sta *sta,
> @@ -7550,6 +7576,7 @@ static void
> ath10k_mac_op_sta_pre_rcu_remove(struct ieee80211_hw *hw,
>  	.set_key			= ath10k_set_key,
>  	.set_default_unicast_key        =
> ath10k_set_default_unicast_key,
>  	.sta_state			= ath10k_sta_state,
> +	.sta_set_txpwr			=
> ath10k_sta_set_txpwr,
>  	.conf_tx			= ath10k_conf_tx,
>  	.remain_on_channel		=
> ath10k_remain_on_channel,
>  	.cancel_remain_on_channel	=
> ath10k_cancel_remain_on_channel,
> @@ -8193,11 +8220,15 @@ int ath10k_mac_register(struct ath10k *ar)
>  		ar->hw->wiphy->iface_combinations =
> ath10k_10x_if_comb;
>  		ar->hw->wiphy->n_iface_combinations =
>  			ARRAY_SIZE(ath10k_10x_if_comb);
> +		wiphy_ext_feature_set(ar->hw->wiphy,
> +				      NL80211_EXT_FEATURE_STA_TX_PWR
> );
>  		break;
>  	case ATH10K_FW_WMI_OP_VERSION_10_4:
>  		ar->hw->wiphy->iface_combinations =
> ath10k_10_4_if_comb;
>  		ar->hw->wiphy->n_iface_combinations =
>  			ARRAY_SIZE(ath10k_10_4_if_comb);
> +		wiphy_ext_feature_set(ar->hw->wiphy,
> +				      NL80211_EXT_FEATURE_STA_TX_PWR
> );
>  		break;
>  	case ATH10K_FW_WMI_OP_VERSION_UNSET:
>  	case ATH10K_FW_WMI_OP_VERSION_MAX:
> diff --git a/drivers/net/wireless/ath/ath10k/wmi.h
> b/drivers/net/wireless/ath/ath10k/wmi.h
> index 861c2d8..1ccb6bf 100644
> --- a/drivers/net/wireless/ath/ath10k/wmi.h
> +++ b/drivers/net/wireless/ath/ath10k/wmi.h
> @@ -5811,6 +5811,7 @@ enum wmi_peer_param {
>  	WMI_PEER_CHAN_WIDTH = 0x4,
>  	WMI_PEER_NSS        = 0x5,
>  	WMI_PEER_USE_4ADDR  = 0x6,
> +	WMI_PEER_USE_FIXED_PWR = 0x8,
>  	WMI_PEER_DUMMY_VAR  = 0xff, /* dummy parameter for STA PS
> workaround */
>  };
>
diff mbox

Patch

diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c
index 9977829..3b91468 100644
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
@@ -5985,6 +5985,32 @@  static int ath10k_mac_tdls_vifs_count(struct ieee80211_hw *hw)
 	return num_tdls_vifs;
 }
 
+static int ath10k_sta_set_txpwr(struct ieee80211_hw *hw,
+				struct ieee80211_vif *vif,
+				struct ieee80211_sta *sta)
+{
+	struct ath10k *ar = hw->priv;
+	struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
+	int ret = 0;
+	u16 txpwr;
+
+	txpwr = MBM_TO_DBM(sta->txpwr);
+
+	mutex_lock(&ar->conf_mutex);
+
+	ret = ath10k_wmi_peer_set_param(ar, arvif->vdev_id, sta->addr,
+					WMI_PEER_USE_FIXED_PWR, txpwr);
+	if (ret) {
+		ath10k_warn(ar, "failed to set tx power for station ret: %d\n",
+			    ret);
+		goto out;
+	}
+
+out:
+	mutex_unlock(&ar->conf_mutex);
+	return ret;
+}
+
 static int ath10k_sta_state(struct ieee80211_hw *hw,
 			    struct ieee80211_vif *vif,
 			    struct ieee80211_sta *sta,
@@ -7550,6 +7576,7 @@  static void ath10k_mac_op_sta_pre_rcu_remove(struct ieee80211_hw *hw,
 	.set_key			= ath10k_set_key,
 	.set_default_unicast_key        = ath10k_set_default_unicast_key,
 	.sta_state			= ath10k_sta_state,
+	.sta_set_txpwr			= ath10k_sta_set_txpwr,
 	.conf_tx			= ath10k_conf_tx,
 	.remain_on_channel		= ath10k_remain_on_channel,
 	.cancel_remain_on_channel	= ath10k_cancel_remain_on_channel,
@@ -8193,11 +8220,15 @@  int ath10k_mac_register(struct ath10k *ar)
 		ar->hw->wiphy->iface_combinations = ath10k_10x_if_comb;
 		ar->hw->wiphy->n_iface_combinations =
 			ARRAY_SIZE(ath10k_10x_if_comb);
+		wiphy_ext_feature_set(ar->hw->wiphy,
+				      NL80211_EXT_FEATURE_STA_TX_PWR);
 		break;
 	case ATH10K_FW_WMI_OP_VERSION_10_4:
 		ar->hw->wiphy->iface_combinations = ath10k_10_4_if_comb;
 		ar->hw->wiphy->n_iface_combinations =
 			ARRAY_SIZE(ath10k_10_4_if_comb);
+		wiphy_ext_feature_set(ar->hw->wiphy,
+				      NL80211_EXT_FEATURE_STA_TX_PWR);
 		break;
 	case ATH10K_FW_WMI_OP_VERSION_UNSET:
 	case ATH10K_FW_WMI_OP_VERSION_MAX:
diff --git a/drivers/net/wireless/ath/ath10k/wmi.h b/drivers/net/wireless/ath/ath10k/wmi.h
index 861c2d8..1ccb6bf 100644
--- a/drivers/net/wireless/ath/ath10k/wmi.h
+++ b/drivers/net/wireless/ath/ath10k/wmi.h
@@ -5811,6 +5811,7 @@  enum wmi_peer_param {
 	WMI_PEER_CHAN_WIDTH = 0x4,
 	WMI_PEER_NSS        = 0x5,
 	WMI_PEER_USE_4ADDR  = 0x6,
+	WMI_PEER_USE_FIXED_PWR = 0x8,
 	WMI_PEER_DUMMY_VAR  = 0xff, /* dummy parameter for STA PS workaround */
 };