All of lore.kernel.org
 help / color / mirror / Atom feed
From: Arend van Spriel <arend.vanspriel@broadcom.com>
To: Wei-Ning Huang <wnhuang@google.com>, Dan Williams <dcbw@redhat.com>
Cc: Linux-Wireless <linux-wireless@vger.kernel.org>,
	LKML <linux-kernel@vger.kernel.org>,
	Johannes Berg <johannes@sipsolutions.net>,
	Sameer Nanda <snanda@chromium.org>,
	Todd Broch <tbroch@chromium.org>,
	davem@davemloft.net, netdev@vger.kernel.org
Subject: Re: [PATCH] cfg80211/nl80211: add wifi tx power mode switching support
Date: Fri, 13 May 2016 00:02:38 +0200	[thread overview]
Message-ID: <5734FD7E.7010307@broadcom.com> (raw)
In-Reply-To: <CABicQ-UeU-8PPdK9Je51j_KD-BH8G1HuOjo0yZLcNBQgtJsyTA@mail.gmail.com>

On 12-05-16 11:34, Wei-Ning Huang wrote:
> On Thu, May 12, 2016 at 2:33 AM, Dan Williams <dcbw@redhat.com> wrote:
>> On Wed, 2016-05-11 at 13:03 +0800, Wei-Ning Huang wrote:
>>> On Fri, May 6, 2016 at 4:19 PM, Wei-Ning Huang <wnhuang@google.com>
>>> wrote:
>>>>
>>>> On Fri, May 6, 2016 at 12:07 AM, Dan Williams <dcbw@redhat.com>
>>>> wrote:
>>>>>
>>>>>
>>>>> On Thu, 2016-05-05 at 14:44 +0800, Wei-Ning Huang wrote:
>>>>>>
>>>>>> Recent new hardware has the ability to switch between tablet
>>>>>> mode and
>>>>>> clamshell mode. To optimize WiFi performance, we want to be
>>>>>> able to
>>>>>> use
>>>>>> different power table between modes. This patch adds a new
>>>>>> netlink
>>>>>> message type and cfg80211_ops function to allow userspace to
>>>>>> trigger
>>>>>> a
>>>>>> power mode switch for a given wireless interface.
>>>>>>
>>>>>> Signed-off-by: Wei-Ning Huang <wnhuang@chromium.org>
>>>>>> ---
>>>>>>  include/net/cfg80211.h       | 11 +++++++++++
>>>>>>  include/uapi/linux/nl80211.h | 21 +++++++++++++++++++++
>>>>>>  net/wireless/nl80211.c       | 16 ++++++++++++++++
>>>>>>  net/wireless/rdev-ops.h      | 22 ++++++++++++++++++++++
>>>>>>  net/wireless/trace.h         | 20 ++++++++++++++++++++
>>>>>>  5 files changed, 90 insertions(+)
>>>>>>
>>>>>> diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
>>>>>> index 9e1b24c..aa77fa0 100644
>>>>>> --- a/include/net/cfg80211.h
>>>>>> +++ b/include/net/cfg80211.h
>>>>>> @@ -2370,6 +2370,12 @@ struct cfg80211_qos_map {
>>>>>>   * @get_tx_power: store the current TX power into the dbm
>>>>>> variable;
>>>>>>   *   return 0 if successful
>>>>>>   *
>>>>>> + * @set_tx_power_mode: set the transmit power mode. Some
>>>>>> device have
>>>>>> the ability
>>>>>> + *   to transform between different mode such as clamshell and
>>>>>> tablet mode.
>>>>>> + *   set_tx_power_mode allows setting of different TX power
>>>>>> mode at runtime.
>>>>>> + * @get_tx_power_mode: store the current TX power mode into
>>>>>> the mode
>>>>>> variable;
>>>>>> + *   return 0 if successful
>>>>>> + *
>>>>>>   * @set_wds_peer: set the WDS peer for a WDS interface
>>>>>>   *
>>>>>>   * @rfkill_poll: polls the hw rfkill line, use cfg80211
>>>>>> reporting
>>>>>> @@ -2631,6 +2637,11 @@ struct cfg80211_ops {
>>>>>>       int     (*get_tx_power)(struct wiphy *wiphy, struct
>>>>>> wireless_dev *wdev,
>>>>>>                               int *dbm);
>>>>>>
>>>>>> +     int     (*set_tx_power_mode)(struct wiphy *wiphy,
>>>>>> +                                  enum nl80211_tx_power_mode
>>>>>> mode);
>>>>>> +     int     (*get_tx_power_mode)(struct wiphy *wiphy,
>>>>>> +                                  enum nl80211_tx_power_mode
>>>>>> *mode);
>>>>>> +
>>>>>>       int     (*set_wds_peer)(struct wiphy *wiphy, struct
>>>>>> net_device *dev,
>>>>>>                               const u8 *addr);
>>>>>>
>>>>>> diff --git a/include/uapi/linux/nl80211.h
>>>>>> b/include/uapi/linux/nl80211.h
>>>>>> index 5a30a75..9b1888a 100644
>>>>>> --- a/include/uapi/linux/nl80211.h
>>>>>> +++ b/include/uapi/linux/nl80211.h
>>>>>> @@ -1796,6 +1796,9 @@ enum nl80211_commands {
>>>>>>   *   connecting to a PCP, and in %NL80211_CMD_START_AP to
>>>>>> start
>>>>>>   *   a PCP instead of AP. Relevant for DMG networks only.
>>>>>>   *
>>>>>> + * @NL80211_ATTR_WIPHY_TX_POWER_MODE: Transmit power mode. See
>>>>>> + *      &enum nl80211_tx_power_mode for possible values.
>>>>>> + *
>>>>>>   * @NUM_NL80211_ATTR: total number of nl80211_attrs available
>>>>>>   * @NL80211_ATTR_MAX: highest attribute number currently
>>>>>> defined
>>>>>>   * @__NL80211_ATTR_AFTER_LAST: internal use
>>>>>> @@ -2172,6 +2175,8 @@ enum nl80211_attrs {
>>>>>>
>>>>>>       NL80211_ATTR_PBSS,
>>>>>>
>>>>>> +     NL80211_ATTR_WIPHY_TX_POWER_MODE,
>>>>>> +
>>>>>>       /* add attributes here, update the policy in nl80211.c */
>>>>>>
>>>>>>       __NL80211_ATTR_AFTER_LAST,
>>>>>> @@ -3703,6 +3708,22 @@ enum nl80211_tx_power_setting {
>>>>>>  };
>>>>>>
>>>>>>  /**
>>>>>> + * enum nl80211_tx_power_mode - TX power mode setting
>>>>>> + * @NL80211_TX_POWER_LOW: general low TX power mode
>>>>>> + * @NL80211_TX_POWER_MEDIUM: general medium TX power mode
>>>>>> + * @NL80211_TX_POWER_HIGH: general high TX power mode
>>>>>> + * @NL80211_TX_POWER_CLAMSHELL: clamshell mode TX power mode
>>>>>> + * @NL80211_TX_POWER_TABLET: tablet mode TX power mode
>>>>>> + */
>>>>>> +enum nl80211_tx_power_mode {
>>>>>> +     NL80211_TX_POWER_LOW,
>>>>>> +     NL80211_TX_POWER_MEDIUM,
>>>>>> +     NL80211_TX_POWER_HIGH,
>>>>>> +     NL80211_TX_POWER_CLAMSHELL,
>>>>>> +     NL80211_TX_POWER_TABLET,
>>>>>
>>>>> "clamshell" and "tablet" probably mean many different things to
>>>>> many
>>>>> different people with respect to whether or not they should do
>>>>> anything
>>>>> with power saving or wifi.  I feel like a more generic interface
>>>>> is
>>>>> needed here.
>>>> We could probably drop those two CLAMSHELL and TABLET constant or
>>>> describing what they mean
>>>> in more detail?
>>>>
>>>>>
>>>>>
>>>>> Could this be already done by:
>>>>> @NL80211_ATTR_WIPHY_TX_POWER_SETTING = NL80211_TX_POWER_LIMITED
>>>>> @NL80211_ATTR_WIPHY_TX_POWER_LEVEL = <limit for clamshell/tablet
>>>>> mode>
>>>>>
>>>>> and then the device would be able to change its TX power as it
>>>>> saw fit
>>>>> up to that limit set by your application which figures out
>>>>> whether it's
>>>>> in clamshell or tablet mode?
>>>> We usually want different power settings in different band/channel.
>>>> For example, we can have three different power settings
>>>> in 2.4Ghz, channels 36-64 & channels 100+ on 5Ghz. In this case, we
>>>> can not simply set a fixed number to the power level.
>>>> A power table is required to map channel/band to actual power
>>>> limit.
>>>> For most of the driver, changing power table requires loading
>>>> a new set of calibration data from either devicetree or ACPI. Due
>>>> to
>>>> this, a new message type is required to allow the driver to
>>>> switch between tables.
>>>>
>>>> Wei-Ning
>>> Hi Dan,
>>>
>>> Does this make sense to you? If so I'll send another patch to clarify
>>> the term clamshell / tablet mode.
>>> Thanks for reviewing.
>>
>> Yes, you're right that NL80211_ATTR_WIPHY_TX_POWER_SETTING is probably
>> too limiting.  But I feel that the constants that you've proposed are
>> too "magic" and will mean many different things to different driver
>> writers and userspace clients.  I think it would be better implemented
>> as a request to simply load specific power calibration data or a new
>> power table, instead of attempting to classify power tables through
>> kernel constants that could mean something different to everyone.
> 
> Dan, Thanks for the pointer. Passing the power table/calibration data
> name instead of
> constants sounds reasonable.
> 
> Johannes, I feel like being able to set calibration data at runtime is
> something common
> to all wireless drivers

Not really. Only implicitly, eg. when changing to another frequency band
etc.

> so instead of using vendor commands what do
> you think if I pass
> the calibration data name instead of using those magic constants? This
> way, userspace
> does not need to know the details of what band/range power limit the
> driver supports.

user-space still need to have knowledge about what calibration data name
to pick for different scenarios. Also this means the driver will use
request_firmware() api to obtain the actual calibration data? I think
you then want that signed like the crda database.

Regards,
Arend

> It allows for flexible driver side implementation and easier for
> userspace to control.
> 
> Wei-Ning
> 
>>
>> Dan
>>
>>> Wei-Ning
>>>>
>>>>>
>>>>>
>>>>>
>>>>> Dan
>>>>>
>>>>>>
>>>>>> +};
>>>>>> +
>>>>>> +/**
>>>>>>   * enum nl80211_packet_pattern_attr - packet pattern attribute
>>>>>>   * @__NL80211_PKTPAT_INVALID: invalid number for nested
>>>>>> attribute
>>>>>>   * @NL80211_PKTPAT_PATTERN: the pattern, values where the mask
>>>>>> has
>>>>>> diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
>>>>>> index 056a730..61b474d 100644
>>>>>> --- a/net/wireless/nl80211.c
>>>>>> +++ b/net/wireless/nl80211.c
>>>>>> @@ -402,6 +402,7 @@ static const struct nla_policy
>>>>>> nl80211_policy[NUM_NL80211_ATTR] = {
>>>>>>       [NL80211_ATTR_SCHED_SCAN_DELAY] = { .type = NLA_U32 },
>>>>>>       [NL80211_ATTR_REG_INDOOR] = { .type = NLA_FLAG },
>>>>>>       [NL80211_ATTR_PBSS] = { .type = NLA_FLAG },
>>>>>> +     [NL80211_ATTR_WIPHY_TX_POWER_MODE] = { .type = NLA_U32 },
>>>>>>  };
>>>>>>
>>>>>>  /* policy for the key attributes */
>>>>>> @@ -2218,6 +2219,21 @@ static int nl80211_set_wiphy(struct
>>>>>> sk_buff
>>>>>> *skb, struct genl_info *info)
>>>>>>                       return result;
>>>>>>       }
>>>>>>
>>>>>> +     if (info->attrs[NL80211_ATTR_WIPHY_TX_POWER_MODE]) {
>>>>>> +             enum nl80211_tx_power_mode mode;
>>>>>> +             int idx = 0;
>>>>>> +
>>>>>> +             if (!rdev->ops->set_tx_power_mode)
>>>>>> +                     return -EOPNOTSUPP;
>>>>>> +
>>>>>> +             idx = NL80211_ATTR_WIPHY_TX_POWER_MODE;
>>>>>> +             mode = nla_get_u32(info->attrs[idx]);
>>>>>> +
>>>>>> +             result = rdev_set_tx_power_mode(rdev, mode);
>>>>>> +             if (result)
>>>>>> +                     return result;
>>>>>> +     }
>>>>>> +
>>>>>>       if (info->attrs[NL80211_ATTR_WIPHY_ANTENNA_TX] &&
>>>>>>           info->attrs[NL80211_ATTR_WIPHY_ANTENNA_RX]) {
>>>>>>               u32 tx_ant, rx_ant;
>>>>>> diff --git a/net/wireless/rdev-ops.h b/net/wireless/rdev-ops.h
>>>>>> index 8ae0c04..c3a1035 100644
>>>>>> --- a/net/wireless/rdev-ops.h
>>>>>> +++ b/net/wireless/rdev-ops.h
>>>>>> @@ -552,6 +552,28 @@ static inline int rdev_get_tx_power(struct
>>>>>> cfg80211_registered_device *rdev,
>>>>>>       return ret;
>>>>>>  }
>>>>>>
>>>>>> +static inline int
>>>>>> +rdev_set_tx_power_mode(struct cfg80211_registered_device
>>>>>> *rdev,
>>>>>> +                    enum nl80211_tx_power_mode mode)
>>>>>> +{
>>>>>> +     int ret;
>>>>>> +     trace_rdev_set_tx_power_mode(&rdev->wiphy, mode);
>>>>>> +     ret = rdev->ops->set_tx_power_mode(&rdev->wiphy, mode);
>>>>>> +     trace_rdev_return_int(&rdev->wiphy, ret);
>>>>>> +     return ret;
>>>>>> +}
>>>>>> +
>>>>>> +static inline int
>>>>>> +rdev_get_tx_power_mode(struct cfg80211_registered_device
>>>>>> *rdev,
>>>>>> +                    enum nl80211_tx_power_mode *mode)
>>>>>> +{
>>>>>> +     int ret;
>>>>>> +     trace_rdev_get_tx_power_mode(&rdev->wiphy);
>>>>>> +     ret = rdev->ops->get_tx_power_mode(&rdev->wiphy, mode);
>>>>>> +     trace_rdev_return_int_int(&rdev->wiphy, ret, *mode);
>>>>>> +     return ret;
>>>>>> +}
>>>>>> +
>>>>>>  static inline int rdev_set_wds_peer(struct
>>>>>> cfg80211_registered_device *rdev,
>>>>>>                                   struct net_device *dev, const
>>>>>> u8
>>>>>> *addr)
>>>>>>  {
>>>>>> diff --git a/net/wireless/trace.h b/net/wireless/trace.h
>>>>>> index 09b242b..132c8c2 100644
>>>>>> --- a/net/wireless/trace.h
>>>>>> +++ b/net/wireless/trace.h
>>>>>> @@ -1420,6 +1420,26 @@ TRACE_EVENT(rdev_set_tx_power,
>>>>>>                 WIPHY_PR_ARG, WDEV_PR_ARG,__entry->type,
>>>>>> __entry-
>>>>>>>
>>>>>>> mbm)
>>>>>>  );
>>>>>>
>>>>>> +DEFINE_EVENT(wiphy_only_evt, rdev_get_tx_power_mode,
>>>>>> +     TP_PROTO(struct wiphy *wiphy),
>>>>>> +     TP_ARGS(wiphy)
>>>>>> +);
>>>>>> +
>>>>>> +TRACE_EVENT(rdev_set_tx_power_mode,
>>>>>> +     TP_PROTO(struct wiphy *wiphy, enum nl80211_tx_power_mode
>>>>>> mode),
>>>>>> +     TP_ARGS(wiphy, mode),
>>>>>> +     TP_STRUCT__entry(
>>>>>> +             WIPHY_ENTRY
>>>>>> +             __field(enum nl80211_tx_power_mode, mode)
>>>>>> +     ),
>>>>>> +     TP_fast_assign(
>>>>>> +             WIPHY_ASSIGN;
>>>>>> +             __entry->mode = mode;
>>>>>> +     ),
>>>>>> +     TP_printk(WIPHY_PR_FMT ", mode: %d",
>>>>>> +               WIPHY_PR_ARG, __entry->mode)
>>>>>> +);
>>>>>> +
>>>>>>  TRACE_EVENT(rdev_return_int_int,
>>>>>>       TP_PROTO(struct wiphy *wiphy, int func_ret, int
>>>>>> func_fill),
>>>>>>       TP_ARGS(wiphy, func_ret, func_fill),
>>>>
>>>>
>>>>
>>>> --
>>>> Wei-Ning Huang, 黃偉寧 | Software Engineer, Google Inc., Taiwan |
>>>> wnhuang@google.com | Cell: +886 910-380678
>>>
>>>
> 
> 
> 

  reply	other threads:[~2016-05-12 22:02 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-05-05  6:44 [PATCH] cfg80211/nl80211: add wifi tx power mode switching support Wei-Ning Huang
2016-05-05 16:07 ` Dan Williams
2016-05-06  8:19   ` Wei-Ning Huang
2016-05-11  5:03     ` Wei-Ning Huang
2016-05-11 18:33       ` Dan Williams
2016-05-12  9:34         ` Wei-Ning Huang
2016-05-12 22:02           ` Arend van Spriel [this message]
2016-05-13  3:22             ` Wei-Ning Huang
2016-06-28 10:57           ` Johannes Berg
2016-06-28 10:57             ` Johannes Berg
2016-07-07  9:30             ` Wei-Ning Huang
2016-05-11  7:21 ` Johannes Berg
2016-05-11  7:21   ` Johannes Berg
2016-11-21  8:50 ` form factor subsystem (Re: [PATCH] cfg80211/nl80211: add wifi tx power mode switching support) Johannes Berg

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=5734FD7E.7010307@broadcom.com \
    --to=arend.vanspriel@broadcom.com \
    --cc=davem@davemloft.net \
    --cc=dcbw@redhat.com \
    --cc=johannes@sipsolutions.net \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-wireless@vger.kernel.org \
    --cc=netdev@vger.kernel.org \
    --cc=snanda@chromium.org \
    --cc=tbroch@chromium.org \
    --cc=wnhuang@google.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.