[PATCH 3.16 52/63] mwifiex: Fix NL80211_TX_POWER_LIMITED

From: Ben Hutchings
Date: Wed Jan 08 2020 - 14:48:22 EST


3.16.81-rc1 review patch. If anyone has any objections, please let me know.

------------------

From: Adrian Bunk <bunk@xxxxxxxxxx>

commit 65a576e27309120e0621f54d5c81eb9128bd56be upstream.

NL80211_TX_POWER_LIMITED was treated as NL80211_TX_POWER_AUTOMATIC,
which is the opposite of what should happen and can cause nasty
regulatory problems.

if/else converted to a switch without default to make gcc warn
on unhandled enum values.

Signed-off-by: Adrian Bunk <bunk@xxxxxxxxxx>
Signed-off-by: Kalle Valo <kvalo@xxxxxxxxxxxxxx>
[bwh: Backported to 3.16: adjust filenames]
Signed-off-by: Ben Hutchings <ben@xxxxxxxxxxxxxxx>
---
drivers/net/wireless/mwifiex/cfg80211.c | 13 +++++++++++--
drivers/net/wireless/mwifiex/ioctl.h | 1 +
drivers/net/wireless/mwifiex/sta_ioctl.c | 11 +++++++----
3 files changed, 19 insertions(+), 6 deletions(-)

--- a/drivers/net/wireless/mwifiex/cfg80211.c
+++ b/drivers/net/wireless/mwifiex/cfg80211.c
@@ -343,11 +343,20 @@ mwifiex_cfg80211_set_tx_power(struct wip
struct mwifiex_power_cfg power_cfg;
int dbm = MBM_TO_DBM(mbm);

- if (type == NL80211_TX_POWER_FIXED) {
+ switch (type) {
+ case NL80211_TX_POWER_FIXED:
power_cfg.is_power_auto = 0;
+ power_cfg.is_power_fixed = 1;
power_cfg.power_level = dbm;
- } else {
+ break;
+ case NL80211_TX_POWER_LIMITED:
+ power_cfg.is_power_auto = 0;
+ power_cfg.is_power_fixed = 0;
+ power_cfg.power_level = dbm;
+ break;
+ case NL80211_TX_POWER_AUTOMATIC:
power_cfg.is_power_auto = 1;
+ break;
}

priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY);
--- a/drivers/net/wireless/mwifiex/ioctl.h
+++ b/drivers/net/wireless/mwifiex/ioctl.h
@@ -245,6 +245,7 @@ struct mwifiex_ds_encrypt_key {

struct mwifiex_power_cfg {
u32 is_power_auto;
+ u32 is_power_fixed;
u32 power_level;
};

--- a/drivers/net/wireless/mwifiex/sta_ioctl.c
+++ b/drivers/net/wireless/mwifiex/sta_ioctl.c
@@ -659,6 +659,9 @@ int mwifiex_set_tx_power(struct mwifiex_
txp_cfg = (struct host_cmd_ds_txpwr_cfg *) buf;
txp_cfg->action = cpu_to_le16(HostCmd_ACT_GEN_SET);
if (!power_cfg->is_power_auto) {
+ u16 dbm_min = power_cfg->is_power_fixed ?
+ dbm : priv->min_tx_power_level;
+
txp_cfg->mode = cpu_to_le32(1);
pg_tlv = (struct mwifiex_types_power_group *)
(buf + sizeof(struct host_cmd_ds_txpwr_cfg));
@@ -673,7 +676,7 @@ int mwifiex_set_tx_power(struct mwifiex_
pg->last_rate_code = 0x03;
pg->modulation_class = MOD_CLASS_HR_DSSS;
pg->power_step = 0;
- pg->power_min = (s8) dbm;
+ pg->power_min = (s8) dbm_min;
pg->power_max = (s8) dbm;
pg++;
/* Power group for modulation class OFDM */
@@ -681,7 +684,7 @@ int mwifiex_set_tx_power(struct mwifiex_
pg->last_rate_code = 0x07;
pg->modulation_class = MOD_CLASS_OFDM;
pg->power_step = 0;
- pg->power_min = (s8) dbm;
+ pg->power_min = (s8) dbm_min;
pg->power_max = (s8) dbm;
pg++;
/* Power group for modulation class HTBW20 */
@@ -689,7 +692,7 @@ int mwifiex_set_tx_power(struct mwifiex_
pg->last_rate_code = 0x20;
pg->modulation_class = MOD_CLASS_HT;
pg->power_step = 0;
- pg->power_min = (s8) dbm;
+ pg->power_min = (s8) dbm_min;
pg->power_max = (s8) dbm;
pg->ht_bandwidth = HT_BW_20;
pg++;
@@ -698,7 +701,7 @@ int mwifiex_set_tx_power(struct mwifiex_
pg->last_rate_code = 0x20;
pg->modulation_class = MOD_CLASS_HT;
pg->power_step = 0;
- pg->power_min = (s8) dbm;
+ pg->power_min = (s8) dbm_min;
pg->power_max = (s8) dbm;
pg->ht_bandwidth = HT_BW_40;
}