Re: [PATCH 2/5] mt76x02: fixup MT_PROT_RATE_* defines

2018-12-08 Thread Lorenzo Bianconi
>
> On new mt76 chips, phy mode is configured by last 3 bits
> of rate value. Hence OFDM bit is marked by 0x2000
> instead of 0x4000.
>
> Signed-off-by: Stanislaw Gruszka 
> ---
>  drivers/net/wireless/mediatek/mt76/mt76x02_regs.h | 6 +++---
>  1 file changed, 3 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_regs.h 
> b/drivers/net/wireless/mediatek/mt76/mt76x02_regs.h
> index f7de77d09d28..d1ac847adce5 100644
> --- a/drivers/net/wireless/mediatek/mt76/mt76x02_regs.h
> +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_regs.h
> @@ -440,9 +440,9 @@
>  #define MT_PROT_TXOP_ALLOW_GF40BIT(25)
>  #define MT_PROT_RTS_THR_EN BIT(26)
>  #define MT_PROT_RATE_CCK_110x0003
> -#define MT_PROT_RATE_OFDM_60x4000
> -#define MT_PROT_RATE_OFDM_24   0x4004
> -#define MT_PROT_RATE_DUP_OFDM_24   0x4084
> +#define MT_PROT_RATE_OFDM_60x2000
> +#define MT_PROT_RATE_OFDM_24   0x2004
> +#define MT_PROT_RATE_DUP_OFDM_24   0x2084
>  #define MT_PROT_TXOP_ALLOW_ALL GENMASK(25, 20)
>  #define MT_PROT_TXOP_ALLOW_BW20(MT_PROT_TXOP_ALLOW_ALL & 
>   \
>      ~MT_PROT_TXOP_ALLOW_MM40 & \
> --
> 1.9.3
>

Acked-by: Lorenzo Bianconi 


Re: [PATCH 5/5] mt76x2: initialize fall-back rate registers

2018-12-08 Thread Lorenzo Bianconi
>
> Initialize MT_LG_FBK_CFG{0,1} and MT_VHT_HT_FBK_CFG{0,1} registers.
>
> Signed-off-by: Stanislaw Gruszka 
> ---
>  drivers/net/wireless/mediatek/mt76/mt76x0/initvals.h | 4 
>  1 file changed, 4 insertions(+)
>
> diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/initvals.h 
> b/drivers/net/wireless/mediatek/mt76/mt76x0/initvals.h
> index a1657922758e..01e672bad2f1 100644
> --- a/drivers/net/wireless/mediatek/mt76/mt76x0/initvals.h
> +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/initvals.h
> @@ -88,6 +88,10 @@
> { MT_TX_PROT_CFG6,  0xe3f42004 },
> { MT_TX_PROT_CFG7,  0xe3f42084 },
> { MT_TX_PROT_CFG8,  0xe3f42104 },
> +   { MT_VHT_HT_FBK_CFG0,   0x65432100 },
> +   { MT_VHT_HT_FBK_CFG1,   0xedcba980 },
> +   { MT_LG_FBK_CFG0,   0xedcba988 },
> +   { MT_LG_FBK_CFG1,   0x00872100 },
>  };
>

as for mt76x2 patch (except  MT_VHT_HT_FBK_CFG1) MT_VHT_HT_FBK_CFG0,
MT_LG_FBK_CFG{0,1} are default values
(at least for mt7610e, I will double-check for mt7610u)

Regards,
Lorenzo

>  static const struct mt76_reg_pair mt76x0_bbp_init_tab[] = {
> --
> 1.9.3
>


Re: [PATCH 4/5] mt76x2: initialize fall-back rate registers

2018-12-08 Thread Lorenzo Bianconi
>
> Initialize MT_LG_FBK_CFG{0,1} and MT_VHT_HT_FBK_CFG0 registers.
> MT_VHT_HT_FBK_CFG1 was already configured.
>
> Signed-off-by: Stanislaw Gruszka 
> ---
>  drivers/net/wireless/mediatek/mt76/mt76x2/init.c | 3 +++
>  1 file changed, 3 insertions(+)
>
> diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/init.c 
> b/drivers/net/wireless/mediatek/mt76/mt76x2/init.c
> index 54a9b5fac787..16fd514b5207 100644
> --- a/drivers/net/wireless/mediatek/mt76/mt76x2/init.c
> +++ b/drivers/net/wireless/mediatek/mt76/mt76x2/init.c
> @@ -140,7 +140,10 @@ void mt76_write_mac_initvals(struct mt76x02_dev *dev)
> { MT_WPDMA_DELAY_INT_CFG,   0x94ff },
> { MT_TX_SW_CFG3,0x0004 },
> { MT_HT_FBK_TO_LEGACY,  0x1818 },
> +   { MT_VHT_HT_FBK_CFG0,   0x65432100 },
> { MT_VHT_HT_FBK_CFG1,   0xedcba980 },
> +   { MT_LG_FBK_CFG0,   0xedcba988 },
> +   { MT_LG_FBK_CFG1,   0x87872100 },
> { MT_PROT_AUTO_TX_CFG,  0x00830083 },
> { MT_HT_CTRL_CFG,   0x01ff },
> };

I do not think this patch is necessary since these value are default ones:

root@lede:/sys/kernel/debug/ieee80211/phy0/mt76# echo 0x1354 > regidx
root@lede:/sys/kernel/debug/ieee80211/phy0/mt76# cat regval
0x65432100
root@lede:/sys/kernel/debug/ieee80211/phy0/mt76# echo 0x135c > regidx
root@lede:/sys/kernel/debug/ieee80211/phy0/mt76# cat regval
0xedcba988
root@lede:/sys/kernel/debug/ieee80211/phy0/mt76# echo 0x1360 > regidx
root@lede:/sys/kernel/debug/ieee80211/phy0/mt76# cat regval
0x87872100

Regards,
Lorenzo

> --
> 1.9.3
>


Re: [PATCH 1/5] mt76x02: do not set protection on set_rts_threshold callback

2018-12-08 Thread Lorenzo Bianconi
On Fri, Dec 7, 2018 at 2:27 PM Stanislaw Gruszka  wrote:
>
> Use set_rts_threshold calback to enable/disable threshold only for
> legacy traffic.
>
> Protection for HT and VHT traffic is defined by HT operation element
> and it's provided by remote AP or by hostapd.
>
> Signed-off-by: Stanislaw Gruszka 
> ---
>  drivers/net/wireless/mediatek/mt76/mt76x02_mac.c  | 16 +---
>  drivers/net/wireless/mediatek/mt76/mt76x02_mac.h  |  2 +-
>  drivers/net/wireless/mediatek/mt76/mt76x02_util.c |  2 +-
>  3 files changed, 3 insertions(+), 17 deletions(-)
>
> diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c 
> b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
> index c08bf371e527..9693d6140b3d 100644
> --- a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
> +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
> @@ -715,7 +715,7 @@ void mt76x02_tx_complete_skb(struct mt76_dev *mdev, 
> struct mt76_queue *q,
>  }
>  EXPORT_SYMBOL_GPL(mt76x02_tx_complete_skb);
>

[...]

> diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c 
> b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
> index 3a70e5bf7d42..e7ee2cc76edf 100644
> --- a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
> +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
> @@ -463,7 +463,7 @@ int mt76x02_set_rts_threshold(struct ieee80211_hw *hw, 
> u32 val)
> return -EINVAL;
>
> mutex_lock(>mutex);
> -   mt76x02_mac_set_tx_protection(dev, val);
> +   mt76x02_mac_set_rts_thresh(dev, val);
> mutex_unlock(>mutex);

I think this patch will not apply since I have recently fixed an
uninitialized mutex access setting rts threshold
1770f0fa978e ("mt76: fix uninitialized mutex access setting rts
threshold"). That patch is in Kalle's pending branch
now. You should probably respin on top of it.

Regards,
Lorenzo

>
> return 0;
> --
> 1.9.3
>


[PATCH] mt76: usb: avoid queue/status spinlocks while passing tx status to mac80211

2018-12-06 Thread Lorenzo Bianconi
As already done for pcie code in commit 79d1c94c9c78 ("mt76: avoid
queue/status spinlocks while passing tx status to mac80211") make sure
that no tx related spinlocks are taken during the ieee80211_tx_status call

Signed-off-by: Lorenzo Bianconi 
---
 drivers/net/wireless/mediatek/mt76/usb.c | 10 ++
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/usb.c 
b/drivers/net/wireless/mediatek/mt76/usb.c
index 14ff06c5764e..6a2507524c6c 100644
--- a/drivers/net/wireless/mediatek/mt76/usb.c
+++ b/drivers/net/wireless/mediatek/mt76/usb.c
@@ -583,6 +583,7 @@ static void mt76u_stop_rx(struct mt76_dev *dev)
 static void mt76u_tx_tasklet(unsigned long data)
 {
struct mt76_dev *dev = (struct mt76_dev *)data;
+   struct mt76_queue_entry entry;
struct mt76u_buf *buf;
struct mt76_queue *q;
bool wake;
@@ -597,17 +598,18 @@ static void mt76u_tx_tasklet(unsigned long data)
if (!buf->done || !q->queued)
break;
 
-   dev->drv->tx_complete_skb(dev, q,
- >entry[q->head],
- false);
-
if (q->entry[q->head].schedule) {
q->entry[q->head].schedule = false;
q->swq_queued--;
}
 
+   entry = q->entry[q->head];
q->head = (q->head + 1) % q->ndesc;
q->queued--;
+
+   spin_unlock_bh(>lock);
+   dev->drv->tx_complete_skb(dev, q, , false);
+   spin_lock_bh(>lock);
}
mt76_txq_schedule(dev, q);
wake = i < IEEE80211_NUM_ACS && q->queued < q->ndesc - 8;
-- 
2.19.2



[PATCH] mt76: mac: run mt76x02_mac_work routine atomically

2018-12-06 Thread Lorenzo Bianconi
Grab mt76_dev mutex in mt76x02_mac_work handler since it runs
concurrently with mt76x{0,2}_set_channel routines

Signed-off-by: Lorenzo Bianconi 
---
 drivers/net/wireless/mediatek/mt76/mt76x02_mac.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c 
b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
index 490368dc9325..64841f40cdcf 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
@@ -784,6 +784,8 @@ void mt76x02_mac_work(struct work_struct *work)
   mac_work.work);
int i, idx;
 
+   mutex_lock(>mt76.mutex);
+
mt76x02_update_channel(>mt76);
for (i = 0, idx = 0; i < 16; i++) {
u32 val = mt76_rr(dev, MT_TX_AGG_CNT(i));
@@ -796,6 +798,8 @@ void mt76x02_mac_work(struct work_struct *work)
if (!dev->beacon_mask)
mt76x02_check_mac_err(dev);
 
+   mutex_unlock(>mt76.mutex);
+
mt76_tx_status_check(>mt76, NULL, false);
 
ieee80211_queue_delayed_work(mt76_hw(dev), >mac_work,
-- 
2.19.2



[PATCH] mt76: fix typo in mt76x02_check_mac_err routine

2018-12-06 Thread Lorenzo Bianconi
Reconfigure properly MT_MAC_SYS_CTRL register after mac sw-reset
in mt76x02_check_mac_err routine

Fixes: 73556561ab9f ("mt76x0: use mt76x02_mac_work as stats handler")
Signed-off-by: Lorenzo Bianconi 
---
 drivers/net/wireless/mediatek/mt76/mt76x02_mac.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c 
b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
index c08bf371e527..490368dc9325 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
@@ -774,8 +774,8 @@ static void mt76x02_check_mac_err(struct mt76x02_dev *dev)
 
mt76_set(dev, MT_MAC_SYS_CTRL, MT_MAC_SYS_CTRL_RESET_CSR);
udelay(10);
-   mt76_clear(dev, MT_MAC_SYS_CTRL,
-  MT_MAC_SYS_CTRL_ENABLE_TX | MT_MAC_SYS_CTRL_ENABLE_RX);
+   mt76_wr(dev, MT_MAC_SYS_CTRL,
+   MT_MAC_SYS_CTRL_ENABLE_TX | MT_MAC_SYS_CTRL_ENABLE_RX);
 }
 
 void mt76x02_mac_work(struct work_struct *work)
-- 
2.19.2



Re: [PATCH 2/2] mt76: dma: add rx buffer recycle support

2018-12-05 Thread Lorenzo Bianconi
> On Wed, Dec 05, 2018 at 11:37:33AM +0100, Lorenzo Bianconi wrote:
> > >
> > > Add support for recycling rx buffers if they are not forwarded
> > > to network stack instead of reallocate them from scratch
> > >
> > > Signed-off-by: Lorenzo Bianconi 
> > > ---
> > 
> > Felix,
> > 
> > could you please drop this patch since it does not help to reduce pressure
> > on page_frag_cache.
> 
> What is the problem ? Maybe using kmalloc() instead of page_frag_alloc()
> could help (kmalloc has standard kmem_cache for 2048 bytes object) ?

Hi Stanislaw,

I think the only difference in using a recycle buffer with page_frag_cache is
we are a little bit less greedy in consuming the compound page since in case of
error we will reuse the previously allocated fragment. However we will need to
reallocate a new compound page if we have a leftover fragment that 'locks'
the previous compound (we have the same issue if we do not use the recycle
buffer). Does this 'little' improvement worth a more complex code?
Do you agree or is there something I am missing here?

Regards,
Lorenzo

> 
> Thanks
> Stanislaw


Re: [PATCH 2/2] mt76: dma: add rx buffer recycle support

2018-12-05 Thread Lorenzo Bianconi
>
> Add support for recycling rx buffers if they are not forwarded
> to network stack instead of reallocate them from scratch
>
> Signed-off-by: Lorenzo Bianconi 
> ---

Felix,

could you please drop this patch since it does not help to reduce pressure
on page_frag_cache.

Regards,
Lorenzo


Re: pull request: mt76 2018-11-30

2018-12-05 Thread Lorenzo Bianconi
> Felix Fietkau  writes:
>
> > here's my first pull request for 4.21
> >
> > - Felix
> >
> > The following changes since commit b72c51a58e6d63ef673ac96b8ab5bc98799c5f7b:
> >
> >   brcmfmac: Fix out of bounds memory access during fw load (2018-11-29 
> > 17:33:10 +0200)
> >
> > are available in the Git repository at:
> >
> >   https://github.com/nbd168/wireless tags/mt76-for-kvalo-2018-11-30
> >
> > for you to fetch changes up to e28487ea84a9c081c6d8d7da319427f7fcc32ff5:
> >
> >   mt76: replace sta_add/remove ops with common sta_state function 
> > (2018-11-30 12:30:37 +0100)
> >
> > 
> > first batch of mt76 patches for 4.21
> >
> > * use the same firmware for mt76x2e and mt76x2u
> > * mt76x2 fixes
> > * mt76x0 fixes
> > * mt76x0e survey support
> > * more unification between mt76x2 and mt76x0
> > * mt76x0e AP mode support
> > * mt76x0e DFS support
> > * rework and fix tx status handling for mt76x0 and mt76x2
> >
> > 
>
> I fast forwarded w-d-next to net-next and now there's a conflict. I did
> a test merge in the pending branch, please double check:
>
> https://git.kernel.org/pub/scm/linux/kernel/git/kvalo/wireless-drivers-next.git/commit/?h=pending=e69caab09bf98d0d8b559d06887364cc0090097c
>

ack

> This was the conflict:
>
> diff --cc drivers/net/wireless/mediatek/mt76/mt76x2/pci_main.c
> index 3f001bd6806c,b54a32397486..
> --- a/drivers/net/wireless/mediatek/mt76/mt76x2/pci_main.c
> +++ b/drivers/net/wireless/mediatek/mt76/mt76x2/pci_main.c
> @@@ -264,21 -173,6 +173,24 @@@ static int mt76x2_get_antenna(struct ie
> return 0;
>   }
>
> ++<<< HEAD
>  +static int
>  +mt76x2_set_rts_threshold(struct ieee80211_hw *hw, u32 val)
>  +{
>  +  struct mt76x02_dev *dev = hw->priv;
>  +
>  +  if (val != ~0 && val > 0x)
>  +  return -EINVAL;
>  +
>  +  mutex_lock(>mt76.mutex);
>  +  mt76x2_mac_set_tx_protection(dev, val);
>  +  mutex_unlock(>mt76.mutex);
>  +
>  +  return 0;
>  +}
>  +
> ++===
> ++>>> 1b0adb0ab8649a1ed44f9840724878cffaaa6896
>   const struct ieee80211_ops mt76x2_ops = {
> .tx = mt76x02_tx,
> .start = mt76x2_start,
>
> I solved it by removing mt76x2_set_rts_threshold(). After there was also
> a compilation error which I fixed like this:

correct, mt76x2_set_rts_threshold has been moved to mt76x02_util.c

>
> diff --cc drivers/net/wireless/mediatek/mt76/mt76x2/pci_main.c
> index 3f001bd6806c,b54a32397486..
> --- a/drivers/net/wireless/mediatek/mt76/mt76x2/pci_main.c
> +++ b/drivers/net/wireless/mediatek/mt76/mt76x2/pci_main.c
> diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c 
> b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
> index 3a70e5bf7d42..38bd466cff16 100644
> --- a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
> +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
> @@ -462,9 +462,9 @@ int mt76x02_set_rts_threshold(struct ieee80211_hw *hw, 
> u32 val)
> if (val != ~0 && val > 0x)
> return -EINVAL;
>
> -   mutex_lock(>mutex);
> +   mutex_lock(>mt76.mutex);
> mt76x02_mac_set_tx_protection(dev, val);
> -   mutex_unlock(>mutex);
> +   mutex_unlock(>mt76.mutex);
>
> return 0;
>  }

correct

Regards,
Lorenzo

>
> --
> Kalle Valo

-- 
UNIX is Sexy: who | grep -i blonde | talk; cd ~; wine; talk; touch;
unzip; touch; strip; gasp; finger; gasp; mount; fsck; more; yes; gasp;
umount; make clean; sleep


Re: [RFC 0/5] add XDP support to mt76x2e/mt76x0e drivers

2018-12-03 Thread Lorenzo Bianconi
> On Mon, 2018-12-03 at 21:36 +0200, Toke Høiland-Jørgensen wrote:
> > Hi Johannes
> >
> > I think your email can be basically summed up to:
> >
> > > [ ... ] but really I think it's a can of worms.
> >
> > ...right? :)
>
> Heh, yeah :)
>
> > I sort of had a feeling it would be, but thank you for spelling out in
> > excruciating detail why that is so.
>
> :-)
>
> > Given this, I think I agree that it's not worth it for now, and we
> > should hold off on adding XDP support until we have 802.3/.11 conversion
> > offload working... Which I think is also where you ended up? :)
>
> That case is at least easy, yeah. And it seems kinda likely that we'll
> end up with that in all well-maintained drivers in the relatively near
> future anyway?

Hi all,

thanks for sharing your thoughts and concerns, as already stated the
main goal of this series
is get feedbacks and/or blocking points to start experimenting with
eBPF over 802.11 devices.
Reviewing the points indicated by Johannes, 802.11 protocol is too
complicated to be managed without skb
allocation. I agree that for the moment XDP/eBPF can be useful for
devices that supports hw offloading
(or FullMac devices?) since all the tricky aspects are already managed
in the firmware and we can take care of XDP stuff.
Probably in the near future we will respin this argument :)

>
> BTW, in a sense I still kind of want to add eBPF to the mac80211 ingress
> path, just not in the XDP sense. For example, I had a proposal a while
> ago to add a filter to the monitor mode RX path(s) in eBPF; I still
> think that's useful.
>
> I also think it may be useful to put eBPF programs into per-netdev
> ingress path, in order to e.g. collect statistics, rather than hard-
> coding all kinds of statistics into mac80211.
>
> All of these things I consider absolutely useful and helpful. I like
> eBPF and the flexibility it affords. I just really don't think we should
> call it XDP or let it do similar things to XDP like dropping or
> redirecting frames.
>

+1 :)

Regards,
Lorenzo

> johannes
>


[PATCH 2/2] mt76: dma: add rx buffer recycle support

2018-12-03 Thread Lorenzo Bianconi
Add support for recycling rx buffers if they are not forwarded
to network stack instead of reallocate them from scratch

Signed-off-by: Lorenzo Bianconi 
---
 drivers/net/wireless/mediatek/mt76/dma.c  | 60 +--
 drivers/net/wireless/mediatek/mt76/mt76.h |  3 ++
 2 files changed, 60 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/dma.c 
b/drivers/net/wireless/mediatek/mt76/dma.c
index 1db163c40dcf..eceadfa3f980 100644
--- a/drivers/net/wireless/mediatek/mt76/dma.c
+++ b/drivers/net/wireless/mediatek/mt76/dma.c
@@ -39,6 +39,15 @@ mt76_dma_alloc_queue(struct mt76_dev *dev, struct mt76_queue 
*q)
if (!q->entry)
return -ENOMEM;
 
+   /* allocate recycle buffer ring */
+   if (q == >q_rx[MT_RXQ_MCU] ||
+   q == >q_rx[MT_RXQ_MAIN]) {
+   size = q->ndesc * sizeof(*q->recycle);
+   q->recycle = devm_kzalloc(dev->dev, size, GFP_KERNEL);
+   if (!q->recycle)
+   return -ENOMEM;
+   }
+
/* clear descriptors */
for (i = 0; i < q->ndesc; i++)
q->desc[i].ctrl = cpu_to_le32(MT_DMA_CTL_DMA_DONE);
@@ -317,6 +326,49 @@ int mt76_dma_tx_queue_skb(struct mt76_dev *dev, struct 
mt76_queue *q,
 }
 EXPORT_SYMBOL_GPL(mt76_dma_tx_queue_skb);
 
+/* caller must hold mt76_queue spinlock */
+static u8 *mt76_dma_get_free_buf(struct mt76_queue *q, bool flush)
+{
+   if (q->recycle[q->rhead] || flush) {
+   u8 *buff = q->recycle[q->rhead];
+
+   q->recycle[q->rhead] = NULL;
+   q->rhead = (q->rhead + 1) % q->ndesc;
+   return buff;
+   }
+
+   return page_frag_alloc(>rx_page, q->buf_size, GFP_ATOMIC);
+}
+
+static void
+mt76_dma_set_recycle_buf(struct mt76_queue *q, u8 *data)
+{
+   spin_lock_bh(>lock);
+   if (!q->recycle[q->rtail]) {
+   q->recycle[q->rtail] = data;
+   q->rtail = (q->rtail + 1) % q->ndesc;
+   } else {
+   skb_free_frag(data);
+   }
+   spin_unlock_bh(>lock);
+}
+
+static void
+mt76_dma_free_recycle_ring(struct mt76_queue *q)
+{
+   u8 *buf;
+
+   spin_lock_bh(>lock);
+   while (true) {
+   buf = mt76_dma_get_free_buf(q, true);
+   if (!buf)
+   break;
+
+   skb_free_frag(buf);
+   }
+   spin_unlock_bh(>lock);
+}
+
 static int
 mt76_dma_rx_fill(struct mt76_dev *dev, struct mt76_queue *q)
 {
@@ -332,7 +384,7 @@ mt76_dma_rx_fill(struct mt76_dev *dev, struct mt76_queue *q)
while (q->queued < q->ndesc - 1) {
struct mt76_queue_buf qbuf;
 
-   buf = page_frag_alloc(>rx_page, q->buf_size, GFP_ATOMIC);
+   buf = mt76_dma_get_free_buf(q, false);
if (!buf)
break;
 
@@ -373,6 +425,8 @@ mt76_dma_rx_cleanup(struct mt76_dev *dev, struct mt76_queue 
*q)
} while (1);
spin_unlock_bh(>lock);
 
+   mt76_dma_free_recycle_ring(q);
+
if (!q->rx_page.va)
return;
 
@@ -438,7 +492,7 @@ mt76_dma_rx_process(struct mt76_dev *dev, struct mt76_queue 
*q, int budget)
dev_kfree_skb(q->rx_head);
q->rx_head = NULL;
 
-   skb_free_frag(data);
+   mt76_dma_set_recycle_buf(q, data);
continue;
}
 
@@ -449,7 +503,7 @@ mt76_dma_rx_process(struct mt76_dev *dev, struct mt76_queue 
*q, int budget)
 
skb = build_skb(data, q->buf_size);
if (!skb) {
-   skb_free_frag(data);
+   mt76_dma_set_recycle_buf(q, data);
continue;
}
skb_reserve(skb, q->buf_offset);
diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h 
b/drivers/net/wireless/mediatek/mt76/mt76.h
index 5cd508a68609..95546c744494 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76.h
@@ -114,6 +114,9 @@ struct mt76_queue {
spinlock_t lock;
struct mt76_queue_entry *entry;
struct mt76_desc *desc;
+   /* recycle ring */
+   u16 rhead, rtail;
+   u8 **recycle;
 
struct list_head swq;
int swq_queued;
-- 
2.19.2



[PATCH 0/2] add rx buffer recycle support to mt76x2e/mt76x0e drivers

2018-12-03 Thread Lorenzo Bianconi
Add the capability to recycle rx buffers if they are not consumed by networking
stack.
This series is based on 'mt76: add size check for additional rx fragments' 
series:
https://patchwork.kernel.org/patch/10709453/

Lorenzo Bianconi (2):
  mt76: dma: do not build skb if reported len does not fit in buf_size
  mt76: dma: add rx buffer recycle support

 drivers/net/wireless/mediatek/mt76/dma.c  | 75 +++
 drivers/net/wireless/mediatek/mt76/mt76.h |  3 +
 2 files changed, 67 insertions(+), 11 deletions(-)

-- 
2.19.2



[PATCH 1/2] mt76: dma: do not build skb if reported len does not fit in buf_size

2018-12-03 Thread Lorenzo Bianconi
Precompute data length in order to avoid to allocate the related
skb data structure if reported length does not fit in queue buf_size

Signed-off-by: Lorenzo Bianconi 
---
 drivers/net/wireless/mediatek/mt76/dma.c | 15 +++
 1 file changed, 7 insertions(+), 8 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/dma.c 
b/drivers/net/wireless/mediatek/mt76/dma.c
index b7fd2e110663..1db163c40dcf 100644
--- a/drivers/net/wireless/mediatek/mt76/dma.c
+++ b/drivers/net/wireless/mediatek/mt76/dma.c
@@ -417,10 +417,9 @@ mt76_add_fragment(struct mt76_dev *dev, struct mt76_queue 
*q, void *data,
 static int
 mt76_dma_rx_process(struct mt76_dev *dev, struct mt76_queue *q, int budget)
 {
+   int len, data_len, done = 0;
struct sk_buff *skb;
unsigned char *data;
-   int len;
-   int done = 0;
bool more;
 
while (done < budget) {
@@ -430,7 +429,12 @@ mt76_dma_rx_process(struct mt76_dev *dev, struct 
mt76_queue *q, int budget)
if (!data)
break;
 
-   if (q->buf_size < len + q->buf_offset) {
+   if (q->rx_head)
+   data_len = q->buf_size;
+   else
+   data_len = SKB_WITH_OVERHEAD(q->buf_size);
+
+   if (data_len < len + q->buf_offset) {
dev_kfree_skb(q->rx_head);
q->rx_head = NULL;
 
@@ -448,12 +452,7 @@ mt76_dma_rx_process(struct mt76_dev *dev, struct 
mt76_queue *q, int budget)
skb_free_frag(data);
continue;
}
-
skb_reserve(skb, q->buf_offset);
-   if (skb->tail + len > skb->end) {
-   dev_kfree_skb(skb);
-   continue;
-   }
 
if (q == >q_rx[MT_RXQ_MCU]) {
u32 *rxfce = (u32 *) skb->cb;
-- 
2.19.2



[PATCH] mt76: usb: do not build the skb if reported len does not fit in buf_size

2018-12-01 Thread Lorenzo Bianconi
Precompute data length in order to avoid to allocate the related
skb data structure if reported length does not fit in queue buf_size

Signed-off-by: Lorenzo Bianconi 
---
 drivers/net/wireless/mediatek/mt76/usb.c | 10 --
 1 file changed, 4 insertions(+), 6 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/usb.c 
b/drivers/net/wireless/mediatek/mt76/usb.c
index b061263453d4..14ff06c5764e 100644
--- a/drivers/net/wireless/mediatek/mt76/usb.c
+++ b/drivers/net/wireless/mediatek/mt76/usb.c
@@ -407,17 +407,15 @@ mt76u_process_rx_entry(struct mt76_dev *dev, struct urb 
*urb)
if (len < 0)
return 0;
 
+   data_len = min_t(int, len, urb->sg[0].length - MT_DMA_HDR_LEN);
+   if (MT_DMA_HDR_LEN + data_len > SKB_WITH_OVERHEAD(q->buf_size))
+   return 0;
+
skb = build_skb(data, q->buf_size);
if (!skb)
return 0;
 
-   data_len = min_t(int, len, urb->sg[0].length - MT_DMA_HDR_LEN);
skb_reserve(skb, MT_DMA_HDR_LEN);
-   if (skb->tail + data_len > skb->end) {
-   dev_kfree_skb(skb);
-   return 1;
-   }
-
__skb_put(skb, data_len);
len -= data_len;
 
-- 
2.19.2



[PATCH] mt76: dma: remove napi from mt76_dma_rx_fill signature

2018-12-01 Thread Lorenzo Bianconi
Remove napi from mt76_dma_rx_fill routine signature since
it is a leftover of a previous implementation and it is no
longer used

Signed-off-by: Lorenzo Bianconi 
---
 drivers/net/wireless/mediatek/mt76/dma.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/dma.c 
b/drivers/net/wireless/mediatek/mt76/dma.c
index e2ba26378575..1e557d16272e 100644
--- a/drivers/net/wireless/mediatek/mt76/dma.c
+++ b/drivers/net/wireless/mediatek/mt76/dma.c
@@ -318,7 +318,7 @@ int mt76_dma_tx_queue_skb(struct mt76_dev *dev, struct 
mt76_queue *q,
 EXPORT_SYMBOL_GPL(mt76_dma_tx_queue_skb);
 
 static int
-mt76_dma_rx_fill(struct mt76_dev *dev, struct mt76_queue *q, bool napi)
+mt76_dma_rx_fill(struct mt76_dev *dev, struct mt76_queue *q)
 {
dma_addr_t addr;
void *buf;
@@ -392,7 +392,7 @@ mt76_dma_rx_reset(struct mt76_dev *dev, enum mt76_rxq_id 
qid)
 
mt76_dma_rx_cleanup(dev, q);
mt76_dma_sync_idx(dev, q);
-   mt76_dma_rx_fill(dev, q, false);
+   mt76_dma_rx_fill(dev, q);
 }
 
 static void
@@ -463,7 +463,7 @@ mt76_dma_rx_process(struct mt76_dev *dev, struct mt76_queue 
*q, int budget)
dev->drv->rx_skb(dev, q - dev->q_rx, skb);
}
 
-   mt76_dma_rx_fill(dev, q, true);
+   mt76_dma_rx_fill(dev, q);
return done;
 }
 
@@ -504,7 +504,7 @@ mt76_dma_init(struct mt76_dev *dev)
for (i = 0; i < ARRAY_SIZE(dev->q_rx); i++) {
netif_napi_add(>napi_dev, >napi[i], mt76_dma_rx_poll,
   64);
-   mt76_dma_rx_fill(dev, >q_rx[i], false);
+   mt76_dma_rx_fill(dev, >q_rx[i]);
skb_queue_head_init(>rx_skb[i]);
napi_enable(>napi[i]);
}
-- 
2.19.2



Re: [RFC 0/5] add XDP support to mt76x2e/mt76x0e drivers

2018-11-29 Thread Lorenzo Bianconi
> Lorenzo Bianconi  writes:
> 
> > On Nov 28, Toke Høiland-Jørgensen wrote:
> >> Lorenzo Bianconi  writes:
> >> 
> >> >> Lorenzo Bianconi  writes:
> >> >> 
> >> >> >> >> > This series is intended as a playground to start 
> >> >> >> >> > experimenting/developing
> >> >> >> >> > with XDP/eBPF over WiFi and collect ideas/concerns about it.
> >> >> >> >> > Introduce XDP support to mt76x2e/mt76x0e drivers. Currently 
> >> >> >> >> > supported
> >> >> >> >> > actions are:
> >> >> >> >> > - XDP_PASS
> >> >> >> >> > - XDP_ABORTED
> >> >> >> >> > - XDP_DROP
> >> >> >> >> > Introduce ndo_bpf mac80211 callback in order to to load a bpf
> >> >> >> >> > program into low level driver XDP rx hook.
> >> >> >> >> > This series has been tested through a simple bpf program 
> >> >> >> >> > (available here:
> >> >> >> >> > https://github.com/LorenzoBianconi/bpf-workspace/tree/master/mt76_xdp_stats)
> >> >> >> >> > used to count frame types received by the device.
> >> >> >> >> > Possible eBPF use cases could be:
> >> >> >> >> > - implement new statistics through bpf maps
> >> >> >> >> > - implement fast packet filtering (e.g in monitor mode)
> >> >> >> >> > - ...
> >> >> >> >
> >> >> >> > Hi Kalle,
> >> >> >> >
> >> >> >> >> 
> >> >> >> >> This is most likely a stupid question, but why do this in the 
> >> >> >> >> driver and
> >> >> >> >> not in mac80211 so that all drivers could benefit from it? I 
> >> >> >> >> guess there
> >> >> >> >> are reasons for that, I just can't figure that out.
> >> >> >> 
> >> >> >> XDP achieves its speedup by running the eBPF program inside the 
> >> >> >> driver
> >> >> >> NAPI loop, before the kernel even touches the data in any other 
> >> >> >> capacity
> >> >> >> (and in particular, before it allocates an SKB). Which kinda means 
> >> >> >> the
> >> >> >> hook needs to be in the driver... Could be a fallback in mac80211,
> >> >> >> though; although we'd have to figure out how that interacts with 
> >> >> >> Generic
> >> >> >> XDP.
> >> >> >> 
> >> >> >> > This is an early stage implementation, at this point I would 
> >> >> >> > collect
> >> >> >> > other people opinions/concerns about using bpf/xdp directly on 
> >> >> >> > 802.11
> >> >> >> > frames.
> >> >> >> 
> >> >> >> Thanks for looking into this!
> >> >> >
> >> >> > Hi Toke,
> >> >> >
> >> >> >> 
> >> >> >> I have two concerns with running XDP on 802.11 frames:
> >> >> >> 
> >> >> >> 1. It makes it more difficult to add other XDP actions (such as
> >> >> >>REDIRECT), as the XDP program would then have to make sure that 
> >> >> >> the
> >> >> >>outer packet headers are removed before, say, redirecting the 
> >> >> >> packet
> >> >> >>out of an ethernet interface. Also, if we do add redirect, we 
> >> >> >> would
> >> >> >>be bypassing mac80211 entirely; to what extent would that mess up
> >> >> >>internal state?
> >> >> >> 
> >> >> >
> >> >> > You are right, my assumption here is the logic/complexity is moved to
> >> >> > the bpf program that needs to take care of all possible issues that
> >> >> > can be introduced. More or less it is the same if a bpf program mess
> >> >> > up with TCP segments on a wired connection, isn't it?
> >> >> 
> >> >> No, I guess not; except here it potentially applies to all packets
> 

Re: [RFC 0/5] add XDP support to mt76x2e/mt76x0e drivers

2018-11-28 Thread Lorenzo Bianconi
On Nov 28, Toke Høiland-Jørgensen wrote:
> Lorenzo Bianconi  writes:
> 
> >> Lorenzo Bianconi  writes:
> >> 
> >> >> >> > This series is intended as a playground to start 
> >> >> >> > experimenting/developing
> >> >> >> > with XDP/eBPF over WiFi and collect ideas/concerns about it.
> >> >> >> > Introduce XDP support to mt76x2e/mt76x0e drivers. Currently 
> >> >> >> > supported
> >> >> >> > actions are:
> >> >> >> > - XDP_PASS
> >> >> >> > - XDP_ABORTED
> >> >> >> > - XDP_DROP
> >> >> >> > Introduce ndo_bpf mac80211 callback in order to to load a bpf
> >> >> >> > program into low level driver XDP rx hook.
> >> >> >> > This series has been tested through a simple bpf program 
> >> >> >> > (available here:
> >> >> >> > https://github.com/LorenzoBianconi/bpf-workspace/tree/master/mt76_xdp_stats)
> >> >> >> > used to count frame types received by the device.
> >> >> >> > Possible eBPF use cases could be:
> >> >> >> > - implement new statistics through bpf maps
> >> >> >> > - implement fast packet filtering (e.g in monitor mode)
> >> >> >> > - ...
> >> >> >
> >> >> > Hi Kalle,
> >> >> >
> >> >> >> 
> >> >> >> This is most likely a stupid question, but why do this in the driver 
> >> >> >> and
> >> >> >> not in mac80211 so that all drivers could benefit from it? I guess 
> >> >> >> there
> >> >> >> are reasons for that, I just can't figure that out.
> >> >> 
> >> >> XDP achieves its speedup by running the eBPF program inside the driver
> >> >> NAPI loop, before the kernel even touches the data in any other capacity
> >> >> (and in particular, before it allocates an SKB). Which kinda means the
> >> >> hook needs to be in the driver... Could be a fallback in mac80211,
> >> >> though; although we'd have to figure out how that interacts with Generic
> >> >> XDP.
> >> >> 
> >> >> > This is an early stage implementation, at this point I would collect
> >> >> > other people opinions/concerns about using bpf/xdp directly on 802.11
> >> >> > frames.
> >> >> 
> >> >> Thanks for looking into this!
> >> >
> >> > Hi Toke,
> >> >
> >> >> 
> >> >> I have two concerns with running XDP on 802.11 frames:
> >> >> 
> >> >> 1. It makes it more difficult to add other XDP actions (such as
> >> >>REDIRECT), as the XDP program would then have to make sure that the
> >> >>outer packet headers are removed before, say, redirecting the packet
> >> >>out of an ethernet interface. Also, if we do add redirect, we would
> >> >>be bypassing mac80211 entirely; to what extent would that mess up
> >> >>internal state?
> >> >> 
> >> >
> >> > You are right, my assumption here is the logic/complexity is moved to
> >> > the bpf program that needs to take care of all possible issues that
> >> > can be introduced. More or less it is the same if a bpf program mess
> >> > up with TCP segments on a wired connection, isn't it?
> >> 
> >> No, I guess not; except here it potentially applies to all packets
> >> (things like BAW tracking), and it is *in addition* to TCP.
> >
> > Yes, here it is a little bit harder, but I was meaning that the bpf program
> > has to be very careful when dropping a packet :)
> 
> Yeah. What kind of filtering were you thinking you would use this for in
> the short term?
> 

When I started working on XDP for mt76 I was thinking about BSSID filtering but
I was looking for a more general solution respect to add that feature in the
driver. Moreover we could use bpf for fast packet filtering when you add an
interface in monitor mode. Nevertheless I guess there could be other use cases 
not
limited to frame filtering. My primary goal with this series is to collect
ideas/concerns on WiFi XDP/eBPF possible uses cases.

Regards,
Lorenzo

> -Toke


Re: [RFC 0/5] add XDP support to mt76x2e/mt76x0e drivers

2018-11-28 Thread Lorenzo Bianconi
> Lorenzo Bianconi  writes:
> 
> >> >> > This series is intended as a playground to start 
> >> >> > experimenting/developing
> >> >> > with XDP/eBPF over WiFi and collect ideas/concerns about it.
> >> >> > Introduce XDP support to mt76x2e/mt76x0e drivers. Currently supported
> >> >> > actions are:
> >> >> > - XDP_PASS
> >> >> > - XDP_ABORTED
> >> >> > - XDP_DROP
> >> >> > Introduce ndo_bpf mac80211 callback in order to to load a bpf
> >> >> > program into low level driver XDP rx hook.
> >> >> > This series has been tested through a simple bpf program (available 
> >> >> > here:
> >> >> > https://github.com/LorenzoBianconi/bpf-workspace/tree/master/mt76_xdp_stats)
> >> >> > used to count frame types received by the device.
> >> >> > Possible eBPF use cases could be:
> >> >> > - implement new statistics through bpf maps
> >> >> > - implement fast packet filtering (e.g in monitor mode)
> >> >> > - ...
> >> >
> >> > Hi Kalle,
> >> >
> >> >> 
> >> >> This is most likely a stupid question, but why do this in the driver and
> >> >> not in mac80211 so that all drivers could benefit from it? I guess there
> >> >> are reasons for that, I just can't figure that out.
> >> 
> >> XDP achieves its speedup by running the eBPF program inside the driver
> >> NAPI loop, before the kernel even touches the data in any other capacity
> >> (and in particular, before it allocates an SKB). Which kinda means the
> >> hook needs to be in the driver... Could be a fallback in mac80211,
> >> though; although we'd have to figure out how that interacts with Generic
> >> XDP.
> >> 
> >> > This is an early stage implementation, at this point I would collect
> >> > other people opinions/concerns about using bpf/xdp directly on 802.11
> >> > frames.
> >> 
> >> Thanks for looking into this!
> >
> > Hi Toke,
> >
> >> 
> >> I have two concerns with running XDP on 802.11 frames:
> >> 
> >> 1. It makes it more difficult to add other XDP actions (such as
> >>REDIRECT), as the XDP program would then have to make sure that the
> >>outer packet headers are removed before, say, redirecting the packet
> >>out of an ethernet interface. Also, if we do add redirect, we would
> >>be bypassing mac80211 entirely; to what extent would that mess up
> >>internal state?
> >> 
> >
> > You are right, my assumption here is the logic/complexity is moved to
> > the bpf program that needs to take care of all possible issues that
> > can be introduced. More or less it is the same if a bpf program mess
> > up with TCP segments on a wired connection, isn't it?
> 
> No, I guess not; except here it potentially applies to all packets
> (things like BAW tracking), and it is *in addition* to TCP.

Yes, here it is a little bit harder, but I was meaning that the bpf program
has to be very careful when dropping a packet :)

> 
> >> 2. UI consistency; suddenly, the user needs to know which kind of
> >>frames to expect, and XDP program reuse becomes more difficult. This
> >>may be unavoidable given the nature of XDP, but some thought needs to
> >>go into this. Especially since we wouldn't necessarily be consistent
> >>between WiFi drivers (there are fullmac devices that remove 802.11
> >>headers before sending up the frame, right?).
> >> 
> >
> > Right, maybe can we have some kind of 'wifi' bpf helpers?
> 
> Yeah, I guess we would at least need helpers to update any internal
> state in mac80211 (such as BAW), or BPF programs wouldn't even be able
> to drop packets without messing things up...
> 

Correct.

Regards,
Lorenzo

> -Toke


Re: [RFC 0/5] add XDP support to mt76x2e/mt76x0e drivers

2018-11-28 Thread Lorenzo Bianconi
> >> > This series is intended as a playground to start experimenting/developing
> >> > with XDP/eBPF over WiFi and collect ideas/concerns about it.
> >> > Introduce XDP support to mt76x2e/mt76x0e drivers. Currently supported
> >> > actions are:
> >> > - XDP_PASS
> >> > - XDP_ABORTED
> >> > - XDP_DROP
> >> > Introduce ndo_bpf mac80211 callback in order to to load a bpf
> >> > program into low level driver XDP rx hook.
> >> > This series has been tested through a simple bpf program (available here:
> >> > https://github.com/LorenzoBianconi/bpf-workspace/tree/master/mt76_xdp_stats)
> >> > used to count frame types received by the device.
> >> > Possible eBPF use cases could be:
> >> > - implement new statistics through bpf maps
> >> > - implement fast packet filtering (e.g in monitor mode)
> >> > - ...
> >
> > Hi Kalle,
> >
> >> 
> >> This is most likely a stupid question, but why do this in the driver and
> >> not in mac80211 so that all drivers could benefit from it? I guess there
> >> are reasons for that, I just can't figure that out.
> 
> XDP achieves its speedup by running the eBPF program inside the driver
> NAPI loop, before the kernel even touches the data in any other capacity
> (and in particular, before it allocates an SKB). Which kinda means the
> hook needs to be in the driver... Could be a fallback in mac80211,
> though; although we'd have to figure out how that interacts with Generic
> XDP.
> 
> > This is an early stage implementation, at this point I would collect
> > other people opinions/concerns about using bpf/xdp directly on 802.11
> > frames.
> 
> Thanks for looking into this!

Hi Toke,

> 
> I have two concerns with running XDP on 802.11 frames:
> 
> 1. It makes it more difficult to add other XDP actions (such as
>REDIRECT), as the XDP program would then have to make sure that the
>outer packet headers are removed before, say, redirecting the packet
>out of an ethernet interface. Also, if we do add redirect, we would
>be bypassing mac80211 entirely; to what extent would that mess up
>internal state?
> 

You are right, my assumption here is the logic/complexity is moved to the bpf
program that needs to take care of all possible issues that can be introduced.
More or less it is the same if a bpf program mess up with TCP segments on a
wired connection, isn't it?

> 2. UI consistency; suddenly, the user needs to know which kind of
>frames to expect, and XDP program reuse becomes more difficult. This
>may be unavoidable given the nature of XDP, but some thought needs to
>go into this. Especially since we wouldn't necessarily be consistent
>between WiFi drivers (there are fullmac devices that remove 802.11
>headers before sending up the frame, right?).
> 

Right, maybe can we have some kind of 'wifi' bpf helpers?

Regards,
Lorenzo

> 
> Adding in Jesper; maybe he has some thoughts on this?
> 
> -Toke


Re: [RFC 0/5] add XDP support to mt76x2e/mt76x0e drivers

2018-11-28 Thread Lorenzo Bianconi
> Lorenzo Bianconi  writes:
> 
> > This series is intended as a playground to start experimenting/developing
> > with XDP/eBPF over WiFi and collect ideas/concerns about it.
> > Introduce XDP support to mt76x2e/mt76x0e drivers. Currently supported
> > actions are:
> > - XDP_PASS
> > - XDP_ABORTED
> > - XDP_DROP
> > Introduce ndo_bpf mac80211 callback in order to to load a bpf
> > program into low level driver XDP rx hook.
> > This series has been tested through a simple bpf program (available here:
> > https://github.com/LorenzoBianconi/bpf-workspace/tree/master/mt76_xdp_stats)
> > used to count frame types received by the device.
> > Possible eBPF use cases could be:
> > - implement new statistics through bpf maps
> > - implement fast packet filtering (e.g in monitor mode)
> > - ...

Hi Kalle,

> 
> This is most likely a stupid question, but why do this in the driver and
> not in mac80211 so that all drivers could benefit from it? I guess there
> are reasons for that, I just can't figure that out.
> 
> -- 
> Kalle Valo

I thought about that possibility (and I think it is definitely valuable) but
I preferred to work as close as possible to the hw running the bpf program
before skb allocation. My primary goal when I started thinking about eBPF over
WiFi was to perform fast packet filtering.
I think these two possibility are not mutually exclusive, we can fall-back to
mac80211 if hw driver does not support XDP.
This is an early stage implementation, at this point I would collect other
people opinions/concerns about using bpf/xdp directly on 802.11 frames.

Regards,
Lorenzo


[RFC 5/5] mt76: add XDP support

2018-11-27 Thread Lorenzo Bianconi
Introduce XDP in mt76 driver. Add mt76_xdp and mt76x02_xdp_setup
routines in order to initialize xdp rx driver hook with the bpf
program received from mac80211.
Introduce the mt76_dma_rx_xdp routine in order to run the attached
bpf program and parse the action result. Currently supported actions
are:
- XDP_PASS
- XDP_ABORTED
- XDP_DROP

Signed-off-by: Lorenzo Bianconi 
---
 drivers/net/wireless/mediatek/mt76/dma.c  | 46 ++
 drivers/net/wireless/mediatek/mt76/mac80211.c | 18 
 drivers/net/wireless/mediatek/mt76/mt76.h |  6 ++
 .../net/wireless/mediatek/mt76/mt76x0/pci.c   |  3 +
 drivers/net/wireless/mediatek/mt76/mt76x02.h  |  3 +
 .../net/wireless/mediatek/mt76/mt76x02_mac.h  |  1 +
 .../net/wireless/mediatek/mt76/mt76x02_mmio.c | 90 +++
 .../net/wireless/mediatek/mt76/mt76x02_util.c | 10 ++-
 .../wireless/mediatek/mt76/mt76x2/pci_init.c  |  2 +
 .../wireless/mediatek/mt76/mt76x2/pci_main.c  |  1 +
 10 files changed, 179 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/mediatek/mt76/dma.c 
b/drivers/net/wireless/mediatek/mt76/dma.c
index efa0eab7cf01..b735849799e3 100644
--- a/drivers/net/wireless/mediatek/mt76/dma.c
+++ b/drivers/net/wireless/mediatek/mt76/dma.c
@@ -15,6 +15,7 @@
  */
 
 #include 
+#include 
 #include "mt76.h"
 #include "dma.h"
 
@@ -421,6 +422,44 @@ mt76_add_fragment(struct mt76_dev *dev, struct mt76_queue 
*q, void *data,
dev->drv->rx_skb(dev, q - dev->q_rx, skb);
 }
 
+static bool
+mt76_dma_rx_xdp(struct mt76_dev *dev, unsigned char *data,
+   int *len)
+{
+   struct page *page = virt_to_head_page(data);
+   struct xdp_buff xdp;
+   u32 action;
+
+   if (!dev->drv->xdp_rxq_info_lookup ||
+   dev->drv->xdp_rxq_info_lookup(dev, data, ) < 0)
+   return false;
+
+   xdp.data_hard_start = page_address(page);
+   xdp.data = (void *)data;
+   xdp_set_data_meta_invalid();
+   xdp.data_end = xdp.data + *len;
+
+   action = bpf_prog_run_xdp(dev->xdp_prog, );
+   /* bpf program chan modify the original frame */
+   *len = xdp.data_end - xdp.data;
+   data = xdp.data;
+
+   switch (action) {
+   case XDP_PASS:
+   return false;
+   default:
+   bpf_warn_invalid_xdp_action(action);
+   /* fall through */
+   case XDP_ABORTED:
+   trace_xdp_exception(xdp.rxq->dev, dev->xdp_prog, action);
+   /* fall through */
+   case XDP_DROP:
+   /* XXX: we can reuse the buffer here */
+   skb_free_frag(data);
+   return true;
+   }
+}
+
 static int
 mt76_dma_rx_process(struct mt76_dev *dev, struct mt76_queue *q, int budget)
 {
@@ -437,6 +476,13 @@ mt76_dma_rx_process(struct mt76_dev *dev, struct 
mt76_queue *q, int budget)
if (!data)
break;
 
+   /* xdp does not support fragmentes frames */
+   if (dev->xdp_prog && !more &&
+   mt76_dma_rx_xdp(dev, data, )) {
+   done++;
+   continue;
+   }
+
if (q->rx_head) {
mt76_add_fragment(dev, q, data, len, more);
continue;
diff --git a/drivers/net/wireless/mediatek/mt76/mac80211.c 
b/drivers/net/wireless/mediatek/mt76/mac80211.c
index b33074cf7e00..387c6bba80ca 100644
--- a/drivers/net/wireless/mediatek/mt76/mac80211.c
+++ b/drivers/net/wireless/mediatek/mt76/mac80211.c
@@ -707,3 +707,21 @@ int mt76_sta_state(struct ieee80211_hw *hw, struct 
ieee80211_vif *vif,
return 0;
 }
 EXPORT_SYMBOL_GPL(mt76_sta_state);
+
+int mt76_xdp(struct ieee80211_hw *hw, struct netdev_bpf *xdp)
+{
+   struct mt76_dev *dev = hw->priv;
+
+   switch (xdp->command) {
+   case XDP_SETUP_PROG:
+   if (!dev->drv->xdp_setup)
+   return -ENOTSUPP;
+   return dev->drv->xdp_setup(dev, xdp->prog);
+   case XDP_QUERY_PROG:
+   xdp->prog_id = dev->xdp_prog ? dev->xdp_prog->aux->id : 0;
+   return 0;
+   default:
+   return -EINVAL;
+   }
+}
+EXPORT_SYMBOL_GPL(mt76_xdp);
diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h 
b/drivers/net/wireless/mediatek/mt76/mt76.h
index 70924792d870..b46e162dbb80 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76.h
@@ -295,6 +295,9 @@ struct mt76_driver_ops {
 
void (*sta_remove)(struct mt76_dev *dev, struct ieee80211_vif *vif,
   struct ieee80211_sta *sta);
+   int (*xdp_setup)(struct mt76_dev *dev, struct bpf_prog *prog);
+   int (*xdp_rxq_info_lookup)(struct mt76_dev *dev, unsigned char *data,
+  struct xdp_buff *xdp);
 };
 
 struct mt76_channel_state {
@

[RFC 1/5] mac80211: introduce ieee80211_xdp handler

2018-11-27 Thread Lorenzo Bianconi
Initialize net_device_ops ndo_bpf callback with ieee80211_xdp routine
in order to load a bpf program into low level driver XDP rx hook

Signed-off-by: Lorenzo Bianconi 
---
 include/net/mac80211.h|  2 ++
 net/mac80211/driver-ops.h | 11 +++
 net/mac80211/iface.c  | 14 ++
 3 files changed, 27 insertions(+)

diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 71985e95d2d9..a91f1733ce43 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -3623,6 +3623,7 @@ enum ieee80211_reconfig_type {
  * skb is always a real frame, head may or may not be an A-MSDU.
  * @get_ftm_responder_stats: Retrieve FTM responder statistics, if available.
  * Statistics should be cumulative, currently no way to reset is provided.
+ * @xdp: main XDP handler
  */
 struct ieee80211_ops {
void (*tx)(struct ieee80211_hw *hw,
@@ -3911,6 +3912,7 @@ struct ieee80211_ops {
int (*get_ftm_responder_stats)(struct ieee80211_hw *hw,
   struct ieee80211_vif *vif,
   struct cfg80211_ftm_responder_stats 
*ftm_stats);
+   int (*xdp)(struct ieee80211_hw *hw, struct netdev_bpf *xdp);
 };
 
 /**
diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h
index 0b1747a2313d..48cad0ae0593 100644
--- a/net/mac80211/driver-ops.h
+++ b/net/mac80211/driver-ops.h
@@ -1278,4 +1278,15 @@ static inline void drv_del_nan_func(struct 
ieee80211_local *local,
trace_drv_return_void(local);
 }
 
+static inline int drv_xdp(struct ieee80211_local *local,
+ struct netdev_bpf *xdp)
+{
+   might_sleep();
+
+   if (!local->ops->xdp)
+   return -EOPNOTSUPP;
+
+   return local->ops->xdp(>hw, xdp);
+}
+
 #endif /* __MAC80211_DRIVER_OPS */
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index 5836ddeac9e3..e21971f7c652 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -1163,6 +1163,19 @@ ieee80211_get_stats64(struct net_device *dev, struct 
rtnl_link_stats64 *stats)
}
 }
 
+static int ieee80211_xdp(struct net_device *dev, struct netdev_bpf *xdp)
+{
+   struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+
+   switch (xdp->command) {
+   case XDP_QUERY_PROG:
+   case XDP_SETUP_PROG:
+   return drv_xdp(sdata->local, xdp);
+   default:
+   return -EINVAL;
+   }
+}
+
 static const struct net_device_ops ieee80211_dataif_ops = {
.ndo_open   = ieee80211_open,
.ndo_stop   = ieee80211_stop,
@@ -1172,6 +1185,7 @@ static const struct net_device_ops ieee80211_dataif_ops = 
{
.ndo_set_mac_address= ieee80211_change_mac,
.ndo_select_queue   = ieee80211_netdev_select_queue,
.ndo_get_stats64= ieee80211_get_stats64,
+   .ndo_bpf= ieee80211_xdp,
 };
 
 static u16 ieee80211_monitor_select_queue(struct net_device *dev,
-- 
2.19.1



[RFC 4/5] mt76: make mt76x02_vif_init return int

2018-11-27 Thread Lorenzo Bianconi
This is a preliminary patch to add xdp support to mt76 driver
since mt76x02_vif_init will be used to xdp_rxq_info data structure
and can return an error code

Signed-off-by: Lorenzo Bianconi 
---
 drivers/net/wireless/mediatek/mt76/mt76x02.h | 4 ++--
 drivers/net/wireless/mediatek/mt76/mt76x02_util.c| 9 +
 drivers/net/wireless/mediatek/mt76/mt76x2/usb_main.c | 3 +--
 3 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02.h 
b/drivers/net/wireless/mediatek/mt76/mt76x02.h
index b1d83dd34204..3922854ffa06 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02.h
@@ -116,8 +116,8 @@ void mt76x02_sta_remove(struct mt76_dev *mdev, struct 
ieee80211_vif *vif,
struct ieee80211_sta *sta);
 
 void mt76x02_config_mac_addr_list(struct mt76x02_dev *dev);
-void mt76x02_vif_init(struct mt76x02_dev *dev, struct ieee80211_vif *vif,
- unsigned int idx);
+int mt76x02_vif_init(struct mt76x02_dev *dev, struct ieee80211_vif *vif,
+unsigned int idx);
 int mt76x02_add_interface(struct ieee80211_hw *hw,
 struct ieee80211_vif *vif);
 void mt76x02_remove_interface(struct ieee80211_hw *hw,
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c 
b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
index 3a70e5bf7d42..87195076cf62 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
@@ -207,8 +207,8 @@ void mt76x02_sta_remove(struct mt76_dev *mdev, struct 
ieee80211_vif *vif,
 }
 EXPORT_SYMBOL_GPL(mt76x02_sta_remove);
 
-void mt76x02_vif_init(struct mt76x02_dev *dev, struct ieee80211_vif *vif,
- unsigned int idx)
+int mt76x02_vif_init(struct mt76x02_dev *dev, struct ieee80211_vif *vif,
+unsigned int idx)
 {
struct mt76x02_vif *mvif = (struct mt76x02_vif *)vif->drv_priv;
struct mt76_txq *mtxq;
@@ -220,6 +220,8 @@ void mt76x02_vif_init(struct mt76x02_dev *dev, struct 
ieee80211_vif *vif,
mtxq->wcid = >group_wcid;
 
mt76_txq_init(>mt76, vif->txq);
+
+   return 0;
 }
 EXPORT_SYMBOL_GPL(mt76x02_vif_init);
 
@@ -248,8 +250,7 @@ mt76x02_add_interface(struct ieee80211_hw *hw, struct 
ieee80211_vif *vif)
if (vif->type == NL80211_IFTYPE_STATION)
idx += 8;
 
-   mt76x02_vif_init(dev, vif, idx);
-   return 0;
+   return mt76x02_vif_init(dev, vif, idx);
 }
 EXPORT_SYMBOL_GPL(mt76x02_add_interface);
 
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/usb_main.c 
b/drivers/net/wireless/mediatek/mt76/mt76x2/usb_main.c
index 2b48cc51a30d..61768c76e5d0 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x2/usb_main.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x2/usb_main.c
@@ -55,8 +55,7 @@ static int mt76x2u_add_interface(struct ieee80211_hw *hw,
if (!ether_addr_equal(dev->mt76.macaddr, vif->addr))
mt76x02_mac_setaddr(dev, vif->addr);
 
-   mt76x02_vif_init(dev, vif, idx);
-   return 0;
+   return mt76x02_vif_init(dev, vif, idx);
 }
 
 static int
-- 
2.19.1



[RFC 3/5] mt76: split mt76_dma_rx_reset in init_rx_reset and complete_rx_reset

2018-11-27 Thread Lorenzo Bianconi
This is a preliminary patch to add XDP support to mt76 driver.
In order to reset the rx dma buffers with a proper buffer_size
(XDP does not support fragmented frames and requires one packet
per memory page) split mt76_dma_rx_reset routine in
mt76_dma_init_rx_reset where we free allocated memory and
mt76_dma_complete_rx_reset used to allocate dma memory with a proper
size according to the working mode (standard or xdp)

Signed-off-by: Lorenzo Bianconi 
---
 drivers/net/wireless/mediatek/mt76/dma.c  | 12 ++--
 drivers/net/wireless/mediatek/mt76/mt76.h |  6 --
 2 files changed, 14 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/dma.c 
b/drivers/net/wireless/mediatek/mt76/dma.c
index e2ba26378575..efa0eab7cf01 100644
--- a/drivers/net/wireless/mediatek/mt76/dma.c
+++ b/drivers/net/wireless/mediatek/mt76/dma.c
@@ -382,7 +382,7 @@ mt76_dma_rx_cleanup(struct mt76_dev *dev, struct mt76_queue 
*q)
 }
 
 static void
-mt76_dma_rx_reset(struct mt76_dev *dev, enum mt76_rxq_id qid)
+mt76_dma_init_rx_reset(struct mt76_dev *dev, enum mt76_rxq_id qid)
 {
struct mt76_queue *q = >q_rx[qid];
int i;
@@ -392,6 +392,13 @@ mt76_dma_rx_reset(struct mt76_dev *dev, enum mt76_rxq_id 
qid)
 
mt76_dma_rx_cleanup(dev, q);
mt76_dma_sync_idx(dev, q);
+}
+
+static void
+mt76_dma_complete_rx_reset(struct mt76_dev *dev, enum mt76_rxq_id qid)
+{
+   struct mt76_queue *q = >q_rx[qid];
+
mt76_dma_rx_fill(dev, q, false);
 }
 
@@ -518,7 +525,8 @@ static const struct mt76_queue_ops mt76_dma_ops = {
.add_buf = mt76_dma_add_buf,
.tx_queue_skb = mt76_dma_tx_queue_skb,
.tx_cleanup = mt76_dma_tx_cleanup,
-   .rx_reset = mt76_dma_rx_reset,
+   .init_rx_reset = mt76_dma_init_rx_reset,
+   .complete_rx_reset = mt76_dma_complete_rx_reset,
.kick = mt76_dma_kick_queue,
 };
 
diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h 
b/drivers/net/wireless/mediatek/mt76/mt76.h
index 5cd508a68609..70924792d870 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76.h
@@ -159,7 +159,8 @@ struct mt76_queue_ops {
void *(*dequeue)(struct mt76_dev *dev, struct mt76_queue *q, bool flush,
 int *len, u32 *info, bool *more);
 
-   void (*rx_reset)(struct mt76_dev *dev, enum mt76_rxq_id qid);
+   void (*init_rx_reset)(struct mt76_dev *dev, enum mt76_rxq_id qid);
+   void (*complete_rx_reset)(struct mt76_dev *dev, enum mt76_rxq_id qid);
 
void (*tx_cleanup)(struct mt76_dev *dev, enum mt76_txq_id qid,
   bool flush);
@@ -552,9 +553,10 @@ static inline u16 mt76_rev(struct mt76_dev *dev)
 #define mt76_init_queues(dev)  
(dev)->mt76.queue_ops->init(&((dev)->mt76))
 #define mt76_queue_alloc(dev, ...) 
(dev)->mt76.queue_ops->alloc(&((dev)->mt76), __VA_ARGS__)
 #define mt76_queue_add_buf(dev, ...)   
(dev)->mt76.queue_ops->add_buf(&((dev)->mt76), __VA_ARGS__)
-#define mt76_queue_rx_reset(dev, ...)  
(dev)->mt76.queue_ops->rx_reset(&((dev)->mt76), __VA_ARGS__)
 #define mt76_queue_tx_cleanup(dev, ...)
(dev)->mt76.queue_ops->tx_cleanup(&((dev)->mt76), __VA_ARGS__)
 #define mt76_queue_kick(dev, ...)  
(dev)->mt76.queue_ops->kick(&((dev)->mt76), __VA_ARGS__)
+#define mt76_queue_init_rx_reset(dev, ...) 
(dev)->mt76.queue_ops->init_rx_reset(&((dev)->mt76), __VA_ARGS__)
+#define mt76_queue_complete_rx_reset(dev, ...) 
(dev)->mt76.queue_ops->complete_rx_reset(&((dev)->mt76), __VA_ARGS__)
 
 static inline struct mt76_channel_state *
 mt76_channel_state(struct mt76_dev *dev, struct ieee80211_channel *c)
-- 
2.19.1



[RFC 2/5] mac80211: introduce ieee80211_vif_to_netdev routine

2018-11-27 Thread Lorenzo Bianconi
Add ieee80211_vif_to_netdev utility routine to get the netdevice
pointer related to ieee80211_vif one even if the sdata has not been
inserted in the driver or running yet. ieee80211_vif_to_netdev
will be used by mt76 to properly configure xdp_rxq_info data
structure adding vif to the driver

Signed-off-by: Lorenzo Bianconi 
---
 include/net/mac80211.h |  2 ++
 net/mac80211/util.c| 12 
 2 files changed, 14 insertions(+)

diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index a91f1733ce43..f2784b36f2e2 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -1603,6 +1603,8 @@ struct ieee80211_vif *wdev_to_ieee80211_vif(struct 
wireless_dev *wdev);
  */
 struct wireless_dev *ieee80211_vif_to_wdev(struct ieee80211_vif *vif);
 
+struct net_device *ieee80211_vif_to_netdev(struct ieee80211_vif *vif);
+
 /**
  * enum ieee80211_key_flags - key flags
  *
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index bec424316ea4..a98293d71818 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -827,6 +827,18 @@ struct wireless_dev *ieee80211_vif_to_wdev(struct 
ieee80211_vif *vif)
 }
 EXPORT_SYMBOL_GPL(ieee80211_vif_to_wdev);
 
+struct net_device *ieee80211_vif_to_netdev(struct ieee80211_vif *vif)
+{
+   struct ieee80211_sub_if_data *sdata;
+
+   if (!vif)
+   return NULL;
+
+   sdata = vif_to_sdata(vif);
+   return sdata->dev;
+}
+EXPORT_SYMBOL_GPL(ieee80211_vif_to_netdev);
+
 /*
  * Nothing should have been stuffed into the workqueue during
  * the suspend->resume cycle. Since we can't check each caller
-- 
2.19.1



[RFC 0/5] add XDP support to mt76x2e/mt76x0e drivers

2018-11-27 Thread Lorenzo Bianconi
This series is intended as a playground to start experimenting/developing
with XDP/eBPF over WiFi and collect ideas/concerns about it.
Introduce XDP support to mt76x2e/mt76x0e drivers. Currently supported
actions are:
- XDP_PASS
- XDP_ABORTED
- XDP_DROP
Introduce ndo_bpf mac80211 callback in order to to load a bpf
program into low level driver XDP rx hook.
This series has been tested through a simple bpf program (available here:
https://github.com/LorenzoBianconi/bpf-workspace/tree/master/mt76_xdp_stats)
used to count frame types received by the device.
Possible eBPF use cases could be:
- implement new statistics through bpf maps
- implement fast packet filtering (e.g in monitor mode)
- ...

Lorenzo Bianconi (5):
  mac80211: introduce ieee80211_xdp handler
  mac80211: introduce ieee80211_vif_to_netdev routine
  mt76: split mt76_dma_rx_reset in init_rx_reset and complete_rx_reset
  mt76: make mt76x02_vif_init return int
  mt76: add XDP support

 drivers/net/wireless/mediatek/mt76/dma.c  | 58 +++-
 drivers/net/wireless/mediatek/mt76/mac80211.c | 18 
 drivers/net/wireless/mediatek/mt76/mt76.h | 12 ++-
 .../net/wireless/mediatek/mt76/mt76x0/pci.c   |  3 +
 drivers/net/wireless/mediatek/mt76/mt76x02.h  |  7 +-
 .../net/wireless/mediatek/mt76/mt76x02_mac.h  |  1 +
 .../net/wireless/mediatek/mt76/mt76x02_mmio.c | 90 +++
 .../net/wireless/mediatek/mt76/mt76x02_util.c | 17 +++-
 .../wireless/mediatek/mt76/mt76x2/pci_init.c  |  2 +
 .../wireless/mediatek/mt76/mt76x2/pci_main.c  |  1 +
 .../wireless/mediatek/mt76/mt76x2/usb_main.c  |  3 +-
 include/net/mac80211.h|  4 +
 net/mac80211/driver-ops.h | 11 +++
 net/mac80211/iface.c  | 14 +++
 net/mac80211/util.c   | 12 +++
 15 files changed, 241 insertions(+), 12 deletions(-)

-- 
2.19.1



Re: [PATCH] mt76: handle protocol error to proper deinit rx_tasklet

2018-11-26 Thread Lorenzo Bianconi
> On Mon, 26 Nov 2018 at 22:31, Lorenzo Bianconi
>  wrote:

[...]

> > Hi Eduardo,
> >
> > AFAIU the -EPROTO error is reported only during device removal or just
> > sporadically
> > (you have never experienced any infinity loop). Is it correct?
> > If so I guess we do not need to develop any intrusive workaround since
> > it is just an annoying log message
> >
>
> It is reported only during device removal as I've been seen with my
> comfast dongle.
> The device removal does not lead to an infinity loop, but there's a
> bouncing around 100 urb failed msgs...
>

Thx for the clarification Eduardo. So is it better to mute all -EPROTO errors
or tolerate these annoying messages during dongle removal? I would prefer the
second choice since would be useful to know if the controller reports
that kind of errors.

Regards,
Lorenzo
> Thanks,
> Eduardo
>
> > Regards,
> > Lorenzo
> >
> > >
> > > Regards,
> > > Eduardo
> > > >
> > > > Thanks
> > > > Stanislaw


Re: [PATCH] mt76: handle protocol error to proper deinit rx_tasklet

2018-11-26 Thread Lorenzo Bianconi
> > > > During removal of usb dongle, noticed many unhandled rx urb
> > > > below. This this patch, make it possible and early completion
> > > > of the rx tasklet.

[...]

> > > Hi Eduardo,
> > >
> > > I think EPROTO is a more general error (it is not strictly related to
> > > device removal)
> > > and it could happen even during normal operation. In this case I guess we 
> > > should
> > > reinsert the urb to usb-core.
> >
> > Some (out of tree) usb host drivers returns EPROTO all the time
> > in some error conditions. On rt2x00 resubmitting urb resulted in
> > infinity loop:
> > https://marc.info/?t=15337512872=1=2
> >
> > Fix I proposed for that was counting EPROTO errors and
> > mark device as removed if 10 of them happened in row:
> > https://marc.info/?l=linux-wireless=153441755529960=2
>
> Thanks for the feedback, guys.
>
> Would it be ok for you if I respin the patch with the suggested
> approach by Stanislaw?

Hi Eduardo,

AFAIU the -EPROTO error is reported only during device removal or just
sporadically
(you have never experienced any infinity loop). Is it correct?
If so I guess we do not need to develop any intrusive workaround since
it is just an annoying log message

Regards,
Lorenzo

>
> Regards,
> Eduardo
> >
> > Thanks
> > Stanislaw


Re: [PATCH] mt76: handle protocol error to proper deinit rx_tasklet

2018-11-24 Thread Lorenzo Bianconi
> During removal of usb dongle, noticed many unhandled rx urb
> below. This this patch, make it possible and early completion
> of the rx tasklet.
>
> mt76x2u 1-3.4.3.1.2:1.0: rx urb failed: -71
> mt76x2u 1-3.4.3.1.2:1.0: rx urb failed: -71
> mt76x2u 1-3.4.3.1.2:1.0: rx urb failed: -71
> mt76x2u 1-3.4.3.1.2:1.0: rx urb failed: -71
> ...

Hi Eduardo,

I think EPROTO is a more general error (it is not strictly related to
device removal)
and it could happen even during normal operation. In this case I guess we should
reinsert the urb to usb-core.

Regards,
Lorenzo

>
> Signed-off-by: Eduardo Abinader 
> ---
>  drivers/net/wireless/mediatek/mt76/usb.c | 1 +
>  1 file changed, 1 insertion(+)
>
> diff --git a/drivers/net/wireless/mediatek/mt76/usb.c 
> b/drivers/net/wireless/mediatek/mt76/usb.c
> index 5f0faf07c346..dc33df9cd155 100644
> --- a/drivers/net/wireless/mediatek/mt76/usb.c
> +++ b/drivers/net/wireless/mediatek/mt76/usb.c
> @@ -446,6 +446,7 @@ static void mt76u_complete_rx(struct urb *urb)
> case -ECONNRESET:
> case -ESHUTDOWN:
> case -ENOENT:
> +   case -EPROTO:
> return;
> default:
> dev_err(dev->dev, "rx urb failed: %d\n", urb->status);
> --
> 2.19.1
>


Re: [PATCH v2 6/7] mt76: mt76x02: remove mt76x02_txq_init

2018-11-16 Thread Lorenzo Bianconi
> Open-coding it simplifies the code
>
> Signed-off-by: Felix Fietkau 
> ---
>  .../net/wireless/mediatek/mt76/mt76x02_mac.c  | 23 ---
>  .../net/wireless/mediatek/mt76/mt76x02_mac.h  |  2 --
>  .../net/wireless/mediatek/mt76/mt76x02_util.c | 15 +---
>  3 files changed, 12 insertions(+), 28 deletions(-)
>

[...]

> @@ -191,8 +191,13 @@ int mt76x02_sta_add(struct ieee80211_hw *hw, struct 
> ieee80211_vif *vif,
> msta->wcid.hw_key_idx = -1;
> mt76x02_mac_wcid_setup(dev, idx, mvif->idx, sta->addr);
> mt76x02_mac_wcid_set_drop(dev, idx, false);
> -   for (i = 0; i < ARRAY_SIZE(sta->txq); i++)
> -   mt76x02_txq_init(dev, sta->txq[i]);
> +   for (i = 0; i < ARRAY_SIZE(sta->txq); i++) {
> +   struct mt76_txq *mtxq;
> +
> +   mtxq = (struct mt76_txq *) sta->txq[i]->drv_priv;

I think sta->txq[i] can be NULL here

> +   mtxq->wcid = >wcid;
> +   mt76_txq_init(>mt76, sta->txq[i]);
> +   }
>
> if (vif->type == NL80211_IFTYPE_AP)
> set_bit(MT_WCID_FLAG_CHECK_PS, >wcid.flags);
> @@ -230,11 +235,15 @@ void mt76x02_vif_init(struct mt76x02_dev *dev, struct 
> ieee80211_vif *vif,
>   unsigned int idx)
>  {
> struct mt76x02_vif *mvif = (struct mt76x02_vif *)vif->drv_priv;
> +   struct mt76_txq *mtxq;
>
> mvif->idx = idx;
> mvif->group_wcid.idx = MT_VIF_WCID(idx);
> mvif->group_wcid.hw_key_idx = -1;
> -   mt76x02_txq_init(dev, vif->txq);
> +   mtxq = (struct mt76_txq *) vif->txq->drv_priv;
> +   mtxq->wcid = >group_wcid;
> +
> +   mt76_txq_init(>mt76, vif->txq);
>  }
>  EXPORT_SYMBOL_GPL(mt76x02_vif_init);
>
> --
> 2.17.0
>


-- 
UNIX is Sexy: who | grep -i blonde | talk; cd ~; wine; talk; touch;
unzip; touch; strip; gasp; finger; gasp; mount; fsck; more; yes; gasp;
umount; make clean; sleep


[PATCH] mt76: fix uninitialized mutex access setting rts threshold

2018-11-09 Thread Lorenzo Bianconi
Fix following crash due to a leftover uninitialized mutex access
in mt76x02_set_rts_threshold routine.

[   55.655884] CPU: 0 PID: 412 Comm: iw Not tainted 4.19.0-rc7+ #2493
[   55.661739] Call Trace:
[   55.662523]  register_lock_class+0x528/0x530
[   55.663806]  __lock_acquire+0x89/0x15d0
[   55.664841]  lock_acquire+0x9f/0x140
[   55.665794]  ? mt76x02_set_rts_threshold+0x28/0x50
[   55.667056]  ? noop_count+0x10/0x10
[   55.667981]  ? mt76x02_set_rts_threshold+0x28/0x50
[   55.669251]  __mutex_lock+0x4a/0x4f0
[   55.670199]  ? mt76x02_set_rts_threshold+0x28/0x50
[   55.671454]  ? find_held_lock+0x2d/0x90
[   55.672450]  ? nl80211_pre_doit+0xf9/0x1a0
[   55.673467]  ? mt76x02_set_rts_threshold+0x28/0x50
[   55.674637]  mt76x02_set_rts_threshold+0x28/0x50
[   55.675773]  ieee80211_set_wiphy_params+0x16d/0x4e0
[   55.676910]  nl80211_set_wiphy+0x72b/0xbc0
[   55.677927]  genl_family_rcv_msg+0x192/0x3a0
[   55.678919]  genl_rcv_msg+0x42/0x89
[   55.679742]  ? genl_family_rcv_msg+0x3a0/0x3a0
[   55.680600]  netlink_rcv_skb+0x38/0x100
[   55.681313]  genl_rcv+0x1f/0x30
[   55.681899]  netlink_unicast+0x16b/0x210
[   55.682628]  netlink_sendmsg+0x1ed/0x390
[   55.683373]  sock_sendmsg+0x31/0x40
[   55.684020]  ___sys_sendmsg+0x23c/0x280
[   55.684736]  ? __handle_mm_fault+0xce8/0x1000
[   55.685445]  ? _raw_spin_unlock+0x1f/0x30
[   55.686059]  ? find_held_lock+0x2d/0x90
[   55.686648]  ? __do_page_fault+0x207/0x440
[   55.687274]  __sys_sendmsg+0x42/0x80
[   55.687825]  do_syscall_64+0x50/0x190
[   55.688410]  entry_SYSCALL_64_after_hwframe+0x49/0xbe
[   55.689174] RIP: 0033:0x7fdeea227ba7
[   55.692157] RSP: 002b:7ffec2395b58 EFLAGS: 0246 ORIG_RAX: 
002e
[   55.693138] RAX: ffda RBX: 0066c350 RCX: 7fdeea227ba7
[   55.694059] RDX:  RSI: 7ffec2395b90 RDI: 0003
[   55.694966] RBP: 00671740 R08: 0002 R09: 
[   55.695773] R10: 0006 R11: 0246 R12: 00671880
[   55.696572] R13: 7ffec2395b90 R14: 7ffec2395e60 R15: 00671880

Fixes: 108a4861ef19 (" mt76: create new mt76x02-lib module for common
mt76x{0,2} code")

Reported-by: lorenzo.trisol...@fluidmesh.com
Reported-by: luca.bi...@fluidmesh.com
Signed-off-by: Lorenzo Bianconi 
---
I will post a fix based on wireless-drivers repo
---
 drivers/net/wireless/mediatek/mt76/mt76x02.h  | 1 -
 drivers/net/wireless/mediatek/mt76/mt76x02_util.c | 4 ++--
 2 files changed, 2 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02.h 
b/drivers/net/wireless/mediatek/mt76/mt76x02.h
index 65daa3d3c289..1d8bb426e772 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02.h
@@ -69,7 +69,6 @@ struct mt76x02_dev {
struct mac_address macaddr_list[8];
 
struct mutex phy_mutex;
-   struct mutex mutex;
 
u8 txdone_seq;
DECLARE_KFIFO_PTR(txstatus_fifo, struct mt76x02_tx_status);
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c 
b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
index 48f2f5382b57..bd0a879f7e7a 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
@@ -481,9 +481,9 @@ int mt76x02_set_rts_threshold(struct ieee80211_hw *hw, u32 
val)
if (val != ~0 && val > 0x)
return -EINVAL;
 
-   mutex_lock(>mutex);
+   mutex_lock(>mt76.mutex);
mt76x02_mac_set_tx_protection(dev, val);
-   mutex_unlock(>mutex);
+   mutex_unlock(>mt76.mutex);
 
return 0;
 }
-- 
2.19.1



Re: [PATCH 2/5] mt76x02: initalize mutli bss mode by default

2018-11-09 Thread Lorenzo Bianconi
> On Fri, Nov 09, 2018 at 02:31:31PM +0100, Lorenzo Bianconi wrote:
> > > 
> > > Anyway I think, to support MAC address change, we should not filter
> > > based on MAC address, but maybe only on BSSID ? 
> > > 
> > > Thanks
> > > Stanislaw
> > 
> > You can create the interface with a given mac address
> > 
> > # iw phy phy0 interface add wlp0s4u1 type managed addr 00:11:22:33:44:55
> 
> I realized I have ancient version of iw :-)
> 
> Ok, so to do not break that we can add it to common function like this:
> 
> + if (vif->type == NL80211_IFTYPE_STATION) {
> + if (idx == 0)
> + mt76x02_mac_init_mbss(dev, vif->addr);
>   idx += 8;
> + }
> 
> Thanks
> Stanislaw
>  

Does this patch break AP + STA configuration (since we are changing 
MT_MAC_ADDR_DW{0,1}
regs with a possible complete different value)? I think (but not 100% sure)
MT_MAC_ADDR_DW is linked to BSSID used.
Maybe it is safer to maintain mt76x2u_add_interface routine since it is just a 
static
function used in mt76x2u module

Regards,
Lorenzo


Re: [PATCH 4/5] mt76x02: minor beaconing init changes

2018-11-09 Thread Lorenzo Bianconi
> On Fri, Nov 09, 2018 at 12:33:32PM +0100, Lorenzo Bianconi wrote:
> > > Disable BEACON timer during init and remove interrupt registers
> > > initalization form generic conde since they are PCIe specific.
> > > 
> > 
> > Since the timer is actually disabled (MT_INT_TIMER_EN set to 0) and
> > we just set the timer timeout here, does it worth to copy/paste
> > the same code?
> 
> As I pointed somwhere else I have some random, not easy to reproduce
> performance drops on MT7610U sta mode, starting when AP mode support
> was added. I'm can not be sure if this is by this setting this
> timer, but I would rather accept slight code duplication, than 
> do something that (even with very low probability) can cause
> troubles and for sure is not necessary.

I am fine with this patch but I do not see how original code can cause issues 
since
MT_INT_TIMER_EN is already set it to 0 (comment mt76_wr(dev, MT_INT_TIMER_EN, 
0) out
in the original code)

Regards,
Lorenzo

> 
> Thanks
> Stanislaw


Re: [PATCH v2] mt76: remove wait argument from mt76x02_mcu_calibrate

2018-11-09 Thread Lorenzo Bianconi
> We always wait for CMD_CALIBRATION_OP mcu message, but wait argument is used
> for do additional MT_MCU_COM_REG0 register operations, which are needed
> for mt76x2e devices and we can use appropriate check instead of wait argument.
> 
> Signed-off-by: Stanislaw Gruszka 
> ---

Reviewed-by: Lorenzo Bianconi 


Re: [PATCH 1/5] mt76x02: correct set bssid for STA

2018-11-09 Thread Lorenzo Bianconi
> On Fri, Nov 09, 2018 at 01:50:51PM +0100, Lorenzo Bianconi wrote:
> > > On 2018-11-09 12:09, Lorenzo Bianconi wrote:
> > > >> Use MT_MAC_APC_BSSID0_H_EN bit to indicatate we are
> > > >> setting BSSID for STA.
> > > >> 
> > > >> Signed-off-by: Stanislaw Gruszka 
> > > >> ---
> > > >>  drivers/net/wireless/mediatek/mt76/mt76x02_mac.c | 12 +---
> > > >>  1 file changed, 9 insertions(+), 3 deletions(-)
> > > >> 
> > > >> diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c 
> > > >> b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
> > > >> index 59b336e34cb5..cfeae5586897 100644
> > > >> --- a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
> > > >> +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
> > > >> @@ -826,10 +826,16 @@ void mt76x02_mac_work(struct work_struct *work)
> > > >>  
> > > >>  void mt76x02_mac_set_bssid(struct mt76x02_dev *dev, u8 idx, const u8 
> > > >> *addr)
> > > >>  {
> > > >> +  u32 bssid_h = FIELD_PREP(MT_MAC_APC_BSSID_H_ADDR,
> > > >> +   get_unaligned_le16(addr + 4));
> > > >> +  u32 bssid_l = get_unaligned_le32(addr);
> > > >> +
> > > >> +  if (idx > 7)
> > > >> +  bssid_h |= MT_MAC_APC_BSSID0_H_EN;
> > > > 
> > > > This bit is to enable APClient mode and it is valid just for register 
> > > > 0x1094
> > > > (MT_MAC_APC_BSSID_{L,h}(0)). Moreover IIRC APClient has been disabled 
> > > > because
> > > > it causes a performance degradation.
> > > The performance degradation was with MAC_ADDR_EXT, not AP-Client.
> > > This patch should be fine.
> > 
> > Ah, now I remember sorry, you are right :)
> > Anyway IIRC MT_MAC_APC_BSSID0_H_EN is just for AP_CLIENT_BSSID0 (at least 
> > for
> > 76x2), for others we need to use BIT(31) but just if APClient is disabled, 
> > right?
> > Moreover BSSID filter is currently disabled (BIT(3) in RX_FILTER_CFG).
> > 
> > # echo 0x1400 > /sys/kernel/debug/ieee80211/phy0/mt76/regidx
> > # cat /sys/kernel/debug/ieee80211/phy0/mt76/regval
> > 0x00017f97
> > 
> > Have you tried to enabled it?
> 
> I didn't try this yet, but I think it should be enabled to support
> mulit BSS and MAC address change. 

I agree we can use multi-BSS for mac filtering in AP mode but my gut feeling in
STA the hw uses the value in MT_MAC_ADDR_DW{0,1} for unicast packet filtering
(BIT(2) in RX_FILTER_CFG). Moreover I think there is a relation between
MT_MAC_ADDR_DW and BSSID values in multiAP mode.

Regards,
Lorenzo

> 
> However I still don't know how to set multiple bssid for STA,
> Use BIT(31) or BIT(16) as indicator or maybe 
> just write BSSID to MT_MAC_APC_BSSID_{H,L} and hardware will
> recognize this is not AP BSSID ?
> 
> Thanks
> Stanislaw


Re: [PATCH 2/5] mt76x02: initalize mutli bss mode by default

2018-11-09 Thread Lorenzo Bianconi
> [root@dhcp-27-155 ~]# iw dev
> phy#1
>   Interface wlan1
>   ifindex 10
>   wdev 0x10001
>   addr 2c:4d:54:cb:d8:04
>   type managed
> [root@dhcp-27-155 ~]# ip link set addres  b0:6e:bf:a5:31:90  wlan1
> [root@dhcp-27-155 ~]# iw dev wlan1 del
> [root@dhcp-27-155 ~]# iw phy phy0 interface  add wlan0 type station
> command failed: No such file or directory (-2)
> [root@dhcp-27-155 ~]# iw phy phy1 interface  add wlan0 type station
> [root@dhcp-27-155 ~]# iw dev 
> phy#1
>   Interface wlan0
>   ifindex 11
>   wdev 0x10002
>   addr 2c:4d:54:cb:d8:04
>   type managed
> [root@dhcp-27-155 ~]# ethtool -i wlan0
> driver: mt76x2u
> version: 4.20.0-rc1+
> firmware-version: 0.0.00-b1
> bus-info: 1-1.2:1.0
> supports-statistics: yes
> supports-test: no
> supports-eeprom-access: no
> supports-register-dump: no
> supports-priv-flags: no
> 
> Anyway I think, to support MAC address change, we should not filter
> based on MAC address, but maybe only on BSSID ? 
> 
> Thanks
> Stanislaw

You can create the interface with a given mac address

# iw phy phy0 interface add wlp0s4u1 type managed addr 00:11:22:33:44:55
# iw dev
phy#0
Interface wlp0s4u1
ifindex 9
wdev 0x2
addr 00:11:22:33:44:55
type managed
txpower 3.00 dBm

# ip link show dev wlp0s4u1
9: wlp0s4u1:  mtu 1500 qdisc noqueue state UP 
mode DORMANT group default qlen 1000
link/ether 00:11:22:33:44:55 brd ff:ff:ff:ff:ff:ff

Regards,
Lorenzo



Re: [PATCH 1/5] mt76x02: correct set bssid for STA

2018-11-09 Thread Lorenzo Bianconi
> On 2018-11-09 12:09, Lorenzo Bianconi wrote:
> >> Use MT_MAC_APC_BSSID0_H_EN bit to indicatate we are
> >> setting BSSID for STA.
> >> 
> >> Signed-off-by: Stanislaw Gruszka 
> >> ---
> >>  drivers/net/wireless/mediatek/mt76/mt76x02_mac.c | 12 +---
> >>  1 file changed, 9 insertions(+), 3 deletions(-)
> >> 
> >> diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c 
> >> b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
> >> index 59b336e34cb5..cfeae5586897 100644
> >> --- a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
> >> +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
> >> @@ -826,10 +826,16 @@ void mt76x02_mac_work(struct work_struct *work)
> >>  
> >>  void mt76x02_mac_set_bssid(struct mt76x02_dev *dev, u8 idx, const u8 
> >> *addr)
> >>  {
> >> +  u32 bssid_h = FIELD_PREP(MT_MAC_APC_BSSID_H_ADDR,
> >> +   get_unaligned_le16(addr + 4));
> >> +  u32 bssid_l = get_unaligned_le32(addr);
> >> +
> >> +  if (idx > 7)
> >> +  bssid_h |= MT_MAC_APC_BSSID0_H_EN;
> > 
> > This bit is to enable APClient mode and it is valid just for register 0x1094
> > (MT_MAC_APC_BSSID_{L,h}(0)). Moreover IIRC APClient has been disabled 
> > because
> > it causes a performance degradation.
> The performance degradation was with MAC_ADDR_EXT, not AP-Client.
> This patch should be fine.

Ah, now I remember sorry, you are right :)
Anyway IIRC MT_MAC_APC_BSSID0_H_EN is just for AP_CLIENT_BSSID0 (at least for
76x2), for others we need to use BIT(31) but just if APClient is disabled, 
right?
Moreover BSSID filter is currently disabled (BIT(3) in RX_FILTER_CFG).

# echo 0x1400 > /sys/kernel/debug/ieee80211/phy0/mt76/regidx
# cat /sys/kernel/debug/ieee80211/phy0/mt76/regval
0x00017f97

Have you tried to enabled it?

Regards,
Lorenzo

> 
> - Felix


Re: [PATCH 4/5] mt76x02: minor beaconing init changes

2018-11-09 Thread Lorenzo Bianconi
> Disable BEACON timer during init and remove interrupt registers
> initalization form generic conde since they are PCIe specific.
> 

Since the timer is actually disabled (MT_INT_TIMER_EN set to 0) and
we just set the timer timeout here, does it worth to copy/paste
the same code?

Regards,
Lorenzo

> Signed-off-by: Stanislaw Gruszka 
> ---
>  drivers/net/wireless/mediatek/mt76/mt76x0/pci.c  |  7 +++
>  drivers/net/wireless/mediatek/mt76/mt76x02_util.c| 11 ---
>  drivers/net/wireless/mediatek/mt76/mt76x2/pci_init.c |  8 
>  3 files changed, 19 insertions(+), 7 deletions(-)
> 


Re: [PATCH 2/5] mt76x02: initalize mutli bss mode by default

2018-11-09 Thread Lorenzo Bianconi
> Configure multi bss mode by default on all devices. That mean we
> use MAC address for MT_MAC_BSSID_DW and use MT_MAC_APC_BSSID
> for configuree bssid for each vif.
> 
> This is separe from beaconing as we can have for example 2 STA vifs,
> so do not mix bssid init and beacon init.
> 
> Signed-off-by: Stanislaw Gruszka 
> ---
>  drivers/net/wireless/mediatek/mt76/mt76x0/eeprom.c   |  2 +-
>  drivers/net/wireless/mediatek/mt76/mt76x02_mac.c | 17 +++--
>  drivers/net/wireless/mediatek/mt76/mt76x02_mac.h |  2 +-
>  drivers/net/wireless/mediatek/mt76/mt76x02_util.c| 13 ++---
>  drivers/net/wireless/mediatek/mt76/mt76x2/pci_init.c |  4 +---
>  drivers/net/wireless/mediatek/mt76/mt76x2/usb_init.c |  2 +-
>  drivers/net/wireless/mediatek/mt76/mt76x2/usb_main.c |  3 ---
>  7 files changed, 21 insertions(+), 22 deletions(-)
> 
> diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/eeprom.c 
> b/drivers/net/wireless/mediatek/mt76/mt76x0/eeprom.c
> index 497e762978cc..5036b61b66f9 100644
> --- a/drivers/net/wireless/mediatek/mt76/mt76x0/eeprom.c
> +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/eeprom.c

[snip]

> diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/usb_init.c 
> b/drivers/net/wireless/mediatek/mt76/mt76x2/usb_init.c
> index de0fbdb02c4d..4fb87deff261 100644
> --- a/drivers/net/wireless/mediatek/mt76/mt76x2/usb_init.c
> +++ b/drivers/net/wireless/mediatek/mt76/mt76x2/usb_init.c
> @@ -189,7 +189,7 @@ int mt76x2u_init_hardware(struct mt76x02_dev *dev)
>   if (err < 0)
>   return err;
>  
> - mt76x02_mac_setaddr(dev, dev->mt76.eeprom.data + MT_EE_MAC_ADDR);
> + mt76x02_mac_init_mbss(dev, dev->mt76.eeprom.data + MT_EE_MAC_ADDR);
>   dev->mt76.rxfilter = mt76_rr(dev, MT_RX_FILTR_CFG);
>  
>   if (!mt76x02_wait_for_txrx_idle(>mt76))
> diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/usb_main.c 
> b/drivers/net/wireless/mediatek/mt76/mt76x2/usb_main.c
> index a9ecc92875ae..977e74091a27 100644
> --- a/drivers/net/wireless/mediatek/mt76/mt76x2/usb_main.c
> +++ b/drivers/net/wireless/mediatek/mt76/mt76x2/usb_main.c
> @@ -52,9 +52,6 @@ static int mt76x2u_add_interface(struct ieee80211_hw *hw,
>   struct mt76x02_dev *dev = hw->priv;
>   unsigned int idx = 8;
>  
> - if (!ether_addr_equal(dev->mt76.macaddr, vif->addr))
> - mt76x02_mac_setaddr(dev, vif->addr);
> -

I think this is a regression since you will able to change device mac address
in this way. Do you agree?

>   mt76x02_vif_init(dev, vif, idx);
>   return 0;
>  }
> -- 
> 1.9.3
> 


Re: [PATCH 3/5] mt76x2u: use common mt76x02_add_interface

2018-11-09 Thread Lorenzo Bianconi
> There is no need anymore to use custom add interface function
> for mt76x02u.
> 
> Signed-off-by: Stanislaw Gruszka 
> ---
>  drivers/net/wireless/mediatek/mt76/mt76x02.h |  2 --
>  drivers/net/wireless/mediatek/mt76/mt76x02_util.c|  6 +++---
>  drivers/net/wireless/mediatek/mt76/mt76x2/usb_main.c | 12 +---
>  3 files changed, 4 insertions(+), 16 deletions(-)
> 
> diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02.h 
> b/drivers/net/wireless/mediatek/mt76/mt76x02.h
> index a8c5fdd903b9..f8e998ef8716 100644
> --- a/drivers/net/wireless/mediatek/mt76/mt76x02.h
> +++ b/drivers/net/wireless/mediatek/mt76/mt76x02.h
> @@ -115,8 +115,6 @@ int mt76x02_sta_add(struct ieee80211_hw *hw, struct 
> ieee80211_vif *vif,
>  int mt76x02_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
> struct ieee80211_sta *sta);
>  
> -void mt76x02_vif_init(struct mt76x02_dev *dev, struct ieee80211_vif *vif,
> -   unsigned int idx);
>  int mt76x02_add_interface(struct ieee80211_hw *hw,
>struct ieee80211_vif *vif);
>  void mt76x02_remove_interface(struct ieee80211_hw *hw,
> diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c 
> b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
> index 2aa3f4b15fd9..dbf9d89dd328 100644
> --- a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
> +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
> @@ -228,8 +228,9 @@ int mt76x02_sta_remove(struct ieee80211_hw *hw, struct 
> ieee80211_vif *vif,
>  }
>  EXPORT_SYMBOL_GPL(mt76x02_sta_remove);
>  
> -void mt76x02_vif_init(struct mt76x02_dev *dev, struct ieee80211_vif *vif,
> -   unsigned int idx)
> +static void
> +mt76x02_vif_init(struct mt76x02_dev *dev, struct ieee80211_vif *vif,
> +  unsigned int idx)
>  {
>   struct mt76x02_vif *mvif = (struct mt76x02_vif *)vif->drv_priv;
>  
> @@ -238,7 +239,6 @@ void mt76x02_vif_init(struct mt76x02_dev *dev, struct 
> ieee80211_vif *vif,
>   mvif->group_wcid.hw_key_idx = -1;
>   mt76x02_txq_init(dev, vif->txq);
>  }
> -EXPORT_SYMBOL_GPL(mt76x02_vif_init);
>  
>  int
>  mt76x02_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
> diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/usb_main.c 
> b/drivers/net/wireless/mediatek/mt76/mt76x2/usb_main.c
> index 977e74091a27..6b51dd749491 100644
> --- a/drivers/net/wireless/mediatek/mt76/mt76x2/usb_main.c
> +++ b/drivers/net/wireless/mediatek/mt76/mt76x2/usb_main.c
> @@ -46,16 +46,6 @@ static void mt76x2u_stop(struct ieee80211_hw *hw)
>   mutex_unlock(>mt76.mutex);
>  }
>  
> -static int mt76x2u_add_interface(struct ieee80211_hw *hw,
> -  struct ieee80211_vif *vif)
> -{
> - struct mt76x02_dev *dev = hw->priv;
> - unsigned int idx = 8;
> -
> - mt76x02_vif_init(dev, vif, idx);
> - return 0;
> -}

This routines seems wrong since here we should have the possibility to change
the device mac address:
https://github.com/nbd168/wireless/blob/mt76/drivers/net/wireless/mediatek/mt76/mt76x2/usb_main.c#L54

and IIRC I have not removed it in:
https://patchwork.kernel.org/patch/10670853/

Regards,
Lorenzo

> -
>  static int
>  mt76x2u_set_channel(struct mt76x02_dev *dev,
>   struct cfg80211_chan_def *chandef)
> @@ -122,7 +112,7 @@ static int mt76x2u_add_interface(struct ieee80211_hw *hw,
>   .tx = mt76x02_tx,
>   .start = mt76x2u_start,
>   .stop = mt76x2u_stop,
> - .add_interface = mt76x2u_add_interface,
> + .add_interface = mt76x02_add_interface,
>   .remove_interface = mt76x02_remove_interface,
>   .sta_add = mt76x02_sta_add,
>   .sta_remove = mt76x02_sta_remove,
> -- 
> 1.9.3
> 


Re: [PATCH 1/5] mt76x02: correct set bssid for STA

2018-11-09 Thread Lorenzo Bianconi
> Use MT_MAC_APC_BSSID0_H_EN bit to indicatate we are
> setting BSSID for STA.
> 
> Signed-off-by: Stanislaw Gruszka 
> ---
>  drivers/net/wireless/mediatek/mt76/mt76x02_mac.c | 12 +---
>  1 file changed, 9 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c 
> b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
> index 59b336e34cb5..cfeae5586897 100644
> --- a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
> +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
> @@ -826,10 +826,16 @@ void mt76x02_mac_work(struct work_struct *work)
>  
>  void mt76x02_mac_set_bssid(struct mt76x02_dev *dev, u8 idx, const u8 *addr)
>  {
> + u32 bssid_h = FIELD_PREP(MT_MAC_APC_BSSID_H_ADDR,
> +  get_unaligned_le16(addr + 4));
> + u32 bssid_l = get_unaligned_le32(addr);
> +
> + if (idx > 7)
> + bssid_h |= MT_MAC_APC_BSSID0_H_EN;

This bit is to enable APClient mode and it is valid just for register 0x1094
(MT_MAC_APC_BSSID_{L,h}(0)). Moreover IIRC APClient has been disabled because
it causes a performance degradation.

> +
>   idx &= 7;
> - mt76_wr(dev, MT_MAC_APC_BSSID_L(idx), get_unaligned_le32(addr));
> - mt76_rmw_field(dev, MT_MAC_APC_BSSID_H(idx), MT_MAC_APC_BSSID_H_ADDR,
> -get_unaligned_le16(addr + 4));
> + mt76_wr(dev, MT_MAC_APC_BSSID_L(idx), bssid_l);
> + mt76_wr(dev, MT_MAC_APC_BSSID_H(idx), bssid_h);
>  }
>  
>  static int
> -- 
> 1.9.3
> 


Re: [RFC/RFT 4/4] mt76x02: set protection according to ht capabilities

2018-11-09 Thread Lorenzo Bianconi
> Use information about protection that mac80211 provide to us.
> Used protection should be part of ht capabilites that either
> remote AP provde to us in STA mode or is set in hostapd.conf
> in ht_capab option.
> 
> Signed-off-by: Stanislaw Gruszka 
> ---
>  drivers/net/wireless/mediatek/mt76/mt76x02_mac.c  | 58 
> +++
>  drivers/net/wireless/mediatek/mt76/mt76x02_mac.h  |  2 +
>  drivers/net/wireless/mediatek/mt76/mt76x02_util.c |  4 ++
>  3 files changed, 64 insertions(+)
> 
> diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c 
> b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
> index 567a7ab47fab..6096efc4119b 100644
> --- a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
> +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
> @@ -753,6 +753,64 @@ void mt76x02_mac_set_rts_thresh(struct mt76x02_dev *dev, 
> u32 val)
>MT_PROT_CFG_CTRL | MT_PROT_CFG_RTS_THRESH, data);
>  }
>  
> +void mt76x02_mac_set_tx_protection(struct mt76x02_dev *dev, bool legacy_prot,
> +int ht_mode)
> +{
> + int mode = ht_mode & IEEE80211_HT_OP_MODE_PROTECTION;
> + bool non_gf = !!(ht_mode & IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT);
> + u32 prot[6];
> + bool ht_rts[4] = {};
> + int i;
> +
> + for (i = 0; i < 6; i++) {

maybe better ARRAY_SIZE() here?

> + prot[i] = mt76_rr(dev, MT_CCK_PROT_CFG + i * 4);
> + if (i >= 2)
> + prot[i] &= ~(MT_PROT_CFG_CTRL | MT_PROT_CFG_RATE);
> + }
> +
> + if (legacy_prot) {
> + prot[1] &= ~MT_PROT_CFG_CTRL;
> + prot[1] |= MT_PROT_CTRL_CTS2SELF;
> +
> + prot[2] |= MT_PROT_RATE_CCK_11;
> + prot[3] |= MT_PROT_RATE_CCK_11;
> + prot[4] |= MT_PROT_RATE_CCK_11;
> + prot[5] |= MT_PROT_RATE_CCK_11;
> + } else {
> + prot[2] |= MT_PROT_RATE_OFDM_24;
> + prot[3] |= MT_PROT_RATE_DUP_OFDM_24;
> + prot[4] |= MT_PROT_RATE_OFDM_24;
> + prot[5] |= MT_PROT_RATE_DUP_OFDM_24;
> + }
> +
> + switch (mode) {
> + case IEEE80211_HT_OP_MODE_PROTECTION_NONE:

I think you can cover it with 'default' case

> + break;
> +
> + case IEEE80211_HT_OP_MODE_PROTECTION_NONMEMBER:
> + ht_rts[0] = ht_rts[1] = ht_rts[2] = ht_rts[3] = true;
> + break;
> +
> + case IEEE80211_HT_OP_MODE_PROTECTION_20MHZ:
> + ht_rts[1] = ht_rts[3] = true;
> + break;
> +
> + case IEEE80211_HT_OP_MODE_PROTECTION_NONHT_MIXED:
> + ht_rts[0] = ht_rts[1] = ht_rts[2] = ht_rts[3] = true;
> + break;

this code is duplicated of 'IEEE80211_HT_OP_MODE_PROTECTION_NONMEMBER'.
maybe better to have:

case IEEE80211_HT_OP_MODE_PROTECTION_NONMEMBER:
case IEEE80211_HT_OP_MODE_PROTECTION_NONHT_MIXED:
ht_rts[0] = ht_rts[1] = ht_rts[2] = ht_rts[3] = true;
break;

> + }
> +
> + if (non_gf)
> + ht_rts[2] = ht_rts[3] = true;
> +
> + for (i = 0; i < 4; i++)

ARRAY_SIZE() here?

> + if (ht_rts[i])
> + prot[i + 2] |= MT_PROT_CTRL_RTS_CTS;
> +
> + for (i = 0; i < 6; i++)

ARRAY_SIZE() here?

> + mt76_wr(dev, MT_CCK_PROT_CFG + i * 4, prot[i]);
> +}
> +
>  void mt76x02_update_channel(struct mt76_dev *mdev)
>  {
>   struct mt76x02_dev *dev = container_of(mdev, struct mt76x02_dev, mt76);
> diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.h 
> b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.h
> index 34da8c600db8..9035397ae081 100644
> --- a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.h
> +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.h
> @@ -197,6 +197,8 @@ void mt76x02_send_tx_status(struct mt76x02_dev *dev,
>   struct mt76x02_tx_status *stat, u8 *update);
>  int mt76x02_mac_process_rx(struct mt76x02_dev *dev, struct sk_buff *skb,
>  void *rxi);
> +void mt76x02_mac_set_tx_protection(struct mt76x02_dev *dev, bool legacy_prot,
> +int ht_mode);
>  void mt76x02_mac_set_rts_thresh(struct mt76x02_dev *dev, u32 val);
>  void mt76x02_mac_setaddr(struct mt76x02_dev *dev, u8 *addr);
>  void mt76x02_mac_write_txwi(struct mt76x02_dev *dev, struct mt76x02_txwi 
> *txwi,
> diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c 
> b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
> index fda67b0923a6..51db4d3dcc13 100644
> --- a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
> +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
> @@ -682,6 +682,10 @@ void mt76x02_bss_info_changed(struct ieee80211_hw *hw,
>   tasklet_enable(>pre_tbtt_tasklet);
>   }
>  
> + if (changed & BSS_CHANGED_HT || changed & BSS_CHANGED_ERP_CTS_PROT)
> + mt76x02_mac_set_tx_protection(dev, info->use_cts_prot,
> +   info->ht_operation_mode);
> 

Re: [RFC/RFT 3/4] mt76x02: do not set protection on set_rts_threshold callback

2018-11-09 Thread Lorenzo Bianconi
> Use set_rts_threshold calback to enable/disable threshold only for
> legacy traffic. RTS/CTS threshold for HT TXOP make make no sense
> to me since used protection (RTS/CTS , CTS-to-self or none)
> should be determined by HT capabilities and applied to any HT
> frames.
> 
> Signed-off-by: Stanislaw Gruszka 
> ---
>  drivers/net/wireless/mediatek/mt76/mt76x02_mac.c  | 16 +---
>  drivers/net/wireless/mediatek/mt76/mt76x02_mac.h  |  2 +-
>  drivers/net/wireless/mediatek/mt76/mt76x02_util.c |  2 +-
>  3 files changed, 3 insertions(+), 17 deletions(-)
> 
> diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c 
> b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
> index 59b336e34cb5..567a7ab47fab 100644
> --- a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
> +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
> @@ -737,7 +737,7 @@ void mt76x02_tx_complete_skb(struct mt76_dev *mdev, 
> struct mt76_queue *q,
>  }
>  EXPORT_SYMBOL_GPL(mt76x02_tx_complete_skb);
>  
> -void mt76x02_mac_set_tx_protection(struct mt76x02_dev *dev, u32 val)
> +void mt76x02_mac_set_rts_thresh(struct mt76x02_dev *dev, u32 val)
>  {
>   u32 data = 0;
>  
> @@ -751,20 +751,6 @@ void mt76x02_mac_set_tx_protection(struct mt76x02_dev 
> *dev, u32 val)
>MT_PROT_CFG_CTRL | MT_PROT_CFG_RTS_THRESH, data);
>   mt76_rmw(dev, MT_OFDM_PROT_CFG,
>MT_PROT_CFG_CTRL | MT_PROT_CFG_RTS_THRESH, data);

Do we need to configure MT_OFDM_PROT_CFG and MT_CCK_PROT_CFG here? (since they
are already configured in 4/4 (mt76x02: set protection according to ht
capabilities))

> - mt76_rmw(dev, MT_MM20_PROT_CFG,
> -  MT_PROT_CFG_CTRL | MT_PROT_CFG_RTS_THRESH, data);
> - mt76_rmw(dev, MT_MM40_PROT_CFG,
> -  MT_PROT_CFG_CTRL | MT_PROT_CFG_RTS_THRESH, data);
> - mt76_rmw(dev, MT_GF20_PROT_CFG,
> -  MT_PROT_CFG_CTRL | MT_PROT_CFG_RTS_THRESH, data);
> - mt76_rmw(dev, MT_GF40_PROT_CFG,
> -  MT_PROT_CFG_CTRL | MT_PROT_CFG_RTS_THRESH, data);
> - mt76_rmw(dev, MT_TX_PROT_CFG6,
> -  MT_PROT_CFG_CTRL | MT_PROT_CFG_RTS_THRESH, data);
> - mt76_rmw(dev, MT_TX_PROT_CFG7,
> -  MT_PROT_CFG_CTRL | MT_PROT_CFG_RTS_THRESH, data);
> - mt76_rmw(dev, MT_TX_PROT_CFG8,
> -  MT_PROT_CFG_CTRL | MT_PROT_CFG_RTS_THRESH, data);

Removing these lines we are no longer able to configure protection for VHT
rates. Do we have an equivalent for them in vht_capab?

Regards,
Lorenzo

>  }


Re: [RFC/RFT 2/4] mt76x02: reserve wcid 0 for global traffic

2018-11-08 Thread Lorenzo Bianconi
> Restore behaviour on mt76x0 before commit  1bb04bb4b838 ("mt76: move
> mt76x02_init_device in mt76x02-lib module"). This will allow to use
> wcid 1 for AP when we work in station mode. It's not clear if this
> is needed, but this is how vendor driver assign wcid's in STA mode.
> This should be harmless for mt76x2.
>
> Signed-off-by: Stanislaw Gruszka 
> ---
>  drivers/net/wireless/mediatek/mt76/mt76x02_util.c | 6 +-
>  1 file changed, 5 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c 
> b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
> index 2be4b527477f..e624397b3d8b 100644
> --- a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
> +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
> @@ -113,7 +113,11 @@ void mt76x02_init_device(struct mt76x02_dev *dev)
> ieee80211_hw_set(hw, SUPPORTS_HT_CCK_RATES);
> ieee80211_hw_set(hw, SUPPORTS_REORDERING_BUFFER);
>
> -   dev->mt76.global_wcid.idx = 255;
> +   /* Reserve WCID 0 for mcast - thanks to this APs WCID will go to
> +* entry no. 1 like it does in the vendor driver.
> +*/
> +   dev->mt76.wcid_mask[0] |= 1;
> +   dev->mt76.global_wcid.idx = 0;
> dev->mt76.global_wcid.hw_key_idx = -1;
> dev->slottime = 9;
>

Does it make any difference in AP mode? What about using 0 instead of
255 for global_wcid.idx?

Regards,
Lorenzo

> --
> 1.9.3
>


Re: [RFC/RFT 1/4] mt76x02: configure basic rates and fallback on STA mode

2018-11-08 Thread Lorenzo Bianconi
> For STA mode configure legacy basic rates according to info
> mac80211 provides to us, as well as follback registers, which
> are setup in vendor driver under CONFIG_STA_SUPPORT .
> For LB_FBK_CFG1 register use values from vendor driver, which
> are different for mt76x0 and mt76x2 .
>
> Signed-off-by: Stanislaw Gruszka 
> ---
>  drivers/net/wireless/mediatek/mt76/mt76x02_util.c | 12 
>  1 file changed, 12 insertions(+)
>
> diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c 
> b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
> index 87ce6a51fb05..2be4b527477f 100644
> --- a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
> +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
> @@ -678,6 +678,18 @@ void mt76x02_bss_info_changed(struct ieee80211_hw *hw,
> tasklet_enable(>pre_tbtt_tasklet);
> }
>
> +   if (changed & BSS_CHANGED_BASIC_RATES &&
> +   vif->type == NL80211_IFTYPE_STATION) {
> +   mt76_wr(dev, MT_LEGACY_BASIC_RATE, info->basic_rates);
> +   mt76_wr(dev, MT_VHT_HT_FBK_CFG0, 0x65432100);
> +   mt76_wr(dev, MT_VHT_HT_FBK_CFG1, 0xedcba980);
> +   mt76_wr(dev, MT_LG_FBK_CFG0, 0xedcba988);
> +   if (is_mt76x2(dev))
> +   mt76_wr(dev, MT_LG_FBK_CFG1, 0x87872100);
> +   else
> +   mt76_wr(dev, MT_LG_FBK_CFG1, 0x00872100);
> +   }
> +

since these values are constant, why not put them init_vals?

Regards,
Lorenzo

> if (changed & BSS_CHANGED_BEACON_INT) {
> mt76_rmw_field(dev, MT_BEACON_TIME_CFG,
>MT_BEACON_TIME_CFG_INTVAL,
> --
> 1.9.3
>


Re: [PATCH] mt76: introduce mt76x02_config_mac_addr_list routine

2018-11-07 Thread Lorenzo Bianconi
> On Tue, Nov 06, 2018 at 11:49:12PM +0100, Lorenzo Bianconi wrote:
> > Add mt76x02_config_mac_addr_list routine in order to set
> > the mac address list supported by the driver. Initialize
> > wiphy->addresses/n_addresses for mt76x0e driver
> > 
> > Signed-off-by: Lorenzo Bianconi 
> > ---
> >  .../net/wireless/mediatek/mt76/mt76x0/init.c  |  2 ++
> >  drivers/net/wireless/mediatek/mt76/mt76x02.h  |  1 +
> >  .../net/wireless/mediatek/mt76/mt76x02_util.c | 22 +++
> >  .../wireless/mediatek/mt76/mt76x2/pci_init.c  | 17 ++
> >  4 files changed, 27 insertions(+), 15 deletions(-)
> > 
> > diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/init.c 
> > b/drivers/net/wireless/mediatek/mt76/mt76x0/init.c
> > index e74d476eca24..87b575fe1c74 100644
> > --- a/drivers/net/wireless/mediatek/mt76/mt76x0/init.c
> > +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/init.c
> > @@ -289,6 +289,8 @@ int mt76x0_register_device(struct mt76x02_dev *dev)
> > int ret;
> >  
> > mt76x02_init_device(dev);
> > +   mt76x02_config_mac_addr_list(dev);
> > +
> 
> Does this work for USB devices ?

Hi Stanislaw,

for usb devices we have just one interface so it does not make any difference I
guess.

Regards,
Lorenzo

> 
> Thanks
> Stanislaw


[PATCH] mt76x0: pci: enable VHT rates in IBSS mode

2018-11-06 Thread Lorenzo Bianconi
Enable VHT tx rates in ad-hoc mode for mt76x0e driver.

Signed-off-by: Lorenzo Bianconi 
---
This patch is based on top of 'mt76: introduce mt76x02_config_mac_addr_list
routine'
https://patchwork.kernel.org/patch/10671591/
---
 drivers/net/wireless/mediatek/mt76/mt76x02_util.c| 2 ++
 drivers/net/wireless/mediatek/mt76/mt76x2/pci_init.c | 3 ---
 2 files changed, 2 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c 
b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
index a52db63c3c68..48f2f5382b57 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
@@ -105,6 +105,8 @@ void mt76x02_init_device(struct mt76x02_dev *dev)
BIT(NL80211_IFTYPE_MESH_POINT) |
 #endif
BIT(NL80211_IFTYPE_ADHOC);
+
+   wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_VHT_IBSS);
}
 
hw->sta_data_size = sizeof(struct mt76x02_sta);
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/pci_init.c 
b/drivers/net/wireless/mediatek/mt76/mt76x2/pci_init.c
index 80b4e11ea28e..843dda261cf8 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x2/pci_init.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x2/pci_init.c
@@ -388,8 +388,6 @@ static void mt76x2_led_set_brightness(struct led_classdev 
*led_cdev,
 
 int mt76x2_register_device(struct mt76x02_dev *dev)
 {
-   struct ieee80211_hw *hw = mt76_hw(dev);
-   struct wiphy *wiphy = hw->wiphy;
int ret;
 
INIT_DELAYED_WORK(>cal_work, mt76x2_phy_calibrate);
@@ -401,7 +399,6 @@ int mt76x2_register_device(struct mt76x02_dev *dev)
return ret;
 
mt76x02_config_mac_addr_list(dev);
-   wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_VHT_IBSS);
 
/* init led callbacks */
dev->mt76.led_cdev.brightness_set = mt76x2_led_set_brightness;
-- 
2.19.1



[PATCH] mt76: introduce mt76x02_config_mac_addr_list routine

2018-11-06 Thread Lorenzo Bianconi
Add mt76x02_config_mac_addr_list routine in order to set
the mac address list supported by the driver. Initialize
wiphy->addresses/n_addresses for mt76x0e driver

Signed-off-by: Lorenzo Bianconi 
---
 .../net/wireless/mediatek/mt76/mt76x0/init.c  |  2 ++
 drivers/net/wireless/mediatek/mt76/mt76x02.h  |  1 +
 .../net/wireless/mediatek/mt76/mt76x02_util.c | 22 +++
 .../wireless/mediatek/mt76/mt76x2/pci_init.c  | 17 ++
 4 files changed, 27 insertions(+), 15 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/init.c 
b/drivers/net/wireless/mediatek/mt76/mt76x0/init.c
index e74d476eca24..87b575fe1c74 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x0/init.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x0/init.c
@@ -289,6 +289,8 @@ int mt76x0_register_device(struct mt76x02_dev *dev)
int ret;
 
mt76x02_init_device(dev);
+   mt76x02_config_mac_addr_list(dev);
+
ret = mt76_register_device(>mt76, true, mt76x02_rates,
   ARRAY_SIZE(mt76x02_rates));
if (ret)
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02.h 
b/drivers/net/wireless/mediatek/mt76/mt76x02.h
index a8c5fdd903b9..65daa3d3c289 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02.h
@@ -115,6 +115,7 @@ int mt76x02_sta_add(struct ieee80211_hw *hw, struct 
ieee80211_vif *vif,
 int mt76x02_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
  struct ieee80211_sta *sta);
 
+void mt76x02_config_mac_addr_list(struct mt76x02_dev *dev);
 void mt76x02_vif_init(struct mt76x02_dev *dev, struct ieee80211_vif *vif,
  unsigned int idx);
 int mt76x02_add_interface(struct ieee80211_hw *hw,
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c 
b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
index 87ce6a51fb05..a52db63c3c68 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
@@ -700,4 +700,26 @@ void mt76x02_bss_info_changed(struct ieee80211_hw *hw,
 }
 EXPORT_SYMBOL_GPL(mt76x02_bss_info_changed);
 
+void mt76x02_config_mac_addr_list(struct mt76x02_dev *dev)
+{
+   struct ieee80211_hw *hw = mt76_hw(dev);
+   struct wiphy *wiphy = hw->wiphy;
+   int i;
+
+   for (i = 0; i < ARRAY_SIZE(dev->macaddr_list); i++) {
+   u8 *addr = dev->macaddr_list[i].addr;
+
+   memcpy(addr, dev->mt76.macaddr, ETH_ALEN);
+
+   if (!i)
+   continue;
+
+   addr[0] |= BIT(1);
+   addr[0] ^= ((i - 1) << 2);
+   }
+   wiphy->addresses = dev->macaddr_list;
+   wiphy->n_addresses = ARRAY_SIZE(dev->macaddr_list);
+}
+EXPORT_SYMBOL_GPL(mt76x02_config_mac_addr_list);
+
 MODULE_LICENSE("Dual BSD/GPL");
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/pci_init.c 
b/drivers/net/wireless/mediatek/mt76/mt76x2/pci_init.c
index 076b7479ba99..80b4e11ea28e 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x2/pci_init.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x2/pci_init.c
@@ -390,7 +390,7 @@ int mt76x2_register_device(struct mt76x02_dev *dev)
 {
struct ieee80211_hw *hw = mt76_hw(dev);
struct wiphy *wiphy = hw->wiphy;
-   int i, ret;
+   int ret;
 
INIT_DELAYED_WORK(>cal_work, mt76x2_phy_calibrate);
 
@@ -400,20 +400,7 @@ int mt76x2_register_device(struct mt76x02_dev *dev)
if (ret)
return ret;
 
-   for (i = 0; i < ARRAY_SIZE(dev->macaddr_list); i++) {
-   u8 *addr = dev->macaddr_list[i].addr;
-
-   memcpy(addr, dev->mt76.macaddr, ETH_ALEN);
-
-   if (!i)
-   continue;
-
-   addr[0] |= BIT(1);
-   addr[0] ^= ((i - 1) << 2);
-   }
-   wiphy->addresses = dev->macaddr_list;
-   wiphy->n_addresses = ARRAY_SIZE(dev->macaddr_list);
-
+   mt76x02_config_mac_addr_list(dev);
wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_VHT_IBSS);
 
/* init led callbacks */
-- 
2.19.1



[PATCH 2/4] mt76x2u: phy: run phy_channel_calibrate after channel switch

2018-11-06 Thread Lorenzo Bianconi
Perform channel calibration after each channel switch and not only after
connection establishment since NetworkManager perform multiple frequency
scanning if RSSI in lower a given threshold

Signed-off-by: Lorenzo Bianconi 
---
 .../wireless/mediatek/mt76/mt76x2/mt76x2u.h|  1 -
 .../wireless/mediatek/mt76/mt76x2/usb_main.c   |  5 -
 .../wireless/mediatek/mt76/mt76x2/usb_phy.c| 18 +++---
 3 files changed, 15 insertions(+), 9 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/mt76x2u.h 
b/drivers/net/wireless/mediatek/mt76/mt76x2/mt76x2u.h
index 833974de5c80..0b0075411b34 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x2/mt76x2u.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76x2/mt76x2u.h
@@ -43,7 +43,6 @@ int mt76x2u_mac_stop(struct mt76x02_dev *dev);
 int mt76x2u_phy_set_channel(struct mt76x02_dev *dev,
struct cfg80211_chan_def *chandef);
 void mt76x2u_phy_calibrate(struct work_struct *work);
-void mt76x2u_phy_channel_calibrate(struct mt76x02_dev *dev);
 
 void mt76x2u_mcu_complete_urb(struct urb *urb);
 int mt76x2u_mcu_init(struct mt76x02_dev *dev);
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/usb_main.c 
b/drivers/net/wireless/mediatek/mt76/mt76x2/usb_main.c
index c2e0a43082e5..cad99715997e 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x2/usb_main.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x2/usb_main.c
@@ -91,11 +91,6 @@ mt76x2u_bss_info_changed(struct ieee80211_hw *hw, struct 
ieee80211_vif *vif,
 
mutex_lock(>mt76.mutex);
 
-   if (changed & BSS_CHANGED_ASSOC) {
-   mt76x2u_phy_channel_calibrate(dev);
-   mt76x2_apply_gain_adj(dev);
-   }
-
if (changed & BSS_CHANGED_BSSID) {
mt76_wr(dev, MT_MAC_BSSID_DW0,
get_unaligned_le32(info->bssid));
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/usb_phy.c 
b/drivers/net/wireless/mediatek/mt76/mt76x2/usb_phy.c
index 24e292e895b6..a64268e8db42 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x2/usb_phy.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x2/usb_phy.c
@@ -18,15 +18,20 @@
 #include "eeprom.h"
 #include "../mt76x02_phy.h"
 
-void mt76x2u_phy_channel_calibrate(struct mt76x02_dev *dev)
+static void
+mt76x2u_phy_channel_calibrate(struct mt76x02_dev *dev, bool mac_stopped)
 {
struct ieee80211_channel *chan = dev->mt76.chandef.chan;
bool is_5ghz = chan->band == NL80211_BAND_5GHZ;
 
+   if (dev->cal.channel_cal_done)
+   return;
+
if (mt76x2_channel_silent(dev))
return;
 
-   mt76x2u_mac_stop(dev);
+   if (!mac_stopped)
+   mt76x2u_mac_stop(dev);
 
if (is_5ghz)
mt76x02_mcu_calibrate(dev, MCU_CAL_LC, 0, false);
@@ -37,7 +42,11 @@ void mt76x2u_phy_channel_calibrate(struct mt76x02_dev *dev)
mt76x02_mcu_calibrate(dev, MCU_CAL_TEMP_SENSOR, 0, false);
mt76x02_mcu_calibrate(dev, MCU_CAL_TX_SHAPING, 0, false);
 
-   mt76x2u_mac_resume(dev);
+   if (!mac_stopped)
+   mt76x2u_mac_resume(dev);
+   mt76x2_apply_gain_adj(dev);
+
+   dev->cal.channel_cal_done = true;
 }
 
 void mt76x2u_phy_calibrate(struct work_struct *work)
@@ -45,6 +54,7 @@ void mt76x2u_phy_calibrate(struct work_struct *work)
struct mt76x02_dev *dev;
 
dev = container_of(work, struct mt76x02_dev, cal_work.work);
+   mt76x2u_phy_channel_calibrate(dev, false);
mt76x2_phy_tssi_compensate(dev, false);
mt76x2_phy_update_channel_gain(dev);
 
@@ -165,7 +175,9 @@ int mt76x2u_phy_set_channel(struct mt76x02_dev *dev,
if (scan)
return 0;
 
+   mt76x2u_phy_channel_calibrate(dev, true);
mt76x02_init_agc_gain(dev);
+
if (mt76x2_tssi_enabled(dev)) {
/* init default values for temp compensation */
mt76_rmw_field(dev, MT_TX_ALC_CFG_1, MT_TX_ALC_CFG_1_TEMP_COMP,
-- 
2.17.2



[PATCH 4/4] mt76x2u: init: remove mt76x2u_init_beacon_offsets routine

2018-11-06 Thread Lorenzo Bianconi
Remove mt76x2u_init_beacon_offsets routine since the driver supports
just STA mode

Signed-off-by: Lorenzo Bianconi 
---
 drivers/net/wireless/mediatek/mt76/mt76x2/usb_init.c | 10 --
 1 file changed, 10 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/usb_init.c 
b/drivers/net/wireless/mediatek/mt76/mt76x2/usb_init.c
index 8b280a4ea792..de0fbdb02c4d 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x2/usb_init.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x2/usb_init.c
@@ -156,14 +156,6 @@ struct mt76x02_dev *mt76x2u_alloc_device(struct device 
*pdev)
return dev;
 }
 
-static void mt76x2u_init_beacon_offsets(struct mt76x02_dev *dev)
-{
-   mt76_wr(dev, MT_BCN_OFFSET(0), 0x18100800);
-   mt76_wr(dev, MT_BCN_OFFSET(1), 0x38302820);
-   mt76_wr(dev, MT_BCN_OFFSET(2), 0x58504840);
-   mt76_wr(dev, MT_BCN_OFFSET(3), 0x78706860);
-}
-
 int mt76x2u_init_hardware(struct mt76x02_dev *dev)
 {
int i, k, err;
@@ -200,8 +192,6 @@ int mt76x2u_init_hardware(struct mt76x02_dev *dev)
mt76x02_mac_setaddr(dev, dev->mt76.eeprom.data + MT_EE_MAC_ADDR);
dev->mt76.rxfilter = mt76_rr(dev, MT_RX_FILTR_CFG);
 
-   mt76x2u_init_beacon_offsets(dev);
-
if (!mt76x02_wait_for_txrx_idle(>mt76))
return -ETIMEDOUT;
 
-- 
2.17.2



[PATCH 1/4] mt76x2u: phy: add TX_SHAPING calibration

2018-11-06 Thread Lorenzo Bianconi
Add MCU_CAL_TX_SHAPING calibration in mt76x2u_phy_channel_calibrate
routine since now mt76x2 and mt76x2u driver run the same firmware

Signed-off-by: Lorenzo Bianconi 
---
 drivers/net/wireless/mediatek/mt76/mt76x2/usb_phy.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/usb_phy.c 
b/drivers/net/wireless/mediatek/mt76/mt76x2/usb_phy.c
index 8011c261c658..24e292e895b6 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x2/usb_phy.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x2/usb_phy.c
@@ -35,6 +35,7 @@ void mt76x2u_phy_channel_calibrate(struct mt76x02_dev *dev)
mt76x02_mcu_calibrate(dev, MCU_CAL_TXIQ, is_5ghz, false);
mt76x02_mcu_calibrate(dev, MCU_CAL_RXIQC_FI, is_5ghz, false);
mt76x02_mcu_calibrate(dev, MCU_CAL_TEMP_SENSOR, 0, false);
+   mt76x02_mcu_calibrate(dev, MCU_CAL_TX_SHAPING, 0, false);
 
mt76x2u_mac_resume(dev);
 }
-- 
2.17.2



[PATCH 3/4] mt76x2u: main: use mt76x02_bss_info_changed utility routine

2018-11-06 Thread Lorenzo Bianconi
Initialize bss_info_changed mac80211 callback to
mt76x02_bss_info_changed utility routine and remove duplicated code.
Use 8 as WCID index for sta interface

Signed-off-by: Lorenzo Bianconi 
---
 .../wireless/mediatek/mt76/mt76x2/usb_main.c  | 23 +++
 1 file changed, 3 insertions(+), 20 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/usb_main.c 
b/drivers/net/wireless/mediatek/mt76/mt76x2/usb_main.c
index cad99715997e..a9ecc92875ae 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x2/usb_main.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x2/usb_main.c
@@ -50,11 +50,12 @@ static int mt76x2u_add_interface(struct ieee80211_hw *hw,
 struct ieee80211_vif *vif)
 {
struct mt76x02_dev *dev = hw->priv;
+   unsigned int idx = 8;
 
if (!ether_addr_equal(dev->mt76.macaddr, vif->addr))
mt76x02_mac_setaddr(dev, vif->addr);
 
-   mt76x02_vif_init(dev, vif, 0);
+   mt76x02_vif_init(dev, vif, idx);
return 0;
 }
 
@@ -83,24 +84,6 @@ mt76x2u_set_channel(struct mt76x02_dev *dev,
return err;
 }
 
-static void
-mt76x2u_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
-struct ieee80211_bss_conf *info, u32 changed)
-{
-   struct mt76x02_dev *dev = hw->priv;
-
-   mutex_lock(>mt76.mutex);
-
-   if (changed & BSS_CHANGED_BSSID) {
-   mt76_wr(dev, MT_MAC_BSSID_DW0,
-   get_unaligned_le32(info->bssid));
-   mt76_wr(dev, MT_MAC_BSSID_DW1,
-   get_unaligned_le16(info->bssid + 4));
-   }
-
-   mutex_unlock(>mt76.mutex);
-}
-
 static int
 mt76x2u_config(struct ieee80211_hw *hw, u32 changed)
 {
@@ -150,7 +133,7 @@ const struct ieee80211_ops mt76x2u_ops = {
.ampdu_action = mt76x02_ampdu_action,
.config = mt76x2u_config,
.wake_tx_queue = mt76_wake_tx_queue,
-   .bss_info_changed = mt76x2u_bss_info_changed,
+   .bss_info_changed = mt76x02_bss_info_changed,
.configure_filter = mt76x02_configure_filter,
.conf_tx = mt76x02_conf_tx,
.sw_scan_start = mt76x02_sw_scan,
-- 
2.17.2



[PATCH 0/4] unify drv_bss_info_changed between mt76x0u and mt76x2u

2018-11-06 Thread Lorenzo Bianconi
Perform channel calibration after each channel switch and not only after
connection establishment.
Enable MCU_CAL_TX_SHAPING phy calibration.
Moreover remove remove beacon offset configuration since the driver
supports just client mode

Lorenzo Bianconi (4):
  mt76x2u: phy: add TX_SHAPING calibration
  mt76x2u: phy: run phy_channel_calibrate after channel switch
  mt76x2u: main: use mt76x02_bss_info_changed utility routine
  mt76x2u: init: remove mt76x2u_init_beacon_offsets routine

 .../wireless/mediatek/mt76/mt76x2/mt76x2u.h   |  1 -
 .../wireless/mediatek/mt76/mt76x2/usb_init.c  | 10 ---
 .../wireless/mediatek/mt76/mt76x2/usb_main.c  | 28 ++-
 .../wireless/mediatek/mt76/mt76x2/usb_phy.c   | 19 +++--
 4 files changed, 19 insertions(+), 39 deletions(-)

-- 
2.17.2



[PATCH v2] mt76: fix building without CONFIG_LEDS_CLASS

2018-11-05 Thread Lorenzo Bianconi
From: Arnd Bergmann 

When CONFIG_LEDS_CLASS is disabled, or it is a loadable module while
mt76 is built-in, we run into a link error:

drivers/net/wireless/mediatek/mt76/mac80211.o: In function 
`mt76_register_device':
mac80211.c:(.text+0xb78): relocation truncated to fit: R_AARCH64_CALL26 against 
undefined symbol `devm_of_led_classdev_register'

We don't really need a hard dependency here as the driver can presumably
work just fine without LEDs, so this follows the iwlwifi example and
adds a separate Kconfig option for the LED support, this will be available
whenever it will link, and otherwise the respective code gets left out from
the driver object.

Fixes: 17f1de56df05 ("mt76: add common code shared between multiple chipsets")
Signed-off-by: Arnd Bergmann 
Signed-off-by: Lorenzo Bianconi 
---
Changes since v1:
- rebased on top of wireless-drivers repository
---
 drivers/net/wireless/mediatek/mt76/Kconfig   | 6 ++
 drivers/net/wireless/mediatek/mt76/mac80211.c| 8 +---
 drivers/net/wireless/mediatek/mt76/mt76x2/pci_init.c | 6 --
 3 files changed, 15 insertions(+), 5 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/Kconfig 
b/drivers/net/wireless/mediatek/mt76/Kconfig
index 0ccbcd7e887d..c30d8f5bbf2a 100644
--- a/drivers/net/wireless/mediatek/mt76/Kconfig
+++ b/drivers/net/wireless/mediatek/mt76/Kconfig
@@ -1,6 +1,12 @@
 config MT76_CORE
tristate
 
+config MT76_LEDS
+   bool
+   depends on MT76_CORE
+   depends on LEDS_CLASS=y || MT76_CORE=LEDS_CLASS
+   default y
+
 config MT76_USB
tristate
depends on MT76_CORE
diff --git a/drivers/net/wireless/mediatek/mt76/mac80211.c 
b/drivers/net/wireless/mediatek/mt76/mac80211.c
index 2a699e8b79bf..7d219ff2d480 100644
--- a/drivers/net/wireless/mediatek/mt76/mac80211.c
+++ b/drivers/net/wireless/mediatek/mt76/mac80211.c
@@ -345,9 +345,11 @@ int mt76_register_device(struct mt76_dev *dev, bool vht,
mt76_check_sband(dev, NL80211_BAND_2GHZ);
mt76_check_sband(dev, NL80211_BAND_5GHZ);
 
-   ret = mt76_led_init(dev);
-   if (ret)
-   return ret;
+   if (IS_ENABLED(CONFIG_MT76_LEDS)) {
+   ret = mt76_led_init(dev);
+   if (ret)
+   return ret;
+   }
 
return ieee80211_register_hw(hw);
 }
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/pci_init.c 
b/drivers/net/wireless/mediatek/mt76/mt76x2/pci_init.c
index 3824290b219d..fd125722d1fb 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x2/pci_init.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x2/pci_init.c
@@ -507,8 +507,10 @@ int mt76x2_register_device(struct mt76x02_dev *dev)
mt76x2_dfs_init_detector(dev);
 
/* init led callbacks */
-   dev->mt76.led_cdev.brightness_set = mt76x2_led_set_brightness;
-   dev->mt76.led_cdev.blink_set = mt76x2_led_set_blink;
+   if (IS_ENABLED(CONFIG_MT76_LEDS)) {
+   dev->mt76.led_cdev.brightness_set = mt76x2_led_set_brightness;
+   dev->mt76.led_cdev.blink_set = mt76x2_led_set_blink;
+   }
 
ret = mt76_register_device(>mt76, true, mt76x02_rates,
   ARRAY_SIZE(mt76x02_rates));
-- 
2.17.2



[PATCH] mt76x0: dfs: fix IBI_R11 configuration on non-radar channels

2018-11-04 Thread Lorenzo Bianconi
Fix IBI_R11 configuration on non-radar channels for mt76x0e
driver. This patch improve system stability under heavy load.
Moreover use IBI_R11 name and remove magic numbers for
0x212c register

Fixes: 0c3b3abc9251 ("mt76x0: pci: add DFS support")
Signed-off-by: Lorenzo Bianconi 
---
 drivers/net/wireless/mediatek/mt76/mt76x02_dfs.c | 8 ++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_dfs.c 
b/drivers/net/wireless/mediatek/mt76/mt76x02_dfs.c
index 527e530d480a..054609c634a2 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_dfs.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_dfs.c
@@ -799,7 +799,7 @@ static void mt76x02_dfs_set_bbp_params(struct mt76x02_dev 
*dev)
 
/* enable detection*/
mt76_wr(dev, MT_BBP(DFS, 0), MT_DFS_CH_EN << 16);
-   mt76_wr(dev, 0x212c, 0x0c350001);
+   mt76_wr(dev, MT_BBP(IBI, 11), 0x0c350001);
 }
 
 void mt76x02_phy_dfs_adjust_agc(struct mt76x02_dev *dev)
@@ -850,7 +850,11 @@ void mt76x02_dfs_init_params(struct mt76x02_dev *dev)
mt76_wr(dev, MT_BBP(DFS, 0), 0);
/* clear detector status */
mt76_wr(dev, MT_BBP(DFS, 1), 0xf);
-   mt76_wr(dev, 0x212c, 0);
+   if (mt76_chip(>mt76) == 0x7610 ||
+   mt76_chip(>mt76) == 0x7630)
+   mt76_wr(dev, MT_BBP(IBI, 11), 0xfde8081);
+   else
+   mt76_wr(dev, MT_BBP(IBI, 11), 0);
 
mt76x02_irq_disable(dev, MT_INT_GPTIMER);
mt76_rmw_field(dev, MT_INT_TIMER_EN,
-- 
2.19.1



[PATCH 3/5] ath9k: dynack: check da->enabled first in sampling routines

2018-11-02 Thread Lorenzo Bianconi
Check da->enabled flag first in ath_dynack_sample_tx_ts and
ath_dynack_sample_ack_ts routines in order to avoid useless
processing

Tested-by: Koen Vandeputte 
Signed-off-by: Lorenzo Bianconi 
---
 drivers/net/wireless/ath/ath9k/dynack.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/dynack.c 
b/drivers/net/wireless/ath/ath9k/dynack.c
index 5c969d833825..5c3b32f4e61b 100644
--- a/drivers/net/wireless/ath/ath9k/dynack.c
+++ b/drivers/net/wireless/ath/ath9k/dynack.c
@@ -178,7 +178,7 @@ void ath_dynack_sample_tx_ts(struct ath_hw *ah, struct 
sk_buff *skb,
u32 dur = ts->duration;
u8 ridx;
 
-   if ((info->flags & IEEE80211_TX_CTL_NO_ACK) || !da->enabled)
+   if (!da->enabled || (info->flags & IEEE80211_TX_CTL_NO_ACK))
return;
 
spin_lock_bh(>qlock);
@@ -251,7 +251,7 @@ void ath_dynack_sample_ack_ts(struct ath_hw *ah, struct 
sk_buff *skb,
struct ath_common *common = ath9k_hw_common(ah);
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
 
-   if (!ath_dynack_bssidmask(ah, hdr->addr1) || !da->enabled)
+   if (!da->enabled || !ath_dynack_bssidmask(ah, hdr->addr1))
return;
 
spin_lock_bh(>qlock);
-- 
2.19.1



[PATCH 0/5] fix ath9k dynack in ad-hoc mode

2018-11-02 Thread Lorenzo Bianconi
Add properly support for dynack in ibss mode. Moreover
allow acktimeout ewma estimation to converge faster
to the correct value during 'late ack' phase.
This series has been tested on devices mounted on offshore
high-voltage stations connected through ~24Km link

Lorenzo Bianconi (5):
  ath9k: dynack: use authentication messages for 'late' ack
  ath9k: dynack: move debug log after buffer increments
  ath9k: dynack: check da->enabled first in sampling routines
  ath9k: dynack: make ewma estimation faster
  ath9k: dynack: remove 'experimental' tag

 drivers/net/wireless/ath/ath9k/Kconfig  |  2 +-
 drivers/net/wireless/ath/ath9k/ath9k.h  |  2 +-
 drivers/net/wireless/ath/ath9k/dynack.c | 61 +++--
 drivers/net/wireless/ath/ath9k/dynack.h |  6 ++-
 drivers/net/wireless/ath/ath9k/xmit.c   |  5 +-
 5 files changed, 46 insertions(+), 30 deletions(-)

-- 
2.19.1



[PATCH 4/5] ath9k: dynack: make ewma estimation faster

2018-11-02 Thread Lorenzo Bianconi
In order to make propagation time estimation faster,
use current sample as ewma output value during 'late ack'
tracking

Tested-by: Koen Vandeputte 
Signed-off-by: Lorenzo Bianconi 
---
 drivers/net/wireless/ath/ath9k/ath9k.h  |  2 +-
 drivers/net/wireless/ath/ath9k/dynack.c | 28 ++---
 drivers/net/wireless/ath/ath9k/dynack.h |  6 --
 drivers/net/wireless/ath/ath9k/xmit.c   |  5 +++--
 4 files changed, 29 insertions(+), 12 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h 
b/drivers/net/wireless/ath/ath9k/ath9k.h
index 21ba20981a80..0fca44e91a71 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -272,7 +272,7 @@ struct ath_node {
 #endif
u8 key_idx[4];
 
-   u32 ackto;
+   int ackto;
struct list_head list;
 };
 
diff --git a/drivers/net/wireless/ath/ath9k/dynack.c 
b/drivers/net/wireless/ath/ath9k/dynack.c
index 5c3b32f4e61b..f112fa5b2eac 100644
--- a/drivers/net/wireless/ath/ath9k/dynack.c
+++ b/drivers/net/wireless/ath/ath9k/dynack.c
@@ -29,9 +29,13 @@
  * ath_dynack_ewma - EWMA (Exponentially Weighted Moving Average) calculation
  *
  */
-static inline u32 ath_dynack_ewma(u32 old, u32 new)
+static inline int ath_dynack_ewma(int old, int new)
 {
-   return (new * (EWMA_DIV - EWMA_LEVEL) + old * EWMA_LEVEL) / EWMA_DIV;
+   if (old > 0)
+   return (new * (EWMA_DIV - EWMA_LEVEL) +
+   old * EWMA_LEVEL) / EWMA_DIV;
+   else
+   return new;
 }
 
 /**
@@ -82,10 +86,10 @@ static inline bool ath_dynack_bssidmask(struct ath_hw *ah, 
const u8 *mac)
  */
 static void ath_dynack_compute_ackto(struct ath_hw *ah)
 {
-   struct ath_node *an;
-   u32 to = 0;
-   struct ath_dynack *da = >dynack;
struct ath_common *common = ath9k_hw_common(ah);
+   struct ath_dynack *da = >dynack;
+   struct ath_node *an;
+   int to = 0;
 
list_for_each_entry(an, >nodes, list)
if (an->ackto > to)
@@ -144,7 +148,8 @@ static void ath_dynack_compute_to(struct ath_hw *ah)
an->ackto = ath_dynack_ewma(an->ackto,
ackto);
ath_dbg(ath9k_hw_common(ah), DYNACK,
-   "%pM to %u\n", dst, an->ackto);
+   "%pM to %d [%u]\n", dst,
+   an->ackto, ackto);
if (time_is_before_jiffies(da->lto)) {
ath_dynack_compute_ackto(ah);
da->lto = jiffies + COMPUTE_TO;
@@ -166,10 +171,12 @@ static void ath_dynack_compute_to(struct ath_hw *ah)
  * @ah: ath hw
  * @skb: socket buffer
  * @ts: tx status info
+ * @sta: station pointer
  *
  */
 void ath_dynack_sample_tx_ts(struct ath_hw *ah, struct sk_buff *skb,
-struct ath_tx_status *ts)
+struct ath_tx_status *ts,
+struct ieee80211_sta *sta)
 {
struct ieee80211_hdr *hdr;
struct ath_dynack *da = >dynack;
@@ -191,9 +198,16 @@ void ath_dynack_sample_tx_ts(struct ath_hw *ah, struct 
sk_buff *skb,
ieee80211_is_assoc_resp(hdr->frame_control) ||
ieee80211_is_auth(hdr->frame_control)) {
ath_dbg(common, DYNACK, "late ack\n");
+
ath9k_hw_setslottime(ah, (LATEACK_TO - 3) / 2);
ath9k_hw_set_ack_timeout(ah, LATEACK_TO);
ath9k_hw_set_cts_timeout(ah, LATEACK_TO);
+   if (sta) {
+   struct ath_node *an;
+
+   an = (struct ath_node *)sta->drv_priv;
+   an->ackto = -1;
+   }
da->lto = jiffies + LATEACK_DELAY;
}
 
diff --git a/drivers/net/wireless/ath/ath9k/dynack.h 
b/drivers/net/wireless/ath/ath9k/dynack.h
index 6d7bef976742..cf60224d40df 100644
--- a/drivers/net/wireless/ath/ath9k/dynack.h
+++ b/drivers/net/wireless/ath/ath9k/dynack.h
@@ -86,7 +86,8 @@ void ath_dynack_node_deinit(struct ath_hw *ah, struct 
ath_node *an);
 void ath_dynack_init(struct ath_hw *ah);
 void ath_dynack_sample_ack_ts(struct ath_hw *ah, struct sk_buff *skb, u32 ts);
 void ath_dynack_sample_tx_ts(struct ath_hw *ah, struct sk_buff *skb,
-struct ath_tx_status *ts);
+struct ath_tx_status *ts,
+struct ieee80211_sta *sta);
 #else
 static inline void ath_dynack_init(struct ath_hw *ah) {}
 static inline void ath_dynack_node_init(struct ath_hw 

[PATCH 5/5] ath9k: dynack: remove 'experimental' tag

2018-11-02 Thread Lorenzo Bianconi
Remove experimental tag from dynack Kconfig entry since it has
been tested on outdoor 25Km links

Tested-by: Koen Vandeputte 
Signed-off-by: Lorenzo Bianconi 
---
 drivers/net/wireless/ath/ath9k/Kconfig | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/wireless/ath/ath9k/Kconfig 
b/drivers/net/wireless/ath/ath9k/Kconfig
index 1f3523019509..ceca23a851d5 100644
--- a/drivers/net/wireless/ath/ath9k/Kconfig
+++ b/drivers/net/wireless/ath/ath9k/Kconfig
@@ -116,7 +116,7 @@ config ATH9K_DFS_CERTIFIED
  except increase code size.
 
 config ATH9K_DYNACK
-   bool "Atheros ath9k ACK timeout estimation algorithm (EXPERIMENTAL)"
+   bool "Atheros ath9k ACK timeout estimation algorithm"
depends on ATH9K
default n
---help---
-- 
2.19.1



[PATCH 2/5] ath9k: dynack: move debug log after buffer increments

2018-11-02 Thread Lorenzo Bianconi
Move debug log in ath_dynack_sample_tx_ts and ath_dynack_sample_ack_ts
after timestamp buffer head/tail increments in order to make debugging
more user friendly

Tested-by: Koen Vandeputte 
Signed-off-by: Lorenzo Bianconi 
---
 drivers/net/wireless/ath/ath9k/dynack.c | 26 -
 1 file changed, 12 insertions(+), 14 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/dynack.c 
b/drivers/net/wireless/ath/ath9k/dynack.c
index cc0dc966c512..5c969d833825 100644
--- a/drivers/net/wireless/ath/ath9k/dynack.c
+++ b/drivers/net/wireless/ath/ath9k/dynack.c
@@ -171,11 +171,12 @@ static void ath_dynack_compute_to(struct ath_hw *ah)
 void ath_dynack_sample_tx_ts(struct ath_hw *ah, struct sk_buff *skb,
 struct ath_tx_status *ts)
 {
-   u8 ridx;
struct ieee80211_hdr *hdr;
struct ath_dynack *da = >dynack;
struct ath_common *common = ath9k_hw_common(ah);
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+   u32 dur = ts->duration;
+   u8 ridx;
 
if ((info->flags & IEEE80211_TX_CTL_NO_ACK) || !da->enabled)
return;
@@ -203,14 +204,13 @@ void ath_dynack_sample_tx_ts(struct ath_hw *ah, struct 
sk_buff *skb,
ridx = ts->ts_rateindex;
 
da->st_rbf.ts[da->st_rbf.t_rb].tstamp = ts->ts_tstamp;
-   da->st_rbf.ts[da->st_rbf.t_rb].dur = ts->duration;
ether_addr_copy(da->st_rbf.addr[da->st_rbf.t_rb].h_dest, hdr->addr1);
ether_addr_copy(da->st_rbf.addr[da->st_rbf.t_rb].h_src, hdr->addr2);
 
if (!(info->status.rates[ridx].flags & IEEE80211_TX_RC_MCS)) {
-   u32 phy, sifs;
const struct ieee80211_rate *rate;
struct ieee80211_tx_rate *rates = info->status.rates;
+   u32 phy;
 
rate = >sbands[info->band].bitrates[rates[ridx].idx];
if (info->band == NL80211_BAND_2GHZ &&
@@ -219,19 +219,18 @@ void ath_dynack_sample_tx_ts(struct ath_hw *ah, struct 
sk_buff *skb,
else
phy = WLAN_RC_PHY_OFDM;
 
-   sifs = ath_dynack_get_sifs(ah, phy);
-   da->st_rbf.ts[da->st_rbf.t_rb].dur -= sifs;
+   dur -= ath_dynack_get_sifs(ah, phy);
}
-
-   ath_dbg(common, DYNACK, "{%pM} tx sample %u [dur %u][h %u-t %u]\n",
-   hdr->addr1, da->st_rbf.ts[da->st_rbf.t_rb].tstamp,
-   da->st_rbf.ts[da->st_rbf.t_rb].dur, da->st_rbf.h_rb,
-   (da->st_rbf.t_rb + 1) % ATH_DYN_BUF);
+   da->st_rbf.ts[da->st_rbf.t_rb].dur = dur;
 
INCR(da->st_rbf.t_rb, ATH_DYN_BUF);
if (da->st_rbf.t_rb == da->st_rbf.h_rb)
INCR(da->st_rbf.h_rb, ATH_DYN_BUF);
 
+   ath_dbg(common, DYNACK, "{%pM} tx sample %u [dur %u][h %u-t %u]\n",
+   hdr->addr1, ts->ts_tstamp, dur, da->st_rbf.h_rb,
+   da->st_rbf.t_rb);
+
ath_dynack_compute_to(ah);
 
spin_unlock_bh(>qlock);
@@ -258,14 +257,13 @@ void ath_dynack_sample_ack_ts(struct ath_hw *ah, struct 
sk_buff *skb,
spin_lock_bh(>qlock);
da->ack_rbf.tstamp[da->ack_rbf.t_rb] = ts;
 
-   ath_dbg(common, DYNACK, "rx sample %u [h %u-t %u]\n",
-   da->ack_rbf.tstamp[da->ack_rbf.t_rb],
-   da->ack_rbf.h_rb, (da->ack_rbf.t_rb + 1) % ATH_DYN_BUF);
-
INCR(da->ack_rbf.t_rb, ATH_DYN_BUF);
if (da->ack_rbf.t_rb == da->ack_rbf.h_rb)
INCR(da->ack_rbf.h_rb, ATH_DYN_BUF);
 
+   ath_dbg(common, DYNACK, "rx sample %u [h %u-t %u]\n",
+   ts, da->ack_rbf.h_rb, da->ack_rbf.t_rb);
+
ath_dynack_compute_to(ah);
 
spin_unlock_bh(>qlock);
-- 
2.19.1



[PATCH 1/5] ath9k: dynack: use authentication messages for 'late' ack

2018-11-02 Thread Lorenzo Bianconi
In order to properly support dynack in ad-hoc mode running
wpa_supplicant, take into account authentication frames for
'late ack' detection. This patch has been tested on devices
mounted on offshore high-voltage stations connected through
~24Km link

Reported-by: Koen Vandeputte 
Tested-by: Koen Vandeputte 
Signed-off-by: Lorenzo Bianconi 
---
 drivers/net/wireless/ath/ath9k/dynack.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/ath/ath9k/dynack.c 
b/drivers/net/wireless/ath/ath9k/dynack.c
index 7334c9b09e82..cc0dc966c512 100644
--- a/drivers/net/wireless/ath/ath9k/dynack.c
+++ b/drivers/net/wireless/ath/ath9k/dynack.c
@@ -187,7 +187,8 @@ void ath_dynack_sample_tx_ts(struct ath_hw *ah, struct 
sk_buff *skb,
/* late ACK */
if (ts->ts_status & ATH9K_TXERR_XRETRY) {
if (ieee80211_is_assoc_req(hdr->frame_control) ||
-   ieee80211_is_assoc_resp(hdr->frame_control)) {
+   ieee80211_is_assoc_resp(hdr->frame_control) ||
+   ieee80211_is_auth(hdr->frame_control)) {
ath_dbg(common, DYNACK, "late ack\n");
ath9k_hw_setslottime(ah, (LATEACK_TO - 3) / 2);
ath9k_hw_set_ack_timeout(ah, LATEACK_TO);
-- 
2.19.1



Re: [PATCH 2/3] mt76x0: phy: introduce tssi calibration support

2018-11-02 Thread Lorenzo Bianconi
> (cc Mediatek.com engineers)
> 
> On Mon, Oct 29, 2018 at 10:31:24PM +0100, Lorenzo Bianconi wrote:
> > Run mt76x0 tssi calibration process if enabled in eeprom data.
> > Perform calibration procedure every 4s
> 
> I just checked the Mediatek vendor drivers for both MT7610E (at
> github https://github.com/i80s/mtk-sources ) and GPL relesed MT7610U driver
> are compiled without MT76x0_TSSI_CAL_COMPENSATION define.
> So seems TSSI compensation is not used or tested in vendor driver.

During the tests I carried out, TSSI calibration is disabled on my mt7610e
device (it runs temperature calibration) but it is enabled on my mt7610u
dongle and it seems to work properly.
Anyway more light on this topic from mtk folks is definitely very useful.

Regards,
Lorenzo

> 
> Perhaps Cheng-Hao Luo and Ryder Lee at Mediatek could clarify if this
> code is needed and is correct.
> 
> Thanks
> Stanislaw
> 
> 


Re: [PATCH] mt76: fix building without CONFIG_LEDS_CLASS

2018-11-02 Thread Lorenzo Bianconi
> Lorenzo Bianconi  writes:
> 
> > From: Arnd Bergmann 
> >
> > When CONFIG_LEDS_CLASS is disabled, or it is a loadable module while
> > mt76 is built-in, we run into a link error:
> >
> > drivers/net/wireless/mediatek/mt76/mac80211.o: In function 
> > `mt76_register_device':
> > mac80211.c:(.text+0xb78): relocation truncated to fit: R_AARCH64_CALL26 
> > against undefined symbol `devm_of_led_classdev_register'
> >
> > We don't really need a hard dependency here as the driver can presumably
> > work just fine without LEDs, so this follows the iwlwifi example and
> > adds a separate Kconfig option for the LED support, this will be available
> > whenever it will link, and otherwise the respective code gets left out from
> > the driver object.
> >
> > Fixes: 17f1de56df05 ("mt76: add common code shared between multiple 
> > chipsets")
> > Signed-off-by: Arnd Bergmann 
> > Signed-off-by: Lorenzo Bianconi 
> 
> Should this go to 4.20? A linker error is pretty bad, even though I
> think this is few months old issue already.

 I guess so. The patch is based on top of Felix's repository so it apply with a
 'fuzz' on net-next/wireless-drivers-next but the patch is ok. Do I need to
 resend or it is ok?

 Regards,
 Lorenzo

> 
> And are conflicts with -next version of mt76 likely?
> 
> -- 
> Kalle Valo


[PATCH] mt76: fix building without CONFIG_LEDS_CLASS

2018-11-02 Thread Lorenzo Bianconi
From: Arnd Bergmann 

When CONFIG_LEDS_CLASS is disabled, or it is a loadable module while
mt76 is built-in, we run into a link error:

drivers/net/wireless/mediatek/mt76/mac80211.o: In function 
`mt76_register_device':
mac80211.c:(.text+0xb78): relocation truncated to fit: R_AARCH64_CALL26 against 
undefined symbol `devm_of_led_classdev_register'

We don't really need a hard dependency here as the driver can presumably
work just fine without LEDs, so this follows the iwlwifi example and
adds a separate Kconfig option for the LED support, this will be available
whenever it will link, and otherwise the respective code gets left out from
the driver object.

Fixes: 17f1de56df05 ("mt76: add common code shared between multiple chipsets")
Signed-off-by: Arnd Bergmann 
Signed-off-by: Lorenzo Bianconi 
---
 drivers/net/wireless/mediatek/mt76/Kconfig   | 6 ++
 drivers/net/wireless/mediatek/mt76/mac80211.c| 8 +---
 drivers/net/wireless/mediatek/mt76/mt76x2/pci_init.c | 6 --
 3 files changed, 15 insertions(+), 5 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/Kconfig 
b/drivers/net/wireless/mediatek/mt76/Kconfig
index 0ccbcd7e887d..c30d8f5bbf2a 100644
--- a/drivers/net/wireless/mediatek/mt76/Kconfig
+++ b/drivers/net/wireless/mediatek/mt76/Kconfig
@@ -1,6 +1,12 @@
 config MT76_CORE
tristate
 
+config MT76_LEDS
+   bool
+   depends on MT76_CORE
+   depends on LEDS_CLASS=y || MT76_CORE=LEDS_CLASS
+   default y
+
 config MT76_USB
tristate
depends on MT76_CORE
diff --git a/drivers/net/wireless/mediatek/mt76/mac80211.c 
b/drivers/net/wireless/mediatek/mt76/mac80211.c
index 2a699e8b79bf..7d219ff2d480 100644
--- a/drivers/net/wireless/mediatek/mt76/mac80211.c
+++ b/drivers/net/wireless/mediatek/mt76/mac80211.c
@@ -345,9 +345,11 @@ int mt76_register_device(struct mt76_dev *dev, bool vht,
mt76_check_sband(dev, NL80211_BAND_2GHZ);
mt76_check_sband(dev, NL80211_BAND_5GHZ);
 
-   ret = mt76_led_init(dev);
-   if (ret)
-   return ret;
+   if (IS_ENABLED(CONFIG_MT76_LEDS)) {
+   ret = mt76_led_init(dev);
+   if (ret)
+   return ret;
+   }
 
return ieee80211_register_hw(hw);
 }
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/pci_init.c 
b/drivers/net/wireless/mediatek/mt76/mt76x2/pci_init.c
index 7b53b2be28c2..b6f1efb7daa8 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x2/pci_init.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x2/pci_init.c
@@ -417,8 +417,10 @@ int mt76x2_register_device(struct mt76x02_dev *dev)
wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_VHT_IBSS);
 
/* init led callbacks */
-   dev->mt76.led_cdev.brightness_set = mt76x2_led_set_brightness;
-   dev->mt76.led_cdev.blink_set = mt76x2_led_set_blink;
+   if (IS_ENABLED(CONFIG_MT76_LEDS)) {
+   dev->mt76.led_cdev.brightness_set = mt76x2_led_set_brightness;
+   dev->mt76.led_cdev.blink_set = mt76x2_led_set_blink;
+   }
 
ret = mt76_register_device(>mt76, true, mt76x02_rates,
   ARRAY_SIZE(mt76x02_rates));
-- 
2.17.2



Re: [PATCH] mt76x0: do not overwrite other MT_BBP(AGC, 8) fields

2018-10-31 Thread Lorenzo Bianconi
> MT_BBP(AGC, 8) register has values depend on band in
> mt76x0_bbp_switch_tab, so we should not overwrite other fields
> than MT_BBP_AGC_GAIN when setting gain.
> 
> This can fix performance issues when connecting to 2.4GHz AP.
> 
> Fixes: 4636a2544c3b ("mt76x0: phy: align channel gain logic to mt76x2 one")
> Signed-off-by: Stanislaw Gruszka 
> ---
>  drivers/net/wireless/mediatek/mt76/mt76x0/phy.c | 4 +---
>  1 file changed, 1 insertion(+), 3 deletions(-)
> 
> diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/phy.c 
> b/drivers/net/wireless/mediatek/mt76/mt76x0/phy.c
> index ba98814ae47d..88dd0aa7e877 100644
> --- a/drivers/net/wireless/mediatek/mt76/mt76x0/phy.c
> +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/phy.c
> @@ -690,10 +690,8 @@ static void mt76x0_phy_temp_sensor(struct mt76x02_dev 
> *dev)
>  static void mt76x0_phy_set_gain_val(struct mt76x02_dev *dev)
>  {
>   u8 gain = dev->cal.agc_gain_cur[0] - dev->cal.agc_gain_adjust;
> - u32 val = 0x122c << 16 | 0xf2;
>  
> - mt76_wr(dev, MT_BBP(AGC, 8),
> - val | FIELD_PREP(MT_BBP_AGC_GAIN, gain));
> + mt76_rmw_field(dev, MT_BBP(AGC, 8), MT_BBP_AGC_GAIN, gain);
>  
>   if ((dev->mt76.chandef.chan->flags & IEEE80211_CHAN_RADAR) &&
>   !is_mt7630(dev))
> -- 
> 2.7.5
> 

Acked-by: Lorenzo Bianconi 


Re: [PATCH] mt76x0: use band parameter for LC calibration

2018-10-30 Thread Lorenzo Bianconi
> diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/phy.c 
> b/drivers/net/wireless/mediatek/mt76/mt76x0/phy.c
> index c734987a344c..ca24b5716b58 100644
> --- a/drivers/net/wireless/mediatek/mt76/mt76x0/phy.c
> +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/phy.c
> @@ -522,6 +522,7 @@ void mt76x0_phy_set_txpower(struct mt76x02_dev *dev)
>  void mt76x0_phy_calibrate(struct mt76x02_dev *dev, bool power_on)
>  {
>   struct ieee80211_channel *chan = dev->mt76.chandef.chan;
> + int is_5ghz = (chan->band == NL80211_BAND_5GHZ) ? 1 : 0;
>   u32 val, tx_alc, reg_val;
>  
>   if (is_mt7630(dev))
> @@ -542,7 +543,7 @@ void mt76x0_phy_calibrate(struct mt76x02_dev *dev, bool 
> power_on)
>   reg_val = mt76_rr(dev, MT_BBP(IBI, 9));
>   mt76_wr(dev, MT_BBP(IBI, 9), 0xff7e);
>  
> - if (chan->band == NL80211_BAND_5GHZ) {
> + if (is_5ghz) {
>   if (chan->hw_value < 100)
>   val = 0x701;
>   else if (chan->hw_value < 140)
> @@ -555,7 +556,7 @@ void mt76x0_phy_calibrate(struct mt76x02_dev *dev, bool 
> power_on)
>  
>   mt76x02_mcu_calibrate(dev, MCU_CAL_FULL, val, false);
>   msleep(350);
> - mt76x02_mcu_calibrate(dev, MCU_CAL_LC, 1, false);
> + mt76x02_mcu_calibrate(dev, MCU_CAL_LC, is_5ghz, false);
>   usleep_range(15000, 2);
>  
>   mt76_wr(dev, MT_BBP(IBI, 9), reg_val);
> -- 
> 2.7.5
> 

Tested-by: Lorenzo Bianconi 

Regards,
Lorenzo


[PATCH 3/3] mt76x0: phy: use tssi reported value to configure tx power if available

2018-10-29 Thread Lorenzo Bianconi
Use tssi calibrated value to configure tx power gain if tssi is enabled
in eeprom data

Signed-off-by: Lorenzo Bianconi 
---
 .../wireless/mediatek/mt76/mt76x0/eeprom.c| 20 +++
 .../net/wireless/mediatek/mt76/mt76x0/phy.c   |  2 +-
 2 files changed, 17 insertions(+), 5 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/eeprom.c 
b/drivers/net/wireless/mediatek/mt76/mt76x0/eeprom.c
index 275d77c90624..497e762978cc 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x0/eeprom.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x0/eeprom.c
@@ -135,9 +135,6 @@ static s8 mt76x0_get_delta(struct mt76x02_dev *dev)
struct cfg80211_chan_def *chandef = >mt76.chandef;
u8 val;
 
-   if (mt76x0_tssi_enabled(dev))
-   return 0;
-
if (chandef->width == NL80211_CHAN_WIDTH_80) {
val = mt76x02_eeprom_get(dev, MT_EE_5G_TARGET_POWER) >> 8;
} else if (chandef->width == NL80211_CHAN_WIDTH_40) {
@@ -160,8 +157,8 @@ void mt76x0_get_tx_power_per_rate(struct mt76x02_dev *dev)
struct ieee80211_channel *chan = dev->mt76.chandef.chan;
bool is_2ghz = chan->band == NL80211_BAND_2GHZ;
struct mt76_rate_power *t = >mt76.rate_power;
-   s8 delta = mt76x0_get_delta(dev);
u16 val, addr;
+   s8 delta;
 
memset(t, 0, sizeof(*t));
 
@@ -211,6 +208,7 @@ void mt76x0_get_tx_power_per_rate(struct mt76x02_dev *dev)
t->vht[7] = s6_to_s8(val);
t->vht[8] = s6_to_s8(val >> 8);
 
+   delta = mt76x0_tssi_enabled(dev) ? 0 : mt76x0_get_delta(dev);
mt76x02_add_rate_power_offset(t, delta);
 }
 
@@ -233,6 +231,20 @@ void mt76x0_get_power_info(struct mt76x02_dev *dev, u8 
*info)
u16 data;
int i;
 
+   if (mt76x0_tssi_enabled(dev)) {
+   s8 target_power;
+
+   if (chan->band == NL80211_BAND_5GHZ)
+   data = mt76x02_eeprom_get(dev, MT_EE_5G_TARGET_POWER);
+   else
+   data = mt76x02_eeprom_get(dev, MT_EE_2G_TARGET_POWER);
+   target_power = (data & 0xff) - dev->mt76.rate_power.ofdm[7];
+   info[0] = target_power + mt76x0_get_delta(dev);
+   info[1] = 0;
+
+   return;
+   }
+
for (i = 0; i < ARRAY_SIZE(chan_map); i++) {
if (chan_map[i].chan <= chan->hw_value) {
offset = chan_map[i].offset;
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/phy.c 
b/drivers/net/wireless/mediatek/mt76/mt76x0/phy.c
index f0d46e7bb76a..a4d08655be61 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x0/phy.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x0/phy.c
@@ -847,8 +847,8 @@ void mt76x0_phy_set_txpower(struct mt76x02_dev *dev)
struct mt76_rate_power *t = >mt76.rate_power;
u8 info[2];
 
-   mt76x0_get_power_info(dev, info);
mt76x0_get_tx_power_per_rate(dev);
+   mt76x0_get_power_info(dev, info);
 
mt76x02_add_rate_power_offset(t, info[0]);
mt76x02_limit_rate_power(t, dev->mt76.txpower_conf);
-- 
2.19.1



[PATCH 1/3] mt76: move mt76x02_eeprom_copy in mt76x02-lib module

2018-10-29 Thread Lorenzo Bianconi
Move mt76x02_eeprom_copy utility routine in mt76x02-lib module
in order to be reused by mt76x0 driver adding tssi calibration
support

Signed-off-by: Lorenzo Bianconi 
---
 .../net/wireless/mediatek/mt76/mt76x02_eeprom.c   | 12 
 .../net/wireless/mediatek/mt76/mt76x02_eeprom.h   |  3 +++
 .../net/wireless/mediatek/mt76/mt76x2/eeprom.c| 15 ++-
 3 files changed, 17 insertions(+), 13 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_eeprom.c 
b/drivers/net/wireless/mediatek/mt76/mt76x02_eeprom.c
index 9390de2a323e..07f0496d828a 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_eeprom.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_eeprom.c
@@ -53,6 +53,18 @@ mt76x02_efuse_read(struct mt76x02_dev *dev, u16 addr, u8 
*data,
return 0;
 }
 
+int mt76x02_eeprom_copy(struct mt76x02_dev *dev,
+   enum mt76x02_eeprom_field field,
+   void *dest, int len)
+{
+   if (field + len > dev->mt76.eeprom.size)
+   return -1;
+
+   memcpy(dest, dev->mt76.eeprom.data + field, len);
+   return 0;
+}
+EXPORT_SYMBOL_GPL(mt76x02_eeprom_copy);
+
 int mt76x02_get_efuse_data(struct mt76x02_dev *dev, u16 base, void *buf,
   int len, enum mt76x02_eeprom_modes mode)
 {
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_eeprom.h 
b/drivers/net/wireless/mediatek/mt76/mt76x02_eeprom.h
index 1de041590050..5db01bda64b5 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_eeprom.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_eeprom.h
@@ -188,5 +188,8 @@ u8 mt76x02_get_lna_gain(struct mt76x02_dev *dev,
s8 *lna_2g, s8 *lna_5g,
struct ieee80211_channel *chan);
 void mt76x02_eeprom_parse_hw_cap(struct mt76x02_dev *dev);
+int mt76x02_eeprom_copy(struct mt76x02_dev *dev,
+   enum mt76x02_eeprom_field field,
+   void *dest, int len);
 
 #endif /* __MT76x02_EEPROM_H */
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/eeprom.c 
b/drivers/net/wireless/mediatek/mt76/mt76x2/eeprom.c
index f39b622d03f4..6f6998561d9d 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x2/eeprom.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x2/eeprom.c
@@ -21,17 +21,6 @@
 
 #define EE_FIELD(_name, _value) [MT_EE_##_name] = (_value) | 1
 
-static int
-mt76x2_eeprom_copy(struct mt76x02_dev *dev, enum mt76x02_eeprom_field field,
-  void *dest, int len)
-{
-   if (field + len > dev->mt76.eeprom.size)
-   return -1;
-
-   memcpy(dest, dev->mt76.eeprom.data + field, len);
-   return 0;
-}
-
 static int
 mt76x2_eeprom_get_macaddr(struct mt76x02_dev *dev)
 {
@@ -378,7 +367,7 @@ mt76x2_get_power_info_2g(struct mt76x02_dev *dev,
else
delta_idx = 5;
 
-   mt76x2_eeprom_copy(dev, offset, data, sizeof(data));
+   mt76x02_eeprom_copy(dev, offset, data, sizeof(data));
 
t->chain[chain].tssi_slope = data[0];
t->chain[chain].tssi_offset = data[1];
@@ -429,7 +418,7 @@ mt76x2_get_power_info_5g(struct mt76x02_dev *dev,
else
delta_idx = 4;
 
-   mt76x2_eeprom_copy(dev, offset, data, sizeof(data));
+   mt76x02_eeprom_copy(dev, offset, data, sizeof(data));
 
t->chain[chain].tssi_slope = data[0];
t->chain[chain].tssi_offset = data[1];
-- 
2.19.1



[PATCH 0/3] mt76x0: add tssi calibration support

2018-10-29 Thread Lorenzo Bianconi
Introduce tssi calibration support in mt76x0 driver.
Configure tx power gain according to tssi calibrated value
if available

Lorenzo Bianconi (3):
  mt76: move mt76x02_eeprom_copy in mt76x02-lib module
  mt76x0: phy: introduce tssi calibration support
  mt76x0: phy: use tssi reported value to configure tx power if
available

 .../wireless/mediatek/mt76/mt76x0/eeprom.c|  20 +-
 .../net/wireless/mediatek/mt76/mt76x0/phy.c   | 357 +-
 drivers/net/wireless/mediatek/mt76/mt76x02.h  |   3 +
 .../wireless/mediatek/mt76/mt76x02_eeprom.c   |  12 +
 .../wireless/mediatek/mt76/mt76x02_eeprom.h   |   5 +
 .../wireless/mediatek/mt76/mt76x2/eeprom.c|  15 +-
 6 files changed, 391 insertions(+), 21 deletions(-)

-- 
2.19.1



[PATCH 2/3] mt76x0: phy: introduce tssi calibration support

2018-10-29 Thread Lorenzo Bianconi
Run mt76x0 tssi calibration process if enabled in eeprom data.
Perform calibration procedure every 4s

Signed-off-by: Lorenzo Bianconi 
---
 .../net/wireless/mediatek/mt76/mt76x0/phy.c   | 355 +-
 drivers/net/wireless/mediatek/mt76/mt76x02.h  |   3 +
 .../wireless/mediatek/mt76/mt76x02_eeprom.h   |   2 +
 3 files changed, 357 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/phy.c 
b/drivers/net/wireless/mediatek/mt76/mt76x0/phy.c
index 830ea6047f10..f0d46e7bb76a 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x0/phy.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x0/phy.c
@@ -503,6 +503,345 @@ mt76x0_phy_bbp_set_bw(struct mt76x02_dev *dev, enum 
nl80211_chan_width width)
mt76x02_mcu_function_select(dev, BW_SETTING, bw, false);
 }
 
+static void mt76x0_phy_tssi_dc_calibrate(struct mt76x02_dev *dev)
+{
+   struct ieee80211_channel *chan = dev->mt76.chandef.chan;
+   u32 val;
+
+   if (chan->band == NL80211_BAND_5GHZ)
+   mt76x0_rf_clear(dev, MT_RF(0, 67), 0xf);
+
+   /* bypass ADDA control */
+   mt76_wr(dev, MT_RF_SETTING_0, 0x60002237);
+   mt76_wr(dev, MT_RF_BYPASS_0, 0x);
+
+   /* bbp sw reset */
+   mt76_set(dev, MT_BBP(CORE, 4), BIT(0));
+   usleep_range(500, 1000);
+   mt76_clear(dev, MT_BBP(CORE, 4), BIT(0));
+
+   val = (chan->band == NL80211_BAND_5GHZ) ? 0x80055 : 0x80050;
+   mt76_wr(dev, MT_BBP(CORE, 34), val);
+
+   /* enable TX with DAC0 input */
+   mt76_wr(dev, MT_BBP(TXBE, 6), BIT(31));
+
+   mt76_poll_msec(dev, MT_BBP(CORE, 34), BIT(4), 0, 200);
+   dev->cal.tssi_dc = mt76_rr(dev, MT_BBP(CORE, 35)) & 0xff;
+
+   /* stop bypass ADDA */
+   mt76_wr(dev, MT_RF_BYPASS_0, 0);
+   /* stop TX */
+   mt76_wr(dev, MT_BBP(TXBE, 6), 0);
+   /* bbp sw reset */
+   mt76_set(dev, MT_BBP(CORE, 4), BIT(0));
+   usleep_range(500, 1000);
+   mt76_clear(dev, MT_BBP(CORE, 4), BIT(0));
+
+   if (chan->band == NL80211_BAND_5GHZ)
+   mt76x0_rf_rmw(dev, MT_RF(0, 67), 0xf, 0x4);
+}
+
+static int
+mt76x0_phy_tssi_adc_calibrate(struct mt76x02_dev *dev, s16 *ltssi,
+ u8 *info)
+{
+   struct ieee80211_channel *chan = dev->mt76.chandef.chan;
+   u32 val;
+
+   val = (chan->band == NL80211_BAND_5GHZ) ? 0x80055 : 0x80050;
+   mt76_wr(dev, MT_BBP(CORE, 34), val);
+
+   if (!mt76_poll_msec(dev, MT_BBP(CORE, 34), BIT(4), 0, 200)) {
+   mt76_clear(dev, MT_BBP(CORE, 34), BIT(4));
+   return -ETIMEDOUT;
+   }
+
+   *ltssi = mt76_rr(dev, MT_BBP(CORE, 35)) & 0xff;
+   if (chan->band == NL80211_BAND_5GHZ)
+   *ltssi += 128;
+
+   /* set packet info#1 mode */
+   mt76_wr(dev, MT_BBP(CORE, 34), 0x80041);
+   info[0] = mt76_rr(dev, MT_BBP(CORE, 35)) & 0xff;
+
+   /* set packet info#2 mode */
+   mt76_wr(dev, MT_BBP(CORE, 34), 0x80042);
+   info[1] = mt76_rr(dev, MT_BBP(CORE, 35)) & 0xff;
+
+   /* set packet info#3 mode */
+   mt76_wr(dev, MT_BBP(CORE, 34), 0x80043);
+   info[2] = mt76_rr(dev, MT_BBP(CORE, 35)) & 0xff;
+
+   return 0;
+}
+
+static u8 mt76x0_phy_get_rf_pa_mode(struct mt76x02_dev *dev,
+   int index, u8 tx_rate)
+{
+   u32 val, reg;
+
+   reg = (index == 1) ? MT_RF_PA_MODE_CFG1 : MT_RF_PA_MODE_CFG0;
+   val = mt76_rr(dev, reg);
+   return (val & (3 << (tx_rate * 2))) >> (tx_rate * 2);
+}
+
+static int
+mt76x0_phy_get_target_power(struct mt76x02_dev *dev, u8 tx_mode,
+   u8 *info, s8 *target_power,
+   s8 *target_pa_power)
+{
+   u8 tx_rate, cur_power;
+
+   cur_power = mt76_rr(dev, MT_TX_ALC_CFG_0) & MT_TX_ALC_CFG_0_CH_INIT_0;
+   switch (tx_mode) {
+   case 0:
+   /* cck rates */
+   tx_rate = (info[0] & 0x60) >> 5;
+   if (tx_rate > 3)
+   return -EINVAL;
+
+   *target_power = cur_power + dev->mt76.rate_power.cck[tx_rate];
+   *target_pa_power = mt76x0_phy_get_rf_pa_mode(dev, 0, tx_rate);
+   break;
+   case 1: {
+   u8 index;
+
+   /* ofdm rates */
+   tx_rate = (info[0] & 0xf0) >> 4;
+   switch (tx_rate) {
+   case 0xb:
+   index = 0;
+   break;
+   case 0xf:
+   index = 1;
+   break;
+   case 0xa:
+   index = 2;
+   break;
+   case 0xe:
+   index = 3;
+   break;
+   case 0x9:
+   index = 4;
+   break;
+   case 0xd:
+   index = 5;
+   break;

[PATCH] mt76x2u: init: use common routines for wcid/key initialization

2018-10-29 Thread Lorenzo Bianconi
Use mt76x02_mac_wcid_setup and mt76x02_mac_shared_key_setup for
shared keys and wcid table initialization and remove duplicated
code

Signed-off-by: Lorenzo Bianconi 
---
 .../wireless/mediatek/mt76/mt76x2/usb_init.c  | 19 +++
 1 file changed, 7 insertions(+), 12 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/usb_init.c 
b/drivers/net/wireless/mediatek/mt76/mt76x2/usb_init.c
index c338ac0433ad..94a4b58fddc1 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x2/usb_init.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x2/usb_init.c
@@ -166,11 +166,7 @@ static void mt76x2u_init_beacon_offsets(struct mt76x02_dev 
*dev)
 
 int mt76x2u_init_hardware(struct mt76x02_dev *dev)
 {
-   const struct mt76_wcid_addr addr = {
-   .macaddr = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
-   .ba_mask = 0,
-   };
-   int i, err;
+   int i, k, err;
 
mt76x2_reset_wlan(dev, true);
mt76x2u_power_on(dev);
@@ -210,15 +206,14 @@ int mt76x2u_init_hardware(struct mt76x02_dev *dev)
return -ETIMEDOUT;
 
/* reset wcid table */
-   for (i = 0; i < 254; i++)
-   mt76_wr_copy(dev, MT_WCID_ADDR(i), ,
-sizeof(struct mt76_wcid_addr));
+   for (i = 0; i < 256; i++)
+   mt76x02_mac_wcid_setup(dev, i, 0, NULL);
 
/* reset shared key table and pairwise key table */
-   for (i = 0; i < 4; i++)
-   mt76_wr(dev, MT_SKEY_MODE_BASE_0 + 4 * i, 0);
-   for (i = 0; i < 256; i++)
-   mt76_wr(dev, MT_WCID_ATTR(i), 1);
+   for (i = 0; i < 16; i++) {
+   for (k = 0; k < 4; k++)
+   mt76x02_mac_shared_key_setup(dev, i, k, NULL);
+   }
 
mt76_clear(dev, MT_BEACON_TIME_CFG,
   MT_BEACON_TIME_CFG_TIMER_EN |
-- 
2.19.1



[PATCH] mt76x2u: init: remove not useful configuration

2018-10-29 Thread Lorenzo Bianconi
Remove MT_TSO_CTRL and MT_HEADER_TRANS_CTRL_REG initialization since
it is already done in mt76_write_mac_initvals routine

Signed-off-by: Lorenzo Bianconi 
---
 drivers/net/wireless/mediatek/mt76/mt76x2/usb_init.c | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/usb_init.c 
b/drivers/net/wireless/mediatek/mt76/mt76x2/usb_init.c
index a7d591610f16..c338ac0433ad 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x2/usb_init.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x2/usb_init.c
@@ -191,9 +191,6 @@ int mt76x2u_init_hardware(struct mt76x02_dev *dev)
if (!mt76x02_wait_for_mac(>mt76))
return -ETIMEDOUT;
 
-   mt76_wr(dev, MT_HEADER_TRANS_CTRL_REG, 0);
-   mt76_wr(dev, MT_TSO_CTRL, 0);
-
mt76x2u_init_dma(dev);
 
err = mt76x2u_mcu_init(dev);
-- 
2.17.2



[PATCH 2/2] mt76x0: init: use mt76x02_mac_wcid_setup for wcid configuration

2018-10-28 Thread Lorenzo Bianconi
Use mt76x02_mac_wcid_setup utility routine for wcid init configuration
and remove duplicated code. This patch fixes a mt76x0 AP issue since
hw key table selection was set to pairwise by default

Fixes: dbad2adcb2c7 ("mt76x0: pci: enable AP support")
Signed-off-by: Lorenzo Bianconi 
---
 .../net/wireless/mediatek/mt76/mt76x0/init.c  | 45 +--
 1 file changed, 2 insertions(+), 43 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/init.c 
b/drivers/net/wireless/mediatek/mt76/mt76x0/init.c
index 23ff29990ff7..55db5a15410e 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x0/init.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x0/init.c
@@ -157,42 +157,6 @@ static void mt76x0_init_mac_registers(struct mt76x02_dev 
*dev)
mt76_rmw(dev, MT_WMM_CTRL, 0x3ff, 0x201);
 }
 
-static int mt76x0_init_wcid_mem(struct mt76x02_dev *dev)
-{
-   u32 *vals;
-   int i;
-
-   vals = kmalloc(sizeof(*vals) * MT76_N_WCIDS * 2, GFP_KERNEL);
-   if (!vals)
-   return -ENOMEM;
-
-   for (i = 0; i < MT76_N_WCIDS; i++)  {
-   vals[i * 2] = 0x;
-   vals[i * 2 + 1] = 0x00ff;
-   }
-
-   mt76_wr_copy(dev, MT_WCID_ADDR_BASE, vals, MT76_N_WCIDS * 2);
-   kfree(vals);
-   return 0;
-}
-
-static int mt76x0_init_wcid_attr_mem(struct mt76x02_dev *dev)
-{
-   u32 *vals;
-   int i;
-
-   vals = kmalloc(sizeof(*vals) * MT76_N_WCIDS * 2, GFP_KERNEL);
-   if (!vals)
-   return -ENOMEM;
-
-   for (i = 0; i < MT76_N_WCIDS * 2; i++)
-   vals[i] = 1;
-
-   mt76_wr_copy(dev, MT_WCID_ATTR_BASE, vals, MT76_N_WCIDS * 2);
-   kfree(vals);
-   return 0;
-}
-
 static void mt76x0_reset_counters(struct mt76x02_dev *dev)
 {
mt76_rr(dev, MT_RX_STAT_0);
@@ -278,17 +242,12 @@ int mt76x0_init_hardware(struct mt76x02_dev *dev)
 
dev->mt76.rxfilter = mt76_rr(dev, MT_RX_FILTR_CFG);
 
-   ret = mt76x0_init_wcid_mem(dev);
-   if (ret)
-   return ret;
-
for (i = 0; i < 16; i++)
for (k = 0; k < 4; k++)
mt76x02_mac_shared_key_setup(dev, i, k, NULL);
 
-   ret = mt76x0_init_wcid_attr_mem(dev);
-   if (ret)
-   return ret;
+   for (i = 0; i < 256; i++)
+   mt76x02_mac_wcid_setup(dev, i, 0, NULL);
 
mt76x0_reset_counters(dev);
 
-- 
2.19.1



[PATCH 0/2] mt76x0: fix hw key table initialization

2018-10-28 Thread Lorenzo Bianconi
Fix wrong mt76x0 hw key table initialization in AP mode.
Remove duplicated code.

This patchset is based on top of 'mt76x0: init: use
mt76x02_mac_shared_key_setup in mt76x0_init_hardware'
https://patchwork.kernel.org/patch/10658721/

Lorenzo Bianconi (2):
  mt76x2: move wcid_tx_rate conf at bootstrap
  mt76x0: init: use mt76x02_mac_wcid_setup for wcid configuration

 .../net/wireless/mediatek/mt76/mt76x0/init.c  | 45 +--
 .../net/wireless/mediatek/mt76/mt76x02_mac.c  |  3 --
 .../wireless/mediatek/mt76/mt76x2/pci_init.c  |  5 ++-
 3 files changed, 6 insertions(+), 47 deletions(-)

-- 
2.19.1



[PATCH 1/2] mt76x2: move wcid_tx_rate conf at bootstrap

2018-10-28 Thread Lorenzo Bianconi
Move WCID tx rate configuration at device bootstrap since
the related register are always set to 0

Signed-off-by: Lorenzo Bianconi 
---
 drivers/net/wireless/mediatek/mt76/mt76x02_mac.c | 3 ---
 drivers/net/wireless/mediatek/mt76/mt76x2/pci_init.c | 5 -
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c 
b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
index 4fb9f095ffec..b0b04415703f 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
@@ -106,9 +106,6 @@ void mt76x02_mac_wcid_setup(struct mt76x02_dev *dev, u8 idx,
 
mt76_wr(dev, MT_WCID_ATTR(idx), attr);
 
-   mt76_wr(dev, MT_WCID_TX_RATE(idx), 0);
-   mt76_wr(dev, MT_WCID_TX_RATE(idx) + 4, 0);
-
if (idx >= 128)
return;
 
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/pci_init.c 
b/drivers/net/wireless/mediatek/mt76/mt76x2/pci_init.c
index f6e8af6432c1..7b53b2be28c2 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x2/pci_init.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x2/pci_init.c
@@ -129,8 +129,11 @@ static int mt76x2_mac_reset(struct mt76x02_dev *dev, bool 
hard)
for (i = 0; i < 256 / 32; i++)
mt76_wr(dev, MT_WCID_DROP_BASE + i * 4, 0);
 
-   for (i = 0; i < 256; i++)
+   for (i = 0; i < 256; i++) {
mt76x02_mac_wcid_setup(dev, i, 0, NULL);
+   mt76_wr(dev, MT_WCID_TX_RATE(i), 0);
+   mt76_wr(dev, MT_WCID_TX_RATE(i) + 4, 0);
+   }
 
for (i = 0; i < MT_MAX_VIFS; i++)
mt76x02_mac_wcid_setup(dev, MT_VIF_WCID(i), i, NULL);
-- 
2.19.1



[PATCH] mt76x0: init: use mt76x02_mac_shared_key_setup in mt76x0_init_hardware

2018-10-28 Thread Lorenzo Bianconi
Use mt76x02_mac_shared_key_setup utility routine for shared key
initialization and remove duplicated code

Signed-off-by: Lorenzo Bianconi 
---
 drivers/net/wireless/mediatek/mt76/mt76x0/init.c | 13 -
 1 file changed, 4 insertions(+), 9 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/init.c 
b/drivers/net/wireless/mediatek/mt76/mt76x0/init.c
index 64eb6f451541..23ff29990ff7 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x0/init.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x0/init.c
@@ -176,13 +176,6 @@ static int mt76x0_init_wcid_mem(struct mt76x02_dev *dev)
return 0;
 }
 
-static void mt76x0_init_key_mem(struct mt76x02_dev *dev)
-{
-   u32 vals[4] = {};
-
-   mt76_wr_copy(dev, MT_SKEY_MODE_BASE_0, vals, ARRAY_SIZE(vals));
-}
-
 static int mt76x0_init_wcid_attr_mem(struct mt76x02_dev *dev)
 {
u32 *vals;
@@ -260,7 +253,7 @@ EXPORT_SYMBOL_GPL(mt76x0_mac_stop);
 
 int mt76x0_init_hardware(struct mt76x02_dev *dev)
 {
-   int ret;
+   int ret, i, k;
 
if (!mt76x02_wait_for_wpdma(>mt76, 1000))
return -EIO;
@@ -289,7 +282,9 @@ int mt76x0_init_hardware(struct mt76x02_dev *dev)
if (ret)
return ret;
 
-   mt76x0_init_key_mem(dev);
+   for (i = 0; i < 16; i++)
+   for (k = 0; k < 4; k++)
+   mt76x02_mac_shared_key_setup(dev, i, k, NULL);
 
ret = mt76x0_init_wcid_attr_mem(dev);
if (ret)
-- 
2.19.1



[PATCH] mt76x0: phy: use mt76_poll_msec in mt76x0_phy_temp_sensor

2018-10-27 Thread Lorenzo Bianconi
Use mt76_poll_msec utility routine for CORE_R34 register polling
instead of mt76_poll in order to allow the hw to complete requested
calibration since on slow devices (e.g. mt7620 based boards) calibration
takes longer than 2ms

Fixes: 66a34c66e0cb ("mt76x0: phy: add phy/vco temperature compensation")
Signed-off-by: Lorenzo Bianconi 
---
 drivers/net/wireless/mediatek/mt76/mt76x0/phy.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/phy.c 
b/drivers/net/wireless/mediatek/mt76/mt76x0/phy.c
index c734987a344c..830ea6047f10 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x0/phy.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x0/phy.c
@@ -686,8 +686,7 @@ static void mt76x0_phy_temp_sensor(struct mt76x02_dev *dev)
mt76x0_rf_wr(dev, MT_RF(0, 67), 0x01);
 
mt76_wr(dev, MT_BBP(CORE, 34), 0x00080055);
-
-   if (!mt76_poll(dev, MT_BBP(CORE, 34), BIT(4), 0, 2000)) {
+   if (!mt76_poll_msec(dev, MT_BBP(CORE, 34), BIT(4), 0, 200)) {
mt76_clear(dev, MT_BBP(CORE, 34), BIT(4));
goto done;
}
-- 
2.19.1



[PATCH 2/2] mt76x0: pci: add DFS support

2018-10-22 Thread Lorenzo Bianconi
Introduce dfs support in mt76x0e driver and unlock radar channels

Signed-off-by: Lorenzo Bianconi 
---
 .../net/wireless/mediatek/mt76/mt76x0/main.c  | 11 +--
 .../net/wireless/mediatek/mt76/mt76x0/phy.c   |  4 +++
 .../net/wireless/mediatek/mt76/mt76x02_dfs.c  | 31 +--
 .../net/wireless/mediatek/mt76/mt76x02_dfs.h  |  1 +
 .../net/wireless/mediatek/mt76/mt76x02_util.c |  5 +++
 .../wireless/mediatek/mt76/mt76x2/pci_init.c  |  7 -
 .../net/wireless/mediatek/mt76/mt76x2/phy.c   | 23 +-
 7 files changed, 49 insertions(+), 33 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/main.c 
b/drivers/net/wireless/mediatek/mt76/mt76x0/main.c
index cd1a1225ad8b..a803a9b6a4c5 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x0/main.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x0/main.c
@@ -22,7 +22,10 @@ mt76x0_set_channel(struct mt76x02_dev *dev, struct 
cfg80211_chan_def *chandef)
int ret;
 
cancel_delayed_work_sync(>cal_work);
-   tasklet_disable(>pre_tbtt_tasklet);
+   if (mt76_is_mmio(dev)) {
+   tasklet_disable(>pre_tbtt_tasklet);
+   tasklet_disable(>dfs_pd.dfs_tasklet);
+   }
 
mt76_set_channel(>mt76);
ret = mt76x0_phy_set_channel(dev, chandef);
@@ -31,7 +34,11 @@ mt76x0_set_channel(struct mt76x02_dev *dev, struct 
cfg80211_chan_def *chandef)
mt76_rr(dev, MT_CH_IDLE);
mt76_rr(dev, MT_CH_BUSY);
 
-   tasklet_enable(>pre_tbtt_tasklet);
+   if (mt76_is_mmio(dev)) {
+   mt76x02_dfs_init_params(dev);
+   tasklet_enable(>pre_tbtt_tasklet);
+   tasklet_enable(>dfs_pd.dfs_tasklet);
+   }
mt76_txq_schedule_all(>mt76);
 
return ret;
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/phy.c 
b/drivers/net/wireless/mediatek/mt76/mt76x0/phy.c
index b33074b783dc..c734987a344c 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x0/phy.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x0/phy.c
@@ -719,6 +719,10 @@ static void mt76x0_phy_set_gain_val(struct mt76x02_dev 
*dev)
 
mt76_wr(dev, MT_BBP(AGC, 8),
val | FIELD_PREP(MT_BBP_AGC_GAIN, gain));
+
+   if ((dev->mt76.chandef.chan->flags & IEEE80211_CHAN_RADAR) &&
+   !is_mt7630(dev))
+   mt76x02_phy_dfs_adjust_agc(dev);
 }
 
 static void
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_dfs.c 
b/drivers/net/wireless/mediatek/mt76/mt76x02_dfs.c
index 21e7b8c9f824..527e530d480a 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_dfs.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_dfs.c
@@ -802,6 +802,35 @@ static void mt76x02_dfs_set_bbp_params(struct mt76x02_dev 
*dev)
mt76_wr(dev, 0x212c, 0x0c350001);
 }
 
+void mt76x02_phy_dfs_adjust_agc(struct mt76x02_dev *dev)
+{
+   u32 agc_r8, agc_r4, val_r8, val_r4, dfs_r31;
+
+   agc_r8 = mt76_rr(dev, MT_BBP(AGC, 8));
+   agc_r4 = mt76_rr(dev, MT_BBP(AGC, 4));
+
+   val_r8 = (agc_r8 & 0x7e00) >> 9;
+   val_r4 = agc_r4 & ~0x1f00;
+   val_r4 += (((val_r8 + 1) >> 1) << 24);
+   mt76_wr(dev, MT_BBP(AGC, 4), val_r4);
+
+   dfs_r31 = FIELD_GET(MT_BBP_AGC_LNA_HIGH_GAIN, val_r4);
+   dfs_r31 += val_r8;
+   dfs_r31 -= (agc_r8 & 0x0038) >> 3;
+   dfs_r31 = (dfs_r31 << 16) | 0x0307;
+   mt76_wr(dev, MT_BBP(DFS, 31), dfs_r31);
+
+   if (is_mt76x2(dev)) {
+   mt76_wr(dev, MT_BBP(DFS, 32), 0x00040071);
+   } else {
+   /* disable hw detector */
+   mt76_wr(dev, MT_BBP(DFS, 0), 0);
+   /* enable hw detector */
+   mt76_wr(dev, MT_BBP(DFS, 0), MT_DFS_CH_EN << 16);
+   }
+}
+EXPORT_SYMBOL_GPL(mt76x02_phy_dfs_adjust_agc);
+
 void mt76x02_dfs_init_params(struct mt76x02_dev *dev)
 {
struct cfg80211_chan_def *chandef = >mt76.chandef;
@@ -841,7 +870,6 @@ void mt76x02_dfs_init_detector(struct mt76x02_dev *dev)
tasklet_init(_pd->dfs_tasklet, mt76x02_dfs_tasklet,
 (unsigned long)dev);
 }
-EXPORT_SYMBOL_GPL(mt76x02_dfs_init_detector);
 
 static void
 mt76x02_dfs_set_domain(struct mt76x02_dev *dev,
@@ -865,4 +893,3 @@ void mt76x02_regd_notifier(struct wiphy *wiphy,
 
mt76x02_dfs_set_domain(dev, request->dfs_region);
 }
-EXPORT_SYMBOL_GPL(mt76x02_regd_notifier);
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_dfs.h 
b/drivers/net/wireless/mediatek/mt76/mt76x02_dfs.h
index 59e1524ff98b..70b394e17340 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_dfs.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_dfs.h
@@ -141,4 +141,5 @@ void mt76x02_dfs_init_params(struct mt76x02_dev *dev);
 void mt76x02_dfs_init_detector(struct mt76x02_dev *dev);
 void mt76x02_regd_notifier(struct wiphy *wiphy,
   struct regulatory_request *request);
+void mt76x02_phy_dfs_adjust_agc(struct mt76x02_dev 

[PATCH 1/2] mt76: move dfs support in mt76x02-lib module

2018-10-22 Thread Lorenzo Bianconi
Move mt76x2 DFS support in mt76x02-lib module in order to
be reused by mt76x0 driver and unlock DFS frequencies

Signed-off-by: Lorenzo Bianconi 
---
 drivers/net/wireless/mediatek/mt76/Makefile   |   3 +-
 .../mt76/{mt76x2/pci_dfs.c => mt76x02_dfs.c}  | 135 ++
 .../net/wireless/mediatek/mt76/mt76x02_dfs.h  |   4 +
 .../wireless/mediatek/mt76/mt76x2/Makefile|   2 +-
 .../net/wireless/mediatek/mt76/mt76x2/dfs.h   |  25 
 .../wireless/mediatek/mt76/mt76x2/mt76x2.h|   1 -
 .../wireless/mediatek/mt76/mt76x2/pci_init.c  |  13 +-
 .../wireless/mediatek/mt76/mt76x2/pci_main.c  |   2 +-
 8 files changed, 83 insertions(+), 102 deletions(-)
 rename drivers/net/wireless/mediatek/mt76/{mt76x2/pci_dfs.c => mt76x02_dfs.c} 
(86%)
 delete mode 100644 drivers/net/wireless/mediatek/mt76/mt76x2/dfs.h

diff --git a/drivers/net/wireless/mediatek/mt76/Makefile 
b/drivers/net/wireless/mediatek/mt76/Makefile
index a737a518802f..1a45cb30f39f 100644
--- a/drivers/net/wireless/mediatek/mt76/Makefile
+++ b/drivers/net/wireless/mediatek/mt76/Makefile
@@ -14,7 +14,8 @@ CFLAGS_mt76x02_trace.o := -I$(src)
 
 mt76x02-lib-y := mt76x02_util.o mt76x02_mac.o mt76x02_mcu.o \
 mt76x02_eeprom.o mt76x02_phy.o mt76x02_mmio.o \
-mt76x02_txrx.o mt76x02_trace.o mt76x02_debugfs.o
+mt76x02_txrx.o mt76x02_trace.o mt76x02_debugfs.o \
+mt76x02_dfs.o
 
 mt76x02-usb-y := mt76x02_usb_mcu.o mt76x02_usb_core.o
 
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/pci_dfs.c 
b/drivers/net/wireless/mediatek/mt76/mt76x02_dfs.c
similarity index 86%
rename from drivers/net/wireless/mediatek/mt76/mt76x2/pci_dfs.c
rename to drivers/net/wireless/mediatek/mt76/mt76x02_dfs.c
index 8d66952400a8..21e7b8c9f824 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x2/pci_dfs.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_dfs.c
@@ -14,7 +14,7 @@
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
-#include "mt76x2.h"
+#include "mt76x02.h"
 
 #define RADAR_SPEC(m, len, el, eh, wl, wh, \
   w_tolerance, tl, th, t_tolerance,\
@@ -151,8 +151,7 @@ static const struct mt76x02_radar_specs 
jp_w53_radar_specs[] = {
 };
 
 static void
-mt76x2_dfs_set_capture_mode_ctrl(struct mt76x02_dev *dev,
-u8 enable)
+mt76x02_dfs_set_capture_mode_ctrl(struct mt76x02_dev *dev, u8 enable)
 {
u32 data;
 
@@ -160,8 +159,8 @@ mt76x2_dfs_set_capture_mode_ctrl(struct mt76x02_dev *dev,
mt76_wr(dev, MT_BBP(DFS, 36), data);
 }
 
-static void mt76x2_dfs_seq_pool_put(struct mt76x02_dev *dev,
-   struct mt76x02_dfs_sequence *seq)
+static void mt76x02_dfs_seq_pool_put(struct mt76x02_dev *dev,
+struct mt76x02_dfs_sequence *seq)
 {
struct mt76x02_dfs_pattern_detector *dfs_pd = >dfs_pd;
 
@@ -172,7 +171,7 @@ static void mt76x2_dfs_seq_pool_put(struct mt76x02_dev *dev,
 }
 
 static struct mt76x02_dfs_sequence *
-mt76x2_dfs_seq_pool_get(struct mt76x02_dev *dev)
+mt76x02_dfs_seq_pool_get(struct mt76x02_dev *dev)
 {
struct mt76x02_dfs_pattern_detector *dfs_pd = >dfs_pd;
struct mt76x02_dfs_sequence *seq;
@@ -192,7 +191,7 @@ mt76x2_dfs_seq_pool_get(struct mt76x02_dev *dev)
return seq;
 }
 
-static int mt76x2_dfs_get_multiple(int val, int frac, int margin)
+static int mt76x02_dfs_get_multiple(int val, int frac, int margin)
 {
int remainder, factor;
 
@@ -214,7 +213,7 @@ static int mt76x2_dfs_get_multiple(int val, int frac, int 
margin)
return factor;
 }
 
-static void mt76x2_dfs_detector_reset(struct mt76x02_dev *dev)
+static void mt76x02_dfs_detector_reset(struct mt76x02_dev *dev)
 {
struct mt76x02_dfs_pattern_detector *dfs_pd = >dfs_pd;
struct mt76x02_dfs_sequence *seq, *tmp_seq;
@@ -231,11 +230,11 @@ static void mt76x2_dfs_detector_reset(struct mt76x02_dev 
*dev)
 
list_for_each_entry_safe(seq, tmp_seq, _pd->sequences, head) {
list_del_init(>head);
-   mt76x2_dfs_seq_pool_put(dev, seq);
+   mt76x02_dfs_seq_pool_put(dev, seq);
}
 }
 
-static bool mt76x2_dfs_check_chirp(struct mt76x02_dev *dev)
+static bool mt76x02_dfs_check_chirp(struct mt76x02_dev *dev)
 {
bool ret = false;
u32 current_ts, delta_ts;
@@ -256,8 +255,8 @@ static bool mt76x2_dfs_check_chirp(struct mt76x02_dev *dev)
return ret;
 }
 
-static void mt76x2_dfs_get_hw_pulse(struct mt76x02_dev *dev,
-   struct mt76x02_dfs_hw_pulse *pulse)
+static void mt76x02_dfs_get_hw_pulse(struct mt76x02_dev *dev,
+struct mt76x02_dfs_hw_pulse *pulse)
 {
u32 data;
 
@@ -276,8 +275,8 @@ static void mt76x2_dfs_get_hw_pulse(struct mt76x02_dev *dev,
pulse->burst = mt76_rr(dev, MT_BBP(DFS, 22));
 }
 
-static bool mt76x

[PATCH 0/2] add dfs support to mt76x0e driver

2018-10-22 Thread Lorenzo Bianconi
Introduce {sw,hw} dfs detector to mt76x0e driver in order to
properly unlock radar frequencies
This series is based on top of 'unify drv_bss_info_changed
between mt76x0 and mt76x2' one:
https://patchwork.kernel.org/cover/10650357/

Lorenzo Bianconi (2):
  mt76: move dfs support in mt76x02-lib module
  mt76x0: pci: add DFS support

 drivers/net/wireless/mediatek/mt76/Makefile   |   3 +-
 .../net/wireless/mediatek/mt76/mt76x0/main.c  |  11 +-
 .../net/wireless/mediatek/mt76/mt76x0/phy.c   |   4 +
 .../mt76/{mt76x2/pci_dfs.c => mt76x02_dfs.c}  | 162 +++---
 .../net/wireless/mediatek/mt76/mt76x02_dfs.h  |   5 +
 .../net/wireless/mediatek/mt76/mt76x02_util.c |   5 +
 .../wireless/mediatek/mt76/mt76x2/Makefile|   2 +-
 .../net/wireless/mediatek/mt76/mt76x2/dfs.h   |  25 ---
 .../wireless/mediatek/mt76/mt76x2/mt76x2.h|   1 -
 .../wireless/mediatek/mt76/mt76x2/pci_init.c  |  16 --
 .../wireless/mediatek/mt76/mt76x2/pci_main.c  |   2 +-
 .../net/wireless/mediatek/mt76/mt76x2/phy.c   |  23 +--
 12 files changed, 128 insertions(+), 131 deletions(-)
 rename drivers/net/wireless/mediatek/mt76/{mt76x2/pci_dfs.c => mt76x02_dfs.c} 
(83%)
 delete mode 100644 drivers/net/wireless/mediatek/mt76/mt76x2/dfs.h

-- 
2.19.1



[PATCH 4/4] mt76: move mt76x02_bss_info_changed in mt76x02-lib module

2018-10-20 Thread Lorenzo Bianconi
Unify drv_bss_info_changed mac80211 callback and remove duplicated
code in mt76x0 and mt76x2 drivers

Signed-off-by: Lorenzo Bianconi 
---
 .../net/wireless/mediatek/mt76/mt76x0/main.c  | 49 ---
 .../wireless/mediatek/mt76/mt76x0/mt76x0.h|  3 --
 .../net/wireless/mediatek/mt76/mt76x0/pci.c   |  2 +-
 .../net/wireless/mediatek/mt76/mt76x0/usb.c   |  2 +-
 drivers/net/wireless/mediatek/mt76/mt76x02.h  |  3 ++
 .../net/wireless/mediatek/mt76/mt76x02_util.c | 42 
 .../wireless/mediatek/mt76/mt76x2/pci_main.c  | 39 +--
 7 files changed, 48 insertions(+), 92 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/main.c 
b/drivers/net/wireless/mediatek/mt76/mt76x0/main.c
index b8eba511d0f3..cd1a1225ad8b 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x0/main.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x0/main.c
@@ -71,52 +71,3 @@ int mt76x0_config(struct ieee80211_hw *hw, u32 changed)
return ret;
 }
 EXPORT_SYMBOL_GPL(mt76x0_config);
-
-void mt76x0_bss_info_changed(struct ieee80211_hw *hw,
-struct ieee80211_vif *vif,
-struct ieee80211_bss_conf *info, u32 changed)
-{
-   struct mt76x02_vif *mvif = (struct mt76x02_vif *)vif->drv_priv;
-   struct mt76x02_dev *dev = hw->priv;
-
-   mutex_lock(>mt76.mutex);
-
-   if (changed & BSS_CHANGED_BSSID)
-   mt76x02_mac_set_bssid(dev, mvif->idx, info->bssid);
-
-   if (changed & BSS_CHANGED_BEACON_ENABLED) {
-   tasklet_disable(>pre_tbtt_tasklet);
-   mt76x02_mac_set_beacon_enable(dev, mvif->idx,
- info->enable_beacon);
-   tasklet_enable(>pre_tbtt_tasklet);
-   }
-
-   if (changed & BSS_CHANGED_BASIC_RATES) {
-   mt76_wr(dev, MT_LEGACY_BASIC_RATE, info->basic_rates);
-   mt76_wr(dev, MT_VHT_HT_FBK_CFG0, 0x65432100);
-   mt76_wr(dev, MT_VHT_HT_FBK_CFG1, 0xedcba980);
-   mt76_wr(dev, MT_LG_FBK_CFG0, 0xedcba988);
-   mt76_wr(dev, MT_LG_FBK_CFG1, 0x2100);
-   }
-
-   if (changed & BSS_CHANGED_BEACON_INT) {
-   mt76_rmw_field(dev, MT_BEACON_TIME_CFG,
-  MT_BEACON_TIME_CFG_INTVAL,
-  info->beacon_int << 4);
-   dev->beacon_int = info->beacon_int;
-   dev->tbtt_count = 0;
-   }
-
-   if (changed & BSS_CHANGED_ERP_PREAMBLE)
-   mt76x02_mac_set_short_preamble(dev, info->use_short_preamble);
-
-   if (changed & BSS_CHANGED_ERP_SLOT) {
-   int slottime = info->use_short_slot ? 9 : 20;
-
-   dev->slottime = slottime;
-   mt76x02_set_tx_ackto(dev);
-   }
-
-   mutex_unlock(>mt76.mutex);
-}
-EXPORT_SYMBOL_GPL(mt76x0_bss_info_changed);
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h 
b/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h
index 14ca5937ed97..46629f61673b 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h
@@ -62,9 +62,6 @@ int mt76x0_mac_start(struct mt76x02_dev *dev);
 void mt76x0_mac_stop(struct mt76x02_dev *dev);
 
 int mt76x0_config(struct ieee80211_hw *hw, u32 changed);
-void mt76x0_bss_info_changed(struct ieee80211_hw *hw,
-struct ieee80211_vif *vif,
-struct ieee80211_bss_conf *info, u32 changed);
 
 /* PHY */
 void mt76x0_phy_init(struct mt76x02_dev *dev);
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/pci.c 
b/drivers/net/wireless/mediatek/mt76/mt76x0/pci.c
index 0a5b499061e9..757816d2b1ab 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x0/pci.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x0/pci.c
@@ -89,7 +89,7 @@ static const struct ieee80211_ops mt76x0e_ops = {
.remove_interface = mt76x02_remove_interface,
.config = mt76x0_config,
.configure_filter = mt76x02_configure_filter,
-   .bss_info_changed = mt76x0_bss_info_changed,
+   .bss_info_changed = mt76x02_bss_info_changed,
.sta_add = mt76x02_sta_add,
.sta_remove = mt76x02_sta_remove,
.set_key = mt76x02_set_key,
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c 
b/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c
index 690c2e6abaeb..35b98661632a 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c
@@ -145,7 +145,7 @@ static const struct ieee80211_ops mt76x0u_ops = {
.remove_interface = mt76x02_remove_interface,
.config = mt76x0_config,
.configure_filter = mt76x02_configure_filter,
-   .bss_info_changed = mt76x0_bss_info_changed,
+   .bss_info_changed = mt76x02_bss_info_changed,
.sta_add = mt76x02_sta_add,
.sta_remove = mt76x02_sta_re

[PATCH 3/4] mt76: move tx protection routines in mt76x02-lib module

2018-10-20 Thread Lorenzo Bianconi
Move mt76x02_set_rts_threshold and mt76x02_mac_set_tx_protection
routines in mt76x02-lib module and remove duplicated code in mt76x0
and mt76x2 drivers. Remove pci_mac.c and mt76x0/mac.c since now are
empty files

Signed-off-by: Lorenzo Bianconi 
---
 .../wireless/mediatek/mt76/mt76x0/Makefile|  3 +-
 .../net/wireless/mediatek/mt76/mt76x0/mac.c   | 77 ---
 .../net/wireless/mediatek/mt76/mt76x0/main.c  | 14 
 .../wireless/mediatek/mt76/mt76x0/mt76x0.h|  5 --
 .../net/wireless/mediatek/mt76/mt76x0/pci.c   |  1 +
 .../net/wireless/mediatek/mt76/mt76x0/usb.c   |  2 +-
 drivers/net/wireless/mediatek/mt76/mt76x02.h  |  1 +
 .../net/wireless/mediatek/mt76/mt76x02_mac.c  | 30 
 .../net/wireless/mediatek/mt76/mt76x02_mac.h  |  4 +-
 .../net/wireless/mediatek/mt76/mt76x02_util.c | 15 
 .../wireless/mediatek/mt76/mt76x2/Makefile|  4 +-
 .../wireless/mediatek/mt76/mt76x2/mt76x2.h|  2 -
 .../wireless/mediatek/mt76/mt76x2/pci_mac.c   | 50 
 .../wireless/mediatek/mt76/mt76x2/pci_main.c  | 17 +---
 14 files changed, 54 insertions(+), 171 deletions(-)
 delete mode 100644 drivers/net/wireless/mediatek/mt76/mt76x0/mac.c
 delete mode 100644 drivers/net/wireless/mediatek/mt76/mt76x2/pci_mac.c

diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/Makefile 
b/drivers/net/wireless/mediatek/mt76/mt76x0/Makefile
index 1b4f2fa99317..aa22ba954716 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x0/Makefile
+++ b/drivers/net/wireless/mediatek/mt76/mt76x0/Makefile
@@ -2,8 +2,7 @@ obj-$(CONFIG_MT76x0U) += mt76x0u.o
 obj-$(CONFIG_MT76x0E) += mt76x0e.o
 obj-$(CONFIG_MT76x0_COMMON) += mt76x0-common.o
 
-mt76x0-common-y := \
-   init.o main.o eeprom.o phy.o mac.o
+mt76x0-common-y := init.o main.o eeprom.o phy.o
 
 mt76x0u-y := usb.o usb_mcu.o
 mt76x0e-y := pci.o pci_mcu.o
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/mac.c 
b/drivers/net/wireless/mediatek/mt76/mt76x0/mac.c
deleted file mode 100644
index 78d15cb006e0..
--- a/drivers/net/wireless/mediatek/mt76/mt76x0/mac.c
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright (C) 2014 Felix Fietkau 
- * Copyright (C) 2015 Jakub Kicinski 
- * Copyright (C) 2018 Stanislaw Gruszka 
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2
- * as published by the Free Software Foundation
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- */
-
-#include 
-
-#include "mt76x0.h"
-
-void mt76x0_mac_set_protection(struct mt76x02_dev *dev, bool legacy_prot,
-  int ht_mode)
-{
-   int mode = ht_mode & IEEE80211_HT_OP_MODE_PROTECTION;
-   bool non_gf = !!(ht_mode & IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT);
-   u32 prot[6];
-   bool ht_rts[4] = {};
-   int i;
-
-   prot[0] = MT_PROT_NAV_SHORT |
- MT_PROT_TXOP_ALLOW_ALL |
- MT_PROT_RTS_THR_EN;
-   prot[1] = prot[0];
-   if (legacy_prot)
-   prot[1] |= MT_PROT_CTRL_CTS2SELF;
-
-   prot[2] = prot[4] = MT_PROT_NAV_SHORT | MT_PROT_TXOP_ALLOW_BW20;
-   prot[3] = prot[5] = MT_PROT_NAV_SHORT | MT_PROT_TXOP_ALLOW_ALL;
-
-   if (legacy_prot) {
-   prot[2] |= MT_PROT_RATE_CCK_11;
-   prot[3] |= MT_PROT_RATE_CCK_11;
-   prot[4] |= MT_PROT_RATE_CCK_11;
-   prot[5] |= MT_PROT_RATE_CCK_11;
-   } else {
-   prot[2] |= MT_PROT_RATE_OFDM_24;
-   prot[3] |= MT_PROT_RATE_DUP_OFDM_24;
-   prot[4] |= MT_PROT_RATE_OFDM_24;
-   prot[5] |= MT_PROT_RATE_DUP_OFDM_24;
-   }
-
-   switch (mode) {
-   case IEEE80211_HT_OP_MODE_PROTECTION_NONE:
-   break;
-
-   case IEEE80211_HT_OP_MODE_PROTECTION_NONMEMBER:
-   ht_rts[0] = ht_rts[1] = ht_rts[2] = ht_rts[3] = true;
-   break;
-
-   case IEEE80211_HT_OP_MODE_PROTECTION_20MHZ:
-   ht_rts[1] = ht_rts[3] = true;
-   break;
-
-   case IEEE80211_HT_OP_MODE_PROTECTION_NONHT_MIXED:
-   ht_rts[0] = ht_rts[1] = ht_rts[2] = ht_rts[3] = true;
-   break;
-   }
-
-   if (non_gf)
-   ht_rts[2] = ht_rts[3] = true;
-
-   for (i = 0; i < 4; i++)
-   if (ht_rts[i])
-   prot[i + 2] |= MT_PROT_CTRL_RTS_CTS;
-
-   for (i = 0; i < 6; i++)
-   mt76_wr(dev, MT_CCK_PROT_CFG + i * 4, prot[i]);
-}
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/main.c 
b/drivers/net/wireless/mediatek/mt76/mt76x0/main.c
index 8de19fe534a3..b8eba511d0f3 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x0/main.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x0/main.c
@@ -107,10 +107,6 @@ void

[PATCH 2/4] mt76x0: update init vals for MT_TX_PROT registers

2018-10-20 Thread Lorenzo Bianconi
Add missing VHT MT_TX_PROT register init values

Signed-off-by: Lorenzo Bianconi 
---
 .../net/wireless/mediatek/mt76/mt76x0/initvals.h  | 15 +--
 1 file changed, 9 insertions(+), 6 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/initvals.h 
b/drivers/net/wireless/mediatek/mt76/mt76x0/initvals.h
index 236dce6860b4..a1657922758e 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x0/initvals.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76x0/initvals.h
@@ -37,14 +37,14 @@ static const struct mt76_reg_pair common_mac_reg_table[] = {
{ MT_PBF_RX_MAX_PCNT,   0xfe9f },
{ MT_TX_RETRY_CFG,  0x47d01f0f },
{ MT_AUTO_RSP_CFG,  0x0013 },
-   { MT_CCK_PROT_CFG,  0x05740003 },
-   { MT_OFDM_PROT_CFG, 0x05740003 },
+   { MT_CCK_PROT_CFG,  0x07f40003 },
+   { MT_OFDM_PROT_CFG, 0x07f42004 },
{ MT_PBF_CFG,   0x00f40006 },
{ MT_WPDMA_GLO_CFG, 0x0030 },
-   { MT_GF20_PROT_CFG, 0x01744004 },
-   { MT_GF40_PROT_CFG, 0x03f44084 },
-   { MT_MM20_PROT_CFG, 0x01744004 },
-   { MT_MM40_PROT_CFG, 0x03f54084 },
+   { MT_GF20_PROT_CFG, 0x01742004 },
+   { MT_GF40_PROT_CFG, 0x03f42084 },
+   { MT_MM20_PROT_CFG, 0x01742004 },
+   { MT_MM40_PROT_CFG, 0x03f42084 },
{ MT_TXOP_CTRL_CFG, 0x583f },
{ MT_TX_RTS_CFG,0x00092b20 },
{ MT_EXP_ACK_TIME,  0x002400ca },
@@ -85,6 +85,9 @@ static const struct mt76_reg_pair mt76x0_mac_reg_table[] = {
{ MT_HT_CTRL_CFG,   0x01FF },
{ MT_TXOP_HLDR_ET,  0x },
{ MT_PN_PAD_MODE,   0x0003 },
+   { MT_TX_PROT_CFG6,  0xe3f42004 },
+   { MT_TX_PROT_CFG7,  0xe3f42084 },
+   { MT_TX_PROT_CFG8,  0xe3f42104 },
 };
 
 static const struct mt76_reg_pair mt76x0_bbp_init_tab[] = {
-- 
2.19.1



[PATCH 1/4] mt76: move mt76x02_set_tx_ackto in mt76x02-lib module

2018-10-20 Thread Lorenzo Bianconi
Move mt76x02_set_tx_ackto and mt76x02_set_coverage_class routines
in mt76x02-lib module in order to be reused by mt76x0 driver.
This is a preliminary patch to unify drv_bss_info_changed mac80211
callback between mt76x0 and mt76x2 drivers

Signed-off-by: Lorenzo Bianconi 
---
 .../net/wireless/mediatek/mt76/mt76x0/main.c  |  4 +--
 .../net/wireless/mediatek/mt76/mt76x0/pci.c   |  1 +
 drivers/net/wireless/mediatek/mt76/mt76x02.h  |  3 ++
 .../net/wireless/mediatek/mt76/mt76x02_util.c | 30 +++
 .../wireless/mediatek/mt76/mt76x2/mt76x2.h|  1 -
 .../wireless/mediatek/mt76/mt76x2/pci_init.c  | 19 +---
 .../wireless/mediatek/mt76/mt76x2/pci_main.c  | 15 ++
 7 files changed, 39 insertions(+), 34 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/main.c 
b/drivers/net/wireless/mediatek/mt76/mt76x0/main.c
index 3dff198bbccd..8de19fe534a3 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x0/main.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x0/main.c
@@ -117,8 +117,8 @@ void mt76x0_bss_info_changed(struct ieee80211_hw *hw,
if (changed & BSS_CHANGED_ERP_SLOT) {
int slottime = info->use_short_slot ? 9 : 20;
 
-   mt76_rmw_field(dev, MT_BKOFF_SLOT_CFG,
-  MT_BKOFF_SLOT_CFG_SLOTTIME, slottime);
+   dev->slottime = slottime;
+   mt76x02_set_tx_ackto(dev);
}
 
mutex_unlock(>mt76.mutex);
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/pci.c 
b/drivers/net/wireless/mediatek/mt76/mt76x0/pci.c
index 08412bbf7dcb..b16227fdbdc4 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x0/pci.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x0/pci.c
@@ -104,6 +104,7 @@ static const struct ieee80211_ops mt76x0e_ops = {
.flush = mt76x0e_flush,
.set_tim = mt76x0e_set_tim,
.release_buffered_frames = mt76_release_buffered_frames,
+   .set_coverage_class = mt76x02_set_coverage_class,
 };
 
 static int mt76x0e_register_device(struct mt76x02_dev *dev)
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02.h 
b/drivers/net/wireless/mediatek/mt76/mt76x02.h
index a4141265d7a9..95af2b1c7eed 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02.h
@@ -133,6 +133,9 @@ s8 mt76x02_tx_get_max_txpwr_adj(struct mt76x02_dev *dev,
 s8 mt76x02_tx_get_txpwr_adj(struct mt76x02_dev *dev, s8 txpwr,
s8 max_txpwr_adj);
 void mt76x02_tx_set_txpwr_auto(struct mt76x02_dev *dev, s8 txpwr);
+void mt76x02_set_tx_ackto(struct mt76x02_dev *dev);
+void mt76x02_set_coverage_class(struct ieee80211_hw *hw,
+   s16 coverage_class);
 int mt76x02_insert_hdr_pad(struct sk_buff *skb);
 void mt76x02_remove_hdr_pad(struct sk_buff *skb, int len);
 void mt76x02_tx_complete(struct mt76_dev *dev, struct sk_buff *skb);
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c 
b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
index 2a81d2fc5d4d..c485f6600ae9 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
@@ -438,6 +438,36 @@ int mt76x02_conf_tx(struct ieee80211_hw *hw, struct 
ieee80211_vif *vif,
 }
 EXPORT_SYMBOL_GPL(mt76x02_conf_tx);
 
+void mt76x02_set_tx_ackto(struct mt76x02_dev *dev)
+{
+   u8 ackto, sifs, slottime = dev->slottime;
+
+   /* As defined by IEEE 802.11-2007 17.3.8.6 */
+   slottime += 3 * dev->coverage_class;
+   mt76_rmw_field(dev, MT_BKOFF_SLOT_CFG,
+  MT_BKOFF_SLOT_CFG_SLOTTIME, slottime);
+
+   sifs = mt76_get_field(dev, MT_XIFS_TIME_CFG,
+ MT_XIFS_TIME_CFG_OFDM_SIFS);
+
+   ackto = slottime + sifs;
+   mt76_rmw_field(dev, MT_TX_TIMEOUT_CFG,
+  MT_TX_TIMEOUT_CFG_ACKTO, ackto);
+}
+EXPORT_SYMBOL_GPL(mt76x02_set_tx_ackto);
+
+void mt76x02_set_coverage_class(struct ieee80211_hw *hw,
+   s16 coverage_class)
+{
+   struct mt76x02_dev *dev = hw->priv;
+
+   mutex_lock(>mt76.mutex);
+   dev->coverage_class = coverage_class;
+   mt76x02_set_tx_ackto(dev);
+   mutex_unlock(>mt76.mutex);
+}
+EXPORT_SYMBOL_GPL(mt76x02_set_coverage_class);
+
 void mt76x02_sta_rate_tbl_update(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
struct ieee80211_sta *sta)
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/mt76x2.h 
b/drivers/net/wireless/mediatek/mt76/mt76x2/mt76x2.h
index 0c323a0762e8..3f0b9c78625d 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x2/mt76x2.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76x2/mt76x2.h
@@ -58,7 +58,6 @@ int mt76x2_init_hardware(struct mt76x02_dev *dev);
 void mt76x2_stop_hardware(struct mt76x02_dev *dev);
 int mt76x2_eeprom_init(struct mt76x02_dev *dev);
 int mt76x2_apply_calibration_data(struct mt76x02_dev *dev, int channel);
-

[PATCH 0/4] unify drv_bss_info_changed between mt76x0 and mt76x2

2018-10-20 Thread Lorenzo Bianconi
Unify drv_bss_info_changed mac80211 callback between mt76x0 and mt76x2.
Move ack timeout and protection utility routines in mt76x02-lib module.

This series is based on top of 'enable AP support in mt76x0e driver' one:
https://patchwork.kernel.org/cover/10650335/

Lorenzo Bianconi (4):
  mt76: move mt76x02_set_tx_ackto in mt76x02-lib module
  mt76x0: update init vals for MT_TX_PROT registers
  mt76: move tx protection routines in mt76x02-lib module
  mt76: move mt76x02_bss_info_changed in mt76x02-lib module

 .../wireless/mediatek/mt76/mt76x0/Makefile|  3 +-
 .../wireless/mediatek/mt76/mt76x0/initvals.h  | 15 ++--
 .../net/wireless/mediatek/mt76/mt76x0/mac.c   | 77 
 .../net/wireless/mediatek/mt76/mt76x0/main.c  | 63 --
 .../wireless/mediatek/mt76/mt76x0/mt76x0.h|  8 --
 .../net/wireless/mediatek/mt76/mt76x0/pci.c   |  4 +-
 .../net/wireless/mediatek/mt76/mt76x0/usb.c   |  4 +-
 drivers/net/wireless/mediatek/mt76/mt76x02.h  |  7 ++
 .../net/wireless/mediatek/mt76/mt76x02_mac.c  | 30 +++
 .../net/wireless/mediatek/mt76/mt76x02_mac.h  |  4 +-
 .../net/wireless/mediatek/mt76/mt76x02_util.c | 87 +++
 .../wireless/mediatek/mt76/mt76x2/Makefile|  4 +-
 .../wireless/mediatek/mt76/mt76x2/mt76x2.h|  3 -
 .../wireless/mediatek/mt76/mt76x2/pci_init.c  | 19 +---
 .../wireless/mediatek/mt76/mt76x2/pci_mac.c   | 50 ---
 .../wireless/mediatek/mt76/mt76x2/pci_main.c  | 69 +--
 16 files changed, 147 insertions(+), 300 deletions(-)
 delete mode 100644 drivers/net/wireless/mediatek/mt76/mt76x0/mac.c
 delete mode 100644 drivers/net/wireless/mediatek/mt76/mt76x2/pci_mac.c

-- 
2.19.1



[PATCH 8/9] mt76: introduce mt76x02_init_beacon_config routine

2018-10-20 Thread Lorenzo Bianconi
Add mt76x02_init_beacon_config utility routine in mt76x02-lib
module in order to be reused by mt76x0 driver configuring
BSSID registers and remove duplicated code

Signed-off-by: Lorenzo Bianconi 
---
 .../net/wireless/mediatek/mt76/mt76x0/init.c  |  8 +
 drivers/net/wireless/mediatek/mt76/mt76x02.h  |  2 +-
 .../net/wireless/mediatek/mt76/mt76x02_util.c | 30 +--
 .../wireless/mediatek/mt76/mt76x2/pci_init.c  | 19 +---
 4 files changed, 31 insertions(+), 28 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/init.c 
b/drivers/net/wireless/mediatek/mt76/mt76x0/init.c
index 95a015281697..64eb6f451541 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x0/init.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x0/init.c
@@ -135,8 +135,6 @@ static void mt76x0_init_mac_registers(struct mt76x02_dev 
*dev)
 {
RANDOM_WRITE(dev, common_mac_reg_table);
 
-   mt76x02_set_beacon_offsets(dev);
-
/* Enable PBF and MAC clock SYS_CTRL[11:10] = 0x3 */
RANDOM_WRITE(dev, mt76x0_mac_reg_table);
 
@@ -297,11 +295,6 @@ int mt76x0_init_hardware(struct mt76x02_dev *dev)
if (ret)
return ret;
 
-   mt76_clear(dev, MT_BEACON_TIME_CFG, (MT_BEACON_TIME_CFG_TIMER_EN |
-MT_BEACON_TIME_CFG_SYNC_MODE |
-MT_BEACON_TIME_CFG_TBTT_EN |
-MT_BEACON_TIME_CFG_BEACON_TX));
-
mt76x0_reset_counters(dev);
 
ret = mt76x0_eeprom_init(dev);
@@ -309,6 +302,7 @@ int mt76x0_init_hardware(struct mt76x02_dev *dev)
return ret;
 
mt76x0_phy_init(dev);
+   mt76x02_init_beacon_config(dev);
 
return 0;
 }
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02.h 
b/drivers/net/wireless/mediatek/mt76/mt76x02.h
index 1733226b657d..a4141265d7a9 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02.h
@@ -156,7 +156,7 @@ int mt76x02_get_txpower(struct ieee80211_hw *hw,
 void mt76x02_sta_ps(struct mt76_dev *dev, struct ieee80211_sta *sta, bool ps);
 
 extern const u16 mt76x02_beacon_offsets[16];
-void mt76x02_set_beacon_offsets(struct mt76x02_dev *dev);
+void mt76x02_init_beacon_config(struct mt76x02_dev *dev);
 void mt76x02_set_irq_mask(struct mt76x02_dev *dev, u32 clear, u32 set);
 void mt76x02_mac_start(struct mt76x02_dev *dev);
 
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c 
b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
index 4e358066bf9b..2a81d2fc5d4d 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
@@ -560,7 +560,7 @@ const u16 mt76x02_beacon_offsets[16] = {
 };
 EXPORT_SYMBOL_GPL(mt76x02_beacon_offsets);
 
-void mt76x02_set_beacon_offsets(struct mt76x02_dev *dev)
+static void mt76x02_set_beacon_offsets(struct mt76x02_dev *dev)
 {
u16 val, base = MT_BEACON_BASE;
u32 regs[4] = {};
@@ -574,6 +574,32 @@ void mt76x02_set_beacon_offsets(struct mt76x02_dev *dev)
for (i = 0; i < 4; i++)
mt76_wr(dev, MT_BCN_OFFSET(i), regs[i]);
 }
-EXPORT_SYMBOL_GPL(mt76x02_set_beacon_offsets);
+
+void mt76x02_init_beacon_config(struct mt76x02_dev *dev)
+{
+   static const u8 null_addr[ETH_ALEN] = {};
+   int i;
+
+   mt76_wr(dev, MT_MAC_BSSID_DW0,
+   get_unaligned_le32(dev->mt76.macaddr));
+   mt76_wr(dev, MT_MAC_BSSID_DW1,
+   get_unaligned_le16(dev->mt76.macaddr + 4) |
+   FIELD_PREP(MT_MAC_BSSID_DW1_MBSS_MODE, 3) | /* 8 beacons */
+   MT_MAC_BSSID_DW1_MBSS_LOCAL_BIT);
+
+   /* Fire a pre-TBTT interrupt 8 ms before TBTT */
+   mt76_rmw_field(dev, MT_INT_TIMER_CFG, MT_INT_TIMER_CFG_PRE_TBTT,
+  8 << 4);
+   mt76_wr(dev, MT_INT_TIMER_EN, 0);
+
+   mt76_wr(dev, MT_BCN_BYPASS_MASK, 0x);
+
+   for (i = 0; i < 8; i++) {
+   mt76x02_mac_set_bssid(dev, i, null_addr);
+   mt76x02_mac_set_beacon(dev, i, NULL);
+   }
+   mt76x02_set_beacon_offsets(dev);
+}
+EXPORT_SYMBOL_GPL(mt76x02_init_beacon_config);
 
 MODULE_LICENSE("Dual BSD/GPL");
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/pci_init.c 
b/drivers/net/wireless/mediatek/mt76/mt76x2/pci_init.c
index c3c2f4441777..f561f5916625 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x2/pci_init.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x2/pci_init.c
@@ -79,7 +79,6 @@ mt76x2_fixup_xtal(struct mt76x02_dev *dev)
 
 static int mt76x2_mac_reset(struct mt76x02_dev *dev, bool hard)
 {
-   static const u8 null_addr[ETH_ALEN] = {};
const u8 *macaddr = dev->mt76.macaddr;
u32 val;
int i, k;
@@ -123,19 +122,10 @@ static int mt76x2_mac_reset(struct mt76x02_dev *dev, bool 
hard)
mt76_wr(dev, MT_MAC_ADDR_DW0, get_unaligned_le32(macaddr));
mt76_wr(dev, MT_MAC_ADDR_DW1,

[PATCH 4/9] mt76x0: pci: add pre_tbtt_tasklet support

2018-10-20 Thread Lorenzo Bianconi
Enable/disable pre_tbtt_tasklet in mt76x0 driver in order
to add AP support

Signed-off-by: Lorenzo Bianconi 
---
 drivers/net/wireless/mediatek/mt76/mt76x0/main.c | 2 ++
 drivers/net/wireless/mediatek/mt76/mt76x0/pci.c  | 1 +
 drivers/net/wireless/mediatek/mt76/mt76x02.h | 2 --
 drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c| 6 --
 drivers/net/wireless/mediatek/mt76/mt76x2/pci_init.c | 3 ---
 5 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/main.c 
b/drivers/net/wireless/mediatek/mt76/mt76x0/main.c
index a61b23239cb2..da98382bdb5a 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x0/main.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x0/main.c
@@ -22,6 +22,7 @@ mt76x0_set_channel(struct mt76x02_dev *dev, struct 
cfg80211_chan_def *chandef)
int ret;
 
cancel_delayed_work_sync(>cal_work);
+   tasklet_disable(>pre_tbtt_tasklet);
 
mt76_set_channel(>mt76);
ret = mt76x0_phy_set_channel(dev, chandef);
@@ -30,6 +31,7 @@ mt76x0_set_channel(struct mt76x02_dev *dev, struct 
cfg80211_chan_def *chandef)
mt76_rr(dev, MT_CH_IDLE);
mt76_rr(dev, MT_CH_BUSY);
 
+   tasklet_enable(>pre_tbtt_tasklet);
mt76_txq_schedule_all(>mt76);
 
return ret;
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/pci.c 
b/drivers/net/wireless/mediatek/mt76/mt76x0/pci.c
index 6e11b8c8e495..f15f9bf14900 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x0/pci.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x0/pci.c
@@ -187,6 +187,7 @@ mt76x0e_probe(struct pci_dev *pdev, const struct 
pci_device_id *id)
 static void mt76x0e_cleanup(struct mt76x02_dev *dev)
 {
clear_bit(MT76_STATE_INITIALIZED, >mt76.state);
+   tasklet_disable(>pre_tbtt_tasklet);
mt76x0_chip_onoff(dev, false, false);
mt76x0e_stop_hw(dev);
mt76x02_dma_cleanup(dev);
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02.h 
b/drivers/net/wireless/mediatek/mt76/mt76x02.h
index 72343d329f81..1cd0f758587d 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02.h
@@ -148,8 +148,6 @@ int mt76x02_tx_prepare_skb(struct mt76_dev *mdev, void 
*txwi,
   struct mt76_wcid *wcid, struct ieee80211_sta *sta,
   u32 *tx_info);
 
-void mt76x02_pre_tbtt_tasklet(unsigned long arg);
-
 extern const u16 mt76x02_beacon_offsets[16];
 void mt76x02_set_beacon_offsets(struct mt76x02_dev *dev);
 void mt76x02_set_irq_mask(struct mt76x02_dev *dev, u32 clear, u32 set);
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c 
b/drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c
index ab1c8c8ef15b..66315410aebe 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c
@@ -99,7 +99,7 @@ mt76x02_resync_beacon_timer(struct mt76x02_dev *dev)
   MT_BEACON_TIME_CFG_INTVAL, timer_val);
 }
 
-void mt76x02_pre_tbtt_tasklet(unsigned long arg)
+static void mt76x02_pre_tbtt_tasklet(unsigned long arg)
 {
struct mt76x02_dev *dev = (struct mt76x02_dev *)arg;
struct mt76_queue *q = >mt76.q_tx[MT_TXQ_PSD];
@@ -144,7 +144,6 @@ void mt76x02_pre_tbtt_tasklet(unsigned long arg)
}
spin_unlock_bh(>lock);
 }
-EXPORT_SYMBOL_GPL(mt76x02_pre_tbtt_tasklet);
 
 static int
 mt76x02_init_tx_queue(struct mt76x02_dev *dev, struct mt76_queue *q,
@@ -223,6 +222,9 @@ int mt76x02_dma_init(struct mt76x02_dev *dev)
return -ENOMEM;
 
tasklet_init(>tx_tasklet, mt76x02_tx_tasklet, (unsigned long) dev);
+   tasklet_init(>pre_tbtt_tasklet, mt76x02_pre_tbtt_tasklet,
+(unsigned long)dev);
+
kfifo_init(>txstatus_fifo, status_fifo, fifo_size);
 
mt76_dma_attach(>mt76);
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/pci_init.c 
b/drivers/net/wireless/mediatek/mt76/mt76x2/pci_init.c
index bc1dbdf5af20..c5d5fcbd9a55 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x2/pci_init.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x2/pci_init.c
@@ -298,9 +298,6 @@ int mt76x2_init_hardware(struct mt76x02_dev *dev)
 {
int ret;
 
-   tasklet_init(>pre_tbtt_tasklet, mt76x02_pre_tbtt_tasklet,
-(unsigned long) dev);
-
mt76x02_dma_disable(dev);
mt76x2_reset_wlan(dev, true);
mt76x2_power_on(dev);
-- 
2.19.1



[PATCH 3/9] mt76: move tx beacon routines in mt76x02-lib module

2018-10-20 Thread Lorenzo Bianconi
Move mt76x02_tx beacon utility routines in mt76x02_mmio.c
in order to be reused by mt76x0 driver adding AP support

Signed-off-by: Lorenzo Bianconi 
---
 drivers/net/wireless/mediatek/mt76/mt76x02.h  |   2 +
 .../net/wireless/mediatek/mt76/mt76x02_mmio.c | 125 +++
 .../wireless/mediatek/mt76/mt76x2/Makefile|   4 +-
 .../wireless/mediatek/mt76/mt76x2/mt76x2.h|   2 -
 .../wireless/mediatek/mt76/mt76x2/pci_init.c  |   2 +-
 .../wireless/mediatek/mt76/mt76x2/pci_tx.c| 142 --
 6 files changed, 130 insertions(+), 147 deletions(-)
 delete mode 100644 drivers/net/wireless/mediatek/mt76/mt76x2/pci_tx.c

diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02.h 
b/drivers/net/wireless/mediatek/mt76/mt76x02.h
index 1cd0f758587d..72343d329f81 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02.h
@@ -148,6 +148,8 @@ int mt76x02_tx_prepare_skb(struct mt76_dev *mdev, void 
*txwi,
   struct mt76_wcid *wcid, struct ieee80211_sta *sta,
   u32 *tx_info);
 
+void mt76x02_pre_tbtt_tasklet(unsigned long arg);
+
 extern const u16 mt76x02_beacon_offsets[16];
 void mt76x02_set_beacon_offsets(struct mt76x02_dev *dev);
 void mt76x02_set_irq_mask(struct mt76x02_dev *dev, u32 clear, u32 set);
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c 
b/drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c
index 784b76e08382..ab1c8c8ef15b 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c
@@ -21,6 +21,131 @@
 #include "mt76x02.h"
 #include "mt76x02_trace.h"
 
+struct beacon_bc_data {
+   struct mt76x02_dev *dev;
+   struct sk_buff_head q;
+   struct sk_buff *tail[8];
+};
+
+static void
+mt76x02_update_beacon_iter(void *priv, u8 *mac, struct ieee80211_vif *vif)
+{
+   struct mt76x02_dev *dev = (struct mt76x02_dev *)priv;
+   struct mt76x02_vif *mvif = (struct mt76x02_vif *)vif->drv_priv;
+   struct sk_buff *skb = NULL;
+
+   if (!(dev->beacon_mask & BIT(mvif->idx)))
+   return;
+
+   skb = ieee80211_beacon_get(mt76_hw(dev), vif);
+   if (!skb)
+   return;
+
+   mt76x02_mac_set_beacon(dev, mvif->idx, skb);
+}
+
+static void
+mt76x02_add_buffered_bc(void *priv, u8 *mac, struct ieee80211_vif *vif)
+{
+   struct beacon_bc_data *data = priv;
+   struct mt76x02_dev *dev = data->dev;
+   struct mt76x02_vif *mvif = (struct mt76x02_vif *)vif->drv_priv;
+   struct ieee80211_tx_info *info;
+   struct sk_buff *skb;
+
+   if (!(dev->beacon_mask & BIT(mvif->idx)))
+   return;
+
+   skb = ieee80211_get_buffered_bc(mt76_hw(dev), vif);
+   if (!skb)
+   return;
+
+   info = IEEE80211_SKB_CB(skb);
+   info->control.vif = vif;
+   info->flags |= IEEE80211_TX_CTL_ASSIGN_SEQ;
+   mt76_skb_set_moredata(skb, true);
+   __skb_queue_tail(>q, skb);
+   data->tail[mvif->idx] = skb;
+}
+
+static void
+mt76x02_resync_beacon_timer(struct mt76x02_dev *dev)
+{
+   u32 timer_val = dev->beacon_int << 4;
+
+   dev->tbtt_count++;
+
+   /*
+* Beacon timer drifts by 1us every tick, the timer is configured
+* in 1/16 TU (64us) units.
+*/
+   if (dev->tbtt_count < 62)
+   return;
+
+   if (dev->tbtt_count >= 64) {
+   dev->tbtt_count = 0;
+   return;
+   }
+
+   /*
+* The updated beacon interval takes effect after two TBTT, because
+* at this point the original interval has already been loaded into
+* the next TBTT_TIMER value
+*/
+   if (dev->tbtt_count == 62)
+   timer_val -= 1;
+
+   mt76_rmw_field(dev, MT_BEACON_TIME_CFG,
+  MT_BEACON_TIME_CFG_INTVAL, timer_val);
+}
+
+void mt76x02_pre_tbtt_tasklet(unsigned long arg)
+{
+   struct mt76x02_dev *dev = (struct mt76x02_dev *)arg;
+   struct mt76_queue *q = >mt76.q_tx[MT_TXQ_PSD];
+   struct beacon_bc_data data = {};
+   struct sk_buff *skb;
+   int i, nframes;
+
+   mt76x02_resync_beacon_timer(dev);
+
+   data.dev = dev;
+   __skb_queue_head_init();
+
+   ieee80211_iterate_active_interfaces_atomic(mt76_hw(dev),
+   IEEE80211_IFACE_ITER_RESUME_ALL,
+   mt76x02_update_beacon_iter, dev);
+
+   do {
+   nframes = skb_queue_len();
+   ieee80211_iterate_active_interfaces_atomic(mt76_hw(dev),
+   IEEE80211_IFACE_ITER_RESUME_ALL,
+   mt76x02_add_buffered_bc, );
+   } while (nframes != skb_queue_len());
+
+   if (!nframes)
+   return;
+
+   for (i = 0; i < ARRAY_SIZE(data.tail); i++) {
+   if (!data.tail[i])
+   continue;
+
+   m

[PATCH 9/9] mt76x0: pci: enable AP support

2018-10-20 Thread Lorenzo Bianconi
Add missing mac80211 callbacks to mt76x0e_ops data structure
and add mt76x02_beacon utility routines in mt76x0_bss_info_changed
in order to enable/disable beacon transmission

Signed-off-by: Lorenzo Bianconi 
---
 .../net/wireless/mediatek/mt76/mt76x0/mac.c   | 20 
 .../net/wireless/mediatek/mt76/mt76x0/main.c  | 32 +--
 .../wireless/mediatek/mt76/mt76x0/mt76x0.h|  2 --
 .../net/wireless/mediatek/mt76/mt76x0/pci.c   | 17 ++
 4 files changed, 32 insertions(+), 39 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/mac.c 
b/drivers/net/wireless/mediatek/mt76/mt76x0/mac.c
index ded0ad623723..78d15cb006e0 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x0/mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x0/mac.c
@@ -75,23 +75,3 @@ void mt76x0_mac_set_protection(struct mt76x02_dev *dev, bool 
legacy_prot,
for (i = 0; i < 6; i++)
mt76_wr(dev, MT_CCK_PROT_CFG + i * 4, prot[i]);
 }
-
-void mt76x0_mac_config_tsf(struct mt76x02_dev *dev, bool enable, int interval)
-{
-   u32 val = mt76_rr(dev, MT_BEACON_TIME_CFG);
-
-   val &= ~(MT_BEACON_TIME_CFG_TIMER_EN |
-MT_BEACON_TIME_CFG_SYNC_MODE |
-MT_BEACON_TIME_CFG_TBTT_EN);
-
-   if (!enable) {
-   mt76_wr(dev, MT_BEACON_TIME_CFG, val);
-   return;
-   }
-
-   val &= ~MT_BEACON_TIME_CFG_INTVAL;
-   val |= FIELD_PREP(MT_BEACON_TIME_CFG_INTVAL, interval << 4) |
-   MT_BEACON_TIME_CFG_TIMER_EN |
-   MT_BEACON_TIME_CFG_SYNC_MODE |
-   MT_BEACON_TIME_CFG_TBTT_EN;
-}
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/main.c 
b/drivers/net/wireless/mediatek/mt76/mt76x0/main.c
index 5747d72bd13a..3dff198bbccd 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x0/main.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x0/main.c
@@ -72,30 +72,23 @@ int mt76x0_config(struct ieee80211_hw *hw, u32 changed)
 }
 EXPORT_SYMBOL_GPL(mt76x0_config);
 
-static void
-mt76x0_addr_wr(struct mt76x02_dev *dev, const u32 offset, const u8 *addr)
-{
-   mt76_wr(dev, offset, get_unaligned_le32(addr));
-   mt76_wr(dev, offset + 4, addr[4] | addr[5] << 8);
-}
-
 void mt76x0_bss_info_changed(struct ieee80211_hw *hw,
 struct ieee80211_vif *vif,
 struct ieee80211_bss_conf *info, u32 changed)
 {
+   struct mt76x02_vif *mvif = (struct mt76x02_vif *)vif->drv_priv;
struct mt76x02_dev *dev = hw->priv;
 
mutex_lock(>mt76.mutex);
 
-   if (changed & BSS_CHANGED_BSSID) {
-   mt76x0_addr_wr(dev, MT_MAC_BSSID_DW0, info->bssid);
+   if (changed & BSS_CHANGED_BSSID)
+   mt76x02_mac_set_bssid(dev, mvif->idx, info->bssid);
 
-   /* Note: this is a hack because beacon_int is not changed
-*   on leave nor is any more appropriate event generated.
-*   rt2x00 doesn't seem to be bothered though.
-*/
-   if (is_zero_ether_addr(info->bssid))
-   mt76x0_mac_config_tsf(dev, false, 0);
+   if (changed & BSS_CHANGED_BEACON_ENABLED) {
+   tasklet_disable(>pre_tbtt_tasklet);
+   mt76x02_mac_set_beacon_enable(dev, mvif->idx,
+ info->enable_beacon);
+   tasklet_enable(>pre_tbtt_tasklet);
}
 
if (changed & BSS_CHANGED_BASIC_RATES) {
@@ -106,8 +99,13 @@ void mt76x0_bss_info_changed(struct ieee80211_hw *hw,
mt76_wr(dev, MT_LG_FBK_CFG1, 0x2100);
}
 
-   if (changed & BSS_CHANGED_BEACON_INT)
-   mt76x0_mac_config_tsf(dev, true, info->beacon_int);
+   if (changed & BSS_CHANGED_BEACON_INT) {
+   mt76_rmw_field(dev, MT_BEACON_TIME_CFG,
+  MT_BEACON_TIME_CFG_INTVAL,
+  info->beacon_int << 4);
+   dev->beacon_int = info->beacon_int;
+   dev->tbtt_count = 0;
+   }
 
if (changed & BSS_CHANGED_HT || changed & BSS_CHANGED_ERP_CTS_PROT)
mt76x0_mac_set_protection(dev, info->use_cts_prot,
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h 
b/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h
index 2f3abbe491c5..5b4f30225dc1 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h
@@ -78,6 +78,4 @@ void mt76x0_phy_calibrate(struct mt76x02_dev *dev, bool 
power_on);
 /* MAC */
 void mt76x0_mac_set_protection(struct mt76x02_dev *dev, bool legacy_prot,
int ht_mode);
-void mt76x0_mac_config_tsf(struct mt76x02_dev *dev, bool enable, int interval);
-
 #endif
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/pci.c 
b/drivers/net/wireless/mediatek/mt76/mt76x0/p

[PATCH 2/9] mt76: move mac beacon routines in mt76x02-lib module

2018-10-20 Thread Lorenzo Bianconi
Move mt76x02_beacon mac routines in mt76x02_mac.c in
order to be reused by mt76x0 driver adding AP support

Signed-off-by: Lorenzo Bianconi 
---
 .../net/wireless/mediatek/mt76/mt76x02_mac.c  | 123 ++
 .../net/wireless/mediatek/mt76/mt76x02_mac.h  |   6 +
 .../net/wireless/mediatek/mt76/mt76x2/mac.h   |   5 -
 .../wireless/mediatek/mt76/mt76x2/pci_init.c  |   4 +-
 .../wireless/mediatek/mt76/mt76x2/pci_mac.c   | 118 -
 .../wireless/mediatek/mt76/mt76x2/pci_main.c  |   6 +-
 .../wireless/mediatek/mt76/mt76x2/pci_tx.c|   2 +-
 7 files changed, 135 insertions(+), 129 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c 
b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
index f21bf0af8937..d9d7f3e609fc 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
@@ -794,3 +794,126 @@ void mt76x02_mac_work(struct work_struct *work)
 MT_CALIBRATE_INTERVAL);
 }
 EXPORT_SYMBOL_GPL(mt76x02_mac_work);
+
+void mt76x02_mac_set_bssid(struct mt76x02_dev *dev, u8 idx, const u8 *addr)
+{
+   idx &= 7;
+   mt76_wr(dev, MT_MAC_APC_BSSID_L(idx), get_unaligned_le32(addr));
+   mt76_rmw_field(dev, MT_MAC_APC_BSSID_H(idx), MT_MAC_APC_BSSID_H_ADDR,
+  get_unaligned_le16(addr + 4));
+}
+EXPORT_SYMBOL_GPL(mt76x02_mac_set_bssid);
+
+static int
+mt76x02_write_beacon(struct mt76x02_dev *dev, int offset, struct sk_buff *skb)
+{
+   int beacon_len = mt76x02_beacon_offsets[1] - mt76x02_beacon_offsets[0];
+   struct mt76x02_txwi txwi;
+
+   if (WARN_ON_ONCE(beacon_len < skb->len + sizeof(struct mt76x02_txwi)))
+   return -ENOSPC;
+
+   mt76x02_mac_write_txwi(dev, , skb, NULL, NULL, skb->len);
+
+   mt76_wr_copy(dev, offset, , sizeof(txwi));
+   offset += sizeof(txwi);
+
+   mt76_wr_copy(dev, offset, skb->data, skb->len);
+   return 0;
+}
+
+static int
+__mt76x02_mac_set_beacon(struct mt76x02_dev *dev, u8 bcn_idx,
+struct sk_buff *skb)
+{
+   int beacon_len = mt76x02_beacon_offsets[1] - mt76x02_beacon_offsets[0];
+   int beacon_addr = mt76x02_beacon_offsets[bcn_idx];
+   int ret = 0;
+   int i;
+
+   /* Prevent corrupt transmissions during update */
+   mt76_set(dev, MT_BCN_BYPASS_MASK, BIT(bcn_idx));
+
+   if (skb) {
+   ret = mt76x02_write_beacon(dev, beacon_addr, skb);
+   if (!ret)
+   dev->beacon_data_mask |= BIT(bcn_idx);
+   } else {
+   dev->beacon_data_mask &= ~BIT(bcn_idx);
+   for (i = 0; i < beacon_len; i += 4)
+   mt76_wr(dev, beacon_addr + i, 0);
+   }
+
+   mt76_wr(dev, MT_BCN_BYPASS_MASK, 0xff00 | ~dev->beacon_data_mask);
+
+   return ret;
+}
+
+int mt76x02_mac_set_beacon(struct mt76x02_dev *dev, u8 vif_idx,
+  struct sk_buff *skb)
+{
+   bool force_update = false;
+   int bcn_idx = 0;
+   int i;
+
+   for (i = 0; i < ARRAY_SIZE(dev->beacons); i++) {
+   if (vif_idx == i) {
+   force_update = !!dev->beacons[i] ^ !!skb;
+
+   if (dev->beacons[i])
+   dev_kfree_skb(dev->beacons[i]);
+
+   dev->beacons[i] = skb;
+   __mt76x02_mac_set_beacon(dev, bcn_idx, skb);
+   } else if (force_update && dev->beacons[i]) {
+   __mt76x02_mac_set_beacon(dev, bcn_idx,
+dev->beacons[i]);
+   }
+
+   bcn_idx += !!dev->beacons[i];
+   }
+
+   for (i = bcn_idx; i < ARRAY_SIZE(dev->beacons); i++) {
+   if (!(dev->beacon_data_mask & BIT(i)))
+   break;
+
+   __mt76x02_mac_set_beacon(dev, i, NULL);
+   }
+
+   mt76_rmw_field(dev, MT_MAC_BSSID_DW1, MT_MAC_BSSID_DW1_MBEACON_N,
+  bcn_idx - 1);
+   return 0;
+}
+EXPORT_SYMBOL_GPL(mt76x02_mac_set_beacon);
+
+void mt76x02_mac_set_beacon_enable(struct mt76x02_dev *dev,
+  u8 vif_idx, bool val)
+{
+   u8 old_mask = dev->beacon_mask;
+   bool en;
+   u32 reg;
+
+   if (val) {
+   dev->beacon_mask |= BIT(vif_idx);
+   } else {
+   dev->beacon_mask &= ~BIT(vif_idx);
+   mt76x02_mac_set_beacon(dev, vif_idx, NULL);
+   }
+
+   if (!!old_mask == !!dev->beacon_mask)
+   return;
+
+   en = dev->beacon_mask;
+
+   mt76_rmw_field(dev, MT_INT_TIMER_EN, MT_INT_TIMER_EN_PRE_TBTT_EN, en);
+   reg = MT_BEACON_TIME_CFG_BEACON_TX |
+ MT_BEACON_TIME_CFG_TBTT_EN |
+ MT_BEACON_TIME_CFG_TIMER_EN;
+   mt76_rmw(dev, MT_BEACON_TIME_CFG, reg, reg * en);

[PATCH 5/9] mt76: move mt76x02_sw_scan and mt76x02_sw_scan_complete in mt76x02-lib module

2018-10-20 Thread Lorenzo Bianconi
Move mt76x02_sw_scan and mt76x02_sw_scan_complete utility routines
in mt76x02_util.c in order to be reused by mt76x0 and mt76x2u drivers
and remove duplicated code

Signed-off-by: Lorenzo Bianconi 
---
 .../net/wireless/mediatek/mt76/mt76x0/main.c  | 18 ---
 .../wireless/mediatek/mt76/mt76x0/mt76x0.h|  4 
 .../net/wireless/mediatek/mt76/mt76x0/pci.c   |  4 ++--
 .../net/wireless/mediatek/mt76/mt76x0/usb.c   |  4 ++--
 drivers/net/wireless/mediatek/mt76/mt76x02.h  |  4 
 .../net/wireless/mediatek/mt76/mt76x02_util.c | 22 ++
 .../wireless/mediatek/mt76/mt76x2/pci_main.c  | 23 ++-
 .../wireless/mediatek/mt76/mt76x2/usb_main.c  | 21 ++---
 8 files changed, 34 insertions(+), 66 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/main.c 
b/drivers/net/wireless/mediatek/mt76/mt76x0/main.c
index da98382bdb5a..5747d72bd13a 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x0/main.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x0/main.c
@@ -127,24 +127,6 @@ void mt76x0_bss_info_changed(struct ieee80211_hw *hw,
 }
 EXPORT_SYMBOL_GPL(mt76x0_bss_info_changed);
 
-void mt76x0_sw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
-   const u8 *mac_addr)
-{
-   struct mt76x02_dev *dev = hw->priv;
-
-   set_bit(MT76_SCANNING, >mt76.state);
-}
-EXPORT_SYMBOL_GPL(mt76x0_sw_scan);
-
-void mt76x0_sw_scan_complete(struct ieee80211_hw *hw,
-struct ieee80211_vif *vif)
-{
-   struct mt76x02_dev *dev = hw->priv;
-
-   clear_bit(MT76_SCANNING, >mt76.state);
-}
-EXPORT_SYMBOL_GPL(mt76x0_sw_scan_complete);
-
 int mt76x0_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
 {
struct mt76x02_dev *dev = hw->priv;
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h 
b/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h
index 9cdecb9bfc64..2f3abbe491c5 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h
@@ -65,10 +65,6 @@ int mt76x0_config(struct ieee80211_hw *hw, u32 changed);
 void mt76x0_bss_info_changed(struct ieee80211_hw *hw,
 struct ieee80211_vif *vif,
 struct ieee80211_bss_conf *info, u32 changed);
-void mt76x0_sw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
-   const u8 *mac_addr);
-void mt76x0_sw_scan_complete(struct ieee80211_hw *hw,
-struct ieee80211_vif *vif);
 int mt76x0_set_rts_threshold(struct ieee80211_hw *hw, u32 value);
 
 /* PHY */
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/pci.c 
b/drivers/net/wireless/mediatek/mt76/mt76x0/pci.c
index f15f9bf14900..7f506975c9b9 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x0/pci.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x0/pci.c
@@ -80,8 +80,8 @@ static const struct ieee80211_ops mt76x0e_ops = {
.sta_remove = mt76x02_sta_remove,
.set_key = mt76x02_set_key,
.conf_tx = mt76x02_conf_tx,
-   .sw_scan_start = mt76x0_sw_scan,
-   .sw_scan_complete = mt76x0_sw_scan_complete,
+   .sw_scan_start = mt76x02_sw_scan,
+   .sw_scan_complete = mt76x02_sw_scan_complete,
.ampdu_action = mt76x02_ampdu_action,
.sta_rate_tbl_update = mt76x02_sta_rate_tbl_update,
.wake_tx_queue = mt76_wake_tx_queue,
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c 
b/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c
index 245eb4aa9764..8640ddf0e594 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c
@@ -150,8 +150,8 @@ static const struct ieee80211_ops mt76x0u_ops = {
.sta_remove = mt76x02_sta_remove,
.set_key = mt76x02_set_key,
.conf_tx = mt76x02_conf_tx,
-   .sw_scan_start = mt76x0_sw_scan,
-   .sw_scan_complete = mt76x0_sw_scan_complete,
+   .sw_scan_start = mt76x02_sw_scan,
+   .sw_scan_complete = mt76x02_sw_scan_complete,
.ampdu_action = mt76x02_ampdu_action,
.sta_rate_tbl_update = mt76x02_sta_rate_tbl_update,
.set_rts_threshold = mt76x0_set_rts_threshold,
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02.h 
b/drivers/net/wireless/mediatek/mt76/mt76x02.h
index 1cd0f758587d..0890794c92d7 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02.h
@@ -147,6 +147,10 @@ int mt76x02_tx_prepare_skb(struct mt76_dev *mdev, void 
*txwi,
   struct sk_buff *skb, struct mt76_queue *q,
   struct mt76_wcid *wcid, struct ieee80211_sta *sta,
   u32 *tx_info);
+void mt76x02_sw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+const u8 *mac);
+void mt76x02_sw_scan_complete(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif);
 
 extern const u16 mt76x02_beacon_off

[PATCH 0/9] enable AP support in mt76x0e driver

2018-10-20 Thread Lorenzo Bianconi
Add beacon transmission/management support to mt76x0 driver.
Add missing mac80211 callbacks to mt76x0e driver in order
to enable AP support

Lorenzo Bianconi (9):
  mt76: move mt76x02_init_device in mt76x02-lib module
  mt76: move mac beacon routines in mt76x02-lib module
  mt76: move tx beacon routines in mt76x02-lib module
  mt76x0: pci: add pre_tbtt_tasklet support
  mt76: move mt76x02_sw_scan and mt76x02_sw_scan_complete in mt76x02-lib
module
  mt76: move mt76x02_get_txpower in mt76x02_util.c
  mt76: move mt76x02_sta_ps in mt76x02-lib module
  mt76: introduce mt76x02_init_beacon_config routine
  mt76x0: pci: enable AP support

 .../wireless/mediatek/mt76/mt76x0/eeprom.c|   2 -
 .../net/wireless/mediatek/mt76/mt76x0/init.c  |  44 +
 .../net/wireless/mediatek/mt76/mt76x0/mac.c   |  20 ---
 .../net/wireless/mediatek/mt76/mt76x0/main.c  |  52 ++
 .../wireless/mediatek/mt76/mt76x0/mt76x0.h|   6 -
 .../net/wireless/mediatek/mt76/mt76x0/pci.c   |  24 ++-
 .../net/wireless/mediatek/mt76/mt76x0/usb.c   |   5 +-
 drivers/net/wireless/mediatek/mt76/mt76x02.h  |  10 +-
 .../net/wireless/mediatek/mt76/mt76x02_mac.c  | 123 +
 .../net/wireless/mediatek/mt76/mt76x02_mac.h  |   6 +
 .../net/wireless/mediatek/mt76/mt76x02_mmio.c | 127 ++
 .../net/wireless/mediatek/mt76/mt76x02_util.c | 163 +-
 .../wireless/mediatek/mt76/mt76x2/Makefile|   4 +-
 .../net/wireless/mediatek/mt76/mt76x2/init.c  |  34 
 .../net/wireless/mediatek/mt76/mt76x2/mac.h   |   5 -
 .../wireless/mediatek/mt76/mt76x2/mt76x2.h|   5 -
 .../wireless/mediatek/mt76/mt76x2/pci_init.c  |  65 +--
 .../wireless/mediatek/mt76/mt76x2/pci_mac.c   | 118 -
 .../wireless/mediatek/mt76/mt76x2/pci_main.c  |  55 +-
 .../wireless/mediatek/mt76/mt76x2/pci_tx.c| 142 ---
 .../wireless/mediatek/mt76/mt76x2/usb_init.c  |   5 +-
 .../wireless/mediatek/mt76/mt76x2/usb_main.c  |  22 +--
 22 files changed, 487 insertions(+), 550 deletions(-)
 delete mode 100644 drivers/net/wireless/mediatek/mt76/mt76x2/pci_tx.c

-- 
2.19.1



[PATCH 6/9] mt76: move mt76x02_get_txpower in mt76x02_util.c

2018-10-20 Thread Lorenzo Bianconi
Move mt76x02_get_txpower utility routine in mt76x02-lib module
in order to be reused by mt76x0 and mt76x2u drivers

Signed-off-by: Lorenzo Bianconi 
---
 .../net/wireless/mediatek/mt76/mt76x0/pci.c|  1 +
 .../net/wireless/mediatek/mt76/mt76x0/usb.c|  1 +
 drivers/net/wireless/mediatek/mt76/mt76x02.h   |  2 ++
 .../net/wireless/mediatek/mt76/mt76x02_util.c  | 18 ++
 .../wireless/mediatek/mt76/mt76x2/pci_main.c   | 15 +--
 .../wireless/mediatek/mt76/mt76x2/usb_main.c   |  1 +
 6 files changed, 24 insertions(+), 14 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/pci.c 
b/drivers/net/wireless/mediatek/mt76/mt76x0/pci.c
index 7f506975c9b9..4d4800d09da6 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x0/pci.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x0/pci.c
@@ -86,6 +86,7 @@ static const struct ieee80211_ops mt76x0e_ops = {
.sta_rate_tbl_update = mt76x02_sta_rate_tbl_update,
.wake_tx_queue = mt76_wake_tx_queue,
.get_survey = mt76_get_survey,
+   .get_txpower = mt76x02_get_txpower,
 };
 
 static int mt76x0e_register_device(struct mt76x02_dev *dev)
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c 
b/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c
index 8640ddf0e594..2105e966f745 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c
@@ -156,6 +156,7 @@ static const struct ieee80211_ops mt76x0u_ops = {
.sta_rate_tbl_update = mt76x02_sta_rate_tbl_update,
.set_rts_threshold = mt76x0_set_rts_threshold,
.wake_tx_queue = mt76_wake_tx_queue,
+   .get_txpower = mt76x02_get_txpower,
 };
 
 static int mt76x0u_register_device(struct mt76x02_dev *dev)
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02.h 
b/drivers/net/wireless/mediatek/mt76/mt76x02.h
index 0890794c92d7..f830e39b58e7 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02.h
@@ -151,6 +151,8 @@ void mt76x02_sw_scan(struct ieee80211_hw *hw, struct 
ieee80211_vif *vif,
 const u8 *mac);
 void mt76x02_sw_scan_complete(struct ieee80211_hw *hw,
  struct ieee80211_vif *vif);
+int mt76x02_get_txpower(struct ieee80211_hw *hw,
+   struct ieee80211_vif *vif, int *dbm);
 
 extern const u16 mt76x02_beacon_offsets[16];
 void mt76x02_set_beacon_offsets(struct mt76x02_dev *dev);
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c 
b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
index bbc2cab4ffdc..25f36e333b9b 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
@@ -508,6 +508,24 @@ void mt76x02_sw_scan_complete(struct ieee80211_hw *hw,
 }
 EXPORT_SYMBOL_GPL(mt76x02_sw_scan_complete);
 
+int mt76x02_get_txpower(struct ieee80211_hw *hw,
+   struct ieee80211_vif *vif, int *dbm)
+{
+   struct mt76x02_dev *dev = hw->priv;
+   u8 nstreams = dev->mt76.chainmask & 0xf;
+
+   *dbm = dev->mt76.txpower_cur / 2;
+
+   /* convert from per-chain power to combined
+* output on 2x2 devices
+*/
+   if (nstreams > 1)
+   *dbm += 3;
+
+   return 0;
+}
+EXPORT_SYMBOL_GPL(mt76x02_get_txpower);
+
 const u16 mt76x02_beacon_offsets[16] = {
/* 1024 byte per beacon */
0xc000,
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/pci_main.c 
b/drivers/net/wireless/mediatek/mt76/mt76x2/pci_main.c
index 36042331e4b2..5dfd06e56636 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x2/pci_main.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x2/pci_main.c
@@ -181,19 +181,6 @@ mt76x2_flush(struct ieee80211_hw *hw, struct ieee80211_vif 
*vif,
 {
 }
 
-static int
-mt76x2_get_txpower(struct ieee80211_hw *hw, struct ieee80211_vif *vif, int 
*dbm)
-{
-   struct mt76x02_dev *dev = hw->priv;
-
-   *dbm = dev->mt76.txpower_cur / 2;
-
-   /* convert from per-chain power to combined output on 2x2 devices */
-   *dbm += 3;
-
-   return 0;
-}
-
 static void mt76x2_set_coverage_class(struct ieee80211_hw *hw,
  s16 coverage_class)
 {
@@ -277,7 +264,7 @@ const struct ieee80211_ops mt76x2_ops = {
.sw_scan_complete = mt76x02_sw_scan_complete,
.flush = mt76x2_flush,
.ampdu_action = mt76x02_ampdu_action,
-   .get_txpower = mt76x2_get_txpower,
+   .get_txpower = mt76x02_get_txpower,
.wake_tx_queue = mt76_wake_tx_queue,
.sta_rate_tbl_update = mt76x02_sta_rate_tbl_update,
.release_buffered_frames = mt76_release_buffered_frames,
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/usb_main.c 
b/drivers/net/wireless/mediatek/mt76/mt76x2/usb_main.c
index 5187a5f4832a..c2e0a43082e5 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x2/usb_main.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x2/usb_main.c
@@ -161,4 

[PATCH 1/9] mt76: move mt76x02_init_device in mt76x02-lib module

2018-10-20 Thread Lorenzo Bianconi
Move mt76x02_init_device routine in mt76x02_util.c in order to be
reused by mt76x0 driver and remove duplicated code. Move interface
combo definition supported by the driver in mt76x02_init_device routine

Signed-off-by: Lorenzo Bianconi 
---
 .../wireless/mediatek/mt76/mt76x0/eeprom.c|  2 -
 .../net/wireless/mediatek/mt76/mt76x0/init.c  | 36 +
 drivers/net/wireless/mediatek/mt76/mt76x02.h  |  1 +
 .../net/wireless/mediatek/mt76/mt76x02_util.c | 81 +++
 .../net/wireless/mediatek/mt76/mt76x2/init.c  | 34 
 .../wireless/mediatek/mt76/mt76x2/mt76x2.h|  1 -
 .../wireless/mediatek/mt76/mt76x2/pci_init.c  | 41 +-
 .../wireless/mediatek/mt76/mt76x2/usb_init.c  |  5 +-
 8 files changed, 87 insertions(+), 114 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/eeprom.c 
b/drivers/net/wireless/mediatek/mt76/mt76x0/eeprom.c
index ab4fd6e0f23a..275d77c90624 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x0/eeprom.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x0/eeprom.c
@@ -340,8 +340,6 @@ int mt76x0_eeprom_init(struct mt76x02_dev *dev)
mt76x0_set_freq_offset(dev);
mt76x0_set_temp_offset(dev);
 
-   dev->mt76.chainmask = 0x0101;
-
return 0;
 }
 
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/init.c 
b/drivers/net/wireless/mediatek/mt76/mt76x0/init.c
index 263d5e8df945..95a015281697 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x0/init.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x0/init.c
@@ -338,46 +338,16 @@ EXPORT_SYMBOL_GPL(mt76x0_alloc_device);
 
 int mt76x0_register_device(struct mt76x02_dev *dev)
 {
-   struct mt76_dev *mdev = >mt76;
-   struct ieee80211_hw *hw = mdev->hw;
-   struct wiphy *wiphy = hw->wiphy;
int ret;
 
-   /* Reserve WCID 0 for mcast - thanks to this APs WCID will go to
-* entry no. 1 like it does in the vendor driver.
-*/
-   mdev->wcid_mask[0] |= 1;
-
-   /* init fake wcid for monitor interfaces */
-   mdev->global_wcid.idx = 0xff;
-   mdev->global_wcid.hw_key_idx = -1;
-
-   /* init antenna configuration */
-   mdev->antenna_mask = 1;
-
-   hw->queues = 4;
-   hw->max_rates = 1;
-   hw->max_report_rates = 7;
-   hw->max_rate_tries = 1;
-   hw->extra_tx_headroom = 2;
-   if (mt76_is_usb(dev))
-   hw->extra_tx_headroom += sizeof(struct mt76x02_txwi) +
-MT_DMA_HDR_LEN;
-
-   hw->sta_data_size = sizeof(struct mt76x02_sta);
-   hw->vif_data_size = sizeof(struct mt76x02_vif);
-
-   wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION);
-
-   INIT_DELAYED_WORK(>mac_work, mt76x02_mac_work);
-
-   ret = mt76_register_device(mdev, true, mt76x02_rates,
+   mt76x02_init_device(dev);
+   ret = mt76_register_device(>mt76, true, mt76x02_rates,
   ARRAY_SIZE(mt76x02_rates));
if (ret)
return ret;
 
/* overwrite unsupported features */
-   if (mdev->cap.has_5ghz)
+   if (dev->mt76.cap.has_5ghz)
mt76x0_vht_cap_mask(>mt76.sband_5g.sband);
 
mt76x02_init_debugfs(dev);
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02.h 
b/drivers/net/wireless/mediatek/mt76/mt76x02.h
index bdbe4bbf7a59..1cd0f758587d 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02.h
@@ -102,6 +102,7 @@ struct mt76x02_dev {
 
 extern struct ieee80211_rate mt76x02_rates[12];
 
+void mt76x02_init_device(struct mt76x02_dev *dev);
 void mt76x02_configure_filter(struct ieee80211_hw *hw,
 unsigned int changed_flags,
 unsigned int *total_flags, u64 multicast);
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c 
b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
index ca05332f81fc..208c76d40afa 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
@@ -47,6 +47,87 @@ struct ieee80211_rate mt76x02_rates[] = {
 };
 EXPORT_SYMBOL_GPL(mt76x02_rates);
 
+static const struct ieee80211_iface_limit mt76x02_if_limits[] = {
+   {
+   .max = 1,
+   .types = BIT(NL80211_IFTYPE_ADHOC)
+   }, {
+   .max = 8,
+   .types = BIT(NL80211_IFTYPE_STATION) |
+#ifdef CONFIG_MAC80211_MESH
+BIT(NL80211_IFTYPE_MESH_POINT) |
+#endif
+BIT(NL80211_IFTYPE_AP)
+},
+};
+
+static const struct ieee80211_iface_combination mt76x02_if_comb[] = {
+   {
+   .limits = mt76x02_if_limits,
+   .n_limits = ARRAY_SIZE(mt76x02_if_limits),
+   .max_interfaces = 8,
+   .num_different_channels = 1,
+   .beacon_int_infra_match = true,
+   .radar_detect_widths = BIT(NL8021

[PATCH 7/9] mt76: move mt76x02_sta_ps in mt76x02-lib module

2018-10-20 Thread Lorenzo Bianconi
Move mt76x02_sta_ps utility routine in mt76x02_util.c
in order to be reused by mt76x0 driver adding AP support

Signed-off-by: Lorenzo Bianconi 
---
 drivers/net/wireless/mediatek/mt76/mt76x0/pci.c  |  1 +
 drivers/net/wireless/mediatek/mt76/mt76x02.h |  1 +
 drivers/net/wireless/mediatek/mt76/mt76x02_util.c| 12 
 drivers/net/wireless/mediatek/mt76/mt76x2/mt76x2.h   |  2 --
 drivers/net/wireless/mediatek/mt76/mt76x2/pci_init.c |  2 +-
 drivers/net/wireless/mediatek/mt76/mt76x2/pci_main.c | 11 ---
 6 files changed, 15 insertions(+), 14 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/pci.c 
b/drivers/net/wireless/mediatek/mt76/mt76x0/pci.c
index 4d4800d09da6..4deaf7f7c4f7 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x0/pci.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x0/pci.c
@@ -142,6 +142,7 @@ mt76x0e_probe(struct pci_dev *pdev, const struct 
pci_device_id *id)
.tx_complete_skb = mt76x02_tx_complete_skb,
.rx_skb = mt76x02_queue_rx_skb,
.rx_poll_complete = mt76x02_rx_poll_complete,
+   .sta_ps = mt76x02_sta_ps,
};
struct mt76x02_dev *dev;
int ret;
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02.h 
b/drivers/net/wireless/mediatek/mt76/mt76x02.h
index f830e39b58e7..1733226b657d 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02.h
@@ -153,6 +153,7 @@ void mt76x02_sw_scan_complete(struct ieee80211_hw *hw,
  struct ieee80211_vif *vif);
 int mt76x02_get_txpower(struct ieee80211_hw *hw,
struct ieee80211_vif *vif, int *dbm);
+void mt76x02_sta_ps(struct mt76_dev *dev, struct ieee80211_sta *sta, bool ps);
 
 extern const u16 mt76x02_beacon_offsets[16];
 void mt76x02_set_beacon_offsets(struct mt76x02_dev *dev);
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c 
b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
index 25f36e333b9b..4e358066bf9b 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
@@ -526,6 +526,18 @@ int mt76x02_get_txpower(struct ieee80211_hw *hw,
 }
 EXPORT_SYMBOL_GPL(mt76x02_get_txpower);
 
+void mt76x02_sta_ps(struct mt76_dev *mdev, struct ieee80211_sta *sta,
+   bool ps)
+{
+   struct mt76x02_dev *dev = container_of(mdev, struct mt76x02_dev, mt76);
+   struct mt76x02_sta *msta = (struct mt76x02_sta *)sta->drv_priv;
+   int idx = msta->wcid.idx;
+
+   mt76_stop_tx_queues(>mt76, sta, true);
+   mt76x02_mac_wcid_set_drop(dev, idx, ps);
+}
+EXPORT_SYMBOL_GPL(mt76x02_sta_ps);
+
 const u16 mt76x02_beacon_offsets[16] = {
/* 1024 byte per beacon */
0xc000,
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/mt76x2.h 
b/drivers/net/wireless/mediatek/mt76/mt76x2/mt76x2.h
index 2bae70c63ab0..0c323a0762e8 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x2/mt76x2.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76x2/mt76x2.h
@@ -77,8 +77,6 @@ void mt76x2_cleanup(struct mt76x02_dev *dev);
 
 void mt76x2_mac_set_tx_protection(struct mt76x02_dev *dev, u32 val);
 
-void mt76x2_sta_ps(struct mt76_dev *dev, struct ieee80211_sta *sta, bool ps);
-
 void mt76x2_reset_wlan(struct mt76x02_dev *dev, bool enable);
 void mt76x2_init_txpower(struct mt76x02_dev *dev,
 struct ieee80211_supported_band *sband);
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/pci_init.c 
b/drivers/net/wireless/mediatek/mt76/mt76x2/pci_init.c
index c5d5fcbd9a55..c3c2f4441777 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x2/pci_init.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x2/pci_init.c
@@ -356,7 +356,7 @@ struct mt76x02_dev *mt76x2_alloc_device(struct device *pdev)
.tx_complete_skb = mt76x02_tx_complete_skb,
.rx_skb = mt76x02_queue_rx_skb,
.rx_poll_complete = mt76x02_rx_poll_complete,
-   .sta_ps = mt76x2_sta_ps,
+   .sta_ps = mt76x02_sta_ps,
};
struct mt76x02_dev *dev;
struct mt76_dev *mdev;
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/pci_main.c 
b/drivers/net/wireless/mediatek/mt76/mt76x2/pci_main.c
index 5dfd06e56636..b2c599d4d670 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x2/pci_main.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x2/pci_main.c
@@ -164,17 +164,6 @@ mt76x2_bss_info_changed(struct ieee80211_hw *hw, struct 
ieee80211_vif *vif,
mutex_unlock(>mt76.mutex);
 }
 
-void
-mt76x2_sta_ps(struct mt76_dev *mdev, struct ieee80211_sta *sta, bool ps)
-{
-   struct mt76x02_sta *msta = (struct mt76x02_sta *) sta->drv_priv;
-   struct mt76x02_dev *dev = container_of(mdev, struct mt76x02_dev, mt76);
-   int idx = msta->wcid.idx;
-
-   mt76_stop_tx_queues(>mt76, sta, true);
-   mt76x02_mac_wcid_set_drop(dev, idx, ps);
-}
-
 static void
 mt76x2_flus

[PATCH] mt76: move mt76x02_mac_set_short_preamble in mt76x02_mac.c

2018-10-19 Thread Lorenzo Bianconi
Move mt76x02_mac_set_short_preamble routine in mt76x02-lib module
since it is shared between mt76x0 and mt76x2 drivers

Signed-off-by: Lorenzo Bianconi 
---
 drivers/net/wireless/mediatek/mt76/mt76x0/mac.c| 8 
 drivers/net/wireless/mediatek/mt76/mt76x0/main.c   | 2 +-
 drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h | 1 -
 drivers/net/wireless/mediatek/mt76/mt76x02_mac.c   | 9 +
 drivers/net/wireless/mediatek/mt76/mt76x02_mac.h   | 1 +
 5 files changed, 11 insertions(+), 10 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/mac.c 
b/drivers/net/wireless/mediatek/mt76/mt76x0/mac.c
index 57e15c8ced7e..ded0ad623723 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x0/mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x0/mac.c
@@ -76,14 +76,6 @@ void mt76x0_mac_set_protection(struct mt76x02_dev *dev, bool 
legacy_prot,
mt76_wr(dev, MT_CCK_PROT_CFG + i * 4, prot[i]);
 }
 
-void mt76x0_mac_set_short_preamble(struct mt76x02_dev *dev, bool short_preamb)
-{
-   if (short_preamb)
-   mt76_set(dev, MT_AUTO_RSP_CFG, MT_AUTO_RSP_PREAMB_SHORT);
-   else
-   mt76_clear(dev, MT_AUTO_RSP_CFG, MT_AUTO_RSP_PREAMB_SHORT);
-}
-
 void mt76x0_mac_config_tsf(struct mt76x02_dev *dev, bool enable, int interval)
 {
u32 val = mt76_rr(dev, MT_BEACON_TIME_CFG);
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/main.c 
b/drivers/net/wireless/mediatek/mt76/mt76x0/main.c
index fdffbdf90e59..a61b23239cb2 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x0/main.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x0/main.c
@@ -112,7 +112,7 @@ void mt76x0_bss_info_changed(struct ieee80211_hw *hw,
   info->ht_operation_mode);
 
if (changed & BSS_CHANGED_ERP_PREAMBLE)
-   mt76x0_mac_set_short_preamble(dev, info->use_short_preamble);
+   mt76x02_mac_set_short_preamble(dev, info->use_short_preamble);
 
if (changed & BSS_CHANGED_ERP_SLOT) {
int slottime = info->use_short_slot ? 9 : 20;
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h 
b/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h
index 282814cbcc12..9cdecb9bfc64 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h
@@ -82,7 +82,6 @@ void mt76x0_phy_calibrate(struct mt76x02_dev *dev, bool 
power_on);
 /* MAC */
 void mt76x0_mac_set_protection(struct mt76x02_dev *dev, bool legacy_prot,
int ht_mode);
-void mt76x0_mac_set_short_preamble(struct mt76x02_dev *dev, bool short_preamb);
 void mt76x0_mac_config_tsf(struct mt76x02_dev *dev, bool enable, int interval);
 
 #endif
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c 
b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
index ccc7f532ceba..f21bf0af8937 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
@@ -213,6 +213,15 @@ void mt76x02_mac_wcid_set_rate(struct mt76x02_dev *dev, 
struct mt76_wcid *wcid,
spin_unlock_bh(>mt76.lock);
 }
 
+void mt76x02_mac_set_short_preamble(struct mt76x02_dev *dev, bool enable)
+{
+   if (enable)
+   mt76_set(dev, MT_AUTO_RSP_CFG, MT_AUTO_RSP_PREAMB_SHORT);
+   else
+   mt76_clear(dev, MT_AUTO_RSP_CFG, MT_AUTO_RSP_PREAMB_SHORT);
+}
+EXPORT_SYMBOL_GPL(mt76x02_mac_set_short_preamble);
+
 bool mt76x02_mac_load_tx_status(struct mt76x02_dev *dev,
struct mt76x02_tx_status *stat)
 {
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.h 
b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.h
index 81c16aef6a94..55b3a49ba77a 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.h
@@ -200,6 +200,7 @@ mt76x02_skb_tx_info(struct sk_buff *skb)
 
 void mt76x02_txq_init(struct mt76x02_dev *dev, struct ieee80211_txq *txq);
 
+void mt76x02_mac_set_short_preamble(struct mt76x02_dev *dev, bool enable);
 int mt76x02_mac_shared_key_setup(struct mt76x02_dev *dev, u8 vif_idx,
 u8 key_idx, struct ieee80211_key_conf *key);
 int mt76x02_mac_wcid_set_key(struct mt76x02_dev *dev, u8 idx,
-- 
2.17.2



[PATCH] mt76x0: mac: remove mt76x0_mac_set_ampdu_factor

2018-10-19 Thread Lorenzo Bianconi
Remove no longer used mt76x0_mac_set_ampdu_factor routine

Signed-off-by: Lorenzo Bianconi 
---
 .../net/wireless/mediatek/mt76/mt76x0/mac.c   | 25 ---
 .../wireless/mediatek/mt76/mt76x0/mt76x0.h|  1 -
 2 files changed, 26 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/mac.c 
b/drivers/net/wireless/mediatek/mt76/mt76x0/mac.c
index 8cbdeb6d3dbe..57e15c8ced7e 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x0/mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x0/mac.c
@@ -103,28 +103,3 @@ void mt76x0_mac_config_tsf(struct mt76x02_dev *dev, bool 
enable, int interval)
MT_BEACON_TIME_CFG_SYNC_MODE |
MT_BEACON_TIME_CFG_TBTT_EN;
 }
-
-void mt76x0_mac_set_ampdu_factor(struct mt76x02_dev *dev)
-{
-   struct ieee80211_sta *sta;
-   struct mt76_wcid *wcid;
-   void *msta;
-   u8 min_factor = 3;
-   int i;
-
-   rcu_read_lock();
-   for (i = 0; i < ARRAY_SIZE(dev->mt76.wcid); i++) {
-   wcid = rcu_dereference(dev->mt76.wcid[i]);
-   if (!wcid)
-   continue;
-
-   msta = container_of(wcid, struct mt76x02_sta, wcid);
-   sta = container_of(msta, struct ieee80211_sta, drv_priv);
-
-   min_factor = min(min_factor, sta->ht_cap.ampdu_factor);
-   }
-   rcu_read_unlock();
-
-   mt76_wr(dev, MT_MAX_LEN_CFG, 0xa0fff |
-  FIELD_PREP(MT_MAX_LEN_CFG_AMPDU, min_factor));
-}
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h 
b/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h
index 1871ec98aefb..282814cbcc12 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h
@@ -84,6 +84,5 @@ void mt76x0_mac_set_protection(struct mt76x02_dev *dev, bool 
legacy_prot,
int ht_mode);
 void mt76x0_mac_set_short_preamble(struct mt76x02_dev *dev, bool short_preamb);
 void mt76x0_mac_config_tsf(struct mt76x02_dev *dev, bool enable, int interval);
-void mt76x0_mac_set_ampdu_factor(struct mt76x02_dev *dev);
 
 #endif
-- 
2.17.2



[PATCH v2] mt76x0: align mt76x0u and mt76x0e fw version

2018-10-19 Thread Lorenzo Bianconi
Unify firmware version used on mt76x0e and mt76x0u drivers.
Fallback to mt7610u fw if mt7610e one is not available

Signed-off-by: Lorenzo Bianconi 
---
this patch is based on top of:
https://patchwork.kernel.org/patch/10648399/

Changes since v1:
- use firmware_request_nowarn instead of request_firmware
---
 .../wireless/mediatek/mt76/mt76x0/mt76x0.h|  2 ++
 .../net/wireless/mediatek/mt76/mt76x0/usb.c   |  2 ++
 .../wireless/mediatek/mt76/mt76x0/usb_mcu.c   | 23 +++
 3 files changed, 23 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h 
b/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h
index 24e817bda500..1871ec98aefb 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h
@@ -31,6 +31,8 @@
 #define MT7610E_FIRMWARE   "mediatek/mt7610e.bin"
 #define MT7650E_FIRMWARE   "mediatek/mt7650e.bin"
 
+#define MT7610U_FIRMWARE   "mediatek/mt7610u.bin"
+
 #define MT_USB_AGGR_SIZE_LIMIT 21 /* * 1024B */
 #define MT_USB_AGGR_TIMEOUT0x80 /* * 33ns */
 
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c 
b/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c
index cdbb8a6db608..245eb4aa9764 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c
@@ -337,6 +337,8 @@ static int __maybe_unused mt76x0_resume(struct 
usb_interface *usb_intf)
 }
 
 MODULE_DEVICE_TABLE(usb, mt76x0_device_table);
+MODULE_FIRMWARE(MT7610E_FIRMWARE);
+MODULE_FIRMWARE(MT7610U_FIRMWARE);
 MODULE_LICENSE("GPL");
 
 static struct usb_driver mt76x0_driver = {
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/usb_mcu.c 
b/drivers/net/wireless/mediatek/mt76/mt76x0/usb_mcu.c
index a9f14d5149d1..9d7585029df9 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x0/usb_mcu.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x0/usb_mcu.c
@@ -22,7 +22,6 @@
 
 #define MCU_FW_URB_MAX_PAYLOAD 0x38f8
 #define MCU_FW_URB_SIZE(MCU_FW_URB_MAX_PAYLOAD + 12)
-#define MT7610U_FIRMWARE   "mediatek/mt7610u.bin"
 
 static int
 mt76x0u_upload_firmware(struct mt76x02_dev *dev,
@@ -75,6 +74,24 @@ mt76x0u_upload_firmware(struct mt76x02_dev *dev,
return err;
 }
 
+static int mt76x0_get_firmware(struct mt76x02_dev *dev,
+  const struct firmware **fw)
+{
+   int err;
+
+   /* try to load mt7610e fw if available
+* otherwise fall back to mt7610u one
+*/
+   err = firmware_request_nowarn(fw, MT7610E_FIRMWARE, dev->mt76.dev);
+   if (err) {
+   dev_info(dev->mt76.dev, "%s not found, switching to %s",
+MT7610E_FIRMWARE, MT7610U_FIRMWARE);
+   return request_firmware(fw, MT7610U_FIRMWARE,
+   dev->mt76.dev);
+   }
+   return 0;
+}
+
 static int mt76x0u_load_firmware(struct mt76x02_dev *dev)
 {
const struct firmware *fw;
@@ -88,7 +105,7 @@ static int mt76x0u_load_firmware(struct mt76x02_dev *dev)
if (mt76x0_firmware_running(dev))
return 0;
 
-   ret = request_firmware(, MT7610U_FIRMWARE, dev->mt76.dev);
+   ret = mt76x0_get_firmware(dev, );
if (ret)
return ret;
 
@@ -171,5 +188,3 @@ int mt76x0u_mcu_init(struct mt76x02_dev *dev)
 
return 0;
 }
-
-MODULE_FIRMWARE(MT7610U_FIRMWARE);
-- 
2.17.2



Re: [PATCH] mt76x0: align mt76x0u and mt76x0e fw version

2018-10-19 Thread Lorenzo Bianconi
>
> On 2018-10-19 10:58, Lorenzo Bianconi wrote:
> > Unify firmware version used on mt76x0e and mt76x0u drivers.
> > Fallback to mt7610u fw if mt7610e one is not available
> >
> > Signed-off-by: Lorenzo Bianconi 
> > ---
> > this patch is based on top of:
> > https://patchwork.kernel.org/patch/10648399/
> > ---
> >  .../wireless/mediatek/mt76/mt76x0/mt76x0.h|  2 ++
> >  .../net/wireless/mediatek/mt76/mt76x0/usb.c   |  2 ++
> >  .../wireless/mediatek/mt76/mt76x0/usb_mcu.c   | 23 +++
> >  3 files changed, 23 insertions(+), 4 deletions(-)
> >
> > diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/usb_mcu.c 
> > b/drivers/net/wireless/mediatek/mt76/mt76x0/usb_mcu.c
> > index a9f14d5149d1..b57c2a11146f 100644
> > --- a/drivers/net/wireless/mediatek/mt76/mt76x0/usb_mcu.c
> > +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/usb_mcu.c
> > @@ -22,7 +22,6 @@
> >
> >  #define MCU_FW_URB_MAX_PAYLOAD   0x38f8
> >  #define MCU_FW_URB_SIZE  (MCU_FW_URB_MAX_PAYLOAD + 12)
> > -#define MT7610U_FIRMWARE "mediatek/mt7610u.bin"
> >
> >  static int
> >  mt76x0u_upload_firmware(struct mt76x02_dev *dev,
> > @@ -75,6 +74,24 @@ mt76x0u_upload_firmware(struct mt76x02_dev *dev,
> >   return err;
> >  }
> >
> > +static int mt76x0_get_firmware(struct mt76x02_dev *dev,
> > +const struct firmware **fw)
> > +{
> > + int err;
> > +
> > + /* try to load mt7610e fw if available
> > +  * otherwise fall back to mt7610u one
> > +  */
> > + err = request_firmware(fw, MT7610E_FIRMWARE, dev->mt76.dev);
> > + if (err) {
> > + dev_info(dev->mt76.dev, "%s not found, switching to %s",
> > +  MT7610E_FIRMWARE, MT7610U_FIRMWARE);
> > + return request_firmware(fw, MT7610U_FIRMWARE,
> > + dev->mt76.dev);
> > + }
> > + return 0;
> > +}
> You should use firmware_request_nowarn for the first request.
>
> - Felix

Ack, will do in v2.

Regards,
Lorenzo


  1   2   3   4   5   6   7   8   >