[PATCH v2 1/2] pci: Add vendor id of Ubiquiti Networks

2018-01-24 Thread Tobias Schramm
Signed-off-by: Tobias Schramm 
---
 include/linux/pci_ids.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
index ab20dc5db423..6b01ac1e9bce 100644
--- a/include/linux/pci_ids.h
+++ b/include/linux/pci_ids.h
@@ -149,6 +149,8 @@
 #define PCI_VENDOR_ID_DYNALINK 0x0675
 #define PCI_DEVICE_ID_DYNALINK_IS64PH  0x1702
 
+#define PCI_VENDOR_ID_UBNT 0x0777
+
 #define PCI_VENDOR_ID_BERKOM   0x0871
 #define PCI_DEVICE_ID_BERKOM_A1T   0xffa1
 #define PCI_DEVICE_ID_BERKOM_T_CONCEPT 0xffa2
-- 
2.16.0



[PATCH v2 2/2] ath10k: Add support for Uiquiti rebranded QCA988X v2

2018-01-24 Thread Tobias Schramm
Some modern Ubiquiti devices contain a rebranded QCA988X rev2 with
a custom Ubiquiti vendor and device id. This patch adds support for
those devices, treating them as a QCA988X v2.

Signed-off-by: Tobias Schramm 
---
 drivers/net/wireless/ath/ath10k/core.c | 24 
 drivers/net/wireless/ath/ath10k/hw.h   |  1 +
 drivers/net/wireless/ath/ath10k/pci.c  |  4 
 3 files changed, 29 insertions(+)

diff --git a/drivers/net/wireless/ath/ath10k/core.c 
b/drivers/net/wireless/ath/ath10k/core.c
index b29fdbd21ead..9fb38f2c1d6e 100644
--- a/drivers/net/wireless/ath/ath10k/core.c
+++ b/drivers/net/wireless/ath/ath10k/core.c
@@ -52,6 +52,30 @@ MODULE_PARM_DESC(cryptmode, "Crypto mode: 0-hardware, 
1-software");
 MODULE_PARM_DESC(rawmode, "Use raw 802.11 frame datapath");
 
 static const struct ath10k_hw_params ath10k_hw_params_list[] = {
+   {
+   .id = QCA988X_HW_2_0_VERSION,
+   .dev_id = QCA988X_2_0_DEVICE_ID_UBNT,
+   .name = "qca988x hw2.0",
+   .patch_load_addr = QCA988X_HW_2_0_PATCH_LOAD_ADDR,
+   .uart_pin = 7,
+   .cc_wraparound_type = ATH10K_HW_CC_WRAP_SHIFTED_ALL,
+   .otp_exe_param = 0,
+   .channel_counters_freq_hz = 88000,
+   .max_probe_resp_desc_thres = 0,
+   .cal_data_len = 2116,
+   .fw = {
+   .dir = QCA988X_HW_2_0_FW_DIR,
+   .board = QCA988X_HW_2_0_BOARD_DATA_FILE,
+   .board_size = QCA988X_BOARD_DATA_SZ,
+   .board_ext_size = QCA988X_BOARD_EXT_DATA_SZ,
+   },
+   .hw_ops = _ops,
+   .decap_align_bytes = 4,
+   .spectral_bin_discard = 0,
+   .vht160_mcs_rx_highest = 0,
+   .vht160_mcs_tx_highest = 0,
+   .n_cipher_suites = 8,
+   },
{
.id = QCA988X_HW_2_0_VERSION,
.dev_id = QCA988X_2_0_DEVICE_ID,
diff --git a/drivers/net/wireless/ath/ath10k/hw.h 
b/drivers/net/wireless/ath/ath10k/hw.h
index 05f26e5858ad..5ae3b56acc19 100644
--- a/drivers/net/wireless/ath/ath10k/hw.h
+++ b/drivers/net/wireless/ath/ath10k/hw.h
@@ -22,6 +22,7 @@
 
 #define ATH10K_FW_DIR  "ath10k"
 
+#define QCA988X_2_0_DEVICE_ID_UBNT   (0x11ac)
 #define QCA988X_2_0_DEVICE_ID   (0x003c)
 #define QCA6164_2_1_DEVICE_ID   (0x0041)
 #define QCA6174_2_1_DEVICE_ID   (0x003e)
diff --git a/drivers/net/wireless/ath/ath10k/pci.c 
b/drivers/net/wireless/ath/ath10k/pci.c
index ffea348b2190..ccac6740795d 100644
--- a/drivers/net/wireless/ath/ath10k/pci.c
+++ b/drivers/net/wireless/ath/ath10k/pci.c
@@ -52,6 +52,7 @@ MODULE_PARM_DESC(reset_mode, "0: auto, 1: warm only (default: 
0)");
 #define ATH10K_PCI_NUM_WARM_RESET_ATTEMPTS 3
 
 static const struct pci_device_id ath10k_pci_id_table[] = {
+   { PCI_VDEVICE(UBNT, QCA988X_2_0_DEVICE_ID_UBNT) }, /* PCI-E QCA988X V2 
(Ubiquiti branded) */
{ PCI_VDEVICE(ATHEROS, QCA988X_2_0_DEVICE_ID) }, /* PCI-E QCA988X V2 */
{ PCI_VDEVICE(ATHEROS, QCA6164_2_1_DEVICE_ID) }, /* PCI-E QCA6164 V2.1 
*/
{ PCI_VDEVICE(ATHEROS, QCA6174_2_1_DEVICE_ID) }, /* PCI-E QCA6174 V2.1 
*/
@@ -68,6 +69,7 @@ static const struct ath10k_pci_supp_chip 
ath10k_pci_supp_chips[] = {
 * hacks. ath10k doesn't have them and these devices crash horribly
 * because of that.
 */
+   { QCA988X_2_0_DEVICE_ID_UBNT, QCA988X_HW_2_0_CHIP_ID_REV },
{ QCA988X_2_0_DEVICE_ID, QCA988X_HW_2_0_CHIP_ID_REV },
 
{ QCA6164_2_1_DEVICE_ID, QCA6174_HW_2_1_CHIP_ID_REV },
@@ -1977,6 +1979,7 @@ static int ath10k_pci_get_num_banks(struct ath10k *ar)
struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
 
switch (ar_pci->pdev->device) {
+   case QCA988X_2_0_DEVICE_ID_UBNT:
case QCA988X_2_0_DEVICE_ID:
case QCA99X0_2_0_DEVICE_ID:
case QCA9888_2_0_DEVICE_ID:
@@ -3208,6 +3211,7 @@ static int ath10k_pci_probe(struct pci_dev *pdev,
u32 (*targ_cpu_to_ce_addr)(struct ath10k *ar, u32 addr);
 
switch (pci_dev->device) {
+   case QCA988X_2_0_DEVICE_ID_UBNT:
case QCA988X_2_0_DEVICE_ID:
hw_rev = ATH10K_HW_QCA988X;
pci_ps = false;
-- 
2.16.0



[PATCH v2 0/2] ath10k: Add support for Ubiquiti-branded QCA988X

2018-01-24 Thread Tobias Schramm
A lot of more modern Ubiquiti AirMAX wireless devices contain a rebranded
QCA988X with changed PCI vendor and device id.
This patch adds support for those chips by treating them as QCA988X rev2
radios.

Changes since v1:
 * Send patch to more people and lists


Tobias Schramm (2):
  pci: Add vendor id of Ubiquiti Networks
  ath10k: Add support for Uiquiti rebranded QCA988X v2

 drivers/net/wireless/ath/ath10k/core.c | 24 
 drivers/net/wireless/ath/ath10k/hw.h   |  1 +
 drivers/net/wireless/ath/ath10k/pci.c  |  4 
 include/linux/pci_ids.h|  2 ++
 4 files changed, 31 insertions(+)

-- 
2.16.0



Re: [2/2] mwifiex: use more_rx_task_flag to avoid USB RX stall

2018-01-24 Thread Kalle Valo
Ganapathi Bhat  wrote:

> From: Shrenik Shikhare 
> 
> There is a race condition for acquiring rx_proc_lock between
> rx worker thread and USB RX data interrupt
> (mwifiex_usb_rx_complete):
> 
> 1. USB receives an RX data interrupt, queues rx_work
> 2. rx_work empties rx_data_q, tries to acquire rx_proc_lock (to
> clear rx_processing flag)
> 3. While #2 is yet to acquire rx_proc_lock, driver receives
> continuous RX data interupts(mwifiex_usb_rx_complete)
> 3. For each interrupt at #3, driver acquires rx_proc_lock(it gets
> the lock since it is in interrupt context), tries to queue
> rx_work, but fails to do so since rx_processing is still set(#2)
> 4. When rx_pending exceeds HIGH_RX_PENDING, driver stops
> submitting URBs back to USB subsystem and thus firmware stops
> uploading RX data to driver
> 5. Now finally #2 will acquire rx_proc_lock, but because of #4,
> there are no further triggers to schedule rx_work again
> 
> The above scenario occurs in some platforms where the RX
> processing is comparitively slower. This results in RX stall in
> driver, command/TX timeouts in firmware. The above scenario is
> introduced after commit c7dbdcb2a4e1
> ("mwifiex: schedule rx_work on RX interrupt for USB")
> 
> To fix this set a new more_rx_task_flag whenever RX data callback
> is trying to schedule rx_work but rx_processing is not yet
> cleared. This will let the current rx_work(which was waiting for
> rx_proc_lock) to loopback and process newly arrived RX packets.
> 
> Signed-off-by: Cathy Luo 
> Signed-off-by: Ganapathi Bhat 

I can't find any commit with id c7dbdcb2a4e1, is it correct?

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

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



Re: [1/2] mwifiex: schedule rx_work on RX interrupt for USB

2018-01-24 Thread Kalle Valo
Ganapathi Bhat  wrote:

> From: Shrenik Shikhare 
> 
> There is race for data_received flag between main thread and
> RX data interrupt(mwifiex_usb_rx_complete()):
> 1. USB received an RX data interrupt, set data_received flag
> 2. main thread checks data_received, if set queues rx_work
> 3. rx worker thread independently start processing rx_data_q
> 4. rx work exits (once rx_data_q is empty)
> 5. main thread resets the data_received flag(after #2)
> 6. Now at the corner case there will be high RX data interrupts
> between #4 and #5
> 7. Driver stops submitting URBs to firmware, once rx_pending
> exceeds HIGH_RX_PENDING
> 8. The flag data_received(cleared in #5) will remain unset since
> there will be no interrupts from firmware to set it(after #7)
> 
> Above scenario causes RX stall in driver, which will finally
> result in command/TX timeouts in firmware.
> 
> As a fix, queue rx_work directly in mwifiex_usb_rx_complete()
> callback, instead in the main thread. This removes dependency
> of RX processing on data_received flag.
> 
> Signed-off-by: Cathy Luo 
> Signed-off-by: Ganapathi Bhat 

Brian, did you have a chance to review these two?

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

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



Re: [2/2] mwifiex: use more_rx_task_flag to avoid USB RX stall

2018-01-24 Thread Kalle Valo
Kalle Valo  writes:

> Ganapathi Bhat  wrote:
>
>> From: Shrenik Shikhare 
>> 
>> There is a race condition for acquiring rx_proc_lock between
>> rx worker thread and USB RX data interrupt
>> (mwifiex_usb_rx_complete):
>> 
>> 1. USB receives an RX data interrupt, queues rx_work
>> 2. rx_work empties rx_data_q, tries to acquire rx_proc_lock (to
>> clear rx_processing flag)
>> 3. While #2 is yet to acquire rx_proc_lock, driver receives
>> continuous RX data interupts(mwifiex_usb_rx_complete)
>> 3. For each interrupt at #3, driver acquires rx_proc_lock(it gets
>> the lock since it is in interrupt context), tries to queue
>> rx_work, but fails to do so since rx_processing is still set(#2)
>> 4. When rx_pending exceeds HIGH_RX_PENDING, driver stops
>> submitting URBs back to USB subsystem and thus firmware stops
>> uploading RX data to driver
>> 5. Now finally #2 will acquire rx_proc_lock, but because of #4,
>> there are no further triggers to schedule rx_work again
>> 
>> The above scenario occurs in some platforms where the RX
>> processing is comparitively slower. This results in RX stall in
>> driver, command/TX timeouts in firmware. The above scenario is
>> introduced after commit c7dbdcb2a4e1
>> ("mwifiex: schedule rx_work on RX interrupt for USB")
>> 
>> To fix this set a new more_rx_task_flag whenever RX data callback
>> is trying to schedule rx_work but rx_processing is not yet
>> cleared. This will let the current rx_work(which was waiting for
>> rx_proc_lock) to loopback and process newly arrived RX packets.
>> 
>> Signed-off-by: Cathy Luo 
>> Signed-off-by: Ganapathi Bhat 
>
> I can't find any commit with id c7dbdcb2a4e1, is it correct?

Oh, and please use Fixes line to mark the commit which broke this.

-- 
Kalle Valo


Re: [v2] wcn36xx: release resources in case of error

2018-01-24 Thread Kalle Valo
Ramon Fried  wrote:

> wcn36xx_dxe_init() doesn't check for the return value of
> wcn36xx_dxe_init_descs(), release the resources in case an error ocurred.
> 
> Signed-off-by: Ramon Fried 
> Signed-off-by: Kalle Valo 

Patch applied to ath-next branch of ath.git, thanks.

d0bb950b9f5f wcn36xx: release DMA memory in case of error

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

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



Re: [v2,1/4] ath9k: Alternative EEPROM size for AR9003

2018-01-24 Thread Kalle Valo
Wojciech Dubowik  wrote:

> AR9003 factory calibration allows to use bigger EEPROM than
> standard 1k without changing the default layout. Allow
> probing of EEPROM at alternative address if initial check
> for default fails.
> The original ar9003 eeprom ops are still be used.
> 
> Signed-off-by: Wojciech Dubowik 
> Signed-off-by: Kalle Valo 

4 patches applied to ath-next branch of ath.git, thanks.

528782ecf59f ath9k: Alternative EEPROM size for AR9003
34d4fcd8813a ath9k: Read noise floor calibration data from eeprom
8da58553cc63 ath9k: Use calibrated noise floor value when available
3717957ce55c ath9k: Display calibration data piers in debugfs

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

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



Re: [v2,1/8] wil6210: add Talyn PCIe device ID

2018-01-24 Thread Kalle Valo
Maya Erez  wrote:

> PCIe device ID has changed in Talyn.
> Add this ID to wil6210_pcie_ids list to allow
> recognition of Talyn device.
> 
> Signed-off-by: Maya Erez 
> Signed-off-by: Kalle Valo 

8 patches applied to ath-next branch of ath.git, thanks.

10cd2d45f6c7 wil6210: add Talyn PCIe device ID
4fe1fccecf87 wil6210: recognize Talyn JTAG ID
4276d7711e7c wil6210: add support for Talyn AHB address map
2a0efe6a32ac wil6210: support flashless device
b8e13b87b15d wil6210: configure OTP HW vectors in SW reset flow
70bcc658c0b1 wil6210: fix random failure to bring network interface up
54fca595d1ee wil6210: enlarge FW mac_rgf_ext section for Sparrow D0
81b35afa49c8 wil6210: support parsing brd file address from fw file

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

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



Re: ath9k: discard undersized packets

2018-01-24 Thread Kalle Valo
Felix Fietkau  wrote:

> Sometimes the hardware will push small packets that trigger a WARN_ON
> in mac80211. Discard them early to avoid this issue.
> 
> Reported-by: Stijn Tintel 
> Signed-off-by: Felix Fietkau 
> Signed-off-by: Kalle Valo 

Patch applied to ath-next branch of ath.git, thanks.

3c0efb745a17 ath9k: discard undersized packets

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

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



Re: [mac80211-next:master 3/5] net//wireless/wext-compat.c:1351:9: warning: function returns address of local variable

2018-01-24 Thread Pkshih
On Mon, 2018-01-22 at 13:00 +, kbuild test robot wrote:
> tree:   https://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next.gi
> t master
> head:   076dc671ee9fa374e77c3d05925dafb75b23a74c
> commit: c179e91512cab01e83be35a60eaeda0f170a9101 [3/5] cfg80211: wext: don't
> use static struct
> config: x86_64-randconfig-x016-01221834 (attached as .config)
> compiler: gcc-7 (Debian 7.2.0-12) 7.2.1 20171025
> reproduce:
> git checkout c179e91512cab01e83be35a60eaeda0f170a9101
> # save the attached .config to linux build tree
> make ARCH=x86_64 
> 
> All warnings (new ones prefixed by >>):
> 
>net//wireless/wext-compat.c: In function 'cfg80211_wireless_stats':
> >> net//wireless/wext-compat.c:1351:9: warning: function returns address of
> local variable [-Wreturn-local-addr]
>  return 
> ^~~
> 

Hi Johannes,

In commit c179e9151, you remove 'static' from struct, but function return the
address of local variable as kbuild robot mentioned. It is a problem, but
my prior experiment looks fine. Hence, I check the callers of 
get_wireless_stats(),
and found they use the address that points to stack immediately, so content of
stack wasn't broken luckily.

So, please recall the 'static' of 'struct iw_statistics wstats'.
Thanks
PK



[PATCH v2] rtlwifi: btcoex: Fix some static warnings from Sparse

2018-01-24 Thread pkshih
From: Ping-Ke Shih 

Add 'static' or declaration to resolve the warnings, and remove two unused
functions halbtc_set_macreg() and halbtc_get_macreg() exposed when they
were made static.

Signed-off-by: Ping-Ke Shih 
---
The original subject of this patch is '[PATCH 07/10]' in previous
patchset, and other patches are applied excepcting to this one that Larry
suggested to add comments why two functions are revmoed, but the content is
unchanged.
---
 .../realtek/rtlwifi/btcoexist/halbtcoutsrc.c   | 36 +++---
 .../realtek/rtlwifi/btcoexist/halbtcoutsrc.h   |  4 +++
 2 files changed, 15 insertions(+), 25 deletions(-)

diff --git a/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtcoutsrc.c 
b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtcoutsrc.c
index 73ef5b271f3b..1404729441a2 100644
--- a/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtcoutsrc.c
+++ b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtcoutsrc.c
@@ -29,7 +29,7 @@
  * Debug related function
  ***/
 
-const char *const gl_btc_wifi_bw_string[] = {
+static const char *const gl_btc_wifi_bw_string[] = {
"11bg",
"HT20",
"HT40",
@@ -37,7 +37,7 @@ const char *const gl_btc_wifi_bw_string[] = {
"HT160"
 };
 
-const char *const gl_btc_wifi_freq_string[] = {
+static const char *const gl_btc_wifi_freq_string[] = {
"2.4G",
"5G"
 };
@@ -156,7 +156,7 @@ static u8 halbtc_get_wifi_central_chnl(struct btc_coexist 
*btcoexist)
return chnl;
 }
 
-u8 rtl_get_hwpg_single_ant_path(struct rtl_priv *rtlpriv)
+static u8 rtl_get_hwpg_single_ant_path(struct rtl_priv *rtlpriv)
 {
struct rtl_mod_params *mod_params = rtlpriv->cfg->mod_params;
 
@@ -171,12 +171,12 @@ u8 rtl_get_hwpg_single_ant_path(struct rtl_priv *rtlpriv)
return rtlpriv->btcoexist.btc_info.single_ant_path;
 }
 
-u8 rtl_get_hwpg_bt_type(struct rtl_priv *rtlpriv)
+static u8 rtl_get_hwpg_bt_type(struct rtl_priv *rtlpriv)
 {
return rtlpriv->btcoexist.btc_info.bt_type;
 }
 
-u8 rtl_get_hwpg_ant_num(struct rtl_priv *rtlpriv)
+static u8 rtl_get_hwpg_ant_num(struct rtl_priv *rtlpriv)
 {
struct rtl_mod_params *mod_params = rtlpriv->cfg->mod_params;
u8 num;
@@ -193,7 +193,7 @@ u8 rtl_get_hwpg_ant_num(struct rtl_priv *rtlpriv)
return num;
 }
 
-u8 rtl_get_hwpg_package_type(struct rtl_priv *rtlpriv)
+static u8 rtl_get_hwpg_package_type(struct rtl_priv *rtlpriv)
 {
struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
 
@@ -504,7 +504,7 @@ static u32 halbtc_get_bt_forbidden_slot_val(void 
*btc_context)
return btcoexist->bt_info.bt_forb_slot_val;
 }
 
-u32 halbtc_get_wifi_link_status(struct btc_coexist *btcoexist)
+static u32 halbtc_get_wifi_link_status(struct btc_coexist *btcoexist)
 {
/* return value:
 * [31:16] => connected port number
@@ -980,7 +980,8 @@ static void halbtc_write_4byte(void *bt_context, u32 
reg_addr, u32 data)
rtl_write_dword(rtlpriv, reg_addr, data);
 }
 
-void halbtc_write_local_reg_1byte(void *btc_context, u32 reg_addr, u8 data)
+static void halbtc_write_local_reg_1byte(void *btc_context, u32 reg_addr,
+u8 data)
 {
struct btc_coexist *btcoexist = (struct btc_coexist *)btc_context;
struct rtl_priv *rtlpriv = btcoexist->adapter;
@@ -993,22 +994,6 @@ void halbtc_write_local_reg_1byte(void *btc_context, u32 
reg_addr, u8 data)
rtl_write_byte(rtlpriv, reg_addr, data);
 }
 
-void halbtc_set_macreg(void *btc_context, u32 reg_addr, u32 bit_mask, u32 data)
-{
-   struct btc_coexist *btcoexist = (struct btc_coexist *)btc_context;
-   struct rtl_priv *rtlpriv = btcoexist->adapter;
-
-   rtl_set_bbreg(rtlpriv->mac80211.hw, reg_addr, bit_mask, data);
-}
-
-u32 halbtc_get_macreg(void *btc_context, u32 reg_addr, u32 bit_mask)
-{
-   struct btc_coexist *btcoexist = (struct btc_coexist *)btc_context;
-   struct rtl_priv *rtlpriv = btcoexist->adapter;
-
-   return rtl_get_bbreg(rtlpriv->mac80211.hw, reg_addr, bit_mask);
-}
-
 static void halbtc_set_bbreg(void *bt_context, u32 reg_addr, u32 bit_mask,
 u32 data)
 {
@@ -1054,6 +1039,7 @@ static void halbtc_fill_h2c_cmd(void *bt_context, u8 
element_id,
cmd_len, cmd_buf);
 }
 
+static
 void halbtc_set_bt_reg(void *btc_context, u8 reg_type, u32 offset, u32 set_val)
 {
struct btc_coexist *btcoexist = (struct btc_coexist *)btc_context;
@@ -1093,7 +1079,7 @@ static void halbtc_display_dbg_msg(void *bt_context, u8 
disp_type,
}
 }
 
-bool halbtc_under_ips(struct btc_coexist *btcoexist)
+static bool halbtc_under_ips(struct btc_coexist *btcoexist)
 {
struct rtl_priv *rtlpriv = btcoexist->adapter;
struct rtl_ps_ctl *ppsc = rtl_psc(rtlpriv);
diff --git a/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtcoutsrc.h 

[PATCH v3] mac80211: mesh: fix wrong mesh TTL offset calculation

2018-01-24 Thread peter . oh
From: Peter Oh 

mesh TTL offset in Mesh Channel Switch Parameters element depends on
not only Secondary Channel Offset element, but also affected by
HT Control field and Wide Bandwidth Channel Switch element.
Use element structure to correct the miscalculation.

Signed-off-by: Peter Oh 
---
 net/mac80211/mesh.c | 17 ++---
 1 file changed, 6 insertions(+), 11 deletions(-)

diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index 73ac607..6a381cb 100644
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -1255,13 +1255,12 @@ int ieee80211_mesh_csa_beacon(struct 
ieee80211_sub_if_data *sdata,
 }
 
 static int mesh_fwd_csa_frame(struct ieee80211_sub_if_data *sdata,
-  struct ieee80211_mgmt *mgmt, size_t len)
+  struct ieee80211_mgmt *mgmt, size_t len,
+  struct ieee802_11_elems *elems)
 {
struct ieee80211_mgmt *mgmt_fwd;
struct sk_buff *skb;
struct ieee80211_local *local = sdata->local;
-   u8 *pos = mgmt->u.action.u.chan_switch.variable;
-   size_t offset_ttl;
 
skb = dev_alloc_skb(local->tx_headroom + len);
if (!skb)
@@ -1269,13 +1268,9 @@ static int mesh_fwd_csa_frame(struct 
ieee80211_sub_if_data *sdata,
skb_reserve(skb, local->tx_headroom);
mgmt_fwd = skb_put(skb, len);
 
-   /* offset_ttl is based on whether the secondary channel
-* offset is available or not. Subtract 1 from the mesh TTL
-* and disable the initiator flag before forwarding.
-*/
-   offset_ttl = (len < 42) ? 7 : 10;
-   *(pos + offset_ttl) -= 1;
-   *(pos + offset_ttl + 1) &= ~WLAN_EID_CHAN_SWITCH_PARAM_INITIATOR;
+   elems->mesh_chansw_params_ie->mesh_ttl--;
+   elems->mesh_chansw_params_ie->mesh_flags &=
+   ~WLAN_EID_CHAN_SWITCH_PARAM_INITIATOR;
 
memcpy(mgmt_fwd, mgmt, len);
eth_broadcast_addr(mgmt_fwd->da);
@@ -1323,7 +1318,7 @@ static void mesh_rx_csa_frame(struct 
ieee80211_sub_if_data *sdata,
 
/* forward or re-broadcast the CSA frame */
if (fwd_csa) {
-   if (mesh_fwd_csa_frame(sdata, mgmt, len) < 0)
+   if (mesh_fwd_csa_frame(sdata, mgmt, len, ) < 0)
mcsa_dbg(sdata, "Failed to forward the CSA frame");
}
 }
-- 
2.7.4



[PATCH] ath10k: Update the phymode along with bandwidth change request

2018-01-24 Thread ryanhsu
From: Ryan Hsu 

In the case of Station connects to AP with narrower bandwidth at beginning.
And later the AP changes the bandwidth to winder bandwidth, the AP will
beacon with wider bandwidth IE, eg VHT20->VHT40->VHT80 or VHT40->VHT80.

Since the supported BANDWIDTH will be limited by the PHYMODE, so while
Station receives the bandwidth change request, it will also need to
reconfigure the PHYMODE setting to firmware instead of just configuring
the BANDWIDTH info, otherwise it'll trigger a firmware crash with
non-support bandwidth.

The issue was observed in WLAN.RM.4.4.1-00051-QCARMSWP-1, QCA6174 with
below scenario.

--
AP xxx changed bandwidth, new config is 5200 MHz, width 2 (5190/0 MHz)
disconnect from AP xxx for new auth to yyy
RX ReassocResp from xxx (capab=0x status=0 aid=102)
associated



AP xxx changed bandwidth, new config is 5200 MHz, width 2 (5190/0 MHz)
AP xxx changed bandwidth, new config is 5200 MHz, width 3 (5210/0 MHz)



firmware register dump:
[00]: 0x0503 0x15B3 0x00987291 0x00955B31
[04]: 0x00987291 0x00060730 0x0004 0x0001
[08]: 0x004089F0 0x00955A00 0x000A0B00 0x0040
[12]: 0x0009 0x 0x00952CD0 0x00952CE6
[16]: 0x00952CC4 0x0098E25F 0x 0x0091080D
[20]: 0x40987291 0x0040E7A8 0x 0x0041EE3C
[24]: 0x809ABF05 0x0040E808 0x 0xC0987291
[28]: 0x809A650C 0x0040E948 0x0041FE40 0x004345C4
[32]: 0x809A5C63 0x0040E988 0x0040E9AC 0x0042D1A8
[36]: 0x8091D252 0x0040E9A8 0x0002 0x0001
[40]: 0x809FDA9D 0x0040EA58 0x0043D554 0x0042D554
[44]: 0x809F8B22 0x0040EA78 0x0043D554 0x0001
[48]: 0x80911210 0x0040EAC8 0x0010 0x004041D0
[52]: 0x80911154 0x0040EB28 0x0040 0x
[56]: 0x8091122D 0x0040EB48 0x 0x00400600
--

Reported-by: Rouven Czerwinski 
Signed-off-by: Ryan Hsu 
---
 drivers/net/wireless/ath/ath10k/mac.c | 16 ++--
 1 file changed, 14 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/mac.c 
b/drivers/net/wireless/ath/ath10k/mac.c
index ebb3f1b..68a5256 100644
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
@@ -1,6 +1,7 @@
 /*
  * Copyright (c) 2005-2011 Atheros Communications Inc.
  * Copyright (c) 2011-2017 Qualcomm Atheros, Inc.
+ * Copyright (c) 2018, The Linux Foundation. All rights reserved.
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -5996,8 +5997,18 @@ static void ath10k_sta_rc_update_wk(struct work_struct 
*wk)
   ath10k_mac_max_vht_nss(vht_mcs_mask)));
 
if (changed & IEEE80211_RC_BW_CHANGED) {
-   ath10k_dbg(ar, ATH10K_DBG_MAC, "mac update sta %pM peer bw 
%d\n",
-  sta->addr, bw);
+   mode = chan_to_phymode();
+
+   ath10k_dbg(ar, ATH10K_DBG_MAC, "mac update sta %pM peer bw %d 
phymode %d\n",
+  sta->addr, bw, mode);
+
+   err = ath10k_wmi_peer_set_param(ar, arvif->vdev_id, sta->addr,
+   WMI_PEER_PHYMODE, mode);
+   if (err) {
+   ath10k_warn(ar, "failed to update STA %pM peer phymode 
%d: %d\n",
+   sta->addr, mode, err);
+   goto exit;
+   }
 
err = ath10k_wmi_peer_set_param(ar, arvif->vdev_id, sta->addr,
WMI_PEER_CHAN_WIDTH, bw);
@@ -6039,6 +6050,7 @@ static void ath10k_sta_rc_update_wk(struct work_struct 
*wk)
sta->addr);
}
 
+exit:
mutex_unlock(>conf_mutex);
 }
 
-- 
1.9.1



Regulatory: reg.c : wiphy_apply_custom_regulatory()

2018-01-24 Thread Neelansh Mittal
Hello,

Can wiphy_apply_custom_regulatory() be called after wiphy registeration?
The documentation(comment) says "/* Used by drivers prior to wiphy
registration */"
Whys is there a restriction to call this after registration? Is the
comment outdated? After Tracing the regulatory code in the cfg80211,
it seems that there should be no restriction.

Regards
Neelansh


Re: [PATCH 8/8] mt76: validate rx CCMP PN

2018-01-24 Thread Felix Fietkau
On 2018-01-24 17:20, Johannes Berg wrote:
> On Wed, 2018-01-24 at 17:11 +0100, Felix Fietkau wrote:
>> 
>> I guess I will have to look into fragmentation. I have a second driver
>> pending that only reports the CCMP PN outside of the packet, and for
>> performance reasons I really don't want to translate it and move it to a
>> place where mac80211 can parse it.
>> I'm also looking into doing parallel rx in software to see if I can get
>> more performance that way. I think for that I would also need CCMP PN
>> validation in the driver.
> 
> Fair enough. We also do it, except we just decide that fragmented
> packets we don't care and can use mac80211 - but we get the PN in-
> frame, just can't always use mac80211 due to parallel RX.
I guess I could make the driver translate the header for fragmented
packets only.

- Felix


Re: [PATCH 8/8] mt76: validate rx CCMP PN

2018-01-24 Thread Johannes Berg
On Wed, 2018-01-24 at 17:11 +0100, Felix Fietkau wrote:
> 
> I guess I will have to look into fragmentation. I have a second driver
> pending that only reports the CCMP PN outside of the packet, and for
> performance reasons I really don't want to translate it and move it to a
> place where mac80211 can parse it.
> I'm also looking into doing parallel rx in software to see if I can get
> more performance that way. I think for that I would also need CCMP PN
> validation in the driver.

Fair enough. We also do it, except we just decide that fragmented
packets we don't care and can use mac80211 - but we get the PN in-
frame, just can't always use mac80211 due to parallel RX.

johannes


Re: [1/2] brcmfmac: assure bcdc dcmd api does not return value > 0

2018-01-24 Thread Kalle Valo
Arend Van Spriel  wrote:

> The protocol layer api defines callbacks for dongle commands.
> Although not really well documented these should only return an
> error code in case of an error, or 0 upon success. In the bcdc
> protocol it can return value above 0 and we carry a fix in the
> caller of the protocol layer api. This patch makes it adhere to
> the intent of the api as described above.
> 
> Reviewed-by: Hante Meuleman 
> Reviewed-by: Pieter-Paul Giesberts 
> Reviewed-by: Franky Lin 
> Signed-off-by: Arend van Spriel 

2 patches applied to wireless-drivers-next.git, thanks.

5242a5444e0b brcmfmac: assure bcdc dcmd api does not return value > 0
b69c1df47281 brcmfmac: separate firmware errors from i/o errors

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

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



Re: [01/11] qtnfmac: remove struct qlink_cmd_set_mac_acl

2018-01-24 Thread Kalle Valo
Sergey Matyukevich  wrote:

> From: Vasily Ulyanov 
> 
> TLV is used to pass ACL data to firmware in start_ap cfg80211 callback.
> Use the same approach in set_mac_acl cfg80211 callback.
> 
> Signed-off-by: Vasily Ulyanov 

11 patches applied to wireless-drivers-next.git, thanks.

33f9899234a2 qtnfmac: remove struct qlink_cmd_set_mac_acl
87affddef94e qtnfmac: fix warnings when mBSS setup is stopped
04b01affb824 qtnfmac: support 64-bit network interface stats
5ec5b532dabc qtnfmac: get more hardware info from card
0b419d0182bc qtnfmac: report hardware/firmware information via ethtool
537faf269d76 qtnfmac: modify supported interface combinations
01efff526235 qtnfmac: validate interface combinations on changes
39845020b39e qtnfmac: fix STA disconnect procedure
f2cddd5469b0 qtnfmac: do not use mutexes in timer context
237d29f6ce46 qtnfmac: do not use bus mutex for events processing
c93fe71c91d0 qtnfmac: remove redundant 'unlikely' checks

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

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



Re: [PATCH 8/8] mt76: validate rx CCMP PN

2018-01-24 Thread Johannes Berg
On Wed, 2018-01-24 at 16:19 +0100, Felix Fietkau wrote:
> Apparently hardware does not perform CCMP PN validation in hardware, so
> we need to take care of this in the driver. This is important for
> protecting against replay attacks
> 
> +static int
> +mt76_check_ccmp_pn(struct sk_buff *skb)
> +{
> + struct mt76_rx_status *status = (struct mt76_rx_status *) skb->cb;
> + struct mt76_wcid *wcid = status->wcid;
> + int ret;
> +
> + if (!(status->flag & RX_FLAG_DECRYPTED))
> + return 0;
> +
> + if (!wcid || !wcid->rx_check_pn)
> + return 0;
> +
> + BUILD_BUG_ON(sizeof(status->iv) != sizeof(wcid->rx_key_pn[0]));
> + ret = memcmp(status->iv, wcid->rx_key_pn[status->tid],
> +  sizeof(status->iv));
> + if (ret <= 0)
> + return -EINVAL; /* replay */
> +
> + memcpy(wcid->rx_key_pn[status->tid], status->iv, sizeof(status->iv));
> + status->flag |= RX_FLAG_PN_VALIDATED;

You shouldn't do this, try to somehow make it rely on mac80211 instead.

Otherwise, you really have to handle CCMP vs. fragmentation.

johannes


Re: rtl8xxxu: Fix trailing semicolon

2018-01-24 Thread Kalle Valo
Luis de Bethencourt  wrote:

> The trailing semicolon is an empty statement that does no operation.
> Removing it since it doesn't do anything.
> 
> Signed-off-by: Luis de Bethencourt 
> Acked-by: Jes Sorensen 

Patch applied to wireless-drivers-next.git, thanks.

8054a275de08 rtl8xxxu: Fix trailing semicolon

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

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



Re: [PATCH 10/10] rtlwifi: Add spec_ver to check whether use new rate-id or not

2018-01-24 Thread Kalle Valo
Pkshih  writes:

> On Mon, 2018-01-22 at 13:10 -0600, Larry Finger wrote:
>> On 01/19/2018 12:45 AM, pks...@realtek.com wrote:
>> > 
>> > From: Ping-Ke Shih 
>> > 
>> > The field spec_ver is IC's specification mask for common code to do proper
>> > process to specified IC. This commit add a field new rate ID for new
>> > generation IC.
>> > 
>> > Signed-off-by: Ping-Ke Shih 
>> Acked-by: Larry Finger 
>> 
>
> Shall I append "Acked-by" in v2?

Yes, you can add Acked-by in the next version (if the patch in question
is not modified after the ack).

But do note that patchwork can automatically take Acked-by from the
mailing list, for example that happened in the 9 patches I just applied
from this series. So you no need to resend the rtlwifi patches for just
to add the Acked-by line.

-- 
Kalle Valo


Re: [01/10] rtlwifi: btcoex: extend get_wifi_bw to support bandwidth 80M

2018-01-24 Thread Kalle Valo
Ping-Ke Shih  wrote:

> From: Ping-Ke Shih 
> 
> The rtlwifi newer ICs support 80M bandwidth in 5G band, so extend
> get_wifi_bw() to know bandwidth 80M that helps btcoex to make correct
> decisions.
> 
> Signed-off-by: Ping-Ke Shih 
> Acked-by: Larry Finger 

9 patches applied to wireless-drivers-next.git, thanks.

66d0f9deba36 rtlwifi: btcoex: extend get_wifi_bw to support bandwidth 80M
17bf85101181 rtlwifi: btcoex: Add switch band notify for btc
f243bca13893 rtlwifi: btcoex: Add variable ant_div_cfg to support antenna 
diversity
ee373844849c rtlwifi: btcoex: add scan_notify within ips_notify if RFON
9177c3363994 rtlwifi: btcoex: Add wifi_only series ops to control solo card
8d73e53e8a87 rtlwifi: btcoex: add boolean variables dbg_mode
ba3cca4d0c3e rtlwifi: 8822be has to report vht capability to mac80211
be98db155646 rtlwifi: Add ratr_table for newer IC
a75f3eebfa3d rtlwifi: Add spec_ver to check whether use new rate-id or not

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

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



Re: [07/10] rtlwifi: btcoex: Fix some static warnings from Sparse

2018-01-24 Thread Kalle Valo
Ping-Ke Shih  wrote:

> From: Ping-Ke Shih 
> 
> Add 'static' or declaration to resolve the warnings.
> 
> Signed-off-by: Ping-Ke Shih 

Dropping this patch 7 per comments, but I'll try to take the rest (if
they apply).

Patch set to Changes Requested.

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

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



[PATCH 1/8] mt76: retry rx polling as long as there is budget left

2018-01-24 Thread Felix Fietkau
Sending frames to mac80211 needs time, which could allow for more rx
packets to end up in the DMA ring. Retry polling until there are no more
frames left. Improves rx latency under load.

Signed-off-by: Felix Fietkau 
---
 drivers/net/wireless/mediatek/mt76/dma.c | 10 +++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/dma.c 
b/drivers/net/wireless/mediatek/mt76/dma.c
index ecd409a4a89b..e539b3838b94 100644
--- a/drivers/net/wireless/mediatek/mt76/dma.c
+++ b/drivers/net/wireless/mediatek/mt76/dma.c
@@ -387,17 +387,21 @@ static int
 mt76_dma_rx_poll(struct napi_struct *napi, int budget)
 {
struct mt76_dev *dev;
-   int qid, done;
+   int qid, done = 0, cur;
 
dev = container_of(napi->dev, struct mt76_dev, napi_dev);
qid = napi - dev->napi;
 
-   done = mt76_dma_rx_process(dev, >q_rx[qid], budget);
+   do {
+   cur = mt76_dma_rx_process(dev, >q_rx[qid], budget - done);
+   mt76_rx_complete(dev, qid);
+   done += cur;
+   } while (cur && done < budget);
+
if (done < budget) {
napi_complete(napi);
dev->drv->rx_poll_complete(dev, qid);
}
-   mt76_rx_complete(dev, qid);
 
return done;
 }
-- 
2.14.2



[PATCH 8/8] mt76: validate rx CCMP PN

2018-01-24 Thread Felix Fietkau
Apparently hardware does not perform CCMP PN validation in hardware, so
we need to take care of this in the driver. This is important for
protecting against replay attacks

Signed-off-by: Felix Fietkau 
---
 drivers/net/wireless/mediatek/mt76/mac80211.c| 51 
 drivers/net/wireless/mediatek/mt76/mt76.h| 12 +-
 drivers/net/wireless/mediatek/mt76/mt76x2_init.c |  2 +-
 drivers/net/wireless/mediatek/mt76/mt76x2_mac.c  | 45 -
 drivers/net/wireless/mediatek/mt76/mt76x2_main.c |  1 +
 5 files changed, 98 insertions(+), 13 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mac80211.c 
b/drivers/net/wireless/mediatek/mt76/mac80211.c
index 77f1be161009..c203e7b48c58 100644
--- a/drivers/net/wireless/mediatek/mt76/mac80211.c
+++ b/drivers/net/wireless/mediatek/mt76/mac80211.c
@@ -384,6 +384,27 @@ int mt76_get_survey(struct ieee80211_hw *hw, int idx,
 }
 EXPORT_SYMBOL_GPL(mt76_get_survey);
 
+void mt76_wcid_key_setup(struct mt76_dev *dev, struct mt76_wcid *wcid,
+struct ieee80211_key_conf *key)
+{
+   struct ieee80211_key_seq seq;
+   int i;
+
+   wcid->rx_check_pn = false;
+
+   if (!key)
+   return;
+
+   if (key->cipher == WLAN_CIPHER_SUITE_CCMP)
+   wcid->rx_check_pn = true;
+
+   for (i = 0; i < IEEE80211_NUM_TIDS; i++) {
+   ieee80211_get_key_rx_seq(key, i, );
+   memcpy(wcid->rx_key_pn[i], seq.ccmp.pn, sizeof(seq.ccmp.pn));
+   }
+}
+EXPORT_SYMBOL(mt76_wcid_key_setup);
+
 static struct ieee80211_sta *mt76_rx_convert(struct sk_buff *skb)
 {
struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
@@ -410,6 +431,31 @@ static struct ieee80211_sta *mt76_rx_convert(struct 
sk_buff *skb)
return wcid_to_sta(mstat.wcid);
 }
 
+static int
+mt76_check_ccmp_pn(struct sk_buff *skb)
+{
+   struct mt76_rx_status *status = (struct mt76_rx_status *) skb->cb;
+   struct mt76_wcid *wcid = status->wcid;
+   int ret;
+
+   if (!(status->flag & RX_FLAG_DECRYPTED))
+   return 0;
+
+   if (!wcid || !wcid->rx_check_pn)
+   return 0;
+
+   BUILD_BUG_ON(sizeof(status->iv) != sizeof(wcid->rx_key_pn[0]));
+   ret = memcmp(status->iv, wcid->rx_key_pn[status->tid],
+sizeof(status->iv));
+   if (ret <= 0)
+   return -EINVAL; /* replay */
+
+   memcpy(wcid->rx_key_pn[status->tid], status->iv, sizeof(status->iv));
+   status->flag |= RX_FLAG_PN_VALIDATED;
+
+   return 0;
+}
+
 void mt76_rx_complete(struct mt76_dev *dev, struct sk_buff_head *frames,
  int queue)
 {
@@ -421,6 +467,11 @@ void mt76_rx_complete(struct mt76_dev *dev, struct 
sk_buff_head *frames,
napi = >napi[queue];
 
while ((skb = __skb_dequeue(frames)) != NULL) {
+   if (mt76_check_ccmp_pn(skb)) {
+   dev_kfree_skb(skb);
+   continue;
+   }
+
sta = mt76_rx_convert(skb);
ieee80211_rx_napi(dev->hw, sta, skb, napi);
}
diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h 
b/drivers/net/wireless/mediatek/mt76/mt76.h
index af98bc65c2e1..129015c9d116 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76.h
@@ -131,6 +131,9 @@ struct mt76_wcid {
 
u8 sta:1;
 
+   u8 rx_check_pn;
+   u8 rx_key_pn[IEEE80211_NUM_TIDS][6];
+
__le16 tx_rate;
bool tx_rate_set;
u8 tx_rate_nss;
@@ -279,12 +282,14 @@ struct mt76_rx_status {
 
unsigned long reorder_time;
 
-   u8 aggr;
+   u8 iv[6];
+
+   u8 aggr:1;
u8 tid;
u16 seqno;
 
-   u32 flag;
u16 freq;
+   u32 flag;
u8 enc_flags;
u8 encoding:2, bw:3;
u8 rate_idx;
@@ -413,6 +418,9 @@ int mt76_rx_aggr_start(struct mt76_dev *dev, struct 
mt76_wcid *wcid, u8 tid,
   u16 ssn, u8 size);
 void mt76_rx_aggr_stop(struct mt76_dev *dev, struct mt76_wcid *wcid, u8 tid);
 
+void mt76_wcid_key_setup(struct mt76_dev *dev, struct mt76_wcid *wcid,
+struct ieee80211_key_conf *key);
+
 /* internal */
 void mt76_tx_free(struct mt76_dev *dev);
 void mt76_put_txwi(struct mt76_dev *dev, struct mt76_txwi_cache *t);
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_init.c 
b/drivers/net/wireless/mediatek/mt76/mt76x2_init.c
index 1e34b578b151..1b00ae4465a2 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x2_init.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x2_init.c
@@ -131,7 +131,7 @@ mt76_write_mac_initvals(struct mt76x2_dev *dev)
{ MT_RX_FILTR_CFG,  0x00015f97 },
{ MT_LEGACY_BASIC_RATE, 0x017f },
{ MT_HT_BASIC_RATE, 0x4003 },
-   { MT_PN_PAD_MODE,   0x0002 },
+   { MT_PN_PAD_MODE,   

[PATCH 3/8] mt76: add an intermediate struct for rx status information

2018-01-24 Thread Felix Fietkau
Preparation for passing in more internal rx data via skb->cb

Signed-off-by: Felix Fietkau 
---
 drivers/net/wireless/mediatek/mt76/mac80211.c   | 29 -
 drivers/net/wireless/mediatek/mt76/mt76.h   | 13 +++
 drivers/net/wireless/mediatek/mt76/mt76x2_mac.c |  4 ++--
 3 files changed, 43 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mac80211.c 
b/drivers/net/wireless/mediatek/mt76/mac80211.c
index 3acf0e175d71..258d2623d1bf 100644
--- a/drivers/net/wireless/mediatek/mt76/mac80211.c
+++ b/drivers/net/wireless/mediatek/mt76/mac80211.c
@@ -384,10 +384,37 @@ int mt76_get_survey(struct ieee80211_hw *hw, int idx,
 }
 EXPORT_SYMBOL_GPL(mt76_get_survey);
 
+static void
+mt76_rx_convert(struct sk_buff *skb)
+{
+   struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
+   struct mt76_rx_status mstat;
+
+   mstat = *((struct mt76_rx_status *) skb->cb);
+   memset(status, 0, sizeof(*status));
+
+   status->flag = mstat.flag;
+   status->freq = mstat.freq;
+   status->enc_flags = mstat.enc_flags;
+   status->encoding = mstat.encoding;
+   status->bw = mstat.bw;
+   status->rate_idx = mstat.rate_idx;
+   status->nss = mstat.nss;
+   status->band = mstat.band;
+   status->signal = mstat.signal;
+   status->chains = mstat.chains;
+
+   BUILD_BUG_ON(sizeof(mstat) > sizeof(skb->cb));
+   BUILD_BUG_ON(sizeof(status->chain_signal) != 
sizeof(mstat.chain_signal));
+   memcpy(status->chain_signal, mstat.chain_signal, 
sizeof(mstat.chain_signal));
+}
+
 void mt76_rx_complete(struct mt76_dev *dev, enum mt76_rxq_id q)
 {
struct sk_buff *skb;
 
-   while ((skb = __skb_dequeue(>rx_skb[q])) != NULL)
+   while ((skb = __skb_dequeue(>rx_skb[q])) != NULL) {
+   mt76_rx_convert(skb);
ieee80211_rx_napi(dev->hw, NULL, skb, >napi[q]);
+   }
 }
diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h 
b/drivers/net/wireless/mediatek/mt76/mt76.h
index f88d9a15210a..be4846ee4828 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76.h
@@ -250,6 +250,19 @@ struct mt76_rate_power {
};
 };
 
+struct mt76_rx_status {
+   u32 flag;
+   u16 freq;
+   u8 enc_flags;
+   u8 encoding:2, bw:3;
+   u8 rate_idx;
+   u8 nss;
+   u8 band;
+   u8 signal;
+   u8 chains;
+   s8 chain_signal[IEEE80211_MAX_CHAINS];
+};
+
 #define mt76_rr(dev, ...)  (dev)->mt76.bus->rr(&((dev)->mt76), __VA_ARGS__)
 #define mt76_wr(dev, ...)  (dev)->mt76.bus->wr(&((dev)->mt76), __VA_ARGS__)
 #define mt76_rmw(dev, ...) (dev)->mt76.bus->rmw(&((dev)->mt76), 
__VA_ARGS__)
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_mac.c 
b/drivers/net/wireless/mediatek/mt76/mt76x2_mac.c
index 98219b971463..2e12fc0d5c9e 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x2_mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x2_mac.c
@@ -29,7 +29,7 @@ void mt76x2_mac_set_bssid(struct mt76x2_dev *dev, u8 idx, 
const u8 *addr)
 }
 
 static int
-mt76x2_mac_process_rate(struct ieee80211_rx_status *status, u16 rate)
+mt76x2_mac_process_rate(struct mt76_rx_status *status, u16 rate)
 {
u8 idx = FIELD_GET(MT_RXWI_RATE_INDEX, rate);
 
@@ -268,7 +268,7 @@ static void mt76x2_remove_hdr_pad(struct sk_buff *skb)
 int mt76x2_mac_process_rx(struct mt76x2_dev *dev, struct sk_buff *skb,
  void *rxi)
 {
-   struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
+   struct mt76_rx_status *status = (struct mt76_rx_status *) skb->cb;
struct mt76x2_rxwi *rxwi = rxi;
u32 ctl = le32_to_cpu(rxwi->ctl);
u16 rate = le16_to_cpu(rxwi->rate);
-- 
2.14.2



[PATCH 6/8] mt76: split mt76_rx_complete

2018-01-24 Thread Felix Fietkau
Add a separate function for processing frames after A-MPDU reordering,
reduce code duplication

Signed-off-by: Felix Fietkau 
---
 drivers/net/wireless/mediatek/mt76/agg-rx.c   |  8 +---
 drivers/net/wireless/mediatek/mt76/dma.c  |  2 +-
 drivers/net/wireless/mediatek/mt76/mac80211.c | 24 ++--
 drivers/net/wireless/mediatek/mt76/mt76.h |  5 +++--
 4 files changed, 23 insertions(+), 16 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/agg-rx.c 
b/drivers/net/wireless/mediatek/mt76/agg-rx.c
index ecd0bcd149e5..8027bb7c03c2 100644
--- a/drivers/net/wireless/mediatek/mt76/agg-rx.c
+++ b/drivers/net/wireless/mediatek/mt76/agg-rx.c
@@ -97,9 +97,7 @@ mt76_rx_aggr_reorder_work(struct work_struct *work)
struct mt76_rx_tid *tid = container_of(work, struct mt76_rx_tid,
   reorder_work.work);
struct mt76_dev *dev = tid->dev;
-   struct ieee80211_sta *sta;
struct sk_buff_head frames;
-   struct sk_buff *skb;
 
__skb_queue_head_init();
 
@@ -110,11 +108,7 @@ mt76_rx_aggr_reorder_work(struct work_struct *work)
spin_unlock(>lock);
 
ieee80211_queue_delayed_work(tid->dev->hw, >reorder_work, 
REORDER_TIMEOUT);
-
-   while ((skb = __skb_dequeue()) != NULL) {
-   sta = mt76_rx_convert(skb);
-   ieee80211_rx_napi(dev->hw, sta, skb, NULL);
-   }
+   mt76_rx_complete(dev, , -1);
 
local_bh_enable();
 }
diff --git a/drivers/net/wireless/mediatek/mt76/dma.c 
b/drivers/net/wireless/mediatek/mt76/dma.c
index fd8bea144973..3518703524e7 100644
--- a/drivers/net/wireless/mediatek/mt76/dma.c
+++ b/drivers/net/wireless/mediatek/mt76/dma.c
@@ -396,7 +396,7 @@ mt76_dma_rx_poll(struct napi_struct *napi, int budget)
 
do {
cur = mt76_dma_rx_process(dev, >q_rx[qid], budget - done);
-   mt76_rx_complete(dev, qid);
+   mt76_rx_poll_complete(dev, qid);
done += cur;
} while (cur && done < budget);
 
diff --git a/drivers/net/wireless/mediatek/mt76/mac80211.c 
b/drivers/net/wireless/mediatek/mt76/mac80211.c
index 5978e5b0a2fe..77f1be161009 100644
--- a/drivers/net/wireless/mediatek/mt76/mac80211.c
+++ b/drivers/net/wireless/mediatek/mt76/mac80211.c
@@ -384,7 +384,7 @@ int mt76_get_survey(struct ieee80211_hw *hw, int idx,
 }
 EXPORT_SYMBOL_GPL(mt76_get_survey);
 
-struct ieee80211_sta *mt76_rx_convert(struct sk_buff *skb)
+static struct ieee80211_sta *mt76_rx_convert(struct sk_buff *skb)
 {
struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
struct mt76_rx_status mstat;
@@ -410,9 +410,24 @@ struct ieee80211_sta *mt76_rx_convert(struct sk_buff *skb)
return wcid_to_sta(mstat.wcid);
 }
 
-void mt76_rx_complete(struct mt76_dev *dev, enum mt76_rxq_id q)
+void mt76_rx_complete(struct mt76_dev *dev, struct sk_buff_head *frames,
+ int queue)
 {
+   struct napi_struct *napi = NULL;
struct ieee80211_sta *sta;
+   struct sk_buff *skb;
+
+   if (queue >= 0)
+   napi = >napi[queue];
+
+   while ((skb = __skb_dequeue(frames)) != NULL) {
+   sta = mt76_rx_convert(skb);
+   ieee80211_rx_napi(dev->hw, sta, skb, napi);
+   }
+}
+
+void mt76_rx_poll_complete(struct mt76_dev *dev, enum mt76_rxq_id q)
+{
struct sk_buff_head frames;
struct sk_buff *skb;
 
@@ -421,8 +436,5 @@ void mt76_rx_complete(struct mt76_dev *dev, enum 
mt76_rxq_id q)
while ((skb = __skb_dequeue(>rx_skb[q])) != NULL)
mt76_rx_aggr_reorder(skb, );
 
-   while ((skb = __skb_dequeue()) != NULL) {
-   sta = mt76_rx_convert(skb);
-   ieee80211_rx_napi(dev->hw, sta, skb, >napi[q]);
-   }
+   mt76_rx_complete(dev, , q);
 }
diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h 
b/drivers/net/wireless/mediatek/mt76/mt76.h
index cde199ed3f57..af98bc65c2e1 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76.h
@@ -416,8 +416,9 @@ void mt76_rx_aggr_stop(struct mt76_dev *dev, struct 
mt76_wcid *wcid, u8 tid);
 /* internal */
 void mt76_tx_free(struct mt76_dev *dev);
 void mt76_put_txwi(struct mt76_dev *dev, struct mt76_txwi_cache *t);
-void mt76_rx_complete(struct mt76_dev *dev, enum mt76_rxq_id q);
+void mt76_rx_complete(struct mt76_dev *dev, struct sk_buff_head *frames,
+ int queue);
+void mt76_rx_poll_complete(struct mt76_dev *dev, enum mt76_rxq_id q);
 void mt76_rx_aggr_reorder(struct sk_buff *skb, struct sk_buff_head *frames);
-struct ieee80211_sta *mt76_rx_convert(struct sk_buff *skb);
 
 #endif
-- 
2.14.2



[PATCH 7/8] mt76: pass the per-vif wcid to the core for multicast rx

2018-01-24 Thread Felix Fietkau
Preparation for adding software rx CCMP PN validation

Signed-off-by: Felix Fietkau 
---
 drivers/net/wireless/mediatek/mt76/mt76x2.h  |  1 +
 drivers/net/wireless/mediatek/mt76/mt76x2_mac.c  | 15 ---
 drivers/net/wireless/mediatek/mt76/mt76x2_main.c |  1 +
 3 files changed, 14 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2.h 
b/drivers/net/wireless/mediatek/mt76/mt76x2.h
index a12dfce8c0d1..17df17afd9bf 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x2.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76x2.h
@@ -144,6 +144,7 @@ struct mt76x2_vif {
 struct mt76x2_sta {
struct mt76_wcid wcid; /* must be first */
 
+   struct mt76x2_vif *vif;
struct mt76x2_tx_status status;
int n_frames;
 };
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_mac.c 
b/drivers/net/wireless/mediatek/mt76/mt76x2_mac.c
index b96d8a88656c..f56a8f459fe6 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x2_mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x2_mac.c
@@ -266,12 +266,20 @@ static void mt76x2_remove_hdr_pad(struct sk_buff *skb)
 }
 
 static struct mt76_wcid *
-mt76x2_rx_get_wcid(struct mt76x2_dev *dev, u8 idx)
+mt76x2_rx_get_sta_wcid(struct mt76x2_dev *dev, u8 idx, bool unicast)
 {
+   struct mt76x2_sta *sta;
+   struct mt76_wcid *wcid;
+
if (idx >= ARRAY_SIZE(dev->wcid))
return NULL;
 
-   return rcu_dereference(dev->wcid[idx]);
+   wcid = rcu_dereference(dev->wcid[idx]);
+   if (unicast || !wcid)
+   return wcid;
+
+   sta = container_of(wcid, struct mt76x2_sta, wcid);
+   return >vif->group_wcid;
 }
 
 int mt76x2_mac_process_rx(struct mt76x2_dev *dev, struct sk_buff *skb,
@@ -282,11 +290,12 @@ int mt76x2_mac_process_rx(struct mt76x2_dev *dev, struct 
sk_buff *skb,
u32 ctl = le32_to_cpu(rxwi->ctl);
u16 rate = le16_to_cpu(rxwi->rate);
u16 tid_sn = le16_to_cpu(rxwi->tid_sn);
+   bool unicast = rxwi->rxinfo & cpu_to_le32(MT_RXINFO_UNICAST);
u8 wcid;
int len;
 
wcid = FIELD_GET(MT_RXWI_CTL_WCID, ctl);
-   status->wcid = mt76x2_rx_get_wcid(dev, wcid);
+   status->wcid = mt76x2_rx_get_sta_wcid(dev, wcid, unicast);
 
if (rxwi->rxinfo & cpu_to_le32(MT_RXINFO_L2PAD))
mt76x2_remove_hdr_pad(skb);
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_main.c 
b/drivers/net/wireless/mediatek/mt76/mt76x2_main.c
index bc08040123b9..08fe804c6a43 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x2_main.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x2_main.c
@@ -273,6 +273,7 @@ mt76x2_sta_add(struct ieee80211_hw *hw, struct 
ieee80211_vif *vif,
goto out;
}
 
+   msta->vif = mvif;
msta->wcid.sta = 1;
msta->wcid.idx = idx;
msta->wcid.hw_key_idx = -1;
-- 
2.14.2



[PATCH 4/8] mt76: get station pointer by wcid and pass it to mac80211

2018-01-24 Thread Felix Fietkau
Avoids the rhashtable lookup based on the MAC address inside mac80211

Signed-off-by: Felix Fietkau 
---
 drivers/net/wireless/mediatek/mt76/dma.c |  4 
 drivers/net/wireless/mediatek/mt76/mac80211.c|  9 ++---
 drivers/net/wireless/mediatek/mt76/mt76.h| 14 ++
 drivers/net/wireless/mediatek/mt76/mt76x2_mac.c  | 13 +
 drivers/net/wireless/mediatek/mt76/mt76x2_main.c |  1 +
 5 files changed, 38 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/dma.c 
b/drivers/net/wireless/mediatek/mt76/dma.c
index e539b3838b94..fd8bea144973 100644
--- a/drivers/net/wireless/mediatek/mt76/dma.c
+++ b/drivers/net/wireless/mediatek/mt76/dma.c
@@ -392,12 +392,16 @@ mt76_dma_rx_poll(struct napi_struct *napi, int budget)
dev = container_of(napi->dev, struct mt76_dev, napi_dev);
qid = napi - dev->napi;
 
+   rcu_read_lock();
+
do {
cur = mt76_dma_rx_process(dev, >q_rx[qid], budget - done);
mt76_rx_complete(dev, qid);
done += cur;
} while (cur && done < budget);
 
+   rcu_read_unlock();
+
if (done < budget) {
napi_complete(napi);
dev->drv->rx_poll_complete(dev, qid);
diff --git a/drivers/net/wireless/mediatek/mt76/mac80211.c 
b/drivers/net/wireless/mediatek/mt76/mac80211.c
index 258d2623d1bf..c1982211d658 100644
--- a/drivers/net/wireless/mediatek/mt76/mac80211.c
+++ b/drivers/net/wireless/mediatek/mt76/mac80211.c
@@ -384,7 +384,7 @@ int mt76_get_survey(struct ieee80211_hw *hw, int idx,
 }
 EXPORT_SYMBOL_GPL(mt76_get_survey);
 
-static void
+static struct ieee80211_sta *
 mt76_rx_convert(struct sk_buff *skb)
 {
struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
@@ -407,14 +407,17 @@ mt76_rx_convert(struct sk_buff *skb)
BUILD_BUG_ON(sizeof(mstat) > sizeof(skb->cb));
BUILD_BUG_ON(sizeof(status->chain_signal) != 
sizeof(mstat.chain_signal));
memcpy(status->chain_signal, mstat.chain_signal, 
sizeof(mstat.chain_signal));
+
+   return wcid_to_sta(mstat.wcid);
 }
 
 void mt76_rx_complete(struct mt76_dev *dev, enum mt76_rxq_id q)
 {
+   struct ieee80211_sta *sta;
struct sk_buff *skb;
 
while ((skb = __skb_dequeue(>rx_skb[q])) != NULL) {
-   mt76_rx_convert(skb);
-   ieee80211_rx_napi(dev->hw, NULL, skb, >napi[q]);
+   sta = mt76_rx_convert(skb);
+   ieee80211_rx_napi(dev->hw, sta, skb, >napi[q]);
}
 }
diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h 
b/drivers/net/wireless/mediatek/mt76/mt76.h
index be4846ee4828..e20c52607c66 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76.h
@@ -125,6 +125,8 @@ struct mt76_wcid {
u8 idx;
u8 hw_key_idx;
 
+   u8 sta:1;
+
__le16 tx_rate;
bool tx_rate_set;
u8 tx_rate_nss;
@@ -251,6 +253,7 @@ struct mt76_rate_power {
 };
 
 struct mt76_rx_status {
+   struct mt76_wcid *wcid;
u32 flag;
u16 freq;
u8 enc_flags;
@@ -343,6 +346,17 @@ mtxq_to_txq(struct mt76_txq *mtxq)
return container_of(ptr, struct ieee80211_txq, drv_priv);
 }
 
+static inline struct ieee80211_sta *
+wcid_to_sta(struct mt76_wcid *wcid)
+{
+   void *ptr = wcid;
+
+   if (!wcid || !wcid->sta)
+   return NULL;
+
+   return container_of(ptr, struct ieee80211_sta, drv_priv);
+}
+
 int mt76_tx_queue_skb(struct mt76_dev *dev, struct mt76_queue *q,
  struct sk_buff *skb, struct mt76_wcid *wcid,
  struct ieee80211_sta *sta);
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_mac.c 
b/drivers/net/wireless/mediatek/mt76/mt76x2_mac.c
index 2e12fc0d5c9e..75f2843847d0 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x2_mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x2_mac.c
@@ -265,6 +265,15 @@ static void mt76x2_remove_hdr_pad(struct sk_buff *skb)
skb_pull(skb, 2);
 }
 
+static struct mt76_wcid *
+mt76x2_rx_get_wcid(struct mt76x2_dev *dev, u8 idx)
+{
+   if (idx >= ARRAY_SIZE(dev->wcid))
+   return NULL;
+
+   return rcu_dereference(dev->wcid[idx]);
+}
+
 int mt76x2_mac_process_rx(struct mt76x2_dev *dev, struct sk_buff *skb,
  void *rxi)
 {
@@ -272,8 +281,12 @@ int mt76x2_mac_process_rx(struct mt76x2_dev *dev, struct 
sk_buff *skb,
struct mt76x2_rxwi *rxwi = rxi;
u32 ctl = le32_to_cpu(rxwi->ctl);
u16 rate = le16_to_cpu(rxwi->rate);
+   u8 wcid;
int len;
 
+   wcid = FIELD_GET(MT_RXWI_CTL_WCID, ctl);
+   status->wcid = mt76x2_rx_get_wcid(dev, wcid);
+
if (rxwi->rxinfo & cpu_to_le32(MT_RXINFO_L2PAD))
mt76x2_remove_hdr_pad(skb);
 
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_main.c 
b/drivers/net/wireless/mediatek/mt76/mt76x2_main.c
index aa5fbb64e218..2a1cb65c5edb 100644
--- 

[PATCH 2/8] mt76: fix TSF value in probe responses

2018-01-24 Thread Felix Fietkau
Like beacons, probe responses need a hardware-generated TSF value. Set
the flag that causes the hw to generate it

Signed-off-by: Felix Fietkau 
---
 drivers/net/wireless/mediatek/mt76/mt76x2_mac.c | 6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_mac.c 
b/drivers/net/wireless/mediatek/mt76/mt76x2_mac.c
index a7416a01baa4..98219b971463 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x2_mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x2_mac.c
@@ -172,6 +172,7 @@ void mt76x2_mac_write_txwi(struct mt76x2_dev *dev, struct 
mt76x2_txwi *txwi,
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
struct ieee80211_tx_rate *rate = >control.rates[0];
struct ieee80211_key_conf *key = info->control.hw_key;
+   struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
u16 rate_ht_mask = FIELD_PREP(MT_RXWI_RATE_PHY, BIT(1) | BIT(2));
u16 txwi_flags = 0;
u8 nss;
@@ -248,6 +249,10 @@ void mt76x2_mac_write_txwi(struct mt76x2_dev *dev, struct 
mt76x2_txwi *txwi,
sta->ht_cap.ampdu_density);
}
 
+   if (ieee80211_is_probe_resp(hdr->frame_control) ||
+   ieee80211_is_beacon(hdr->frame_control))
+   txwi_flags |= MT_TXWI_FLAGS_TS;
+
txwi->flags |= cpu_to_le16(txwi_flags);
txwi->len_ctl = cpu_to_le16(skb->len);
 }
@@ -634,7 +639,6 @@ mt76_write_beacon(struct mt76x2_dev *dev, int offset, 
struct sk_buff *skb)
return -ENOSPC;
 
mt76x2_mac_write_txwi(dev, , skb, NULL, NULL);
-   txwi.flags |= cpu_to_le16(MT_TXWI_FLAGS_TS);
 
mt76_wr_copy(dev, offset, , sizeof(txwi));
offset += sizeof(txwi);
-- 
2.14.2



[PATCH 5/8] mt76: implement A-MPDU rx reordering in the driver code

2018-01-24 Thread Felix Fietkau
This is required for performing CCMP PN validation in software

Signed-off-by: Felix Fietkau 
---
 drivers/net/wireless/mediatek/mt76/Makefile  |   2 +-
 drivers/net/wireless/mediatek/mt76/agg-rx.c  | 264 +++
 drivers/net/wireless/mediatek/mt76/mac80211.c|  11 +-
 drivers/net/wireless/mediatek/mt76/mt76.h|  35 +++
 drivers/net/wireless/mediatek/mt76/mt76x2_init.c |   2 +
 drivers/net/wireless/mediatek/mt76/mt76x2_mac.c  |   7 +
 drivers/net/wireless/mediatek/mt76/mt76x2_main.c |   2 +
 7 files changed, 319 insertions(+), 4 deletions(-)
 create mode 100644 drivers/net/wireless/mediatek/mt76/agg-rx.c

diff --git a/drivers/net/wireless/mediatek/mt76/Makefile 
b/drivers/net/wireless/mediatek/mt76/Makefile
index 2bb919863616..a0156bc01dea 100644
--- a/drivers/net/wireless/mediatek/mt76/Makefile
+++ b/drivers/net/wireless/mediatek/mt76/Makefile
@@ -2,7 +2,7 @@ obj-$(CONFIG_MT76_CORE) += mt76.o
 obj-$(CONFIG_MT76x2E) += mt76x2e.o
 
 mt76-y := \
-   mmio.o util.o trace.o dma.o mac80211.o debugfs.o eeprom.o tx.o
+   mmio.o util.o trace.o dma.o mac80211.o debugfs.o eeprom.o tx.o agg-rx.o
 
 CFLAGS_trace.o := -I$(src)
 
diff --git a/drivers/net/wireless/mediatek/mt76/agg-rx.c 
b/drivers/net/wireless/mediatek/mt76/agg-rx.c
new file mode 100644
index ..ecd0bcd149e5
--- /dev/null
+++ b/drivers/net/wireless/mediatek/mt76/agg-rx.c
@@ -0,0 +1,264 @@
+/*
+ * Copyright (C) 2018 Felix Fietkau 
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+#include "mt76.h"
+
+#define REORDER_TIMEOUT (HZ / 10)
+
+static void
+mt76_aggr_release(struct mt76_rx_tid *tid, struct sk_buff_head *frames, int 
idx)
+{
+   struct sk_buff *skb;
+
+   tid->head = ieee80211_sn_inc(tid->head);
+
+   skb = tid->reorder_buf[idx];
+   if (!skb)
+   return;
+
+   tid->reorder_buf[idx] = NULL;
+   tid->nframes--;
+   __skb_queue_tail(frames, skb);
+}
+
+static void
+mt76_rx_aggr_release_frames(struct mt76_rx_tid *tid, struct sk_buff_head 
*frames,
+u16 head)
+{
+   int idx;
+
+   while (ieee80211_sn_less(tid->head, head)) {
+   idx = tid->head % tid->size;
+   mt76_aggr_release(tid, frames, idx);
+   }
+}
+
+static void
+mt76_rx_aggr_release_head(struct mt76_rx_tid *tid, struct sk_buff_head *frames)
+{
+   int idx = tid->head % tid->size;
+
+   while (tid->reorder_buf[idx]) {
+   mt76_aggr_release(tid, frames, idx);
+   idx = tid->head % tid->size;
+   }
+}
+
+static void
+mt76_rx_aggr_check_release(struct mt76_rx_tid *tid, struct sk_buff_head 
*frames)
+{
+   struct mt76_rx_status *status;
+   struct sk_buff *skb;
+   int start, idx, nframes;
+
+   if (!tid->nframes)
+   return;
+
+   mt76_rx_aggr_release_head(tid, frames);
+
+   start = tid->head % tid->size;
+   nframes = tid->nframes;
+
+   for (idx = (tid->head + 1) % tid->size;
+idx != start && nframes;
+idx = (idx + 1) % tid->size) {
+
+   skb = tid->reorder_buf[idx];
+   if (!skb)
+   continue;
+
+   nframes--;
+   status = (struct mt76_rx_status *) skb->cb;
+   if (!time_after(jiffies, status->reorder_time +
+REORDER_TIMEOUT))
+   continue;
+
+   mt76_rx_aggr_release_frames(tid, frames, status->seqno);
+   }
+
+   mt76_rx_aggr_release_head(tid, frames);
+}
+
+static void
+mt76_rx_aggr_reorder_work(struct work_struct *work)
+{
+   struct mt76_rx_tid *tid = container_of(work, struct mt76_rx_tid,
+  reorder_work.work);
+   struct mt76_dev *dev = tid->dev;
+   struct ieee80211_sta *sta;
+   struct sk_buff_head frames;
+   struct sk_buff *skb;
+
+   __skb_queue_head_init();
+
+   local_bh_disable();
+
+   spin_lock(>lock);
+   mt76_rx_aggr_check_release(tid, );
+   spin_unlock(>lock);
+
+   ieee80211_queue_delayed_work(tid->dev->hw, >reorder_work, 
REORDER_TIMEOUT);
+
+   while ((skb = __skb_dequeue()) != NULL) {
+   sta = mt76_rx_convert(skb);
+   

Re: [v2] mt76x2: init: disable all pending tasklets during device removal

2018-01-24 Thread Kalle Valo
Lorenzo Bianconi  wrote:

> There is a possible race in mt76x2_stop_hardware() since pre_tbtt and
> dfs tasklets could run during driver cleanup. Fix it disabling all
> pending tasklets during device removal
> 
> Signed-off-by: Lorenzo Bianconi 
> Acked-by: Felix Fietkau 

Patch applied to wireless-drivers-next.git, thanks.

ba9797b2a7a5 mt76x2: init: disable all pending tasklets during device removal

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

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



Re: [1/3] mt76x2: dfs: avoid tasklet scheduling during mt76x2_dfs_init_params()

2018-01-24 Thread Kalle Valo
Lorenzo Bianconi  wrote:

> Substitute tasklet_kill with tasklet_disable/tasklet_enable in order to
> guarantee dfs tasklet can not be executed during dfs parameter
> initialization
> 
> Signed-off-by: Lorenzo Bianconi 

3 patches applied to wireless-drivers-next.git, thanks.

8c9f6491a313 mt76x2: dfs: avoid tasklet scheduling during 
mt76x2_dfs_init_params()
2070f3cc2c2c mt76x2: dfs: add set_domain handler
634e99f0d4da mt76x2: dfs: take into account dfs region in 
mt76x2_dfs_init_params()

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

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



Re: mt76: fix transmission of encrypted management frames

2018-01-24 Thread Kalle Valo
Felix Fietkau  wrote:

> Hardware encryption seems to break encrypted unicast mgmt tx.
> Unfortunately the hardware TXWI header does not have a bit to indicate
> that a frame is software encrypted, so sw-encrypted frames need to use a
> different WCID. For that to work, the CCMP PN needs to be generated in
> software, which makes things a bit slower, so only do it for keys that
> also need to tx management frames.
> 
> Signed-off-by: Felix Fietkau 

Patch applied to wireless-drivers-next.git, thanks.

23405236460b mt76: fix transmission of encrypted management frames

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

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



Re: mt76x2: fix WMM parameter configuration

2018-01-24 Thread Kalle Valo
Lorenzo Bianconi  wrote:

> Fix hw queue configuration since mt76x2 devices use a reverse queue
> enumeration respect to mac80211 one:
>  - 0: AC_BE
>  - 1: AC_BK
>  - 2: AC_VI
>  - 3: AC_VO
> 
> The issue can be reproduced sending two concurrent flow using
> two separate queues:
>  - VO: 20Mbps UDP traffic
>  - BE: TCP traffic
> 
> In this scenario the UDP traffic will be blocked by the TCP one.
> Fix it configuring properly WMM hw queue parameters
> 
> Fixes: 7bc04215a66b ("mt76: add driver code for MT76x2e")
> Tested-by: Gaetano Catalli 
> Signed-off-by: Gaetano Catalli 
> Signed-off-by: Lorenzo Bianconi 
> Acked-by: Felix Fietkau 

Patch applied to wireless-drivers-next.git, thanks.

1cbbf69cc83e mt76x2: fix WMM parameter configuration

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

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



Re: [PATCH v2] wcn36xx: release resources in case of error

2018-01-24 Thread Kalle Valo
Ramon Fried  writes:

> wcn36xx_dxe_init() doesn't check for the return value
> of wcn36xx_dxe_init_descs().
> This patch releases the resources in case an error ocurred.
>
> Change-Id: I924bd7489b60243c0a0cbaa716caf924f11d7587
> Signed-off-by: Ramon Fried 

This compiled now, thanks. But I did some minor changes in the commit
log and in indentation on the pending branch:

https://git.kernel.org/pub/scm/linux/kernel/git/kvalo/ath.git/commit/?h=master-pending=e5ff4344eab68c86e00036e937847ce89dfaeef6

> @@ -819,11 +847,19 @@ int wcn36xx_dxe_init(struct wcn36xx *wcn)
>  
>   ret = wcn36xx_dxe_request_irqs(wcn);
>   if (ret < 0)
> - goto out_err;
> + goto out_err_irq;

The recommended style is to label the err_ based what the target does,
not from where they are called from. It's easier to manage the labels
that way. But as this is a style issue I didn't change it.

-- 
Kalle Valo


Re: [PATCH 1/2] cfg80211: Add tx ack signal attribute in sta info

2018-01-24 Thread vnaralas

On 2018-01-22 17:52, Johannes Berg wrote:

On Thu, 2018-01-18 at 18:10 +0530, Venkateswara Naralasetty wrote:

From: Bhagavathi Perumal S 

This patch provides support for users to get ack signal
strength of last transmitted by introducing new attribute
'NL80211_STA_INFO_ACK_SIGNAL'.


No real objection to the patch itself, but you should say *why* you
need this, and I'm not really sure I see much point in having the
signal strength of the very last ACK frame?
If user wants to get instant RSSI for the station which is ideal for 
long time, user can sent null frame and get RSSI form the ack of that 
null frame.




At least provide reasoning so other drivers can decide whether to
implement it or not.

+ * @NL80211_STA_INFO_ACK_SIGNAL: signal strength of the last ACK 
frame(u8, dBm)


more like s8, really.


I have taken reference from 'NL80211_STA_INFO_SIGNAL_AVG'.


Re: [PATCH v2] mac80211_hwsim: don't use WQ_MEM_RECLAIM

2018-01-24 Thread Johannes Berg
On Wed, 2018-01-24 at 10:39 +0100, Benjamin Beichler wrote:

> sorry for introducing that error, but I'm a bit confused by the
> workqueue documentation.
> My assumption was, that deleting hwsim radios is reclaiming memory, and
> since this queue does nothing else it would save/necessary to set this flag.
> 
> Maybe a hint in the documentation, that a work item on a WQ_MEM_RECLAIM
> queue must not call flush of an !WQ_MEM_RECLAIM queue would be nice.
> Maybe it's kind of obvious, but there is also a reminder not to forget
> that flag, if a queue may have work items that reclaim memory

Yeah, honestly, I'm not really sure either. Clearly we can't set it,
but other drivers also set it...

I don't think it was *intended* for when you're freeing memory, since I
think reclaiming is what happens when you write out dirty buffers to
disk etc.

johannes


Re: ieee80211 phy0: rt2x00queue_write_tx_frame: Error - Dropping frame due to full tx queue...?

2018-01-24 Thread Stanislaw Gruszka
Hi

So if 3.9 works and current kernel does not, the best way to address
the issue would be identify change that broke. Ideally if  bisecton
could be performed, but this can be hard taking that the problem is not
easy reproducible. Further difficultly comes from a fact that OpenWRT
has custom patches. So I suggest some kind of manual semi-bisection 
on OpenWRT repository with long testing, to find out first or close
to first OpenWRT change that start to broke things.

Cheers
Stanislaw

On Wed, Jan 24, 2018 at 09:18:23AM +0100, Enrico Mioso wrote:
> Hello!
> I can confirm - there is no firmware being uploaded to the device, or at 
> least: if it's there, it's not uploaded from an external file.
> root@smalltalk:~# ls -Fa -1 /lib/firmware/
> ./
> ../
> regulatory.db
> root@smalltalk:~#
> 
> Anything I might do? I can also give an ssh session to the device in case.
> 
> Enrico
> 
> On Tue, 23 Jan 2018, Stanislaw Gruszka wrote:
> 
> >Date: Tue, 23 Jan 2018 14:22:35
> >From: Stanislaw Gruszka 
> >To: Enrico Mioso 
> >Cc: Tom Psyborg ,
> >linux-wireless ,
> >Johannes Berg ,
> >Daniel Golle , Arnd Bergmann ,
> >John Crispin , Felix Fietkau 
> >Subject: Re: ieee80211 phy0: rt2x00queue_write_tx_frame: Error - Dropping
> >frame due to full tx queue...?
> >
> >On Mon, Jan 22, 2018 at 06:45:57AM +0100, Enrico Mioso wrote:
> >>Crash happening here also in the WL-330n3G device; unfortunately, no 
> >>messages to report.
> >>Regarding your hypothesis regardingthe firmware not being able to 
> >>communicate a problem regarding it's inability to send frames: around when 
> >>OpenWRT had 3.9.9 kernel, this device worked for weeks no stop with no 
> >>issues I think.
> >>And I don't think this is only a coicnidence. So I suspect, but it's only 
> >>an impression, also because I know ... very very little about this, that at 
> >>some point things worked.
> >
> >I think FW was upgraded since 3.9 kernel as well. But this
> >could be also problem how driver program the device registers,
> >not only FW problem.
> >
> >Regards
> >Stanislaw
> >


Re: [PATCH v2] mac80211_hwsim: don't use WQ_MEM_RECLAIM

2018-01-24 Thread Benjamin Beichler
Hi Johannes,

sorry for introducing that error, but I'm a bit confused by the
workqueue documentation.
My assumption was, that deleting hwsim radios is reclaiming memory, and
since this queue does nothing else it would save/necessary to set this flag.

Maybe a hint in the documentation, that a work item on a WQ_MEM_RECLAIM
queue must not call flush of an !WQ_MEM_RECLAIM queue would be nice.
Maybe it's kind of obvious, but there is also a reminder not to forget
that flag, if a queue may have work items that reclaim memory.

Again sorry for not seeing the warning on my test system ...

kind regards

Benjamin

Am 24.01.2018 um 08:40 schrieb Johannes Berg:
> From: Johannes Berg 
>
> We're obviously not part of a memory reclaim path, so don't set the flag.
>
> This also causes a warning in check_flush_dependency() since we end up
> in a code path that flushes a non-reclaim workqueue, and we shouldn't do
> that if we were really part of reclaim.
>

-- 
M.Sc. Benjamin Beichler

Universität Rostock, Fakultät für Informatik und Elektrotechnik
Institut für Angewandte Mikroelektronik und Datentechnik

University of Rostock, Department of CS and EE
Institute of Applied Microelectronics and CE

Richard-Wagner-Straße 31
18119 Rostock
Deutschland/Germany

phone: +49 (0) 381 498 - 7278
email: benjamin.beich...@uni-rostock.de
www: http://www.imd.uni-rostock.de/




smime.p7s
Description: S/MIME Cryptographic Signature


RE: [linuxwifi] Null pointer dereference in iwlwifi when starting ad-hoc network

2018-01-24 Thread Grumbach, Emmanuel
Hi,

> I get this oops in 4.15rc9 when doing the following:
> 
> # iw dev wlp2s0 set type ibss
> # ip link set dev wlp2s0 up
> # iw dev wlp2s0 ibss join "TEST" 2412
> 
> The oops happens after some delay (approx. 5 seconds).
> 
> Hardware is:
> 
> 02:00.0 Network controller: Intel Corporation Wireless 8265 / 8275 (rev 78) 
> pci
> vendor code 8086:24fd
> Subsystem: 8086:0050
> 
> Oops message is:
> 
> IPv6: ADDRCONF(NETDEV_UP): wlp2s0: link is not ready
> wlp2s0: Trigger new scan to find an IBSS to join
> wlp2s0: Trigger new scan to find an IBSS to join
> wlp2s0: Trigger new scan to find an IBSS to join
> wlp2s0: Trigger new scan to find an IBSS to join
> wlp2s0: Trigger new scan to find an IBSS to join
> wlp2s0: Trigger new scan to find an IBSS to join
> wlp2s0: Trigger new scan to find an IBSS to join
> wlp2s0: Trigger new scan to find an IBSS to join
> wlp2s0: Trigger new scan to find an IBSS to join
> wlp2s0: Trigger new scan to find an IBSS to join
> wlp2s0: Creating new IBSS network, BSSID 3a:94:1d:dd:ab:09
> BUG: unable to handle kernel NULL pointer dereference at
> 0068

We have a fix for this which should go upstream soon:

commit 0e37a1940fcfae99ffec59ad620ed81feb2d
Author: Sara Sharon 
Date:   Thu Dec 21 15:05:28 2017 +0200

[BUGFIX] iwlwifi: mvm: fix IBSS for devices that support station type API


in our internal  tree which is mirrored here:
https://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/backport-iwlwifi.git/


Re: ieee80211 phy0: rt2x00queue_write_tx_frame: Error - Dropping frame due to full tx queue...?

2018-01-24 Thread Enrico Mioso

Hello!
I can confirm - there is no firmware being uploaded to the device, or at least: 
if it's there, it's not uploaded from an external file.
root@smalltalk:~# ls -Fa -1 /lib/firmware/
./
../
regulatory.db
root@smalltalk:~#

Anything I might do? I can also give an ssh session to the device in case.

Enrico

On Tue, 23 Jan 2018, Stanislaw Gruszka wrote:


Date: Tue, 23 Jan 2018 14:22:35
From: Stanislaw Gruszka 
To: Enrico Mioso 
Cc: Tom Psyborg ,
linux-wireless ,
Johannes Berg ,
Daniel Golle , Arnd Bergmann ,
John Crispin , Felix Fietkau 
Subject: Re: ieee80211 phy0: rt2x00queue_write_tx_frame: Error - Dropping
frame due to full tx queue...?

On Mon, Jan 22, 2018 at 06:45:57AM +0100, Enrico Mioso wrote:

Crash happening here also in the WL-330n3G device; unfortunately, no messages 
to report.
Regarding your hypothesis regardingthe firmware not being able to communicate a 
problem regarding it's inability to send frames: around when OpenWRT had 3.9.9 
kernel, this device worked for weeks no stop with no issues I think.
And I don't think this is only a coicnidence. So I suspect, but it's only an 
impression, also because I know ... very very little about this, that at some 
point things worked.


I think FW was upgraded since 3.9 kernel as well. But this
could be also problem how driver program the device registers,
not only FW problem.

Regards
Stanislaw



Null pointer dereference in iwlwifi when starting ad-hoc network

2018-01-24 Thread Austin Lund
I get this oops in 4.15rc9 when doing the following:

# iw dev wlp2s0 set type ibss
# ip link set dev wlp2s0 up
# iw dev wlp2s0 ibss join "TEST" 2412

The oops happens after some delay (approx. 5 seconds).

Hardware is:

02:00.0 Network controller: Intel Corporation Wireless 8265 / 8275 (rev 78)
pci vendor code 8086:24fd
Subsystem: 8086:0050

Oops message is:

IPv6: ADDRCONF(NETDEV_UP): wlp2s0: link is not ready
wlp2s0: Trigger new scan to find an IBSS to join
wlp2s0: Trigger new scan to find an IBSS to join
wlp2s0: Trigger new scan to find an IBSS to join
wlp2s0: Trigger new scan to find an IBSS to join
wlp2s0: Trigger new scan to find an IBSS to join
wlp2s0: Trigger new scan to find an IBSS to join
wlp2s0: Trigger new scan to find an IBSS to join
wlp2s0: Trigger new scan to find an IBSS to join
wlp2s0: Trigger new scan to find an IBSS to join
wlp2s0: Trigger new scan to find an IBSS to join
wlp2s0: Creating new IBSS network, BSSID 3a:94:1d:dd:ab:09
BUG: unable to handle kernel NULL pointer dereference at 0068
IP: iwl_trans_pcie_txq_enable+0x5e/0x440 [iwlwifi]
PGD 0 P4D 0
Oops: 0002 [#1] PREEMPT SMP PTI
Modules linked in: snd_hda_codec_hdmi snd_hda_codec_realtek
snd_hda_codec_generic btusb btrtl btbcm btintel bluetooth uvcvideo
videobuf2_vmalloc videobuf2_memops videobuf2_v4l2 videobuf2_core
videodev media ecdh_generic crc16 joydev mousedev arc4 hid_multitouch
msr mei_wdt nouveau iwlmvm i915 intel_rapl x86_pkg_temp_thermal
intel_powerclamp coretemp kvm_intel mac80211 kvm iTCO_wdt
iTCO_vendor_support nls_iso8859_1 nls_cp437 vfat irqbypass
crct10dif_pclmul fat wmi_bmof crc32_pclmul dell_smbios_wmi iwlwifi
dell_wmi dell_rbtn ghash_clmulni_intel dell_wmi_descriptor
intel_wmi_thunderbolt dell_laptop dell_smbios_smm dell_smbios pcbc
dcdbas mxm_wmi dell_smm_hwmon ttm snd_hda_intel i2c_algo_bit
drm_kms_helper snd_hda_codec tpm_crb idma64 cfg80211 aesni_intel
snd_hda_core aes_x86_64 crypto_simd
 drm glue_helper snd_hwdep cryptd intel_cstate snd_pcm intel_rapl_perf
psmouse evdev snd_timer input_leds intel_gtt rfkill led_class mac_hid
agpgart snd rtsx_pci_ms pcspkr mei_me memstick syscopyarea i2c_hid
sysfillrect tpm_tis sysimgblt processor_thermal_device tpm_tis_core
i2c_i801 intel_lpss_pci soundcore mei fb_sys_fops shpchp
intel_pch_thermal thermal intel_lpss intel_soc_dts_iosf hid battery
tpm int3400_thermal ac wmi video acpi_thermal_rel int3403_thermal
intel_hid acpi_pad int340x_thermal_zone sparse_keymap button
sch_fq_codel crypto_user ip_tables x_tables btrfs xor zstd_decompress
zstd_compress xxhash raid6_pq rtsx_pci_sdmmc mmc_core serio_raw atkbd
libps2 crc32c_intel ahci libahci xhci_pci libata nvme xhci_hcd
nvme_core rtsx_pci scsi_mod usbcore usb_common i8042 serio
CPU: 4 PID: 371 Comm: kworker/u16:6 Not tainted 4.15.0-rc9-1-mainline #4
Hardware name: Dell Inc. Precision 5520/0R6JFH, BIOS 1.7.0 12/15/2017
Workqueue: phy0 ieee80211_iface_work [mac80211]
RIP: 0010:iwl_trans_pcie_txq_enable+0x5e/0x440 [iwlwifi]
RSP: 0018:bb4702b4bb90 EFLAGS: 00010246
RAX: 0bb8 RBX: 00ff RCX: 
RDX:  RSI: 00ff RDI: 17700fa0
RBP:  R08: 2710 R09: 0001
R10:  R11: 8f45cb5aacd0 R12: 
R13:  R14:  R15: 8f45d7020018
FS:  () GS:8f45fe50() knlGS:
CS:  0010 DS:  ES:  CR0: 80050033
CR2: 0068 CR3: 0003f100a005 CR4: 003606e0
DR0:  DR1:  DR2: 
DR3:  DR6: fffe0ff0 DR7: 0400
Call Trace:
 iwl_mvm_enable_txq+0x205/0x390 [iwlmvm]
 ? ieee80211_iterate_active_interfaces_atomic+0x2e/0x40 [mac80211]
 ? iwl_mvm_add_mcast_sta+0x159/0x1e0 [iwlmvm]
 iwl_mvm_add_mcast_sta+0x159/0x1e0 [iwlmvm]
 iwl_mvm_start_ap_ibss+0xb4/0x1b0 [iwlmvm]
 __ieee80211_sta_join_ibss+0x340/0x7f0 [mac80211]
 ieee80211_sta_create_ibss+0x8c/0xf0 [mac80211]
 ieee80211_ibss_work+0x3a4/0x5a0 [mac80211]
 ? skb_dequeue+0x52/0x60
 ? ieee80211_iface_work+0xbe/0x340 [mac80211]
 process_one_work+0x1de/0x410
 worker_thread+0x2b/0x3d0
 ? process_one_work+0x410/0x410
 kthread+0x111/0x130
 ? kthread_create_worker_on_cpu+0x70/0x70
 ? do_group_exit+0x3a/0xa0
 ret_from_fork+0x3a/0x50
Code: 4c 8b ac c7 e8 7d 00 00 f0 48 0f ab 87 e8 8d 00 00 73 0d 80 3d
0a 07 03 00 00 0f 84 97 03 00 00 44 89 c7 e8 a5 88 71 e8 4d 85 e4 <49>
89 45 68 0f 84 d6 02 00 00 41 0f b6 04 24 89 44 24 04 41 0f
RIP: iwl_trans_pcie_txq_enable+0x5e/0x440 [iwlwifi] RSP: bb4702b4bb90
CR2: 0068
---[ end trace 3e02d7f42559c48e ]---

GDB tells me that iwl_trans_pcie_txq_enable+0x5e is in
drivers/net/wireless/intel/iwlwifi/pcie/tx.c:

txq->wd_timeout = msecs_to_jiffies(wdg_timeout);


[PATCH v2 0/4] ath9k: AR9003 noise floor calibration support

2018-01-24 Thread Wojciech Dubowik
AR9003 series allows to calibrate noise floor for different frequency
bins. Once it's done it's possible to get more accurate rssi/signal
values over whole frequency band at a given temperature.
The RSSI/signal accuracy reported by calibrated RF cards improves
from 6 to up to 2dB.

This could be interesting for application which require good signal
accuracy like roaming or mesh protocols.

V2: Copied cover letter feature description to patch 3 in the series.

Wojciech Dubowik (4):
  ath9k: Alternative EEPROM size for AR9003
  ath9k: Read noise floor calibration data from eeprom
  ath9k: Use calibrated noise floor value when available
  ath9k: Display calibration data piers in debugfs

 drivers/net/wireless/ath/ath9k/ar9003_eeprom.c | 133 +++--
 drivers/net/wireless/ath/ath9k/ar9003_eeprom.h |  10 ++
 drivers/net/wireless/ath/ath9k/calib.c |  38 ---
 drivers/net/wireless/ath/ath9k/hw.h|   2 +
 4 files changed, 160 insertions(+), 23 deletions(-)

-- 
2.7.4



[PATCH v2 4/4] ath9k: Display calibration data piers in debugfs

2018-01-24 Thread Wojciech Dubowik
Display per frequency calibration data in dump_modal
debugfs entry including reference power, voltage,
tx temperature and noise floor.

Example of chain 0 of OEM card (dump from modal_eeprom):
Chain 0
Freq refvolttempnf_Cal  nf_Pow  rx_temp
5180-30 0   137 0   0   0
5320-24 0   137 0   0   0
5500-15 0   137 0   0   0
5620-10 0   137 0   0   0
5700-15 0   137 0   0   0
5745-16 0   135 0   0   0
5785-19 0   136 0   0   0
5825-22 0   136 0   0   0

Example of a card with calibrated noise floor.
Chain 0
Freq refvolttempnf_Cal  nf_Pow  rx_temp
4890-49 0   128 -107-97 124
5100-23 0   128 -101-96 124
5180-18 0   128 -101-96 124
5300-12 0   128 -102-97 124
5500-9  0   128 -101-97 125
5640-17 0   128 -101-98 124
5785-25 0   128 -101-98 124
5940-33 0   128 -106-99 124

Signed-off-by: Wojciech Dubowik 
---
 drivers/net/wireless/ath/ath9k/ar9003_eeprom.c | 64 +-
 1 file changed, 63 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c 
b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
index de2e503..f019a20 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
@@ -3436,6 +3436,60 @@ static u32 ar9003_dump_modal_eeprom(char *buf, u32 len, 
u32 size,
return len;
 }
 
+static u32 ar9003_dump_cal_data(struct ath_hw *ah, char *buf, u32 len, u32 
size,
+   bool is_2g)
+{
+   struct ar9300_eeprom *eep = >eeprom.ar9300_eep;
+   struct ar9300_base_eep_hdr *pBase;
+   struct ar9300_cal_data_per_freq_op_loop *cal_pier;
+   int cal_pier_nr;
+   int freq;
+   int i, j;
+
+   pBase = >baseEepHeader;
+
+   if (is_2g)
+   cal_pier_nr = AR9300_NUM_2G_CAL_PIERS;
+   else
+   cal_pier_nr = AR9300_NUM_5G_CAL_PIERS;
+
+   for (i = 0; i < AR9300_MAX_CHAINS; i++) {
+   if (!((pBase->txrxMask >> i) & 1))
+   continue;
+
+   len += snprintf(buf + len, size - len, "Chain %d\n", i);
+
+   len += snprintf(buf + len, size - len,
+   "Freq\t ref\tvolt\ttemp\tnf_cal\tnf_pow\trx_temp\n");
+
+   for (j = 0; j < cal_pier_nr; j++) {
+   if (is_2g) {
+   cal_pier = >calPierData2G[i][j];
+   freq = 2300 + eep->calFreqPier2G[j];
+   } else {
+   cal_pier = >calPierData5G[i][j];
+   freq = 4800 + eep->calFreqPier5G[j] * 5;
+   }
+
+   len += snprintf(buf + len, size - len,
+   "%d\t", freq);
+
+   len += snprintf(buf + len, size - len,
+   "%d\t%d\t%d\t%d\t%d\t%d\n",
+   cal_pier->refPower,
+   cal_pier->voltMeas,
+   cal_pier->tempMeas,
+   cal_pier->rxTempMeas ?
+   N2DBM(cal_pier->rxNoisefloorCal) : 0,
+   cal_pier->rxTempMeas ?
+   N2DBM(cal_pier->rxNoisefloorPower) : 0,
+   cal_pier->rxTempMeas);
+   }
+   }
+
+   return len;
+}
+
 static u32 ath9k_hw_ar9003_dump_eeprom(struct ath_hw *ah, bool dump_base_hdr,
   u8 *buf, u32 len, u32 size)
 {
@@ -3447,10 +3501,18 @@ static u32 ath9k_hw_ar9003_dump_eeprom(struct ath_hw 
*ah, bool dump_base_hdr,
 "%20s :\n", "2GHz modal Header");
len = ar9003_dump_modal_eeprom(buf, len, size,
>modalHeader2G);
-   len += scnprintf(buf + len, size - len,
+
+   len += scnprintf(buf + len, size - len, "Calibration data\n");
+   len = ar9003_dump_cal_data(ah, buf, len, size, true);
+
+   len +=  snprintf(buf + len, size - len,
 "%20s :\n", "5GHz modal Header");
len = ar9003_dump_modal_eeprom(buf, len, size,
>modalHeader5G);
+
+   len += snprintf(buf + len, size - len, "Calibration data\n");
+   len = ar9003_dump_cal_data(ah, buf, len, size, false);
+
goto out;
}
 
-- 
2.7.4



[PATCH v2 3/4] ath9k: Use calibrated noise floor value when available

2018-01-24 Thread Wojciech Dubowik
AR9003 series allows to calibrate noise floor for different frequency
bins. Once it's done it's possible to get more accurate rssi/signal
values over whole frequency band at a given temperature.
The RSSI/signal accuracy reported by calibrated RF cards improves
from 6 to up to 2dB.

This could be interesting for application which require good signal
accuracy like roaming or mesh protocols.

Signed-off-by: Wojciech Dubowik 
---
 drivers/net/wireless/ath/ath9k/calib.c | 38 +-
 1 file changed, 24 insertions(+), 14 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/calib.c 
b/drivers/net/wireless/ath/ath9k/calib.c
index 13ab6bc..3d9447e 100644
--- a/drivers/net/wireless/ath/ath9k/calib.c
+++ b/drivers/net/wireless/ath/ath9k/calib.c
@@ -58,19 +58,25 @@ static struct ath_nf_limits *ath9k_hw_get_nf_limits(struct 
ath_hw *ah,
 }
 
 static s16 ath9k_hw_get_default_nf(struct ath_hw *ah,
-  struct ath9k_channel *chan)
+  struct ath9k_channel *chan,
+  int chain)
 {
-   return ath9k_hw_get_nf_limits(ah, chan)->nominal;
+   s16 calib_nf = ath9k_hw_get_nf_limits(ah, chan)->cal[chain];
+
+   if (calib_nf)
+   return calib_nf;
+   else
+   return ath9k_hw_get_nf_limits(ah, chan)->nominal;
 }
 
 s16 ath9k_hw_getchan_noise(struct ath_hw *ah, struct ath9k_channel *chan,
   s16 nf)
 {
-   s8 noise = ATH_DEFAULT_NOISE_FLOOR;
+   s8 noise = ath9k_hw_get_default_nf(ah, chan, 0);
 
if (nf) {
s8 delta = nf - ATH9K_NF_CAL_NOISE_THRESH -
-  ath9k_hw_get_default_nf(ah, chan);
+  ath9k_hw_get_default_nf(ah, chan, 0);
if (delta > 0)
noise += delta;
}
@@ -240,7 +246,7 @@ int ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel 
*chan)
unsigned i, j;
u8 chainmask = (ah->rxchainmask << 3) | ah->rxchainmask;
struct ath_common *common = ath9k_hw_common(ah);
-   s16 default_nf = ath9k_hw_get_default_nf(ah, chan);
+   s16 default_nf = ath9k_hw_get_nf_limits(ah, chan)->nominal;
u32 bb_agc_ctl = REG_READ(ah, AR_PHY_AGC_CONTROL);
 
if (ah->caldata)
@@ -258,8 +264,13 @@ int ath9k_hw_loadnf(struct ath_hw *ah, struct 
ath9k_channel *chan)
nfval = ah->nf_override;
else if (h)
nfval = h[i].privNF;
-   else
-   nfval = default_nf;
+   else {
+   /* Try to get calibrated noise floor value */
+   nfval =
+   ath9k_hw_get_nf_limits(ah, chan)->cal[i];
+   if (nfval > -60 || nfval < -127)
+   nfval = default_nf;
+   }
 
REG_RMW(ah, ah->nf_regs[i],
(((u32) nfval << 1) & 0x1ff), 0x1ff);
@@ -429,20 +440,19 @@ void ath9k_init_nfcal_hist_buffer(struct ath_hw *ah,
  struct ath9k_channel *chan)
 {
struct ath9k_nfcal_hist *h;
-   s16 default_nf;
-   int i, j;
+   int i, j, k = 0;
 
ah->caldata->channel = chan->channel;
ah->caldata->channelFlags = chan->channelFlags;
h = ah->caldata->nfCalHist;
-   default_nf = ath9k_hw_get_default_nf(ah, chan);
for (i = 0; i < NUM_NF_READINGS; i++) {
h[i].currIndex = 0;
-   h[i].privNF = default_nf;
+   h[i].privNF = ath9k_hw_get_default_nf(ah, chan, k);
h[i].invalidNFcount = AR_PHY_CCA_FILTERWINDOW_LENGTH;
-   for (j = 0; j < ATH9K_NF_CAL_HIST_MAX; j++) {
-   h[i].nfCalBuffer[j] = default_nf;
-   }
+   for (j = 0; j < ATH9K_NF_CAL_HIST_MAX; j++)
+   h[i].nfCalBuffer[j] = h[i].privNF;
+   if (++k >= AR5416_MAX_CHAINS)
+   k = 0;
}
 }
 
-- 
2.7.4



[PATCH v2 1/4] ath9k: Alternative EEPROM size for AR9003

2018-01-24 Thread Wojciech Dubowik
AR9003 factory calibration allows to use bigger EEPROM than
standard 1k without changing the default layout. Allow
probing of EEPROM at alternative address if initial check
for default fails.
The original ar9003 eeprom ops are still be used.

Signed-off-by: Wojciech Dubowik 
---
 drivers/net/wireless/ath/ath9k/ar9003_eeprom.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c 
b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
index c2e210c..23bb677 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
@@ -3310,6 +3310,12 @@ static int ar9300_eeprom_restore_internal(struct ath_hw 
*ah,
if (ar9300_check_eeprom_header(ah, read, cptr))
goto found;
 
+   cptr = AR9300_BASE_ADDR_4K;
+   ath_dbg(common, EEPROM, "Trying EEPROM access at Address 0x%04x\n",
+   cptr);
+   if (ar9300_check_eeprom_header(ah, read, cptr))
+   goto found;
+
cptr = AR9300_BASE_ADDR_512;
ath_dbg(common, EEPROM, "Trying EEPROM access at Address 0x%04x\n",
cptr);
-- 
2.7.4



[PATCH v2 2/4] ath9k: Read noise floor calibration data from eeprom

2018-01-24 Thread Wojciech Dubowik
AR9003 devices can have calibrated noise floor values
which can be used instead of hard coded one. Read them
from eeprom and save interpolated value in nf limits for
the current channel.

Signed-off-by: Wojciech Dubowik 
---
 drivers/net/wireless/ath/ath9k/ar9003_eeprom.c | 63 ++
 drivers/net/wireless/ath/ath9k/ar9003_eeprom.h | 10 
 drivers/net/wireless/ath/ath9k/hw.h|  2 +
 3 files changed, 67 insertions(+), 8 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c 
b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
index 23bb677..de2e503 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
@@ -4689,7 +4689,8 @@ static int ar9003_hw_cal_pier_get(struct ath_hw *ah,
  int ichain,
  int *pfrequency,
  int *pcorrection,
- int *ptemperature, int *pvoltage)
+ int *ptemperature, int *pvoltage,
+ int *pnf_cal, int *pnf_power)
 {
u8 *pCalPier;
struct ar9300_cal_data_per_freq_op_loop *pCalPierStruct;
@@ -4731,6 +4732,10 @@ static int ar9003_hw_cal_pier_get(struct ath_hw *ah,
*pcorrection = pCalPierStruct->refPower;
*ptemperature = pCalPierStruct->tempMeas;
*pvoltage = pCalPierStruct->voltMeas;
+   *pnf_cal = pCalPierStruct->rxTempMeas ?
+   N2DBM(pCalPierStruct->rxNoisefloorCal) : 0;
+   *pnf_power = pCalPierStruct->rxTempMeas ?
+   N2DBM(pCalPierStruct->rxNoisefloorPower) : 0;
 
return 0;
 }
@@ -4895,14 +4900,18 @@ static int ar9003_hw_calibration_apply(struct ath_hw 
*ah, int frequency)
int mode;
int lfrequency[AR9300_MAX_CHAINS],
lcorrection[AR9300_MAX_CHAINS],
-   ltemperature[AR9300_MAX_CHAINS], lvoltage[AR9300_MAX_CHAINS];
+   ltemperature[AR9300_MAX_CHAINS], lvoltage[AR9300_MAX_CHAINS],
+   lnf_cal[AR9300_MAX_CHAINS], lnf_pwr[AR9300_MAX_CHAINS];
int hfrequency[AR9300_MAX_CHAINS],
hcorrection[AR9300_MAX_CHAINS],
-   htemperature[AR9300_MAX_CHAINS], hvoltage[AR9300_MAX_CHAINS];
+   htemperature[AR9300_MAX_CHAINS], hvoltage[AR9300_MAX_CHAINS],
+   hnf_cal[AR9300_MAX_CHAINS], hnf_pwr[AR9300_MAX_CHAINS];
int fdiff;
int correction[AR9300_MAX_CHAINS],
-   voltage[AR9300_MAX_CHAINS], temperature[AR9300_MAX_CHAINS];
-   int pfrequency, pcorrection, ptemperature, pvoltage;
+   voltage[AR9300_MAX_CHAINS], temperature[AR9300_MAX_CHAINS],
+   nf_cal[AR9300_MAX_CHAINS], nf_pwr[AR9300_MAX_CHAINS];
+   int pfrequency, pcorrection, ptemperature, pvoltage,
+   pnf_cal, pnf_pwr;
struct ath_common *common = ath9k_hw_common(ah);
 
mode = (frequency >= 4000);
@@ -4920,7 +4929,8 @@ static int ar9003_hw_calibration_apply(struct ath_hw *ah, 
int frequency)
for (ipier = 0; ipier < npier; ipier++) {
if (!ar9003_hw_cal_pier_get(ah, mode, ipier, ichain,
, ,
-   , )) {
+   , ,
+   _cal, _pwr)) {
fdiff = frequency - pfrequency;
 
/*
@@ -4942,6 +4952,8 @@ static int ar9003_hw_calibration_apply(struct ath_hw *ah, 
int frequency)
htemperature[ichain] =
ptemperature;
hvoltage[ichain] = pvoltage;
+   hnf_cal[ichain] = pnf_cal;
+   hnf_pwr[ichain] = pnf_pwr;
}
}
if (fdiff >= 0) {
@@ -4958,6 +4970,8 @@ static int ar9003_hw_calibration_apply(struct ath_hw *ah, 
int frequency)
ltemperature[ichain] =
ptemperature;
lvoltage[ichain] = pvoltage;
+   lnf_cal[ichain] = pnf_cal;
+   lnf_pwr[ichain] = pnf_pwr;
}
}
}
@@ -4966,15 +4980,20 @@ static int ar9003_hw_calibration_apply(struct ath_hw 
*ah, int frequency)
 
/* interpolate  */
for (ichain = 0; ichain < AR9300_MAX_CHAINS; ichain++) {
-   ath_dbg(common, EEPROM, "ch=%d f=%d low=%d %d h=%d %d\n",
+   ath_dbg(common,