Rate-ctrl experience gained with ath10k

2018-10-16 Thread Ben Greear

So, I've been trying to understand why the ath10k-rate ctrl was acting
so poorly in my 20-station UDP tx case.  I wrote that wifi-diag tool,
and it gave some clues, but only in retrospect were they obvious :)

The problem in general was that a single station could upload, at say 500Mbps,
but 20 stations could only do about 325Mbps.  If we fixed the MCS at 3x3 MCS7,
then the 20 station upload test ran about 490Mbps.

There were several optimizations I made in the ath10k firmware rate-ctrl.  One
was to penalize rates with higher PER (packet error rate) more than the old 
algorithm did.  This helped
a small bit, but not enough (around 350-370Mbps total throughput).

Then, after adding logs I noticed that each station was probing once about 
every 5 ampdu
chains, or almost 20% of the time!  These probe AMPDUs are limited to a max of 
4 AMSDUs,
and that explains why my 'bad' case showed 17% of the AMPDU chains were 4 in 
length in
my wifi-diag output.

I changed the firmware to take number of active stations into account, and 
increase the
75ms probe interval by up to a factor of 5.  I also probe less often when the 
probed
rate has PER > 5 or the last probe had a dropped frame.

And, I allow probing with AMPDU chains of up to 16 AMSDU instead of just 4.

Together this gets me up to about 460Mbps in this test case.   Still not quite 
as good
as fixing the MCS at 7, but good enough I think.

Here's hoping this email will let other folks poking at rate-ctrl have a faster
time at fixing things than I did.

Thanks,
Ben

--
Ben Greear 
Candela Technologies Inc  http://www.candelatech.com



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

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

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

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

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

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

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

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



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

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

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

diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/mac.c 
b/drivers/net/wireless/mediatek/mt76/mt76x0/mac.c
index 98d4a97f0a72..fa7f59a14a77 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x0/mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x0/mac.c
@@ -85,26 +85,6 @@ void mt76x0_mac_set_short_preamble(struct mt76x02_dev *dev, 
bool short_preamb)
mt76_clear(dev, MT_AUTO_RSP_CFG, MT_AUTO_RSP_PREAMB_SHORT);
 }
 
-void mt76x0_mac_config_tsf(struct mt76x02_dev *dev, bool enable, int interval)
-{
-   u32 val = mt76_rr(dev, MT_BEACON_TIME_CFG);
-
-   val &= ~(MT_BEACON_TIME_CFG_TIMER_EN |
-MT_BEACON_TIME_CFG_SYNC_MODE |
-MT_BEACON_TIME_CFG_TBTT_EN);
-
-   if (!enable) {
-   mt76_wr(dev, MT_BEACON_TIME_CFG, val);
-   return;
-   }
-
-   val &= ~MT_BEACON_TIME_CFG_INTVAL;
-   val |= FIELD_PREP(MT_BEACON_TIME_CFG_INTVAL, interval << 4) |
-   MT_BEACON_TIME_CFG_TIMER_EN |
-   MT_BEACON_TIME_CFG_SYNC_MODE |
-   MT_BEACON_TIME_CFG_TBTT_EN;
-}
-
 void mt76x0_mac_set_ampdu_factor(struct mt76x02_dev *dev)
 {
struct ieee80211_sta *sta;
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/main.c 
b/drivers/net/wireless/mediatek/mt76/mt76x0/main.c
index 4435d8e65a00..50ef97444b58 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x0/main.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x0/main.c
@@ -72,30 +72,23 @@ int mt76x0_config(struct ieee80211_hw *hw, u32 changed)
 }
 EXPORT_SYMBOL_GPL(mt76x0_config);
 
-static void
-mt76x0_addr_wr(struct mt76x02_dev *dev, const u32 offset, const u8 *addr)
-{
-   mt76_wr(dev, offset, get_unaligned_le32(addr));
-   mt76_wr(dev, offset + 4, addr[4] | addr[5] << 8);
-}
-
 void mt76x0_bss_info_changed(struct ieee80211_hw *hw,
 struct ieee80211_vif *vif,
 struct ieee80211_bss_conf *info, u32 changed)
 {
+   struct mt76x02_vif *mvif = (struct mt76x02_vif *)vif->drv_priv;
struct mt76x02_dev *dev = hw->priv;
 
mutex_lock(>mt76.mutex);
 
-   if (changed & BSS_CHANGED_BSSID) {
-   mt76x0_addr_wr(dev, MT_MAC_BSSID_DW0, info->bssid);
+   if (changed & BSS_CHANGED_BSSID)
+   mt76x02_mac_set_bssid(dev, mvif->idx, info->bssid);
 
-   /* Note: this is a hack because beacon_int is not changed
-*   on leave nor is any more appropriate event generated.
-*   rt2x00 doesn't seem to be bothered though.
-*/
-   if (is_zero_ether_addr(info->bssid))
-   mt76x0_mac_config_tsf(dev, false, 0);
+   if (changed & BSS_CHANGED_BEACON_ENABLED) {
+   tasklet_disable(>pre_tbtt_tasklet);
+   mt76x02_mac_set_beacon_enable(dev, mvif->idx,
+ info->enable_beacon);
+   tasklet_enable(>pre_tbtt_tasklet);
}
 
if (changed & BSS_CHANGED_BASIC_RATES) {
@@ -106,8 +99,13 @@ void mt76x0_bss_info_changed(struct ieee80211_hw *hw,
mt76_wr(dev, MT_LG_FBK_CFG1, 0x2100);
}
 
-   if (changed & BSS_CHANGED_BEACON_INT)
-   mt76x0_mac_config_tsf(dev, true, info->beacon_int);
+   if (changed & BSS_CHANGED_BEACON_INT) {
+   mt76_rmw_field(dev, MT_BEACON_TIME_CFG,
+  MT_BEACON_TIME_CFG_INTVAL,
+  info->beacon_int << 4);
+   dev->beacon_int = info->beacon_int;
+   dev->tbtt_count = 0;
+   }
 
if (changed & BSS_CHANGED_HT || changed & BSS_CHANGED_ERP_CTS_PROT)
mt76x0_mac_set_protection(dev, info->use_cts_prot,
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h 
b/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h
index 79c70c74d5d4..33d5ed47b5de 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h
@@ -67,7 +67,6 @@ void mt76x0_phy_calibrate(struct mt76x02_dev *dev, bool 
power_on);
 void mt76x0_mac_set_protection(struct mt76x02_dev *dev, bool legacy_prot,
int ht_mode);
 void mt76x0_mac_set_short_preamble(struct mt76x02_dev *dev, bool short_preamb);
-void mt76x0_mac_config_tsf(struct mt76x02_dev *dev, bool enable, int interval);
 void mt76x0_mac_set_ampdu_factor(struct mt76x02_dev *dev);
 
 #endif
diff 

[RFC 8/9] mt76: introduce mt76x02_init_beacon_config routine

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

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

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

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

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

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

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

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

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

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

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

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

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

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

diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/main.c 
b/drivers/net/wireless/mediatek/mt76/mt76x0/main.c
index 6fa57cd1c337..4435d8e65a00 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x0/main.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x0/main.c
@@ -127,24 +127,6 @@ void mt76x0_bss_info_changed(struct ieee80211_hw *hw,
 }
 EXPORT_SYMBOL_GPL(mt76x0_bss_info_changed);
 
-void mt76x0_sw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
-   const u8 *mac_addr)
-{
-   struct mt76x02_dev *dev = hw->priv;
-
-   set_bit(MT76_SCANNING, >mt76.state);
-}
-EXPORT_SYMBOL_GPL(mt76x0_sw_scan);
-
-void mt76x0_sw_scan_complete(struct ieee80211_hw *hw,
-struct ieee80211_vif *vif)
-{
-   struct mt76x02_dev *dev = hw->priv;
-
-   clear_bit(MT76_SCANNING, >mt76.state);
-}
-EXPORT_SYMBOL_GPL(mt76x0_sw_scan_complete);
-
 int mt76x0_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
 {
struct mt76x02_dev *dev = hw->priv;
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h 
b/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h
index 17ad3fa0858b..79c70c74d5d4 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h
@@ -53,10 +53,6 @@ int mt76x0_config(struct ieee80211_hw *hw, u32 changed);
 void mt76x0_bss_info_changed(struct ieee80211_hw *hw,
 struct ieee80211_vif *vif,
 struct ieee80211_bss_conf *info, u32 changed);
-void mt76x0_sw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
-   const u8 *mac_addr);
-void mt76x0_sw_scan_complete(struct ieee80211_hw *hw,
-struct ieee80211_vif *vif);
 int mt76x0_set_rts_threshold(struct ieee80211_hw *hw, u32 value);
 
 /* PHY */
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/pci.c 
b/drivers/net/wireless/mediatek/mt76/mt76x0/pci.c
index 39e1f87c3d2c..5e9160348433 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x0/pci.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x0/pci.c
@@ -80,8 +80,8 @@ static const struct ieee80211_ops mt76x0e_ops = {
.sta_remove = mt76x02_sta_remove,
.set_key = mt76x02_set_key,
.conf_tx = mt76x02_conf_tx,
-   .sw_scan_start = mt76x0_sw_scan,
-   .sw_scan_complete = mt76x0_sw_scan_complete,
+   .sw_scan_start = mt76x02_sw_scan,
+   .sw_scan_complete = mt76x02_sw_scan_complete,
.ampdu_action = mt76x02_ampdu_action,
.sta_rate_tbl_update = mt76x02_sta_rate_tbl_update,
.wake_tx_queue = mt76_wake_tx_queue,
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c 
b/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c
index ea517864186b..f7e39b5405fe 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c
@@ -151,8 +151,8 @@ static const struct ieee80211_ops mt76x0u_ops = {
.sta_remove = mt76x02_sta_remove,
.set_key = mt76x02_set_key,
.conf_tx = mt76x02_conf_tx,
-   .sw_scan_start = mt76x0_sw_scan,
-   .sw_scan_complete = mt76x0_sw_scan_complete,
+   .sw_scan_start = mt76x02_sw_scan,
+   .sw_scan_complete = mt76x02_sw_scan_complete,
.ampdu_action = mt76x02_ampdu_action,
.sta_rate_tbl_update = mt76x02_sta_rate_tbl_update,
.set_rts_threshold = mt76x0_set_rts_threshold,
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02.h 
b/drivers/net/wireless/mediatek/mt76/mt76x02.h
index 1cd0f758587d..0890794c92d7 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02.h
@@ -147,6 +147,10 @@ int mt76x02_tx_prepare_skb(struct mt76_dev *mdev, void 
*txwi,
   struct sk_buff *skb, struct mt76_queue *q,
   struct mt76_wcid *wcid, struct ieee80211_sta *sta,
   u32 *tx_info);
+void mt76x02_sw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+const u8 *mac);
+void mt76x02_sw_scan_complete(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif);
 
 extern const u16 mt76x02_beacon_offsets[16];
 void 

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

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

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

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

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

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

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

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

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

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

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

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

-- 
2.19.0



Large number of crda failures

2018-10-16 Thread Adam Cottrel
Hi,

On start up I am getting a large number of error faults reported with CRDA:-
➢ ies0600133 systemd-udevd[3949]: Process '/sbin/crda' failed with exit code 234
Typically, over 50 lines are reported to the syslogs

However, once the system has fully started, I do not get any issues with 
running:-
➢ iw reg set XX

These errors are doubling the boot time for Linux. My kernel is 4.14.4 and I am 
running a Debian base.

Please can someone advise what is going wrong?

Best,
Adam


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

2018-10-16 Thread Stanislaw Gruszka
Hello

On Tue, Oct 16, 2018 at 01:32:18PM +0200, Tom Psyborg wrote:
> I am sending you two builds privately so please check if there are any
> differences between the two builds and report back. Thanks.

I extracted rt2800lib.ko module from provided images, did disassembly via:

./staging_dir/toolchain-mipsel_24kc_gcc-7.3.0_musl/bin/mipsel-openwrt-linux-objdump
 \
 -d -r --prefix-addresses ~/rt2800lib-BUILDn.ko  > ~/BUILDn.dump.txt

command and compered disassembled code. Here is difference:

$ diff -up  BUILD1.dump.txt BUILD2.dump.txt 
--- BUILD1.dump.txt 2018-10-16 16:40:34.834220838 +0200
+++ BUILD2.dump.txt 2018-10-16 16:40:40.187219211 +0200
@@ -1,5 +1,5 @@
 
-/home/stasiu/rt2800lib-BUILD1.ko: file format elf32-tradlittlemips
+/home/stasiu/rt2800lib-BUILD2.ko: file format elf32-tradlittlemips
 
 
 Disassembly of section .text:
@@ -9374,7 +9374,7 @@ Disassembly of section .text:
 7f80  jalr  v0
 7f84  move  a0,s0
 7f88  lhu   v1,732(s0)
-7f8c  liv0,21392
+7f8c  liv0,25426
 7f90  bne   v1,v0,810c 

 7f94  lia2,1025
 7f98  lwv0,4(s0)

There is no difference in init_registers (which is inlined in
rt2800_enable_radio). The only difference is in some number
rt2800_clear_beacon() function.

Regards
Stanislaw


RE: [EXTERNAL] Re: [PATCH 1/3] cfg80211: Add support to configure station specific RSSI threshold for AP mode

2018-10-16 Thread Tamizh Chelvam Raja
>> +static int nl80211_set_sta_mon(struct sk_buff *skb, struct genl_info 
>> +*info) {
>> +   struct cfg80211_registered_device *rdev = info->user_ptr[0];
>> +   struct net_device *dev = info->user_ptr[1];
>> +   struct nlattr *attrs[NL80211_ATTR_CQM_MAX + 1];
>> +   bool fixed_thold = false;
>> +   struct nlattr *sta_mon;
>> +   u8 *addr = NULL;
>> +   int err;
>> +
>> +   if (!wiphy_ext_feature_isset(>wiphy,
>> +
>> NL80211_EXT_FEATURE_STA_MON_RSSI_CONFIG))
>> +   return -EOPNOTSUPP;
>> +
>> +   sta_mon = info->attrs[NL80211_ATTR_CQM];
>> +   if (!sta_mon || !(info->attrs[NL80211_ATTR_MAC]))
>> +   return -EINVAL;
>> +
>> +   err = nla_parse_nested(attrs, NL80211_ATTR_CQM_MAX, sta_mon,
>> +  nl80211_attr_cqm_policy, info->extack);
>> +   if (err)
>> +   return err;
>> +
>> +   addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
>> +   fixed_thold =
>> +   
>> + nla_get_flag(info->attrs[NL80211_ATTR_STA_MON_FIXED_THOLD]);
>> +
>> +   if (attrs[NL80211_ATTR_CQM_RSSI_THOLD] &&
>> +   attrs[NL80211_ATTR_CQM_RSSI_HYST]) {
>> +   const s32 *thresholds =
>> +   nla_data(attrs[NL80211_ATTR_CQM_RSSI_THOLD]);
>> +   int len = nla_len(attrs[NL80211_ATTR_CQM_RSSI_THOLD]);
>> +   u32 hysteresis = 
>> + nla_get_u32(attrs[NL80211_ATTR_CQM_RSSI_HYST]);
>> +
>> +   if (len % 4)
>> +   return -EINVAL;
>> +
>> +   err = nl80211_validate_rssi_tholds(thresholds, len / 4);
>> +   if (err)
>> +   return err;
>> +
>> +   return rdev_set_sta_mon_rssi_config(rdev, dev, addr, 
>> thresholds,
>> +   hysteresis, len / 4,
>> +   fixed_thold);
>> +   }
>> +
>> +   return -EINVAL;
>> +}

>IIUC there is a noticeable overlap between this new command and existing 
>nl80211_set_cqm_rssi command. Is there any reason why >nl80211_set_cqm_rss can 
>not be adapted for AP case ?

[Tamizh] This new command for AP mode introduced as per the previous 
discussion. 

>If there is a reason to handle AP case separately, then it looks like it makes 
>sense to add explicit check for supported iftype in this new command. 
>>Besides, it looks like there is no generic way to handle disabling of RSSI 
>monitoring in the new command.
>As a result, we may end up in multiple driver specific implementations.

[Tamizh] thanks for pointing me out. I'll add the ifmode check in the next 
patchset version.

Thanks,
Tamizh.


Re: [PATCH 3/3] mac80211: Implement functionality to monitor station's signal stregnth

2018-10-16 Thread Sergey Matyukevich
> +/*
> + * How many frames need to have been used in average station's
> + * signal strength before checking against the threshold
> + */
> +#define IEEE80211_STA_SIGNAL_AVE_MIN_COUNT 4
> +
> +
>  /* there are 40 bytes if you don't need the rateset to be kept */
>  #define IEEE80211_TX_INFO_DRIVER_DATA_SIZE 40

...

> +static void ieee80211_sta_rx_signal_thold_check(struct ieee80211_rx_data *rx)
> +{
> +   struct sta_info *sta = rx->sta;
> +   struct ieee80211_bss_conf *bss_conf = >sdata->vif.bss_conf;
> +   bool rssi_cross =  false;
> +
> +   if (!wiphy_ext_feature_isset(rx->local->hw.wiphy,
> +   NL80211_EXT_FEATURE_STA_MON_RSSI_CONFIG))
> +   return;
> +
> +   sta->count_rx_signal++;
> +   if (sta->count_rx_signal < IEEE80211_STA_SIGNAL_AVE_MIN_COUNT)
> +   return;

Could you please clarify count_rx_signal processing and averaging
approach ? I couldn't find where this counter is reset or
modified in any other way.

Regards,
Sergey


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

2018-10-16 Thread Tom Psyborg
On 16/10/2018, Stanislaw Gruszka  wrote:
> On Fri, Oct 12, 2018 at 02:41:41PM +0200, Tom Psyborg wrote:
>> On 12/10/2018, Stanislaw Gruszka  wrote:
>> > On Fri, Oct 12, 2018 at 02:20:07PM +0200, Tom Psyborg wrote:
>> >> > On upstream tree where this patch is intended
>> >> > additional registers where never programmed as proper branch
>> >> > were never used, because of additional check in RT5390 branch.
>> >> >
>> >>
>> >> on my hardware additional registers were programmed in regardless of
>> >> redundant check. that why i opened whole thread on forum since i
>> >> couldn't understand how's that happening
>> >
>> > I don't understand how that possible either.
>>
>> i'd assume because device use external lna
>
> I have no idea how this could be related. But I think I found
> somewhat reasonable explenation where the problem is.
> I think below code :
>
>   if (a || b || c) {
>   CODE1();
>   } else if (c) {
>   CODE2();
>   }
>
> can not be deterministic and can be compiled differently depending
> on compiler version and used options. Sometimes it could result
> in this
>
>   if (a || b || c) {
>   CODE1();
>   }
>
> and sometimes in this:
>
>   if (a || b) {
>   CODE1();
>   } else if (c) {
>   CODE2();
>   }
>
> So that would explain the problems you see. And indeed patch
> could cause regression on systems where second variant of
> initalizing RT6352 registers was used.
>
> Thanks
> Stanislaw
>

Hi

I am sending you two builds privately so please check if there are any
differences between the two builds and report back. Thanks.


Re: [PATCH 1/3] cfg80211: Add support to configure station specific RSSI threshold for AP mode

2018-10-16 Thread Sergey Matyukevich
> Signed-off-by: Tamizh chelvam 
> ---
>  include/net/cfg80211.h   |   28 +
>  include/uapi/linux/nl80211.h |   18 ++
>  net/wireless/nl80211.c   |  131 
> +-
>  net/wireless/rdev-ops.h  |   18 ++
>  4 files changed, 181 insertions(+), 14 deletions(-)

...

> +static int nl80211_set_sta_mon(struct sk_buff *skb, struct genl_info *info)
> +{
> +   struct cfg80211_registered_device *rdev = info->user_ptr[0];
> +   struct net_device *dev = info->user_ptr[1];
> +   struct nlattr *attrs[NL80211_ATTR_CQM_MAX + 1];
> +   bool fixed_thold = false;
> +   struct nlattr *sta_mon;
> +   u8 *addr = NULL;
> +   int err;
> +
> +   if (!wiphy_ext_feature_isset(>wiphy,
> +NL80211_EXT_FEATURE_STA_MON_RSSI_CONFIG))
> +   return -EOPNOTSUPP;
> +
> +   sta_mon = info->attrs[NL80211_ATTR_CQM];
> +   if (!sta_mon || !(info->attrs[NL80211_ATTR_MAC]))
> +   return -EINVAL;
> +
> +   err = nla_parse_nested(attrs, NL80211_ATTR_CQM_MAX, sta_mon,
> +  nl80211_attr_cqm_policy, info->extack);
> +   if (err)
> +   return err;
> +
> +   addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
> +   fixed_thold =
> +   nla_get_flag(info->attrs[NL80211_ATTR_STA_MON_FIXED_THOLD]);
> +
> +   if (attrs[NL80211_ATTR_CQM_RSSI_THOLD] &&
> +   attrs[NL80211_ATTR_CQM_RSSI_HYST]) {
> +   const s32 *thresholds =
> +   nla_data(attrs[NL80211_ATTR_CQM_RSSI_THOLD]);
> +   int len = nla_len(attrs[NL80211_ATTR_CQM_RSSI_THOLD]);
> +   u32 hysteresis = 
> nla_get_u32(attrs[NL80211_ATTR_CQM_RSSI_HYST]);
> +
> +   if (len % 4)
> +   return -EINVAL;
> +
> +   err = nl80211_validate_rssi_tholds(thresholds, len / 4);
> +   if (err)
> +   return err;
> +
> +   return rdev_set_sta_mon_rssi_config(rdev, dev, addr, 
> thresholds,
> +   hysteresis, len / 4,
> +   fixed_thold);
> +   }
> +
> +   return -EINVAL;
> +}

IIUC there is a noticeable overlap between this new command and
existing nl80211_set_cqm_rssi command. Is there any reason why
nl80211_set_cqm_rss can not be adapted for AP case ?

If there is a reason to handle AP case separately, then it looks
like it makes sense to add explicit check for supported iftype
in this new command. Besides, it looks like there is no generic
way to handle disabling of RSSI monitoring in the new command.
As a result, we may end up in multiple driver
specific implementations.

Regards,
Sergey


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

2018-10-16 Thread Felix Fietkau
On 2018-10-16 13:21, Stanislaw Gruszka wrote:
> On Tue, Oct 16, 2018 at 01:19:52PM +0200, Felix Fietkau wrote:
>> > I have no idea how this could be related. But I think I found
>> > somewhat reasonable explenation where the problem is.
>> > I think below code :
>> > 
>> >if (a || b || c) {
>> >CODE1();
>> >} else if (c) {
>> >CODE2();
>> >}
>> > 
>> > can not be deterministic and can be compiled differently depending
>> > on compiler version and used options. Sometimes it could result
>> > in this 
>> > 
>> >if (a || b || c) {
>> >CODE1();
>> >}
>> > 
>> > and sometimes in this:
>> > 
>> >if (a || b) {
>> >CODE1();
>> >} else if (c) {
>> >CODE2();
>> >}
>> > 
>> > So that would explain the problems you see. And indeed patch
>> > could cause regression on systems where second variant of
>> > initalizing RT6352 registers was used.
>> I don't see how that can be non-deterministic at all. The 'else if' part
>> can only be hit if the first if did not match.
> 
> I meant non-deterministic during compilation process, when compiler
> do or do not some optimizations or if compiler version differs.
In my opinion, this is not C undefined behavior territory. The compiler
is not allowed to change the behavior here based on optimization settings.

- Felix


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

2018-10-16 Thread Stanislaw Gruszka
On Tue, Oct 16, 2018 at 01:19:52PM +0200, Felix Fietkau wrote:
> > I have no idea how this could be related. But I think I found
> > somewhat reasonable explenation where the problem is.
> > I think below code :
> > 
> > if (a || b || c) {
> > CODE1();
> > } else if (c) {
> > CODE2();
> > }
> > 
> > can not be deterministic and can be compiled differently depending
> > on compiler version and used options. Sometimes it could result
> > in this 
> > 
> > if (a || b || c) {
> > CODE1();
> > }
> > 
> > and sometimes in this:
> > 
> > if (a || b) {
> > CODE1();
> > } else if (c) {
> > CODE2();
> > }
> > 
> > So that would explain the problems you see. And indeed patch
> > could cause regression on systems where second variant of
> > initalizing RT6352 registers was used.
> I don't see how that can be non-deterministic at all. The 'else if' part
> can only be hit if the first if did not match.

I meant non-deterministic during compilation process, when compiler
do or do not some optimizations or if compiler version differs.

Regards
Stanislaw


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

2018-10-16 Thread Felix Fietkau
On 2018-10-16 10:09, Stanislaw Gruszka wrote:
> On Fri, Oct 12, 2018 at 02:41:41PM +0200, Tom Psyborg wrote:
>> On 12/10/2018, Stanislaw Gruszka  wrote:
>> > On Fri, Oct 12, 2018 at 02:20:07PM +0200, Tom Psyborg wrote:
>> >> > On upstream tree where this patch is intended
>> >> > additional registers where never programmed as proper branch
>> >> > were never used, because of additional check in RT5390 branch.
>> >> >
>> >>
>> >> on my hardware additional registers were programmed in regardless of
>> >> redundant check. that why i opened whole thread on forum since i
>> >> couldn't understand how's that happening
>> >
>> > I don't understand how that possible either.
>> 
>> i'd assume because device use external lna
> 
> I have no idea how this could be related. But I think I found
> somewhat reasonable explenation where the problem is.
> I think below code :
> 
>   if (a || b || c) {
>   CODE1();
>   } else if (c) {
>   CODE2();
>   }
> 
> can not be deterministic and can be compiled differently depending
> on compiler version and used options. Sometimes it could result
> in this 
> 
>   if (a || b || c) {
>   CODE1();
>   }
> 
> and sometimes in this:
> 
>   if (a || b) {
>   CODE1();
>   } else if (c) {
>   CODE2();
>   }
> 
> So that would explain the problems you see. And indeed patch
> could cause regression on systems where second variant of
> initalizing RT6352 registers was used.
I don't see how that can be non-deterministic at all. The 'else if' part
can only be hit if the first if did not match.

- Felix


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

2018-10-16 Thread Daniel Golle
On Tue, Oct 16, 2018 at 10:11:16AM +0200, Stanislaw Gruszka wrote:
> On Fri, Oct 12, 2018 at 12:48:07PM +0200, Tom Psyborg wrote:
> > chip version support exist in daniel's tree since a long time ago. so
> > don't disable registers initialization but try to upstream his
> > changes.
> 
> Where is this patch ? I can not find it.

So this requires to make the chip version and package available to
drivers like rt2x00. First of all, this is a patch for linux-mips:

https://git.openwrt.org/?p=openwrt/staging/dangole.git;a=blob;f=target/linux/ramips/patches-4.4/300-mt7620-export-chip-version-and-pkg.patch;h=f6aca6c90516f9c534b3c51e9f99dff6a3f41b75;hb=709fe05dfea58728d6accb9fe56c7056d9d0715b

It belongs to this (very outdated) tree:
https://git.openwrt.org/?p=openwrt/staging/dangole.git;a=shortlog;h=refs/heads/differentiate-pkg-ver-eco

I'm not sure whether this is the right way to do this, but it worked.


Cheers


Daniel



> 
> Thanks
> Stanislaw


iwlmvm crashes when connecting to a WPA-Enterprise network

2018-10-16 Thread Damjan Georgievski
each time I connect to the corporate wpa-enterprise network, iwlmvm crashes

distro is ArchLinux
- kernel is 4.19.0-rc8+
- networkmanager 1.14.1dev+13+g0d3234478-1
- wpa_supplicant 1:2.6-12



[ 1257.940526] BUG: scheduling while atomic: irq/133-iwlwifi/388/0x0403
[ 1257.940535] Modules linked in: ccm cmac rfcomm joydev mousedev
rmi_smbus bnep rmi_core arc4 iTCO_wdt iTCO_vendor_support wmi_bmof
intel_wmi_thunderbolt iwlmvm snd_soc_skl snd_soc_skl_ipc
snd_soc_sst_ipc mac80211 snd_soc_sst_dsp snd_hda_ext_core btusb
snd_soc_acpi_intel_match snd_soc_acpi uvcvideo intel_rapl snd_soc_core
snd_hda_codec_hdmi x86_pkg_temp_thermal intel_powerclamp btrtl
snd_hda_codec_conexant snd_hda_codec_generic snd_compress
videobuf2_vmalloc btbcm videobuf2_memops ac97_bus btintel
videobuf2_v4l2 coretemp snd_pcm_dmaengine iwlwifi videobuf2_common
psmouse snd_hda_intel kvm_intel bluetooth videodev snd_hda_codec
e1000e intel_cstate qcserial intel_uncore intel_rapl_perf usb_wwan
cdc_mbim cdc_wdm input_leds snd_hda_core pcspkr media cdc_ncm
usbserial usbnet mii cfg80211 snd_hwdep ecdh_generic
[ 1257.940645]  snd_pcm ptp pps_core i2c_i801 snd_timer rtsx_pci_ms
thinkpad_acpi memstick mei_me mei intel_pch_thermal nvram ucsi_acpi
typec_ucsi rfkill tpm_crb typec wmi snd soundcore led_class i2c_hid
battery ac tpm_tis rtc_cmos hid tpm_tis_core evdev tpm mac_hid
rng_core pcc_cpufreq usbip_host usbip_core sg scsi_mod crypto_user
ip_tables x_tables ext4 crc32c_generic crc16 mbcache jbd2 fscrypto
algif_skcipher af_alg dm_crypt dm_mod rtsx_pci_sdmmc crct10dif_pclmul
crc32_pclmul serio_raw crc32c_intel ghash_clmulni_intel atkbd mmc_core
pcbc libps2 aesni_intel xhci_pci aes_x86_64 crypto_simd xhci_hcd
cryptd glue_helper usbcore rtsx_pci usb_common i8042 serio
nls_iso8859_1 nls_cp437 vfat fat i915 intel_gtt i2c_algo_bit
drm_kms_helper syscopyarea sysfillrect sysimgblt fb_sys_fops drm
agpgart kvmgt vfio_mdev
[ 1257.940816]  mdev vfio_iommu_type1 vfio kvm irqbypass
[ 1257.940833] Preemption disabled at:
[ 1257.940865] [] iwl_pcie_irq_handler+0x6f5/0xbc0 [iwlwifi]
[ 1257.940882] CPU: 2 PID: 388 Comm: irq/133-iwlwifi Tainted: G
W 4.19.0-rc8+ #14
[ 1257.940887] Hardware name: LENOVO 20HQS0LV00/20HQS0LV00, BIOS
N1MET49W (1.34 ) 07/02/2018
[ 1257.940892] Call Trace:
[ 1257.940912]  dump_stack+0x5c/0x80
[ 1257.940938]  ? iwl_pcie_irq_handler+0x6f5/0xbc0 [iwlwifi]
[ 1257.940950]  __schedule_bug.cold.14+0x82/0x9b
[ 1257.940960]  __schedule+0x6fd/0x8b0
[ 1257.940971]  schedule+0x32/0x90
[ 1257.940981]  schedule_timeout+0x1d1/0x4a0
[ 1257.940995]  ? collect_expired_timers+0xa0/0xa0
[ 1257.941025]  iwl_trans_pcie_send_hcmd+0x2a4/0x520 [iwlwifi]
[ 1257.941039]  ? wait_woken+0x80/0x80
[ 1257.941075]  iwl_trans_send_cmd+0x61/0xd0 [iwlwifi]
[ 1257.941099]  iwl_mvm_send_cmd+0x2c/0x90 [iwlmvm]
[ 1257.941125]  ? rs_fill_lq_cmd+0x267/0x4e0 [iwlmvm]
[ 1257.941145]  iwl_mvm_send_lq_cmd+0x73/0xa0 [iwlmvm]
[ 1257.941168]  iwl_mvm_rs_rate_init+0x952/0xd10 [iwlmvm]
[ 1257.941192]  iwl_mvm_rs_tx_status+0x66c/0x21c0 [iwlmvm]
[ 1257.941247]  ? ieee80211_prepare_and_rx_handle+0xbe7/0x1250 [mac80211]
[ 1257.941288]  rate_control_tx_status+0x9e/0xb0 [mac80211]
[ 1257.941320]  __ieee80211_tx_status+0x449/0x8e0 [mac80211]
[ 1257.941355]  ? sta_info_hash_lookup+0xe3/0x120 [mac80211]
[ 1257.941384]  ieee80211_tx_status+0x89/0xc0 [mac80211]
[ 1257.941406]  iwl_mvm_rx_tx_cmd+0x447/0x8b0 [iwlmvm]
[ 1257.941432]  ? iwl_pcie_gen2_tx_init+0x140/0x140 [iwlwifi]
[ 1257.941451]  iwl_pcie_rx_handle+0x252/0x9e0 [iwlwifi]
[ 1257.941472]  iwl_pcie_irq_handler+0x6ff/0xbc0 [iwlwifi]
[ 1257.941484]  ? irq_forced_thread_fn+0x70/0x70
[ 1257.941492]  irq_thread_fn+0x1f/0x50
[ 1257.941501]  irq_thread+0xe7/0x170
[ 1257.941510]  ? wake_threads_waitq+0x30/0x30
[ 1257.941522]  ? irq_thread_dtor+0x80/0x80
[ 1257.941529]  kthread+0x112/0x130
[ 1257.941536]  ? kthread_park+0x80/0x80
[ 1257.941545]  ret_from_fork+0x35/0x40
[ 1259.948869] iwlwifi :04:00.0: Error sending LQ_CMD: time out
after 2000ms.
[ 1259.948880] iwlwifi :04:00.0: Current CMD queue read_ptr 99 write_ptr 100
[ 1259.949046] iwlwifi :04:00.0: Start IWL Error Log Dump:
[ 1259.949052] iwlwifi :04:00.0: Status: 0x0100, count: 6
[ 1259.949057] iwlwifi :04:00.0: Loaded firmware version: 36.e91976c0.0
[ 1259.949063] iwlwifi :04:00.0: 0x0084 | NMI_INTERRUPT_UNKNOWN
[ 1259.949068] iwlwifi :04:00.0: 0x00A00220 | trm_hw_status0
[ 1259.949073] iwlwifi :04:00.0: 0x | trm_hw_status1
[ 1259.949078] iwlwifi :04:00.0: 0x000248DC | branchlink2
[ 1259.949083] iwlwifi :04:00.0: 0x0003A7DA | interruptlink1
[ 1259.949088] iwlwifi :04:00.0: 0x0003A7DA | interruptlink2
[ 1259.949093] iwlwifi :04:00.0: 0x | data1
[ 1259.949097] iwlwifi :04:00.0: 0x0080 | data2
[ 1259.949102] iwlwifi :04:00.0: 0x0783 | data3
[ 1259.949107] iwlwifi :04:00.0: 0x14C01989 | beacon time
[ 1259.949112] iwlwifi :04:00.0: 0xD0D7A45A | tsf low
[ 1259.949117] iwlwifi :04:00.0: 

[PATCH v2 2/2] qtnfmac: add support for Topaz chipsets

2018-10-16 Thread Sergey Matyukevich
This patch adds support for QSR1000/QSR2000 family of chipsets
to qtnfmac_pcie platform driver.

QSR1000/QSR2000 (aka Topaz) is a family of 80MHz, 11ac Wave2,
4x4/2x4/2x2 chips, including single and dual band devices.
Depending on specific chip model and firmware in use, either
STA or both STA and AP modes are supported.

Patch adds Topaz support to qtnfmac_pcie driver. Proper platform
bus will be selected on probing based on chip ID.

Signed-off-by: Igor Mitsyanko 
Signed-off-by: Sergey Matyukevich 
Signed-off-by: Andrey Shevchenko 
---
 drivers/net/wireless/quantenna/qtnfmac/Kconfig |5 +-
 drivers/net/wireless/quantenna/qtnfmac/Makefile|3 +-
 drivers/net/wireless/quantenna/qtnfmac/pcie/pcie.c |5 +-
 .../wireless/quantenna/qtnfmac/pcie/pcie_priv.h|1 +
 .../wireless/quantenna/qtnfmac/pcie/topaz_pcie.c   | 1219 
 .../quantenna/qtnfmac/pcie/topaz_pcie_ipc.h|   94 ++
 .../quantenna/qtnfmac/pcie/topaz_pcie_regs.h   |   45 +
 .../net/wireless/quantenna/qtnfmac/qtn_hw_ids.h|4 +-
 drivers/net/wireless/quantenna/qtnfmac/util.c  |2 +
 9 files changed, 1373 insertions(+), 5 deletions(-)
 create mode 100644 drivers/net/wireless/quantenna/qtnfmac/pcie/topaz_pcie.c
 create mode 100644 drivers/net/wireless/quantenna/qtnfmac/pcie/topaz_pcie_ipc.h
 create mode 100644 
drivers/net/wireless/quantenna/qtnfmac/pcie/topaz_pcie_regs.h

diff --git a/drivers/net/wireless/quantenna/qtnfmac/Kconfig 
b/drivers/net/wireless/quantenna/qtnfmac/Kconfig
index 696c50066b53..6cf5202c3666 100644
--- a/drivers/net/wireless/quantenna/qtnfmac/Kconfig
+++ b/drivers/net/wireless/quantenna/qtnfmac/Kconfig
@@ -5,7 +5,7 @@ config QTNFMAC
default y if QTNFMAC_PCIE=y
 
 config QTNFMAC_PCIE
-   tristate "Quantenna QSR10g PCIe support"
+   tristate "Quantenna QSR1000/QSR2000/QSR10g PCIe support"
default n
depends on PCI && CFG80211
select QTNFMAC
@@ -13,7 +13,8 @@ config QTNFMAC_PCIE
select CRC32
help
  This option adds support for wireless adapters based on Quantenna
- 802.11ac QSR10g (aka Pearl) FullMAC chipset running over PCIe.
+ 802.11ac QSR10g (aka Pearl) and QSR1000/QSR2000 (aka Topaz)
+ FullMAC chipsets running over PCIe.
 
  If you choose to build it as a module, two modules will be built:
  qtnfmac.ko and qtnfmac_pcie.ko.
diff --git a/drivers/net/wireless/quantenna/qtnfmac/Makefile 
b/drivers/net/wireless/quantenna/qtnfmac/Makefile
index d7e8185fddab..40dffbd2ea47 100644
--- a/drivers/net/wireless/quantenna/qtnfmac/Makefile
+++ b/drivers/net/wireless/quantenna/qtnfmac/Makefile
@@ -24,6 +24,7 @@ obj-$(CONFIG_QTNFMAC_PCIE) += qtnfmac_pcie.o
 qtnfmac_pcie-objs += \
shm_ipc.o \
pcie/pcie.o \
-   pcie/pearl_pcie.o
+   pcie/pearl_pcie.o \
+   pcie/topaz_pcie.o
 
 qtnfmac_pcie-$(CONFIG_DEBUG_FS) += debug.o
diff --git a/drivers/net/wireless/quantenna/qtnfmac/pcie/pcie.c 
b/drivers/net/wireless/quantenna/qtnfmac/pcie/pcie.c
index 70dd8da5b0dc..c3a32effa6f0 100644
--- a/drivers/net/wireless/quantenna/qtnfmac/pcie/pcie.c
+++ b/drivers/net/wireless/quantenna/qtnfmac/pcie/pcie.c
@@ -330,6 +330,9 @@ static int qtnf_pcie_probe(struct pci_dev *pdev, const 
struct pci_device_id *id)
case QTN_CHIP_ID_PEARL_C:
bus = qtnf_pcie_pearl_alloc(pdev);
break;
+   case QTN_CHIP_ID_TOPAZ:
+   bus = qtnf_pcie_topaz_alloc(pdev);
+   break;
default:
pr_err("unsupported chip ID 0x%x\n", chipid);
return -ENOTSUPP;
@@ -465,7 +468,7 @@ static SIMPLE_DEV_PM_OPS(qtnf_pcie_pm_ops, 
qtnf_pcie_suspend,
 
 static const struct pci_device_id qtnf_pcie_devid_table[] = {
{
-   PCIE_VENDOR_ID_QUANTENNA, PCIE_DEVICE_ID_QTN_PEARL,
+   PCIE_VENDOR_ID_QUANTENNA, PCIE_DEVICE_ID_QSR,
PCI_ANY_ID, PCI_ANY_ID, 0, 0,
},
{ },
diff --git a/drivers/net/wireless/quantenna/qtnfmac/pcie/pcie_priv.h 
b/drivers/net/wireless/quantenna/qtnfmac/pcie/pcie_priv.h
index 7c742c56efaf..bbc074e1f34d 100644
--- a/drivers/net/wireless/quantenna/qtnfmac/pcie/pcie_priv.h
+++ b/drivers/net/wireless/quantenna/qtnfmac/pcie/pcie_priv.h
@@ -76,6 +76,7 @@ void qtnf_pcie_init_shm_ipc(struct qtnf_pcie_bus_priv *priv,
struct qtnf_shm_ipc_region __iomem *ipc_rx_reg,
const struct qtnf_shm_ipc_int *ipc_int);
 struct qtnf_bus *qtnf_pcie_pearl_alloc(struct pci_dev *pdev);
+struct qtnf_bus *qtnf_pcie_topaz_alloc(struct pci_dev *pdev);
 
 static inline void qtnf_non_posted_write(u32 val, void __iomem *basereg)
 {
diff --git a/drivers/net/wireless/quantenna/qtnfmac/pcie/topaz_pcie.c 
b/drivers/net/wireless/quantenna/qtnfmac/pcie/topaz_pcie.c
new file mode 100644
index ..598edb814421
--- /dev/null
+++ b/drivers/net/wireless/quantenna/qtnfmac/pcie/topaz_pcie.c
@@ -0,0 +1,1219 @@
+// 

[PATCH v2 1/2] qtnfmac_pcie: use single PCIe driver for all platforms

2018-10-16 Thread Sergey Matyukevich
From: Igor Mitsyanko 

Single PCIe driver can identify hardware type by reading CHIP ID at
probe time and invoking a correct initialization sequence.

Signed-off-by: Igor Mitsyanko 
---
 drivers/net/wireless/quantenna/qtnfmac/Kconfig |  10 +-
 drivers/net/wireless/quantenna/qtnfmac/Makefile|   6 +-
 drivers/net/wireless/quantenna/qtnfmac/pcie/pcie.c | 279 ++---
 .../wireless/quantenna/qtnfmac/pcie/pcie_priv.h|  19 +-
 .../wireless/quantenna/qtnfmac/pcie/pearl_pcie.c   | 211 +---
 drivers/net/wireless/quantenna/qtnfmac/util.c  |  16 ++
 drivers/net/wireless/quantenna/qtnfmac/util.h  |   2 +
 7 files changed, 292 insertions(+), 251 deletions(-)

diff --git a/drivers/net/wireless/quantenna/qtnfmac/Kconfig 
b/drivers/net/wireless/quantenna/qtnfmac/Kconfig
index b8c12a5f16b4..696c50066b53 100644
--- a/drivers/net/wireless/quantenna/qtnfmac/Kconfig
+++ b/drivers/net/wireless/quantenna/qtnfmac/Kconfig
@@ -1,10 +1,10 @@
 config QTNFMAC
tristate
-   depends on QTNFMAC_PEARL_PCIE
-   default m if QTNFMAC_PEARL_PCIE=m
-   default y if QTNFMAC_PEARL_PCIE=y
+   depends on QTNFMAC_PCIE
+   default m if QTNFMAC_PCIE=m
+   default y if QTNFMAC_PCIE=y
 
-config QTNFMAC_PEARL_PCIE
+config QTNFMAC_PCIE
tristate "Quantenna QSR10g PCIe support"
default n
depends on PCI && CFG80211
@@ -16,4 +16,4 @@ config QTNFMAC_PEARL_PCIE
  802.11ac QSR10g (aka Pearl) FullMAC chipset running over PCIe.
 
  If you choose to build it as a module, two modules will be built:
- qtnfmac.ko and qtnfmac_pearl_pcie.ko.
+ qtnfmac.ko and qtnfmac_pcie.ko.
diff --git a/drivers/net/wireless/quantenna/qtnfmac/Makefile 
b/drivers/net/wireless/quantenna/qtnfmac/Makefile
index 17cd7adb4109..d7e8185fddab 100644
--- a/drivers/net/wireless/quantenna/qtnfmac/Makefile
+++ b/drivers/net/wireless/quantenna/qtnfmac/Makefile
@@ -19,11 +19,11 @@ qtnfmac-objs += \
 
 #
 
-obj-$(CONFIG_QTNFMAC_PEARL_PCIE) += qtnfmac_pearl_pcie.o
+obj-$(CONFIG_QTNFMAC_PCIE) += qtnfmac_pcie.o
 
-qtnfmac_pearl_pcie-objs += \
+qtnfmac_pcie-objs += \
shm_ipc.o \
pcie/pcie.o \
pcie/pearl_pcie.o
 
-qtnfmac_pearl_pcie-$(CONFIG_DEBUG_FS) += debug.o
+qtnfmac_pcie-$(CONFIG_DEBUG_FS) += debug.o
diff --git a/drivers/net/wireless/quantenna/qtnfmac/pcie/pcie.c 
b/drivers/net/wireless/quantenna/qtnfmac/pcie/pcie.c
index 16795dbe475b..70dd8da5b0dc 100644
--- a/drivers/net/wireless/quantenna/qtnfmac/pcie/pcie.c
+++ b/drivers/net/wireless/quantenna/qtnfmac/pcie/pcie.c
@@ -1,6 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0+
 /* Copyright (c) 2018 Quantenna Communications, Inc. All rights reserved. */
 
+#include 
 #include 
 #include 
 #include 
@@ -15,14 +16,37 @@
 #include "shm_ipc.h"
 #include "core.h"
 #include "debug.h"
-
-#undef pr_fmt
-#define pr_fmt(fmt)"qtnf_pcie: %s: " fmt, __func__
+#include "util.h"
+#include "qtn_hw_ids.h"
 
 #define QTN_SYSCTL_BAR 0
 #define QTN_SHMEM_BAR  2
 #define QTN_DMA_BAR3
 
+#define QTN_PCIE_MAX_FW_BUFSZ  (1 * 1024 * 1024)
+
+static bool use_msi = true;
+module_param(use_msi, bool, 0644);
+MODULE_PARM_DESC(use_msi, "set 0 to use legacy interrupt");
+
+static unsigned int tx_bd_size_param;
+module_param(tx_bd_size_param, uint, 0644);
+MODULE_PARM_DESC(tx_bd_size_param, "Tx descriptors queue size");
+
+static unsigned int rx_bd_size_param = 256;
+module_param(rx_bd_size_param, uint, 0644);
+MODULE_PARM_DESC(rx_bd_size_param, "Rx descriptors queue size");
+
+static u8 flashboot = 1;
+module_param(flashboot, byte, 0644);
+MODULE_PARM_DESC(flashboot, "set to 0 to use FW binary file on FS");
+
+static unsigned int fw_blksize_param = QTN_PCIE_MAX_FW_BUFSZ;
+module_param(fw_blksize_param, uint, 0644);
+MODULE_PARM_DESC(fw_blksize_param, "firmware loading block size in bytes");
+
+#define DRV_NAME   "qtnfmac_pcie"
+
 int qtnf_pcie_control_tx(struct qtnf_bus *bus, struct sk_buff *skb)
 {
struct qtnf_pcie_bus_priv *priv = get_bus_priv(bus);
@@ -58,7 +82,7 @@ int qtnf_pcie_alloc_skb_array(struct qtnf_pcie_bus_priv *priv)
return 0;
 }
 
-void qtnf_pcie_bringup_fw_async(struct qtnf_bus *bus)
+static void qtnf_pcie_bringup_fw_async(struct qtnf_bus *bus)
 {
struct qtnf_pcie_bus_priv *priv = get_bus_priv(bus);
struct pci_dev *pdev = priv->pdev;
@@ -72,7 +96,7 @@ static int qtnf_dbg_mps_show(struct seq_file *s, void *data)
struct qtnf_bus *bus = dev_get_drvdata(s->private);
struct qtnf_pcie_bus_priv *priv = get_bus_priv(bus);
 
-   seq_printf(s, "%d\n", priv->mps);
+   seq_printf(s, "%d\n", pcie_get_mps(priv->pdev));
 
return 0;
 }
@@ -104,8 +128,7 @@ static int qtnf_dbg_shm_stats(struct seq_file *s, void 
*data)
return 0;
 }
 
-void qtnf_pcie_fw_boot_done(struct qtnf_bus *bus, bool boot_success,
-   const char *drv_name)
+void qtnf_pcie_fw_boot_done(struct qtnf_bus *bus, bool boot_success)
 {
struct 

[PATCH v2 0/2] qtnfmac: add support for QSR1000/QSR2000 (aka Topaz) chipsets

2018-10-16 Thread Sergey Matyukevich
Hello Kalle and all, 

Here is the next update for qtnfmac driver. This patchset adds support
for the previous generation of Quantenna wireless cards,
namely QSR1000/QSR2000 family of PCIe devices.

The summary of changes is as follows:
- the last bits of pcie layer unification work:
  -- extract remaining code that can be shared across various PCIe chips
  -- cleanup/rename: get ready to support another chipset
- add support for QSR1000/QSR2000 devices

Regards,
Sergey

Changes v1 -> v2
- simplify Kconfig options for PCIe backend driver

 Kconfig|   15 
 Makefile   |9 
 pcie/pcie.c|  282 +++
 pcie/pcie_priv.h   |   20 
 pcie/pearl_pcie.c  |  211 ++--
 pcie/topaz_pcie.c  | 1219 +
 pcie/topaz_pcie_ipc.h  |   94 +++
 pcie/topaz_pcie_regs.h |   45 +
 qtn_hw_ids.h   |4 
 util.c |   18 
 util.h |2 
 11 files changed, 1664 insertions(+), 255 deletions(-)


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

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

> On 2018-10-12 03:16, Toke Høiland-Jørgensen wrote:
>> 
>> - Just loop with the smaller quantum until one of the stations go into
>>   the positive (what we do now).
>> 
>> - Go through all active stations, find the one that is closest being in
>>   the positive, and add that amount to the quantum. I.e., something
>>   like (assuming no station has positive deficit; if one does, you 
>> don't
>>   want to add anything anyway):
>> 
>>   to_add = -(max(stn.deficit) for stn in active stations)
>>   for stn in active stations:
>> stn.deficit += to_add + stn.weight
>> 
> Toke,
>
> Sorry for the delayed response. I did lot of experiments. Below are my 
> observations.
> Sorry for lengthy reply.
>
> In current model, next_txq() is main routine that serves DRR and
> fairness is enforced by serving only only first txq. Here the first
> node could be either newly initiated traffic or returned node by
> return_txq(). This works perfectly as long as the driver is running
> any RR algo.
>
> Whereas in ath10k, firmware runs its own RR in pull mode and builds
> txq list based on driver's hostq table. In this case it can not be
> simply assumed that firmware always gives fetch request for first node
> of mac80211's txq list. i.e both RR algo could be out of sync.

So I'm wondering why they don't sync; if the hardware is just doing RR
scheduling, eventually it should hit the TXQ that's first in the queue
and keep in sync after that?

How are you testing, and what metrics are you using?

> On an idle condition a single fetch indication can dequeue ~190 msdus
> from each tid of give stn list.

Wow, that sounds pretty bad. Guess we need the airtime queue limits! :)

> diff --git a/drivers/net/wireless/ath/ath10k/htt_rx.c 
> b/drivers/net/wireless/ath/ath10k/htt_rx.c
> index 625a4ab37ea0..269ae8311056 100644
> --- a/drivers/net/wireless/ath/ath10k/htt_rx.c
> +++ b/drivers/net/wireless/ath/ath10k/htt_rx.c
> @@ -2352,7 +2352,7 @@ static void ath10k_htt_rx_tx_fetch_ind(struct ath10k 
> *ar, struct sk_buff *skb)
>   num_msdus++;
>   num_bytes += ret;
>   }
> - ieee80211_return_txq(hw, txq);
> + ieee80211_return_txq(hw, txq, true);

I don't like the extra parameter; a similar one was in an earlier
version of my patch set, but I'd prefer that mac80211 just does the
right thing...

Do I understand it correctly that push/pull mode is selected solely by
hardware/firmware versions? Because in that case we could split it into
two feature flags instead...

> @@ -3670,13 +3670,8 @@ bool ieee80211_txq_may_transmit(struct ieee80211_hw 
> *hw,
>   if (sta->airtime[ac].deficit >= 0)
>   goto out;
>  
> - list_for_each_entry(txqi, >active_txqs[ac], schedule_order) {
> - if (!txqi->txq.sta)
> - continue;
> - sta = container_of(txqi->txq.sta, struct sta_info, sta);
> - sta->airtime[ac].deficit +=
> - (IEEE80211_TXQ_MAY_TX_QUANTUM * sta->airtime_weight);
> - }
> + sta->airtime[ac].deficit += sta->airtime_weight;
> + list_move_tail(>schedule_order, >active_txqs[ac]);

I'm wondering whether this actually succeeds in achieving fairness? This
basically allows a TXQ to be plucked from any point in the list, get a
quantum increase and be put back on, no matter the state of other TXQs.

Did you test how well the stations divide their airtime? And if so,
under which conditions?

-Toke


[PATCH] mt76x0: init: simplify mt76x0_init_mac_registers

2018-10-16 Thread Lorenzo Bianconi
Simplify mt76x0_init_mac_registers routine using mt76_set, mt76_clear
and mt76_rmw utility routines

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

diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/init.c 
b/drivers/net/wireless/mediatek/mt76/mt76x0/init.c
index f5c7db9ca02a..d49357c7f104 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x0/init.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x0/init.c
@@ -134,8 +134,6 @@ static int mt76x0_init_bbp(struct mt76x02_dev *dev)
 
 static void mt76x0_init_mac_registers(struct mt76x02_dev *dev)
 {
-   u32 reg;
-
RANDOM_WRITE(dev, common_mac_reg_table);
 
mt76x02_set_beacon_offsets(dev);
@@ -144,27 +142,22 @@ static void mt76x0_init_mac_registers(struct mt76x02_dev 
*dev)
RANDOM_WRITE(dev, mt76x0_mac_reg_table);
 
/* Release BBP and MAC reset MAC_SYS_CTRL[1:0] = 0x0 */
-   reg = mt76_rr(dev, MT_MAC_SYS_CTRL);
-   reg &= ~0x3;
-   mt76_wr(dev, MT_MAC_SYS_CTRL, reg);
+   mt76_clear(dev, MT_MAC_SYS_CTRL, 0x3);
 
/* Set 0x141C[15:12]=0xF */
-   reg = mt76_rr(dev, MT_EXT_CCA_CFG);
-   reg |= 0xF000;
-   mt76_wr(dev, MT_EXT_CCA_CFG, reg);
+   mt76_set(dev, MT_EXT_CCA_CFG, 0xf000);
 
mt76_clear(dev, MT_FCE_L2_STUFF, MT_FCE_L2_STUFF_WR_MPDU_LEN_EN);
 
/*
-   TxRing 9 is for Mgmt frame.
-   TxRing 8 is for In-band command frame.
-   WMM_RG0_TXQMA: This register setting is for FCE to define the 
rule of TxRing 9.
-   WMM_RG1_TXQMA: This register setting is for FCE to define the 
rule of TxRing 8.
-   */
-   reg = mt76_rr(dev, MT_WMM_CTRL);
-   reg &= ~0x03FF;
-   reg |= 0x0201;
-   mt76_wr(dev, MT_WMM_CTRL, reg);
+* tx_ring 9 is for mgmt frame
+* tx_ring 8 is for in-band command frame.
+* WMM_RG0_TXQMA: this register setting is for FCE to
+*define the rule of tx_ring 9
+* WMM_RG1_TXQMA: this register setting is for FCE to
+*define the rule of tx_ring 8
+*/
+   mt76_rmw(dev, MT_WMM_CTRL, 0x3ff, 0x201);
 }
 
 static int mt76x0_init_wcid_mem(struct mt76x02_dev *dev)
-- 
2.17.2



[PATCH v4 2/2] mac80211: allow drivers to use peer measurement API

2018-10-16 Thread Johannes Berg
From: Johannes Berg 

There's nothing much for mac80211 to do, so only pass through
the requests with minimal checks and tracing. The driver must
call cfg80211's results APIs.

Signed-off-by: Johannes Berg 
---
v4: first version - just takes the same number as the cfg80211 patch
---
 include/net/mac80211.h|  7 +++
 net/mac80211/cfg.c| 22 ++
 net/mac80211/driver-ops.h | 34 ++
 net/mac80211/trace.h  | 12 
 4 files changed, 75 insertions(+)

diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 71985e95d2d9..e3d57e7a55cc 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -3623,6 +3623,9 @@ enum ieee80211_reconfig_type {
  * skb is always a real frame, head may or may not be an A-MSDU.
  * @get_ftm_responder_stats: Retrieve FTM responder statistics, if available.
  * Statistics should be cumulative, currently no way to reset is provided.
+ *
+ * @start_pmsr: start peer measurement (e.g. FTM) (this call can sleep)
+ * @abort_pmsr: abort peer measurement (this call can sleep)
  */
 struct ieee80211_ops {
void (*tx)(struct ieee80211_hw *hw,
@@ -3911,6 +3914,10 @@ struct ieee80211_ops {
int (*get_ftm_responder_stats)(struct ieee80211_hw *hw,
   struct ieee80211_vif *vif,
   struct cfg80211_ftm_responder_stats 
*ftm_stats);
+   int (*start_pmsr)(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+ struct cfg80211_pmsr_request *request);
+   void (*abort_pmsr)(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+  struct cfg80211_pmsr_request *request);
 };
 
 /**
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 51622333d460..2ffbbf4d 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -3849,6 +3849,26 @@ ieee80211_get_ftm_responder_stats(struct wiphy *wiphy,
return drv_get_ftm_responder_stats(local, sdata, ftm_stats);
 }
 
+static int
+ieee80211_start_pmsr(struct wiphy *wiphy, struct wireless_dev *dev,
+struct cfg80211_pmsr_request *request)
+{
+   struct ieee80211_local *local = wiphy_priv(wiphy);
+   struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(dev);
+
+   return drv_start_pmsr(local, sdata, request);
+}
+
+static void
+ieee80211_abort_pmsr(struct wiphy *wiphy, struct wireless_dev *dev,
+struct cfg80211_pmsr_request *request)
+{
+   struct ieee80211_local *local = wiphy_priv(wiphy);
+   struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(dev);
+
+   return drv_abort_pmsr(local, sdata, request);
+}
+
 const struct cfg80211_ops mac80211_config_ops = {
.add_virtual_intf = ieee80211_add_iface,
.del_virtual_intf = ieee80211_del_iface,
@@ -3944,4 +3964,6 @@ const struct cfg80211_ops mac80211_config_ops = {
.tx_control_port = ieee80211_tx_control_port,
.get_txq_stats = ieee80211_get_txq_stats,
.get_ftm_responder_stats = ieee80211_get_ftm_responder_stats,
+   .start_pmsr = ieee80211_start_pmsr,
+   .abort_pmsr = ieee80211_abort_pmsr,
 };
diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h
index 0b1747a2313d..3e0d5922a440 100644
--- a/net/mac80211/driver-ops.h
+++ b/net/mac80211/driver-ops.h
@@ -1199,6 +1199,40 @@ drv_get_ftm_responder_stats(struct ieee80211_local 
*local,
return ret;
 }
 
+static inline int drv_start_pmsr(struct ieee80211_local *local,
+struct ieee80211_sub_if_data *sdata,
+struct cfg80211_pmsr_request *request)
+{
+   int ret = -EOPNOTSUPP;
+
+   might_sleep();
+   if (!check_sdata_in_driver(sdata))
+   return -EIO;
+
+   trace_drv_start_pmsr(local, sdata);
+
+   if (local->ops->start_pmsr)
+   ret = local->ops->start_pmsr(>hw, >vif, request);
+   trace_drv_return_int(local, ret);
+
+   return ret;
+}
+
+static inline void drv_abort_pmsr(struct ieee80211_local *local,
+ struct ieee80211_sub_if_data *sdata,
+ struct cfg80211_pmsr_request *request)
+{
+   trace_drv_abort_pmsr(local, sdata);
+
+   might_sleep();
+   if (!check_sdata_in_driver(sdata))
+   return;
+
+   if (local->ops->abort_pmsr)
+   local->ops->abort_pmsr(>hw, >vif, request);
+   trace_drv_return_void(local);
+}
+
 static inline int drv_start_nan(struct ieee80211_local *local,
struct ieee80211_sub_if_data *sdata,
struct cfg80211_nan_conf *conf)
diff --git a/net/mac80211/trace.h b/net/mac80211/trace.h
index 588c51a67c89..ac2f1922d469 100644
--- a/net/mac80211/trace.h
+++ b/net/mac80211/trace.h
@@ -1882,6 +1882,18 @@ TRACE_EVENT(drv_del_nan_func,
)
 );
 
+DEFINE_EVENT(local_sdata_evt, 

[PATCH v4 1/2] cfg80211: add peer measurement with FTM initiator API

2018-10-16 Thread Johannes Berg
From: Johannes Berg 

Add a new "peer measurement" API, that can be used to measure
certain things related to a peer. Right now, only implement
FTM (flight time measurement) over it, but the idea is that
it'll be extensible to also support measuring the necessary
things to calculate e.g. angle-of-arrival for WiGig.

The API is structured to have a generic list of peers and
channels to measure with/on, and then for each of those a
set of measurements (again, only FTM right now) to perform.

Results are sent to the requesting socket, including a final
complete message.

Closing the controlling netlink socket will abort a running
measurement.

Signed-off-by: Johannes Berg 
---
v3:
 - add a bit to report "final" for partial results
 - remove list keeping etc. and just unicast out the results
   to the requester (big code reduction ...)
 - also send complete message unicast, and as a result
   remove the multicast group
 - separate out struct cfg80211_pmsr_ftm_request_peer
   from struct cfg80211_pmsr_request_peer
 - document timeout == 0 if no timeout
 - disallow setting timeout nl80211 attribute to 0,
   must not include attribute for no timeout
 - make MAC address randomization optional
 - change num bursts exponent default to 0 (1 burst, rather
   rather than the old default of 15==don't care)

v4:
 - clarify NL80211_ATTR_TIMEOUT documentation
---
 include/net/cfg80211.h   | 255 
 include/uapi/linux/nl80211.h | 412 +
 net/wireless/Makefile|   1 +
 net/wireless/core.c  |  33 ++
 net/wireless/core.h  |   4 +
 net/wireless/nl80211.c   | 200 +---
 net/wireless/nl80211.h   |  41 +++
 net/wireless/pmsr.c  | 576 +++
 net/wireless/rdev-ops.h  |  25 ++
 net/wireless/trace.h |  68 +
 10 files changed, 1581 insertions(+), 34 deletions(-)
 create mode 100644 net/wireless/pmsr.c

diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 1fa41b7a1be3..69b34b8e22ea 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -2848,6 +2848,191 @@ struct cfg80211_ftm_responder_stats {
u32 out_of_window_triggers_num;
 };
 
+/**
+ * struct cfg80211_pmsr_ftm_result - FTM result
+ * @failure_reason: if this measurement failed (PMSR status is
+ * %NL80211_PMSR_STATUS_FAILURE), this gives a more precise
+ * reason than just "failure"
+ * @burst_index: if reporting partial results, this is the index
+ * in [0 .. num_bursts-1] of the burst that's being reported
+ * @num_ftmr_attempts: number of FTM request frames transmitted
+ * @num_ftmr_successes: number of FTM request frames acked
+ * @busy_retry_time: if failure_reason is %NL80211_PMSR_FTM_FAILURE_PEER_BUSY,
+ * fill this to indicate in how many seconds a retry is deemed possible
+ * by the responder
+ * @num_bursts_exp: actual number of bursts exponent negotiated
+ * @burst_duration: actual burst duration negotiated
+ * @frames_per_burst: actual frames per burst negotiated
+ * @lci_len: length of LCI information (if present)
+ * @civicloc_len: length of civic location information (if present)
+ * @lci: LCI data (may be %NULL)
+ * @civicloc: civic location data (may be %NULL)
+ * @rssi_avg: average RSSI over FTM action frames reported
+ * @rssi_spread: spread of the RSSI over FTM action frames reported
+ * @tx_rate: bitrate for transmitted FTM action frame response
+ * @rx_rate: bitrate of received FTM action frame
+ * @rtt_avg: average of RTTs measured (must have either this or @dist_avg)
+ * @rtt_variance: variance of RTTs measured (note that standard deviation is
+ * the square root of the variance)
+ * @rtt_spread: spread of the RTTs measured
+ * @dist_avg: average of distances (mm) measured
+ * (must have either this or @rtt_avg)
+ * @dist_variance: variance of distances measured (see also @rtt_variance)
+ * @dist_spread: spread of distances measured (see also @rtt_spread)
+ * @num_ftmr_attempts_valid: @num_ftmr_attempts is valid
+ * @num_ftmr_successes_valid: @num_ftmr_successes is valid
+ * @rssi_avg_valid: @rssi_avg is valid
+ * @rssi_spread_valid: @rssi_spread is valid
+ * @tx_rate_valid: @tx_rate is valid
+ * @rx_rate_valid: @rx_rate is valid
+ * @rtt_avg_valid: @rtt_avg is valid
+ * @rtt_variance_valid: @rtt_variance is valid
+ * @rtt_spread_valid: @rtt_spread is valid
+ * @dist_avg_valid: @dist_avg is valid
+ * @dist_variance_valid: @dist_variance is valid
+ * @dist_spread_valid: @dist_spread is valid
+ */
+struct cfg80211_pmsr_ftm_result {
+   const u8 *lci;
+   const u8 *civicloc;
+   unsigned int lci_len;
+   unsigned int civicloc_len;
+   enum nl80211_peer_measurement_ftm_failure_reasons failure_reason;
+   u32 num_ftmr_attempts, num_ftmr_successes;
+   s16 burst_index;
+   u8 busy_retry_time;
+   u8 num_bursts_exp;
+   u8 burst_duration;
+   u8 frames_per_burst;
+   s32 rssi_avg;
+   s32 rssi_spread;
+   struct 

Re: [PATCH] mt76x0: do not perform MCU calibration for MT7630

2018-10-16 Thread Felix Fietkau
On 2018-10-16 09:58, Stanislaw Gruszka wrote:
> Driver works better for MT7630 without MCU calibration, which
> looks like it can hangs the firmware. Vendor driver do not
> perform it for MT7630 as well.
> 
> Signed-off-by: Stanislaw Gruszka 
Applied, thanks.

- Felix


Re: [PATCH] mt76x0: phy: unify calibration between mt76x0u and mt76x0e

2018-10-16 Thread Felix Fietkau
On 2018-10-15 14:18, Lorenzo Bianconi wrote:
> Align phy calibration logic between mt76x0u and mt76x0e drivers
> This patch improves connection stability with low SNR
> 
> Signed-off-by: Lorenzo Bianconi 
Applied, thanks.

- Felix


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

2018-10-16 Thread Johannes Berg


> v3:
>  - add a bit to report "final" for partial results
>  - remove list keeping etc. and just unicast out the results
>to the requester (big code reduction ...)
>  - also send complete message unicast, and as a result
>remove the multicast group
>  - separate out struct cfg80211_pmsr_ftm_request_peer
>from struct cfg80211_pmsr_request_peer
>  - document timeout == 0 if no timeout
>  - disallow setting timeout nl80211 attribute to 0,
>must not include attribute for no timeout
>  - make MAC address randomization optional
>  - change num bursts exponent default to 0 (1 burst, rather
>rather than the old default of 15==don't care)

Forgot to say ... I didn't make the channel optional (yet), because I
think that doing so now could possibly cause an issue where it's
required for some devices and not required for others, unless we can do
lookups in cfg80211. But if we can do it there, then userspace can also
easily do it (station dump is the only data cfg80211 has), so then
there's not that much point ...

I think we could relax this later if we really needed to.

johannes



Re: [PATCH 0/6] unify debugfs code between mt76x0 and mt76x2

2018-10-16 Thread Felix Fietkau
On 2018-10-15 11:33, Lorenzo Bianconi wrote:
> Unify debugfs implementation between mt76x0 and mt76x2 drivers.
> Add get_survey support to mt76x0e driver
> Add mac work support to mt76x2u driver
Applied, thanks.

- Felix


Re: [PATCH 0/3] mt76x0: simplify rf configuration routines

2018-10-16 Thread Felix Fietkau
On 2018-10-14 18:55, Lorenzo Bianconi wrote:
> Simplify rf configuration using mt76x0_rf_wr, mt76x0_rf_set
> and mt76x0_rf_clear routines. Moreover use mt76x0_phy as
> prefix for phy routines
Applied, thanks.

- Felix


Re: [RFC v4 05/13] rtw88: mac files

2018-10-16 Thread Stanislaw Gruszka
On Sat, Oct 13, 2018 at 05:00:37PM +0800, yhchu...@realtek.com wrote:
> + buf = kmalloc(size, GFP_KERNEL);
> + memcpy(buf, data, size);

Error check and it could be replaced by kmemdup.

Regards
Stanislaw


Re: [RFC v4 00/13] rtw88: mac80211 driver for Realtek 802.11ac wireless network chips

2018-10-16 Thread Stanislaw Gruszka
On Sat, Oct 13, 2018 at 05:00:32PM +0800, yhchu...@realtek.com wrote:
> From: Yan-Hsuan Chuang 
> 
> This is a new mac80211 driver for Realtek 802.11ac wireless network chips.
> rtw88 supports 8822BE and 8822CE chips, and will be able to support
> multi-vif combinations in run-time.
> 
> For now, only PCI bus is supported, but rtw88 was originally designed
> to optionally support three buses includes USB & SDIO. USB & SDIO modules
> will soon be supported by rtw88, with configurable core module to fit
> with different bus modules in the same time.
> 
> For example, if we choose 8822BE and 8822CU, only PCI & USB modules will
> be selected, built, loaded into kernel. This is one of the major
> difference from rtlwifi, which can only support specific combinations.
> 
> Another difference from rtlwifi is that rtw88 is designed to support
> the latest Realtek 802.11ac wireless network chips like 8822B and
> 8822C series. Compared to the earlier chips supported by rtlwifi like
> the 802.11n 8192EE chipset or 802.11ac 8821AE/8812AE chips, newer ICs
> have different MAC & PHY settings, such as new multi-port feature for the
> MAC layer design and Jaguar2/Jaguar3 PHY layer IPs.
> 
> Multi-Port feature is also supported under rtw88's software architecture.
> rtlwifi can only support one vif in the same time, most because of the
> hardware limitations for early chips, hence the original design of it
> also restricts the usage of multi-vif support, so latest chipset seems not
> take advantages from its new MAC engine.
> 
> However, rtw88 can run multiple vifs concurrently by holding them on
> hardware ports provided by MAC engine, hence can easily start different
> roles on a single device.
> 
> Based on the reasons mentioned before, we implemented rtw88. It had many
> authors, they are listed here alphabetically:
> 
> Ping-Ke Shih 
> Tzu-En Huang 
> Yan-Hsuan Chuang 

For the series:
Reviewed-by: Stanislaw Gruszka 


Re: [RFC v4 06/13] rtw88: fw and efuse files

2018-10-16 Thread Stanislaw Gruszka
On Sat, Oct 13, 2018 at 05:00:38PM +0800, yhchu...@realtek.com wrote:
> +rtw_beacon_get(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
> +{
> + struct sk_buff *skb_new;
> +
> + if (vif->type != NL80211_IFTYPE_AP &&
> + vif->type != NL80211_IFTYPE_ADHOC &&
> + !ieee80211_vif_is_mesh(vif)) {
> + skb_new = alloc_skb(1, GFP_KERNEL);
> + skb_put(skb_new, 1);

Error check.

Thanks
Stanislaw


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

2018-10-16 Thread Stanislaw Gruszka
On Fri, Oct 12, 2018 at 12:48:07PM +0200, Tom Psyborg wrote:
> chip version support exist in daniel's tree since a long time ago. so
> don't disable registers initialization but try to upstream his
> changes.

Where is this patch ? I can not find it.

Thanks
Stanislaw


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

2018-10-16 Thread Stanislaw Gruszka
On Fri, Oct 12, 2018 at 02:41:41PM +0200, Tom Psyborg wrote:
> On 12/10/2018, Stanislaw Gruszka  wrote:
> > On Fri, Oct 12, 2018 at 02:20:07PM +0200, Tom Psyborg wrote:
> >> > On upstream tree where this patch is intended
> >> > additional registers where never programmed as proper branch
> >> > were never used, because of additional check in RT5390 branch.
> >> >
> >>
> >> on my hardware additional registers were programmed in regardless of
> >> redundant check. that why i opened whole thread on forum since i
> >> couldn't understand how's that happening
> >
> > I don't understand how that possible either.
> 
> i'd assume because device use external lna

I have no idea how this could be related. But I think I found
somewhat reasonable explenation where the problem is.
I think below code :

if (a || b || c) {
CODE1();
} else if (c) {
CODE2();
}

can not be deterministic and can be compiled differently depending
on compiler version and used options. Sometimes it could result
in this 

if (a || b || c) {
CODE1();
}

and sometimes in this:

if (a || b) {
CODE1();
} else if (c) {
CODE2();
}

So that would explain the problems you see. And indeed patch
could cause regression on systems where second variant of
initalizing RT6352 registers was used.

Thanks
Stanislaw







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

2018-10-16 Thread Stanislaw Gruszka
On Sat, Oct 13, 2018 at 12:46:54PM +0300, Kalle Valo wrote:
> No '#if 0', please. If the code is not needed you can remove it, it's
> available from git history anyway if it's needed later.

Plase drop this patch, other patches from the set can be applied
without it.

Thanks
Stanislaw


[PATCH] mt76x0: do not perform MCU calibration for MT7630

2018-10-16 Thread Stanislaw Gruszka
Driver works better for MT7630 without MCU calibration, which
looks like it can hangs the firmware. Vendor driver do not
perform it for MT7630 as well.

Signed-off-by: Stanislaw Gruszka 
---
This is on top of:
https://marc.info/?l=linux-wireless=153960591116586=2

 drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h | 5 +
 drivers/net/wireless/mediatek/mt76/mt76x0/phy.c| 3 +++
 2 files changed, 8 insertions(+)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h 
b/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h
index 17ad3fa0858b..33475788bc26 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h
@@ -37,6 +37,11 @@ static inline bool is_mt7610e(struct mt76x02_dev *dev)
return false;
 }
 
+static inline bool is_mt7630(struct mt76x02_dev *dev)
+{
+   return mt76_chip(>mt76) == 0x7630;
+}
+
 /* Init */
 struct mt76x02_dev *
 mt76x0_alloc_device(struct device *pdev,
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/phy.c 
b/drivers/net/wireless/mediatek/mt76/mt76x0/phy.c
index dbb92586b6e1..37e1ead1dc85 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x0/phy.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x0/phy.c
@@ -500,6 +500,9 @@ 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 (is_mt7630(dev))
+   return;
+
if (power_on) {
mt76x02_mcu_calibrate(dev, MCU_CAL_R, 0, false);
mt76x02_mcu_calibrate(dev, MCU_CAL_VCO, chan->hw_value,
-- 
1.9.3



Re: [PATCH] mt76x0: phy: unify calibration between mt76x0u and mt76x0e

2018-10-16 Thread Stanislaw Gruszka
On Mon, Oct 15, 2018 at 02:18:05PM +0200, Lorenzo Bianconi wrote:
> Align phy calibration logic between mt76x0u and mt76x0e drivers
> This patch improves connection stability with low SNR
> 
> Signed-off-by: Lorenzo Bianconi 

Tested-by: Stanislaw Gruszka 


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

2018-10-16 Thread Rajkumar Manoharan

On 2018-10-12 03:16, Toke Høiland-Jørgensen wrote:


- Just loop with the smaller quantum until one of the stations go into
  the positive (what we do now).

- Go through all active stations, find the one that is closest being in
  the positive, and add that amount to the quantum. I.e., something
  like (assuming no station has positive deficit; if one does, you 
don't

  want to add anything anyway):

  to_add = -(max(stn.deficit) for stn in active stations)
  for stn in active stations:
stn.deficit += to_add + stn.weight


Toke,

Sorry for the delayed response. I did lot of experiments. Below are my 
observations.

Sorry for lengthy reply.

In current model, next_txq() is main routine that serves DRR and 
fairness is
enforced by serving only only first txq. Here the first node could be 
either
newly initiated traffic or returned node by return_txq(). This works 
perfectly

as long as the driver is running any RR algo.

Whereas in ath10k, firmware runs its own RR in pull mode and builds txq 
list
based on driver's hostq table. In this case it can not be simply assumed 
that
firmware always gives fetch request for first node of mac80211's txq 
list.

i.e both RR algo could be out of sync.

Two major differences b/w ath9k and ath10k

1) Serving txqs
The ath9k always serves txq by next_txq and so that the txqs_list is 
rotated to serve
other txq. But in ath10k (pull-mode), first node becomes sticky one 
until it is

picked by firmware via fetch indication and it becomes negative deficit.
The sequence is followed in wake_tx_queue

   - dequeue first node
   - push is not allowed
   - enqueue same txq back to head

2) Refill rate of deficit.

The ath9k refills deficit mostly in hot path by next_txq() in tx & isr 
routine.
In case of ath10k, due to above problem, deficits wont be filled in hot 
path.
Either it should be filled in fetch_ind itself or by scheduling another 
task.
Both the approaches are slower compared to hot path when the driver is 
bursting
aggregation. On an idle condition a single fetch indication can dequeue 
~190 msdus
from each tid of give stn list. This drains the deficit quickly and 
becomes too low.
To speed up this, either refill the station by multiples of stn airtime 
weight or
allows the txqs_list rotation. So that next_txq will be used for 
refilling deficit.


Attaching return_txq() change that helps to get rid of quantum multiple.

-Rajkumardiff --git a/drivers/net/wireless/ath/ath10k/htt_rx.c b/drivers/net/wireless/ath/ath10k/htt_rx.c
index 625a4ab37ea0..269ae8311056 100644
--- a/drivers/net/wireless/ath/ath10k/htt_rx.c
+++ b/drivers/net/wireless/ath/ath10k/htt_rx.c
@@ -2352,7 +2352,7 @@ static void ath10k_htt_rx_tx_fetch_ind(struct ath10k *ar, struct sk_buff *skb)
 			num_msdus++;
 			num_bytes += ret;
 		}
-		ieee80211_return_txq(hw, txq);
+		ieee80211_return_txq(hw, txq, true);
 		ieee80211_txq_schedule_end(hw, txq->ac);
 
 		record->num_msdus = cpu_to_le16(num_msdus);
diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c
index cf64d9e02a24..d39bc841ea04 100644
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
@@ -4206,7 +4206,7 @@ static int ath10k_mac_schedule_txq(struct ieee80211_hw *hw, u32 ac)
 			if (ret < 0)
 break;
 		}
-		ieee80211_return_txq(hw, txq);
+		ieee80211_return_txq(hw, txq, true);
 		ath10k_htt_tx_txq_update(hw, txq);
 		if (ret == -EBUSY)
 			break;
@@ -4475,18 +4475,21 @@ static void ath10k_mac_op_wake_tx_queue(struct ieee80211_hw *hw,
 {
 	u8 ac = txq->ac;
 	int ret = 0;
+	bool pushed = false;
 
+	ath10k_htt_tx_txq_update(hw, txq);
 	ieee80211_txq_schedule_start(hw, ac);
 	txq = ieee80211_next_txq(hw, ac);
 	if (!txq)
 		goto out;
 
 	while (ath10k_mac_tx_can_push(hw, txq)) {
+		pushed = true;
 		ret = ath10k_mac_tx_push_txq(hw, txq);
 		if (ret < 0)
 			break;
 	}
-	ieee80211_return_txq(hw, txq);
+	ieee80211_return_txq(hw, txq, pushed);
 	ath10k_htt_tx_txq_update(hw, txq);
 out:
 	ieee80211_txq_schedule_end(hw, ac);
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index 6aab06909e76..40ff0bdbf7c9 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -117,7 +117,7 @@ void ath_tx_queue_tid(struct ath_softc *sc, struct ath_atx_tid *tid)
 	struct ieee80211_txq *queue = container_of(
 		(void *)tid, struct ieee80211_txq, drv_priv);
 
-	ieee80211_return_txq(sc->hw, queue);
+	ieee80211_return_txq(sc->hw, queue, false);
 }
 
 void ath9k_wake_tx_queue(struct ieee80211_hw *hw, struct ieee80211_txq *queue)
@@ -1913,7 +1913,7 @@ void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq)
 		ret = ath_tx_sched_aggr(sc, txq, tid);
 		ath_dbg(common, QUEUE, "ath_tx_sched_aggr returned %d\n", ret);
 
-		ieee80211_return_txq(hw, queue);
+		ieee80211_return_txq(hw, queue, false);
 	}
 
 out:
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 9cadfa408f50..995e19e29d9e 100644
---