| From 1ebb020ab2ee139baed670d3ddc10f4c15263a2a Mon Sep 17 00:00:00 2001 |
| From: Xinming Hu <huxm@marvell.com> |
| Date: Mon, 20 Jun 2016 07:30:37 -0700 |
| Subject: [PATCH] CHROMIUM: mwifiex: vendor command support for set tx power |
| mode |
| |
| This patch is to port SAR changes for Marvell to kernel 5.10. |
| This patch add vendor command support for mwifiex, currently command 0 |
| is used to set device transmit power mode. |
| |
| Signed-off-by: Xinming Hu <huxm@marvell.com> |
| Signed-off-by: Shengzhen Li <szli@marvell.com> |
| Signed-off-by: Amitkumar Karwar <akarwar@marvell.com> |
| |
| Conflicts: |
| drivers/net/wireless/marvell/mwifiex/cfg80211.c: nla_parse requires |
| extack: extended ACK pointer as one additional argument on 5.10 kernel. |
| |
| BUG=b:195142916 |
| TEST=tast run -var=<router> -var <pacp> DUT_IP wifi.SetTXPower |
| |
| Signed-off-by: Abhishek Kumar <kuabhs@chromium.org> |
| [kuabhs: Fixed merged conflicts on kernel 5.10, fixed |
| style check issues. Added 5.10 kernel required parameter |
| i.e. policy and maxattr] |
| Change-Id: I2bba15dfd4d050b156f31532211124b7523b8c85 |
| Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/3171689 |
| Reviewed-by: Brian Norris <briannorris@chromium.org> |
| --- |
| .../net/wireless/marvell/mwifiex/cfg80211.c | 90 +++++++++++++++++++ |
| drivers/net/wireless/marvell/mwifiex/main.h | 19 ++++ |
| 2 files changed, 109 insertions(+) |
| |
| diff --git a/drivers/net/wireless/marvell/mwifiex/cfg80211.c b/drivers/net/wireless/marvell/mwifiex/cfg80211.c |
| index 0dd1cb470abdb8244b2f2857e8550d12c6c2469f..23da297c908b0b09886db6476bd6444c87ecf8a0 100644 |
| --- a/drivers/net/wireless/marvell/mwifiex/cfg80211.c |
| +++ b/drivers/net/wireless/marvell/mwifiex/cfg80211.c |
| @@ -4326,6 +4326,94 @@ int mwifiex_init_channel_scan_gap(struct mwifiex_adapter *adapter) |
| return 0; |
| } |
| |
| +static const struct nla_policy |
| +mwifiex_vendor_attr_policy[NUM_MWIFIEX_VENDOR_CMD_ATTR] = { |
| + [MWIFIEX_VENDOR_CMD_ATTR_TXP_LIMIT_24] = { .type = NLA_U8 }, |
| + [MWIFIEX_VENDOR_CMD_ATTR_TXP_LIMIT_52] = { .type = NLA_U8 }, |
| +}; |
| + |
| +static int mwifiex_parse_vendor_data(struct nlattr **tb, |
| + const void *data, int data_len) |
| +{ |
| + if (!data) |
| + return -EINVAL; |
| + |
| + return nla_parse(tb, MAX_MWIFIEX_VENDOR_CMD_ATTR, data, data_len, |
| + mwifiex_vendor_attr_policy, NULL); |
| +} |
| + |
| +static int mwifiex_vendor_set_tx_power_limt(struct wiphy *wiphy, |
| + struct wireless_dev *wdev, |
| + const void *data, int data_len) |
| +{ |
| + struct mwifiex_private *priv = mwifiex_netdev_get_priv(wdev->netdev); |
| + struct nlattr *tb[NUM_MWIFIEX_VENDOR_CMD_ATTR]; |
| + int ret; |
| + u8 lowpwr; |
| + |
| + ret = mwifiex_parse_vendor_data(tb, data, data_len); |
| + if (ret) |
| + return ret; |
| + |
| + if (tb[MWIFIEX_VENDOR_CMD_ATTR_TXP_LIMIT_24]) { |
| + lowpwr = nla_get_u8(tb[MWIFIEX_VENDOR_CMD_ATTR_TXP_LIMIT_24]) ? |
| + true : false; |
| + if (lowpwr != priv->adapter->lowpwr_mode_2g4 && |
| + priv->adapter->dt_node) { |
| + ret = mwifiex_dnld_dt_cfgdata |
| + (priv, priv->adapter->dt_node, lowpwr ? |
| + "marvell,caldata_00_txpwrlimit_2g" : |
| + "marvell,caldata_01_txpwrlimit_2g"); |
| + if (ret) |
| + return -1; |
| + priv->adapter->lowpwr_mode_2g4 = lowpwr; |
| + } |
| + } |
| + |
| + if (tb[MWIFIEX_VENDOR_CMD_ATTR_TXP_LIMIT_52]) { |
| + lowpwr = nla_get_u8(tb[MWIFIEX_VENDOR_CMD_ATTR_TXP_LIMIT_52]) ? |
| + true : false; |
| + if (lowpwr != priv->adapter->lowpwr_mode_5g2 && |
| + priv->adapter->dt_node) { |
| + ret = mwifiex_dnld_dt_cfgdata |
| + (priv, priv->adapter->dt_node, lowpwr ? |
| + "marvell,caldata_00_txpwrlimit_5g" : |
| + "marvell,caldata_01_txpwrlimit_5g"); |
| + if (ret) |
| + return -1; |
| + priv->adapter->lowpwr_mode_5g2 = lowpwr; |
| + } |
| + } |
| + |
| + return 0; |
| +} |
| + |
| +static const struct wiphy_vendor_command mwifiex_vendor_commands[] = { |
| + { |
| + .info = { |
| + .vendor_id = MWIFIEX_VENDOR_ID, |
| + .subcmd = MWIFIEX_VENDOR_CMD_SET_TX_POWER_LIMIT, |
| + }, |
| + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | |
| + WIPHY_VENDOR_CMD_NEED_RUNNING, |
| + .doit = mwifiex_vendor_set_tx_power_limt, |
| + .policy = mwifiex_vendor_attr_policy, |
| + .maxattr = MAX_MWIFIEX_VENDOR_CMD_ATTR, |
| + }, |
| +}; |
| + |
| +/* @brief register vendor commands and events |
| + * |
| + * @param wiphy A pointer to wiphy struct |
| + * |
| + * @return |
| + */ |
| +static void mwifiex_register_cfg80211_vendor_command(struct wiphy *wiphy) |
| +{ |
| + wiphy->vendor_commands = mwifiex_vendor_commands; |
| + wiphy->n_vendor_commands = ARRAY_SIZE(mwifiex_vendor_commands); |
| +} |
| + |
| /* |
| * This function registers the device with CFG802.11 subsystem. |
| * |
| @@ -4363,6 +4451,8 @@ int mwifiex_register_cfg80211(struct mwifiex_adapter *adapter) |
| if (ISSUPP_ADHOC_ENABLED(adapter->fw_cap_info)) |
| wiphy->interface_modes |= BIT(NL80211_IFTYPE_ADHOC); |
| |
| + mwifiex_register_cfg80211_vendor_command(wiphy); |
| + |
| wiphy->bands[NL80211_BAND_2GHZ] = devm_kmemdup(adapter->dev, |
| &mwifiex_band_2ghz, |
| sizeof(mwifiex_band_2ghz), |
| diff --git a/drivers/net/wireless/marvell/mwifiex/main.h b/drivers/net/wireless/marvell/mwifiex/main.h |
| index c5164ae41b547534ec0c62ec0e6fa08f6251e645..c2bd953b248ea69edd71f1611a39888a26502cf8 100644 |
| --- a/drivers/net/wireless/marvell/mwifiex/main.h |
| +++ b/drivers/net/wireless/marvell/mwifiex/main.h |
| @@ -158,6 +158,23 @@ enum { |
| |
| #define MWIFIEX_MAC_LOCAL_ADMIN_BIT 41 |
| |
| +/* marvell vendor command and event ID */ |
| +#define MWIFIEX_VENDOR_ID 0x005043 |
| + |
| +/* vendor sub command */ |
| +enum mwifiex_vendor_sub_command { |
| + MWIFIEX_VENDOR_CMD_SET_TX_POWER_LIMIT = 0, |
| + MWIFIEX_VENDOR_CMD_MAX, |
| +}; |
| + |
| +enum mwifiex_vendor_cmd_attr { |
| + MWIFIEX_VENDOR_CMD_ATTR_INVALID, |
| + MWIFIEX_VENDOR_CMD_ATTR_TXP_LIMIT_24, |
| + MWIFIEX_VENDOR_CMD_ATTR_TXP_LIMIT_52, |
| + NUM_MWIFIEX_VENDOR_CMD_ATTR, |
| + MAX_MWIFIEX_VENDOR_CMD_ATTR = NUM_MWIFIEX_VENDOR_CMD_ATTR - 1, |
| +}; |
| + |
| /** |
| *enum mwifiex_debug_level - marvell wifi debug level |
| */ |
| @@ -848,6 +865,8 @@ struct mwifiex_if_ops { |
| }; |
| |
| struct mwifiex_adapter { |
| + u8 lowpwr_mode_2g4; |
| + u8 lowpwr_mode_5g2; |
| u8 iface_type; |
| unsigned int debug_mask; |
| struct mwifiex_iface_comb iface_limit; |
| -- |
| 2.46.0.792.g87dc391469-goog |
| |