[PATCH 8/9] wifi: mt76: mt7921: introduce remain_on_channel support

Sean Wang sean.wang at kernel.org
Wed Aug 17 18:03:03 PDT 2022


Hi Lorenzo,

On Wed, Aug 17, 2022 at 12:18 AM Lorenzo Bianconi <lorenzo at kernel.org> wrote:
>
> > From: Sean Wang <sean.wang at mediatek.com>
> >
> > Introduce remain_on_channel support. Additionally, we add
> > mt7921_check_offload_capability to disable .remain_on_channel and
> > .cancel_remain_on_channel and related configuration because those
> > operations would rely on the fundamental MCU commands that will be only
> > supported with newer firmware.
> >
> > Co-developed-by: Deren Wu <deren.wu at mediatek.com>
> > Signed-off-by: Deren Wu <deren.wu at mediatek.com>
> > Signed-off-by: Sean Wang <sean.wang at mediatek.com>
> > ---
> >  .../net/wireless/mediatek/mt76/mt7921/init.c  |  36 ++++++
> >  .../net/wireless/mediatek/mt76/mt7921/main.c  | 112 ++++++++++++++++++
> >  .../net/wireless/mediatek/mt76/mt7921/mcu.c   |  24 ++++
> >  .../wireless/mediatek/mt76/mt7921/mt7921.h    |  34 ++++++
> >  .../net/wireless/mediatek/mt76/mt7921/pci.c   |  13 +-
> >  .../net/wireless/mediatek/mt76/mt7921/sdio.c  |  11 +-
> >  .../net/wireless/mediatek/mt76/mt7921/usb.c   |   1 +
> >  7 files changed, 225 insertions(+), 6 deletions(-)
> >
> > diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/init.c b/drivers/net/wireless/mediatek/mt76/mt7921/init.c
> > index cd960e23770f..1b7a18d42f5b 100644
> > --- a/drivers/net/wireless/mediatek/mt76/mt7921/init.c
> > +++ b/drivers/net/wireless/mediatek/mt76/mt7921/init.c
> > @@ -44,6 +44,35 @@ mt7921_regd_notifier(struct wiphy *wiphy,
> >       mt7921_mutex_release(dev);
> >  }
> >
> > +static int mt7921_check_offload_capability(struct mt7921_dev *dev)
> > +{
> > +     struct ieee80211_hw *hw = mt76_hw(dev);
> > +     int year, mon, day, hour, min, sec;
> > +     struct wiphy *wiphy = hw->wiphy;
> > +     bool fw_can_roc = false;
> > +     int ret;
> > +
> > +     ret = sscanf(dev->mt76.hw->wiphy->fw_version + 11, "%4d%2d%2d%2d%2d%2d",
> > +                  &year, &mon, &day, &hour, &min, &sec);
>
> does the fw have a differnt base version with respect to the previous ones?
> checking the date is a bit ugly.

I admitted that way was a bit ugly, but I have investigated for a
while, and that is the only way we can use to distinguish the version
in current mt7921 firmware.

>
> > +     if (ret != 6)
> > +             goto out;
> > +
> > +     /* Old firmware cannot support remained on channel and channel
> > +      * context management.
> > +      */
> > +     fw_can_roc =  mktime64(year, mon, day, hour, min, sec) >=
> > +                   mktime64(2022, 7, 15, 12, 1, 1);
> > +out:
> > +     if (!fw_can_roc) {
> > +             dev->ops->remain_on_channel = NULL;
> > +             dev->ops->cancel_remain_on_channel = NULL;
> > +
> > +             wiphy->flags &= ~WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
> > +     }
> > +
> > +     return 0;
> > +}
> > +

<snip>

> > -     mdev = mt76_alloc_device(&pdev->dev, sizeof(*dev), &mt7921_ops,
> > -                              &drv_ops);
> > +     ops = devm_kmemdup(&pdev->dev, &mt7921_ops, sizeof(mt7921_ops),
> > +                        GFP_KERNEL);
>
> why do we need to copy mt7921_ops?
>

As the old fw cannot support the roc and chanctx and considering
backward compatibility, I need to copy the mt7921_ops here and
disable related operations for old fw before registering the hw to mac80211.

     Sean

> Regards,
> Lorenzo
>
> > +     if (!ops) {
> > +             ret = -ENOMEM;
> > +             goto err_free_pci_vec;
> > +     }
> > +
> > +     mdev = mt76_alloc_device(&pdev->dev, sizeof(*dev), ops, &drv_ops);
> >       if (!mdev) {
> >               ret = -ENOMEM;
> >               goto err_free_pci_vec;
> > @@ -286,7 +293,7 @@ static int mt7921_pci_probe(struct pci_dev *pdev,
> >
> >       dev = container_of(mdev, struct mt7921_dev, mt76);
> >       dev->hif_ops = &mt7921_pcie_ops;
> > -
> > +     dev->ops = ops;
> >       mt76_mmio_init(&dev->mt76, pcim_iomap_table(pdev)[0]);
> >       tasklet_init(&dev->irq_tasklet, mt7921_irq_tasklet, (unsigned long)dev);
> >
> > diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/sdio.c b/drivers/net/wireless/mediatek/mt76/mt7921/sdio.c
> > index 487acd6e2be8..6d27875f41b8 100644
> > --- a/drivers/net/wireless/mediatek/mt76/mt7921/sdio.c
> > +++ b/drivers/net/wireless/mediatek/mt76/mt7921/sdio.c
> > @@ -120,18 +120,23 @@ static int mt7921s_probe(struct sdio_func *func,
> >               .fw_own = mt7921s_mcu_fw_pmctrl,
> >       };
> >
> > +     struct ieee80211_ops *ops;
> >       struct mt7921_dev *dev;
> >       struct mt76_dev *mdev;
> >       int ret;
> >
> > -     mdev = mt76_alloc_device(&func->dev, sizeof(*dev), &mt7921_ops,
> > -                              &drv_ops);
> > +     ops = devm_kmemdup(&func->dev, &mt7921_ops, sizeof(mt7921_ops),
> > +                        GFP_KERNEL);
> > +     if (!ops)
> > +             return -ENOMEM;
> > +
> > +     mdev = mt76_alloc_device(&func->dev, sizeof(*dev), ops, &drv_ops);
> >       if (!mdev)
> >               return -ENOMEM;
> >
> >       dev = container_of(mdev, struct mt7921_dev, mt76);
> >       dev->hif_ops = &mt7921_sdio_ops;
> > -
> > +     dev->ops = ops;
> >       sdio_set_drvdata(func, dev);
> >
> >       ret = mt76s_init(mdev, func, &mt7921s_ops);
> > diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/usb.c b/drivers/net/wireless/mediatek/mt76/mt7921/usb.c
> > index d06cee386acd..cf3ec59a4270 100644
> > --- a/drivers/net/wireless/mediatek/mt76/mt7921/usb.c
> > +++ b/drivers/net/wireless/mediatek/mt76/mt7921/usb.c
> > @@ -217,6 +217,7 @@ static int mt7921u_probe(struct usb_interface *usb_intf,
> >
> >       dev = container_of(mdev, struct mt7921_dev, mt76);
> >       dev->hif_ops = &hif_ops;
> > +     dev->ops = ops;
> >
> >       udev = usb_get_dev(udev);
> >       usb_reset_device(udev);
> > --
> > 2.25.1
> >



More information about the Linux-mediatek mailing list