Linux wireless drivers development
 help / color / mirror / Atom feed
* Re: [wireless-drivers-next:master 28/45] drivers/net/wireless/rsi/rsi_91x_usb.c:229:27: sparse: restricted __le32 degrades to integer
From: Siva Rebbagondla @ 2019-04-26 11:34 UTC (permalink / raw)
  To: Kalle Valo; +Cc: kbuild test robot, kbuild-all, Linux Wireless
In-Reply-To: <875zr1wi3z.fsf@kamboji.qca.qualcomm.com>

Hi Kalle,

On Fri, Apr 26, 2019 at 9:09 AM Kalle Valo <kvalo@codeaurora.org> wrote:
>
> + linux-wireless
>
> Siva Rebbagondla <siva8118@gmail.com> writes:
>
> > Hi Kalle,
> >
> > On Fri, Apr 26, 2019 at 1:06 AM kbuild test robot <lkp@intel.com> wrote:
> >>
> >> tree:   https://git.kernel.org/pub/scm/linux/kernel/git/kvalo/wireless-drivers-next.git master
> >> head:   147b502bda338f4f2dff19faaa5829b691305ea5
> >> commit: 0a60014b76f512f18e48cfb4efc71e07c6791996 [28/45] rsi: miscallaneous changes for 9116 and common
> >> reproduce:
> >>         # apt-get install sparse
> >>         git checkout 0a60014b76f512f18e48cfb4efc71e07c6791996
> >>         make ARCH=x86_64 allmodconfig
> >>         make C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__'
> >>
> >> If you fix the issue, kindly add following tag
> >> Reported-by: kbuild test robot <lkp@intel.com>
> >>
> >>
> >> sparse warnings: (new ones prefixed by >>)
> >>
> >> >> drivers/net/wireless/rsi/rsi_91x_usb.c:229:27: sparse: restricted __le32 degrades to integer
> >>    drivers/net/wireless/rsi/rsi_91x_usb.c:230:27: sparse: restricted __le32 degrades to integer
> >>    drivers/net/wireless/rsi/rsi_91x_usb.c:231:27: sparse: restricted __le32 degrades to integer
> >>    drivers/net/wireless/rsi/rsi_91x_usb.c:232:27: sparse: restricted __le32 degrades to integer
> >>    drivers/net/wireless/rsi/rsi_91x_usb.c:238:36: sparse: restricted __le32 degrades to integer
> >>    drivers/net/wireless/rsi/rsi_91x_usb.c:239:35: sparse: restricted __le32 degrades to integer
> >>    drivers/net/wireless/rsi/rsi_91x_usb.c:354:28: sparse: expression using sizeof(void)
> >>    drivers/net/wireless/rsi/rsi_91x_usb.c:401:28: sparse: expression using sizeof(void)
> >>
> >> vim +229 drivers/net/wireless/rsi/rsi_91x_usb.c
> >>
> >>    203
> >>    204  /**
> >>    205   * rsi_usb_reg_write() - This function writes the given data into the given
> >>    206   *                       register address.
> >>    207   * @usbdev: Pointer to the usb_device structure.
> >>    208   * @reg: Address of the register.
> >>    209   * @value: Value to write.
> >>    210   * @len: Length of data to be written.
> >>    211   *
> >>    212   * Return: status: 0 on success, a negative error code on failure.
> >>    213   */
> >>    214  static int rsi_usb_reg_write(struct usb_device *usbdev,
> >>    215                               u32 reg,
> >>    216                               u32 value,
> >>    217                               u16 len)
> >>    218  {
> >>    219          u8 *usb_reg_buf;
> >>    220          int status = -ENOMEM;
> >>    221
> >>    222          if (len > RSI_USB_CTRL_BUF_SIZE)
> >>    223                  return -EINVAL;
> >>    224
> >>    225          usb_reg_buf  = kmalloc(RSI_USB_CTRL_BUF_SIZE, GFP_KERNEL);
> >>    226          if (!usb_reg_buf)
> >>    227                  return status;
> >>    228
> >>  > 229          usb_reg_buf[0] = (cpu_to_le32(value) & 0x00ff);
> >>    230          usb_reg_buf[1] = (cpu_to_le32(value) & 0xff00) >> 8;
> >>    231          usb_reg_buf[2] = (cpu_to_le32(value) & 0x00ff0000) >> 16;
> >>    232          usb_reg_buf[3] = (cpu_to_le32(value) & 0xff000000) >> 24;
> >>    233
> >>    234          status = usb_control_msg(usbdev,
> >>    235                                   usb_sndctrlpipe(usbdev, 0),
> >>    236                                   USB_VENDOR_REGISTER_WRITE,
> >>    237                                   RSI_USB_REQ_OUT,
> >>    238                                   ((cpu_to_le32(reg) & 0xffff0000) >> 16),
> >>    239                                   (cpu_to_le32(reg) & 0xffff),
> >>    240                                   (void *)usb_reg_buf,
> >>    241                                   len,
> >>    242                                   USB_CTRL_SET_TIMEOUT);
> >>    243          if (status < 0) {
> >>    244                  rsi_dbg(ERR_ZONE,
> >>    245                          "%s: Reg write failed with error code :%d\n",
> >>    246                          __func__, status);
> >>    247          }
> >>    248          kfree(usb_reg_buf);
> >>    249
> >>    250          return status;
> >>    251  }
> >>    252
> >>
> >> ---
> >> 0-DAY kernel test infrastructure                Open Source Technology Center
> >> https://lists.01.org/pipermail/kbuild-all                   Intel Corporation
> >
> > Some where went wrong. I fixed this one. I will resend you the patches
> > with changes.
>
> Your patches are now applied and cannot be changed, so no point of
> resending them anymore. You need to send followup patches which fix the
> issues and apply to wireless-drivers-next.
>
> And remember to use Fixes tag so that we know which commit patch fixes.
Sure. I will send a patch which fixes this.

Best regards,
Siva Rebbagondla

^ permalink raw reply

* pull-request: mac80211-next 2019-04-26
From: Johannes Berg @ 2019-04-26 11:11 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, linux-wireless

Hi Dave,

And another set for -next, not that big this time.
See below for a summary of the highlights.

Please pull and let me know if there's any problem.

Thanks,
johannes



The following changes since commit 1f17f7742eeba73dbd5ae8bdec1a85ce5877001e:

  net: sched: flower: insert filter to ht before offloading it to hw (2019-04-07 19:33:07 -0700)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next.git tags/mac80211-next-for-davem-2019-04-26

for you to fetch changes up to 8828f81ad4a2f4e89ebe6e7793c06ed767c31d53:

  mac80211: probe unexercised mesh links (2019-04-26 13:02:11 +0200)

----------------------------------------------------------------
Various updates, notably:
 * extended key ID support (from 802.11-2016)
 * per-STA TX power control support
 * mac80211 TX performance improvements
 * HE (802.11ax) updates
 * mesh link probing support
 * enhancements of multi-BSSID support (also related to HE)
 * OWE userspace processing support

----------------------------------------------------------------
Alexander Wetzel (6):
      mac80211: Optimize tailroom_needed update checks
      nl80211/cfg80211: Extended Key ID support
      mac80211: IEEE 802.11 Extended Key ID support
      mac80211: Fix Extended Key ID auto activation
      mac80211_hwsim: Extended Key ID support
      mac80211: Set CAN_REPLACE_PTK0 for SW crypto only drivers

Ashok Raj Nagarajan (2):
      cfg80211: Add support to set tx power for a station associated
      mac80211: store tx power value from user to station

Avraham Stern (1):
      mac80211_hwsim: set p2p device interface support indication

Colin Ian King (1):
      cfg80211: remove redundant zero check on variable 'changed'

Dan Carpenter (1):
      cfg80211: don't pass pointer to pointer unnecessarily

Felix Fietkau (7):
      mac80211: mesh: drop redundant rcu_read_lock/unlock calls
      mac80211: calculate hash for fq without holding fq->lock in itxq enqueue
      mac80211: run late dequeue late tx handlers without holding fq->lock
      mac80211: set NETIF_F_LLTX when using intermediate tx queues
      mac80211: when using iTXQ, select the queue in ieee80211_subif_start_xmit
      mac80211: minstrel_ht: add support for rates with 4 spatial streams
      mac80211: minstrel_ht: automatically calculate rate duration shift

Gustavo A. R. Silva (2):
      cfg80211: Use struct_size() in kzalloc()
      nl80211: Use struct_size() in kzalloc()

Johannes Berg (2):
      nl80211: reindent some sched scan code
      mac80211: only allocate one queue when using iTXQs

Julius Niedworok (1):
      mac80211: debugfs option to force TX status frames

Liad Kaufman (1):
      ieee80211: update HE IEs to D4.0 spec

Luca Coelho (1):
      nl80211: do a struct assignment to radar_chandef instead of memcpy()

Narayanraddi Masti (1):
      mac80211: Add support for NL80211_STA_INFO_AIRTIME_LINK_METRIC

Rajkumar Manoharan (3):
      cfg80211: add support to probe unexercised mesh link
      mac80211: add option for setting control flags
      mac80211: probe unexercised mesh links

Sara Sharon (5):
      cfg80211: don't skip multi-bssid index element
      cfg80211: support non-inheritance element
      mac80211: support non-inheritance element
      cfg80211: support profile split between elements
      mac80211: support profile split between elements

Sergey Matyukevich (1):
      mac80211/cfg80211: update bss channel on channel switch

Shaul Triebitz (1):
      nl80211: increase NL80211_MAX_SUPP_REG_RULES

Sunil Dutt (1):
      cfg80211/nl80211: Offload OWE processing to user space in AP mode

vamsi krishna (1):
      nl80211/cfg80211: Specify band specific min RSSI thresholds with sched scan

 drivers/net/wireless/mac80211_hwsim.c |   8 +
 include/linux/ieee80211.h             |  14 +-
 include/net/cfg80211.h                | 104 +++++++++++
 include/net/fq_impl.h                 |  18 +-
 include/net/mac80211.h                |  30 +++
 include/uapi/linux/nl80211.h          |  86 ++++++++-
 net/mac80211/cfg.c                    |  46 +++++
 net/mac80211/debugfs.c                |  54 ++++++
 net/mac80211/driver-ops.c             |  21 +++
 net/mac80211/driver-ops.h             |   5 +
 net/mac80211/ieee80211_i.h            |   9 +-
 net/mac80211/iface.c                  |  11 +-
 net/mac80211/key.c                    |  87 ++++++---
 net/mac80211/key.h                    |   2 +
 net/mac80211/main.c                   |  16 ++
 net/mac80211/mesh.h                   |   2 +
 net/mac80211/mesh_hwmp.c              |  34 ++--
 net/mac80211/mesh_pathtbl.c           |   2 +-
 net/mac80211/mlme.c                   |   3 -
 net/mac80211/rc80211_minstrel_ht.c    | 124 ++++++++-----
 net/mac80211/rc80211_minstrel_ht.h    |   2 +-
 net/mac80211/rx.c                     |  74 ++++----
 net/mac80211/sta_info.c               |  15 ++
 net/mac80211/tdls.c                   |   2 +-
 net/mac80211/trace.h                  |  30 +++
 net/mac80211/tx.c                     | 113 +++++++++---
 net/mac80211/util.c                   | 162 ++++++++++-------
 net/mac80211/wme.c                    |  82 +++++----
 net/mac80211/wme.h                    |   2 +
 net/wireless/nl80211.c                | 331 +++++++++++++++++++++++++++++-----
 net/wireless/rdev-ops.h               |  29 ++-
 net/wireless/reg.c                    |  23 +--
 net/wireless/scan.c                   | 173 +++++++++++++++++-
 net/wireless/trace.h                  |  87 ++++++++-
 net/wireless/util.c                   |  21 ++-
 net/wireless/wext-compat.c            |   3 -
 36 files changed, 1465 insertions(+), 360 deletions(-)


^ permalink raw reply

* Re: [PATCH] cfg80211: Handle bss expiry during connection
From: Krishna Chaitanya @ 2019-04-26 10:56 UTC (permalink / raw)
  To: Johannes Berg; +Cc: linux-wireless, Chaitanya Tata
In-Reply-To: <d569a6171e50a8bdb026a2ec86c78268c9d7e989.camel@sipsolutions.net>

On Fri, Apr 26, 2019 at 4:15 PM Johannes Berg <johannes@sipsolutions.net> wrote:
>
> On Fri, 2019-04-26 at 16:05 +0530, Krishna Chaitanya wrote:
>
> > > > +             /* Meanwhile if BSS is expired then add it back to the list as
> > > > +              * we have just connected with it.
> > > > +              */
> > > > +             if (list_empty(&ibss->list))
> > > > +                     cfg80211_bss_update(rdev, ibss, ibss->pub.signal);
> > >
> > > But I think this adds *another* reference, which is wrong? We do need
> > > one reference (the original one the driver gave us) but not a second
> > > one?
> >
> > This was assuming found will be false so refcnt will be reset and a fresh ref
> > is taken.
>
> Yes, it actually adds a new entry entirely, not refs the old entry. But
> then you have a new entry returned from cfg80211_bss_update() with a
> reference, and leak that reference in the code as written.
>
> You probably need to unref the old one, and keep the new one to pass on
> to the next function etc.
>

Right, we should unref after the update.

> > > Maybe the copy we do in cfg80211_bss_update() isn't so bad, but then I'd
> > > probably expose it without the signal_valid part and signal/timestamp
> > > updates, and just copy the information raw there? However, the "if
> > > (found)" part should never be possible here, right? Actually, maybe it
> > > is, if we got a *new* entry in the meantime, but then we'd override the
> > > newer information with the older, which is kinda bad?
> >
> > If we get new information (scan during connection) the bss would not have
> > expired right? so this code will not be triggered.
>
> It could have expired and been re-added, no? Ok, I'll admit that's a
> stretch since the driver is busy connecting and not scanning, but I
> suppose it could happen with multiple VIFs etc?

Yes, it might be possible with multiple VIF's, when one VIF is connecting
and other VIF is scanning, it can find the connecting bssid in its scan results.

> > My initial stab was in similar lines, something like below: But as the
> > bss is expired
> > we need to udpate ts, signal and other fields anyway, so I went ahead
> > with full update.
>
> Why would we want to update ts, signal etc.? We just keep the old
> information, and then the entry will be held for the duration of the
> connection, presumably it'll get new updates while you're connected.

If we are holding it, then we will not be using ts anyway, so updating or
not should not matter. But as its old info better to leave it that way, and
update these fields only from scan results.

> > +void cfg80211_add_expired_bss(struct cfg80211_registered_device *rdev,
> > +                            struct cfg80211_internal_bss *new)
> > +{
> > +       if (!new)
> > +               return;
> > +
> > +       spin_lock_bh(&rdev->bss_lock);
> > +       new->ts = jiffies
> > +       list_add_tail(&new->list, &rdev->bss_list);
> > +       rdev->bss_entries++;
> > +
> > +       rb_insert_bss(rdev, new);
> > +       rdev->bss_generation++;
> > +
> > +       bss_ref_get(rdev, new);
> > +
> > +       spin_unlock_bh(&rdev->bss_lock);
> > +}
>
> Yeah, I was thinking along those lines too, except there's a bit of an
> issue with the hidden and non-transmitting lists?
Ok, let me think for a bit and will send you V2. Thanks for quick review.
> johannes
>


-- 
Thanks,
Regards,
Chaitanya T K.

^ permalink raw reply

* Re: [PATCH] cfg80211: Handle bss expiry during connection
From: Johannes Berg @ 2019-04-26 10:45 UTC (permalink / raw)
  To: Krishna Chaitanya; +Cc: linux-wireless, Chaitanya Tata
In-Reply-To: <CABPxzYK3MuJT=r3o6UgBqv-m1B2pqCACwq+i1DDRkC2ZHExvxQ@mail.gmail.com>

On Fri, 2019-04-26 at 16:05 +0530, Krishna Chaitanya wrote:

> > > +             /* Meanwhile if BSS is expired then add it back to the list as
> > > +              * we have just connected with it.
> > > +              */
> > > +             if (list_empty(&ibss->list))
> > > +                     cfg80211_bss_update(rdev, ibss, ibss->pub.signal);
> > 
> > But I think this adds *another* reference, which is wrong? We do need
> > one reference (the original one the driver gave us) but not a second
> > one?
> 
> This was assuming found will be false so refcnt will be reset and a fresh ref
> is taken.

Yes, it actually adds a new entry entirely, not refs the old entry. But
then you have a new entry returned from cfg80211_bss_update() with a
reference, and leak that reference in the code as written.

You probably need to unref the old one, and keep the new one to pass on
to the next function etc.

> > Maybe the copy we do in cfg80211_bss_update() isn't so bad, but then I'd
> > probably expose it without the signal_valid part and signal/timestamp
> > updates, and just copy the information raw there? However, the "if
> > (found)" part should never be possible here, right? Actually, maybe it
> > is, if we got a *new* entry in the meantime, but then we'd override the
> > newer information with the older, which is kinda bad?
> 
> If we get new information (scan during connection) the bss would not have
> expired right? so this code will not be triggered.

It could have expired and been re-added, no? Ok, I'll admit that's a
stretch since the driver is busy connecting and not scanning, but I
suppose it could happen with multiple VIFs etc?

> My initial stab was in similar lines, something like below: But as the
> bss is expired
> we need to udpate ts, signal and other fields anyway, so I went ahead
> with full update.

Why would we want to update ts, signal etc.? We just keep the old
information, and then the entry will be held for the duration of the
connection, presumably it'll get new updates while you're connected.

> +void cfg80211_add_expired_bss(struct cfg80211_registered_device *rdev,
> +                            struct cfg80211_internal_bss *new)
> +{
> +       if (!new)
> +               return;
> +
> +       spin_lock_bh(&rdev->bss_lock);
> +       new->ts = jiffies
> +       list_add_tail(&new->list, &rdev->bss_list);
> +       rdev->bss_entries++;
> +
> +       rb_insert_bss(rdev, new);
> +       rdev->bss_generation++;
> +
> +       bss_ref_get(rdev, new);
> +
> +       spin_unlock_bh(&rdev->bss_lock);
> +}

Yeah, I was thinking along those lines too, except there's a bit of an
issue with the hidden and non-transmitting lists?

johannes


^ permalink raw reply

* Re: [PATCH] cfg80211: Handle bss expiry during connection
From: Krishna Chaitanya @ 2019-04-26 10:35 UTC (permalink / raw)
  To: Johannes Berg; +Cc: linux-wireless, Chaitanya Tata
In-Reply-To: <cb1c3fcafc7addf0ed8d8d946658801472ad8a1b.camel@sipsolutions.net>

On Fri, Apr 26, 2019 at 3:44 PM Johannes Berg <johannes@sipsolutions.net> wrote:
>
> On Fri, 2019-04-26 at 15:24 +0530, chaitanya.mgit@gmail.com wrote:
> > From: Chaitanya Tata <chaitanya.tata@bluwireless.co.uk>
> >
> > If the BSS is expired during connection, the connect result will
> > trigger a kernel warning. Ideally cfg80211 should hold the BSS
> > before the connection is attempted, but as the BSSID is not known
> > in case of auth/assoc MLME offload (connect op) it doesn't.
> >
> > For those drivers without the connect op cfg80211 holds down the
> > reference so it wil not be removed from list.
> >
> > Fix this by removing the warning and silently adding the BSS back to
> > the bss list which is return by the driver (with proper BSSID set).
> > The requirements for drivers are documented in the API's.
>
> This looks good, mostly :-)
>
> >   * @bssid: The BSSID of the AP (may be %NULL)
> >   * @bss: Entry of bss to which STA got connected to, can be obtained through
> > - *   cfg80211_get_bss() (may be %NULL). Only one parameter among @bssid and
> > - *   @bss needs to be specified.
> > + *   cfg80211_get_bss() (may be %NULL) but it is recommended to store the
> > + *   bss from the connect_request and hold a reference to it and return
> > + *   through this param to avoid warning if the bss is expired during the
> > + *   connection, esp. for those drivers implementing connect op.
> > + *   Only one parameter among @bssid and @bss needs to be specified.
>
> So while we're at it, we should probably amend the documentation to say
> that the reference to the BSS passes from the driver to cfg80211, right?
Yes
>
> > +     /* bss is not NULL, so even though bss might have expired, the driver
> > +      * is still holding a reference to it.
> > +      */
>
> is -> was? It's our reference now.
Yes
>
> >       if (params->bss) {
> > -             /* Make sure the bss entry provided by the driver is valid. */
> >               struct cfg80211_internal_bss *ibss = bss_from_pub(params->bss);
> >
> > -             if (WARN_ON(list_empty(&ibss->list))) {
> > -                     cfg80211_put_bss(wdev->wiphy, params->bss);
>
> That's why we had a put_bss() here.
I will add a change to put bss after we update.
>
> > +             /* Meanwhile if BSS is expired then add it back to the list as
> > +              * we have just connected with it.
> > +              */
> > +             if (list_empty(&ibss->list))
> > +                     cfg80211_bss_update(rdev, ibss, ibss->pub.signal);
>
> But I think this adds *another* reference, which is wrong? We do need
> one reference (the original one the driver gave us) but not a second
> one?
This was assuming found will be false so refcnt will be reset and a fresh ref
is taken.
> Also, not sure the last argument (signal_valid) is right?
>
> Basically all that really just means that cfg80211_bss_update() is
> probably not the right function to call. It also updates the timestamp,
> which is not true, we haven't received updated information we just used
> it and thus held on to it.
>
> I think we should probably just instead of a "cfg80211_bss_relink()"
> function exposed, and that just does something like
>
>         list_add_tail(&new->list, &rdev->bss_list);
>         rdev->bss_entries++;
>         rb_insert_bss(rdev, new);
>
>         rdev->bss_generation++;
>
> though I'm not - off the top of my head - sure about
> cfg80211_combine_bsses() being needed or not.
>
> Maybe the copy we do in cfg80211_bss_update() isn't so bad, but then I'd
> probably expose it without the signal_valid part and signal/timestamp
> updates, and just copy the information raw there? However, the "if
> (found)" part should never be possible here, right? Actually, maybe it
> is, if we got a *new* entry in the meantime, but then we'd override the
> newer information with the older, which is kinda bad?

If we get new information (scan during connection) the bss would not have
expired right? so this code will not be triggered.

My initial stab was in similar lines, something like below: But as the
bss is expired
we need to udpate ts, signal and other fields anyway, so I went ahead
with full update.
+void cfg80211_add_expired_bss(struct cfg80211_registered_device *rdev,
+                            struct cfg80211_internal_bss *new)
+{
+       if (!new)
+               return;
+
+       spin_lock_bh(&rdev->bss_lock);
+       new->ts = jiffies
+       list_add_tail(&new->list, &rdev->bss_list);
+       rdev->bss_entries++;
+
+       rb_insert_bss(rdev, new);
+       rdev->bss_generation++;
+
+       bss_ref_get(rdev, new);
+
+       spin_unlock_bh(&rdev->bss_lock);
+}


> johannes
>


-- 
Thanks,
Regards,
Chaitanya T K.

^ permalink raw reply

* Re: [PATCH] cfg80211: Handle bss expiry during connection
From: Johannes Berg @ 2019-04-26 10:14 UTC (permalink / raw)
  To: chaitanya.mgit, linux-wireless; +Cc: Chaitanya Tata
In-Reply-To: <20190426095448.3169-1-chaitanya.mgit@gmail.com>

On Fri, 2019-04-26 at 15:24 +0530, chaitanya.mgit@gmail.com wrote:
> From: Chaitanya Tata <chaitanya.tata@bluwireless.co.uk>
> 
> If the BSS is expired during connection, the connect result will
> trigger a kernel warning. Ideally cfg80211 should hold the BSS
> before the connection is attempted, but as the BSSID is not known
> in case of auth/assoc MLME offload (connect op) it doesn't.
> 
> For those drivers without the connect op cfg80211 holds down the
> reference so it wil not be removed from list.
> 
> Fix this by removing the warning and silently adding the BSS back to
> the bss list which is return by the driver (with proper BSSID set).
> The requirements for drivers are documented in the API's.

This looks good, mostly :-)

>   * @bssid: The BSSID of the AP (may be %NULL)
>   * @bss: Entry of bss to which STA got connected to, can be obtained through
> - *	cfg80211_get_bss() (may be %NULL). Only one parameter among @bssid and
> - *	@bss needs to be specified.
> + *	cfg80211_get_bss() (may be %NULL) but it is recommended to store the
> + *	bss from the connect_request and hold a reference to it and return
> + *	through this param to avoid warning if the bss is expired during the
> + *	connection, esp. for those drivers implementing connect op.
> + *	Only one parameter among @bssid and @bss needs to be specified.

So while we're at it, we should probably amend the documentation to say
that the reference to the BSS passes from the driver to cfg80211, right?

> +	/* bss is not NULL, so even though bss might have expired, the driver
> +	 * is still holding a reference to it.
> +	 */

is -> was? It's our reference now.

>  	if (params->bss) {
> -		/* Make sure the bss entry provided by the driver is valid. */
>  		struct cfg80211_internal_bss *ibss = bss_from_pub(params->bss);
>  
> -		if (WARN_ON(list_empty(&ibss->list))) {
> -			cfg80211_put_bss(wdev->wiphy, params->bss);

That's why we had a put_bss() here.

> +		/* Meanwhile if BSS is expired then add it back to the list as
> +		 * we have just connected with it.
> +		 */
> +		if (list_empty(&ibss->list))
> +			cfg80211_bss_update(rdev, ibss, ibss->pub.signal);

But I think this adds *another* reference, which is wrong? We do need
one reference (the original one the driver gave us) but not a second
one?

Also, not sure the last argument (signal_valid) is right?

Basically all that really just means that cfg80211_bss_update() is
probably not the right function to call. It also updates the timestamp,
which is not true, we haven't received updated information we just used
it and thus held on to it.

I think we should probably just instead of a "cfg80211_bss_relink()"
function exposed, and that just does something like

        list_add_tail(&new->list, &rdev->bss_list);
        rdev->bss_entries++;
        rb_insert_bss(rdev, new);

        rdev->bss_generation++;

though I'm not - off the top of my head - sure about
cfg80211_combine_bsses() being needed or not.

Maybe the copy we do in cfg80211_bss_update() isn't so bad, but then I'd
probably expose it without the signal_valid part and signal/timestamp
updates, and just copy the information raw there? However, the "if
(found)" part should never be possible here, right? Actually, maybe it
is, if we got a *new* entry in the meantime, but then we'd override the
newer information with the older, which is kinda bad?

johannes


^ permalink raw reply

* Re: [PATCHv4 2/2] mac80211: Implement API to configure station specific rssi threshold
From: Johannes Berg @ 2019-04-26 10:04 UTC (permalink / raw)
  To: Tamizh chelvam; +Cc: linux-wireless
In-Reply-To: <1555492880-26457-3-git-send-email-tamizhr@codeaurora.org>


> +void ieee80211_update_rssi_config(struct sta_info *sta)
> +{
> +	s32 last;
> +	u32 hyst;
> +	int i, n;
> +
> +	if (!sta->rssi_config || sta->rssi_config->fixed_thold)
> +		return;

sparse is also giving various complaints about the RCU usage here.

johannes


^ permalink raw reply

* Re: [PATCHv4 0/2] cfg80211/mac80211: Add support to configure and monitor station's rssi threshold
From: Johannes Berg @ 2019-04-26 10:03 UTC (permalink / raw)
  To: Tamizh chelvam; +Cc: linux-wireless
In-Reply-To: <1555492880-26457-1-git-send-email-tamizhr@codeaurora.org>

On Wed, 2019-04-17 at 14:51 +0530, Tamizh chelvam wrote:
> This patchsets introduced new NL command and api to support
> configuring rssi for the connected stations and api to notify
> userspace application upon crossing the configured threshold.
> This will be useful for the application which requires
> station's current signal strength change information.

What is "the application"?

Given all our discussions at the summit and my thinking on all of this
recently, I'm _very_ tempted to just reject this patchset after all, and
ask you to (help) implement appropriate eBPF hooks in the stack that can
be used to implement it instead.

Why is this better than programmable infrastructure for it?

johannes


^ permalink raw reply

* [PATCH] cfg80211: Handle bss expiry during connection
From: chaitanya.mgit @ 2019-04-26  9:54 UTC (permalink / raw)
  To: linux-wireless; +Cc: Chaitanya Tata

From: Chaitanya Tata <chaitanya.tata@bluwireless.co.uk>

If the BSS is expired during connection, the connect result will
trigger a kernel warning. Ideally cfg80211 should hold the BSS
before the connection is attempted, but as the BSSID is not known
in case of auth/assoc MLME offload (connect op) it doesn't.

For those drivers without the connect op cfg80211 holds down the
reference so it wil not be removed from list.

Fix this by removing the warning and silently adding the BSS back to
the bss list which is return by the driver (with proper BSSID set).
The requirements for drivers are documented in the API's.

Signed-off-by: Chaitanya Tata <chaitanya.tata@bluwireless.co.uk>
---
Tested this using the below hack in cfg80211_connect_done():
	cfg80211_bss_age(rdev, get_seconds() - 30);
	cfg80211_bss_expire(rdev);
---
 include/net/cfg80211.h | 13 ++++++++++---
 net/wireless/core.h    |  5 +++++
 net/wireless/scan.c    |  2 +-
 net/wireless/sme.c     | 13 ++++++++-----
 4 files changed, 24 insertions(+), 9 deletions(-)

diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index bb307a11ee63..91fee5ab2433 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -6137,8 +6137,12 @@ struct cfg80211_fils_resp_params {
  *	case.
  * @bssid: The BSSID of the AP (may be %NULL)
  * @bss: Entry of bss to which STA got connected to, can be obtained through
- *	cfg80211_get_bss() (may be %NULL). Only one parameter among @bssid and
- *	@bss needs to be specified.
+ *	cfg80211_get_bss() (may be %NULL) but it is recommended to store the
+ *	bss from the connect_request and hold a reference to it and return
+ *	through this param to avoid warning if the bss is expired during the
+ *	connection, esp. for those drivers implementing connect op.
+ *	Only one parameter among @bssid and @bss needs to be specified.
+
  * @req_ie: Association request IEs (may be %NULL)
  * @req_ie_len: Association request IEs length
  * @resp_ie: Association response IEs (may be %NULL)
@@ -6187,7 +6191,10 @@ void cfg80211_connect_done(struct net_device *dev,
  * @dev: network device
  * @bssid: the BSSID of the AP
  * @bss: entry of bss to which STA got connected to, can be obtained
- *	through cfg80211_get_bss (may be %NULL)
+ *	through cfg80211_get_bss (may be %NULL), but it is recommended to store
+ *	the bss from the connect_request and hold a reference to it and return
+ *	through this param to avoid warning if the bss is expired during the
+ *	connection, esp. for those drivers implementing connect op.
  * @req_ie: association request IEs (maybe be %NULL)
  * @req_ie_len: association request IEs length
  * @resp_ie: association response IEs (may be %NULL)
diff --git a/net/wireless/core.h b/net/wireless/core.h
index 84d36ca7a7ab..7ad461845d07 100644
--- a/net/wireless/core.h
+++ b/net/wireless/core.h
@@ -531,6 +531,11 @@ void cfg80211_stop_p2p_device(struct cfg80211_registered_device *rdev,
 void cfg80211_stop_nan(struct cfg80211_registered_device *rdev,
 		       struct wireless_dev *wdev);
 
+struct cfg80211_internal_bss *
+cfg80211_bss_update(struct cfg80211_registered_device *rdev,
+		    struct cfg80211_internal_bss *tmp,
+		    bool signal_valid);
+
 #ifdef CONFIG_CFG80211_DEVELOPER_WARNINGS
 #define CFG80211_DEV_WARN_ON(cond)	WARN_ON(cond)
 #else
diff --git a/net/wireless/scan.c b/net/wireless/scan.c
index 287518c6caa4..0f5ae54c7644 100644
--- a/net/wireless/scan.c
+++ b/net/wireless/scan.c
@@ -1035,7 +1035,7 @@ struct cfg80211_non_tx_bss {
 };
 
 /* Returned bss is reference counted and must be cleaned up appropriately. */
-static struct cfg80211_internal_bss *
+struct cfg80211_internal_bss *
 cfg80211_bss_update(struct cfg80211_registered_device *rdev,
 		    struct cfg80211_internal_bss *tmp,
 		    bool signal_valid)
diff --git a/net/wireless/sme.c b/net/wireless/sme.c
index 7d34cb884840..6881d0b151b2 100644
--- a/net/wireless/sme.c
+++ b/net/wireless/sme.c
@@ -795,14 +795,17 @@ void cfg80211_connect_done(struct net_device *dev,
 	unsigned long flags;
 	u8 *next;
 
+	/* bss is not NULL, so even though bss might have expired, the driver
+	 * is still holding a reference to it.
+	 */
 	if (params->bss) {
-		/* Make sure the bss entry provided by the driver is valid. */
 		struct cfg80211_internal_bss *ibss = bss_from_pub(params->bss);
 
-		if (WARN_ON(list_empty(&ibss->list))) {
-			cfg80211_put_bss(wdev->wiphy, params->bss);
-			return;
-		}
+		/* Meanwhile if BSS is expired then add it back to the list as
+		 * we have just connected with it.
+		 */
+		if (list_empty(&ibss->list))
+			cfg80211_bss_update(rdev, ibss, ibss->pub.signal);
 	}
 
 	ev = kzalloc(sizeof(*ev) + (params->bssid ? ETH_ALEN : 0) +
-- 
2.17.1


^ permalink raw reply related

* [ANN] resend patches or respond to 0-day reports
From: Johannes Berg @ 2019-04-26  9:48 UTC (permalink / raw)
  To: linux-wireless

Hi all,

Just in case it wasn't clear already - if you get a 0-day report with
something that's trivially fixed (like missing documentation etc.)
please resend the patches immediately.

I'd rather have a resend than to comment and then wait later for both
changes, or to have to double-check that those things were later
addressed (or wait for 0-day again).

Thanks,
johannes


^ permalink raw reply

* Re: [PATCH v2 25/79] docs: convert docs to ReST and rename to *.rst
From: Mauro Carvalho Chehab @ 2019-04-26  9:46 UTC (permalink / raw)
  To: Mark Brown
  Cc: Linux Doc Mailing List, Mauro Carvalho Chehab, linux-kernel,
	Jonathan Corbet, Sebastian Reichel, Bjorn Helgaas,
	Rafael J. Wysocki, Viresh Kumar, Len Brown, Pavel Machek,
	Nishanth Menon, Stephen Boyd, Liam Girdwood, Mathieu Poirier,
	Suzuki K Poulose, Harry Wei, Alex Shi, Thomas Gleixner,
	Ingo Molnar, Borislav Petkov, H. Peter Anvin, x86, Jani Nikula,
	Joonas Lahtinen, Rodrigo Vivi, David Airlie, Daniel Vetter,
	Johannes Berg, David S. Miller, linux-pm, linux-pci,
	linux-arm-kernel, intel-gfx, dri-devel, linux-wireless, netdev
In-Reply-To: <20190425180758.GC23183@sirena.org.uk>

Hi Mark,

Em Thu, 25 Apr 2019 19:07:58 +0100
Mark Brown <broonie@kernel.org> escreveu:

> On Mon, Apr 22, 2019 at 10:27:14AM -0300, Mauro Carvalho Chehab wrote:
> > Convert the PM documents to ReST, in order to allow them to
> > build with Sphinx.  
> 
> This is massively CCed covering a large range of subsystems and is patch
> 25 of a 79 patch series so I've no context for what's going on here or
> why...  

There are two goals of this series:

1) to prepare for placing the new *.rst files under Documentation/ into an
   index file, being part of one of the books. Most of the stuff covered
   on this series either fit at the system admin guide or at the
   Kernel API documentation book;

2) to ensure that, if some edition on a file would cause warnings at
   Sphinx build, someone will notice and submit a followup patch.

You can see more details at patch 00/79:
	https://lore.kernel.org/lkml/20190422115110.26443b44@coco.lan/

In order to do that, this series has one patch per Documentation/*
sub-directory. This specific one is for the documents under
Documentation/power/ [1].

[1] btw, the title of this specific patch should be, instead:
	docs: power: convert docs to ReST and rename to *.rst

The series is long because I'm trying to cover a significant part
of the documentation files. In any case, except if an eventual
conflict might rise on some file, this patch is independent from
all other files, and should be safe to apply directly via the
subsystem git tree.

I'm working on a follow-up patch series that should be adding the
power/index.rst file into another index file - probably at
Documentation/index.rst[1]. As such patch will be adding a lot of other
index files, the best would be to merge it via the docs tree, in
order to avoid conflicts.


[1] such patch will be removing the ":orphan:" meta-tag from it
(that basically tells the build system to not produce warnings if
the file is not directly or indirectly referenced by the main
index file).

Thanks,
Mauro

^ permalink raw reply

* [PATCH V2 1/3] mac80211: allow turning TWT responder support on and off via netlink
From: John Crispin @ 2019-04-26  9:41 UTC (permalink / raw)
  To: Johannes Berg, Kalle Valo
  Cc: Srini Kode, Rajkumar Manoharan, linux-wireless, ath11k,
	John Crispin, Shashidhar Lakkavalli
In-Reply-To: <20190426094150.18078-1-john@phrozen.org>

Allow the userland daemon to en/disable TWT support for an AP.

Signed-off-by: Shashidhar Lakkavalli <slakkavalli@datto.com>
Signed-off-by: John Crispin <john@phrozen.org>
---
 include/net/cfg80211.h       | 2 ++
 include/net/mac80211.h       | 5 +++++
 include/uapi/linux/nl80211.h | 4 ++++
 net/mac80211/cfg.c           | 6 ++++++
 net/wireless/nl80211.c       | 6 ++++++
 5 files changed, 23 insertions(+)

diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index bb307a11ee63..8a20f5a42977 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -1511,6 +1511,7 @@ struct mpath_info {
  * 	(u16 = opmode, -1 = do not change)
  * @p2p_ctwindow: P2P CT Window (-1 = no change)
  * @p2p_opp_ps: P2P opportunistic PS (-1 = no change)
+ * @twt_responder: HE Target Wait Time support.
  */
 struct bss_parameters {
 	int use_cts_prot;
@@ -1521,6 +1522,7 @@ struct bss_parameters {
 	int ap_isolate;
 	int ht_opmode;
 	s8 p2p_ctwindow, p2p_opp_ps;
+	int twt_responder;
 };
 
 /**
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index ac2ed8ec662b..87a6e149abda 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -317,6 +317,7 @@ struct ieee80211_vif_chanctx_switch {
  * @BSS_CHANGED_MCAST_RATE: Multicast Rate setting changed for this interface
  * @BSS_CHANGED_FTM_RESPONDER: fime timing reasurement request responder
  *	functionality changed for this BSS (AP mode).
+ * @BSS_CHANGED_TWT: TWT enable status changed
  *
  */
 enum ieee80211_bss_change {
@@ -347,6 +348,7 @@ enum ieee80211_bss_change {
 	BSS_CHANGED_KEEP_ALIVE		= 1<<24,
 	BSS_CHANGED_MCAST_RATE		= 1<<25,
 	BSS_CHANGED_FTM_RESPONDER	= 1<<26,
+	BSS_CHANGED_TWT			= 1<<27,
 
 	/* when adding here, make sure to change ieee80211_reconfig */
 };
@@ -504,6 +506,8 @@ struct ieee80211_ftm_responder_params {
  * @he_support: does this BSS support HE
  * @twt_requester: does this BSS support TWT requester (relevant for managed
  *	mode only, set if the AP advertises TWT responder role)
+ * @twt_responder: does this BSS support TWT responder (relevant for AP
+ *	mode only, set if the AP advertises TWT responder role)
  * @assoc: association status
  * @ibss_joined: indicates whether this station is part of an IBSS
  *	or not
@@ -611,6 +615,7 @@ struct ieee80211_bss_conf {
 	u16 frame_time_rts_th;
 	bool he_support;
 	bool twt_requester;
+	bool twt_responder;
 	/* association related data */
 	bool assoc, ibss_joined;
 	bool ibss_creator;
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index dd4f86ee286e..ba1f69751a4a 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -2308,6 +2308,8 @@ enum nl80211_commands {
  * @NL80211_ATTR_AIRTIME_WEIGHT: Station's weight when scheduled by the airtime
  *	scheduler.
  *
+ * @NL80211_ATTR_TWT_RESPONDER: Enable target wait time responder support.
+ *
  * @NUM_NL80211_ATTR: total number of nl80211_attrs available
  * @NL80211_ATTR_MAX: highest attribute number currently defined
  * @__NL80211_ATTR_AFTER_LAST: internal use
@@ -2759,6 +2761,8 @@ enum nl80211_attrs {
 
 	NL80211_ATTR_AIRTIME_WEIGHT,
 
+	NL80211_ATTR_TWT_RESPONDER,
+
 	/* add attributes here, update the policy in nl80211.c */
 
 	__NL80211_ATTR_AFTER_LAST,
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 09dd1c2860fc..a66600bf9cef 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -2176,6 +2176,12 @@ static int ieee80211_change_bss(struct wiphy *wiphy,
 		changed |= BSS_CHANGED_P2P_PS;
 	}
 
+	if (params->twt_responder >= 0) {
+		sdata->vif.bss_conf.twt_responder =
+			params->twt_responder;
+		changed |= BSS_CHANGED_TWT;
+	}
+
 	ieee80211_bss_info_change_notify(sdata, changed);
 
 	return 0;
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 25a9e3b5c154..afd04a98a601 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -541,6 +541,7 @@ const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
 	[NL80211_ATTR_PEER_MEASUREMENTS] =
 		NLA_POLICY_NESTED(nl80211_pmsr_attr_policy),
 	[NL80211_ATTR_AIRTIME_WEIGHT] = NLA_POLICY_MIN(NLA_U16, 1),
+	[NL80211_ATTR_BSS_SHORT_PREAMBLE] = NLA_POLICY_RANGE(NLA_U8, 0, 1),
 };
 
 /* policy for the key attributes */
@@ -6105,6 +6106,7 @@ static int nl80211_set_bss(struct sk_buff *skb, struct genl_info *info)
 	params.ht_opmode = -1;
 	params.p2p_ctwindow = -1;
 	params.p2p_opp_ps = -1;
+	params.twt_responder = -1;
 
 	if (info->attrs[NL80211_ATTR_BSS_CTS_PROT])
 		params.use_cts_prot =
@@ -6149,6 +6151,10 @@ static int nl80211_set_bss(struct sk_buff *skb, struct genl_info *info)
 			return -EINVAL;
 	}
 
+	if (info->attrs[NL80211_ATTR_TWT_RESPONDER])
+		params.twt_responder =
+		    nla_get_u8(info->attrs[NL80211_ATTR_TWT_RESPONDER]);
+
 	if (!rdev->ops->change_bss)
 		return -EOPNOTSUPP;
 
-- 
2.11.0


^ permalink raw reply related

* [PATCH V2 3/3] ath11k: add TWT support
From: John Crispin @ 2019-04-26  9:41 UTC (permalink / raw)
  To: Johannes Berg, Kalle Valo
  Cc: Srini Kode, Rajkumar Manoharan, linux-wireless, ath11k,
	John Crispin, Shashidhar Lakkavalli
In-Reply-To: <20190426094150.18078-1-john@phrozen.org>

Add target wait time wmi calls to the driver. En/disable the support
from when the bss_config changes. We ignore the cmd completion events.

Signed-off-by: Shashidhar Lakkavalli <slakkavalli@datto.com>
Signed-off-by: John Crispin <john@phrozen.org>
---
 drivers/net/wireless/ath/ath11k/mac.c |  7 +++
 drivers/net/wireless/ath/ath11k/wmi.c | 91 +++++++++++++++++++++++++++++++++++
 drivers/net/wireless/ath/ath11k/wmi.h | 71 +++++++++++++++++++++++++++
 3 files changed, 169 insertions(+)

diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c
index 8bb4ff82fb6f..a38c101e0140 100644
--- a/drivers/net/wireless/ath/ath11k/mac.c
+++ b/drivers/net/wireless/ath/ath11k/mac.c
@@ -1938,6 +1938,13 @@ static void ath11k_bss_info_changed(struct ieee80211_hw *hw,
 		ath11k_mac_txpower_recalc(ar);
 	}
 
+	if (changed & BSS_CHANGED_TWT) {
+		if (info->twt_responder || info->twt_responder)
+			ath11k_wmi_send_twt_enable_cmd(ar, ar->pdev_idx);
+		else
+			ath11k_wmi_send_twt_disable_cmd(ar, ar->pdev_idx);
+	}
+
 	mutex_unlock(&ar->conf_mutex);
 }
 
diff --git a/drivers/net/wireless/ath/ath11k/wmi.c b/drivers/net/wireless/ath/ath11k/wmi.c
index 7edaed5c97df..52d6fb200d07 100644
--- a/drivers/net/wireless/ath/ath11k/wmi.c
+++ b/drivers/net/wireless/ath/ath11k/wmi.c
@@ -1797,6 +1797,10 @@ ath11k_wmi_copy_peer_flags(struct wmi_peer_assoc_complete_cmd *cmd,
 			cmd->peer_flags |= WMI_PEER_VHT;
 		if (param->he_flag)
 			cmd->peer_flags |= WMI_PEER_HE;
+		if (param->twt_requester)
+			cmd->peer_flags |= WMI_PEER_TWT_REQ;
+		if (param->twt_responder)
+			cmd->peer_flags |= WMI_PEER_TWT_RESP;
 	}
 
 	/* Suppress authorization for all AUTH modes that need 4-way handshake
@@ -2787,6 +2791,86 @@ int ath11k_wmi_pdev_pktlog_disable(struct ath11k *ar)
 	return ret;
 }
 
+int
+ath11k_wmi_send_twt_enable_cmd(struct ath11k *ar, u32 pdev_id)
+{
+	struct ath11k_pdev_wmi *wmi = ar->wmi;
+	struct ath11k_base *ab = wmi->wmi_sc->sc;
+	struct wmi_twt_enable_params_cmd *cmd;
+	struct sk_buff *skb;
+	int ret, len;
+
+	len = sizeof(*cmd);
+
+	skb = ath11k_wmi_alloc_skb(wmi->wmi_sc, len);
+	if (!skb)
+		return -ENOMEM;
+
+	cmd = (void *)skb->data;
+	cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_TWT_ENABLE_CMD) |
+			  FIELD_PREP(WMI_TLV_LEN, len - TLV_HDR_SIZE);
+	cmd->pdev_id = pdev_id;
+	cmd->sta_cong_timer_ms = ATH11K_TWT_DEF_STA_CONG_TIMER_MS;
+	cmd->default_slot_size = ATH11K_TWT_DEF_DEFAULT_SLOT_SIZE;
+	cmd->congestion_thresh_setup = ATH11K_TWT_DEF_CONGESTION_THRESH_SETUP;
+	cmd->congestion_thresh_teardown =
+		ATH11K_TWT_DEF_CONGESTION_THRESH_TEARDOWN;
+	cmd->congestion_thresh_critical =
+		ATH11K_TWT_DEF_CONGESTION_THRESH_CRITICAL;
+	cmd->interference_thresh_teardown =
+		ATH11K_TWT_DEF_INTERFERENCE_THRESH_TEARDOWN;
+	cmd->interference_thresh_setup =
+		ATH11K_TWT_DEF_INTERFERENCE_THRESH_SETUP;
+	cmd->min_no_sta_setup = ATH11K_TWT_DEF_MIN_NO_STA_SETUP;
+	cmd->min_no_sta_teardown = ATH11K_TWT_DEF_MIN_NO_STA_TEARDOWN;
+	cmd->no_of_bcast_mcast_slots = ATH11K_TWT_DEF_NO_OF_BCAST_MCAST_SLOTS;
+	cmd->min_no_twt_slots = ATH11K_TWT_DEF_MIN_NO_TWT_SLOTS;
+	cmd->max_no_sta_twt = ATH11K_TWT_DEF_MAX_NO_STA_TWT;
+	cmd->mode_check_interval = ATH11K_TWT_DEF_MODE_CHECK_INTERVAL;
+	cmd->add_sta_slot_interval = ATH11K_TWT_DEF_ADD_STA_SLOT_INTERVAL;
+	cmd->remove_sta_slot_interval =
+		ATH11K_TWT_DEF_REMOVE_STA_SLOT_INTERVAL;
+	/* TODO add MBSSID support */
+	cmd->mbss_support = 0;
+
+	ret = ath11k_wmi_cmd_send(wmi, skb,
+				  WMI_TWT_ENABLE_CMDID);
+	if (ret) {
+		ath11k_warn(ab, "Failed to send WMI_TWT_ENABLE_CMDID");
+		dev_kfree_skb(skb);
+	}
+	return ret;
+}
+
+int
+ath11k_wmi_send_twt_disable_cmd(struct ath11k *ar, u32 pdev_id)
+{
+	struct ath11k_pdev_wmi *wmi = ar->wmi;
+	struct ath11k_base *ab = wmi->wmi_sc->sc;
+	struct wmi_twt_disable_params_cmd *cmd;
+	struct sk_buff *skb;
+	int ret, len;
+
+	len = sizeof(*cmd);
+
+	skb = ath11k_wmi_alloc_skb(wmi->wmi_sc, len);
+	if (!skb)
+		return -ENOMEM;
+
+	cmd = (void *)skb->data;
+	cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_TWT_DISABLE_CMD) |
+			  FIELD_PREP(WMI_TLV_LEN, len - TLV_HDR_SIZE);
+	cmd->pdev_id = pdev_id;
+
+	ret = ath11k_wmi_cmd_send(wmi, skb,
+				  WMI_TWT_DISABLE_CMDID);
+	if (ret) {
+		ath11k_warn(ab, "Failed to send WMI_TWT_DIeABLE_CMDID");
+		dev_kfree_skb(skb);
+	}
+	return ret;
+}
+
 static inline void ath11k_fill_band_to_mac_param(struct ath11k_base  *soc,
 				struct wmi_host_pdev_band_to_mac *band_to_mac)
 {
@@ -2877,6 +2961,9 @@ ath11k_wmi_copy_resource_config(struct wmi_resource_config *wmi_cfg,
 	wmi_cfg->use_pdev_id = tg_cfg->use_pdev_id;
 	wmi_cfg->flag1 = tg_cfg->atf_config;
 	wmi_cfg->peer_map_unmap_v2_support = tg_cfg->peer_map_unmap_v2_support;
+	wmi_cfg->sched_params = tg_cfg->sched_params;
+	wmi_cfg->twt_ap_pdev_count = tg_cfg->twt_ap_pdev_count;
+	wmi_cfg->twt_ap_sta_count = tg_cfg->twt_ap_sta_count;
 }
 
 static int ath11k_init_cmd_send(struct ath11k_pdev_wmi *wmi,
@@ -3068,6 +3155,8 @@ int ath11k_wmi_cmd_init(struct ath11k_base *sc)
 	config.beacon_tx_offload_max_vdev = sc->num_radios * TARGET_MAX_BCN_OFFLD;
 	config.rx_batchmode = TARGET_RX_BATCHMODE;
 	config.peer_map_unmap_v2_support = 1;
+	config.twt_ap_pdev_count = 2;
+	config.twt_ap_sta_count = 1000;
 
 	memcpy(&wmi_sc->wlan_resource_config, &config, sizeof(config));
 
@@ -5859,6 +5948,8 @@ static void ath11k_wmi_tlv_op_rx(struct ath11k_base *ab, struct sk_buff *skb)
 	/* add Unsupported events here */
 	case WMI_TBTTOFFSET_EXT_UPDATE_EVENTID:
 	case WMI_VDEV_DELETE_RESP_EVENTID:
+	case WMI_TWT_ENABLE_EVENTID:
+	case WMI_TWT_DISABLE_EVENTID:
 		ath11k_dbg(ab, ATH11K_DBG_WMI,
 			   "ignoring unsupported event 0x%x\n", id);
 		break;
diff --git a/drivers/net/wireless/ath/ath11k/wmi.h b/drivers/net/wireless/ath/ath11k/wmi.h
index 071537850c68..99f69fc3cf53 100644
--- a/drivers/net/wireless/ath/ath11k/wmi.h
+++ b/drivers/net/wireless/ath/ath11k/wmi.h
@@ -169,6 +169,10 @@ enum wmi_cmd_group {
 	WMI_GRP_MONITOR,        /* 0x39 */
 	WMI_GRP_REGULATORY,     /* 0x3a */
 	WMI_GRP_HW_DATA_FILTER, /* 0x3b */
+	WMI_GRP_WLM,            /* 0x3c */
+	WMI_GRP_11K_OFFLOAD,    /* 0x3d */
+	WMI_GRP_TWT,            /* 0x3e */
+
 };
 
 #define WMI_CMD_GRP(grp_id) (((grp_id) << 12) | 0x1)
@@ -531,6 +535,12 @@ enum wmi_tlv_cmd_id {
 	WMI_NDP_RESPONDER_REQ_CMDID,
 	WMI_NDP_END_REQ_CMDID,
 	WMI_HW_DATA_FILTER_CMDID = WMI_TLV_CMD(WMI_GRP_HW_DATA_FILTER),
+	WMI_TWT_ENABLE_CMDID = WMI_TLV_CMD(WMI_GRP_TWT),
+	WMI_TWT_DISABLE_CMDID,
+	WMI_TWT_ADD_DIALOG_CMDID,
+	WMI_TWT_DEL_DIALOG_CMDID,
+	WMI_TWT_PAUSE_DIALOG_CMDID,
+	WMI_TWT_RESUME_DIALOG_CMDID,
 };
 
 enum wmi_tlv_event_id {
@@ -713,6 +723,13 @@ enum wmi_tlv_event_id {
 	WMI_NDP_INDICATION_EVENTID,
 	WMI_NDP_CONFIRM_EVENTID,
 	WMI_NDP_END_INDICATION_EVENTID,
+
+	WMI_TWT_ENABLE_EVENTID = WMI_TLV_CMD(WMI_GRP_TWT),
+	WMI_TWT_DISABLE_EVENTID,
+	WMI_TWT_ADD_DIALOG_EVENTID,
+	WMI_TWT_DEL_DIALOG_EVENTID,
+	WMI_TWT_PAUSE_DIALOG_EVENTID,
+	WMI_TWT_RESUME_DIALOG_EVENTID,
 };
 
 enum wmi_tlv_pdev_param {
@@ -2736,6 +2753,9 @@ struct wmi_resource_config {
 	u32 max_num_dbs_scan_duty_cycle;
 	u32 max_num_group_keys;
 	u32 peer_map_unmap_v2_support;
+	u32 sched_params;
+	u32 twt_ap_pdev_count;
+	u32 twt_ap_sta_count;
 } __packed;
 
 struct wmi_service_ready_event {
@@ -3907,6 +3927,8 @@ struct peer_assoc_params {
 	u32 peer_he_mcs_count;
 	u32 peer_he_rx_mcs_set[WMI_HOST_MAX_HE_RATE_SET];
 	u32 peer_he_tx_mcs_set[WMI_HOST_MAX_HE_RATE_SET];
+	bool twt_responder;
+	bool twt_requester;
 	struct ath11k_ppe_threshold peer_ppet;
 };
 
@@ -4130,6 +4152,8 @@ struct wmi_pktlog_disable_cmd {
 #define WMI_PEER_DYN_MIMOPS	0x00020000
 #define WMI_PEER_STATIC_MIMOPS	0x00040000
 #define WMI_PEER_SPATIAL_MUX	0x00200000
+#define WMI_PEER_TWT_REQ	0x00400000
+#define WMI_PEER_TWT_RESP	0x00800000
 #define WMI_PEER_VHT		0x02000000
 #define WMI_PEER_80MHZ		0x04000000
 #define WMI_PEER_PMF		0x08000000
@@ -5005,6 +5029,48 @@ struct wmi_wmm_params_all_arg {
 	struct wmi_wmm_params_arg ac_vo;
 };
 
+#define ATH11K_TWT_DEF_STA_CONG_TIMER_MS		5000
+#define ATH11K_TWT_DEF_DEFAULT_SLOT_SIZE		10
+#define ATH11K_TWT_DEF_CONGESTION_THRESH_SETUP		50
+#define ATH11K_TWT_DEF_CONGESTION_THRESH_TEARDOWN	20
+#define ATH11K_TWT_DEF_CONGESTION_THRESH_CRITICAL	100
+#define ATH11K_TWT_DEF_INTERFERENCE_THRESH_TEARDOWN	80
+#define ATH11K_TWT_DEF_INTERFERENCE_THRESH_SETUP	50
+#define ATH11K_TWT_DEF_MIN_NO_STA_SETUP			10
+#define ATH11K_TWT_DEF_MIN_NO_STA_TEARDOWN		2
+#define ATH11K_TWT_DEF_NO_OF_BCAST_MCAST_SLOTS		2
+#define ATH11K_TWT_DEF_MIN_NO_TWT_SLOTS			2
+#define ATH11K_TWT_DEF_MAX_NO_STA_TWT			500
+#define ATH11K_TWT_DEF_MODE_CHECK_INTERVAL		10000
+#define ATH11K_TWT_DEF_ADD_STA_SLOT_INTERVAL		1000
+#define ATH11K_TWT_DEF_REMOVE_STA_SLOT_INTERVAL		5000
+
+struct wmi_twt_enable_params_cmd {
+	u32 tlv_header;
+	u32 pdev_id;
+	u32 sta_cong_timer_ms;
+	u32 mbss_support;
+	u32 default_slot_size;
+	u32 congestion_thresh_setup;
+	u32 congestion_thresh_teardown;
+	u32 congestion_thresh_critical;
+	u32 interference_thresh_teardown;
+	u32 interference_thresh_setup;
+	u32 min_no_sta_setup;
+	u32 min_no_sta_teardown;
+	u32 no_of_bcast_mcast_slots;
+	u32 min_no_twt_slots;
+	u32 max_no_sta_twt;
+	u32 mode_check_interval;
+	u32 add_sta_slot_interval;
+	u32 remove_sta_slot_interval;
+};
+
+struct wmi_twt_disable_params_cmd {
+	u32 tlv_header;
+	u32 pdev_id;
+};
+
 struct target_resource_config {
 	u32 num_vdevs;
 	u32 num_peers;
@@ -5065,6 +5131,9 @@ struct target_resource_config {
 	u32 max_bssid_rx_filters;
 	u32 use_pdev_id;
 	u32 peer_map_unmap_v2_support;
+	u32 sched_params;
+	u32 twt_ap_pdev_count;
+	u32 twt_ap_sta_count;
 };
 
 #define WMI_MAX_MEM_REQS 32
@@ -5190,4 +5259,6 @@ size_t ath11k_wmi_fw_stats_num_vdevs(struct list_head *head);
 void ath11k_wmi_fw_stats_fill(struct ath11k *ar,
 			      struct ath11k_fw_stats *fw_stats, u32 stats_id,
 			      char *buf);
+int ath11k_wmi_send_twt_enable_cmd(struct ath11k *ar, u32 pdev_id);
+int ath11k_wmi_send_twt_disable_cmd(struct ath11k *ar, u32 pdev_id);
 #endif
-- 
2.11.0


^ permalink raw reply related

* [PATCH V2 2/3] mac80211: dynamically turn TWT requester support on and off
From: John Crispin @ 2019-04-26  9:41 UTC (permalink / raw)
  To: Johannes Berg, Kalle Valo
  Cc: Srini Kode, Rajkumar Manoharan, linux-wireless, ath11k,
	John Crispin, Shashidhar Lakkavalli
In-Reply-To: <20190426094150.18078-1-john@phrozen.org>

Turn TWT on/off for STA interfaces when they associate and/or receive a
beacon where the twt_responder bit has changed.

Signed-off-by: Shashidhar Lakkavalli <slakkavalli@datto.com>
Signed-off-by: John Crispin <john@phrozen.org>
---
 net/mac80211/mlme.c | 20 ++++++++++++++++++--
 1 file changed, 18 insertions(+), 2 deletions(-)

diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 2dbcf5d5512e..f3563670ed58 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -3151,6 +3151,21 @@ static bool ieee80211_twt_req_supported(const struct sta_info *sta,
 		IEEE80211_HE_MAC_CAP0_TWT_RES;
 }
 
+static int ieee80211_recalc_twt_req(struct ieee80211_sub_if_data *sdata,
+				    struct sta_info *sta,
+				    struct ieee802_11_elems *elems)
+{
+	bool twt_req;
+
+	twt_req = ieee80211_twt_req_supported(sta, elems);
+
+	if (sdata->vif.bss_conf.twt_requester != twt_req) {
+		sdata->vif.bss_conf.twt_requester = twt_req;
+		return BSS_CHANGED_TWT;
+	}
+	return 0;
+}
+
 static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata,
 				    struct cfg80211_bss *cbss,
 				    struct ieee80211_mgmt *mgmt, size_t len)
@@ -3333,8 +3348,7 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata,
 						  sta);
 
 		bss_conf->he_support = sta->sta.he_cap.has_he;
-		bss_conf->twt_requester =
-			ieee80211_twt_req_supported(sta, &elems);
+		changed |= ieee80211_recalc_twt_req(sdata, sta, &elems);
 	} else {
 		bss_conf->he_support = false;
 		bss_conf->twt_requester = false;
@@ -3994,6 +4008,8 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
 	mutex_lock(&local->sta_mtx);
 	sta = sta_info_get(sdata, bssid);
 
+	changed |= ieee80211_recalc_twt_req(sdata, sta, &elems);
+
 	if (ieee80211_config_bw(sdata, sta,
 				elems.ht_cap_elem, elems.ht_operation,
 				elems.vht_operation, elems.he_operation,
-- 
2.11.0


^ permalink raw reply related

* [PATCH V2 0/3] mac80211: notify the driver when it should enable TWT
From: John Crispin @ 2019-04-26  9:41 UTC (permalink / raw)
  To: Johannes Berg, Kalle Valo
  Cc: Srini Kode, Rajkumar Manoharan, linux-wireless, ath11k,
	John Crispin

The ath11k FW has dedicated calls for setting the TWT state. Trigger these
via the BSS config changes.

In a later step we need to also add calls for manually starting TWT dialogs.

Changes in V2
* add NLA_POLICY_RANGE for NL80211_ATTR_TWT_RESPONDER

John Crispin (3):
  mac80211: allow turning TWT responder support on and off via netlink
  mac80211: dynamically turn TWT requester support on and off
  ath11k: add TWT support

 drivers/net/wireless/ath/ath11k/mac.c |  7 +++
 drivers/net/wireless/ath/ath11k/wmi.c | 91 +++++++++++++++++++++++++++++++++++
 drivers/net/wireless/ath/ath11k/wmi.h | 71 +++++++++++++++++++++++++++
 include/net/cfg80211.h                |  2 +
 include/net/mac80211.h                |  5 ++
 include/uapi/linux/nl80211.h          |  4 ++
 net/mac80211/cfg.c                    |  6 +++
 net/mac80211/mlme.c                   | 20 +++++++-
 net/wireless/nl80211.c                |  6 +++
 9 files changed, 210 insertions(+), 2 deletions(-)

-- 
2.11.0


^ permalink raw reply

* Re: [PATCHv5 5/9] nl80211: Add netlink attribute to configure TID specific tx rate
From: Johannes Berg @ 2019-04-26  9:37 UTC (permalink / raw)
  To: Tamizh chelvam, ath10k; +Cc: linux-wireless
In-Reply-To: <1553592550-15282-6-git-send-email-tamizhr@codeaurora.org>


> @@ -13354,6 +13367,42 @@ static int parse_tid_conf(struct cfg80211_registered_device *rdev,
>  			nla_get_u8(attrs[NL80211_ATTR_TID_CONFIG_RTSCTS_CTRL]);
>  	}
>  
> +	if (attrs[NL80211_ATTR_TID_CONFIG_TX_RATES_TYPE]) {
> +		int idx;
> +		enum nl80211_attrs attr;
> +
> +		if (!wiphy_ext_feature_isset(&rdev->wiphy,
> +				NL80211_EXT_FEATURE_PER_TID_TX_BITRATE_MASK))
> +			return -EOPNOTSUPP;
> +
> +		if (peer &&
> +		    !wiphy_ext_feature_isset(&rdev->wiphy,
> +				NL80211_EXT_FEATURE_PER_STA_TX_BITRATE_MASK))
> +			return -EOPNOTSUPP;
> +
> +		idx = NL80211_ATTR_TID_CONFIG_TX_RATES_TYPE;
> +		tid_conf->txrate_type = nla_get_u8(attrs[idx]);
> +
> +		tid_conf->tid_conf_mask |= IEEE80211_TID_CONF_TX_BITRATE;
> +		if (tid_conf->txrate_type != NL80211_TX_RATE_AUTOMATIC) {
> +			tid_conf->mask =
> +				kzalloc(sizeof(struct cfg80211_bitrate_mask),
> +					GFP_KERNEL);

You leak this

> +			if (!tid_conf->mask)
> +				return -ENOMEM;
> +
> +			attr = NL80211_ATTR_TID_CONFIG_TX_RATES;
> +			ret = nl80211_parse_tx_bitrate_mask(attrs, rdev, attr,
> +							    tid_conf->mask);
> +			if (ret) {
> +				kfree(tid_conf->mask);
> +				return ret;
> +			}
> +		} else {
> +			tid_conf->mask = NULL;
> +		}
> +	}
> +
>  	return 0;
>  }
>  
> @@ -13407,7 +13456,7 @@ static int nl80211_set_tid_config(struct sk_buff *skb,
>  		}
>  
>  		ret = parse_tid_conf(rdev, attrs, &tid_conf->tid_conf[conf_idx],
> -				     tid_conf->peer);
> +				     info, tid_conf->peer);
>  		if (ret)
>  			goto bad_tid_conf;

Practically everywhere, but particularly in the bad case in the next
loop iteration etc?

johannes


^ permalink raw reply

* Re: [PATCHv5 2/9] nl80211: Add new netlink attribute for TID speicific retry count
From: Johannes Berg @ 2019-04-26  9:32 UTC (permalink / raw)
  To: Tamizh chelvam, ath10k; +Cc: linux-wireless
In-Reply-To: <1553592550-15282-3-git-send-email-tamizhr@codeaurora.org>

On Tue, 2019-03-26 at 14:59 +0530, Tamizh chelvam wrote:
> 
> @@ -13288,6 +13291,37 @@ static int parse_tid_conf(struct cfg80211_registered_device *rdev,
>  			nla_get_u8(attrs[NL80211_ATTR_TID_CONFIG_NOACK]);
>  	}
>  
> +	if (nla_get_flag(attrs[NL80211_ATTR_TID_CONFIG_RETRY])) {
> +		if (!wiphy_ext_feature_isset(&rdev->wiphy,
> +				NL80211_EXT_FEATURE_PER_TID_RETRY_CONFIG))
> +			return -ENOTSUPP;
> +
> +		if (peer && !wiphy_ext_feature_isset(&rdev->wiphy,
> +				NL80211_EXT_FEATURE_PER_STA_RETRY_CONFIG))
> +			return -ENOTSUPP;
> +
> +		tid_conf->tid_conf_mask |= IEEE80211_TID_CONF_RETRY;
> +		if (attrs[NL80211_ATTR_TID_CONFIG_RETRY_SHORT]) {
> +			tid_conf->retry_short =
> +			nla_get_u8(attrs[NL80211_ATTR_TID_CONFIG_RETRY_SHORT]);
> +			if (tid_conf->retry_short >
> +					rdev->wiphy.max_data_retry_count)
> +				return -EINVAL;
> 
Forgot to comment on that before (perhaps also in the first patch), but
having extended error messages for this would be very useful.

johannes


^ permalink raw reply

* Re: [PATCHv5 2/9] nl80211: Add new netlink attribute for TID speicific retry count
From: Johannes Berg @ 2019-04-26  9:31 UTC (permalink / raw)
  To: Tamizh chelvam, ath10k; +Cc: linux-wireless
In-Reply-To: <1553592550-15282-3-git-send-email-tamizhr@codeaurora.org>

On Tue, 2019-03-26 at 14:59 +0530, Tamizh chelvam wrote:
> 
> +	[NL80211_ATTR_TID_CONFIG_RETRY] = { .type = NLA_FLAG },
> +	[NL80211_ATTR_TID_CONFIG_RETRY_SHORT] = NLA_POLICY_MIN(NLA_U8, 1),
> +	[NL80211_ATTR_TID_CONFIG_RETRY_LONG] = NLA_POLICY_MIN(NLA_U8, 1),
> 
I guess it's a question of semantics, but for *TX retries* 0 should be
valid. Unless you're setting *TX attempts* (including the first one) but
that would be wrong...

So I guess you should clarify that in the documentation and really allow
0, which is sort of equivalent to no-ack but not really because it does
request an ACK.

johannes


^ permalink raw reply

* Re: [PATCHv5 1/9] nl80211: New netlink command for TID specific configuration
From: Johannes Berg @ 2019-04-26  9:28 UTC (permalink / raw)
  To: Tamizh chelvam, ath10k; +Cc: linux-wireless
In-Reply-To: <1553592550-15282-2-git-send-email-tamizhr@codeaurora.org>

Hi,

Sorry, I apologize for taking so long to review this (again).

> +enum ieee80211_tid_conf_mask {
> +	IEEE80211_TID_CONF_NOACK	= BIT(0),
> +};
> +
> +/**
> + * struct ieee80211_tid_cfg - TID specific configuration
> + * @tid: TID number
> + * @tid_conf_mask: bitmap indicating which parameter changed
> + *	see %enum ieee80211_tid_conf_mask
> + * @noack: noack configuration value for the TID
> + */
> +struct ieee80211_tid_cfg {
> +	u8 tid;
> +	enum ieee80211_tid_conf_mask tid_conf_mask;

This shouldn't use the enum type if it's a bitmap. Doing the enum type
above is only useful for documentation, which you should add there.

> + * @set_tid_config: TID specific configuration. Apply this configuration for
> + *	all the connected stations in the BSS if peer is NULL. Otherwise

%NULL renders better, IIRC

> + * @NL80211_ATTR_TID_CONFIG: TID specific configuration in a
> + *	nested attribute with %NL80211_ATTR_TID_* sub-attributes.

Please use NL80211_TID_ATTR_* to disambiguate the namespaces

> +enum nl80211_tid_config {
> +	NL80211_TID_CONFIG_DEFAULT,
> +	NL80211_TID_CONFIG_ENABLE,
> +	NL80211_TID_CONFIG_DISABLE,
> +};


That could do with some documentation

> +
> +/* enum nl80211_attr_tid_config - TID specific configuration.
> + * @NL80211_ATTR_TID_CONFIG_TID: a TID value (u8 attribute).

See above - TID_ATTR_* is better.

> + * @NL80211_ATTR_TID_CONFIG_NOACK: Configure ack policy for the TID.
> + *	specified in %NL80211_ATTR_TID_CONFIG_TID. see %enum nl80211_tid_config.
> + *	Its type is u8, if the peer MAC address is passed in %NL80211_ATTR_MAC,
> + *	then the noack configuration is applied to the data frame for the tid
> + *	to that connected station. This configuration is valid only for STA's
> + *      current connection. i.e. the configuration will be reset to default when
> + *      the station connects back after disconnection/roaming.
> + *      when user-space does not include %NL80211_ATTR_MAC, then this

please use tabs consistently

> + *	configuration should be treated as per-netdev configuration.
> + *	This configuration will be cleared when the interface goes down and on
> + *	the disconnection from a BSS. 

"goes down" is redundant then? Or do you mean that's for the AP case?

> +static const struct nla_policy
> +nl80211_attr_tid_config_policy[NL80211_ATTR_TID_CONFIG_MAX + 1] = {
> +	[NL80211_ATTR_TID_CONFIG_TID] = { .type = NLA_U8 },

Shouldn't this use NLA_POLICY_RANGE() or MAX()?

> +	[NL80211_ATTR_TID_CONFIG_NOACK] =
> +			NLA_POLICY_MAX(NLA_U8, NL80211_TID_CONFIG_DISABLE),
> +};
> +
>  const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
>  	[NL80211_ATTR_WIPHY] = { .type = NLA_U32 },
>  	[NL80211_ATTR_WIPHY_NAME] = { .type = NLA_NUL_STRING,
> @@ -541,6 +548,8 @@ static int validate_ie_attr(const struct nlattr *attr,
>  	[NL80211_ATTR_PEER_MEASUREMENTS] =
>  		NLA_POLICY_NESTED(nl80211_pmsr_attr_policy),
>  	[NL80211_ATTR_AIRTIME_WEIGHT] = NLA_POLICY_MIN(NLA_U16, 1),
> +	[NL80211_ATTR_TID_CONFIG] =
> +			NLA_POLICY_NESTED(nl80211_attr_tid_config_policy),
>  };

Great! :-)

>  /* policy for the key attributes */
> @@ -13259,6 +13268,93 @@ static int nl80211_get_ftm_responder_stats(struct sk_buff *skb,
>  	return -ENOBUFS;
>  }
>  
> +static int parse_tid_conf(struct cfg80211_registered_device *rdev,
> +			  struct nlattr *attrs[],
> +			  struct ieee80211_tid_cfg *tid_conf,
> +			  const u8 *peer)
> +{
> +	tid_conf->tid = nla_get_u8(attrs[NL80211_ATTR_TID_CONFIG_TID]);

You need to check that this is even present!

> +	size_of_conf = sizeof(struct ieee80211_tid_config) +
> +		num_conf * sizeof(struct ieee80211_tid_cfg);

use struct_size()

> +	tid_conf = kzalloc(size_of_conf, GFP_KERNEL);
> +	if (!tid_conf)
> +		return -ENOMEM;
> +
> +	tid_conf->n_tid_conf = num_conf;
> +
> +	if (info->attrs[NL80211_ATTR_MAC])
> +		tid_conf->peer = nla_data(info->attrs[NL80211_ATTR_MAC]);
> +	else
> +		tid_conf->peer = NULL;

No need to initialize to NULL after kzalloc()

> +	nla_for_each_nested(tid, info->attrs[NL80211_ATTR_TID_CONFIG],
> +			    rem_conf) {
> +		ret = nla_parse_nested(attrs, NL80211_ATTR_TID_CONFIG_MAX, tid,
> +				       NULL, NULL);
> +
> +		if (ret)
> +			goto bad_tid_conf;
> +
> +		if (!attrs[NL80211_ATTR_TID_CONFIG_TID]) {
> +			ret = -EINVAL;
> +			goto bad_tid_conf;
> +		}

Oh, you check here. Perhaps easier to do inside though?

> +	{
> +		.cmd = NL80211_CMD_SET_TID_CONFIG,
> +		.doit = nl80211_set_tid_config,
> +		.policy = nl80211_policy,

The .policy field no longer exists.

johannes


^ permalink raw reply

* pull-request: mac80211 2019-04-26
From: Johannes Berg @ 2019-04-26  9:07 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, linux-wireless

Hi Dave,

Just have a few more stragglers, looks like things have quieted down.

Please pull and let me know if there's any problem.

Thanks,
johannes



The following changes since commit c03fd0171ba6c8807ff5ba7c797896c84e18f3bc:

  Merge tag 'mac80211-for-davem-2019-04-09' of git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211 (2019-04-09 10:57:10 -0700)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211.git tags/mac80211-for-davem-2019-04-26

for you to fetch changes up to 517879147493a5e1df6b89a50f708f1133fcaddb:

  mac80211: don't attempt to rename ERR_PTR() debugfs dirs (2019-04-23 13:47:05 +0200)

----------------------------------------------------------------
 * fix use-after-free in mac80211 TXQs
 * fix RX STBC byte order
 * fix debugfs rename crashing due to ERR_PTR()
 * fix missing regulatory notification

----------------------------------------------------------------
Bhagavathi Perumal S (1):
      mac80211: Fix kernel panic due to use of txq after free

Johannes Berg (2):
      mac80211: fix RX STBC override byte order
      mac80211: don't attempt to rename ERR_PTR() debugfs dirs

Sriram R (1):
      cfg80211: Notify previous user request during self managed wiphy registration

 net/mac80211/debugfs_netdev.c | 2 +-
 net/mac80211/ht.c             | 5 +++--
 net/mac80211/iface.c          | 3 +++
 net/wireless/reg.c            | 5 ++---
 4 files changed, 9 insertions(+), 6 deletions(-)


^ permalink raw reply

* Re: [PATCH 1/3] mac80211: allow turning TWT responder support on and off via netlink
From: Johannes Berg @ 2019-04-26  8:49 UTC (permalink / raw)
  To: John Crispin, Kalle Valo
  Cc: Srini Kode, Rajkumar Manoharan, linux-wireless, ath11k,
	Shashidhar Lakkavalli
In-Reply-To: <20190426084244.28098-2-john@phrozen.org>

On Fri, 2019-04-26 at 10:42 +0200, John Crispin wrote:
> 
> +++ b/net/wireless/nl80211.c
> @@ -6105,6 +6105,7 @@ static int nl80211_set_bss(struct sk_buff *skb, struct genl_info *info)
>  	params.ht_opmode = -1;
>  	params.p2p_ctwindow = -1;
>  	params.p2p_opp_ps = -1;
> +	params.twt_responder = -1;
>  
>  	if (info->attrs[NL80211_ATTR_BSS_CTS_PROT])
>  		params.use_cts_prot =
> @@ -6149,6 +6150,10 @@ static int nl80211_set_bss(struct sk_buff *skb, struct genl_info *info)
>  			return -EINVAL;
>  	}
>  
> +	if (info->attrs[NL80211_ATTR_TWT_RESPONDER])
> +		params.twt_responder =
> +		    nla_get_u8(info->attrs[NL80211_ATTR_TWT_RESPONDER]);

You need an NLA_POLICY_RANGE() policy for that attribute.

johannes


^ permalink raw reply

* [PATCH 2/3] mac80211: dynamically turn TWT requester support on and off
From: John Crispin @ 2019-04-26  8:42 UTC (permalink / raw)
  To: Johannes Berg, Kalle Valo
  Cc: Srini Kode, Rajkumar Manoharan, linux-wireless, ath11k,
	John Crispin, Shashidhar Lakkavalli
In-Reply-To: <20190426084244.28098-1-john@phrozen.org>

Turn TWT for STA interfaces when they associate and/or receive a
beacon where the twt_responder bit has changed.

Signed-off-by: Shashidhar Lakkavalli <slakkavalli@datto.com>
Signed-off-by: John Crispin <john@phrozen.org>
---
 net/mac80211/mlme.c | 20 ++++++++++++++++++--
 1 file changed, 18 insertions(+), 2 deletions(-)

diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 2dbcf5d5512e..f3563670ed58 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -3151,6 +3151,21 @@ static bool ieee80211_twt_req_supported(const struct sta_info *sta,
 		IEEE80211_HE_MAC_CAP0_TWT_RES;
 }
 
+static int ieee80211_recalc_twt_req(struct ieee80211_sub_if_data *sdata,
+				    struct sta_info *sta,
+				    struct ieee802_11_elems *elems)
+{
+	bool twt_req;
+
+	twt_req = ieee80211_twt_req_supported(sta, elems);
+
+	if (sdata->vif.bss_conf.twt_requester != twt_req) {
+		sdata->vif.bss_conf.twt_requester = twt_req;
+		return BSS_CHANGED_TWT;
+	}
+	return 0;
+}
+
 static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata,
 				    struct cfg80211_bss *cbss,
 				    struct ieee80211_mgmt *mgmt, size_t len)
@@ -3333,8 +3348,7 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata,
 						  sta);
 
 		bss_conf->he_support = sta->sta.he_cap.has_he;
-		bss_conf->twt_requester =
-			ieee80211_twt_req_supported(sta, &elems);
+		changed |= ieee80211_recalc_twt_req(sdata, sta, &elems);
 	} else {
 		bss_conf->he_support = false;
 		bss_conf->twt_requester = false;
@@ -3994,6 +4008,8 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
 	mutex_lock(&local->sta_mtx);
 	sta = sta_info_get(sdata, bssid);
 
+	changed |= ieee80211_recalc_twt_req(sdata, sta, &elems);
+
 	if (ieee80211_config_bw(sdata, sta,
 				elems.ht_cap_elem, elems.ht_operation,
 				elems.vht_operation, elems.he_operation,
-- 
2.11.0


^ permalink raw reply related

* [PATCH 3/3] ath11k: add TWT support
From: John Crispin @ 2019-04-26  8:42 UTC (permalink / raw)
  To: Johannes Berg, Kalle Valo
  Cc: Srini Kode, Rajkumar Manoharan, linux-wireless, ath11k,
	John Crispin, Shashidhar Lakkavalli
In-Reply-To: <20190426084244.28098-1-john@phrozen.org>

Add target wait time wmi calls to the driver. En/disable the support
from when the bss_config changes. We ignore the cmd completion events.

Signed-off-by: Shashidhar Lakkavalli <slakkavalli@datto.com>
Signed-off-by: John Crispin <john@phrozen.org>
---
 drivers/net/wireless/ath/ath11k/mac.c |  7 +++
 drivers/net/wireless/ath/ath11k/wmi.c | 91 +++++++++++++++++++++++++++++++++++
 drivers/net/wireless/ath/ath11k/wmi.h | 71 +++++++++++++++++++++++++++
 3 files changed, 169 insertions(+)

diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c
index 8bb4ff82fb6f..a38c101e0140 100644
--- a/drivers/net/wireless/ath/ath11k/mac.c
+++ b/drivers/net/wireless/ath/ath11k/mac.c
@@ -1938,6 +1938,13 @@ static void ath11k_bss_info_changed(struct ieee80211_hw *hw,
 		ath11k_mac_txpower_recalc(ar);
 	}
 
+	if (changed & BSS_CHANGED_TWT) {
+		if (info->twt_responder || info->twt_responder)
+			ath11k_wmi_send_twt_enable_cmd(ar, ar->pdev_idx);
+		else
+			ath11k_wmi_send_twt_disable_cmd(ar, ar->pdev_idx);
+	}
+
 	mutex_unlock(&ar->conf_mutex);
 }
 
diff --git a/drivers/net/wireless/ath/ath11k/wmi.c b/drivers/net/wireless/ath/ath11k/wmi.c
index 7edaed5c97df..52d6fb200d07 100644
--- a/drivers/net/wireless/ath/ath11k/wmi.c
+++ b/drivers/net/wireless/ath/ath11k/wmi.c
@@ -1797,6 +1797,10 @@ ath11k_wmi_copy_peer_flags(struct wmi_peer_assoc_complete_cmd *cmd,
 			cmd->peer_flags |= WMI_PEER_VHT;
 		if (param->he_flag)
 			cmd->peer_flags |= WMI_PEER_HE;
+		if (param->twt_requester)
+			cmd->peer_flags |= WMI_PEER_TWT_REQ;
+		if (param->twt_responder)
+			cmd->peer_flags |= WMI_PEER_TWT_RESP;
 	}
 
 	/* Suppress authorization for all AUTH modes that need 4-way handshake
@@ -2787,6 +2791,86 @@ int ath11k_wmi_pdev_pktlog_disable(struct ath11k *ar)
 	return ret;
 }
 
+int
+ath11k_wmi_send_twt_enable_cmd(struct ath11k *ar, u32 pdev_id)
+{
+	struct ath11k_pdev_wmi *wmi = ar->wmi;
+	struct ath11k_base *ab = wmi->wmi_sc->sc;
+	struct wmi_twt_enable_params_cmd *cmd;
+	struct sk_buff *skb;
+	int ret, len;
+
+	len = sizeof(*cmd);
+
+	skb = ath11k_wmi_alloc_skb(wmi->wmi_sc, len);
+	if (!skb)
+		return -ENOMEM;
+
+	cmd = (void *)skb->data;
+	cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_TWT_ENABLE_CMD) |
+			  FIELD_PREP(WMI_TLV_LEN, len - TLV_HDR_SIZE);
+	cmd->pdev_id = pdev_id;
+	cmd->sta_cong_timer_ms = ATH11K_TWT_DEF_STA_CONG_TIMER_MS;
+	cmd->default_slot_size = ATH11K_TWT_DEF_DEFAULT_SLOT_SIZE;
+	cmd->congestion_thresh_setup = ATH11K_TWT_DEF_CONGESTION_THRESH_SETUP;
+	cmd->congestion_thresh_teardown =
+		ATH11K_TWT_DEF_CONGESTION_THRESH_TEARDOWN;
+	cmd->congestion_thresh_critical =
+		ATH11K_TWT_DEF_CONGESTION_THRESH_CRITICAL;
+	cmd->interference_thresh_teardown =
+		ATH11K_TWT_DEF_INTERFERENCE_THRESH_TEARDOWN;
+	cmd->interference_thresh_setup =
+		ATH11K_TWT_DEF_INTERFERENCE_THRESH_SETUP;
+	cmd->min_no_sta_setup = ATH11K_TWT_DEF_MIN_NO_STA_SETUP;
+	cmd->min_no_sta_teardown = ATH11K_TWT_DEF_MIN_NO_STA_TEARDOWN;
+	cmd->no_of_bcast_mcast_slots = ATH11K_TWT_DEF_NO_OF_BCAST_MCAST_SLOTS;
+	cmd->min_no_twt_slots = ATH11K_TWT_DEF_MIN_NO_TWT_SLOTS;
+	cmd->max_no_sta_twt = ATH11K_TWT_DEF_MAX_NO_STA_TWT;
+	cmd->mode_check_interval = ATH11K_TWT_DEF_MODE_CHECK_INTERVAL;
+	cmd->add_sta_slot_interval = ATH11K_TWT_DEF_ADD_STA_SLOT_INTERVAL;
+	cmd->remove_sta_slot_interval =
+		ATH11K_TWT_DEF_REMOVE_STA_SLOT_INTERVAL;
+	/* TODO add MBSSID support */
+	cmd->mbss_support = 0;
+
+	ret = ath11k_wmi_cmd_send(wmi, skb,
+				  WMI_TWT_ENABLE_CMDID);
+	if (ret) {
+		ath11k_warn(ab, "Failed to send WMI_TWT_ENABLE_CMDID");
+		dev_kfree_skb(skb);
+	}
+	return ret;
+}
+
+int
+ath11k_wmi_send_twt_disable_cmd(struct ath11k *ar, u32 pdev_id)
+{
+	struct ath11k_pdev_wmi *wmi = ar->wmi;
+	struct ath11k_base *ab = wmi->wmi_sc->sc;
+	struct wmi_twt_disable_params_cmd *cmd;
+	struct sk_buff *skb;
+	int ret, len;
+
+	len = sizeof(*cmd);
+
+	skb = ath11k_wmi_alloc_skb(wmi->wmi_sc, len);
+	if (!skb)
+		return -ENOMEM;
+
+	cmd = (void *)skb->data;
+	cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_TWT_DISABLE_CMD) |
+			  FIELD_PREP(WMI_TLV_LEN, len - TLV_HDR_SIZE);
+	cmd->pdev_id = pdev_id;
+
+	ret = ath11k_wmi_cmd_send(wmi, skb,
+				  WMI_TWT_DISABLE_CMDID);
+	if (ret) {
+		ath11k_warn(ab, "Failed to send WMI_TWT_DIeABLE_CMDID");
+		dev_kfree_skb(skb);
+	}
+	return ret;
+}
+
 static inline void ath11k_fill_band_to_mac_param(struct ath11k_base  *soc,
 				struct wmi_host_pdev_band_to_mac *band_to_mac)
 {
@@ -2877,6 +2961,9 @@ ath11k_wmi_copy_resource_config(struct wmi_resource_config *wmi_cfg,
 	wmi_cfg->use_pdev_id = tg_cfg->use_pdev_id;
 	wmi_cfg->flag1 = tg_cfg->atf_config;
 	wmi_cfg->peer_map_unmap_v2_support = tg_cfg->peer_map_unmap_v2_support;
+	wmi_cfg->sched_params = tg_cfg->sched_params;
+	wmi_cfg->twt_ap_pdev_count = tg_cfg->twt_ap_pdev_count;
+	wmi_cfg->twt_ap_sta_count = tg_cfg->twt_ap_sta_count;
 }
 
 static int ath11k_init_cmd_send(struct ath11k_pdev_wmi *wmi,
@@ -3068,6 +3155,8 @@ int ath11k_wmi_cmd_init(struct ath11k_base *sc)
 	config.beacon_tx_offload_max_vdev = sc->num_radios * TARGET_MAX_BCN_OFFLD;
 	config.rx_batchmode = TARGET_RX_BATCHMODE;
 	config.peer_map_unmap_v2_support = 1;
+	config.twt_ap_pdev_count = 2;
+	config.twt_ap_sta_count = 1000;
 
 	memcpy(&wmi_sc->wlan_resource_config, &config, sizeof(config));
 
@@ -5859,6 +5948,8 @@ static void ath11k_wmi_tlv_op_rx(struct ath11k_base *ab, struct sk_buff *skb)
 	/* add Unsupported events here */
 	case WMI_TBTTOFFSET_EXT_UPDATE_EVENTID:
 	case WMI_VDEV_DELETE_RESP_EVENTID:
+	case WMI_TWT_ENABLE_EVENTID:
+	case WMI_TWT_DISABLE_EVENTID:
 		ath11k_dbg(ab, ATH11K_DBG_WMI,
 			   "ignoring unsupported event 0x%x\n", id);
 		break;
diff --git a/drivers/net/wireless/ath/ath11k/wmi.h b/drivers/net/wireless/ath/ath11k/wmi.h
index 071537850c68..99f69fc3cf53 100644
--- a/drivers/net/wireless/ath/ath11k/wmi.h
+++ b/drivers/net/wireless/ath/ath11k/wmi.h
@@ -169,6 +169,10 @@ enum wmi_cmd_group {
 	WMI_GRP_MONITOR,        /* 0x39 */
 	WMI_GRP_REGULATORY,     /* 0x3a */
 	WMI_GRP_HW_DATA_FILTER, /* 0x3b */
+	WMI_GRP_WLM,            /* 0x3c */
+	WMI_GRP_11K_OFFLOAD,    /* 0x3d */
+	WMI_GRP_TWT,            /* 0x3e */
+
 };
 
 #define WMI_CMD_GRP(grp_id) (((grp_id) << 12) | 0x1)
@@ -531,6 +535,12 @@ enum wmi_tlv_cmd_id {
 	WMI_NDP_RESPONDER_REQ_CMDID,
 	WMI_NDP_END_REQ_CMDID,
 	WMI_HW_DATA_FILTER_CMDID = WMI_TLV_CMD(WMI_GRP_HW_DATA_FILTER),
+	WMI_TWT_ENABLE_CMDID = WMI_TLV_CMD(WMI_GRP_TWT),
+	WMI_TWT_DISABLE_CMDID,
+	WMI_TWT_ADD_DIALOG_CMDID,
+	WMI_TWT_DEL_DIALOG_CMDID,
+	WMI_TWT_PAUSE_DIALOG_CMDID,
+	WMI_TWT_RESUME_DIALOG_CMDID,
 };
 
 enum wmi_tlv_event_id {
@@ -713,6 +723,13 @@ enum wmi_tlv_event_id {
 	WMI_NDP_INDICATION_EVENTID,
 	WMI_NDP_CONFIRM_EVENTID,
 	WMI_NDP_END_INDICATION_EVENTID,
+
+	WMI_TWT_ENABLE_EVENTID = WMI_TLV_CMD(WMI_GRP_TWT),
+	WMI_TWT_DISABLE_EVENTID,
+	WMI_TWT_ADD_DIALOG_EVENTID,
+	WMI_TWT_DEL_DIALOG_EVENTID,
+	WMI_TWT_PAUSE_DIALOG_EVENTID,
+	WMI_TWT_RESUME_DIALOG_EVENTID,
 };
 
 enum wmi_tlv_pdev_param {
@@ -2736,6 +2753,9 @@ struct wmi_resource_config {
 	u32 max_num_dbs_scan_duty_cycle;
 	u32 max_num_group_keys;
 	u32 peer_map_unmap_v2_support;
+	u32 sched_params;
+	u32 twt_ap_pdev_count;
+	u32 twt_ap_sta_count;
 } __packed;
 
 struct wmi_service_ready_event {
@@ -3907,6 +3927,8 @@ struct peer_assoc_params {
 	u32 peer_he_mcs_count;
 	u32 peer_he_rx_mcs_set[WMI_HOST_MAX_HE_RATE_SET];
 	u32 peer_he_tx_mcs_set[WMI_HOST_MAX_HE_RATE_SET];
+	bool twt_responder;
+	bool twt_requester;
 	struct ath11k_ppe_threshold peer_ppet;
 };
 
@@ -4130,6 +4152,8 @@ struct wmi_pktlog_disable_cmd {
 #define WMI_PEER_DYN_MIMOPS	0x00020000
 #define WMI_PEER_STATIC_MIMOPS	0x00040000
 #define WMI_PEER_SPATIAL_MUX	0x00200000
+#define WMI_PEER_TWT_REQ	0x00400000
+#define WMI_PEER_TWT_RESP	0x00800000
 #define WMI_PEER_VHT		0x02000000
 #define WMI_PEER_80MHZ		0x04000000
 #define WMI_PEER_PMF		0x08000000
@@ -5005,6 +5029,48 @@ struct wmi_wmm_params_all_arg {
 	struct wmi_wmm_params_arg ac_vo;
 };
 
+#define ATH11K_TWT_DEF_STA_CONG_TIMER_MS		5000
+#define ATH11K_TWT_DEF_DEFAULT_SLOT_SIZE		10
+#define ATH11K_TWT_DEF_CONGESTION_THRESH_SETUP		50
+#define ATH11K_TWT_DEF_CONGESTION_THRESH_TEARDOWN	20
+#define ATH11K_TWT_DEF_CONGESTION_THRESH_CRITICAL	100
+#define ATH11K_TWT_DEF_INTERFERENCE_THRESH_TEARDOWN	80
+#define ATH11K_TWT_DEF_INTERFERENCE_THRESH_SETUP	50
+#define ATH11K_TWT_DEF_MIN_NO_STA_SETUP			10
+#define ATH11K_TWT_DEF_MIN_NO_STA_TEARDOWN		2
+#define ATH11K_TWT_DEF_NO_OF_BCAST_MCAST_SLOTS		2
+#define ATH11K_TWT_DEF_MIN_NO_TWT_SLOTS			2
+#define ATH11K_TWT_DEF_MAX_NO_STA_TWT			500
+#define ATH11K_TWT_DEF_MODE_CHECK_INTERVAL		10000
+#define ATH11K_TWT_DEF_ADD_STA_SLOT_INTERVAL		1000
+#define ATH11K_TWT_DEF_REMOVE_STA_SLOT_INTERVAL		5000
+
+struct wmi_twt_enable_params_cmd {
+	u32 tlv_header;
+	u32 pdev_id;
+	u32 sta_cong_timer_ms;
+	u32 mbss_support;
+	u32 default_slot_size;
+	u32 congestion_thresh_setup;
+	u32 congestion_thresh_teardown;
+	u32 congestion_thresh_critical;
+	u32 interference_thresh_teardown;
+	u32 interference_thresh_setup;
+	u32 min_no_sta_setup;
+	u32 min_no_sta_teardown;
+	u32 no_of_bcast_mcast_slots;
+	u32 min_no_twt_slots;
+	u32 max_no_sta_twt;
+	u32 mode_check_interval;
+	u32 add_sta_slot_interval;
+	u32 remove_sta_slot_interval;
+};
+
+struct wmi_twt_disable_params_cmd {
+	u32 tlv_header;
+	u32 pdev_id;
+};
+
 struct target_resource_config {
 	u32 num_vdevs;
 	u32 num_peers;
@@ -5065,6 +5131,9 @@ struct target_resource_config {
 	u32 max_bssid_rx_filters;
 	u32 use_pdev_id;
 	u32 peer_map_unmap_v2_support;
+	u32 sched_params;
+	u32 twt_ap_pdev_count;
+	u32 twt_ap_sta_count;
 };
 
 #define WMI_MAX_MEM_REQS 32
@@ -5190,4 +5259,6 @@ size_t ath11k_wmi_fw_stats_num_vdevs(struct list_head *head);
 void ath11k_wmi_fw_stats_fill(struct ath11k *ar,
 			      struct ath11k_fw_stats *fw_stats, u32 stats_id,
 			      char *buf);
+int ath11k_wmi_send_twt_enable_cmd(struct ath11k *ar, u32 pdev_id);
+int ath11k_wmi_send_twt_disable_cmd(struct ath11k *ar, u32 pdev_id);
 #endif
-- 
2.11.0


^ permalink raw reply related

* [PATCH 0/3] mac80211: notify the driver when it should enable TWT
From: John Crispin @ 2019-04-26  8:42 UTC (permalink / raw)
  To: Johannes Berg, Kalle Valo
  Cc: Srini Kode, Rajkumar Manoharan, linux-wireless, ath11k,
	John Crispin

The ath11k FW has a dedicated call for setting the TWT state. trigger this
changes to the BSS config.

In a later step we need to also add calls for manually stating TWT dialogs.

John Crispin (3):
  mac80211: allow turning TWT responder support on and off via netlink
  mac80211: dynamically turn TWT requester support on and off
  ath11k: add TWT support

 drivers/net/wireless/ath/ath11k/mac.c |  7 +++
 drivers/net/wireless/ath/ath11k/wmi.c | 91 +++++++++++++++++++++++++++++++++++
 drivers/net/wireless/ath/ath11k/wmi.h | 71 +++++++++++++++++++++++++++
 include/net/cfg80211.h                |  2 +
 include/net/mac80211.h                |  5 ++
 include/uapi/linux/nl80211.h          |  4 ++
 net/mac80211/cfg.c                    |  6 +++
 net/mac80211/mlme.c                   | 20 +++++++-
 net/wireless/nl80211.c                |  5 ++
 9 files changed, 209 insertions(+), 2 deletions(-)

-- 
2.11.0


^ permalink raw reply

* [PATCH 1/3] mac80211: allow turning TWT responder support on and off via netlink
From: John Crispin @ 2019-04-26  8:42 UTC (permalink / raw)
  To: Johannes Berg, Kalle Valo
  Cc: Srini Kode, Rajkumar Manoharan, linux-wireless, ath11k,
	John Crispin, Shashidhar Lakkavalli
In-Reply-To: <20190426084244.28098-1-john@phrozen.org>

Allow the userland daemon to en/disable TWT support for an AP.

Signed-off-by: Shashidhar Lakkavalli <slakkavalli@datto.com>
Signed-off-by: John Crispin <john@phrozen.org>
---
 include/net/cfg80211.h       | 2 ++
 include/net/mac80211.h       | 5 +++++
 include/uapi/linux/nl80211.h | 4 ++++
 net/mac80211/cfg.c           | 6 ++++++
 net/wireless/nl80211.c       | 5 +++++
 5 files changed, 22 insertions(+)

diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index bb307a11ee63..8a20f5a42977 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -1511,6 +1511,7 @@ struct mpath_info {
  * 	(u16 = opmode, -1 = do not change)
  * @p2p_ctwindow: P2P CT Window (-1 = no change)
  * @p2p_opp_ps: P2P opportunistic PS (-1 = no change)
+ * @twt_responder: HE Target Wait Time support.
  */
 struct bss_parameters {
 	int use_cts_prot;
@@ -1521,6 +1522,7 @@ struct bss_parameters {
 	int ap_isolate;
 	int ht_opmode;
 	s8 p2p_ctwindow, p2p_opp_ps;
+	int twt_responder;
 };
 
 /**
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index ac2ed8ec662b..87a6e149abda 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -317,6 +317,7 @@ struct ieee80211_vif_chanctx_switch {
  * @BSS_CHANGED_MCAST_RATE: Multicast Rate setting changed for this interface
  * @BSS_CHANGED_FTM_RESPONDER: fime timing reasurement request responder
  *	functionality changed for this BSS (AP mode).
+ * @BSS_CHANGED_TWT: TWT enable status changed
  *
  */
 enum ieee80211_bss_change {
@@ -347,6 +348,7 @@ enum ieee80211_bss_change {
 	BSS_CHANGED_KEEP_ALIVE		= 1<<24,
 	BSS_CHANGED_MCAST_RATE		= 1<<25,
 	BSS_CHANGED_FTM_RESPONDER	= 1<<26,
+	BSS_CHANGED_TWT			= 1<<27,
 
 	/* when adding here, make sure to change ieee80211_reconfig */
 };
@@ -504,6 +506,8 @@ struct ieee80211_ftm_responder_params {
  * @he_support: does this BSS support HE
  * @twt_requester: does this BSS support TWT requester (relevant for managed
  *	mode only, set if the AP advertises TWT responder role)
+ * @twt_responder: does this BSS support TWT responder (relevant for AP
+ *	mode only, set if the AP advertises TWT responder role)
  * @assoc: association status
  * @ibss_joined: indicates whether this station is part of an IBSS
  *	or not
@@ -611,6 +615,7 @@ struct ieee80211_bss_conf {
 	u16 frame_time_rts_th;
 	bool he_support;
 	bool twt_requester;
+	bool twt_responder;
 	/* association related data */
 	bool assoc, ibss_joined;
 	bool ibss_creator;
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index dd4f86ee286e..ba1f69751a4a 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -2308,6 +2308,8 @@ enum nl80211_commands {
  * @NL80211_ATTR_AIRTIME_WEIGHT: Station's weight when scheduled by the airtime
  *	scheduler.
  *
+ * @NL80211_ATTR_TWT_RESPONDER: Enable target wait time responder support.
+ *
  * @NUM_NL80211_ATTR: total number of nl80211_attrs available
  * @NL80211_ATTR_MAX: highest attribute number currently defined
  * @__NL80211_ATTR_AFTER_LAST: internal use
@@ -2759,6 +2761,8 @@ enum nl80211_attrs {
 
 	NL80211_ATTR_AIRTIME_WEIGHT,
 
+	NL80211_ATTR_TWT_RESPONDER,
+
 	/* add attributes here, update the policy in nl80211.c */
 
 	__NL80211_ATTR_AFTER_LAST,
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 09dd1c2860fc..a66600bf9cef 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -2176,6 +2176,12 @@ static int ieee80211_change_bss(struct wiphy *wiphy,
 		changed |= BSS_CHANGED_P2P_PS;
 	}
 
+	if (params->twt_responder >= 0) {
+		sdata->vif.bss_conf.twt_responder =
+			params->twt_responder;
+		changed |= BSS_CHANGED_TWT;
+	}
+
 	ieee80211_bss_info_change_notify(sdata, changed);
 
 	return 0;
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 25a9e3b5c154..4f98ee0a98f3 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -6105,6 +6105,7 @@ static int nl80211_set_bss(struct sk_buff *skb, struct genl_info *info)
 	params.ht_opmode = -1;
 	params.p2p_ctwindow = -1;
 	params.p2p_opp_ps = -1;
+	params.twt_responder = -1;
 
 	if (info->attrs[NL80211_ATTR_BSS_CTS_PROT])
 		params.use_cts_prot =
@@ -6149,6 +6150,10 @@ static int nl80211_set_bss(struct sk_buff *skb, struct genl_info *info)
 			return -EINVAL;
 	}
 
+	if (info->attrs[NL80211_ATTR_TWT_RESPONDER])
+		params.twt_responder =
+		    nla_get_u8(info->attrs[NL80211_ATTR_TWT_RESPONDER]);
+
 	if (!rdev->ops->change_bss)
 		return -EOPNOTSUPP;
 
-- 
2.11.0


^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox