Re: Intel 8265 unstable/asymmetric ping response time (only under Linux)

2018-10-11 Thread Qu Wenruo


On 2018/10/12 上午3:30, Michał Kazior wrote:
> On Thu, 11 Oct 2018 at 15:56, Qu Wenruo  wrote:
>>
>> Hi,
>>
>> I found one pretty strange behavior for the Intel 8265/8275 wireless
>> (from ThinkPad X1 carbon)
>>
>> If I ping *FROM* my router/desktop to the wireless laptop, the response
>> time is very unstable and slow, like:
>> --
>> $ ping -4 thinkpad
>> PING thinkpad.lan (172.16.0.100) 56(84) bytes of data.
>> 64 bytes from thinkpad.lan (172.16.0.100): icmp_seq=1 ttl=64 time=143 ms
>> 64 bytes from thinkpad.lan (172.16.0.100): icmp_seq=2 ttl=64 time=166 ms
>> 64 bytes from thinkpad.lan (172.16.0.100): icmp_seq=3 ttl=64 time=188 ms
>> 64 bytes from thinkpad.lan (172.16.0.100): icmp_seq=4 ttl=64 time=211 ms
>> 64 bytes from thinkpad.lan (172.16.0.100): icmp_seq=5 ttl=64 time=29.8 ms
>> 64 bytes from thinkpad.lan (172.16.0.100): icmp_seq=6 ttl=64 time=51.7 ms
>> 64 bytes from thinkpad.lan (172.16.0.100): icmp_seq=7 ttl=64 time=72.8 ms
>> 64 bytes from thinkpad.lan (172.16.0.100): icmp_seq=8 ttl=64 time=94.6 ms
>> 64 bytes from thinkpad.lan (172.16.0.100): icmp_seq=9 ttl=64 time=117 ms
>> 64 bytes from thinkpad.lan (172.16.0.100): icmp_seq=10 ttl=64 time=140 ms
>> 64 bytes from thinkpad.lan (172.16.0.100): icmp_seq=11 ttl=64 time=163 ms
>> 64 bytes from thinkpad.lan (172.16.0.100): icmp_seq=12 ttl=64 time=186 ms
>> 64 bytes from thinkpad.lan (172.16.0.100): icmp_seq=13 ttl=64 time=207 ms
>> 64 bytes from thinkpad.lan (172.16.0.100): icmp_seq=14 ttl=64 time=25.1 ms
>> 64 bytes from thinkpad.lan (172.16.0.100): icmp_seq=15 ttl=64 time=47.6 ms
>> -
>>
>> It looks like the response time get increase by 20ms and flipped over
>> around 200ms.
> [...]
>> So is this something wrong with the wireless card or something wrong
>> with the firmware/powersaving setting of ThinkPad X1 Carbon 6th gen?
> 
> What you're seeing here is powersave.
> 
> When you ping your laptop its wifi card may be in powersave so AP will
> store those icmp requests in a queue. The AP will start advertising
> that fact in the next beacon frame (which it broadcasts regularily).
> The wifi client can then see that there's traffic queued up for it,
> wake up, receive it and possibly reply (with icmp response in your
> case). The interval between each ping is long enough for the wifi
> client to re-enter powersave due to "nothing more to do" every time
> causing the same sequence (sleep, queue, advertise, wake, txrx).

Thanks for your detailed explanation, this really helps me to understand
the problem.

> 
> The time drift comes from the fact beacon interval tends to be
> slightly off from your ping interval. The fact it wraps around at
> ~200msec for you means your AP's beacon interval is roughly that long
> as well which you can probably confirm with your AP/wifi router
> settings. Most APs tend to run 100 or 200msec (or TU, actually, which
> is 1024/1000 of msec) by default.
> 
> If you run more traffic the lag will go away. I find this sort of
> behavior behavior annoying for mostly idle systems where I want to do
> remoting with ssh (or any other bursty and interactive work).

Yeah, completely the same case.

> 
> You can try disabling powersave with:
>   iw wlan0 set power_save off
> 
> You might need to replace wlan0 with wlpXsY depending on your system.
> You'll need root privileges to do it, e.g. via sudo, or su.

Works like a charm.

> 
> Keep in mind it'll cause more power to be outputted and e.g. leave you
> with slightly shorter battery runtime. On intel compute sticks
> disabling wifi powersave can cause its fan to kick in more often due
> to thermal impact and unfortunate fan trip points.

Not a problem for Thinkpad with better thermal paste and extra tweaked
CPU parameters.

> 
> Wifi powersave might be disabled in Windows for some reason. Maybe it
> does that disable it when AC is plugged in, and if you were to plug it
> out and run off of battery only, it'd enable it and show similar
> (laggy) behavior?

On battery, windows behaves exactly the same as Linux.

I only need to add some hook for AC/battery switch for Linux.

Thanks for your help!
Qu

> 
> 
> Michał
> 



signature.asc
Description: OpenPGP digital signature


[PATCH] brcmfmac: support STA info struct v7

2018-10-11 Thread Dan Haab
The newest firmwares provide STA info using v7 of the struct. As v7
isn't backward compatible, a union is needed.

Even though brcmfmac does not use any of the new info it's important to
provide the proper struct buffer. Without this change new firmwares will
fallback to the very limited v3 instead of something in between such as
v4.

Signed-off-by: Dan Haab 
---
 .../broadcom/brcm80211/brcmfmac/fwil_types.h   | 39 ++
 1 file changed, 32 insertions(+), 7 deletions(-)

diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h 
b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h
index d5bb81e..189d576 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h
@@ -176,6 +176,8 @@
 
 #define BRCMF_VHT_CAP_MCS_MAP_NSS_MAX  8
 
+#define BRCMF_HE_CAP_MCS_MAP_NSS_MAX   8
+
 /* MAX_CHUNK_LEN is the maximum length for data passing to firmware in each
  * ioctl. It is relatively small because firmware has small maximum size input
  * playload restriction for ioctls.
@@ -601,13 +603,36 @@ struct brcmf_sta_info_le {
__le32 rx_pkts_retried;/* # rx with retry bit set */
__le32 tx_rate_fallback;   /* lowest fallback TX rate */
 
-   /* Fields valid for ver >= 5 */
-   struct {
-   __le32 count;   /* # rates in 
this set */
-   u8 rates[BRCMF_MAXRATES_IN_SET];/* rates in 
500kbps units w/hi bit set if basic */
-   u8 mcs[BRCMF_MCSSET_LEN];   /* supported 
mcs index bit map */
-   __le16 vht_mcs[BRCMF_VHT_CAP_MCS_MAP_NSS_MAX];  /* supported 
mcs index bit map per nss */
-   } rateset_adv;
+   union {
+   struct {
+   struct {
+   __le32 count;   
/* # rates in this set */
+   u8 rates[BRCMF_MAXRATES_IN_SET];
/* rates in 500kbps units w/hi bit set if basic */
+   u8 mcs[BRCMF_MCSSET_LEN];   
/* supported mcs index bit map */
+   __le16 vht_mcs[BRCMF_VHT_CAP_MCS_MAP_NSS_MAX];  
/* supported mcs index bit map per nss */
+   } rateset_adv;
+   } v5;
+
+   struct {
+   __le32 rx_dur_total;/* total user RX duration 
(estimated) */
+   __le16 chanspec;/** chanspec this sta is on */
+   __le16 pad;
+   struct {
+   __le16 version; 
/* version */
+   __le16 len; 
/* length */
+   __le32 count;   
/* # rates in this set */
+   u8 rates[BRCMF_MAXRATES_IN_SET];
/* rates in 500kbps units w/hi bit set if basic */
+   u8 mcs[BRCMF_MCSSET_LEN];   
/* supported mcs index bit map */
+   __le16 vht_mcs[BRCMF_VHT_CAP_MCS_MAP_NSS_MAX];  
/* supported mcs index bit map per nss */
+   __le16 he_mcs[BRCMF_HE_CAP_MCS_MAP_NSS_MAX];
/* supported he mcs index bit map per nss */
+   } rateset_adv;  /* rateset along with mcs index 
bitmap */
+   __le16 wpauth;  /* authentication type */
+   u8 algo;/* crypto algorithm */
+   __le32 tx_rspec;/* Rate of last successful tx 
frame */
+   __le32 rx_rspec;/* Rate of last successful rx 
frame */
+   __le32 wnm_cap; /* wnm capabilities */
+   } v7;
+   };
 };
 
 struct brcmf_chanspec_list {
-- 
1.9.1



Re: Intel 8265 unstable/asymmetric ping response time (only under Linux)

2018-10-11 Thread Michał Kazior
On Thu, 11 Oct 2018 at 15:56, Qu Wenruo  wrote:
>
> Hi,
>
> I found one pretty strange behavior for the Intel 8265/8275 wireless
> (from ThinkPad X1 carbon)
>
> If I ping *FROM* my router/desktop to the wireless laptop, the response
> time is very unstable and slow, like:
> --
> $ ping -4 thinkpad
> PING thinkpad.lan (172.16.0.100) 56(84) bytes of data.
> 64 bytes from thinkpad.lan (172.16.0.100): icmp_seq=1 ttl=64 time=143 ms
> 64 bytes from thinkpad.lan (172.16.0.100): icmp_seq=2 ttl=64 time=166 ms
> 64 bytes from thinkpad.lan (172.16.0.100): icmp_seq=3 ttl=64 time=188 ms
> 64 bytes from thinkpad.lan (172.16.0.100): icmp_seq=4 ttl=64 time=211 ms
> 64 bytes from thinkpad.lan (172.16.0.100): icmp_seq=5 ttl=64 time=29.8 ms
> 64 bytes from thinkpad.lan (172.16.0.100): icmp_seq=6 ttl=64 time=51.7 ms
> 64 bytes from thinkpad.lan (172.16.0.100): icmp_seq=7 ttl=64 time=72.8 ms
> 64 bytes from thinkpad.lan (172.16.0.100): icmp_seq=8 ttl=64 time=94.6 ms
> 64 bytes from thinkpad.lan (172.16.0.100): icmp_seq=9 ttl=64 time=117 ms
> 64 bytes from thinkpad.lan (172.16.0.100): icmp_seq=10 ttl=64 time=140 ms
> 64 bytes from thinkpad.lan (172.16.0.100): icmp_seq=11 ttl=64 time=163 ms
> 64 bytes from thinkpad.lan (172.16.0.100): icmp_seq=12 ttl=64 time=186 ms
> 64 bytes from thinkpad.lan (172.16.0.100): icmp_seq=13 ttl=64 time=207 ms
> 64 bytes from thinkpad.lan (172.16.0.100): icmp_seq=14 ttl=64 time=25.1 ms
> 64 bytes from thinkpad.lan (172.16.0.100): icmp_seq=15 ttl=64 time=47.6 ms
> -
>
> It looks like the response time get increase by 20ms and flipped over
> around 200ms.
[...]
> So is this something wrong with the wireless card or something wrong
> with the firmware/powersaving setting of ThinkPad X1 Carbon 6th gen?

What you're seeing here is powersave.

When you ping your laptop its wifi card may be in powersave so AP will
store those icmp requests in a queue. The AP will start advertising
that fact in the next beacon frame (which it broadcasts regularily).
The wifi client can then see that there's traffic queued up for it,
wake up, receive it and possibly reply (with icmp response in your
case). The interval between each ping is long enough for the wifi
client to re-enter powersave due to "nothing more to do" every time
causing the same sequence (sleep, queue, advertise, wake, txrx).

The time drift comes from the fact beacon interval tends to be
slightly off from your ping interval. The fact it wraps around at
~200msec for you means your AP's beacon interval is roughly that long
as well which you can probably confirm with your AP/wifi router
settings. Most APs tend to run 100 or 200msec (or TU, actually, which
is 1024/1000 of msec) by default.

If you run more traffic the lag will go away. I find this sort of
behavior behavior annoying for mostly idle systems where I want to do
remoting with ssh (or any other bursty and interactive work).

You can try disabling powersave with:
  iw wlan0 set power_save off

You might need to replace wlan0 with wlpXsY depending on your system.
You'll need root privileges to do it, e.g. via sudo, or su.

Keep in mind it'll cause more power to be outputted and e.g. leave you
with slightly shorter battery runtime. On intel compute sticks
disabling wifi powersave can cause its fan to kick in more often due
to thermal impact and unfortunate fan trip points.

Wifi powersave might be disabled in Windows for some reason. Maybe it
does that disable it when AC is plugged in, and if you were to plug it
out and run off of battery only, it'd enable it and show similar
(laggy) behavior?


Michał


Dear Friend,

2018-10-11 Thread Eng. Ibrahim Mahamadi



Dear Friend,

Greeting in the name of our creator Allah the most Merciful, My Name is Eng. 
Ibrahim Mahamadi from Damascus Syria I am now 47 years Old, and a military 
officer under Marine Corps with 4 year experience in medical field.

I was in charge of supply of weapon and ammunitions from Russia to Syrian 
Government. I have personally repented and decided to leave military work for a 
holy living that was the reason I contacted you today if you know any 
profitable Business in your Country I can invest my Money since my Country 
Syria Security, Economy and happiness has been lost to the Lowest level 
including our happiness has been taken away from us.

Our Country has been on fire for many years that made me lost my only child and 
wife and I will like to relocate out from Syria. I need a trustworthy foreign 
partner to enable me move my investment capital which is in my international 
account amounting 12.5 million dollars. I will resign from work to join you in 
your country as soon as you receive my investment fund.

You may as well tell me little more about yourself. Contact me urgently to 
enable us proceed with the business.

SINCERELY YOURS
eng-ibrahim...@hot-shot.com





تحية باسم الله الخالق الرحيم اسمي المهندس. إبراهيم محمدي من دمشق سوريا أنا الآن 
في السابعة والأربعين من العمر ، ضابط عسكري تحت قيادة مشاة البحرية مع خبرة 4 
سنوات في المجال الطبي.

كنت مسؤولاً عن توريد الأسلحة والذخائر من روسيا إلى الحكومة السورية. لقد تبعت 
شخصياً وقررت ترك العمل العسكري من أجل حياة مقدسة كان السبب في أنني اتصلت بك 
اليوم إذا كنت تعرف أي عمل مربح في بلدك يمكنني أن أستثمر أموالي منذ أن فقدت بلدي 
سوريا الأمن والاقتصاد والسعادة إلى أدنى مستوى بما في ذلك سعادتنا قد اتخذ بعيدا 
عنا.

كانت بلادنا مشتعلة منذ سنوات عديدة ، مما جعلني أفقد ولدي وزوجتي الوحيدتين ، 
وأنا أرغب في الانتقال من سوريا. أحتاج إلى شريك أجنبي جدير بالثقة لتمكينني من 
تحريك رأسمال استثماري في حسابي الدولي الذي يبلغ 12.5 مليون دولار. سأستقيل من 
العمل للانضمام إليك في بلدك بمجرد تلقي صندوق الاستثمار الخاص بي.

يمكنك كذلك أن تخبرني بالمزيد عن نفسك. اتصل بي على وجه السرعة لتمكيننا من المضي 
قدمًا في العمل.

صديقك المخلص
eng-ibrahim...@hot-shot.com


Occhiali da sole Ray Ban solo 20 $,

2018-10-11 Thread acwrmvr
Ciao

Il giorno di Natale sta arrivando

Occhiali da sole Ray Ban solo 20 $, consegna gratuita su 3 prodotti, 3-5 giorni 
per volare a casa tua con DHL, EMS, UPS o TNT

Master card online direttamente



www.rbaydg.com

Re: brcmfmac with BCM4359 on arm64 (RK3399) and SDIO

2018-10-11 Thread Christoph Müllner
Hi Franky and Arend,

today I could get a SDIO Wifi module, which includes a BCM43455.
I was able to get this up and running without any issues with the brcmfmac
driver and a 4.19 kernel. For me that's enough evidence to say that the SDIO
driver works.

However, the BCM4359 still does not work.
It times out in brcmf_sdio_firmware_callback(), while enabling func2.

I've inserted tons of debug log outputs in both, the DHD driver and the
brcmfmac driver, and compared them. Differences which I've found so far
are: a) brcmfmac strips out whitespaces from nvram contents and
b) DHD downloads firmware first and brcmfmac downloads nvram first.
I've adapted the DHD driver to behave like brcmfmac in both cases
and it still works.

I've increased the timeout for enabling func2 from 3 seconds to 10 seconds,
but that did not help.

Any ideas left?

Thanks,
Christoph


> On 09.10.2018, at 22:55, Christoph Müllner 
>  wrote:
> 
> Hi Franky,
> 
> thank's for your help.
> 
> As the BCM4359 is already supported (as PCIe device) in the brcmfmac
> driver, I assumed that base addresses will be correct.
> But having a closer look it is indeed the problematic part.
> I've temporary fixed the return value in brcmf_chip_tcm_rambase
> to the one matching the DHD's output and the SDIO errors are gone:
> 
> bcmdhd (4.4):
> [   15.701860] dhdsdio_write_vars: varaddr=0x23f1e8
> [   15.707024] dhdsdio_write_vars: varsize=3604
> [   15.711830] dhdsdio_write_vars: bus->dongle_ram_base=0x16
> [   15.718221] dhdsdio_write_vars: bus->ramsize=917504
> [   15.723649] dhdsdio_write_vars: bus->varsz=3601
> [   15.752063] dhdsdio_write_vars: Download, Upload and compare of NVRAM
> succeeded.
> 
> brcmfmac (4.19):
> [7.773752] brcmf_sdio_download_nvram: address=0x25f1f0
> [7.782824] brcmf_sdio_download_nvram: bus->ci->ramsize=917504
> [7.792544] brcmf_sdio_download_nvram: varsz=3600
> [7.800926] brcmf_sdio_download_nvram: bus->ci->rambase=0x18
> [7.816106] brcmfmac: brcmf_sdiod_ramrw: membytes transfer failed
> [7.835253] brcmfmac: brcmf_sdio_verifymemory: error -84 on reading
> 2048 membytes at 0x0025f1f0
> 
> brcmfmac (4.19-fixedoffset):
> [7.625436] brcmf_sdio_download_nvram: address=0x23f1f0
> [7.634582] brcmf_sdio_download_nvram: bus->ci->ramsize=917504
> [7.644284] brcmf_sdio_download_nvram: varsz=3600
> [7.652641] brcmf_sdio_download_nvram: bus->ci->rambase=0x16
> 
> Unfortunately I still don't get a wlan0 interface (and more important:
> no error message from the brcmfmac driver).
> I'm now trying to get brcmfmac's tracing features up and running
> to see where the driver got stuck.
> 
> Anyways, thank you very much so far.
> 
> BR
> Christoph
> 
> 
> On 10/9/18 8:59 PM, Franky Lin wrote:
>> Hi Christoph,
>> 
>> On Tue, Oct 9, 2018 at 11:10 AM Christoph Müllner
>>  wrote:
>>> 
>>> Hi Arend,
>>> 
>>> recently I got an SDIO module, which includes a BCM4359.
>>> I tried to get it up and running via the SD card interface
>>> on a RK3399 SoC and succeeded in doing so with
>>> bcmdhd.1.579.77.41.x and a vendor kernel (based on Linux 4.4).
>>> All that was necessary was configure BCMDHD to run with
>>> in-band IRQs and use a GPIO as gpio_wl_reg_on.
>>> 
>>> Since I can run a mainline kernel as well, I gave it a try and
>>> tried brcmfmac on Linux 4.19-rc7. As the BCM4359 is not in
>>> the list of supported SDIO devices, but is supported USB device,
>>> I've created a patch (attached), which adds the support for that device.
>>> Additionally I've patched my DTS to include the WL_REG_ON
>>> pin as part of mmc-pwrseq-simple's reset-gpios and added
>>> a bcm4329-fmac node in the mmc node.
>>> 
>>> During bootup I see messages from brcmfmac, which indicate
>>> that the BCM4359 has been found, but loading the nvram file
>>> continuously fails:
>>> 
 [5.993741] brcmfmac: brcmf_fw_alloc_request: using 
 brcm/brcmfmac4359-sdio for chip BCM4359/9
 [...]
 [7.987167] brcmfmac: brcmf_sdiod_ramrw: membytes transfer failed
 [8.008715] brcmfmac: brcmf_sdio_verifymemory: error -84 on reading 
 2048 membytes at 0x0025f1f0
 [8.021182] brcmfmac: brcmf_sdio_download_firmware: dongle nvram file 
 download failed
>> 
>> Does it always fail at nvram verification? If so please help to get
>> the address and varsz in brcmf_sdio_download_nvram. Also their
>> equivalent in bcmdhd which should be varaddr and varsize in
>> dhdsdio_write_vars.
>> 
>> Thanks,
>> --Franky
>> 
>>> That -84 means EILSEQ, which is the error value, which represents
>>> a CRC error during SDIO data exchange (returned by the function 
>>> dw_mci_data_complete()
>>> in the MMC driver).
>>> 
>>> To address this, I've reduced the clock speed (in several steps) to 400 kHz
>>> (and verified the clock signal on an oscilloscope), but the issue persists.
>>> I've also tried to use Linux 4.14.74, where I see the same issue.
>>> 
>>> I can confirm that the MMC interface works in general (I can use an SD card
>>> 

Re: Question on FIELD_PREP() for static array

2018-10-11 Thread John Garry

On 10/10/2018 19:13, Johannes Berg wrote:

On Wed, 2018-10-10 at 10:33 -0700, Joe Perches wrote:



Specifically it doesn't like the __BF_FIELD_CHECK() in FIELD_PREP().

Any ideas on compiler trickery we could do with the FIELD_PREP()
definition to avoid this issue (i.e. enforce the check but only use the
constant value)?




thanks guys


Perhaps __bf_shf should not use __builtin_ffsll.


__bf_shf() is a constant expression, and is fine in this context.

The problem is the use of the compound statement here:

static int x[2] = {
({ (void)(0); 1; }),
0,
}

similarly fails to compile.

I've recently run into a similar situation, namely in
include/net/netlink.h, and the applicable way to solve it here would be
something like this:

diff --git a/include/linux/bitfield.h b/include/linux/bitfield.h
index 3f1ef4450a7c..0680d641923f 100644
--- a/include/linux/bitfield.h
+++ b/include/linux/bitfield.h
@@ -49,19 +49,16 @@

 #define __bf_shf(x) (__builtin_ffsll(x) - 1)

+#define BUILD_BUG_ON_RET_ZERO(cond) (sizeof(char[1 - 2*!!(cond)]) - 1)
+#define BUILD_BUG_ON_NOT_POW2_RET_ZERO(n)  BUILD_BUG_ON_RET_ZERO(((n) & 
((n) - 1)) != 0)
+



 #define __BF_FIELD_CHECK(_mask, _reg, _val, _pfx)  \
-   ({  \
-   BUILD_BUG_ON_MSG(!__builtin_constant_p(_mask),  \
-_pfx "mask is not constant");\
-   BUILD_BUG_ON_MSG((_mask) == 0, _pfx "mask is zero");  \
-   BUILD_BUG_ON_MSG(__builtin_constant_p(_val) ?   \
-~((_mask) >> __bf_shf(_mask)) & (_val) : 0, \
-_pfx "value too large for the field"); \
-   BUILD_BUG_ON_MSG((_mask) > (typeof(_reg))~0ull,  \
-_pfx "type of reg too small for mask"); \
-   __BUILD_BUG_ON_NOT_POWER_OF_2((_mask) + \
- (1ULL << __bf_shf(_mask))); \
-   })
+   BUILD_BUG_ON_RET_ZERO(!__builtin_constant_p(_mask)) +   \
+   BUILD_BUG_ON_RET_ZERO((_mask) == 0) +   \
+   BUILD_BUG_ON_RET_ZERO(__builtin_constant_p(_val) ?  \
+ ~((_mask) >> __bf_shf(_mask)) & (_val) : 0) + \
+   BUILD_BUG_ON_RET_ZERO((_mask) > (typeof(_reg))~0ull) +   \
+   BUILD_BUG_ON_NOT_POW2_RET_ZERO((_mask) + (1ULL << __bf_shf(_mask)))

 /**
  * FIELD_FIT() - check if value fits in the field
@@ -85,10 +82,8 @@
  * be combined with other fields of the bitfield using logical OR.
  */
 #define FIELD_PREP(_mask, _val)
\
-   ({  \
-   __BF_FIELD_CHECK(_mask, 0ULL, _val, "FIELD_PREP: ");  \
-   ((typeof(_mask))(_val) << __bf_shf(_mask)) & (_mask); \
-   })
+   (__BF_FIELD_CHECK(_mask, 0ULL, _val, "FIELD_PREP: ") +\
+(((typeof(_mask))(_val) << __bf_shf(_mask)) & (_mask)))

 /**
  * FIELD_GET() - extract a bitfield element


Note that this is an incomplete patch - everything but FIELD_PREP will
not compile with this.

Also, BUILD_BUG_ON_RET_ZERO and BUILD_BUG_ON_NOT_POW2_RET_ZERO should
probably have better names, or perhaps do the positive way that I did in
__NLA_ENSURE, e.g. CONST_ASSERT()/CONST_ASSERT_IS_POWER_OF_2()? I guess
they should go to build_bug.h as well...


Seems reasonable. However I did try this and was getting compiler 
warnings about VLA, from a non-constant being fed into 
BUILD_BUG_ON_RET_ZERO(), related to sizeof char[]:
drivers/iio/adc/meson_saradc.c:375:2: warning: ISO C90 forbids variable 
length array [-Wvla]

  regval = FIELD_PREP(MESON_SAR_ADC_CHAN_LIST_ENTRY_MASK(0),

Surely __NLA_ENSURE is getting a similar issue as it uses a similar 
principle, no? I see that this is in -next now, but could not this macro 
or derivatives being referenced.






Much appreciated,
John


johannes

.






Re: [for -stable] commit "c82919888064 ath10k: fix scan crash due to incorrect length calculation"

2018-10-11 Thread Greg KH
On Thu, Sep 06, 2018 at 02:36:22PM -0700, Brian Norris wrote:
> Hi Greg / stable maintainer(s),
> 
> IIUC, this commit is a good candidate for -stable. I just hit the bug on
> 4.14, because of new vendor firmware that noticed the mismatched length
> (an internal "assert"), but it seems like this is equally problematic
> from the kernel side for as long as this code existed [1]:
> 
> commit c8291988806407e02a01b4b15b4504eafbcc04e0
> Author: Zhi Chen 
> Date:   Mon Jun 18 17:00:39 2018 +0300
> 
> ath10k: fix scan crash due to incorrect length calculation
> 
> Thanks,
> Brian
> 
> [1] I guess that would be:
> 
> Fixes: ca996ec56608 ("ath10k: implement wmi-tlv backend")
> 
> which was in v4.0.

Thanks, now queued up.

greg k-h


Intel 8265 unstable/asymmetric ping response time (only under Linux)

2018-10-11 Thread Qu Wenruo
Hi,

I found one pretty strange behavior for the Intel 8265/8275 wireless
(from ThinkPad X1 carbon)

If I ping *FROM* my router/desktop to the wireless laptop, the response
time is very unstable and slow, like:
--
$ ping -4 thinkpad
PING thinkpad.lan (172.16.0.100) 56(84) bytes of data.
64 bytes from thinkpad.lan (172.16.0.100): icmp_seq=1 ttl=64 time=143 ms
64 bytes from thinkpad.lan (172.16.0.100): icmp_seq=2 ttl=64 time=166 ms
64 bytes from thinkpad.lan (172.16.0.100): icmp_seq=3 ttl=64 time=188 ms
64 bytes from thinkpad.lan (172.16.0.100): icmp_seq=4 ttl=64 time=211 ms
64 bytes from thinkpad.lan (172.16.0.100): icmp_seq=5 ttl=64 time=29.8 ms
64 bytes from thinkpad.lan (172.16.0.100): icmp_seq=6 ttl=64 time=51.7 ms
64 bytes from thinkpad.lan (172.16.0.100): icmp_seq=7 ttl=64 time=72.8 ms
64 bytes from thinkpad.lan (172.16.0.100): icmp_seq=8 ttl=64 time=94.6 ms
64 bytes from thinkpad.lan (172.16.0.100): icmp_seq=9 ttl=64 time=117 ms
64 bytes from thinkpad.lan (172.16.0.100): icmp_seq=10 ttl=64 time=140 ms
64 bytes from thinkpad.lan (172.16.0.100): icmp_seq=11 ttl=64 time=163 ms
64 bytes from thinkpad.lan (172.16.0.100): icmp_seq=12 ttl=64 time=186 ms
64 bytes from thinkpad.lan (172.16.0.100): icmp_seq=13 ttl=64 time=207 ms
64 bytes from thinkpad.lan (172.16.0.100): icmp_seq=14 ttl=64 time=25.1 ms
64 bytes from thinkpad.lan (172.16.0.100): icmp_seq=15 ttl=64 time=47.6 ms
-

It looks like the response time get increase by 20ms and flipped over
around 200ms.

But when pinging *FROM* the laptop to the router/desktop, it's
completely fine:

--
$ ping openwrt
PING openwrt.lan (172.16.0.1) 56(84) bytes of data.
64 bytes from _gateway (172.16.0.1): icmp_seq=1 ttl=64 time=2.52 ms
64 bytes from _gateway (172.16.0.1): icmp_seq=2 ttl=64 time=3.59 ms
64 bytes from _gateway (172.16.0.1): icmp_seq=3 ttl=64 time=2.54 ms
64 bytes from _gateway (172.16.0.1): icmp_seq=4 ttl=64 time=3.11 ms
64 bytes from _gateway (172.16.0.1): icmp_seq=5 ttl=64 time=2.93 ms
64 bytes from _gateway (172.16.0.1): icmp_seq=6 ttl=64 time=2.69 ms
64 bytes from _gateway (172.16.0.1): icmp_seq=7 ttl=64 time=3.49 ms
64 bytes from _gateway (172.16.0.1): icmp_seq=8 ttl=64 time=2.58 ms
64 bytes from _gateway (172.16.0.1): icmp_seq=9 ttl=64 time=2.75 ms
64 bytes from _gateway (172.16.0.1): icmp_seq=10 ttl=64 time=2.60 ms
--

The kernel is 4.18.12-arch1-1-ARCH, so it's pretty new.
The BIOS of the ThinkPad is already updated with fwpud.

BTW, if I boot that thinkpad with Windows, no matter I ping from/to that
laptop, response time is always around 2~3ms.

So is this something wrong with the wireless card or something wrong
with the firmware/powersaving setting of ThinkPad X1 Carbon 6th gen?

Thanks
Qu



signature.asc
Description: OpenPGP digital signature


Re: linux-next: manual merge of the crypto tree with the mac80211-next tree

2018-10-11 Thread Herbert Xu
On Thu, Oct 11, 2018 at 12:08:57PM +0200, Johannes Berg wrote:
>
> Herbert, maybe you can drop the patch from the crypto tree since my
> change also removes the VLA usage?

Sorry but it's too late now.

Cheers,
-- 
Email: Herbert Xu 
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt


[PATCH 2/2] ath10k: report tx rate using ieee80211_tx_rate_update()

2018-10-11 Thread Anilkumar Kolli
Mesh path metric needs tx rate information from ieee80211_tx_status()
call but in ath10k there is no mechanism to report tx rate information
via ieee80211_tx_status(), the tx rate is only accessible via
sta_statiscs() op.

Per peer tx stats has tx rate info available, Tx rate is available
to ath10k driver after every 4 PPDU sent in the air. For each PPDU,
ath10k driver updates rate informattion to mac80211 using
ieee80211_tx_rate_update().

Per peer txrate information is updated through per peer statistics
and is available for QCA9888/QCA9984/QCA4019/QCA998X only

Tested on QCA9984 with firmware-5.bin_10.4-3.5.3-00053
Tested on QCA998X with firmware-5.bin_10.2.4-1.0-00036

Signed-off-by: Anilkumar Kolli 
---
 drivers/net/wireless/ath/ath10k/core.h   |1 +
 drivers/net/wireless/ath/ath10k/htt_rx.c |   70 +++---
 drivers/net/wireless/ath/ath10k/wmi.h|1 +
 3 files changed, 66 insertions(+), 6 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/core.h 
b/drivers/net/wireless/ath/ath10k/core.h
index 491eb0d2fc5f..cd4ed5cab630 100644
--- a/drivers/net/wireless/ath/ath10k/core.h
+++ b/drivers/net/wireless/ath/ath10k/core.h
@@ -494,6 +494,7 @@ struct ath10k_sta {
u32 smps;
u16 peer_id;
struct rate_info txrate;
+   struct ieee80211_tx_info tx_info;
 
struct work_struct update_wk;
u64 rx_duration;
diff --git a/drivers/net/wireless/ath/ath10k/htt_rx.c 
b/drivers/net/wireless/ath/ath10k/htt_rx.c
index b862d5de5e2f..2c871ecd6afc 100644
--- a/drivers/net/wireless/ath/ath10k/htt_rx.c
+++ b/drivers/net/wireless/ath/ath10k/htt_rx.c
@@ -2627,7 +2627,7 @@ void ath10k_htt_htc_t2h_msg_handler(struct ath10k *ar, 
struct sk_buff *skb)
dev_kfree_skb_any(skb);
 }
 
-static inline int ath10k_get_legacy_rate_idx(struct ath10k *ar, u8 rate)
+static inline s8 ath10k_get_legacy_rate_idx(struct ath10k *ar, u8 rate)
 {
static const u8 legacy_rates[] = {1, 2, 5, 11, 6, 9, 12,
  18, 24, 36, 48, 54};
@@ -2646,7 +2646,7 @@ static inline int ath10k_get_legacy_rate_idx(struct 
ath10k *ar, u8 rate)
 ath10k_accumulate_per_peer_tx_stats(struct ath10k *ar,
struct ath10k_sta *arsta,
struct ath10k_per_peer_tx_stats *pstats,
-   u8 legacy_rate_idx)
+   s8 legacy_rate_idx)
 {
struct rate_info *txrate = >txrate;
struct ath10k_htt_tx_stats *tx_stats;
@@ -2768,8 +2768,11 @@ static inline int ath10k_get_legacy_rate_idx(struct 
ath10k *ar, u8 rate)
struct ath10k_per_peer_tx_stats *peer_stats)
 {
struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
-   u8 rate = 0, rate_idx = 0, sgi;
+   struct ieee80211_chanctx_conf *conf = NULL;
struct rate_info txrate;
+   u8 rate = 0, sgi;
+   s8 rate_idx = 0;
+   bool skip_auto_rate;
 
lockdep_assert_held(>data_lock);
 
@@ -2778,6 +2781,13 @@ static inline int ath10k_get_legacy_rate_idx(struct 
ath10k *ar, u8 rate)
txrate.nss = ATH10K_HW_NSS(peer_stats->ratecode);
txrate.mcs = ATH10K_HW_MCS_RATE(peer_stats->ratecode);
sgi = ATH10K_HW_GI(peer_stats->flags);
+   skip_auto_rate = ATH10K_FW_SKIPPED_RATE_CTRL(peer_stats->flags);
+
+   /* Firmware's rate control skips broadcast/management frames,
+* if host has configure fixed rates and in some other special cases.
+*/
+   if (skip_auto_rate)
+   return;
 
if (txrate.flags == WMI_RATE_PREAMBLE_VHT && txrate.mcs > 9) {
ath10k_warn(ar, "Invalid VHT mcs %hhd peer stats",  txrate.mcs);
@@ -2792,7 +2802,7 @@ static inline int ath10k_get_legacy_rate_idx(struct 
ath10k *ar, u8 rate)
}
 
memset(>txrate, 0, sizeof(arsta->txrate));
-
+   memset(>tx_info.status, 0, sizeof(arsta->tx_info.status));
if (txrate.flags == WMI_RATE_PREAMBLE_CCK ||
txrate.flags == WMI_RATE_PREAMBLE_OFDM) {
rate = ATH10K_HW_LEGACY_RATE(peer_stats->ratecode);
@@ -2811,11 +2821,59 @@ static inline int ath10k_get_legacy_rate_idx(struct 
ath10k *ar, u8 rate)
arsta->txrate.mcs = txrate.mcs;
}
 
-   if (sgi)
-   arsta->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
+   switch (txrate.flags) {
+   case WMI_RATE_PREAMBLE_OFDM:
+   if (arsta->arvif && arsta->arvif->vif)
+   conf = rcu_dereference(arsta->arvif->vif->chanctx_conf);
+   if (conf && conf->def.chan->band == NL80211_BAND_5GHZ)
+   arsta->tx_info.status.rates[0].idx = rate_idx - 4;
+   break;
+   case WMI_RATE_PREAMBLE_CCK:
+   arsta->tx_info.status.rates[0].idx = rate_idx;
+   if (sgi)
+   arsta->tx_info.status.rates[0].flags |=
+   

[PATCH 1/2] mac80211: implement ieee80211_tx_rate_update to update rate

2018-10-11 Thread Anilkumar Kolli
Current mac80211 has provision to update tx status through
ieee80211_tx_status() and ieee80211_tx_status_ext(). But
drivers like ath10k updates the tx status from the skb except
txrate, txrate will be updated from a different path, peer stats.

Using ieee80211_tx_status_ext() in two different paths
  - (one for the stats, one for the tx rate) will duplicate the stats.

To avoid this stats duplication, ieee80211_tx_rate_update() is implemented.

Signed-off-by: Anilkumar Kolli 
---
 include/net/mac80211.h |   15 +++
 net/mac80211/status.c  |   22 ++
 2 files changed, 37 insertions(+)

diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index c4fadbafbf21..86a6b1117a16 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -4352,6 +4352,21 @@ void ieee80211_sta_set_expected_throughput(struct 
ieee80211_sta *pubsta,
   u32 thr);
 
 /**
+ * ieee80211_tx_rate_update - transmit rate update callback
+ *
+ * Drivers should call this functions with a non-NULL pub sta
+ * This function can be used in drivers that does not have provision
+ * in updating the tx rate in data path.
+ *
+ * @hw: the hardware the frame was transmitted by
+ * @pubsta: the station to update the tx rate for.
+ * @info: tx status information
+ */
+void ieee80211_tx_rate_update(struct ieee80211_hw *hw,
+ struct ieee80211_sta *pubsta,
+ struct ieee80211_tx_info *info);
+
+/**
  * ieee80211_tx_status - transmit status callback
  *
  * Call this function for all transmitted frames after they have been
diff --git a/net/mac80211/status.c b/net/mac80211/status.c
index 91d7c0cd1882..6272fe1b351d 100644
--- a/net/mac80211/status.c
+++ b/net/mac80211/status.c
@@ -987,6 +987,28 @@ void ieee80211_tx_status_ext(struct ieee80211_hw *hw,
 }
 EXPORT_SYMBOL(ieee80211_tx_status_ext);
 
+void ieee80211_tx_rate_update(struct ieee80211_hw *hw,
+ struct ieee80211_sta *pubsta,
+ struct ieee80211_tx_info *info)
+{
+   struct ieee80211_local *local = hw_to_local(hw);
+   struct ieee80211_supported_band *sband;
+   struct sta_info *sta;
+   struct ieee80211_tx_status status;
+
+   sband = hw->wiphy->bands[info->band];
+
+   sta = container_of(pubsta, struct sta_info, sta);
+   status.skb = NULL;
+   status.info = info;
+   status.sta = pubsta;
+
+   rate_control_tx_status(local, sband, );
+   if (ieee80211_hw_check(>hw, HAS_RATE_CONTROL))
+   sta->tx_stats.last_rate = info->status.rates[0];
+}
+EXPORT_SYMBOL(ieee80211_tx_rate_update);
+
 void ieee80211_report_low_ack(struct ieee80211_sta *pubsta, u32 num_packets)
 {
struct sta_info *sta = container_of(pubsta, struct sta_info, sta);
-- 
1.7.9.5



[PATCH 0/2] ath10k: Add support to update tx rate to mac80211

2018-10-11 Thread Anilkumar Kolli
Tx rate was updated to nl80211/user using sta_statistics callback.
This rate can not be used for mac80211 mesh and ATF.

This patch adds support to update tx rate to mac80211

Anilkumar Kolli (2):
  mac80211: implement ieee80211_tx_rate_update to update rate
  ath10k: report tx rate using ieee80211_tx_rate_update()

 drivers/net/wireless/ath/ath10k/core.h   |1 +
 drivers/net/wireless/ath/ath10k/htt_rx.c |   70 +++---
 drivers/net/wireless/ath/ath10k/wmi.h|1 +
 include/net/mac80211.h   |   15 +++
 net/mac80211/status.c|   22 ++
 5 files changed, 103 insertions(+), 6 deletions(-)

-- 
1.7.9.5



Re: [PATCH v3 4/4] rt2800: fix registers init for MT7620

2018-10-11 Thread Tom Psyborg
so this is RX test where I assume your 7265 card is sending data. is
that HT20 or HT40 mode and do you get regression on TX too?

can you try same case 2 test but with registers set to:

TX_SW_CFG0, 0x0401
TX_SW_CFG1, 0x000C
TX_SW_CFG2, 0x (or 0x000C0408)

did you ever notice any tx power difference between nexx fw and openwrt fw?

On 11/10/2018, Stanislaw Gruszka  wrote:
> On Wed, Oct 10, 2018 at 10:03:12PM +0200, Tom Psyborg wrote:
>> ok, that is strange. do you see any performance differences without
>> TX_SW_CFG regs? iperf test is a good pointer.
>>
>> this was a problem on xiaomi mini with old DD trunk builds on 4.4
>> kernel and LEDE builds from last year. i ain't got no chance to try
>> this on 18.06. which device you tried this on? if ipa/ilna it might
>> make no difference
>
> No diffrence for me. I have nexx wt3020 8M.
>
> However I notice this set couse performance regression for me.
> When connecting to iwl 7265 . Without the set I have:
>
> root@LEDE:~# iperf3 -c 192.168.10.243
> Connecting to host 192.168.10.243, port 5201
> [  5] local 192.168.10.1 port 59304 connected to 192.168.10.243 port 5201
> [ ID] Interval   Transfer Bitrate Retr  Cwnd
> [  5]   0.00-1.00   sec  5.37 MBytes  44.9 Mbits/sec0279 KBytes
>
> [  5]   1.00-2.00   sec  5.80 MBytes  48.8 Mbits/sec0494 KBytes
>
> [  5]   2.00-3.00   sec  6.03 MBytes  50.5 Mbits/sec0513 KBytes
>
> [  5]   3.00-4.01   sec  5.90 MBytes  49.2 Mbits/sec0513 KBytes
>
> [  5]   4.01-5.01   sec  5.90 MBytes  49.5 Mbits/sec0515 KBytes
>
> [  5]   5.01-6.00   sec  5.78 MBytes  48.9 Mbits/sec0515 KBytes
>
> [  5]   6.00-7.00   sec  5.66 MBytes  47.4 Mbits/sec0515 KBytes
>
> [  5]   7.00-8.00   sec  6.03 MBytes  50.6 Mbits/sec0515 KBytes
>
> [  5]   8.00-9.00   sec  6.09 MBytes  50.9 Mbits/sec0515 KBytes
>
> [  5]   9.00-10.00  sec  5.72 MBytes  48.2 Mbits/sec0515 KBytes
>
> - - - - - - - - - - - - - - - - - - - - - - - - -
> [ ID] Interval   Transfer Bitrate Retr
> [  5]   0.00-10.00  sec  58.3 MBytes  48.9 Mbits/sec0
> sender
> [  5]   0.00-10.00  sec  58.3 MBytes  48.9 Mbits/sec
> receiver
>
> With the set I have:
>
> root@LEDE:~# iperf3  -c 192.168.10.243
> Connecting to host 192.168.10.243, port 5201
> [  5] local 192.168.10.1 port 45824 connected to 192.168.10.243 port 5201
> [ ID] Interval   Transfer Bitrate Retr  Cwnd
> [  5]   0.00-1.00   sec  3.78 MBytes  31.7 Mbits/sec0197 KBytes
> [  5]   1.00-2.00   sec  3.71 MBytes  31.0 Mbits/sec0369 KBytes
> [  5]   2.00-3.00   sec  3.51 MBytes  29.5 Mbits/sec0484 KBytes
> [  5]   3.00-4.00   sec  3.36 MBytes  28.1 Mbits/sec0519 KBytes
> [  5]   4.00-5.00   sec  4.10 MBytes  34.4 Mbits/sec0519 KBytes
> [  5]   5.00-6.00   sec  3.73 MBytes  31.2 Mbits/sec0519 KBytes
> [  5]   6.00-7.00   sec  4.29 MBytes  36.0 Mbits/sec0519 KBytes
> [  5]   7.00-8.00   sec  4.16 MBytes  34.9 Mbits/sec0519 KBytes
> [  5]   8.00-9.00   sec  4.35 MBytes  36.5 Mbits/sec0519 KBytes
> [  5]   9.00-10.00  sec  4.41 MBytes  37.0 Mbits/sec0519 KBytes
> - - - - - - - - - - - - - - - - - - - - - - - - -
> [ ID] Interval   Transfer Bitrate Retr
> [  5]   0.00-10.00  sec  39.4 MBytes  33.0 Mbits/sec0
> sender
> [  5]   0.00-10.00  sec  39.4 MBytes  33.0 Mbits/sec
> receiver
>
>
> Stanislaw
>
>


Re: [PATCH RFC v5 3/4] mac80211: Add airtime accounting and scheduling to TXQs

2018-10-11 Thread Toke Høiland-Jørgensen
Rajkumar Manoharan  writes:

> On 2018-10-10 04:15, Toke Høiland-Jørgensen wrote:
>> Rajkumar Manoharan  writes:
>> 
>>> On 2018-10-09 05:32, Toke Høiland-Jørgensen wrote:
 This adds airtime accounting and scheduling to the mac80211 TXQ
 scheduler. A new callback, ieee80211_sta_register_airtime(), is added
 that drivers can call to report airtime usage for stations.
 
 When airtime information is present, mac80211 will schedule TXQs
 (through ieee80211_next_txq()) in a way that enforces airtime 
 fairness
 between active stations. This scheduling works the same way as the
 ath9k
 in-driver airtime fairness scheduling. If no airtime usage is 
 reported
 by the driver, the scheduler will default to round-robin scheduling.
 
 For drivers that don't control TXQ scheduling in software, a new API
 function, ieee80211_txq_may_transmit(), is added which the driver can
 use
 to check if the TXQ is eligible for transmission, or should be
 throttled to
 enforce fairness. Calls to this function must also be enclosed in
 ieee80211_txq_schedule_{start,end}() calls to ensure proper locking.
 TXQs
 that are throttled by ieee802111_txq_may_transmit() will be woken up
 again
 by a check added to the ieee80211_wake_txqs() tasklet.
 
>>> 
>>> Toke,
>>> 
>>> I am observing soft lockup issues again with this new series while
>>> running traffic with 50 clients. I am continuing testing with earlier
>>> series along with snippet I shared.
>> 
>> Are these new lockups (that was not in your patched previous version),
>> or did I just not get all your lock-related fixes incorporated?
>> 
>>> When driver operates in pull-mode, throttled txqs are marked and
>>> refilled in airtime_tasklet. This is causing major throughput drops
>>> and packet loss and I am suspecting the latency in replenishing
>>> deficit. Whereas in push-mode or in ath9k model, refill happens
>>> quicker at every packet indication as well as tx completion.
>> 
>> Yeah, the tasklet shouldn't be the main source of deficit replenishing.
>> Can see why that would give bad performance :)
>> 
>>> I am planning to get rid of tasklet completely as it is only meant for
>>> pull-mode. It would be better to refill in may_transmit() itself.
>> 
>> Hmm, right. So the way to do this correctly (from a fairness point of
>> view) would be something like this (in max_tx()):
>> 
>> if (this_txq.stn.deficit > 0)
>>   return true;
>> 
>> else if (any queued TXQ currently have positive deficit)
>>   return false; /* other TXQ should try may_tx() later and get 
>> permission */
>> 
>> else /* all deficits < 0 */
>>   return replenish_deficits(this_txq);
>> 
>> And replenish_deficits() would be something like:
>> 
>> replenish_deficits(this_txq) {
>> repeat:
>>   for (txq in queued txqs) {
>> txq.stn.deficit += stn.weight;
>> if (txq.stn.deficit > 0 && !wake_txq)
>>   wake_txq = txq;
>>   }
>>   if not wake_txq:
>> goto repeat;
>> 
>>   if (this_txq.stn.deficit > 0)
>> return true;
>>   else
>> drv_wake_tx_queue(wake_txq);
>> }
>> 
>> The wake_tx_queue call may have to be delegated to a tasklet still, to
>> avoid the infinite recursion problem I mentioned earlier. But the
>> tasklet could be made simpler and wouldn't have to be called so 
>> often...
>> 
>> Does the above make sense?
>> 
> Hmm... mine is bit different. txqs are refilled only once for all txqs.
> It will give more opportunity for non-served txqs. drv_wake_tx_queue 
> won't be
> called from may_tx as the driver anyway will not push packets in 
> pull-mode.

So, as far as I can tell, this requires the hardware to "keep trying"?
I.e., if it just stops scheduling a TXQ after may_transmit() returns
false, there is no guarantee that that TXQ will ever get re-awoken
unless a new packet arrives for it?

-Toke


Re: linux-next: manual merge of the crypto tree with the mac80211-next tree

2018-10-11 Thread Johannes Berg
On Thu, 2018-10-11 at 11:13 +1100, Stephen Rothwell wrote:
> Hi all,
> 
> Today's linux-next merge of the crypto tree got conflicts in:
> 
>   net/wireless/lib80211_crypt_tkip.c
>   net/wireless/lib80211_crypt_wep.c
> 
> between commit:
> 
>   b802a5d6f345 ("lib80211: don't use skcipher")
> 
> from the mac80211-next tree and commit:
> 
>   db20f570e17a ("lib80211: Remove VLA usage of skcipher")
> 
> from the crypto tree.

Thanks Stephen.

The fixup (use mac80211-next file) is fine, but I'm not sure we want to
bother Linus/Greg with it?

Herbert, maybe you can drop the patch from the crypto tree since my
change also removes the VLA usage?

johannes


Re: [PATCH 0/4] rt2800: more register programing tweaks

2018-10-11 Thread Stanislaw Gruszka
On Wed, Oct 10, 2018 at 05:46:16PM +0200, Stanislaw Gruszka wrote:
> This is on top of previous post:
> https://marc.info/?l=linux-wireless=153908617400582=2
> 
> Stanislaw Gruszka (4):
>   rt2800: enable TX_PIN_CFG_LNA_PE_ bits per band
>   rt2800: enable TX_PIN_CFG_RFRX_EN only for MT7620
>   rt2800: remove unneeded RT6352 check
>   rt2800: comment and simplify AGC init for RT6352
> 
>  drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 37 
> --
>  1 file changed, 23 insertions(+), 14 deletions(-)

and drop this one as well.

Thanks
Stanislaw


Re: [PATCH v3 1/4] rt2x00: remove unneeded check

2018-10-11 Thread Stanislaw Gruszka
Kalle, plese drop this set it has to be reworked.

Thanks
Stanislaw


Re: [RFC v2] cfg80211: add peer measurement with FTM API

2018-10-11 Thread Johannes Berg
On Tue, 2018-10-09 at 17:40 +0300, Lior David wrote:

> Thanks for the explanation. The send to same socket does sound more efficient.
> (In our internal implementation with vendor commands we were forced
> to send the results as broadcast...)

I suppose we can fix that, in the sense that we can add API to allow
vendor commands to know the socket to send back to etc.

> Yes as far as I remember rtt<->distance is a trivial calculation. What I meant
> here, you return the average of few measurements done in a burst, and for
> debugging we could return all the measurements done in the burst. For example 
> if
> there were 4 measurements per burst return the 4 distance measurements done.

Ah, OK. I guess you'd have to report separate measurements or something.
Though if it's for debugging I'd think it may not make sense in this API
but rather something out-of-band.

> I meant we could have an AoA value (angle in degrees or other units) which
> drivers can fill up if they want. For example if the driver has 2 antennas on
> both sides it can report either 90 or 270 degrees. It will be usually very low
> accuracy but at least can provide some information like from which side of the
> AP you are. This can certainly be added later if at all (hopefully we will 
> have
> AoA measurement with higher accuracy in the future)

Yeah, ok, I get it now - I guess we can add it if somebody plays with it
and finds how to obtain and use the value.

> > > For connected station, usually you will want to do the measurement on the
> > > connected channel (possibly some chips will not be able to do otherwise)
> > > Maybe add option to use default channel?
> > 
> > Perhaps. It's somewhat complicated to look up in general, userspace
> > generally has a decent idea, and making it optional means you end up
> > with an invalid chandef?
> > 
> > I'll take a look, perhaps just leaving all the fields 0/NULL can work
> > reasonably well, but drivers would have to support it.
> > 
> 
> As I remember the driver/FW can easily find the connected channel for 
> connected
> station. For unconnected station we should probably force this parameter.

Should be able to, yes, but I suppose even userspace can. It just seems
like extra complexity to impose on the driver, since cfg80211 doesn't
necessarily have all the right information.

Actually, hmm, that would imply "use maximum bandwidth" or something?
And then what if that bandwidth isn't possible with FTM for some reason?
It's a bit tricky then.

> > If so, that sounds like something that generally needs improvement?
> > 
> 
> Good point. I see we currently use 20_NOHT for DMG, guess we can continue 
> using it.

Well, I think it'd make more sense to just enforce the DMG bandwidth
everywhere, but I won't force the issue over this.

> Ok I thought 15 meant to actually request 65535 bursts :-)
> I still prefer the default to be 1 burst. Supporting the "no preference" means
> it will be difficult to pre-allocate memory for burst results. Also all 
> drivers
> should know to do one burst.

Fair, I'll change it.

johannes


Re: [PATCH v3 4/4] rt2800: fix registers init for MT7620

2018-10-11 Thread Stanislaw Gruszka
On Wed, Oct 10, 2018 at 10:03:12PM +0200, Tom Psyborg wrote:
> ok, that is strange. do you see any performance differences without
> TX_SW_CFG regs? iperf test is a good pointer.
> 
> this was a problem on xiaomi mini with old DD trunk builds on 4.4
> kernel and LEDE builds from last year. i ain't got no chance to try
> this on 18.06. which device you tried this on? if ipa/ilna it might
> make no difference

No diffrence for me. I have nexx wt3020 8M.

However I notice this set couse performance regression for me. 
When connecting to iwl 7265 . Without the set I have:

root@LEDE:~# iperf3 -c 192.168.10.243
Connecting to host 192.168.10.243, port 5201
[  5] local 192.168.10.1 port 59304 connected to 192.168.10.243 port 5201
[ ID] Interval   Transfer Bitrate Retr  Cwnd
[  5]   0.00-1.00   sec  5.37 MBytes  44.9 Mbits/sec0279 KBytes   
[  5]   1.00-2.00   sec  5.80 MBytes  48.8 Mbits/sec0494 KBytes   
[  5]   2.00-3.00   sec  6.03 MBytes  50.5 Mbits/sec0513 KBytes   
[  5]   3.00-4.01   sec  5.90 MBytes  49.2 Mbits/sec0513 KBytes   
[  5]   4.01-5.01   sec  5.90 MBytes  49.5 Mbits/sec0515 KBytes   
[  5]   5.01-6.00   sec  5.78 MBytes  48.9 Mbits/sec0515 KBytes   
[  5]   6.00-7.00   sec  5.66 MBytes  47.4 Mbits/sec0515 KBytes   
[  5]   7.00-8.00   sec  6.03 MBytes  50.6 Mbits/sec0515 KBytes   
[  5]   8.00-9.00   sec  6.09 MBytes  50.9 Mbits/sec0515 KBytes   
[  5]   9.00-10.00  sec  5.72 MBytes  48.2 Mbits/sec0515 KBytes   
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval   Transfer Bitrate Retr
[  5]   0.00-10.00  sec  58.3 MBytes  48.9 Mbits/sec0 sender
[  5]   0.00-10.00  sec  58.3 MBytes  48.9 Mbits/sec  receiver

With the set I have:

root@LEDE:~# iperf3  -c 192.168.10.243
Connecting to host 192.168.10.243, port 5201
[  5] local 192.168.10.1 port 45824 connected to 192.168.10.243 port 5201
[ ID] Interval   Transfer Bitrate Retr  Cwnd
[  5]   0.00-1.00   sec  3.78 MBytes  31.7 Mbits/sec0197 KBytes
[  5]   1.00-2.00   sec  3.71 MBytes  31.0 Mbits/sec0369 KBytes
[  5]   2.00-3.00   sec  3.51 MBytes  29.5 Mbits/sec0484 KBytes
[  5]   3.00-4.00   sec  3.36 MBytes  28.1 Mbits/sec0519 KBytes
[  5]   4.00-5.00   sec  4.10 MBytes  34.4 Mbits/sec0519 KBytes
[  5]   5.00-6.00   sec  3.73 MBytes  31.2 Mbits/sec0519 KBytes
[  5]   6.00-7.00   sec  4.29 MBytes  36.0 Mbits/sec0519 KBytes
[  5]   7.00-8.00   sec  4.16 MBytes  34.9 Mbits/sec0519 KBytes
[  5]   8.00-9.00   sec  4.35 MBytes  36.5 Mbits/sec0519 KBytes
[  5]   9.00-10.00  sec  4.41 MBytes  37.0 Mbits/sec0519 KBytes
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval   Transfer Bitrate Retr
[  5]   0.00-10.00  sec  39.4 MBytes  33.0 Mbits/sec0 sender
[  5]   0.00-10.00  sec  39.4 MBytes  33.0 Mbits/sec  receiver


Stanislaw



[PATCH] iwlwifi: fix spelling mistake "registrating" -> "registering"

2018-10-11 Thread Colin King
From: Colin Ian King 

Trivial fix to spelling mistake in IWL_ERR error message

Signed-off-by: Colin Ian King 
---
 drivers/net/wireless/intel/iwlwifi/dvm/main.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/main.c 
b/drivers/net/wireless/intel/iwlwifi/dvm/main.c
index 1088ff036e13..a5041d92babc 100644
--- a/drivers/net/wireless/intel/iwlwifi/dvm/main.c
+++ b/drivers/net/wireless/intel/iwlwifi/dvm/main.c
@@ -1054,7 +1054,7 @@ static void iwl_bg_restart(struct work_struct *data)
ieee80211_restart_hw(priv->hw);
else
IWL_ERR(priv,
-   "Cannot request restart before registrating 
with mac80211\n");
+   "Cannot request restart before registering with 
mac80211\n");
} else {
WARN_ON(1);
}
-- 
2.17.1



[PATCH v4 2/2] brcmfmac: Fix ccode from EFI nvram when necessary

2018-10-11 Thread Hans de Goede
In some cases the EFI-var stored nvram contains "ccode=ALL" or "ccode=XV"
to specify "worldwide" compatible settings, but these 2 ccode-s do not work
properly.

I've tested the different known "worldwide" ccode-s used in various nvram
sources with the latest firmwares from linux-firmware for various brcmfmac
models, here is a simplified (*) table with what each setting results in:

ALL: 12-14 disab, U-NII-1, U-NII-2 no-IR/radar, U-NII-3
XV:  12-14 no-IR, disables all 5G channels
XY:  12-13 enab, 14 disab, U-NII-1 enab, U-NII-2 no-IR/radar, U-NII-3 disab
X2:  12-13 no-IR, 14 dis, U-NII-1 no-IR, U-NII-2 no-IR/radar, U-NII-3 no-IR

Where 12,13,14 are 2.4G channels 12-14 and U-NII-1/2/3 are the 3 different
5G channel groups. no-IR is no-Initiate-Radiation, we will never send on
these channels without first having received valid wifi traffic there.

This immediately shows that both ALL and XV are not as worldwide as we want
them to be. ALL causes channels 12 and 13 to not be available and XV causes
all 5GHz channels to not be available. Also ALL unconditionally enables the
U-NII-1 and U-NII-3 5G groups, while we really should be using no-IR for
these.

This commit replace XV and ALL with X2, which allows usage of chan 12-13
and 5G channels, but only after receiving valid wifi traffic there first.

Note that this configure the firmware's channel limits, the kernels own
regulatory restrictions based on e.g. regulatory info received from the
access-point, will be applied on top of this.

This fixes channels 12+13 not working on the Asus T200TA and the Lenovo
Mixx 2 8 and 5G channels not working on the Asus T100HA.

This has been tested on the following models: Acer Iconia Tab8 w1-810,
Acer One 10, Asus T100CHI, Asus T100HA, Asus T100TA, Asus T200TA and a
Lenovo Mixx 2 8.

*) There are some exceptions to this table:
1) On really old firmware e.g. linux-firmware's 2011 brcmfmac4330-sdio.bin
   ALL really means all, unconditionally enabling everything
2) The exact meaning might be influenced by setting the regrev nvram var.
   Specifically using ccode=XV + regrev=1 on brcmfmac43241b4 leads to:
   12-14 no-ir, U-NII-1 no-ir, U-NII-2 no-ir/radar, U-NII-3 no-ir
   But only on the brcmfmac43241b4 and not on e.g. the brcmfmac43340

Tested-by: Hans de Goede 
Signed-off-by: Hans de Goede 
---
Changes in v4:
-Rebase for changes to "brcmfmac: Add support for getting nvram contents
 from EFI variables" patch

Changes in v3:
-New patch in v3 of this patch-set
---
 .../broadcom/brcm80211/brcmfmac/firmware.c| 24 +++
 1 file changed, 24 insertions(+)

diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c 
b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c
index 965ae5c24c2d..72d8c0c3c3a1 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c
@@ -447,6 +447,29 @@ struct brcmf_fw {
 static void brcmf_fw_request_done(const struct firmware *fw, void *ctx);
 
 #ifdef CONFIG_EFI
+/* In some cases the EFI-var stored nvram contains "ccode=ALL" or "ccode=XV"
+ * to specify "worldwide" compatible settings, but these 2 ccode-s do not work
+ * properly. "ccode=ALL" causes channels 12 and 13 to not be available,
+ * "ccode=XV" causes all 5GHz channels to not be available. So we replace both
+ * with "ccode=X2" which allows channels 12+13 and 5Ghz channels in
+ * no-Initiate-Radiation mode. This means that we will never send on these
+ * channels without first having received valid wifi traffic on the channel.
+ */
+static void brcmf_fw_fix_efi_nvram_ccode(char *data, unsigned long data_len)
+{
+   char *ccode;
+
+   ccode = strnstr((char *)data, "ccode=ALL", data_len);
+   if (!ccode)
+   ccode = strnstr((char *)data, "ccode=XV\r", data_len);
+   if (!ccode)
+   return;
+
+   ccode[6] = 'X';
+   ccode[7] = '2';
+   ccode[8] = '\r';
+}
+
 static u8 *brcmf_fw_nvram_from_efi(size_t *data_len_ret)
 {
const u16 name[] = { 'n', 'v', 'r', 'a', 'm', 0 };
@@ -476,6 +499,7 @@ static u8 *brcmf_fw_nvram_from_efi(size_t *data_len_ret)
if (err)
goto fail;
 
+   brcmf_fw_fix_efi_nvram_ccode(data, data_len);
brcmf_info("Using nvram EFI variable\n");
 
kfree(nvram_efivar);
-- 
2.19.0



[PATCH v4 1/2] brcmfmac: Add support for getting nvram contents from EFI variables

2018-10-11 Thread Hans de Goede
Various X86 laptops with a SDIO attached brcmfmac wifi chip, store the
nvram contents in a special EFI variable. This commit adds support for
getting nvram directly from this EFI variable, without the user needing
to manually copy it.

This makes Wifi / Bluetooth work out of the box on these devices instead of
requiring manual setup.

This has been tested on the following models: Acer Iconia Tab8 w1-810,
Acer One 10, Asus T100CHI, Asus T100HA, Asus T100TA, Asus T200TA and a
Lenovo Mixx 2 8.

Tested-by: Hans de Goede 
Signed-off-by: Hans de Goede 
---
Changes in v4:
-Drop unused path argument from brcmf_fw_nvram_from_efi(), this makes its
 prototype the same again as the empty implementation which gets used when
 CONFIG_EFI is not defined, fixing compilation without CONFIG_EFI

Changes in v3:
-Drop ccode fixup code (to be re-added in a separate commit), so that we
 can get the main EFI nvram support merged while we figure out the ccode
 handling

Changes in v2:
-Stop testing for asus in the dmi sys_vendor string at least the Toshiba
 Encore uses the nvram efivar variable too
-Use a table mapping the firmare name to the correct ccode value (XV / X2) to
 use for the worldwide regulatory domain for that firmware, assuming the
 firmware from linux-firmware is used. This fixes the T200TA and T100HA not
 seeing 5GHz networks
-Not only fixup ccode=ALL, but also ccode=XV, this is necessary since the
 T100HA nvram efivar containts ccode=XV, but the firmware from Linux firmware
 needs ccode=X2 for proper operation
---
 .../broadcom/brcm80211/brcmfmac/firmware.c| 63 +--
 1 file changed, 57 insertions(+), 6 deletions(-)

diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c 
b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c
index b38c4b40b235..965ae5c24c2d 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c
@@ -14,6 +14,7 @@
  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
+#include 
 #include 
 #include 
 #include 
@@ -445,6 +446,51 @@ struct brcmf_fw {
 
 static void brcmf_fw_request_done(const struct firmware *fw, void *ctx);
 
+#ifdef CONFIG_EFI
+static u8 *brcmf_fw_nvram_from_efi(size_t *data_len_ret)
+{
+   const u16 name[] = { 'n', 'v', 'r', 'a', 'm', 0 };
+   struct efivar_entry *nvram_efivar;
+   unsigned long data_len = 0;
+   u8 *data = NULL;
+   int err;
+
+   nvram_efivar = kzalloc(sizeof(*nvram_efivar), GFP_KERNEL);
+   if (!nvram_efivar)
+   return NULL;
+
+   memcpy(_efivar->var.VariableName, name, sizeof(name));
+   nvram_efivar->var.VendorGuid = EFI_GUID(0x74b00bd9, 0x805a, 0x4d61,
+   0xb5, 0x1f, 0x43, 0x26,
+   0x81, 0x23, 0xd1, 0x13);
+
+   err = efivar_entry_size(nvram_efivar, _len);
+   if (err)
+   goto fail;
+
+   data = kmalloc(data_len, GFP_KERNEL);
+   if (!data)
+   goto fail;
+
+   err = efivar_entry_get(nvram_efivar, NULL, _len, data);
+   if (err)
+   goto fail;
+
+   brcmf_info("Using nvram EFI variable\n");
+
+   kfree(nvram_efivar);
+   *data_len_ret = data_len;
+   return data;
+
+fail:
+   kfree(data);
+   kfree(nvram_efivar);
+   return NULL;
+}
+#else
+static u8 *brcmf_fw_nvram_from_efi(size_t *data_len) { return NULL; }
+#endif
+
 static void brcmf_fw_free_request(struct brcmf_fw_request *req)
 {
struct brcmf_fw_item *item;
@@ -463,11 +509,12 @@ static int brcmf_fw_request_nvram_done(const struct 
firmware *fw, void *ctx)
 {
struct brcmf_fw *fwctx = ctx;
struct brcmf_fw_item *cur;
+   bool free_bcm47xx_nvram = false;
+   bool kfree_nvram = false;
u32 nvram_length = 0;
void *nvram = NULL;
u8 *data = NULL;
size_t data_len;
-   bool raw_nvram;
 
brcmf_dbg(TRACE, "enter: dev=%s\n", dev_name(fwctx->dev));
 
@@ -476,12 +523,13 @@ static int brcmf_fw_request_nvram_done(const struct 
firmware *fw, void *ctx)
if (fw && fw->data) {
data = (u8 *)fw->data;
data_len = fw->size;
-   raw_nvram = false;
} else {
-   data = bcm47xx_nvram_get_contents(_len);
-   if (!data && !(cur->flags & BRCMF_FW_REQF_OPTIONAL))
+   if ((data = bcm47xx_nvram_get_contents(_len)))
+   free_bcm47xx_nvram = true;
+   else if ((data = brcmf_fw_nvram_from_efi(_len)))
+   kfree_nvram = true;
+   else if (!(cur->flags & BRCMF_FW_REQF_OPTIONAL))
goto fail;
-   raw_nvram = true;
}
 
if (data)
@@ -489,8 +537,11 @@ static int brcmf_fw_request_nvram_done(const struct 
firmware *fw, void *ctx)
 fwctx->req->domain_nr,
 

Re: [PATCH][next] ath10k: fix out of bound read on array ath10k_rates

2018-10-11 Thread Kalle Valo
Colin King  wrote:

> From: Colin Ian King 
> 
> An out-of-bounds read on array ath10k_rates is occurring because
> the maximum number of elements is currently based on the size of
> the array and not the number of elements in the array. Fix this
> by using ARRAY_SIZE instead of sizeof.
> 
> Detected by CoverityScan, CID#1473918 ("Out-of-bounds read")
> 
> Fixes: f279294e9ee2 ("ath10k: add support for configuring management packet 
> rate")
> Signed-off-by: Colin Ian King 

This is already fixed in ath-next.

error: patch failed: drivers/net/wireless/ath/ath10k/mac.c:164
error: drivers/net/wireless/ath/ath10k/mac.c: patch does not apply
stg import: Diff does not apply cleanly

Patch set to Rejected.

-- 
https://patchwork.kernel.org/patch/10628815/

https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches



[RFC 01/12] mt76: move mt76x02_phy_set_bw in mt76x02-lib module

2018-10-11 Thread Lorenzo Bianconi
Move mt76x02_phy_set_bw routine in mt76x02_phy.c since
it is shared between mt76x0 and mt76x2 drivers and remove
duplicated code

Signed-off-by: Lorenzo Bianconi 
---
 .../net/wireless/mediatek/mt76/mt76x0/phy.c   | 29 +--
 .../net/wireless/mediatek/mt76/mt76x02_phy.c  | 26 +
 .../net/wireless/mediatek/mt76/mt76x02_phy.h  |  1 +
 .../wireless/mediatek/mt76/mt76x2/mt76x2.h|  1 -
 .../wireless/mediatek/mt76/mt76x2/pci_phy.c   |  2 +-
 .../net/wireless/mediatek/mt76/mt76x2/phy.c   | 26 -
 .../wireless/mediatek/mt76/mt76x2/usb_phy.c   |  2 +-
 7 files changed, 30 insertions(+), 57 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/phy.c 
b/drivers/net/wireless/mediatek/mt76/mt76x0/phy.c
index 7c30ba47c7f4..3bc6d7b0914a 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x0/phy.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x0/phy.c
@@ -214,33 +214,6 @@ int mt76x0_wait_bbp_ready(struct mt76x02_dev *dev)
return 0;
 }
 
-static void
-mt76x0_bbp_set_ctrlch(struct mt76x02_dev *dev, enum nl80211_chan_width width,
- u8 ctrl)
-{
-   int core_val, agc_val;
-
-   switch (width) {
-   case NL80211_CHAN_WIDTH_80:
-   core_val = 3;
-   agc_val = 7;
-   break;
-   case NL80211_CHAN_WIDTH_40:
-   core_val = 2;
-   agc_val = 3;
-   break;
-   default:
-   core_val = 0;
-   agc_val = 1;
-   break;
-   }
-
-   mt76_rmw_field(dev, MT_BBP(CORE, 1), MT_BBP_CORE_R1_BW, core_val);
-   mt76_rmw_field(dev, MT_BBP(AGC, 0), MT_BBP_AGC_R0_BW, agc_val);
-   mt76_rmw_field(dev, MT_BBP(AGC, 0), MT_BBP_AGC_R0_CTRL_CHAN, ctrl);
-   mt76_rmw_field(dev, MT_BBP(TXBE, 0), MT_BBP_TXBE_R0_CTRL_CHAN, ctrl);
-}
-
 static void mt76x0_vco_cal(struct mt76x02_dev *dev, u8 channel)
 {
u8 val;
@@ -681,7 +654,7 @@ int mt76x0_phy_set_channel(struct mt76x02_dev *dev,
}
 
mt76x0_bbp_set_bw(dev, chandef->width);
-   mt76x0_bbp_set_ctrlch(dev, chandef->width, ch_group_index);
+   mt76x02_phy_set_bw(dev, chandef->width, ch_group_index);
mt76x0_mac_set_ctrlch(dev, ch_group_index & 1);
mt76x0_ant_select(dev);
 
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_phy.c 
b/drivers/net/wireless/mediatek/mt76/mt76x02_phy.c
index c398471b6376..3de7170db111 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_phy.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_phy.c
@@ -178,3 +178,29 @@ int mt76x02_phy_get_min_avg_rssi(struct mt76x02_dev *dev)
return min_rssi;
 }
 EXPORT_SYMBOL_GPL(mt76x02_phy_get_min_avg_rssi);
+
+void mt76x02_phy_set_bw(struct mt76x02_dev *dev, int width, u8 ctrl)
+{
+   int core_val, agc_val;
+
+   switch (width) {
+   case NL80211_CHAN_WIDTH_80:
+   core_val = 3;
+   agc_val = 7;
+   break;
+   case NL80211_CHAN_WIDTH_40:
+   core_val = 2;
+   agc_val = 3;
+   break;
+   default:
+   core_val = 0;
+   agc_val = 1;
+   break;
+   }
+
+   mt76_rmw_field(dev, MT_BBP(CORE, 1), MT_BBP_CORE_R1_BW, core_val);
+   mt76_rmw_field(dev, MT_BBP(AGC, 0), MT_BBP_AGC_R0_BW, agc_val);
+   mt76_rmw_field(dev, MT_BBP(AGC, 0), MT_BBP_AGC_R0_CTRL_CHAN, ctrl);
+   mt76_rmw_field(dev, MT_BBP(TXBE, 0), MT_BBP_TXBE_R0_CTRL_CHAN, ctrl);
+}
+EXPORT_SYMBOL_GPL(mt76x02_phy_set_bw);
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_phy.h 
b/drivers/net/wireless/mediatek/mt76/mt76x02_phy.h
index c370b4cc68ee..e0ca44ed5081 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_phy.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_phy.h
@@ -26,5 +26,6 @@ int mt76x02_get_max_rate_power(struct mt76_rate_power *r);
 void mt76x02_phy_set_rxpath(struct mt76x02_dev *dev);
 void mt76x02_phy_set_txdac(struct mt76x02_dev *dev);
 int mt76x02_phy_get_min_avg_rssi(struct mt76x02_dev *dev);
+void mt76x02_phy_set_bw(struct mt76x02_dev *dev, int width, u8 ctrl);
 
 #endif /* __MT76x02_PHY_H */
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/mt76x2.h 
b/drivers/net/wireless/mediatek/mt76/mt76x2/mt76x2.h
index cbec8c6f1b2d..8b18acafedb2 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x2/mt76x2.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76x2/mt76x2.h
@@ -100,7 +100,6 @@ void mt76x2_phy_set_txpower_regs(struct mt76x02_dev *dev,
 enum nl80211_band band);
 void mt76x2_configure_tx_delay(struct mt76x02_dev *dev,
   enum nl80211_band band, u8 bw);
-void mt76x2_phy_set_bw(struct mt76x02_dev *dev, int width, u8 ctrl);
 void mt76x2_phy_set_band(struct mt76x02_dev *dev, int band, bool 
primary_upper);
 void mt76x2_apply_gain_adj(struct mt76x02_dev *dev);
 
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/pci_phy.c 
b/drivers/net/wireless/mediatek/mt76/mt76x2/pci_phy.c

[RFC 02/12] mt76: move mt76x02_phy_set_band in mt76x02-lib module

2018-10-11 Thread Lorenzo Bianconi
Move mt76x02_phy_set_band routine in mt76x02_phy.c since
it is shared between mt76x0 and mt76x2 drivers and remove
duplicated code

Signed-off-by: Lorenzo Bianconi 
---
 .../net/wireless/mediatek/mt76/mt76x0/phy.c   | 16 ++--
 .../net/wireless/mediatek/mt76/mt76x02_phy.c  | 19 +++
 .../net/wireless/mediatek/mt76/mt76x02_phy.h  |  2 ++
 .../wireless/mediatek/mt76/mt76x2/mt76x2.h|  1 -
 .../wireless/mediatek/mt76/mt76x2/pci_phy.c   |  2 +-
 .../net/wireless/mediatek/mt76/mt76x2/phy.c   | 18 --
 .../wireless/mediatek/mt76/mt76x2/usb_phy.c   |  2 +-
 7 files changed, 25 insertions(+), 35 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/phy.c 
b/drivers/net/wireless/mediatek/mt76/mt76x0/phy.c
index 3bc6d7b0914a..638a2bca5cff 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x0/phy.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x0/phy.c
@@ -270,13 +270,6 @@ static void mt76x0_vco_cal(struct mt76x02_dev *dev, u8 
channel)
msleep(2);
 }
 
-static void
-mt76x0_mac_set_ctrlch(struct mt76x02_dev *dev, bool primary_upper)
-{
-   mt76_rmw_field(dev, MT_TX_BAND_CFG, MT_TX_BAND_CFG_UPPER_40M,
-  primary_upper);
-}
-
 static void
 mt76x0_phy_set_band(struct mt76x02_dev *dev, enum nl80211_band band)
 {
@@ -287,9 +280,6 @@ mt76x0_phy_set_band(struct mt76x02_dev *dev, enum 
nl80211_band band)
rf_wr(dev, MT_RF(5, 0), 0x45);
rf_wr(dev, MT_RF(6, 0), 0x44);
 
-   mt76_set(dev, MT_TX_BAND_CFG, MT_TX_BAND_CFG_2G);
-   mt76_clear(dev, MT_TX_BAND_CFG, MT_TX_BAND_CFG_5G);
-
mt76_wr(dev, MT_TX_ALC_VGA3, 0x00050007);
mt76_wr(dev, MT_TX0_RF_GAIN_CORR, 0x003E0002);
break;
@@ -299,9 +289,6 @@ mt76x0_phy_set_band(struct mt76x02_dev *dev, enum 
nl80211_band band)
rf_wr(dev, MT_RF(5, 0), 0x44);
rf_wr(dev, MT_RF(6, 0), 0x45);
 
-   mt76_clear(dev, MT_TX_BAND_CFG, MT_TX_BAND_CFG_2G);
-   mt76_set(dev, MT_TX_BAND_CFG, MT_TX_BAND_CFG_5G);
-
mt76_wr(dev, MT_TX_ALC_VGA3, 0x0005);
mt76_wr(dev, MT_TX0_RF_GAIN_CORR, 0x01010102);
break;
@@ -655,7 +642,8 @@ int mt76x0_phy_set_channel(struct mt76x02_dev *dev,
 
mt76x0_bbp_set_bw(dev, chandef->width);
mt76x02_phy_set_bw(dev, chandef->width, ch_group_index);
-   mt76x0_mac_set_ctrlch(dev, ch_group_index & 1);
+   mt76x02_phy_set_band(dev, chandef->chan->band,
+ch_group_index & 1);
mt76x0_ant_select(dev);
 
mt76_rmw(dev, MT_EXT_CCA_CFG,
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_phy.c 
b/drivers/net/wireless/mediatek/mt76/mt76x02_phy.c
index 3de7170db111..b0c78ab97ad7 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_phy.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_phy.c
@@ -204,3 +204,22 @@ void mt76x02_phy_set_bw(struct mt76x02_dev *dev, int 
width, u8 ctrl)
mt76_rmw_field(dev, MT_BBP(TXBE, 0), MT_BBP_TXBE_R0_CTRL_CHAN, ctrl);
 }
 EXPORT_SYMBOL_GPL(mt76x02_phy_set_bw);
+
+void mt76x02_phy_set_band(struct mt76x02_dev *dev, int band,
+ bool primary_upper)
+{
+   switch (band) {
+   case NL80211_BAND_2GHZ:
+   mt76_set(dev, MT_TX_BAND_CFG, MT_TX_BAND_CFG_2G);
+   mt76_clear(dev, MT_TX_BAND_CFG, MT_TX_BAND_CFG_5G);
+   break;
+   case NL80211_BAND_5GHZ:
+   mt76_clear(dev, MT_TX_BAND_CFG, MT_TX_BAND_CFG_2G);
+   mt76_set(dev, MT_TX_BAND_CFG, MT_TX_BAND_CFG_5G);
+   break;
+   }
+
+   mt76_rmw_field(dev, MT_TX_BAND_CFG, MT_TX_BAND_CFG_UPPER_40M,
+  primary_upper);
+}
+EXPORT_SYMBOL_GPL(mt76x02_phy_set_band);
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_phy.h 
b/drivers/net/wireless/mediatek/mt76/mt76x02_phy.h
index e0ca44ed5081..1a20c1852dbf 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_phy.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_phy.h
@@ -27,5 +27,7 @@ void mt76x02_phy_set_rxpath(struct mt76x02_dev *dev);
 void mt76x02_phy_set_txdac(struct mt76x02_dev *dev);
 int mt76x02_phy_get_min_avg_rssi(struct mt76x02_dev *dev);
 void mt76x02_phy_set_bw(struct mt76x02_dev *dev, int width, u8 ctrl);
+void mt76x02_phy_set_band(struct mt76x02_dev *dev, int band,
+ bool primary_upper);
 
 #endif /* __MT76x02_PHY_H */
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/mt76x2.h 
b/drivers/net/wireless/mediatek/mt76/mt76x2/mt76x2.h
index 8b18acafedb2..ab93125f46de 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x2/mt76x2.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76x2/mt76x2.h
@@ -100,7 +100,6 @@ void mt76x2_phy_set_txpower_regs(struct mt76x02_dev *dev,
 enum nl80211_band band);
 void mt76x2_configure_tx_delay(struct mt76x02_dev *dev,
   enum nl80211_band band, 

[RFC 09/12] mt76: move mt76x02_phy_adjust_vga_gain in mt76/mt76x02_phy.c

2018-10-11 Thread Lorenzo Bianconi
Move mt76x02_phy_adjust_vga_gain routine in mt76x02-lib module
in order to be reused by mt76x0 driver for vga calibration

Signed-off-by: Lorenzo Bianconi 
---
 .../net/wireless/mediatek/mt76/mt76x02_phy.c  | 21 ++
 .../net/wireless/mediatek/mt76/mt76x02_phy.h  |  1 +
 .../wireless/mediatek/mt76/mt76x2/pci_phy.c   | 22 ++-
 3 files changed, 24 insertions(+), 20 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_phy.c 
b/drivers/net/wireless/mediatek/mt76/mt76x02_phy.c
index b0c78ab97ad7..97310da37d77 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_phy.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_phy.c
@@ -223,3 +223,24 @@ void mt76x02_phy_set_band(struct mt76x02_dev *dev, int 
band,
   primary_upper);
 }
 EXPORT_SYMBOL_GPL(mt76x02_phy_set_band);
+
+bool mt76x02_phy_adjust_vga_gain(struct mt76x02_dev *dev)
+{
+   u8 limit = dev->cal.low_gain > 0 ? 16 : 4;
+   bool ret = false;
+   u32 false_cca;
+
+   false_cca = FIELD_GET(MT_RX_STAT_1_CCA_ERRORS, mt76_rr(dev, 
MT_RX_STAT_1));
+   dev->cal.false_cca = false_cca;
+   if (false_cca > 800 && dev->cal.agc_gain_adjust < limit) {
+   dev->cal.agc_gain_adjust += 2;
+   ret = true;
+   } else if ((false_cca < 10 && dev->cal.agc_gain_adjust > 0) ||
+  (dev->cal.agc_gain_adjust >= limit && false_cca < 500)) {
+   dev->cal.agc_gain_adjust -= 2;
+   ret = true;
+   }
+
+   return ret;
+}
+EXPORT_SYMBOL_GPL(mt76x02_phy_adjust_vga_gain);
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_phy.h 
b/drivers/net/wireless/mediatek/mt76/mt76x02_phy.h
index 3a5ba5d209ba..8e3a0f93ca80 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_phy.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_phy.h
@@ -55,5 +55,6 @@ int mt76x02_phy_get_min_avg_rssi(struct mt76x02_dev *dev);
 void mt76x02_phy_set_bw(struct mt76x02_dev *dev, int width, u8 ctrl);
 void mt76x02_phy_set_band(struct mt76x02_dev *dev, int band,
  bool primary_upper);
+bool mt76x02_phy_adjust_vga_gain(struct mt76x02_dev *dev);
 
 #endif /* __MT76x02_PHY_H */
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/pci_phy.c 
b/drivers/net/wireless/mediatek/mt76/mt76x2/pci_phy.c
index 86b87d896b46..818d2f3e8ac9 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x2/pci_phy.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x2/pci_phy.c
@@ -156,25 +156,6 @@ mt76x2_phy_set_gain_val(struct mt76x02_dev *dev)
mt76x2_dfs_adjust_agc(dev);
 }
 
-static void
-mt76x2_phy_adjust_vga_gain(struct mt76x02_dev *dev)
-{
-   u32 false_cca;
-   u8 limit = dev->cal.low_gain > 0 ? 16 : 4;
-
-   false_cca = FIELD_GET(MT_RX_STAT_1_CCA_ERRORS, mt76_rr(dev, 
MT_RX_STAT_1));
-   dev->cal.false_cca = false_cca;
-   if (false_cca > 800 && dev->cal.agc_gain_adjust < limit)
-   dev->cal.agc_gain_adjust += 2;
-   else if ((false_cca < 10 && dev->cal.agc_gain_adjust > 0) ||
-(dev->cal.agc_gain_adjust >= limit && false_cca < 500))
-   dev->cal.agc_gain_adjust -= 2;
-   else
-   return;
-
-   mt76x2_phy_set_gain_val(dev);
-}
-
 static void
 mt76x2_phy_update_channel_gain(struct mt76x02_dev *dev)
 {
@@ -193,7 +174,8 @@ mt76x2_phy_update_channel_gain(struct mt76x02_dev *dev)
dev->cal.low_gain = low_gain;
 
if (!gain_change) {
-   mt76x2_phy_adjust_vga_gain(dev);
+   if (mt76x02_phy_adjust_vga_gain(dev))
+   mt76x2_phy_set_gain_val(dev);
return;
}
 
-- 
2.17.2



[RFC 04/12] mt76x0: pci: introduce mt76x0_phy_calirate routine

2018-10-11 Thread Lorenzo Bianconi
Add mt76x0_phy_calirate routine in order to perform
phy calibration for mt76x0e devices.

Signed-off-by: Lorenzo Bianconi 
---
 .../net/wireless/mediatek/mt76/mt76x0/mcu.h   |  3 ++
 .../wireless/mediatek/mt76/mt76x0/mt76x0.h|  1 +
 .../net/wireless/mediatek/mt76/mt76x0/pci.c   |  1 +
 .../net/wireless/mediatek/mt76/mt76x0/phy.c   | 53 +--
 4 files changed, 55 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/mcu.h 
b/drivers/net/wireless/mediatek/mt76/mt76x0/mcu.h
index b66e70f6cd89..3b34e1d2769f 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x0/mcu.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76x0/mcu.h
@@ -39,6 +39,9 @@ enum mcu_calibrate {
MCU_CAL_TXDCOC,
MCU_CAL_RX_GROUP_DELAY,
MCU_CAL_TX_GROUP_DELAY,
+   MCU_CAL_VCO,
+   MCU_CAL_NO_SIGNAL = 0xfe,
+   MCU_CAL_FULL = 0xff,
 };
 
 int mt76x0e_mcu_init(struct mt76x02_dev *dev);
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h 
b/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h
index 1bff2be45a13..6717d83e0ff6 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h
@@ -72,6 +72,7 @@ int mt76x0_phy_set_channel(struct mt76x02_dev *dev,
struct cfg80211_chan_def *chandef);
 void mt76x0_phy_recalibrate_after_assoc(struct mt76x02_dev *dev);
 void mt76x0_phy_set_txpower(struct mt76x02_dev *dev);
+void mt76x0_phy_calibrate(struct mt76x02_dev *dev, bool power_on);
 
 /* MAC */
 void mt76x0_mac_work(struct work_struct *work);
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/pci.c 
b/drivers/net/wireless/mediatek/mt76/mt76x0/pci.c
index 10845f37af37..f31c63444c82 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x0/pci.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x0/pci.c
@@ -28,6 +28,7 @@ static int mt76x0e_start(struct ieee80211_hw *hw)
mutex_lock(>mt76.mutex);
 
mt76x02_mac_start(dev);
+   mt76x0_phy_calibrate(dev, true);
ieee80211_queue_delayed_work(dev->mt76.hw, >mac_work,
 MT_CALIBRATE_INTERVAL);
ieee80211_queue_delayed_work(dev->mt76.hw, >cal_work,
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/phy.c 
b/drivers/net/wireless/mediatek/mt76/mt76x0/phy.c
index 9a8e1fcee26b..96be496e5ee3 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x0/phy.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x0/phy.c
@@ -581,6 +581,48 @@ void mt76x0_phy_set_txpower(struct mt76x02_dev *dev)
mt76x02_phy_set_txpower(dev, info[0], info[1]);
 }
 
+void mt76x0_phy_calibrate(struct mt76x02_dev *dev, bool power_on)
+{
+   struct ieee80211_channel *chan = dev->mt76.chandef.chan;
+   u32 val, tx_alc, reg_val;
+
+   if (power_on) {
+   mt76x02_mcu_calibrate(dev, MCU_CAL_R, 0, false);
+   mt76x02_mcu_calibrate(dev, MCU_CAL_VCO, chan->hw_value,
+ false);
+   udelay(10);
+   /* XXX: tssi */
+   }
+
+   tx_alc = mt76_rr(dev, MT_TX_ALC_CFG_0);
+   mt76_wr(dev, MT_TX_ALC_CFG_0, 0);
+   usleep_range(500, 700);
+
+   reg_val = mt76_rr(dev, MT_BBP(IBI, 9));
+   mt76_wr(dev, MT_BBP(IBI, 9), 0xff7e);
+
+   if (chan->band == NL80211_BAND_5GHZ) {
+   if (chan->hw_value < 100)
+   val = 0x701;
+   else if (chan->hw_value < 140)
+   val = 0x801;
+   else
+   val = 0x901;
+   } else {
+   val = 0x600;
+   }
+
+   mt76x02_mcu_calibrate(dev, MCU_CAL_FULL, val, false);
+   msleep(350);
+   mt76x02_mcu_calibrate(dev, MCU_CAL_LC, 1, false);
+   usleep_range(15000, 2);
+
+   mt76_wr(dev, MT_BBP(IBI, 9), reg_val);
+   mt76_wr(dev, MT_TX_ALC_CFG_0, tx_alc);
+   mt76x02_mcu_calibrate(dev, MCU_CAL_RXDCOC, 1, false);
+}
+EXPORT_SYMBOL_GPL(mt76x0_phy_calibrate);
+
 int mt76x0_phy_set_channel(struct mt76x02_dev *dev,
   struct cfg80211_chan_def *chandef)
 {
@@ -671,9 +713,14 @@ int mt76x0_phy_set_channel(struct mt76x02_dev *dev,
/* Vendor driver don't do it */
/* mt76x0_phy_set_tx_power(dev, channel, rf_bw_band); */
 
-   mt76x0_vco_cal(dev, channel);
-   if (scan)
-   mt76x02_mcu_calibrate(dev, MCU_CAL_RXDCOC, 1, false);
+   if (mt76_is_usb(dev)) {
+   mt76x0_vco_cal(dev, channel);
+   if (scan)
+   mt76x02_mcu_calibrate(dev, MCU_CAL_RXDCOC, 1,
+ false);
+   } else {
+   mt76x0_phy_calibrate(dev, false);
+   }
 
mt76x0_phy_set_txpower(dev);
 
-- 
2.17.2



[RFC 06/12] mt76x0: eeprom: introduce mt76x0_tssi_enabled routine

2018-10-11 Thread Lorenzo Bianconi
Add mt76x0_tssi_enabled in order to check if tssi compensation
is enabled since mt76x0 condition differs from mt76x2 one.
Moreover move back mt76x02_temp_tx_alc_enabled and mt76x02_tssi_enabled
routines in mt76x2/eeprom.h since they are mt76x2 specific

Signed-off-by: Lorenzo Bianconi 
---
 .../wireless/mediatek/mt76/mt76x0/eeprom.c|  2 +-
 .../wireless/mediatek/mt76/mt76x0/eeprom.h|  6 ++
 .../wireless/mediatek/mt76/mt76x02_eeprom.h   | 21 ---
 .../wireless/mediatek/mt76/mt76x2/eeprom.c|  4 ++--
 .../wireless/mediatek/mt76/mt76x2/eeprom.h| 21 +++
 .../wireless/mediatek/mt76/mt76x2/pci_phy.c   |  4 ++--
 .../wireless/mediatek/mt76/mt76x2/usb_phy.c   |  2 +-
 7 files changed, 33 insertions(+), 27 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/eeprom.c 
b/drivers/net/wireless/mediatek/mt76/mt76x0/eeprom.c
index 1defb072ccbf..ab4fd6e0f23a 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x0/eeprom.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x0/eeprom.c
@@ -135,7 +135,7 @@ static s8 mt76x0_get_delta(struct mt76x02_dev *dev)
struct cfg80211_chan_def *chandef = >mt76.chandef;
u8 val;
 
-   if (mt76x02_tssi_enabled(dev))
+   if (mt76x0_tssi_enabled(dev))
return 0;
 
if (chandef->width == NL80211_CHAN_WIDTH_80) {
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/eeprom.h 
b/drivers/net/wireless/mediatek/mt76/mt76x0/eeprom.h
index 40fd4e61769b..ee9ade9f3c8b 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x0/eeprom.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76x0/eeprom.h
@@ -37,4 +37,10 @@ static inline s8 s6_to_s8(u32 val)
return ret;
 }
 
+static inline bool mt76x0_tssi_enabled(struct mt76x02_dev *dev)
+{
+   return (mt76x02_eeprom_get(dev, MT_EE_NIC_CONF_1) &
+   MT_EE_NIC_CONF_1_TX_ALC_EN);
+}
+
 #endif
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_eeprom.h 
b/drivers/net/wireless/mediatek/mt76/mt76x02_eeprom.h
index 0fba43d569b5..b3ec74835d10 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_eeprom.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_eeprom.h
@@ -179,27 +179,6 @@ mt76x02_eeprom_get(struct mt76x02_dev *dev,
return get_unaligned_le16(dev->mt76.eeprom.data + field);
 }
 
-static inline bool
-mt76x02_temp_tx_alc_enabled(struct mt76x02_dev *dev)
-{
-   u16 val;
-
-   val = mt76x02_eeprom_get(dev, MT_EE_TX_POWER_EXT_PA_5G);
-   if (!(val & BIT(15)))
-   return false;
-
-   return mt76x02_eeprom_get(dev, MT_EE_NIC_CONF_1) &
-  MT_EE_NIC_CONF_1_TEMP_TX_ALC;
-}
-
-static inline bool
-mt76x02_tssi_enabled(struct mt76x02_dev *dev)
-{
-   return !mt76x02_temp_tx_alc_enabled(dev) &&
-  (mt76x02_eeprom_get(dev, MT_EE_NIC_CONF_1) &
-   MT_EE_NIC_CONF_1_TX_ALC_EN);
-}
-
 bool mt76x02_ext_pa_enabled(struct mt76x02_dev *dev, enum nl80211_band band);
 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/mt76x2/eeprom.c 
b/drivers/net/wireless/mediatek/mt76/mt76x2/eeprom.c
index 5fb9532f3eed..f39b622d03f4 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x2/eeprom.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x2/eeprom.c
@@ -464,7 +464,7 @@ void mt76x2_get_power_info(struct mt76x02_dev *dev,
 MT_EE_TX_POWER_1_START_2G);
}
 
-   if (mt76x02_tssi_enabled(dev) ||
+   if (mt76x2_tssi_enabled(dev) ||
!mt76x02_field_valid(t->target_power))
t->target_power = t->chain[0].target_power;
 
@@ -481,7 +481,7 @@ int mt76x2_get_temp_comp(struct mt76x02_dev *dev, struct 
mt76x2_temp_comp *t)
 
memset(t, 0, sizeof(*t));
 
-   if (!mt76x02_temp_tx_alc_enabled(dev))
+   if (!mt76x2_temp_tx_alc_enabled(dev))
return -EINVAL;
 
if (!mt76x02_ext_pa_enabled(dev, band))
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/eeprom.h 
b/drivers/net/wireless/mediatek/mt76/mt76x2/eeprom.h
index 13bceb6aa5e4..9e735524d367 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x2/eeprom.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76x2/eeprom.h
@@ -70,4 +70,25 @@ mt76x2_has_ext_lna(struct mt76x02_dev *dev)
return val & MT_EE_NIC_CONF_1_LNA_EXT_5G;
 }
 
+static inline bool
+mt76x2_temp_tx_alc_enabled(struct mt76x02_dev *dev)
+{
+   u16 val;
+
+   val = mt76x02_eeprom_get(dev, MT_EE_TX_POWER_EXT_PA_5G);
+   if (!(val & BIT(15)))
+   return false;
+
+   return mt76x02_eeprom_get(dev, MT_EE_NIC_CONF_1) &
+  MT_EE_NIC_CONF_1_TEMP_TX_ALC;
+}
+
+static inline bool
+mt76x2_tssi_enabled(struct mt76x02_dev *dev)
+{
+   return !mt76x2_temp_tx_alc_enabled(dev) &&
+  (mt76x02_eeprom_get(dev, MT_EE_NIC_CONF_1) &
+   MT_EE_NIC_CONF_1_TX_ALC_EN);
+}
+
 #endif
diff --git 

[RFC 03/12] mt76x0: pci: rename mt76x0_phy_calibrate

2018-10-11 Thread Lorenzo Bianconi
Rename mt76x0_phy_calibrate routine in mt76x0_phy_calibration_work
in order to not collide with calibration routine for mt76x0e

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

diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/phy.c 
b/drivers/net/wireless/mediatek/mt76/mt76x0/phy.c
index 638a2bca5cff..9a8e1fcee26b 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x0/phy.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x0/phy.c
@@ -787,7 +787,7 @@ static void mt76x0_dynamic_vga_tuning(struct mt76x02_dev 
*dev)
mt76_wr(dev, MT_BBP(AGC,8), val);
 }
 
-static void mt76x0_phy_calibrate(struct work_struct *work)
+static void mt76x0_phy_calibration_work(struct work_struct *work)
 {
struct mt76x02_dev *dev = container_of(work, struct mt76x02_dev,
   cal_work.work);
@@ -854,7 +854,7 @@ static void mt76x0_rf_init(struct mt76x02_dev *dev)
 
 void mt76x0_phy_init(struct mt76x02_dev *dev)
 {
-   INIT_DELAYED_WORK(>cal_work, mt76x0_phy_calibrate);
+   INIT_DELAYED_WORK(>cal_work, mt76x0_phy_calibration_work);
 
mt76x0_rf_init(dev);
mt76x02_phy_set_rxpath(dev);
-- 
2.17.2



[RFC 08/12] mt76: move rssi_gain_thresh routines in mt76x02-lib module

2018-10-11 Thread Lorenzo Bianconi
Move mt76x2_get_rssi_gain_thresh and mt76x2_get_low_rssi_gain_thresh
routines in mt76x02-lib module in order to be reused by mt76x0 driver
for dynamic vga calibration

Signed-off-by: Lorenzo Bianconi 
---
 .../net/wireless/mediatek/mt76/mt76x02_phy.h  | 26 
 .../wireless/mediatek/mt76/mt76x2/pci_phy.c   | 30 ++-
 2 files changed, 28 insertions(+), 28 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_phy.h 
b/drivers/net/wireless/mediatek/mt76/mt76x02_phy.h
index 1a20c1852dbf..3a5ba5d209ba 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_phy.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_phy.h
@@ -19,6 +19,32 @@
 
 #include "mt76x02_regs.h"
 
+static inline int
+mt76x02_get_rssi_gain_thresh(struct mt76x02_dev *dev)
+{
+   switch (dev->mt76.chandef.width) {
+   case NL80211_CHAN_WIDTH_80:
+   return -62;
+   case NL80211_CHAN_WIDTH_40:
+   return -65;
+   default:
+   return -68;
+   }
+}
+
+static inline int
+mt76x02_get_low_rssi_gain_thresh(struct mt76x02_dev *dev)
+{
+   switch (dev->mt76.chandef.width) {
+   case NL80211_CHAN_WIDTH_80:
+   return -76;
+   case NL80211_CHAN_WIDTH_40:
+   return -79;
+   default:
+   return -82;
+   }
+}
+
 void mt76x02_add_rate_power_offset(struct mt76_rate_power *r, int offset);
 void mt76x02_phy_set_txpower(struct mt76x02_dev *dev, int txp_0, int txp_2);
 void mt76x02_limit_rate_power(struct mt76_rate_power *r, int limit);
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/pci_phy.c 
b/drivers/net/wireless/mediatek/mt76/mt76x2/pci_phy.c
index 55708b8e6e10..86b87d896b46 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x2/pci_phy.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x2/pci_phy.c
@@ -131,32 +131,6 @@ mt76x2_get_agc_gain(struct mt76x02_dev *dev, u8 *dest)
dest[1] = mt76_get_field(dev, MT_BBP(AGC, 9), MT_BBP_AGC_GAIN);
 }
 
-static int
-mt76x2_get_rssi_gain_thresh(struct mt76x02_dev *dev)
-{
-   switch (dev->mt76.chandef.width) {
-   case NL80211_CHAN_WIDTH_80:
-   return -62;
-   case NL80211_CHAN_WIDTH_40:
-   return -65;
-   default:
-   return -68;
-   }
-}
-
-static int
-mt76x2_get_low_rssi_gain_thresh(struct mt76x02_dev *dev)
-{
-   switch (dev->mt76.chandef.width) {
-   case NL80211_CHAN_WIDTH_80:
-   return -76;
-   case NL80211_CHAN_WIDTH_40:
-   return -79;
-   default:
-   return -82;
-   }
-}
-
 static void
 mt76x2_phy_set_gain_val(struct mt76x02_dev *dev)
 {
@@ -212,8 +186,8 @@ mt76x2_phy_update_channel_gain(struct mt76x02_dev *dev)
 
dev->cal.avg_rssi_all = mt76x02_phy_get_min_avg_rssi(dev);
 
-   low_gain = (dev->cal.avg_rssi_all > mt76x2_get_rssi_gain_thresh(dev)) +
-  (dev->cal.avg_rssi_all > 
mt76x2_get_low_rssi_gain_thresh(dev));
+   low_gain = (dev->cal.avg_rssi_all > mt76x02_get_rssi_gain_thresh(dev)) +
+  (dev->cal.avg_rssi_all > 
mt76x02_get_low_rssi_gain_thresh(dev));
 
gain_change = (dev->cal.low_gain & 2) ^ (low_gain & 2);
dev->cal.low_gain = low_gain;
-- 
2.17.2



[RFC 05/12] mt76x0: phy: update set_channel for mt76x0e devices

2018-10-11 Thread Lorenzo Bianconi
Do not run mt76x0_vco_cal and mt76x0_bbp_set_bw routines and
configure MT_TX_SW_CFG0 register for pcie devices in
mt76x0_phy_set_channel function.

Signed-off-by: Lorenzo Bianconi 
---
 .../net/wireless/mediatek/mt76/mt76x0/phy.c| 18 +-
 1 file changed, 13 insertions(+), 5 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/phy.c 
b/drivers/net/wireless/mediatek/mt76/mt76x0/phy.c
index 96be496e5ee3..049e750457e6 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x0/phy.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x0/phy.c
@@ -682,7 +682,16 @@ int mt76x0_phy_set_channel(struct mt76x02_dev *dev,
break;
}
 
-   mt76x0_bbp_set_bw(dev, chandef->width);
+   if (mt76_is_usb(dev)) {
+   mt76x0_bbp_set_bw(dev, chandef->width);
+   } else {
+   if (chandef->width == NL80211_CHAN_WIDTH_80 ||
+   chandef->width == NL80211_CHAN_WIDTH_40)
+   val = 0x201;
+   else
+   val = 0x601;
+   mt76_wr(dev, MT_TX_SW_CFG0, val);
+   }
mt76x02_phy_set_bw(dev, chandef->width, ch_group_index);
mt76x02_phy_set_band(dev, chandef->chan->band,
 ch_group_index & 1);
@@ -698,7 +707,6 @@ int mt76x0_phy_set_channel(struct mt76x02_dev *dev,
 
mt76x0_phy_set_band(dev, chandef->chan->band);
mt76x0_phy_set_chan_rf_params(dev, channel, rf_bw_band);
-   mt76x0_read_rx_gain(dev);
 
/* set Japan Tx filter at channel 14 */
val = mt76_rr(dev, MT_BBP(CORE, 1));
@@ -708,17 +716,17 @@ int mt76x0_phy_set_channel(struct mt76x02_dev *dev,
val &= ~0x20;
mt76_wr(dev, MT_BBP(CORE, 1), val);
 
+   mt76x0_read_rx_gain(dev);
mt76x0_phy_set_chan_bbp_params(dev, rf_bw_band);
 
-   /* Vendor driver don't do it */
-   /* mt76x0_phy_set_tx_power(dev, channel, rf_bw_band); */
-
if (mt76_is_usb(dev)) {
mt76x0_vco_cal(dev, channel);
if (scan)
mt76x02_mcu_calibrate(dev, MCU_CAL_RXDCOC, 1,
  false);
} else {
+   /* enable vco */
+   rf_set(dev, MT_RF(0, 4), BIT(7));
mt76x0_phy_calibrate(dev, false);
}
 
-- 
2.17.2



[RFC 10/12] mt76: introduce mt76x02_init_agc_gain routine

2018-10-11 Thread Lorenzo Bianconi
Add mt76x02_init_agc_gain routine in mt76x02-lib moudule in
order to be reused by mt76x0 for vga initalization

Signed-off-by: Lorenzo Bianconi 
---
 drivers/net/wireless/mediatek/mt76/mt76x02_phy.c| 12 
 drivers/net/wireless/mediatek/mt76/mt76x02_phy.h|  1 +
 drivers/net/wireless/mediatek/mt76/mt76x2/pci_phy.c | 12 +---
 3 files changed, 14 insertions(+), 11 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_phy.c 
b/drivers/net/wireless/mediatek/mt76/mt76x02_phy.c
index 97310da37d77..0f1d7b5c9f68 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_phy.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_phy.c
@@ -244,3 +244,15 @@ bool mt76x02_phy_adjust_vga_gain(struct mt76x02_dev *dev)
return ret;
 }
 EXPORT_SYMBOL_GPL(mt76x02_phy_adjust_vga_gain);
+
+void mt76x02_init_agc_gain(struct mt76x02_dev *dev)
+{
+   dev->cal.agc_gain_init[0] = mt76_get_field(dev, MT_BBP(AGC, 8),
+  MT_BBP_AGC_GAIN);
+   dev->cal.agc_gain_init[1] = mt76_get_field(dev, MT_BBP(AGC, 9),
+  MT_BBP_AGC_GAIN);
+   memcpy(dev->cal.agc_gain_cur, dev->cal.agc_gain_init,
+  sizeof(dev->cal.agc_gain_cur));
+   dev->cal.low_gain = -1;
+}
+EXPORT_SYMBOL_GPL(mt76x02_init_agc_gain);
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_phy.h 
b/drivers/net/wireless/mediatek/mt76/mt76x02_phy.h
index 8e3a0f93ca80..2b316cf7c70c 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_phy.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_phy.h
@@ -56,5 +56,6 @@ void mt76x02_phy_set_bw(struct mt76x02_dev *dev, int width, 
u8 ctrl);
 void mt76x02_phy_set_band(struct mt76x02_dev *dev, int band,
  bool primary_upper);
 bool mt76x02_phy_adjust_vga_gain(struct mt76x02_dev *dev);
+void mt76x02_init_agc_gain(struct mt76x02_dev *dev);
 
 #endif /* __MT76x02_PHY_H */
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/pci_phy.c 
b/drivers/net/wireless/mediatek/mt76/mt76x2/pci_phy.c
index 818d2f3e8ac9..5bda44540225 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x2/pci_phy.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x2/pci_phy.c
@@ -124,13 +124,6 @@ void mt76x2_phy_set_antenna(struct mt76x02_dev *dev)
mt76_wr(dev, MT_BBP(AGC, 0), val);
 }
 
-static void
-mt76x2_get_agc_gain(struct mt76x02_dev *dev, u8 *dest)
-{
-   dest[0] = mt76_get_field(dev, MT_BBP(AGC, 8), MT_BBP_AGC_GAIN);
-   dest[1] = mt76_get_field(dev, MT_BBP(AGC, 9), MT_BBP_AGC_GAIN);
-}
-
 static void
 mt76x2_phy_set_gain_val(struct mt76x02_dev *dev)
 {
@@ -340,11 +333,8 @@ int mt76x2_phy_set_channel(struct mt76x02_dev *dev,
if (scan)
return 0;
 
-   dev->cal.low_gain = -1;
mt76x2_phy_channel_calibrate(dev, true);
-   mt76x2_get_agc_gain(dev, dev->cal.agc_gain_init);
-   memcpy(dev->cal.agc_gain_cur, dev->cal.agc_gain_init,
-  sizeof(dev->cal.agc_gain_cur));
+   mt76x02_init_agc_gain(dev);
 
/* init default values for temp compensation */
if (mt76x2_tssi_enabled(dev)) {
-- 
2.17.2



[RFC 00/12] add calibration logics for mt76x0e driver

2018-10-11 Thread Lorenzo Bianconi
Introduce vga, temperature and phy calibration routines for
mt76x0e driver. Move phy shared code in mt76x02-lib module.
Moreover do not run calibration during channel switch

Lorenzo Bianconi (12):
  mt76: move mt76x02_phy_set_bw in mt76x02-lib module
  mt76: move mt76x02_phy_set_band in mt76x02-lib module
  mt76x0: pci: rename mt76x0_phy_calibrate
  mt76x0: pci: introduce mt76x0_phy_calirate routine
  mt76x0: phy: update set_channel for mt76x0e devices
  mt76x0: eeprom: introduce mt76x0_tssi_enabled routine
  mt76x0: phy: add phy/vco temperature compensation
  mt76: move rssi_gain_thresh routines in mt76x02-lib module
  mt76: move mt76x02_phy_adjust_vga_gain in mt76/mt76x02_phy.c
  mt76: introduce mt76x02_init_agc_gain routine
  mt76x0: phy: align channel gain logic to mt76x2 one
  mt76x0: phy: do not run calibration during channel switch

 .../wireless/mediatek/mt76/mt76x0/eeprom.c|   2 +-
 .../wireless/mediatek/mt76/mt76x0/eeprom.h|   6 +
 .../net/wireless/mediatek/mt76/mt76x0/main.c  |  22 +-
 .../net/wireless/mediatek/mt76/mt76x0/mcu.h   |   3 +
 .../wireless/mediatek/mt76/mt76x0/mt76x0.h|   3 +-
 .../net/wireless/mediatek/mt76/mt76x0/pci.c   |   1 +
 .../net/wireless/mediatek/mt76/mt76x0/phy.c   | 238 ++
 drivers/net/wireless/mediatek/mt76/mt76x02.h  |   5 +-
 .../wireless/mediatek/mt76/mt76x02_eeprom.h   |  21 --
 .../net/wireless/mediatek/mt76/mt76x02_phy.c  |  78 ++
 .../net/wireless/mediatek/mt76/mt76x02_phy.h  |  31 +++
 .../wireless/mediatek/mt76/mt76x2/eeprom.c|   4 +-
 .../wireless/mediatek/mt76/mt76x2/eeprom.h|  21 ++
 .../wireless/mediatek/mt76/mt76x2/mt76x2.h|   2 -
 .../wireless/mediatek/mt76/mt76x2/pci_phy.c   |  72 +-
 .../net/wireless/mediatek/mt76/mt76x2/phy.c   |  44 
 .../wireless/mediatek/mt76/mt76x2/usb_phy.c   |   6 +-
 17 files changed, 306 insertions(+), 253 deletions(-)

-- 
2.17.2



[RFC 12/12] mt76x0: phy: do not run calibration during channel switch

2018-10-11 Thread Lorenzo Bianconi
Do not perform phy/vga calibration during channel switch.
Moreover remove mt76x0_agc_save and mt76x0_agc_restore routines
since they are no longer necessary. Furthermore run mt76_set_channel
in order to check if there are pending frame during channel switch

Signed-off-by: Lorenzo Bianconi 
---
 .../net/wireless/mediatek/mt76/mt76x0/main.c  | 22 +--
 .../wireless/mediatek/mt76/mt76x0/mt76x0.h|  2 --
 .../net/wireless/mediatek/mt76/mt76x0/phy.c   | 20 +
 drivers/net/wireless/mediatek/mt76/mt76x02.h  |  2 --
 4 files changed, 21 insertions(+), 25 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/main.c 
b/drivers/net/wireless/mediatek/mt76/mt76x0/main.c
index c9cd0254a979..9273d2d2764a 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x0/main.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x0/main.c
@@ -16,6 +16,20 @@
 #include 
 #include "mt76x0.h"
 
+static int
+mt76x0_set_channel(struct mt76x02_dev *dev, struct cfg80211_chan_def *chandef)
+{
+   int ret;
+
+   cancel_delayed_work_sync(>cal_work);
+
+   mt76_set_channel(>mt76);
+   ret = mt76x0_phy_set_channel(dev, chandef);
+   mt76_txq_schedule_all(>mt76);
+
+   return ret;
+}
+
 int mt76x0_config(struct ieee80211_hw *hw, u32 changed)
 {
struct mt76x02_dev *dev = hw->priv;
@@ -25,7 +39,7 @@ int mt76x0_config(struct ieee80211_hw *hw, u32 changed)
 
if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
ieee80211_stop_queues(hw);
-   ret = mt76x0_phy_set_channel(dev, >conf.chandef);
+   ret = mt76x0_set_channel(dev, >conf.chandef);
ieee80211_wake_queues(hw);
}
 
@@ -114,8 +128,6 @@ void mt76x0_sw_scan(struct ieee80211_hw *hw, struct 
ieee80211_vif *vif,
 {
struct mt76x02_dev *dev = hw->priv;
 
-   cancel_delayed_work_sync(>cal_work);
-   mt76x0_agc_save(dev);
set_bit(MT76_SCANNING, >mt76.state);
 }
 EXPORT_SYMBOL_GPL(mt76x0_sw_scan);
@@ -125,11 +137,7 @@ void mt76x0_sw_scan_complete(struct ieee80211_hw *hw,
 {
struct mt76x02_dev *dev = hw->priv;
 
-   mt76x0_agc_restore(dev);
clear_bit(MT76_SCANNING, >mt76.state);
-
-   ieee80211_queue_delayed_work(dev->mt76.hw, >cal_work,
-MT_CALIBRATE_INTERVAL);
 }
 EXPORT_SYMBOL_GPL(mt76x0_sw_scan_complete);
 
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h 
b/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h
index 6717d83e0ff6..2187bafaf2e9 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h
@@ -66,8 +66,6 @@ int mt76x0_set_rts_threshold(struct ieee80211_hw *hw, u32 
value);
 /* PHY */
 void mt76x0_phy_init(struct mt76x02_dev *dev);
 int mt76x0_wait_bbp_ready(struct mt76x02_dev *dev);
-void mt76x0_agc_save(struct mt76x02_dev *dev);
-void mt76x0_agc_restore(struct mt76x02_dev *dev);
 int mt76x0_phy_set_channel(struct mt76x02_dev *dev,
struct cfg80211_chan_def *chandef);
 void mt76x0_phy_recalibrate_after_assoc(struct mt76x02_dev *dev);
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/phy.c 
b/drivers/net/wireless/mediatek/mt76/mt76x0/phy.c
index 22ef733cacd6..a3c27dc6bb56 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x0/phy.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x0/phy.c
@@ -721,11 +721,11 @@ int mt76x0_phy_set_channel(struct mt76x02_dev *dev,
mt76x0_phy_set_chan_bbp_params(dev, rf_bw_band);
mt76x02_init_agc_gain(dev);
 
+   if (scan)
+   return 0;
+
if (mt76_is_usb(dev)) {
mt76x0_vco_cal(dev, channel);
-   if (scan)
-   mt76x02_mcu_calibrate(dev, MCU_CAL_RXDCOC, 1,
- false);
} else {
/* enable vco */
rf_set(dev, MT_RF(0, 4), BIT(7));
@@ -734,6 +734,9 @@ int mt76x0_phy_set_channel(struct mt76x02_dev *dev,
 
mt76x0_phy_set_txpower(dev);
 
+   ieee80211_queue_delayed_work(dev->mt76.hw, >cal_work,
+MT_CALIBRATE_INTERVAL);
+
return 0;
 }
 
@@ -770,17 +773,6 @@ void mt76x0_phy_recalibrate_after_assoc(struct mt76x02_dev 
*dev)
mt76x02_mcu_calibrate(dev, MCU_CAL_RXDCOC, 1, false);
 }
 
-void mt76x0_agc_save(struct mt76x02_dev *dev)
-{
-   /* Only one RX path */
-   dev->agc_save = FIELD_GET(MT_BBP_AGC_GAIN, mt76_rr(dev, MT_BBP(AGC, 
8)));
-}
-
-void mt76x0_agc_restore(struct mt76x02_dev *dev)
-{
-   mt76_rmw_field(dev, MT_BBP(AGC, 8), MT_BBP_AGC_GAIN, dev->agc_save);
-}
-
 static void mt76x0_temp_sensor(struct mt76x02_dev *dev)
 {
u32 rf_b7_73, rf_b0_66, rf_b0_67;
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02.h 
b/drivers/net/wireless/mediatek/mt76/mt76x02.h
index f375fdcbd2bf..47c42c607964 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02.h
@@ 

[RFC 11/12] mt76x0: phy: align channel gain logic to mt76x2 one

2018-10-11 Thread Lorenzo Bianconi
Update vga tuning algorithm to the one used in mt76x2 driver

Signed-off-by: Lorenzo Bianconi 
---
 .../net/wireless/mediatek/mt76/mt76x0/phy.c   | 56 +--
 1 file changed, 39 insertions(+), 17 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/phy.c 
b/drivers/net/wireless/mediatek/mt76/mt76x0/phy.c
index 5c155a3c1c77..22ef733cacd6 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x0/phy.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x0/phy.c
@@ -719,6 +719,7 @@ int mt76x0_phy_set_channel(struct mt76x02_dev *dev,
 
mt76x0_read_rx_gain(dev);
mt76x0_phy_set_chan_bbp_params(dev, rf_bw_band);
+   mt76x02_init_agc_gain(dev);
 
if (mt76_is_usb(dev)) {
mt76x0_vco_cal(dev, channel);
@@ -820,23 +821,44 @@ static void mt76x0_temp_sensor(struct mt76x02_dev *dev)
rf_wr(dev, MT_RF(0, 67), rf_b0_67);
 }
 
-static void mt76x0_dynamic_vga_tuning(struct mt76x02_dev *dev)
+static void mt76x0_phy_set_gain_val(struct mt76x02_dev *dev)
 {
-   struct cfg80211_chan_def *chandef = >mt76.chandef;
-   u32 val, init_vga;
-   int avg_rssi;
-
-   init_vga = chandef->chan->band == NL80211_BAND_5GHZ ? 0x54 : 0x4E;
-   avg_rssi = mt76x02_phy_get_min_avg_rssi(dev);
-   if (avg_rssi > -60)
-   init_vga -= 0x20;
-   else if (avg_rssi > -70)
-   init_vga -= 0x10;
-
-   val = mt76_rr(dev, MT_BBP(AGC, 8));
-   val &= 0x80FF;
-   val |= init_vga << 8;
-   mt76_wr(dev, MT_BBP(AGC,8), val);
+   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));
+}
+
+static void
+mt76x0_phy_update_channel_gain(struct mt76x02_dev *dev)
+{
+   bool gain_change;
+   u8 gain_delta;
+   int low_gain;
+
+   dev->cal.avg_rssi_all = mt76x02_phy_get_min_avg_rssi(dev);
+
+   low_gain = (dev->cal.avg_rssi_all > mt76x02_get_rssi_gain_thresh(dev)) +
+  (dev->cal.avg_rssi_all > 
mt76x02_get_low_rssi_gain_thresh(dev));
+
+   gain_change = (dev->cal.low_gain & 2) ^ (low_gain & 2);
+   dev->cal.low_gain = low_gain;
+
+   if (!gain_change) {
+   if (mt76x02_phy_adjust_vga_gain(dev))
+   mt76x0_phy_set_gain_val(dev);
+   return;
+   }
+
+   dev->cal.agc_gain_adjust = (low_gain == 2) ? 0 : 10;
+   gain_delta = (low_gain == 2) ? 10 : 0;
+
+   dev->cal.agc_gain_cur[0] = dev->cal.agc_gain_init[0] - gain_delta;
+   mt76x0_phy_set_gain_val(dev);
+
+   /* clear false CCA counters */
+   mt76_rr(dev, MT_RX_STAT_1);
 }
 
 static void mt76x0_phy_calibration_work(struct work_struct *work)
@@ -844,7 +866,7 @@ static void mt76x0_phy_calibration_work(struct work_struct 
*work)
struct mt76x02_dev *dev = container_of(work, struct mt76x02_dev,
   cal_work.work);
 
-   mt76x0_dynamic_vga_tuning(dev);
+   mt76x0_phy_update_channel_gain(dev);
if (!mt76x0_tssi_enabled(dev))
mt76x0_temp_sensor(dev);
 
-- 
2.17.2



[RFC 07/12] mt76x0: phy: add phy/vco temperature compensation

2018-10-11 Thread Lorenzo Bianconi
Introduce phy/vco temperature calibration.
Moreover fix configuration of register 67 on bank0
during temperature reading and use mt76_poll utility routine
to poll core34 register.
Furthermore temperature compensation needs to be disabled
if the device supports tssi compensation.
This issue has never been hit since temperature reading is not
actually used by usb code.

Fixes: 10de7a8b4ab9 ("mt76x0: phy files")
Signed-off-by: Lorenzo Bianconi 
---
 .../net/wireless/mediatek/mt76/mt76x0/phy.c   | 50 +--
 drivers/net/wireless/mediatek/mt76/mt76x02.h  |  3 +-
 2 files changed, 26 insertions(+), 27 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/phy.c 
b/drivers/net/wireless/mediatek/mt76/mt76x0/phy.c
index 049e750457e6..5c155a3c1c77 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x0/phy.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x0/phy.c
@@ -14,6 +14,9 @@
  * GNU General Public License for more details.
  */
 
+#include 
+#include 
+
 #include "mt76x0.h"
 #include "mcu.h"
 #include "eeprom.h"
@@ -23,8 +26,6 @@
 #include "initvals_phy.h"
 #include "../mt76x02_phy.h"
 
-#include 
-
 static int
 mt76x0_rf_csr_wr(struct mt76x02_dev *dev, u32 offset, u8 value)
 {
@@ -781,46 +782,42 @@ void mt76x0_agc_restore(struct mt76x02_dev *dev)
 
 static void mt76x0_temp_sensor(struct mt76x02_dev *dev)
 {
-   u8 rf_b7_73, rf_b0_66, rf_b0_67;
-   int cycle, temp;
-   u32 val;
-   s32 sval;
+   u32 rf_b7_73, rf_b0_66, rf_b0_67;
+   s8 val;
 
rf_b7_73 = rf_rr(dev, MT_RF(7, 73));
rf_b0_66 = rf_rr(dev, MT_RF(0, 66));
-   rf_b0_67 = rf_rr(dev, MT_RF(0, 73));
+   rf_b0_67 = rf_rr(dev, MT_RF(0, 67));
 
rf_wr(dev, MT_RF(7, 73), 0x02);
rf_wr(dev, MT_RF(0, 66), 0x23);
-   rf_wr(dev, MT_RF(0, 73), 0x01);
+   rf_wr(dev, MT_RF(0, 67), 0x01);
 
mt76_wr(dev, MT_BBP(CORE, 34), 0x00080055);
 
-   for (cycle = 0; cycle < 2000; cycle++) {
-   val = mt76_rr(dev, MT_BBP(CORE, 34));
-   if (!(val & 0x10))
-   break;
-   udelay(3);
-   }
-
-   if (cycle >= 2000) {
-   val &= 0x10;
-   mt76_wr(dev, MT_BBP(CORE, 34), val);
+   if (!mt76_poll(dev, MT_BBP(CORE, 34), BIT(4), 0, 2000)) {
+   mt76_clear(dev, MT_BBP(CORE, 34), BIT(4));
goto done;
}
 
-   sval = mt76_rr(dev, MT_BBP(CORE, 35)) & 0xff;
-   if (!(sval & 0x80))
-   sval &= 0x7f; /* Positive */
-   else
-   sval |= 0xff00; /* Negative */
+   val = mt76_rr(dev, MT_BBP(CORE, 35));
+   val = (35 * (val - dev->cal.rx.temp_offset)) / 10 + 25;
 
-   temp = (35 * (sval - dev->cal.rx.temp_offset)) / 10 + 25;
+   if (abs(val - dev->cal.temp_vco) > 20) {
+   mt76x02_mcu_calibrate(dev, MCU_CAL_VCO,
+ dev->mt76.chandef.chan->hw_value,
+ false);
+   dev->cal.temp_vco = val;
+   }
+   if (abs(val - dev->cal.temp) > 30) {
+   mt76x0_phy_calibrate(dev, false);
+   dev->cal.temp = val;
+   }
 
 done:
rf_wr(dev, MT_RF(7, 73), rf_b7_73);
rf_wr(dev, MT_RF(0, 66), rf_b0_66);
-   rf_wr(dev, MT_RF(0, 73), rf_b0_67);
+   rf_wr(dev, MT_RF(0, 67), rf_b0_67);
 }
 
 static void mt76x0_dynamic_vga_tuning(struct mt76x02_dev *dev)
@@ -848,7 +845,8 @@ static void mt76x0_phy_calibration_work(struct work_struct 
*work)
   cal_work.work);
 
mt76x0_dynamic_vga_tuning(dev);
-   mt76x0_temp_sensor(dev);
+   if (!mt76x0_tssi_enabled(dev))
+   mt76x0_temp_sensor(dev);
 
ieee80211_queue_delayed_work(dev->mt76.hw, >cal_work,
 MT_CALIBRATE_INTERVAL);
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02.h 
b/drivers/net/wireless/mediatek/mt76/mt76x02.h
index fe731529144c..f375fdcbd2bf 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02.h
@@ -55,7 +55,8 @@ struct mt76x02_calibration {
s8 agc_gain_adjust;
s8 low_gain;
 
-   u8 temp;
+   s8 temp_vco;
+   s8 temp;
 
bool init_cal_done;
bool tssi_cal_done;
-- 
2.17.2



[PATCH] ath10k: htt: remove some dead code

2018-10-11 Thread Dan Carpenter
We added an unnecessary condition here in commit a904417fc876 ("ath10k:
add extended per sta tx statistics support").  "legacy_rate_idx" is a u8
so it can't be negative.  The caller doesn't pass negatives either.  I
have deleted this code.

Signed-off-by: Dan Carpenter 
---
I didn't use the Fixes tag because it's not really a bug.

diff --git a/drivers/net/wireless/ath/ath10k/htt_rx.c 
b/drivers/net/wireless/ath/ath10k/htt_rx.c
index f2405258a6d3..13717a287848 100644
--- a/drivers/net/wireless/ath/ath10k/htt_rx.c
+++ b/drivers/net/wireless/ath/ath10k/htt_rx.c
@@ -2680,8 +2680,6 @@ ath10k_accumulate_per_peer_tx_stats(struct ath10k *ar,
STATS_OP_FMT(RETRY).ht[1][ht_idx] += pstats->retry_pkts;
} else {
mcs = legacy_rate_idx;
-   if (mcs < 0)
-   return;
 
STATS_OP_FMT(SUCC).legacy[0][mcs] += pstats->succ_bytes;
STATS_OP_FMT(SUCC).legacy[1][mcs] += pstats->succ_pkts;


Re: [PATCH] qtnfmac: avoid uninitialized variable access

2018-10-11 Thread Kalle Valo
Sergey Matyukevich  writes:

>> > When qtnf_trans_send_cmd_with_resp() fails, we have not yet initialized
>> > 'resp', as pointed out by a valid gcc warning:
>> >
>> > drivers/net/wireless/quantenna/qtnfmac/commands.c: In function
>> > 'qtnf_cmd_send_with_reply':
>> > drivers/net/wireless/quantenna/qtnfmac/commands.c:133:54: error:
>> > 'resp' may be used uninitialized in this function
>> > [-Werror=maybe-uninitialized]
>> >
>> > Since 'resp_skb' is also not set here, we can skip all further
>> > processing and just print the warning and return the failure code.
>> >
>> > Fixes: c6ed298ffe09 ("qtnfmac: cleanup and unify command error handling")
>> > Signed-off-by: Arnd Bergmann 
>> 
>> Thanks for the patch! And for reminding me that I forgot to enable
>> gcc warnings in CI builds in addition to sparse checks.
>> 
>> Reviewed-by: Sergey Matyukevich 
>
> Hi Kalle,
>
> Could you please hold back applying this patch for now. We have got
> another report for the same function, this time static analysis tool
> warning. It looks like the patch from Arnd does not cover both cases.
> So we will take a closer look and send a combined fix later.

Ok, I'll drop this from my queue. Please resend whatever patch I need to
apply.

-- 
Kalle Valo


[PATCH V3] ath10k: allocate small size dma memory in ath10k_pci_diag_write_mem

2018-10-11 Thread Carl Huang
ath10k_pci_diag_write_mem may allocate big size of the dma memory
based on the parameter nbytes. Take firmware diag download as
example, the biggest size is about 500K. In some systems, the
allocation is likely to fail because it can't acquire such a large
contiguous dma memory.

The fix is to allocate a small size dma memory. In the loop,
driver copies the data to the allocated dma memory and writes to
the destination until all the data is written.

Tested with QCA6174 PCI with
firmware-6.bin_WLAN.RM.4.4.1-00119-QCARMSWP-1, this also affects
QCA9377 PCI.

Signed-off-by: Carl Huang 
Reviewed-by: Brian Norris 
---
V3:
  *removed (u32)cast to ce_data_base.

V2:
  *addressed Brian's comment. Removed ce_data variable.

 drivers/net/wireless/ath/ath10k/pci.c | 23 +++
 1 file changed, 11 insertions(+), 12 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/pci.c 
b/drivers/net/wireless/ath/ath10k/pci.c
index 873dbb6..01b4edb 100644
--- a/drivers/net/wireless/ath/ath10k/pci.c
+++ b/drivers/net/wireless/ath/ath10k/pci.c
@@ -1071,10 +1071,9 @@ int ath10k_pci_diag_write_mem(struct ath10k *ar, u32 
address,
struct ath10k_ce *ce = ath10k_ce_priv(ar);
int ret = 0;
u32 *buf;
-   unsigned int completed_nbytes, orig_nbytes, remaining_bytes;
+   unsigned int completed_nbytes, alloc_nbytes, remaining_bytes;
struct ath10k_ce_pipe *ce_diag;
void *data_buf = NULL;
-   u32 ce_data;/* Host buffer address in CE space */
dma_addr_t ce_data_base = 0;
int i;
 
@@ -1088,9 +1087,10 @@ int ath10k_pci_diag_write_mem(struct ath10k *ar, u32 
address,
 *   1) 4-byte alignment
 *   2) Buffer in DMA-able space
 */
-   orig_nbytes = nbytes;
+   alloc_nbytes = min_t(unsigned int, nbytes, DIAG_TRANSFER_LIMIT);
+
data_buf = (unsigned char *)dma_alloc_coherent(ar->dev,
-  orig_nbytes,
+  alloc_nbytes,
   _data_base,
   GFP_ATOMIC);
if (!data_buf) {
@@ -1098,9 +1098,6 @@ int ath10k_pci_diag_write_mem(struct ath10k *ar, u32 
address,
goto done;
}
 
-   /* Copy caller's data to allocated DMA buf */
-   memcpy(data_buf, data, orig_nbytes);
-
/*
 * The address supplied by the caller is in the
 * Target CPU virtual address space.
@@ -1113,12 +1110,14 @@ int ath10k_pci_diag_write_mem(struct ath10k *ar, u32 
address,
 */
address = ath10k_pci_targ_cpu_to_ce_addr(ar, address);
 
-   remaining_bytes = orig_nbytes;
-   ce_data = ce_data_base;
+   remaining_bytes = nbytes;
while (remaining_bytes) {
/* FIXME: check cast */
nbytes = min_t(int, remaining_bytes, DIAG_TRANSFER_LIMIT);
 
+   /* Copy caller's data to allocated DMA buf */
+   memcpy(data_buf, data, nbytes);
+
/* Set up to receive directly into Target(!) address */
ret = ce_diag->ops->ce_rx_post_buf(ce_diag, , address);
if (ret != 0)
@@ -1128,7 +1127,7 @@ int ath10k_pci_diag_write_mem(struct ath10k *ar, u32 
address,
 * Request CE to send caller-supplied data that
 * was copied to bounce buffer to Target(!) address.
 */
-   ret = ath10k_ce_send_nolock(ce_diag, NULL, (u32)ce_data,
+   ret = ath10k_ce_send_nolock(ce_diag, NULL, ce_data_base,
nbytes, 0, 0);
if (ret != 0)
goto done;
@@ -1171,12 +1170,12 @@ int ath10k_pci_diag_write_mem(struct ath10k *ar, u32 
address,
 
remaining_bytes -= nbytes;
address += nbytes;
-   ce_data += nbytes;
+   data += nbytes;
}
 
 done:
if (data_buf) {
-   dma_free_coherent(ar->dev, orig_nbytes, data_buf,
+   dma_free_coherent(ar->dev, alloc_nbytes, data_buf,
  ce_data_base);
}
 
-- 
2.7.4



Re: [RFC v3 01/12] rtw88: main files

2018-10-11 Thread Johannes Berg
On Thu, 2018-10-11 at 07:23 +, Tony Chuang wrote:

> > > + switch (vif->type) {
> > > + case NL80211_IFTYPE_AP:
> > > + case NL80211_IFTYPE_MESH_POINT:
> > > + net_type = RTW_NET_AP_MODE;
> > > + break;
> > > + case NL80211_IFTYPE_ADHOC:
> > > + net_type = RTW_NET_AD_HOC;
> > > + break;
> > > + default:
> > > + net_type = RTW_NET_NO_LINK;
> > 
> > you might to add STATION and then fail in the default case?
> 
> 
> Yeah, station starts with NO_LINK until it's associated with an AP

Right. I was just thinking of the switch statement - you might want to
handle STATION explicitly, instead of in the default case, and then fail
in the default case for this to be a little more readable and robust.
Not all that important.


> > This will provoke error messages to be printed for e.g. CMAC keys, or do
> > you really not support protected management frames? If you were to pick
> > "-EOPNOTSUPP" then no errors would be printed.
> 
> We do not support PMF hw encryption/decryption now, perhaps we need
> to register the cipher_schemes when ieee80211_register_hw.

Ok, that's fine.

> Even if HW does not support it, I think mac80211 can use SW 
> encryption/decryption
> after driver failed to upload key to hardware?

Yes.

> So if driver has not declared MFP_CAPABLE, the mac80211 will ignore it and
> wpa_supplicant will guess we cannot perform MFP. It is strange.

Right, no, it's not strange. That was my point though, if you do want to
support it you should set MFP_CAPABLE, but you should return a different
error code to avoid an error message being printed from mac80211. That's
all. The logic is fine, just use -EOPNOTSUPP (rather than -ENOTSUPP) to
suppress any error messages.

> > why should statistics be reset evyer 2 seconds?
> 
> All of our statistics are counted in 2 seconds, ex. pkts, bytes, fa ...
> So just reset them every seconds.

No other device behaves this way though, so you shouldn't do this
either.

> > > + ieee80211_hw_set(hw, MFP_CAPABLE);
> > 
> > so you do have MFP - I guess you should test it and check for spurious
> > hardware crypto messages
> 
> We don't have now, should remove them. But as I have mentioned, if we don't
> declare it here, mac80211 will discard the cipher and pass it to wiphy.
> And we still should be able to work with MFP because mac80211 can do
> software encryption/decryption for us.

Right. So this is fine, see above regarding the error message that gets
printed.

> Finally, I removed the vif_list and sta_list. And use the iterator
> provided by mac80211,
> But there is one question that how can we find all of the sta associated
> with specific vif,
> Has there an only way to iterate every sta and see if (sta->vif == vif) ?

Yes, looks like that's the only way - I guess you could pass the vif as
the data pointer. I suppose we could add a vif filter argument to the
iteration and ignore it if it's NULL, but is it worth it?

johannes


Re: [PATCH 13/19] wilc: add linux_wlan.c

2018-10-11 Thread Ajay Singh


On 10/11/2018 12:33 PM, Johannes Berg wrote:
> On Thu, 2018-10-11 at 12:30 +0530, Ajay Singh wrote:
 +  if (queue_count > FLOW_CONTROL_UPPER_THRESHOLD) {
 +  netif_stop_queue(wilc->vif[0]->ndev);
 +  netif_stop_queue(wilc->vif[1]->ndev);
 +  }
>>> It seems like a pretty bad idea to hard-code two interfaces, we do
>>> dynamic addition/removal these days, in *particular* for P2P.
>>>
>> Did you mean it not good to call stop queue for both the interfaces.
>> Can you please provide some more details about this comments.
> No, I mean you should be more dynamic and have e.g. a list of interfaces
> (actually, you can use cfg80211's list, I believe!), instead of hard-
> coding that you have "wlan0" and "p2p0".


I got your point now. I will check on this to add the support.

Regards,
Ajay



RE: [RFC v3 01/12] rtw88: main files

2018-10-11 Thread Tony Chuang
> -Original Message-
> From: Johannes Berg [mailto:johan...@sipsolutions.net]
> Sent: Monday, October 08, 2018 10:10 PM
> To: Tony Chuang; kv...@codeaurora.org
> Cc: larry.fin...@lwfinger.net; Pkshih; Andy Huang; sgrus...@redhat.com;
> linux-wireless@vger.kernel.org
> Subject: Re: [RFC v3 01/12] rtw88: main files
> 
> On Wed, 2018-10-03 at 19:20 +0800, yhchu...@realtek.com wrote:
> >
> > +static int rtw_ops_config(struct ieee80211_hw *hw, u32 changed)
> > +{
> > +   struct rtw_dev *rtwdev = hw->priv;
> > +   int ret = 0;
> > +
> > +   mutex_lock(>mutex);
> > +
> > +   if (changed & IEEE80211_CONF_CHANGE_IDLE) {
> > +   if (hw->conf.flags & IEEE80211_CONF_IDLE) {
> > +   rtw_enter_ips(rtwdev);
> > +   } else {
> > +   ret = rtw_leave_ips(rtwdev);
> > +   if (ret) {
> > +   rtw_err(rtwdev, "failed to leave idle state\n");
> > +   goto out;
> > +   }
> > +   }
> > +   }
> > +
> > +   if (changed & IEEE80211_CONF_CHANGE_CHANNEL)
> > +   rtw_set_channel(rtwdev);
> 
> You really should consider supporting channel contexts - it's the far
> more modern API and likely gives you more control even if you support
> only a single channel.
> 

Get it, but seems to need quite of time to get it down.
Will switch to channel context APIs after.

> > +static struct rtw_vif_port rtw_vif_port[] = {
> > +   [0] = {
> > +   .mac_addr   = {.addr = 0x0610},
> > +   .bssid  = {.addr = 0x0618},
> > +   .net_type   = {.addr = 0x0100, .mask = 0x3},
> > +   .aid= {.addr = 0x06a8, .mask = 0x7ff},
> > +   },
> 
> err, what's all this?
> 
> Anyway, you really cannot make this static - again, multiple devices
> might get plugged in.

They are just constants, will mark them with "const static"

> 
> > +   list_add_rcu(>list, >vif_list);
> 
> I don't see a reason for you to maintain your own list, you can always
> iterate mac80211's list if you really need to?
> 
> > +   switch (vif->type) {
> > +   case NL80211_IFTYPE_AP:
> > +   case NL80211_IFTYPE_MESH_POINT:
> > +   net_type = RTW_NET_AP_MODE;
> > +   break;
> > +   case NL80211_IFTYPE_ADHOC:
> > +   net_type = RTW_NET_AD_HOC;
> > +   break;
> > +   default:
> > +   net_type = RTW_NET_NO_LINK;
> 
> you might to add STATION and then fail in the default case?


Yeah, station starts with NO_LINK until it's associated with an AP


> 
> > +static void rtw_ops_remove_interface(struct ieee80211_hw *hw,
> > +struct ieee80211_vif *vif)
> > +{
> > +   struct rtw_dev *rtwdev = hw->priv;
> > +   struct rtw_vif *rtwvif = (struct rtw_vif *)vif->drv_priv;
> > +   u32 config = 0;
> > +
> > +   rtw_info(rtwdev, "stop vif %pM on port %d", vif->addr, rtwvif->port);
> > +
> > +   mutex_lock(>mutex);
> > +
> > +   eth_zero_addr(rtwvif->mac_addr);
> > +   config |= PORT_SET_MAC_ADDR;
> > +   rtwvif->net_type = RTW_NET_NO_LINK;
> > +   config |= PORT_SET_NET_TYPE;
> > +   rtw_vif_port_config(rtwdev, rtwvif, config);
> > +
> > +   list_del_rcu(>list);
> > +   synchronize_rcu();
> 
> That synchronize_rcu() is *really* expensive, you should probably use
> mac80211's list iteration to avoid it.
> 
> > +static u8 rtw_acquire_macid(struct rtw_dev *rtwdev)
> > +{
> > +   u8 i;
> > +
> > +   for (i = 0; i < RTW_MAX_MAC_ID_NUM; i++) {
> > +   if (!rtwdev->macid_used[i]) {
> > +   rtwdev->macid_used[i] = true;
> > +   return i;
> > +   }
> > +   }
> > +
> > +   return i;
> > +}
> > +
> > +static void rtw_release_macid(struct rtw_dev *rtwdev, u8 mac_id)
> > +{
> > +   rtwdev->macid_used[mac_id] = false;
> > +}
> 
> This would be way simpler (and use much less memory) with a bitmap and
> find_first_zero_bit().

OK, it looks better.

> 
> > +static int rtw_ops_sta_add(struct ieee80211_hw *hw,
> > +  struct ieee80211_vif *vif,
> > +  struct ieee80211_sta *sta)
> 
> You might want to use sta_state() instead of sta_add(), it's likely the
> better API.

Yeah I know sta_state is the better version of sta_add/sta_remove.
Should make a transition to get more control about the states.
But it seems to be not a really urgent requirement for now.
Anyway, it is a good point, we should follow sta_state in the future.

> 
> > +   si->sta = sta;
> > +   si->vif = vif;
> > +   si->init_ra_lv = 1;
> > +   ewma_rssi_init(>avg_rssi);
> 
> What's this for that mac80211 doesn't do already?
> 
> > +   rtw_update_sta_info(rtwdev, si);
> > +   rtw_fw_media_status_report(rtwdev, si->mac_id, true);
> > +
> > +   list_add_tail_rcu(>list, >sta_list);
> 
> Again, you shouldn't need to keep your own list in the driver, mac80211
> does all that bookkeeping for you.
> 
> > +static int rtw_ops_sta_remove(struct ieee80211_hw *hw,
> > + struct ieee80211_vif *vif,

Re: [PATCH 14/19] wilc: add linux_mon.c

2018-10-11 Thread Johannes Berg
On Thu, 2018-10-11 at 12:42 +0530, Ajay Singh wrote:
> > I'm
> > just doing a drive-by review for the stack integration aspects (and
> > haven't even found where that happens yet).
[...]
> Currently, I am not clear about which stack integration part is missing
> . Can you please provide some more details about it.

No, I'm just saying that *I* was looking for how you integrate with the
stack (cfg80211), and not so much trying to review everything else.

johannes


Re: [PATCH 14/19] wilc: add linux_mon.c

2018-10-11 Thread Ajay Singh


On 10/8/2018 8:14 PM, Johannes Berg wrote:
> On Wed, 2018-09-26 at 15:55 +0530, Ajay Singh wrote:
>> +static struct net_device *wilc_wfi_mon; /* global monitor netdev */
> There might not exist platforms with multiple devices (yet), but it's
> really bad practice to do this anyway.
>
Sure, will work on to avoid the use of this static variable here.
>> +static u8 srcadd[6];
>> +static u8 bssid[6];
>> +
>> +#define IEEE80211_RADIOTAP_F_TX_RTS 0x0004  /* used rts/cts handshake */
>> +#define IEEE80211_RADIOTAP_F_TX_FAIL0x0001  /* failed due to 
>> excessive*/
> Uh.. we have a radiotap include file and you already use it, why?
>
Right, will remove these macro as header is already included.
>> +void wilc_wfi_deinit_mon_interface(void)
>> +{
>> +bool rollback_lock = false;
>> +
>> +if (wilc_wfi_mon) {
>> +if (rtnl_is_locked()) {
>> +rtnl_unlock();
>> +rollback_lock = true;
>> +}
>> +unregister_netdev(wilc_wfi_mon);
>> +
>> +if (rollback_lock) {
>> +rtnl_lock();
>> +rollback_lock = false;
>> +}
>> +wilc_wfi_mon = NULL;
>> +}
>> +}
> Uh, no, you really cannot do conditional locking like this.
>
> But seeing things like this pretty much destroys all of the confidence I
> might have had of the code, so I'd say we cannot merge this until you
> can demonstrate somebody more familiar with Linux has reviewed it, I'm
> just doing a drive-by review for the stack integration aspects (and
> haven't even found where that happens yet).

I will refactor wilc_wfi_deinit_mon_interface() and submit more cleaner
version of this function.
Currently, I am not clear about which stack integration part is missing
. Can you please provide some more details about it.

Regards,
Ajay



Re: [PATCH 13/19] wilc: add linux_wlan.c

2018-10-11 Thread Johannes Berg
On Thu, 2018-10-11 at 12:30 +0530, Ajay Singh wrote:
> 
> > > + if (queue_count > FLOW_CONTROL_UPPER_THRESHOLD) {
> > > + netif_stop_queue(wilc->vif[0]->ndev);
> > > + netif_stop_queue(wilc->vif[1]->ndev);
> > > + }
> > 
> > It seems like a pretty bad idea to hard-code two interfaces, we do
> > dynamic addition/removal these days, in *particular* for P2P.
> > 
> 
> Did you mean it not good to call stop queue for both the interfaces.
> Can you please provide some more details about this comments.

No, I mean you should be more dynamic and have e.g. a list of interfaces
(actually, you can use cfg80211's list, I believe!), instead of hard-
coding that you have "wlan0" and "p2p0".

johannes


Re: [PATCH 04/19] wilc: add host_interface.c

2018-10-11 Thread Johannes Berg


> Agree. parameter validation can be done before scheduling the work,
> and hence appropriate error can be returned to caller .


> If I got your point correctly, you are referring to the lines that
> stores the parameters into the hif_drv->cfg_values.

Well, I was actually thinking that I'm not even sure why you schedule
work at all!

> Instead of packing the parameters in host structures like struct
> add_sta_param, then repacking it in the device format, it can use
> struct station_parameters and pack them directly into the device
> format

Makes sense. Also note my other email on how there should be structs
involved, rather than open-coded WID entry lists.

johannes


Re: [PATCH 13/19] wilc: add linux_wlan.c

2018-10-11 Thread Ajay Singh


On 10/8/2018 8:11 PM, Johannes Berg wrote:
> On Wed, 2018-09-26 at 15:55 +0530, Ajay Singh wrote:
>> Moved '/driver/staging/wilc1000/linux_wlan.c' to
>> 'drivers/net/wireless/microchip/wilc/'.
>>
>> Signed-off-by: Ajay Singh 
>> ---
>>  drivers/net/wireless/microchip/wilc/linux_wlan.c | 1161 
>> ++
>>  1 file changed, 1161 insertions(+)
>>  create mode 100644 drivers/net/wireless/microchip/wilc/linux_wlan.c
> Hmm. It's pretty obviously a linux driver, what's the point?
>
Agree, will rename by avoiding the 'linux' prefix.
>> diff --git a/drivers/net/wireless/microchip/wilc/linux_wlan.c 
>> b/drivers/net/wireless/microchip/wilc/linux_wlan.c
>> new file mode 100644
>> index 000..76c9012
>> --- /dev/null
>> +++ b/drivers/net/wireless/microchip/wilc/linux_wlan.c
>> @@ -0,0 +1,1161 @@
>> +// SPDX-License-Identifier: GPL-2.0
>> +/*
>> + * Copyright (c) 2012 - 2018 Microchip Technology Inc., and its 
>> subsidiaries.
>> + * All rights reserved.
>> + */
>> +
>> +#include 
>> +#include 
>> +#include 
>> +#include 
>> +#include 
>> +
>> +#include "wilc_wfi_cfgoperations.h"
>> +
>> +static int dev_state_ev_handler(struct notifier_block *this,
>> +unsigned long event, void *ptr)
>> +{
>> +struct in_ifaddr *dev_iface = ptr;
>> +struct wilc_priv *priv;
>> +struct host_if_drv *hif_drv;
>> +struct net_device *dev;
>> +u8 *ip_addr_buf;
>> +struct wilc_vif *vif;
>> +u8 null_ip[4] = {0};
>> +char wlan_dev_name[5] = "wlan0";
> Regardless of what you're trying to do, thta seems like a bad idea.
>
>> +if (!dev_iface || !dev_iface->ifa_dev || !dev_iface->ifa_dev->dev)
>> +return NOTIFY_DONE;
>> +
>> +if (memcmp(dev_iface->ifa_label, "wlan0", 5) &&
>> +memcmp(dev_iface->ifa_label, "p2p0", 4))
>> +return NOTIFY_DONE;
> That too. What???
Purpose of this function is to deferred going into powsersave till the
IP address is acquired by the interfaces. This is to avoid any issue in
acquiring the IP address(due to power save mode).
We will investigate and check the better to handle this condition.
>> +dev  = (struct net_device *)dev_iface->ifa_dev->dev;
>> +if (!dev->ieee80211_ptr || !dev->ieee80211_ptr->wiphy)
>> +return NOTIFY_DONE;
>> +
>> +priv = wiphy_priv(dev->ieee80211_ptr->wiphy);
>> +if (!priv)
>> +return NOTIFY_DONE;
>> +
>> +hif_drv = (struct host_if_drv *)priv->hif_drv;
>> +vif = netdev_priv(dev);
>> +if (!vif || !hif_drv)
>> +return NOTIFY_DONE;
>> +
>> +switch (event) {
>> +case NETDEV_UP:
>> +if (vif->iftype == STATION_MODE || vif->iftype == CLIENT_MODE) {
>> +hif_drv->ifc_up = 1;
>> +vif->obtaining_ip = false;
>> +del_timer(>during_ip_timer);
>> +}
>> +
>> +if (vif->wilc->enable_ps)
>> +wilc_set_power_mgmt(vif, 1, 0);
>> +
>> +netdev_dbg(dev, "[%s] Up IP\n", dev_iface->ifa_label);
>> +
>> +ip_addr_buf = (char *)_iface->ifa_address;
>> +netdev_dbg(dev, "IP add=%d:%d:%d:%d\n",
>> +   ip_addr_buf[0], ip_addr_buf[1],
>> +   ip_addr_buf[2], ip_addr_buf[3]);
> %pI4, I believe, but I think you should just remove it, it likely won't
> have an IP address anyway, and you might have multiple, and so this is
> just broken.
>
>> +eth_h = (struct ethhdr *)(skb->data);
>> +if (eth_h->h_proto == cpu_to_be16(0x8e88))
>> +netdev_dbg(ndev, "EAPOL transmitted\n");
> Err, no, just remove that.
Ok.
>> +ih = (struct iphdr *)(skb->data + sizeof(struct ethhdr));
> Sure, everything is IP. You just checked that it wasn't EAPOL?
>
>> +udp_buf = (char *)ih + sizeof(struct iphdr);
>> +if ((udp_buf[1] == 68 && udp_buf[3] == 67) ||
>> +(udp_buf[1] == 67 && udp_buf[3] == 68))
>> +netdev_dbg(ndev, "DHCP Message transmitted, type:%x %x %x\n",
>> +   udp_buf[248], udp_buf[249], udp_buf[250]);
> Umm... no. Just remove that too.
>
Ok
>> +vif->netstats.tx_packets++;
>> +vif->netstats.tx_bytes += tx_data->size;
>> +tx_data->bssid = wilc->vif[vif->idx]->bssid;
>> +queue_count = wilc_wlan_txq_add_net_pkt(ndev, (void *)tx_data,
>> +tx_data->buff, tx_data->size,
>> +linux_wlan_tx_complete);
>> +
>> +if (queue_count > FLOW_CONTROL_UPPER_THRESHOLD) {
>> +netif_stop_queue(wilc->vif[0]->ndev);
>> +netif_stop_queue(wilc->vif[1]->ndev);
>> +}
> It seems like a pretty bad idea to hard-code two interfaces, we do
> dynamic addition/removal these days, in *particular* for P2P.
>
Did you mean it not good to call stop queue for both the interfaces.
Can you please provide some more details about this comments.
>> +static int wilc_mac_close(struct net_device *ndev)
>> +{
>> +struct 

Re: [PATCH 05/19] wilc: add wilc_wlan_if.h

2018-10-11 Thread Ajay Singh


On 10/8/2018 8:03 PM, Johannes Berg wrote:
>> +#define WILC_TX_ERR_NO_BUF  (-2)
> Hmm? what's wrong with just e.g. -ENOBUFS? If it doesn't go to userspace
> it doesn't matter, and if it does you can't use this anyway? This would
> be -ENOENT which is a bad idea.
>
Actually this value doesn't return to userspace and its used locally for
the error status.
But anyway we can make use of (-ENOBUFS) instead of adding this new macro.
>> +
>> +/
>> + *
>> + *  Wlan Configuration ID
>> + *
>> + /
>> +#define WILC_MULTICAST_TABLE_SIZE   8
>> +#define MAX_SSID_LEN33
> Err, it's 32?
>
>> +#define MAX_RATES_SUPPORTED 12
>> +
>> +enum bss_types {
>> +INFRASTRUCTURE  = 0,
>> +INDEPENDENT,
>> +AP,
>> +};
>> +
>> +enum {
>> +B_ONLY_MODE = 0,/* 1, 2 M, otherwise 5, 11 M */
>> +G_ONLY_MODE,/* 6,12,24 otherwise 9,18,36,48,54 */
>> +G_MIXED_11B_1_MODE, /* 1,2,5.5,11 otherwise all on */
>> +G_MIXED_11B_2_MODE, /* 1,2,5,11,6,12,24 otherwise all on */
>> +};
>> +
>> +enum {
>> +G_SHORT_PREAMBLE= 0,/* Short Preamble */
>> +G_LONG_PREAMBLE = 1,/* Long Preamble */
>> +G_AUTO_PREAMBLE = 2,/* Auto Preamble Selection */
>> +};
> here we have a lot of those "constants should have some sort of prefix"
> things ... it's not even clear if they're spec or not:
>
>> +enum authtype {
>> +OPEN_SYSTEM = 1,
>> +SHARED_KEY  = 2,
>> +ANY = 3,
>> +IEEE8021= 5
>> +};
> These look like they're spec but aren't ... not a good idea.
>
Yes,  these are not part of any spec . We will  add the prefix for
better understanding.

Regards,
Ajay



Re: [PATCH 04/19] wilc: add host_interface.c

2018-10-11 Thread Ajay Singh
Hi,

On 10/8/2018 8:01 PM, Johannes Berg wrote:
>> +*currbyte = (u32)0 & DRV_HANDLER_MASK;
> You do this a few times, not sure what it's supposed to achieve?
>
Agree, the bitwise operation is useless here and this logic should be
modified.
>
> So far I guess I'd say:
>  * use more kernel infra, in particular {get,put}_unaligned_le{16,32}
>  * name your device/driver-specific constants better, rather than things
>like "SET_CFG" which leave everyone wondering if it's specific to
>this driver or something from elsewhere
>
Thanks for your inputs.
I will use your suggestion while submitting the refactor code.

Regards,
Ajay