[PATCH 1/3] mt76: add size check for additional rx fragments

2018-12-03 Thread Felix Fietkau
So far the code only validates the buffer size of the first skb.
Extend this check to cover additional fragments as well, in case the size
is corrupted during a DMA reset.

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

diff --git a/drivers/net/wireless/mediatek/mt76/dma.c 
b/drivers/net/wireless/mediatek/mt76/dma.c
index e2ba26378575..710a77fccf63 100644
--- a/drivers/net/wireless/mediatek/mt76/dma.c
+++ b/drivers/net/wireless/mediatek/mt76/dma.c
@@ -430,6 +430,14 @@ mt76_dma_rx_process(struct mt76_dev *dev, struct 
mt76_queue *q, int budget)
if (!data)
break;
 
+   if (q->buf_size < len + q->buf_offset) {
+   dev_kfree_skb(q->rx_head);
+   q->rx_head = NULL;
+
+   skb_free_frag(data);
+   continue;
+   }
+
if (q->rx_head) {
mt76_add_fragment(dev, q, data, len, more);
continue;
-- 
2.17.0



[PATCH 2/3] mt76: throttle transmission of buffered multicast packets

2018-12-03 Thread Felix Fietkau
Avoids drowning out regular transmissions

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

diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c 
b/drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c
index 66315410aebe..6974acc75e2b 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c
@@ -121,9 +121,10 @@ static void mt76x02_pre_tbtt_tasklet(unsigned long arg)
ieee80211_iterate_active_interfaces_atomic(mt76_hw(dev),
IEEE80211_IFACE_ITER_RESUME_ALL,
mt76x02_add_buffered_bc, );
-   } while (nframes != skb_queue_len());
+   } while (nframes != skb_queue_len() &&
+skb_queue_len() < 8);
 
-   if (!nframes)
+   if (!skb_queue_len())
return;
 
for (i = 0; i < ARRAY_SIZE(data.tail); i++) {
-- 
2.17.0



[PATCH 3/3] mt76: request tx status for powersave released EOSP packet

2018-12-03 Thread Felix Fietkau
Allows mac80211 to keep track of the service period

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

diff --git a/drivers/net/wireless/mediatek/mt76/tx.c 
b/drivers/net/wireless/mediatek/mt76/tx.c
index f4093dc0e174..06178bdafbac 100644
--- a/drivers/net/wireless/mediatek/mt76/tx.c
+++ b/drivers/net/wireless/mediatek/mt76/tx.c
@@ -330,7 +330,8 @@ mt76_queue_ps_skb(struct mt76_dev *dev, struct 
ieee80211_sta *sta,
 
info->control.flags |= IEEE80211_TX_CTRL_PS_RESPONSE;
if (last)
-   info->flags |= IEEE80211_TX_STATUS_EOSP;
+   info->flags |= IEEE80211_TX_STATUS_EOSP |
+  IEEE80211_TX_CTL_REQ_TX_STATUS;
 
mt76_skb_set_moredata(skb, !last);
dev->queue_ops->tx_queue_skb(dev, hwq, skb, wcid, sta);
-- 
2.17.0



pull request: mt76 2018-11-30

2018-11-30 Thread Felix Fietkau
Hi Kalle,

here's my first pull request for 4.21

- Felix

The following changes since commit b72c51a58e6d63ef673ac96b8ab5bc98799c5f7b:

  brcmfmac: Fix out of bounds memory access during fw load (2018-11-29 17:33:10 
+0200)

are available in the Git repository at:

  https://github.com/nbd168/wireless tags/mt76-for-kvalo-2018-11-30

for you to fetch changes up to e28487ea84a9c081c6d8d7da319427f7fcc32ff5:

  mt76: replace sta_add/remove ops with common sta_state function (2018-11-30 
12:30:37 +0100)


first batch of mt76 patches for 4.21

* use the same firmware for mt76x2e and mt76x2u
* mt76x2 fixes
* mt76x0 fixes
* mt76x0e survey support
* more unification between mt76x2 and mt76x0
* mt76x0e AP mode support
* mt76x0e DFS support
* rework and fix tx status handling for mt76x0 and mt76x2


Felix Fietkau (13):
  mt76: clean up unused leftover EXPORT_SYMBOLs
  mt76: mt76x0: handle chip specific initval differences
  mt76: clean up more unused EXPORT_SYMBOLs
  mt76: mt76x02: skip station tx status for non-sta wcid entries
  mt76: mt76x02: only override control->sta on sw-encrypted tx
  mt76: add support for reporting tx status with skb
  mt76: avoid queue/status spinlocks while passing tx status to mac80211
  mt76: do not wake tx queues during flush
  mt76: fix race condition in station removal
  mt76: add mt76_sta_remove helper
  mt76: mt76x02: make group_wcid the first member in struct mt76x02_vif
  mt76: mt76x02: remove mt76x02_txq_init
  mt76: replace sta_add/remove ops with common sta_state function

Lorenzo Bianconi (49):
  mt76x2: align mt76x2 and mt76x2u firmware
  mt76x2u: align channel gain logic to mt76x2 one
  mt76x0: phy: use proper name convention
  mt76x0: phy: simplify rf configuration routines
  mt76x0: phy: improve code readability in initvals_phy.h
  mt76x0: pci: add get_survey support
  mt76: move mt76x02_mac_work routine in mt76x02-lib module
  mt76: move mt76x02_debugfs in mt76x02-lib module
  mt76x0: use shared debugfs implementation
  mt76x0: use mt76x02_mac_work as stats handler
  mt76x2u: introduce mac workqueue support
  mt76x0: phy: unify calibration between mt76x0u and mt76x0e
  mt76: usb: fix static tracepoints
  mt76x0: init: simplify mt76x0_init_mac_registers
  mt76x0: pci: add missing MODULE_FIRMWARE macro
  mt76x0: mac: remove mt76x0_mac_set_ampdu_factor
  mt76x0: align mt76x0u and mt76x0e fw version
  mt76: move mt76x02_mac_set_short_preamble in mt76x02_mac.c
  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
  mt76: move mt76x02_set_tx_ackto in mt76x02-lib module
  mt76x0: update init vals for MT_TX_PROT registers
  mt76: move tx protection routines in mt76x02-lib module
  mt76: move mt76x02_bss_info_changed in mt76x02-lib module
  mt76: move dfs support in mt76x02-lib module
  mt76x0: pci: add DFS support
  mt76x0: phy: use mt76_poll_msec in mt76x0_phy_temp_sensor
  mt76x0: init: use mt76x02_mac_shared_key_setup in mt76x0_init_hardware
  mt76x2: move wcid_tx_rate conf at bootstrap
  mt76x0: init: use mt76x02_mac_wcid_setup for wcid configuration
  mt76x2u: init: remove not useful configuration
  mt76x2u: init: use common routines for wcid/key initialization
  mt76: move mt76x02_eeprom_copy in mt76x02-lib module
  mt76x0: phy: introduce tssi calibration support
  mt76x0: phy: use tssi reported value to configure tx power if available
  mt76x0: dfs: fix IBI_R11 configuration on non-radar channels
  mt76: introduce mt76x02_config_mac_addr_list routine
  mt76x0: pci: enable VHT rates in IBSS mode
  mt76x2u: phy: add TX_SHAPING calibration
  mt76x2u: phy: run phy_channel_calibrate after channel switch
  mt76x2u: main: use mt76x02_bss_info_changed utility routine
  mt76x2u: init: remove mt76x2u_init_beacon_offsets routine

Stanislaw Gruszka (10):
  mt76x0: do not perform MCU calibration for MT7630
  mt76x0: antenna select corrections
  mt76x0: do not overwrite other MT_BBP(AGC, 8) fields
  mt76x0: use band parameter for LC calibration
  mt76: remove mcu_msg_alloc
  mt76: remove wait argument from mt76x02_mcu_function_select
  mt76: remove wait argument from mt76x02_mcu_set_radio_state
  mt76x02: run calibration after scanning
  mt76x02: assure we upd

[PATCH] mac80211: fix reordering of buffered broadcast packets

2018-11-28 Thread Felix Fietkau
If the buffered broadcast queue contains packets, letting new packets bypass
that queue can lead to heavy reordering, since the driver is probably throttling
transmission of buffered multicast packets after beacons.

Keep buffering packets until the buffer has been cleared (and no client
is in powersave mode).

Cc: sta...@vger.kernel.org
Signed-off-by: Felix Fietkau 
---
 net/mac80211/tx.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 582b3d49f891..cd35af38d81f 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -439,8 +439,8 @@ ieee80211_tx_h_multicast_ps_buf(struct ieee80211_tx_data 
*tx)
if (ieee80211_hw_check(>local->hw, QUEUE_CONTROL))
info->hw_queue = tx->sdata->vif.cab_queue;
 
-   /* no stations in PS mode */
-   if (!atomic_read(>num_sta_ps))
+   /* no stations in PS mode and no buffered packets */
+   if (!atomic_read(>num_sta_ps) && skb_queue_empty(>bc_buf))
return TX_CONTINUE;
 
info->flags |= IEEE80211_TX_CTL_SEND_AFTER_DTIM;
-- 
2.17.0



[PATCH v3 7/7] mt76: replace sta_add/remove ops with common sta_state function

2018-11-16 Thread Felix Fietkau
Allows adding unassociated stations from mac80211

Signed-off-by: Felix Fietkau 
Signed-off-by: Lorenzo Bianconi 
---
v3: fix typo in mt76x2u

 drivers/net/wireless/mediatek/mt76/mac80211.c | 61 ++-
 drivers/net/wireless/mediatek/mt76/mt76.h | 12 +++-
 .../net/wireless/mediatek/mt76/mt76x0/pci.c   |  5 +-
 .../net/wireless/mediatek/mt76/mt76x0/usb.c   |  5 +-
 drivers/net/wireless/mediatek/mt76/mt76x02.h  |  8 +--
 .../net/wireless/mediatek/mt76/mt76x02_util.c | 40 +++-
 .../wireless/mediatek/mt76/mt76x2/pci_init.c  |  2 +
 .../wireless/mediatek/mt76/mt76x2/pci_main.c  |  3 +-
 .../wireless/mediatek/mt76/mt76x2/usb_init.c  |  2 +
 .../wireless/mediatek/mt76/mt76x2/usb_main.c  |  3 +-
 10 files changed, 92 insertions(+), 49 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mac80211.c 
b/drivers/net/wireless/mediatek/mt76/mac80211.c
index 1098919f5498..d3f94163ef8e 100644
--- a/drivers/net/wireless/mediatek/mt76/mac80211.c
+++ b/drivers/net/wireless/mediatek/mt76/mac80211.c
@@ -631,8 +631,40 @@ void mt76_rx_poll_complete(struct mt76_dev *dev, enum 
mt76_rxq_id q,
 }
 EXPORT_SYMBOL_GPL(mt76_rx_poll_complete);
 
-void mt76_sta_remove(struct mt76_dev *dev, struct ieee80211_vif *vif,
-struct ieee80211_sta *sta)
+static int
+mt76_sta_add(struct mt76_dev *dev, struct ieee80211_vif *vif,
+struct ieee80211_sta *sta)
+{
+   struct mt76_wcid *wcid = (struct mt76_wcid *)sta->drv_priv;
+   int ret;
+   int i;
+
+   mutex_lock(>mutex);
+
+   ret = dev->drv->sta_add(dev, vif, sta);
+   if (ret)
+   goto out;
+
+   for (i = 0; i < ARRAY_SIZE(sta->txq); i++) {
+   struct mt76_txq *mtxq;
+
+   mtxq = (struct mt76_txq *)sta->txq[i]->drv_priv;
+   mtxq->wcid = wcid;
+
+   mt76_txq_init(dev, sta->txq[i]);
+   }
+
+   rcu_assign_pointer(dev->wcid[wcid->idx], wcid);
+
+out:
+   mutex_unlock(>mutex);
+
+   return ret;
+}
+
+static void
+mt76_sta_remove(struct mt76_dev *dev, struct ieee80211_vif *vif,
+   struct ieee80211_sta *sta)
 {
struct mt76_wcid *wcid = (struct mt76_wcid *)sta->drv_priv;
int idx = wcid->idx;
@@ -642,10 +674,33 @@ void mt76_sta_remove(struct mt76_dev *dev, struct 
ieee80211_vif *vif,
synchronize_rcu();
 
mutex_lock(>mutex);
+
+   if (dev->drv->sta_remove)
+   dev->drv->sta_remove(dev, vif, sta);
+
mt76_tx_status_check(dev, wcid, true);
for (i = 0; i < ARRAY_SIZE(sta->txq); i++)
mt76_txq_remove(dev, sta->txq[i]);
mt76_wcid_free(dev->wcid_mask, idx);
+
mutex_unlock(>mutex);
 }
-EXPORT_SYMBOL_GPL(mt76_sta_remove);
+
+int mt76_sta_state(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+  struct ieee80211_sta *sta,
+  enum ieee80211_sta_state old_state,
+  enum ieee80211_sta_state new_state)
+{
+   struct mt76_dev *dev = hw->priv;
+
+   if (old_state == IEEE80211_STA_NOTEXIST &&
+   new_state == IEEE80211_STA_NONE)
+   return mt76_sta_add(dev, vif, sta);
+
+   if (old_state == IEEE80211_STA_NONE &&
+new_state == IEEE80211_STA_NOTEXIST)
+   mt76_sta_remove(dev, vif, sta);
+
+   return 0;
+}
+EXPORT_SYMBOL_GPL(mt76_sta_state);
diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h 
b/drivers/net/wireless/mediatek/mt76/mt76.h
index 878836fe80d3..5cd508a68609 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76.h
@@ -288,6 +288,12 @@ struct mt76_driver_ops {
 
void (*sta_ps)(struct mt76_dev *dev, struct ieee80211_sta *sta,
   bool ps);
+
+   int (*sta_add)(struct mt76_dev *dev, struct ieee80211_vif *vif,
+  struct ieee80211_sta *sta);
+
+   void (*sta_remove)(struct mt76_dev *dev, struct ieee80211_vif *vif,
+  struct ieee80211_sta *sta);
 };
 
 struct mt76_channel_state {
@@ -664,8 +670,10 @@ void mt76_tx_status_skb_done(struct mt76_dev *dev, struct 
sk_buff *skb,
 void mt76_tx_complete_skb(struct mt76_dev *dev, struct sk_buff *skb);
 void mt76_tx_status_check(struct mt76_dev *dev, struct mt76_wcid *wcid,
  bool flush);
-void mt76_sta_remove(struct mt76_dev *dev, struct ieee80211_vif *vif,
-struct ieee80211_sta *sta);
+int mt76_sta_state(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+  struct ieee80211_sta *sta,
+  enum ieee80211_sta_state old_state,
+  enum ieee80211_sta_state new_state);
 
 struct ieee80211_sta *mt76_rx_convert(struct sk_buff *skb);
 
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/pci.c 
b/drivers/net/wireless/mediatek/mt76/mt76x0/pci.c
index 757816d2b1ab..d895b6f3dc44 100644
--- a/d

[PATCH v2 3/7] mt76: fix race condition in station removal

2018-11-16 Thread Felix Fietkau
If there are still pending packets in the tx queue when removing a station,
it could possibly lead to a call to further attempts to pull packets from
the mac80211 tx queue after it has already been removed from the scheduling
list.
Prevent this from happening by calling synchronize_rcu after deleting the
wcid pointer before further cleaning up the tx queues.
To be extra careful, ensure that mtxq->list is always initialized properly.

Signed-off-by: Felix Fietkau 
---
v2: keep the call to mt76x02_mac_wcid_setup in place

 drivers/net/wireless/mediatek/mt76/mt76x02_util.c | 4 +++-
 drivers/net/wireless/mediatek/mt76/tx.c   | 2 +-
 2 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c 
b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
index d2ac1a84668c..1a51193d5d59 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
@@ -216,9 +216,11 @@ int mt76x02_sta_remove(struct ieee80211_hw *hw, struct 
ieee80211_vif *vif,
int idx = msta->wcid.idx;
int i;
 
+   rcu_assign_pointer(dev->mt76.wcid[idx], NULL);
+   synchronize_rcu();
+
mutex_lock(>mt76.mutex);
mt76_tx_status_check(>mt76, >wcid, true);
-   rcu_assign_pointer(dev->mt76.wcid[idx], NULL);
for (i = 0; i < ARRAY_SIZE(sta->txq); i++)
mt76_txq_remove(>mt76, sta->txq[i]);
mt76x02_mac_wcid_set_drop(dev, idx, true);
diff --git a/drivers/net/wireless/mediatek/mt76/tx.c 
b/drivers/net/wireless/mediatek/mt76/tx.c
index e42a24628e4f..f4093dc0e174 100644
--- a/drivers/net/wireless/mediatek/mt76/tx.c
+++ b/drivers/net/wireless/mediatek/mt76/tx.c
@@ -590,7 +590,7 @@ void mt76_txq_remove(struct mt76_dev *dev, struct 
ieee80211_txq *txq)
 
spin_lock_bh(>lock);
if (!list_empty(>list))
-   list_del(>list);
+   list_del_init(>list);
spin_unlock_bh(>lock);
 
while ((skb = skb_dequeue(>retry_q)) != NULL)
-- 
2.17.0



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

2018-11-16 Thread Felix Fietkau
Open-coding it simplifies the code

Signed-off-by: Felix Fietkau 
---
 .../net/wireless/mediatek/mt76/mt76x02_mac.c  | 23 ---
 .../net/wireless/mediatek/mt76/mt76x02_mac.h  |  2 --
 .../net/wireless/mediatek/mt76/mt76x02_util.c | 15 +---
 3 files changed, 12 insertions(+), 28 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c 
b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
index 4c35d3f7fb15..c08bf371e527 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
@@ -126,29 +126,6 @@ void mt76x02_mac_wcid_set_drop(struct mt76x02_dev *dev, u8 
idx, bool drop)
mt76_wr(dev, MT_WCID_DROP(idx), (val & ~bit) | (bit * drop));
 }
 
-void mt76x02_txq_init(struct mt76x02_dev *dev, struct ieee80211_txq *txq)
-{
-   struct mt76_txq *mtxq;
-
-   if (!txq)
-   return;
-
-   mtxq = (struct mt76_txq *) txq->drv_priv;
-   if (txq->sta) {
-   struct mt76x02_sta *sta;
-
-   sta = (struct mt76x02_sta *) txq->sta->drv_priv;
-   mtxq->wcid = >wcid;
-   } else {
-   struct mt76x02_vif *mvif;
-
-   mvif = (struct mt76x02_vif *) txq->vif->drv_priv;
-   mtxq->wcid = >group_wcid;
-   }
-
-   mt76_txq_init(>mt76, txq);
-}
-
 static __le16
 mt76x02_mac_tx_rate_val(struct mt76x02_dev *dev,
const struct ieee80211_tx_rate *rate, u8 *nss_val)
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.h 
b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.h
index cf5c06a0a58a..4e597004c445 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.h
@@ -178,8 +178,6 @@ static inline bool mt76x02_wait_for_mac(struct mt76_dev 
*dev)
return false;
 }
 
-void mt76x02_txq_init(struct mt76x02_dev *dev, struct ieee80211_txq *txq);
-
 void mt76x02_mac_set_short_preamble(struct mt76x02_dev *dev, bool enable);
 int mt76x02_mac_shared_key_setup(struct mt76x02_dev *dev, u8 vif_idx,
 u8 key_idx, struct ieee80211_key_conf *key);
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c 
b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
index 0ea7ab9cf0c6..f5ebed75b939 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
@@ -191,8 +191,13 @@ int mt76x02_sta_add(struct ieee80211_hw *hw, struct 
ieee80211_vif *vif,
msta->wcid.hw_key_idx = -1;
mt76x02_mac_wcid_setup(dev, idx, mvif->idx, sta->addr);
mt76x02_mac_wcid_set_drop(dev, idx, false);
-   for (i = 0; i < ARRAY_SIZE(sta->txq); i++)
-   mt76x02_txq_init(dev, sta->txq[i]);
+   for (i = 0; i < ARRAY_SIZE(sta->txq); i++) {
+   struct mt76_txq *mtxq;
+
+   mtxq = (struct mt76_txq *) sta->txq[i]->drv_priv;
+   mtxq->wcid = >wcid;
+   mt76_txq_init(>mt76, sta->txq[i]);
+   }
 
if (vif->type == NL80211_IFTYPE_AP)
set_bit(MT_WCID_FLAG_CHECK_PS, >wcid.flags);
@@ -230,11 +235,15 @@ void mt76x02_vif_init(struct mt76x02_dev *dev, struct 
ieee80211_vif *vif,
  unsigned int idx)
 {
struct mt76x02_vif *mvif = (struct mt76x02_vif *)vif->drv_priv;
+   struct mt76_txq *mtxq;
 
mvif->idx = idx;
mvif->group_wcid.idx = MT_VIF_WCID(idx);
mvif->group_wcid.hw_key_idx = -1;
-   mt76x02_txq_init(dev, vif->txq);
+   mtxq = (struct mt76_txq *) vif->txq->drv_priv;
+   mtxq->wcid = >group_wcid;
+
+   mt76_txq_init(>mt76, vif->txq);
 }
 EXPORT_SYMBOL_GPL(mt76x02_vif_init);
 
-- 
2.17.0



[PATCH v2 1/7] mt76: avoid queue/status spinlocks while passing tx status to mac80211

2018-11-16 Thread Felix Fietkau
There is some code in the mac80211 tx status processing code that could
potentially call back into the tx codepath.
To avoid deadlocks, make sure that no tx related spinlocks are taken
during the ieee80211_tx_status call.

Signed-off-by: Felix Fietkau 
---
 drivers/net/wireless/mediatek/mt76/dma.c  | 11 ++--
 drivers/net/wireless/mediatek/mt76/mac80211.c |  2 +-
 drivers/net/wireless/mediatek/mt76/mt76.h | 30 --
 .../net/wireless/mediatek/mt76/mt76x02_mac.c  | 11 ++--
 .../net/wireless/mediatek/mt76/mt76x02_util.c |  2 +-
 drivers/net/wireless/mediatek/mt76/tx.c   | 58 ---
 6 files changed, 76 insertions(+), 38 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/dma.c 
b/drivers/net/wireless/mediatek/mt76/dma.c
index 2d7bd26875c6..d62f8d9f2ea1 100644
--- a/drivers/net/wireless/mediatek/mt76/dma.c
+++ b/drivers/net/wireless/mediatek/mt76/dma.c
@@ -157,17 +157,20 @@ mt76_dma_tx_cleanup(struct mt76_dev *dev, enum 
mt76_txq_id qid, bool flush)
if (entry.schedule)
q->swq_queued--;
 
-   if (entry.skb)
+   q->tail = (q->tail + 1) % q->ndesc;
+   q->queued--;
+
+   if (entry.skb) {
+   spin_unlock_bh(>lock);
dev->drv->tx_complete_skb(dev, q, , flush);
+   spin_lock_bh(>lock);
+   }
 
if (entry.txwi) {
mt76_put_txwi(dev, entry.txwi);
wake = true;
}
 
-   q->tail = (q->tail + 1) % q->ndesc;
-   q->queued--;
-
if (!flush && q->tail == last)
last = ioread32(>regs->dma_idx);
}
diff --git a/drivers/net/wireless/mediatek/mt76/mac80211.c 
b/drivers/net/wireless/mediatek/mt76/mac80211.c
index 85e05a825b5d..3be73b021d27 100644
--- a/drivers/net/wireless/mediatek/mt76/mac80211.c
+++ b/drivers/net/wireless/mediatek/mt76/mac80211.c
@@ -359,7 +359,7 @@ void mt76_unregister_device(struct mt76_dev *dev)
 {
struct ieee80211_hw *hw = dev->hw;
 
-   mt76_tx_status_flush(dev, NULL);
+   mt76_tx_status_check(dev, NULL, true);
ieee80211_unregister_hw(hw);
mt76_tx_free(dev);
 }
diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h 
b/drivers/net/wireless/mediatek/mt76/mt76.h
index e1d89163ee6b..ea74ba00aebc 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76.h
@@ -648,28 +648,22 @@ void mt76_rx_aggr_stop(struct mt76_dev *dev, struct 
mt76_wcid *wcid, u8 tid);
 
 void mt76_wcid_key_setup(struct mt76_dev *dev, struct mt76_wcid *wcid,
 struct ieee80211_key_conf *key);
+
+void mt76_tx_status_lock(struct mt76_dev *dev, struct sk_buff_head *list)
+__acquires(>status_list.lock);
+void mt76_tx_status_unlock(struct mt76_dev *dev, struct sk_buff_head *list)
+  __releases(>status_list.lock);
+
 int mt76_tx_status_skb_add(struct mt76_dev *dev, struct mt76_wcid *wcid,
   struct sk_buff *skb);
 struct sk_buff *mt76_tx_status_skb_get(struct mt76_dev *dev,
-  struct mt76_wcid *wcid, int pktid);
-void mt76_tx_status_skb_done(struct mt76_dev *dev, struct sk_buff *skb);
+  struct mt76_wcid *wcid, int pktid,
+  struct sk_buff_head *list);
+void mt76_tx_status_skb_done(struct mt76_dev *dev, struct sk_buff *skb,
+struct sk_buff_head *list);
 void mt76_tx_complete_skb(struct mt76_dev *dev, struct sk_buff *skb);
-
-static inline void
-mt76_tx_status_check(struct mt76_dev *dev)
-{
-   spin_lock_bh(>status_list.lock);
-   mt76_tx_status_skb_get(dev, NULL, 0);
-   spin_unlock_bh(>status_list.lock);
-}
-
-static inline void
-mt76_tx_status_flush(struct mt76_dev *dev, struct mt76_wcid *wcid)
-{
-   spin_lock_bh(>status_list.lock);
-   mt76_tx_status_skb_get(dev, wcid, -1);
-   spin_unlock_bh(>status_list.lock);
-}
+void mt76_tx_status_check(struct mt76_dev *dev, struct mt76_wcid *wcid,
+ bool flush);
 
 struct ieee80211_sta *mt76_rx_convert(struct sk_buff *skb);
 
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c 
b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
index 59b336e34cb5..4c35d3f7fb15 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
@@ -438,12 +438,13 @@ void mt76x02_send_tx_status(struct mt76x02_dev *dev,
struct mt76_wcid *wcid = NULL;
struct mt76x02_sta *msta = NULL;
struct mt76_dev *mdev = >mt76;
+   struct sk_buff_head list;
 
if (stat->pktid == MT_PACKET_ID_NO_ACK)
return;
 
rcu_read_lock();
-   spin_lock_b

[PATCH v2 5/7] mt76: mt76x02: make group_wcid the first member in struct mt76x02_vif

2018-11-16 Thread Felix Fietkau
Allows mt76 core to cast vif->drv_priv to struct mt76_wcid

Signed-off-by: Felix Fietkau 
---
 drivers/net/wireless/mediatek/mt76/mt76x02_mac.h | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.h 
b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.h
index b076c4305585..cf5c06a0a58a 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.h
@@ -37,9 +37,8 @@ struct mt76x02_tx_status {
 #define MT_MAX_VIFS8
 
 struct mt76x02_vif {
+   struct mt76_wcid group_wcid; /* must be first */
u8 idx;
-
-   struct mt76_wcid group_wcid;
 };
 
 DECLARE_EWMA(signal, 10, 8);
-- 
2.17.0



[PATCH v2 4/7] mt76: add mt76_sta_remove helper

2018-11-16 Thread Felix Fietkau
This allows station removal code to be used by mt7603 later

Signed-off-by: Felix Fietkau 
---
 drivers/net/wireless/mediatek/mt76/mac80211.c | 19 +++
 drivers/net/wireless/mediatek/mt76/mt76.h |  2 ++
 .../net/wireless/mediatek/mt76/mt76x02_util.c | 12 +++-
 3 files changed, 24 insertions(+), 9 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mac80211.c 
b/drivers/net/wireless/mediatek/mt76/mac80211.c
index 3be73b021d27..1098919f5498 100644
--- a/drivers/net/wireless/mediatek/mt76/mac80211.c
+++ b/drivers/net/wireless/mediatek/mt76/mac80211.c
@@ -630,3 +630,22 @@ void mt76_rx_poll_complete(struct mt76_dev *dev, enum 
mt76_rxq_id q,
mt76_rx_complete(dev, , napi);
 }
 EXPORT_SYMBOL_GPL(mt76_rx_poll_complete);
+
+void mt76_sta_remove(struct mt76_dev *dev, struct ieee80211_vif *vif,
+struct ieee80211_sta *sta)
+{
+   struct mt76_wcid *wcid = (struct mt76_wcid *)sta->drv_priv;
+   int idx = wcid->idx;
+   int i;
+
+   rcu_assign_pointer(dev->wcid[idx], NULL);
+   synchronize_rcu();
+
+   mutex_lock(>mutex);
+   mt76_tx_status_check(dev, wcid, true);
+   for (i = 0; i < ARRAY_SIZE(sta->txq); i++)
+   mt76_txq_remove(dev, sta->txq[i]);
+   mt76_wcid_free(dev->wcid_mask, idx);
+   mutex_unlock(>mutex);
+}
+EXPORT_SYMBOL_GPL(mt76_sta_remove);
diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h 
b/drivers/net/wireless/mediatek/mt76/mt76.h
index ea74ba00aebc..878836fe80d3 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76.h
@@ -664,6 +664,8 @@ void mt76_tx_status_skb_done(struct mt76_dev *dev, struct 
sk_buff *skb,
 void mt76_tx_complete_skb(struct mt76_dev *dev, struct sk_buff *skb);
 void mt76_tx_status_check(struct mt76_dev *dev, struct mt76_wcid *wcid,
  bool flush);
+void mt76_sta_remove(struct mt76_dev *dev, struct ieee80211_vif *vif,
+struct ieee80211_sta *sta);
 
 struct ieee80211_sta *mt76_rx_convert(struct sk_buff *skb);
 
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c 
b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
index 1a51193d5d59..0ea7ab9cf0c6 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
@@ -212,19 +212,13 @@ int mt76x02_sta_remove(struct ieee80211_hw *hw, struct 
ieee80211_vif *vif,
   struct ieee80211_sta *sta)
 {
struct mt76x02_dev *dev = hw->priv;
-   struct mt76x02_sta *msta = (struct mt76x02_sta *)sta->drv_priv;
-   int idx = msta->wcid.idx;
-   int i;
+   struct mt76_wcid *wcid = (struct mt76_wcid *)sta->drv_priv;
+   int idx = wcid->idx;
 
-   rcu_assign_pointer(dev->mt76.wcid[idx], NULL);
-   synchronize_rcu();
+   mt76_sta_remove(>mt76, vif, sta);
 
mutex_lock(>mt76.mutex);
-   mt76_tx_status_check(>mt76, >wcid, true);
-   for (i = 0; i < ARRAY_SIZE(sta->txq); i++)
-   mt76_txq_remove(>mt76, sta->txq[i]);
mt76x02_mac_wcid_set_drop(dev, idx, true);
-   mt76_wcid_free(dev->mt76.wcid_mask, idx);
mt76x02_mac_wcid_setup(dev, idx, 0, NULL);
mutex_unlock(>mt76.mutex);
 
-- 
2.17.0



[PATCH v2 2/7] mt76: do not wake tx queues during flush

2018-11-16 Thread Felix Fietkau
While the queue is being cleaned up, the stack must not attempt to add
any extra packets

Signed-off-by: Felix Fietkau 
---
 drivers/net/wireless/mediatek/mt76/dma.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/wireless/mediatek/mt76/dma.c 
b/drivers/net/wireless/mediatek/mt76/dma.c
index d62f8d9f2ea1..e2ba26378575 100644
--- a/drivers/net/wireless/mediatek/mt76/dma.c
+++ b/drivers/net/wireless/mediatek/mt76/dma.c
@@ -168,7 +168,7 @@ mt76_dma_tx_cleanup(struct mt76_dev *dev, enum mt76_txq_id 
qid, bool flush)
 
if (entry.txwi) {
mt76_put_txwi(dev, entry.txwi);
-   wake = true;
+   wake = !flush;
}
 
if (!flush && q->tail == last)
-- 
2.17.0



[PATCH v2 7/7] mt76: replace sta_add/remove ops with common sta_state function

2018-11-16 Thread Felix Fietkau
Allows adding unassociated stations from mac80211

Signed-off-by: Felix Fietkau 
---
 drivers/net/wireless/mediatek/mt76/mac80211.c | 61 ++-
 drivers/net/wireless/mediatek/mt76/mt76.h | 12 +++-
 .../net/wireless/mediatek/mt76/mt76x0/pci.c   |  5 +-
 .../net/wireless/mediatek/mt76/mt76x0/usb.c   |  5 +-
 drivers/net/wireless/mediatek/mt76/mt76x02.h  |  8 +--
 .../net/wireless/mediatek/mt76/mt76x02_util.c | 40 +++-
 .../wireless/mediatek/mt76/mt76x2/pci_init.c  |  2 +
 .../wireless/mediatek/mt76/mt76x2/pci_main.c  |  3 +-
 .../wireless/mediatek/mt76/mt76x2/usb_init.c  |  2 +
 .../wireless/mediatek/mt76/mt76x2/usb_main.c  |  3 +-
 10 files changed, 92 insertions(+), 49 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mac80211.c 
b/drivers/net/wireless/mediatek/mt76/mac80211.c
index 1098919f5498..d3f94163ef8e 100644
--- a/drivers/net/wireless/mediatek/mt76/mac80211.c
+++ b/drivers/net/wireless/mediatek/mt76/mac80211.c
@@ -631,8 +631,40 @@ void mt76_rx_poll_complete(struct mt76_dev *dev, enum 
mt76_rxq_id q,
 }
 EXPORT_SYMBOL_GPL(mt76_rx_poll_complete);
 
-void mt76_sta_remove(struct mt76_dev *dev, struct ieee80211_vif *vif,
-struct ieee80211_sta *sta)
+static int
+mt76_sta_add(struct mt76_dev *dev, struct ieee80211_vif *vif,
+struct ieee80211_sta *sta)
+{
+   struct mt76_wcid *wcid = (struct mt76_wcid *)sta->drv_priv;
+   int ret;
+   int i;
+
+   mutex_lock(>mutex);
+
+   ret = dev->drv->sta_add(dev, vif, sta);
+   if (ret)
+   goto out;
+
+   for (i = 0; i < ARRAY_SIZE(sta->txq); i++) {
+   struct mt76_txq *mtxq;
+
+   mtxq = (struct mt76_txq *)sta->txq[i]->drv_priv;
+   mtxq->wcid = wcid;
+
+   mt76_txq_init(dev, sta->txq[i]);
+   }
+
+   rcu_assign_pointer(dev->wcid[wcid->idx], wcid);
+
+out:
+   mutex_unlock(>mutex);
+
+   return ret;
+}
+
+static void
+mt76_sta_remove(struct mt76_dev *dev, struct ieee80211_vif *vif,
+   struct ieee80211_sta *sta)
 {
struct mt76_wcid *wcid = (struct mt76_wcid *)sta->drv_priv;
int idx = wcid->idx;
@@ -642,10 +674,33 @@ void mt76_sta_remove(struct mt76_dev *dev, struct 
ieee80211_vif *vif,
synchronize_rcu();
 
mutex_lock(>mutex);
+
+   if (dev->drv->sta_remove)
+   dev->drv->sta_remove(dev, vif, sta);
+
mt76_tx_status_check(dev, wcid, true);
for (i = 0; i < ARRAY_SIZE(sta->txq); i++)
mt76_txq_remove(dev, sta->txq[i]);
mt76_wcid_free(dev->wcid_mask, idx);
+
mutex_unlock(>mutex);
 }
-EXPORT_SYMBOL_GPL(mt76_sta_remove);
+
+int mt76_sta_state(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+  struct ieee80211_sta *sta,
+  enum ieee80211_sta_state old_state,
+  enum ieee80211_sta_state new_state)
+{
+   struct mt76_dev *dev = hw->priv;
+
+   if (old_state == IEEE80211_STA_NOTEXIST &&
+   new_state == IEEE80211_STA_NONE)
+   return mt76_sta_add(dev, vif, sta);
+
+   if (old_state == IEEE80211_STA_NONE &&
+new_state == IEEE80211_STA_NOTEXIST)
+   mt76_sta_remove(dev, vif, sta);
+
+   return 0;
+}
+EXPORT_SYMBOL_GPL(mt76_sta_state);
diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h 
b/drivers/net/wireless/mediatek/mt76/mt76.h
index 878836fe80d3..5cd508a68609 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76.h
@@ -288,6 +288,12 @@ struct mt76_driver_ops {
 
void (*sta_ps)(struct mt76_dev *dev, struct ieee80211_sta *sta,
   bool ps);
+
+   int (*sta_add)(struct mt76_dev *dev, struct ieee80211_vif *vif,
+  struct ieee80211_sta *sta);
+
+   void (*sta_remove)(struct mt76_dev *dev, struct ieee80211_vif *vif,
+  struct ieee80211_sta *sta);
 };
 
 struct mt76_channel_state {
@@ -664,8 +670,10 @@ void mt76_tx_status_skb_done(struct mt76_dev *dev, struct 
sk_buff *skb,
 void mt76_tx_complete_skb(struct mt76_dev *dev, struct sk_buff *skb);
 void mt76_tx_status_check(struct mt76_dev *dev, struct mt76_wcid *wcid,
  bool flush);
-void mt76_sta_remove(struct mt76_dev *dev, struct ieee80211_vif *vif,
-struct ieee80211_sta *sta);
+int mt76_sta_state(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+  struct ieee80211_sta *sta,
+  enum ieee80211_sta_state old_state,
+  enum ieee80211_sta_state new_state);
 
 struct ieee80211_sta *mt76_rx_convert(struct sk_buff *skb);
 
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/pci.c 
b/drivers/net/wireless/mediatek/mt76/mt76x0/pci.c
index 757816d2b1ab..d895b6f3dc44 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x0/pci.c
+++ b/drive

Re: [PATCH 3/4] mt76: fix race condition in station removal

2018-11-16 Thread Felix Fietkau
On 2018-11-13 20:41, Felix Fietkau wrote:
> If there are still pending packets in the tx queue when removing a station,
> it could possibly lead to a call to further attempts to pull packets from
> the mac80211 tx queue after it has already been removed from the scheduling
> list.
> Prevent this from happening by calling synchronize_rcu after deleting the
> wcid pointer before further cleaning up the tx queues.
> To be extra careful, ensure that mtxq->list is always initialized properly.
> 
> Also drop the useless call to mt76x02_mac_wcid_setup, which only re-assigns
> the bss index of the wcid entry, but does not help with the cleanup in any
> way.
I misread the code and the call to mt76x02_mac_wcid_setup matters after
all. Will send a v2 of this series with further improvements.

- Felix


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

2018-11-13 Thread Felix Fietkau
On 2018-11-13 20:45, Felix Fietkau wrote:
> On 2018-11-09 11:56, Stanislaw Gruszka wrote:
>> We always wait for CMD_CALIBRATION_OP mcu message, but wait argument is used
>> for do additional MT_MCU_COM_REG0 register operations, which are needed
>> for mt76x2e devices and we can use appropriate check instead of wait 
>> argument.
>> 
>> Signed-off-by: Stanislaw Gruszka 
> This doesn't apply on my tree. Am I missing some other patch?
Never mind, found it. Applied, thanks.

- Felix


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

2018-11-13 Thread Felix Fietkau
On 2018-11-06 17:59, Lorenzo Bianconi wrote:
> Perform channel calibration after each channel switch and not only after
> connection establishment.
> Enable MCU_CAL_TX_SHAPING phy calibration.
> Moreover remove remove beacon offset configuration since the driver
> supports just client mode
Applied, thanks.

- Felix


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

2018-11-13 Thread Felix Fietkau
On 2018-11-06 23:54, Lorenzo Bianconi wrote:
> Enable VHT tx rates in ad-hoc mode for mt76x0e driver.
> 
> Signed-off-by: Lorenzo Bianconi 
Applied, thanks.

- Felix


Re: [PATCH] mt76: introduce mt76x02_config_mac_addr_list routine

2018-11-13 Thread Felix Fietkau
On 2018-11-06 23:49, Lorenzo Bianconi wrote:
> Add mt76x02_config_mac_addr_list routine in order to set
> the mac address list supported by the driver. Initialize
> wiphy->addresses/n_addresses for mt76x0e driver
> 
> Signed-off-by: Lorenzo Bianconi 
Applied, thanks.

- Felix


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

2018-11-13 Thread Felix Fietkau
On 2018-11-09 11:56, Stanislaw Gruszka wrote:
> We always wait for CMD_CALIBRATION_OP mcu message, but wait argument is used
> for do additional MT_MCU_COM_REG0 register operations, which are needed
> for mt76x2e devices and we can use appropriate check instead of wait argument.
> 
> Signed-off-by: Stanislaw Gruszka 
This doesn't apply on my tree. Am I missing some other patch?

- Felix


[PATCH 2/4] mt76: do not wake tx queues during flush

2018-11-13 Thread Felix Fietkau
While the queue is being cleaned up, the stack must not attempt to add
any extra packets

Signed-off-by: Felix Fietkau 
---
 drivers/net/wireless/mediatek/mt76/dma.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/wireless/mediatek/mt76/dma.c 
b/drivers/net/wireless/mediatek/mt76/dma.c
index d62f8d9f2ea1..e2ba26378575 100644
--- a/drivers/net/wireless/mediatek/mt76/dma.c
+++ b/drivers/net/wireless/mediatek/mt76/dma.c
@@ -168,7 +168,7 @@ mt76_dma_tx_cleanup(struct mt76_dev *dev, enum mt76_txq_id 
qid, bool flush)
 
if (entry.txwi) {
mt76_put_txwi(dev, entry.txwi);
-   wake = true;
+   wake = !flush;
}
 
if (!flush && q->tail == last)
-- 
2.17.0



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

2018-11-13 Thread Felix Fietkau
There is some code in the mac80211 tx status processing code that could
potentially call back into the tx codepath.
To avoid deadlocks, make sure that no tx related spinlocks are taken
during the ieee80211_tx_status call.

Signed-off-by: Felix Fietkau 
---
 drivers/net/wireless/mediatek/mt76/dma.c  | 11 ++--
 drivers/net/wireless/mediatek/mt76/mac80211.c |  2 +-
 drivers/net/wireless/mediatek/mt76/mt76.h | 30 --
 .../net/wireless/mediatek/mt76/mt76x02_mac.c  | 11 ++--
 .../net/wireless/mediatek/mt76/mt76x02_util.c |  2 +-
 drivers/net/wireless/mediatek/mt76/tx.c   | 58 ---
 6 files changed, 76 insertions(+), 38 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/dma.c 
b/drivers/net/wireless/mediatek/mt76/dma.c
index 2d7bd26875c6..d62f8d9f2ea1 100644
--- a/drivers/net/wireless/mediatek/mt76/dma.c
+++ b/drivers/net/wireless/mediatek/mt76/dma.c
@@ -157,17 +157,20 @@ mt76_dma_tx_cleanup(struct mt76_dev *dev, enum 
mt76_txq_id qid, bool flush)
if (entry.schedule)
q->swq_queued--;
 
-   if (entry.skb)
+   q->tail = (q->tail + 1) % q->ndesc;
+   q->queued--;
+
+   if (entry.skb) {
+   spin_unlock_bh(>lock);
dev->drv->tx_complete_skb(dev, q, , flush);
+   spin_lock_bh(>lock);
+   }
 
if (entry.txwi) {
mt76_put_txwi(dev, entry.txwi);
wake = true;
}
 
-   q->tail = (q->tail + 1) % q->ndesc;
-   q->queued--;
-
if (!flush && q->tail == last)
last = ioread32(>regs->dma_idx);
}
diff --git a/drivers/net/wireless/mediatek/mt76/mac80211.c 
b/drivers/net/wireless/mediatek/mt76/mac80211.c
index 85e05a825b5d..3be73b021d27 100644
--- a/drivers/net/wireless/mediatek/mt76/mac80211.c
+++ b/drivers/net/wireless/mediatek/mt76/mac80211.c
@@ -359,7 +359,7 @@ void mt76_unregister_device(struct mt76_dev *dev)
 {
struct ieee80211_hw *hw = dev->hw;
 
-   mt76_tx_status_flush(dev, NULL);
+   mt76_tx_status_check(dev, NULL, true);
ieee80211_unregister_hw(hw);
mt76_tx_free(dev);
 }
diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h 
b/drivers/net/wireless/mediatek/mt76/mt76.h
index e1d89163ee6b..ea74ba00aebc 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76.h
@@ -648,28 +648,22 @@ void mt76_rx_aggr_stop(struct mt76_dev *dev, struct 
mt76_wcid *wcid, u8 tid);
 
 void mt76_wcid_key_setup(struct mt76_dev *dev, struct mt76_wcid *wcid,
 struct ieee80211_key_conf *key);
+
+void mt76_tx_status_lock(struct mt76_dev *dev, struct sk_buff_head *list)
+__acquires(>status_list.lock);
+void mt76_tx_status_unlock(struct mt76_dev *dev, struct sk_buff_head *list)
+  __releases(>status_list.lock);
+
 int mt76_tx_status_skb_add(struct mt76_dev *dev, struct mt76_wcid *wcid,
   struct sk_buff *skb);
 struct sk_buff *mt76_tx_status_skb_get(struct mt76_dev *dev,
-  struct mt76_wcid *wcid, int pktid);
-void mt76_tx_status_skb_done(struct mt76_dev *dev, struct sk_buff *skb);
+  struct mt76_wcid *wcid, int pktid,
+  struct sk_buff_head *list);
+void mt76_tx_status_skb_done(struct mt76_dev *dev, struct sk_buff *skb,
+struct sk_buff_head *list);
 void mt76_tx_complete_skb(struct mt76_dev *dev, struct sk_buff *skb);
-
-static inline void
-mt76_tx_status_check(struct mt76_dev *dev)
-{
-   spin_lock_bh(>status_list.lock);
-   mt76_tx_status_skb_get(dev, NULL, 0);
-   spin_unlock_bh(>status_list.lock);
-}
-
-static inline void
-mt76_tx_status_flush(struct mt76_dev *dev, struct mt76_wcid *wcid)
-{
-   spin_lock_bh(>status_list.lock);
-   mt76_tx_status_skb_get(dev, wcid, -1);
-   spin_unlock_bh(>status_list.lock);
-}
+void mt76_tx_status_check(struct mt76_dev *dev, struct mt76_wcid *wcid,
+ bool flush);
 
 struct ieee80211_sta *mt76_rx_convert(struct sk_buff *skb);
 
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c 
b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
index 59b336e34cb5..4c35d3f7fb15 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
@@ -438,12 +438,13 @@ void mt76x02_send_tx_status(struct mt76x02_dev *dev,
struct mt76_wcid *wcid = NULL;
struct mt76x02_sta *msta = NULL;
struct mt76_dev *mdev = >mt76;
+   struct sk_buff_head list;
 
if (stat->pktid == MT_PACKET_ID_NO_ACK)
return;
 
rcu_read_lock();
-   spin_lock_b

[PATCH 3/4] mt76: fix race condition in station removal

2018-11-13 Thread Felix Fietkau
If there are still pending packets in the tx queue when removing a station,
it could possibly lead to a call to further attempts to pull packets from
the mac80211 tx queue after it has already been removed from the scheduling
list.
Prevent this from happening by calling synchronize_rcu after deleting the
wcid pointer before further cleaning up the tx queues.
To be extra careful, ensure that mtxq->list is always initialized properly.

Also drop the useless call to mt76x02_mac_wcid_setup, which only re-assigns
the bss index of the wcid entry, but does not help with the cleanup in any
way.

Signed-off-by: Felix Fietkau 
---
 drivers/net/wireless/mediatek/mt76/mt76x02_util.c | 5 +++--
 drivers/net/wireless/mediatek/mt76/tx.c   | 2 +-
 2 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c 
b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
index 850b0f050da5..cd32ef5864b5 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
@@ -214,14 +214,15 @@ int mt76x02_sta_remove(struct ieee80211_hw *hw, struct 
ieee80211_vif *vif,
int idx = msta->wcid.idx;
int i;
 
+   rcu_assign_pointer(dev->mt76.wcid[idx], NULL);
+   synchronize_rcu();
+
mutex_lock(>mt76.mutex);
mt76_tx_status_check(>mt76, >wcid, true);
-   rcu_assign_pointer(dev->mt76.wcid[idx], NULL);
for (i = 0; i < ARRAY_SIZE(sta->txq); i++)
mt76_txq_remove(>mt76, sta->txq[i]);
mt76x02_mac_wcid_set_drop(dev, idx, true);
mt76_wcid_free(dev->mt76.wcid_mask, idx);
-   mt76x02_mac_wcid_setup(dev, idx, 0, NULL);
mutex_unlock(>mt76.mutex);
 
return 0;
diff --git a/drivers/net/wireless/mediatek/mt76/tx.c 
b/drivers/net/wireless/mediatek/mt76/tx.c
index e42a24628e4f..f4093dc0e174 100644
--- a/drivers/net/wireless/mediatek/mt76/tx.c
+++ b/drivers/net/wireless/mediatek/mt76/tx.c
@@ -590,7 +590,7 @@ void mt76_txq_remove(struct mt76_dev *dev, struct 
ieee80211_txq *txq)
 
spin_lock_bh(>lock);
if (!list_empty(>list))
-   list_del(>list);
+   list_del_init(>list);
spin_unlock_bh(>lock);
 
while ((skb = skb_dequeue(>retry_q)) != NULL)
-- 
2.17.0



[PATCH 4/4] mt76: add mt76_sta_remove helper

2018-11-13 Thread Felix Fietkau
This allows station removal code to be used by mt7603 later

Signed-off-by: Felix Fietkau 
---
 drivers/net/wireless/mediatek/mt76/mac80211.c | 19 +++
 drivers/net/wireless/mediatek/mt76/mt76.h |  2 ++
 .../net/wireless/mediatek/mt76/mt76x02_util.c | 12 +++-
 3 files changed, 24 insertions(+), 9 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mac80211.c 
b/drivers/net/wireless/mediatek/mt76/mac80211.c
index 3be73b021d27..1098919f5498 100644
--- a/drivers/net/wireless/mediatek/mt76/mac80211.c
+++ b/drivers/net/wireless/mediatek/mt76/mac80211.c
@@ -630,3 +630,22 @@ void mt76_rx_poll_complete(struct mt76_dev *dev, enum 
mt76_rxq_id q,
mt76_rx_complete(dev, , napi);
 }
 EXPORT_SYMBOL_GPL(mt76_rx_poll_complete);
+
+void mt76_sta_remove(struct mt76_dev *dev, struct ieee80211_vif *vif,
+struct ieee80211_sta *sta)
+{
+   struct mt76_wcid *wcid = (struct mt76_wcid *)sta->drv_priv;
+   int idx = wcid->idx;
+   int i;
+
+   rcu_assign_pointer(dev->wcid[idx], NULL);
+   synchronize_rcu();
+
+   mutex_lock(>mutex);
+   mt76_tx_status_check(dev, wcid, true);
+   for (i = 0; i < ARRAY_SIZE(sta->txq); i++)
+   mt76_txq_remove(dev, sta->txq[i]);
+   mt76_wcid_free(dev->wcid_mask, idx);
+   mutex_unlock(>mutex);
+}
+EXPORT_SYMBOL_GPL(mt76_sta_remove);
diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h 
b/drivers/net/wireless/mediatek/mt76/mt76.h
index ea74ba00aebc..878836fe80d3 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76.h
@@ -664,6 +664,8 @@ void mt76_tx_status_skb_done(struct mt76_dev *dev, struct 
sk_buff *skb,
 void mt76_tx_complete_skb(struct mt76_dev *dev, struct sk_buff *skb);
 void mt76_tx_status_check(struct mt76_dev *dev, struct mt76_wcid *wcid,
  bool flush);
+void mt76_sta_remove(struct mt76_dev *dev, struct ieee80211_vif *vif,
+struct ieee80211_sta *sta);
 
 struct ieee80211_sta *mt76_rx_convert(struct sk_buff *skb);
 
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c 
b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
index cd32ef5864b5..dc25de2d02d5 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
@@ -210,19 +210,13 @@ int mt76x02_sta_remove(struct ieee80211_hw *hw, struct 
ieee80211_vif *vif,
   struct ieee80211_sta *sta)
 {
struct mt76x02_dev *dev = hw->priv;
-   struct mt76x02_sta *msta = (struct mt76x02_sta *)sta->drv_priv;
-   int idx = msta->wcid.idx;
-   int i;
+   struct mt76_wcid *wcid = (struct mt76_wcid *)sta->drv_priv;
+   int idx = wcid->idx;
 
-   rcu_assign_pointer(dev->mt76.wcid[idx], NULL);
-   synchronize_rcu();
+   mt76_sta_remove(>mt76, vif, sta);
 
mutex_lock(>mt76.mutex);
-   mt76_tx_status_check(>mt76, >wcid, true);
-   for (i = 0; i < ARRAY_SIZE(sta->txq); i++)
-   mt76_txq_remove(>mt76, sta->txq[i]);
mt76x02_mac_wcid_set_drop(dev, idx, true);
-   mt76_wcid_free(dev->mt76.wcid_mask, idx);
mutex_unlock(>mt76.mutex);
 
return 0;
-- 
2.17.0



[PATCH] mac80211: ignore tx status for PS stations in ieee80211_tx_status_ext

2018-11-13 Thread Felix Fietkau
Make it behave like regular ieee80211_tx_status calls, except for the lack of
filtered frame processing.
This fixes spurious low-ack triggered disconnections with powersave clients
connected to an AP.

Fixes: f027c2aca0cf4 ("mac80211: add ieee80211_tx_status_noskb")
Cc: sta...@vger.kernel.org
Signed-off-by: Felix Fietkau 
---
 net/mac80211/status.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/net/mac80211/status.c b/net/mac80211/status.c
index aa4afbf0abaf..a794ca729000 100644
--- a/net/mac80211/status.c
+++ b/net/mac80211/status.c
@@ -964,6 +964,8 @@ void ieee80211_tx_status_ext(struct ieee80211_hw *hw,
/* Track when last TDLS packet was ACKed */
if (test_sta_flag(sta, WLAN_STA_TDLS_PEER_AUTH))
sta->status_stats.last_tdls_pkt_time = jiffies;
+   } else if (test_sta_flag(sta, WLAN_STA_PS_STA)) {
+   return;
} else {
ieee80211_lost_packet(sta, info);
}
-- 
2.17.0



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

2018-11-09 Thread Felix Fietkau
On 2018-11-09 14:42, Lorenzo Bianconi wrote:
>> On Fri, Nov 09, 2018 at 01:50:51PM +0100, Lorenzo Bianconi wrote:
>> > > On 2018-11-09 12:09, Lorenzo Bianconi wrote:
>> > > >> Use MT_MAC_APC_BSSID0_H_EN bit to indicatate we are
>> > > >> setting BSSID for STA.
>> > > >> 
>> > > >> Signed-off-by: Stanislaw Gruszka 
>> > > >> ---
>> > > >>  drivers/net/wireless/mediatek/mt76/mt76x02_mac.c | 12 +---
>> > > >>  1 file changed, 9 insertions(+), 3 deletions(-)
>> > > >> 
>> > > >> diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c 
>> > > >> b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
>> > > >> index 59b336e34cb5..cfeae5586897 100644
>> > > >> --- a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
>> > > >> +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
>> > > >> @@ -826,10 +826,16 @@ void mt76x02_mac_work(struct work_struct *work)
>> > > >>  
>> > > >>  void mt76x02_mac_set_bssid(struct mt76x02_dev *dev, u8 idx, const u8 
>> > > >> *addr)
>> > > >>  {
>> > > >> + u32 bssid_h = FIELD_PREP(MT_MAC_APC_BSSID_H_ADDR,
>> > > >> +  get_unaligned_le16(addr + 4));
>> > > >> + u32 bssid_l = get_unaligned_le32(addr);
>> > > >> +
>> > > >> + if (idx > 7)
>> > > >> + bssid_h |= MT_MAC_APC_BSSID0_H_EN;
>> > > > 
>> > > > This bit is to enable APClient mode and it is valid just for register 
>> > > > 0x1094
>> > > > (MT_MAC_APC_BSSID_{L,h}(0)). Moreover IIRC APClient has been disabled 
>> > > > because
>> > > > it causes a performance degradation.
>> > > The performance degradation was with MAC_ADDR_EXT, not AP-Client.
>> > > This patch should be fine.
>> > 
>> > Ah, now I remember sorry, you are right :)
>> > Anyway IIRC MT_MAC_APC_BSSID0_H_EN is just for AP_CLIENT_BSSID0 (at least 
>> > for
>> > 76x2), for others we need to use BIT(31) but just if APClient is disabled, 
>> > right?
>> > Moreover BSSID filter is currently disabled (BIT(3) in RX_FILTER_CFG).
>> > 
>> > # echo 0x1400 > /sys/kernel/debug/ieee80211/phy0/mt76/regidx
>> > # cat /sys/kernel/debug/ieee80211/phy0/mt76/regval
>> > 0x00017f97
>> > 
>> > Have you tried to enabled it?
>> 
>> I didn't try this yet, but I think it should be enabled to support
>> mulit BSS and MAC address change. 
> 
> I agree we can use multi-BSS for mac filtering in AP mode but my gut feeling 
> in
> STA the hw uses the value in MT_MAC_ADDR_DW{0,1} for unicast packet filtering
> (BIT(2) in RX_FILTER_CFG). Moreover I think there is a relation between
> MT_MAC_ADDR_DW and BSSID values in multiAP mode.
I'm pretty sure that value also gets used for local ACK/BA filtering. We
definitely need to set it up properly.
In the past, I observed cases where a misconfigured MAC address led to
no tx status being reported anymore.

- Felix


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

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

- Felix


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

2018-11-08 Thread Felix Fietkau
On 2018-11-08 16:54, Stanislaw Gruszka wrote:
> On Thu, Nov 08, 2018 at 04:01:54PM +0100, Lorenzo Bianconi wrote:
>> > Restore behaviour on mt76x0 before commit  1bb04bb4b838 ("mt76: move
>> > mt76x02_init_device in mt76x02-lib module"). This will allow to use
>> > wcid 1 for AP when we work in station mode. It's not clear if this
>> > is needed, but this is how vendor driver assign wcid's in STA mode.
>> > This should be harmless for mt76x2.
>> >
>> > Signed-off-by: Stanislaw Gruszka 
>> > ---
>> >  drivers/net/wireless/mediatek/mt76/mt76x02_util.c | 6 +-
>> >  1 file changed, 5 insertions(+), 1 deletion(-)
>> >
>> > diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c 
>> > b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
>> > index 2be4b527477f..e624397b3d8b 100644
>> > --- a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
>> > +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
>> > @@ -113,7 +113,11 @@ void mt76x02_init_device(struct mt76x02_dev *dev)
>> > ieee80211_hw_set(hw, SUPPORTS_HT_CCK_RATES);
>> > ieee80211_hw_set(hw, SUPPORTS_REORDERING_BUFFER);
>> >
>> > -   dev->mt76.global_wcid.idx = 255;
>> > +   /* Reserve WCID 0 for mcast - thanks to this APs WCID will go to
>> > +* entry no. 1 like it does in the vendor driver.
>> > +*/
>> > +   dev->mt76.wcid_mask[0] |= 1;
>> > +   dev->mt76.global_wcid.idx = 0;
>> > dev->mt76.global_wcid.hw_key_idx = -1;
>> > dev->slottime = 9;
>> >
>> 
>> Does it make any difference in AP mode?
> 
> First sta will get wcid = 1 instead of 0.
> 
>> What about using 0 instead of
>> 255 for global_wcid.idx?
> 
> Patch do exactly that , it assigns:
> 
>   dev->mt76.global_wcid.idx = 0;
I don't think we should reserve WCID0 just because the vendor driver
does it, unless we can find a case where it actually makes a meaningful
difference. WCID entries >128 are useless for normal stations, so let's
use those for reserved entries instead of reducing the effective station
number limit.

- Felix


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

2018-11-08 Thread Felix Fietkau
On 2018-11-08 16:52, Stanislaw Gruszka wrote:
> On Thu, Nov 08, 2018 at 03:58:29PM +0100, Lorenzo Bianconi wrote:
>> > For STA mode configure legacy basic rates according to info
>> > mac80211 provides to us, as well as follback registers, which
>> > are setup in vendor driver under CONFIG_STA_SUPPORT .
>> > For LB_FBK_CFG1 register use values from vendor driver, which
>> > are different for mt76x0 and mt76x2 .
>> >
>> > Signed-off-by: Stanislaw Gruszka 
>> > ---
>> >  drivers/net/wireless/mediatek/mt76/mt76x02_util.c | 12 
>> >  1 file changed, 12 insertions(+)
>> >
>> > diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c 
>> > b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
>> > index 87ce6a51fb05..2be4b527477f 100644
>> > --- a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
>> > +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
>> > @@ -678,6 +678,18 @@ void mt76x02_bss_info_changed(struct ieee80211_hw *hw,
>> > tasklet_enable(>pre_tbtt_tasklet);
>> > }
>> >
>> > +   if (changed & BSS_CHANGED_BASIC_RATES &&
>> > +   vif->type == NL80211_IFTYPE_STATION) {
>> > +   mt76_wr(dev, MT_LEGACY_BASIC_RATE, info->basic_rates);
>> > +   mt76_wr(dev, MT_VHT_HT_FBK_CFG0, 0x65432100);
>> > +   mt76_wr(dev, MT_VHT_HT_FBK_CFG1, 0xedcba980);
>> > +   mt76_wr(dev, MT_LG_FBK_CFG0, 0xedcba988);
>> > +   if (is_mt76x2(dev))
>> > +   mt76_wr(dev, MT_LG_FBK_CFG1, 0x87872100);
>> > +   else
>> > +   mt76_wr(dev, MT_LG_FBK_CFG1, 0x00872100);
>> > +   }
>> > +
>> 
>> since these values are constant, why not put them init_vals?
> 
> I wanted them to be used only in STA mode like vendor driver does.
> However if we will have AP+STA , we still will configure them,
> so better to configure them anyway and put in init_vals .
Yes, I think we should put them in initvals. Also, I think we should
keep the values the shared between mt76x0 and mt76x2.

For MT_LG_FBK_CFG1 there is no need to make a distinction between 76x2
and 76x0, because 76x0 will simply ignore the upper values (they apply
to 2SS transmission only).
Also, I don't think MT_VHT_HT_FBK_CFG1 even gets used on mt76x0, because
it is for 2SS rates only. However, the value in there seems more useful
than the one we currently use on mt76x2, because it allows fallback from
2SS MCS0 to 1SS MCS0.
The contents of MT_LG_FBK_CFG0 also match the default initialization
values documented in the 7612E datasheet.

I don't think there is any meaningful difference between the 76x2 and
the 76x0 MAC except for the missing 2SS support.

- Felix


Re: [PATCH v3 1/2] mt76x02: run calibration after scanning

2018-11-05 Thread Felix Fietkau
On 2018-11-01 16:35, Stanislaw Gruszka wrote:
> If we are associated and scanning is performed, sw_scan_complete callback
> is done after we get back to operating channel, so we do not perform
> queue cal work. Fix this queue cal work from sw_scan_complete().
> 
> On mt76x0 we have to restore gain in MT_BBP(AGC, 8) register after
> scanning, as it was multiple times modified by channel switch code.
> So queue cal work without any delay to set AGC gain value.
> 
> Similar like in mt76x2 init AGC gain only when set operating channel
> and just check before queuing cal work in sw_scan_complete() if 
> initialization was already done.
> 
> Fixes: bbd10586f0df ("mt76x0: phy: do not run calibration during channel 
> switch")
> Signed-off-by: Stanislaw Gruszka 
Applied both patches, thanks.

- Felix


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

2018-11-05 Thread Felix Fietkau
On 2018-10-25 18:18, Stanislaw Gruszka wrote:
> We use always 1 as band parameter for MCU_CAL_LC, this break 2GHz,
> we should use 0 for this band instead.
> 
> Patch fixes problems happened sometimes when try to associate with 2GHz
> AP and manifest by errors like below:
> 
> [14680.920823] wlan0: authenticate with 18:31:bf:c0:51:b0
> [14681.109506] wlan0: send auth to 18:31:bf:c0:51:b0 (try 1/3)
> [14681.310454] wlan0: send auth to 18:31:bf:c0:51:b0 (try 2/3)
> [14681.518469] wlan0: send auth to 18:31:bf:c0:51:b0 (try 3/3)
> [14681.726499] wlan0: authentication with 18:31:bf:c0:51:b0 timed out
> 
> Fixes: 9aec146d0f6b ("mt76x0: pci: introduce mt76x0_phy_calirate routine")
> Signed-off-by: Stanislaw Gruszka 
Applied, thanks.

- Felix


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

2018-11-05 Thread Felix Fietkau
On 2018-11-05 00:18, Lorenzo Bianconi wrote:
> Fix IBI_R11 configuration on non-radar channels for mt76x0e
> driver. This patch improve system stability under heavy load.
> Moreover use IBI_R11 name and remove magic numbers for
> 0x212c register
> 
> Fixes: 0c3b3abc9251 ("mt76x0: pci: add DFS support")
> Signed-off-by: Lorenzo Bianconi 
Applied, thanks.

- Felix


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

2018-11-05 Thread Felix Fietkau
On 2018-10-29 22:31, Lorenzo Bianconi wrote:
> Introduce tssi calibration support in mt76x0 driver.
> Configure tx power gain according to tssi calibrated value
> if available
Applied, thanks.

- Felix


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

2018-11-05 Thread Felix Fietkau
On 2018-10-29 22:16, Lorenzo Bianconi wrote:
> Use mt76x02_mac_wcid_setup and mt76x02_mac_shared_key_setup for
> shared keys and wcid table initialization and remove duplicated
> code
> 
> Signed-off-by: Lorenzo Bianconi 
Applied, thanks.

- Felix


Re: [PATCH] mt76x2u: init: remove not useful configuration

2018-11-05 Thread Felix Fietkau
On 2018-10-29 15:12, Lorenzo Bianconi wrote:
> Remove MT_TSO_CTRL and MT_HEADER_TRANS_CTRL_REG initialization since
> it is already done in mt76_write_mac_initvals routine
> 
> Signed-off-by: Lorenzo Bianconi 
Applied, thanks.

- Felix


Re: [PATCH] mt76x0: init: use mt76x02_mac_shared_key_setup in mt76x0_init_hardware

2018-11-05 Thread Felix Fietkau
On 2018-10-28 23:54, Lorenzo Bianconi wrote:
> Use mt76x02_mac_shared_key_setup utility routine for shared key
> initialization and remove duplicated code
> 
> Signed-off-by: Lorenzo Bianconi 
Applied, thanks.

- Felix


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

2018-11-05 Thread Felix Fietkau
On 2018-10-29 01:36, Lorenzo Bianconi wrote:
> Fix wrong mt76x0 hw key table initialization in AP mode.
> Remove duplicated code.
> 
> This patchset is based on top of 'mt76x0: init: use
> mt76x02_mac_shared_key_setup in mt76x0_init_hardware'
> https://patchwork.kernel.org/patch/10658721/
Applied, thanks.

- Felix


Re: [PATCH 0/4] mt76: mcu api clenups

2018-11-05 Thread Felix Fietkau
On 2018-10-26 14:00, Stanislaw Gruszka wrote:
> Simplify mcu api and wait for response for mcu commands the same
> as vendor driver.
> 
> This is on top of:
> [PATCH] mt76x0: use band parameter for LC calibration
> 
> Stanislaw Gruszka (4):
>   mt76: remove mcu_msg_alloc
>   mt76: remove wait argument from mt76x02_mcu_calibrate
>   mt76: remove wait argument from mt76x02_mcu_function_select
>   mt76: remove wait argument from mt76x02_mcu_set_radio_state
Applied patches 1,3,4.

Thanks,

- Felix


Re: [PATCH] mt76x0: phy: use mt76_poll_msec in mt76x0_phy_temp_sensor

2018-11-05 Thread Felix Fietkau
On 2018-10-27 21:06, Lorenzo Bianconi wrote:
> Use mt76_poll_msec utility routine for CORE_R34 register polling
> instead of mt76_poll in order to allow the hw to complete requested
> calibration since on slow devices (e.g. mt7620 based boards) calibration
> takes longer than 2ms
> 
> Fixes: 66a34c66e0cb ("mt76x0: phy: add phy/vco temperature compensation")
> Signed-off-by: Lorenzo Bianconi 
Applied, thanks.

- Felix


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

2018-11-05 Thread Felix Fietkau
On 2018-11-05 15:58, Kalle Valo wrote:
> Stanislaw Gruszka  writes:
> 
>> On Thu, Oct 25, 2018 at 06:18:33PM +0200, Stanislaw Gruszka wrote:
>>> We use always 1 as band parameter for MCU_CAL_LC, this break 2GHz,
>>> we should use 0 for this band instead.
>>> 
>>> Patch fixes problems happened sometimes when try to associate with 2GHz
>>> AP and manifest by errors like below:
>>> 
>>> [14680.920823] wlan0: authenticate with 18:31:bf:c0:51:b0
>>> [14681.109506] wlan0: send auth to 18:31:bf:c0:51:b0 (try 1/3)
>>> [14681.310454] wlan0: send auth to 18:31:bf:c0:51:b0 (try 2/3)
>>> [14681.518469] wlan0: send auth to 18:31:bf:c0:51:b0 (try 3/3)
>>> [14681.726499] wlan0: authentication with 18:31:bf:c0:51:b0 timed out
>>> 
>>> Fixes: 9aec146d0f6b ("mt76x0: pci: introduce mt76x0_phy_calirate routine")
>>> Signed-off-by: Stanislaw Gruszka 
>>> ---
>>> This is for 4.20.
>>
>> Actually it is not needed for 4.20, bacause the new calibrate code is
>> not use for USB in 4.20. It start to be used since:
>>
>> commit e868a944c55b1f42303ab2941dc1aaada9a3570c
>> Author: Lorenzo Bianconi 
>> Date:   Mon Oct 15 14:18:05 2018 +0200
>>
>> mt76x0: phy: unify calibration between mt76x0u and mt76x0e
> 
> So what should happen to this patch? Will Felix take it?
Yes, I will take it.

- Felix


Re: [PATCH 2/4] mt76: remove wait argument from mt76x02_mcu_calibrate

2018-11-02 Thread Felix Fietkau
On 2018-11-02 13:56, Stanislaw Gruszka wrote:
> On Thu, Nov 01, 2018 at 06:29:01PM +0100, Felix Fietkau wrote:
>> On 2018-10-26 14:00, Stanislaw Gruszka wrote:
>> > We always wait for CMD_CALIBRATION_OP mcu message, but wait argument is 
>> > used
>> > for do additioanl MT_MCU_COM_REG0 register operations, which are needed
>> > for MMIO devices and we can use mt76_is_mmio() check instead of wait 
>> > argument.
>> > 
>> > Signed-off-by: Stanislaw Gruszka 
>> With this commit, I hit the WARN_ON on polling the MT_MCU_COM_REG0
>> register on mt76x0e. It seems to me that this register polling should be
>> moved out of mt76x02 and into a mt76x2 wrapper function.
> 
> I think it would be better to just do mt76x2e check like this:
> 
> bool is_mt76x2e = mt76_is_mmio(dev) && is_mt76x2(dev);
> 
> if (is_mt76x2e)
> mt76_rmw(dev, MT_MCU_COM_REG0, BIT(31), 0);
> 
> Then we will not have sparate calibration functions for mt76x2e and
> mt76x2u, so code could be easier shared between those.
My suggestion would have been making a wrapper function that checks for
mt76_is_mmio(dev) and gets put into mt76x2-common. What you're proposing
is fine with me as well, I guess it's a matter of preference.

- Felix


Re: [PATCH 2/4] mt76: remove wait argument from mt76x02_mcu_calibrate

2018-11-01 Thread Felix Fietkau
On 2018-10-26 14:00, Stanislaw Gruszka wrote:
> We always wait for CMD_CALIBRATION_OP mcu message, but wait argument is used
> for do additioanl MT_MCU_COM_REG0 register operations, which are needed
> for MMIO devices and we can use mt76_is_mmio() check instead of wait argument.
> 
> Signed-off-by: Stanislaw Gruszka 
With this commit, I hit the WARN_ON on polling the MT_MCU_COM_REG0
register on mt76x0e. It seems to me that this register polling should be
moved out of mt76x02 and into a mt76x2 wrapper function.

- Felix


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

2018-11-01 Thread Felix Fietkau
On 2018-10-31 08:32, Stanislaw Gruszka wrote:
> MT_BBP(AGC, 8) register has values depend on band in
> mt76x0_bbp_switch_tab, so we should not overwrite other fields
> than MT_BBP_AGC_GAIN when setting gain.
> 
> This can fix performance issues when connecting to 2.4GHz AP.
> 
> Fixes: 4636a2544c3b ("mt76x0: phy: align channel gain logic to mt76x2 one")
> Signed-off-by: Stanislaw Gruszka 
Applied, thanks.

- Felix


[PATCH v2 4/4] mt76: add support for reporting tx status with skb

2018-11-01 Thread Felix Fietkau
MT76x2/MT76x0 has somewhat unreliable tx status reporting, and for that
reason the driver currently does not report per-skb tx ack status at all.
This breaks things like client idle polling, which relies on the tx ack
status of a transmitted nullfunc frame.

This patch adds code to report skb-attached tx status if requested by
mac80211 or the rate control module. Since tx status is polled from a
simple FIFO register, the code needs to account for the possibility of
tx status events getting lost.

The code keeps a list of skbs for which tx status is required and passes
them to mac80211 once tx status has been filled in and the DMA queue is
done with it.
If a tx status event is not received after one second, the status rates
are cleared, and a succesful ACK is indicated to avoid spurious disassoc
during assoc or client polling.

Signed-off-by: Felix Fietkau 
---
v2: add support for per-packet tx status handling of packets with sta=NULL

 drivers/net/wireless/mediatek/mt76/dma.c  |   1 +
 drivers/net/wireless/mediatek/mt76/mac80211.c |   3 +
 drivers/net/wireless/mediatek/mt76/mt76.h |  48 
 drivers/net/wireless/mediatek/mt76/mt76x02.h  |   1 -
 .../net/wireless/mediatek/mt76/mt76x02_mac.c  |  74 ++--
 .../net/wireless/mediatek/mt76/mt76x02_mac.h  |  19 ---
 .../net/wireless/mediatek/mt76/mt76x02_txrx.c |  25 ++--
 .../wireless/mediatek/mt76/mt76x02_usb_core.c |  42 +++
 .../net/wireless/mediatek/mt76/mt76x02_util.c |   1 +
 drivers/net/wireless/mediatek/mt76/tx.c   | 111 ++
 drivers/net/wireless/mediatek/mt76/usb.c  |   1 +
 11 files changed, 231 insertions(+), 95 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/dma.c 
b/drivers/net/wireless/mediatek/mt76/dma.c
index f7fbd7016403..2d7bd26875c6 100644
--- a/drivers/net/wireless/mediatek/mt76/dma.c
+++ b/drivers/net/wireless/mediatek/mt76/dma.c
@@ -258,6 +258,7 @@ int mt76_dma_tx_queue_skb(struct mt76_dev *dev, struct 
mt76_queue *q,
return -ENOMEM;
}
 
+   skb->prev = skb->next = NULL;
dma_sync_single_for_cpu(dev->dev, t->dma_addr, sizeof(t->txwi),
DMA_TO_DEVICE);
ret = dev->drv->tx_prepare_skb(dev, >txwi, skb, q, wcid, sta,
diff --git a/drivers/net/wireless/mediatek/mt76/mac80211.c 
b/drivers/net/wireless/mediatek/mt76/mac80211.c
index 2a699e8b79bf..85e05a825b5d 100644
--- a/drivers/net/wireless/mediatek/mt76/mac80211.c
+++ b/drivers/net/wireless/mediatek/mt76/mac80211.c
@@ -285,6 +285,7 @@ mt76_alloc_device(unsigned int size, const struct 
ieee80211_ops *ops)
spin_lock_init(>cc_lock);
mutex_init(>mutex);
init_waitqueue_head(>tx_wait);
+   skb_queue_head_init(>status_list);
 
return dev;
 }
@@ -326,6 +327,7 @@ int mt76_register_device(struct mt76_dev *dev, bool vht,
ieee80211_hw_set(hw, TX_FRAG_LIST);
ieee80211_hw_set(hw, MFP_CAPABLE);
ieee80211_hw_set(hw, AP_LINK_PS);
+   ieee80211_hw_set(hw, REPORTS_TX_ACK_STATUS);
 
wiphy->flags |= WIPHY_FLAG_IBSS_RSN;
 
@@ -357,6 +359,7 @@ void mt76_unregister_device(struct mt76_dev *dev)
 {
struct ieee80211_hw *hw = dev->hw;
 
+   mt76_tx_status_flush(dev, NULL);
ieee80211_unregister_hw(hw);
mt76_tx_free(dev);
 }
diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h 
b/drivers/net/wireless/mediatek/mt76/mt76.h
index 53ddc4fa5884..94ab00b549af 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76.h
@@ -195,6 +195,8 @@ struct mt76_wcid {
u8 tx_rate_nss;
s8 max_txpwr_adj;
bool sw_iv;
+
+   u8 packet_id;
 };
 
 struct mt76_txq {
@@ -233,6 +235,22 @@ struct mt76_rx_tid {
struct sk_buff *reorder_buf[];
 };
 
+#define MT_TX_CB_DMA_DONE  BIT(0)
+#define MT_TX_CB_TXS_DONE  BIT(1)
+#define MT_TX_CB_TXS_FAILEDBIT(2)
+
+#define MT_PACKET_ID_MASK  GENMASK(7, 0)
+#define MT_PACKET_ID_NO_ACKMT_PACKET_ID_MASK
+
+#define MT_TX_STATUS_SKB_TIMEOUT   HZ
+
+struct mt76_tx_cb {
+   unsigned long jiffies;
+   u8 wcid;
+   u8 pktid;
+   u8 flags;
+};
+
 enum {
MT76_STATE_INITIALIZED,
MT76_STATE_RUNNING,
@@ -400,6 +418,7 @@ struct mt76_dev {
const struct mt76_queue_ops *queue_ops;
 
wait_queue_head_t tx_wait;
+   struct sk_buff_head status_list;
 
unsigned long wcid_mask[MT76_N_WCIDS / BITS_PER_LONG];
 
@@ -594,6 +613,13 @@ wcid_to_sta(struct mt76_wcid *wcid)
return container_of(ptr, struct ieee80211_sta, drv_priv);
 }
 
+static inline struct mt76_tx_cb *mt76_tx_skb_cb(struct sk_buff *skb)
+{
+   BUILD_BUG_ON(sizeof(struct mt76_tx_cb) >
+sizeof(IEEE80211_SKB_CB(skb)->status.status_driver_data));
+   return ((void *) IEEE80211_SKB_CB(skb)->status.status_driver_data);
+}
+
 int mt76_dma_tx_q

[PATCH v2 3/4] mt76: mt76x02: only override control->sta on sw-encrypted tx

2018-11-01 Thread Felix Fietkau
control->sta is set to NULL early when encryption is turned on for the
station and info->control.hw_key is not set.
This code is missing a check for the 802.11 header protected flag, otherwise
it resets the station for other frames, e.g. client probing frames.

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

diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_txrx.c 
b/drivers/net/wireless/mediatek/mt76/mt76x02_txrx.c
index 7ec3f8f5f228..c008e08602f3 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_txrx.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_txrx.c
@@ -22,6 +22,7 @@
 void mt76x02_tx(struct ieee80211_hw *hw, struct ieee80211_tx_control *control,
struct sk_buff *skb)
 {
+   struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
struct mt76x02_dev *dev = hw->priv;
struct ieee80211_vif *vif = info->control.vif;
@@ -33,7 +34,8 @@ void mt76x02_tx(struct ieee80211_hw *hw, struct 
ieee80211_tx_control *control,
msta = (struct mt76x02_sta *)control->sta->drv_priv;
wcid = >wcid;
/* sw encrypted frames */
-   if (!info->control.hw_key && wcid->hw_key_idx != 0xff)
+   if (!info->control.hw_key && wcid->hw_key_idx != 0xff &&
+   ieee80211_has_protected(hdr->frame_control))
control->sta = NULL;
}
 
-- 
2.17.0



[PATCH v2 1/4] mt76: clean up more unused EXPORT_SYMBOLs

2018-11-01 Thread Felix Fietkau
Make functions static where possible

Signed-off-by: Felix Fietkau 
---
 drivers/net/wireless/mediatek/mt76/mt76x02_mac.c  | 9 +
 drivers/net/wireless/mediatek/mt76/mt76x02_mac.h  | 1 -
 drivers/net/wireless/mediatek/mt76/mt76x02_util.c | 1 -
 3 files changed, 1 insertion(+), 10 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c 
b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
index 4fb9f095ffec..34fc9f2eb51f 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
@@ -128,7 +128,6 @@ void mt76x02_mac_wcid_set_drop(struct mt76x02_dev *dev, u8 
idx, bool drop)
if ((val & bit) != (bit * drop))
mt76_wr(dev, MT_WCID_DROP(idx), (val & ~bit) | (bit * drop));
 }
-EXPORT_SYMBOL_GPL(mt76x02_mac_wcid_set_drop);
 
 void mt76x02_txq_init(struct mt76x02_dev *dev, struct ieee80211_txq *txq)
 {
@@ -220,7 +219,6 @@ void mt76x02_mac_set_short_preamble(struct mt76x02_dev 
*dev, bool enable)
else
mt76_clear(dev, MT_AUTO_RSP_CFG, MT_AUTO_RSP_PREAMB_SHORT);
 }
-EXPORT_SYMBOL_GPL(mt76x02_mac_set_short_preamble);
 
 bool mt76x02_mac_load_tx_status(struct mt76x02_dev *dev,
struct mt76x02_tx_status *stat)
@@ -491,7 +489,7 @@ void mt76x02_send_tx_status(struct mt76x02_dev *dev,
rcu_read_unlock();
 }
 
-int
+static int
 mt76x02_mac_process_rate(struct mt76_rx_status *status, u16 rate)
 {
u8 idx = FIELD_GET(MT_RXWI_RATE_INDEX, rate);
@@ -557,7 +555,6 @@ mt76x02_mac_process_rate(struct mt76_rx_status *status, u16 
rate)
 
return 0;
 }
-EXPORT_SYMBOL_GPL(mt76x02_mac_process_rate);
 
 void mt76x02_mac_setaddr(struct mt76x02_dev *dev, u8 *addr)
 {
@@ -823,7 +820,6 @@ void mt76x02_mac_work(struct work_struct *work)
ieee80211_queue_delayed_work(mt76_hw(dev), >mac_work,
 MT_CALIBRATE_INTERVAL);
 }
-EXPORT_SYMBOL_GPL(mt76x02_mac_work);
 
 void mt76x02_mac_set_bssid(struct mt76x02_dev *dev, u8 idx, const u8 *addr)
 {
@@ -832,7 +828,6 @@ void mt76x02_mac_set_bssid(struct mt76x02_dev *dev, u8 idx, 
const u8 *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)
@@ -914,7 +909,6 @@ int mt76x02_mac_set_beacon(struct mt76x02_dev *dev, u8 
vif_idx,
   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)
@@ -946,4 +940,3 @@ void mt76x02_mac_set_beacon_enable(struct mt76x02_dev *dev,
else
mt76x02_irq_disable(dev, MT_INT_PRE_TBTT | MT_INT_TBTT);
 }
-EXPORT_SYMBOL_GPL(mt76x02_mac_set_beacon_enable);
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.h 
b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.h
index f65157600779..e2c47ca18d85 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.h
@@ -216,7 +216,6 @@ void mt76x02_send_tx_status(struct mt76x02_dev *dev,
struct mt76x02_tx_status *stat, u8 *update);
 int mt76x02_mac_process_rx(struct mt76x02_dev *dev, struct sk_buff *skb,
   void *rxi);
-int mt76x02_mac_process_rate(struct mt76_rx_status *status, u16 rate);
 void mt76x02_mac_set_tx_protection(struct mt76x02_dev *dev, u32 val);
 void mt76x02_mac_setaddr(struct mt76x02_dev *dev, u8 *addr);
 void mt76x02_mac_write_txwi(struct mt76x02_dev *dev, struct mt76x02_txwi *txwi,
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c 
b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
index 9f083008dbd4..c0f923942edc 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
@@ -606,7 +606,6 @@ const u16 mt76x02_beacon_offsets[16] = {
0xc000,
0xc000,
 };
-EXPORT_SYMBOL_GPL(mt76x02_beacon_offsets);
 
 static void mt76x02_set_beacon_offsets(struct mt76x02_dev *dev)
 {
-- 
2.17.0



[PATCH v2 2/4] mt76: mt76x02: skip station tx status for non-sta wcid entries

2018-11-01 Thread Felix Fietkau
Fixes a crash that could occur if a frame is sent to a station, but the
station's wcid was not used (e.g. for software encrypted mgmt tx)

Signed-off-by: Felix Fietkau 
---
 drivers/net/wireless/mediatek/mt76/mt76x02_mac.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c 
b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
index 34fc9f2eb51f..ad8df680c6a5 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
@@ -450,7 +450,7 @@ void mt76x02_send_tx_status(struct mt76x02_dev *dev,
if (stat->wcid < ARRAY_SIZE(dev->mt76.wcid))
wcid = rcu_dereference(dev->mt76.wcid[stat->wcid]);
 
-   if (wcid) {
+   if (wcid && wcid->sta) {
void *priv;
 
priv = msta = container_of(wcid, struct mt76x02_sta, wcid);
-- 
2.17.0



Re: [PATCH v2] mt76x0: run calibration after scanning

2018-10-31 Thread Felix Fietkau
On 2018-10-31 14:11, Stanislaw Gruszka wrote:
> If we are associated and scanning is performed, sw_scan_complete callback
> is done after we get back to operating channel, so we do not perform
> queue cal work. Fix this queue cal work from sw_scan_complete().
> 
> We have to restore gain in MT_BBP(AGC, 8) register after scanning, as
> it was multiple times modified by channel switch code. So queue cal work
> without  any delay and reset dev->cal.low_gain to assure calibration
> code will AGC gain value.
> 
> Note patch was not tested on mt76x2, but should work and be needed
> fix as well.
> 
> Fixes: bbd10586f0df ("mt76x0: phy: do not run calibration during channel 
> switch")
> Signed-off-by: Stanislaw Gruszka 
> ---
> v1 -> v2:
> only queue cal work with 0 delay an reset dev->cal.low_gain 
> 
>  drivers/net/wireless/mediatek/mt76/mt76x02_util.c | 6 ++
>  1 file changed, 6 insertions(+)
> 
> diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c 
> b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
> index 9f083008dbd4..747fd2c9ec45 100644
> --- a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
> +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
> @@ -553,6 +553,12 @@ void mt76x02_sw_scan_complete(struct ieee80211_hw *hw,
>   clear_bit(MT76_SCANNING, >mt76.state);
>   if (mt76_is_mmio(dev))
>   tasklet_enable(>pre_tbtt_tasklet);
> +
> + if (vif->bss_conf.assoc) {
> + /* Restore AGC gain and resume calibration after scanning. */
> + dev->cal.low_gain = -1;
> + ieee80211_queue_delayed_work(hw, >cal_work, 0);
> + }
I think checking vif->bss_conf.assoc here is not enough, since we might
be using multiple interfaces (e.g. AP+STA)

- Felix


Re: [PATCH 4/4] mt76: add support for reporting tx status with skb

2018-10-27 Thread Felix Fietkau
On 2018-10-27 17:04, Stanislaw Gruszka wrote:
> On Thu, Oct 25, 2018 at 06:55:41PM +0200, Felix Fietkau wrote:
>> +struct mt76_tx_cb *cb = mt76_tx_skb_cb(skb);
>> +u8 done = MT_TX_CB_DMA_DONE | MT_TX_CB_TXS_DONE;
> can be "const u8 done = ..."
I think the compiler is smart enough to figure that one out.

>> +mt76_tx_status_skb_add(struct mt76_dev *dev, struct mt76_wcid *wcid,
>> +   struct sk_buff *skb)
>> +{
>> +struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
>> +struct mt76_tx_cb *cb = mt76_tx_skb_cb(skb);
>> +int pid;
>> +
>> +if (!wcid || !wcid->sta)
>> +return 0;
> 
> Due to !wcid->sta check I can not associate with AP on MT7610U,
> because we use pid = 0 for assoc frames which are marked
> IEEE80211_TX_CTL_REQ_TX_STATUS .
> After removing it and leave just !wcid check, things work ok.
Thanks, will send a v2.

- Felix


[PATCH 1/4] mt76: clean up more unused EXPORT_SYMBOLs

2018-10-25 Thread Felix Fietkau
Make functions static where possible

Signed-off-by: Felix Fietkau 
---
 drivers/net/wireless/mediatek/mt76/mt76x02_mac.c  | 9 +
 drivers/net/wireless/mediatek/mt76/mt76x02_mac.h  | 1 -
 drivers/net/wireless/mediatek/mt76/mt76x02_util.c | 1 -
 3 files changed, 1 insertion(+), 10 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c 
b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
index 4fb9f095ffec..34fc9f2eb51f 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
@@ -128,7 +128,6 @@ void mt76x02_mac_wcid_set_drop(struct mt76x02_dev *dev, u8 
idx, bool drop)
if ((val & bit) != (bit * drop))
mt76_wr(dev, MT_WCID_DROP(idx), (val & ~bit) | (bit * drop));
 }
-EXPORT_SYMBOL_GPL(mt76x02_mac_wcid_set_drop);
 
 void mt76x02_txq_init(struct mt76x02_dev *dev, struct ieee80211_txq *txq)
 {
@@ -220,7 +219,6 @@ void mt76x02_mac_set_short_preamble(struct mt76x02_dev 
*dev, bool enable)
else
mt76_clear(dev, MT_AUTO_RSP_CFG, MT_AUTO_RSP_PREAMB_SHORT);
 }
-EXPORT_SYMBOL_GPL(mt76x02_mac_set_short_preamble);
 
 bool mt76x02_mac_load_tx_status(struct mt76x02_dev *dev,
struct mt76x02_tx_status *stat)
@@ -491,7 +489,7 @@ void mt76x02_send_tx_status(struct mt76x02_dev *dev,
rcu_read_unlock();
 }
 
-int
+static int
 mt76x02_mac_process_rate(struct mt76_rx_status *status, u16 rate)
 {
u8 idx = FIELD_GET(MT_RXWI_RATE_INDEX, rate);
@@ -557,7 +555,6 @@ mt76x02_mac_process_rate(struct mt76_rx_status *status, u16 
rate)
 
return 0;
 }
-EXPORT_SYMBOL_GPL(mt76x02_mac_process_rate);
 
 void mt76x02_mac_setaddr(struct mt76x02_dev *dev, u8 *addr)
 {
@@ -823,7 +820,6 @@ void mt76x02_mac_work(struct work_struct *work)
ieee80211_queue_delayed_work(mt76_hw(dev), >mac_work,
 MT_CALIBRATE_INTERVAL);
 }
-EXPORT_SYMBOL_GPL(mt76x02_mac_work);
 
 void mt76x02_mac_set_bssid(struct mt76x02_dev *dev, u8 idx, const u8 *addr)
 {
@@ -832,7 +828,6 @@ void mt76x02_mac_set_bssid(struct mt76x02_dev *dev, u8 idx, 
const u8 *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)
@@ -914,7 +909,6 @@ int mt76x02_mac_set_beacon(struct mt76x02_dev *dev, u8 
vif_idx,
   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)
@@ -946,4 +940,3 @@ void mt76x02_mac_set_beacon_enable(struct mt76x02_dev *dev,
else
mt76x02_irq_disable(dev, MT_INT_PRE_TBTT | MT_INT_TBTT);
 }
-EXPORT_SYMBOL_GPL(mt76x02_mac_set_beacon_enable);
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.h 
b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.h
index f65157600779..e2c47ca18d85 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.h
@@ -216,7 +216,6 @@ void mt76x02_send_tx_status(struct mt76x02_dev *dev,
struct mt76x02_tx_status *stat, u8 *update);
 int mt76x02_mac_process_rx(struct mt76x02_dev *dev, struct sk_buff *skb,
   void *rxi);
-int mt76x02_mac_process_rate(struct mt76_rx_status *status, u16 rate);
 void mt76x02_mac_set_tx_protection(struct mt76x02_dev *dev, u32 val);
 void mt76x02_mac_setaddr(struct mt76x02_dev *dev, u8 *addr);
 void mt76x02_mac_write_txwi(struct mt76x02_dev *dev, struct mt76x02_txwi *txwi,
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c 
b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
index 9f083008dbd4..c0f923942edc 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
@@ -606,7 +606,6 @@ const u16 mt76x02_beacon_offsets[16] = {
0xc000,
0xc000,
 };
-EXPORT_SYMBOL_GPL(mt76x02_beacon_offsets);
 
 static void mt76x02_set_beacon_offsets(struct mt76x02_dev *dev)
 {
-- 
2.17.0



[PATCH 4/4] mt76: add support for reporting tx status with skb

2018-10-25 Thread Felix Fietkau
MT76x2/MT76x0 has somewhat unreliable tx status reporting, and for that
reason the driver currently does not report per-skb tx ack status at all.
This breaks things like client idle polling, which relies on the tx ack
status of a transmitted nullfunc frame.

This patch adds code to report skb-attached tx status if requested by
mac80211 or the rate control module. Since tx status is polled from a
simple FIFO register, the code needs to account for the possibility of
tx status events getting lost.

The code keeps a list of skbs for which tx status is required and passes
them to mac80211 once tx status has been filled in and the DMA queue is
done with it.
If a tx status event is not received after one second, the status rates
are cleared, and a succesful ACK is indicated to avoid spurious disassoc
during assoc or client polling.

Signed-off-by: Felix Fietkau 
---
 drivers/net/wireless/mediatek/mt76/dma.c  |   1 +
 drivers/net/wireless/mediatek/mt76/mac80211.c |   3 +
 drivers/net/wireless/mediatek/mt76/mt76.h |  48 
 drivers/net/wireless/mediatek/mt76/mt76x02.h  |   1 -
 .../net/wireless/mediatek/mt76/mt76x02_mac.c  |  71 +--
 .../net/wireless/mediatek/mt76/mt76x02_mac.h  |  19 ---
 .../net/wireless/mediatek/mt76/mt76x02_txrx.c |  25 ++--
 .../wireless/mediatek/mt76/mt76x02_usb_core.c |  42 +++
 .../net/wireless/mediatek/mt76/mt76x02_util.c |   1 +
 drivers/net/wireless/mediatek/mt76/tx.c   | 111 ++
 drivers/net/wireless/mediatek/mt76/usb.c  |   1 +
 11 files changed, 228 insertions(+), 95 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/dma.c 
b/drivers/net/wireless/mediatek/mt76/dma.c
index f7fbd7016403..2d7bd26875c6 100644
--- a/drivers/net/wireless/mediatek/mt76/dma.c
+++ b/drivers/net/wireless/mediatek/mt76/dma.c
@@ -258,6 +258,7 @@ int mt76_dma_tx_queue_skb(struct mt76_dev *dev, struct 
mt76_queue *q,
return -ENOMEM;
}
 
+   skb->prev = skb->next = NULL;
dma_sync_single_for_cpu(dev->dev, t->dma_addr, sizeof(t->txwi),
DMA_TO_DEVICE);
ret = dev->drv->tx_prepare_skb(dev, >txwi, skb, q, wcid, sta,
diff --git a/drivers/net/wireless/mediatek/mt76/mac80211.c 
b/drivers/net/wireless/mediatek/mt76/mac80211.c
index 2a699e8b79bf..85e05a825b5d 100644
--- a/drivers/net/wireless/mediatek/mt76/mac80211.c
+++ b/drivers/net/wireless/mediatek/mt76/mac80211.c
@@ -285,6 +285,7 @@ mt76_alloc_device(unsigned int size, const struct 
ieee80211_ops *ops)
spin_lock_init(>cc_lock);
mutex_init(>mutex);
init_waitqueue_head(>tx_wait);
+   skb_queue_head_init(>status_list);
 
return dev;
 }
@@ -326,6 +327,7 @@ int mt76_register_device(struct mt76_dev *dev, bool vht,
ieee80211_hw_set(hw, TX_FRAG_LIST);
ieee80211_hw_set(hw, MFP_CAPABLE);
ieee80211_hw_set(hw, AP_LINK_PS);
+   ieee80211_hw_set(hw, REPORTS_TX_ACK_STATUS);
 
wiphy->flags |= WIPHY_FLAG_IBSS_RSN;
 
@@ -357,6 +359,7 @@ void mt76_unregister_device(struct mt76_dev *dev)
 {
struct ieee80211_hw *hw = dev->hw;
 
+   mt76_tx_status_flush(dev, NULL);
ieee80211_unregister_hw(hw);
mt76_tx_free(dev);
 }
diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h 
b/drivers/net/wireless/mediatek/mt76/mt76.h
index 53ddc4fa5884..94ab00b549af 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76.h
@@ -195,6 +195,8 @@ struct mt76_wcid {
u8 tx_rate_nss;
s8 max_txpwr_adj;
bool sw_iv;
+
+   u8 packet_id;
 };
 
 struct mt76_txq {
@@ -233,6 +235,22 @@ struct mt76_rx_tid {
struct sk_buff *reorder_buf[];
 };
 
+#define MT_TX_CB_DMA_DONE  BIT(0)
+#define MT_TX_CB_TXS_DONE  BIT(1)
+#define MT_TX_CB_TXS_FAILEDBIT(2)
+
+#define MT_PACKET_ID_MASK  GENMASK(7, 0)
+#define MT_PACKET_ID_NO_ACKMT_PACKET_ID_MASK
+
+#define MT_TX_STATUS_SKB_TIMEOUT   HZ
+
+struct mt76_tx_cb {
+   unsigned long jiffies;
+   u8 wcid;
+   u8 pktid;
+   u8 flags;
+};
+
 enum {
MT76_STATE_INITIALIZED,
MT76_STATE_RUNNING,
@@ -400,6 +418,7 @@ struct mt76_dev {
const struct mt76_queue_ops *queue_ops;
 
wait_queue_head_t tx_wait;
+   struct sk_buff_head status_list;
 
unsigned long wcid_mask[MT76_N_WCIDS / BITS_PER_LONG];
 
@@ -594,6 +613,13 @@ wcid_to_sta(struct mt76_wcid *wcid)
return container_of(ptr, struct ieee80211_sta, drv_priv);
 }
 
+static inline struct mt76_tx_cb *mt76_tx_skb_cb(struct sk_buff *skb)
+{
+   BUILD_BUG_ON(sizeof(struct mt76_tx_cb) >
+sizeof(IEEE80211_SKB_CB(skb)->status.status_driver_data));
+   return ((void *) IEEE80211_SKB_CB(skb)->status.status_driver_data);
+}
+
 int mt76_dma_tx_queue_skb(struct mt76_dev *dev, struct mt76_queue *q,
  struct sk_buff *skb, struc

[PATCH 2/4] mt76: mt76x02: skip station tx status for non-sta wcid entries

2018-10-25 Thread Felix Fietkau
Fixes a crash that could occur if a frame is sent to a station, but the
station's wcid was not used (e.g. for software encrypted mgmt tx)

Signed-off-by: Felix Fietkau 
---
 drivers/net/wireless/mediatek/mt76/mt76x02_mac.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c 
b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
index 34fc9f2eb51f..ad8df680c6a5 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
@@ -450,7 +450,7 @@ void mt76x02_send_tx_status(struct mt76x02_dev *dev,
if (stat->wcid < ARRAY_SIZE(dev->mt76.wcid))
wcid = rcu_dereference(dev->mt76.wcid[stat->wcid]);
 
-   if (wcid) {
+   if (wcid && wcid->sta) {
void *priv;
 
priv = msta = container_of(wcid, struct mt76x02_sta, wcid);
-- 
2.17.0



[PATCH 3/4] mt76: mt76x02: only override control->sta on sw-encrypted tx

2018-10-25 Thread Felix Fietkau
control->sta is set to NULL early when encryption is turned on for the
station and info->control.hw_key is not set.
This code is missing a check for the 802.11 header protected flag, otherwise
it resets the station for other frames, e.g. client probing frames.

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

diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_txrx.c 
b/drivers/net/wireless/mediatek/mt76/mt76x02_txrx.c
index 7ec3f8f5f228..c008e08602f3 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_txrx.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_txrx.c
@@ -22,6 +22,7 @@
 void mt76x02_tx(struct ieee80211_hw *hw, struct ieee80211_tx_control *control,
struct sk_buff *skb)
 {
+   struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
struct mt76x02_dev *dev = hw->priv;
struct ieee80211_vif *vif = info->control.vif;
@@ -33,7 +34,8 @@ void mt76x02_tx(struct ieee80211_hw *hw, struct 
ieee80211_tx_control *control,
msta = (struct mt76x02_sta *)control->sta->drv_priv;
wcid = >wcid;
/* sw encrypted frames */
-   if (!info->control.hw_key && wcid->hw_key_idx != 0xff)
+   if (!info->control.hw_key && wcid->hw_key_idx != 0xff &&
+   ieee80211_has_protected(hdr->frame_control))
control->sta = NULL;
}
 
-- 
2.17.0



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

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

- Felix


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

2018-10-23 Thread Felix Fietkau
On 2018-10-20 12:40, Lorenzo Bianconi wrote:
> Unify drv_bss_info_changed mac80211 callback between mt76x0 and mt76x2.
> Move ack timeout and protection utility routines in mt76x02-lib module.
> 
> This series is based on top of 'enable AP support in mt76x0e driver' one:
> https://patchwork.kernel.org/cover/10650335/
Applied, thanks.

- Felix


Re: [PATCH] mt76: move mt76x02_mac_set_short_preamble in mt76x02_mac.c

2018-10-23 Thread Felix Fietkau
On 2018-10-19 14:56, Lorenzo Bianconi wrote:
> Move mt76x02_mac_set_short_preamble routine in mt76x02-lib module
> since it is shared between mt76x0 and mt76x2 drivers
> 
> Signed-off-by: Lorenzo Bianconi 
Applied, thanks.

- Felix


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

2018-10-23 Thread Felix Fietkau
On 2018-10-20 12:13, Lorenzo Bianconi wrote:
> Add beacon transmission/management support to mt76x0 driver.
> Add missing mac80211 callbacks to mt76x0e driver in order
> to enable AP support
Applied, thanks.

- Felix


Re: [PATCH] mt76x0: pci: add missing MODULE_FIRMWARE macro

2018-10-19 Thread Felix Fietkau
On 2018-10-19 00:57, Lorenzo Bianconi wrote:
> Add missing firmware declaration for mt76x0e driver
> 
> Signed-off-by: Lorenzo Bianconi 
Applied, thanks.

- Felix


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

2018-10-19 Thread Felix Fietkau
On 2018-10-19 11:40, Lorenzo Bianconi wrote:
> Unify firmware version used on mt76x0e and mt76x0u drivers.
> Fallback to mt7610u fw if mt7610e one is not available
> 
> Signed-off-by: Lorenzo Bianconi 
Applied, thanks.

- Felix


Re: [PATCH] mt76x0: mac: remove mt76x0_mac_set_ampdu_factor

2018-10-19 Thread Felix Fietkau
On 2018-10-19 12:47, Lorenzo Bianconi wrote:
> Remove no longer used mt76x0_mac_set_ampdu_factor routine
> 
> Signed-off-by: Lorenzo Bianconi 
Applied, thanks.

- Felix


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

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

- Felix


Re: [PATCH 1/2] mt76: mt76x0: reduce duplication in setting rf bandwidth parameters

2018-10-19 Thread Felix Fietkau
On 2018-10-19 10:17, Stanislaw Gruszka wrote:
> On Thu, Oct 18, 2018 at 04:16:44PM +0200, Felix Fietkau wrote:
>> Remove initval table with duplicated registers and driver specific flags
>> in favor of a function that sets the registers directly
> 
> There are few problems with this patch: MT_RF(7, 77) is missing and
> band is not taken directly from chandef but overwriteen in
> 'rf_band = mt76x0_frequency_plan[i].band' . But even after fixing that
> I can not make MT7610U associate with AP on 5GHz. So please drop this
> patch.
Will do, thanks.

- Felix


Re: [PATCH] mt76x0: init: simplify mt76x0_init_mac_registers

2018-10-18 Thread Felix Fietkau
On 2018-10-16 11:42, Lorenzo Bianconi wrote:
> Simplify mt76x0_init_mac_registers routine using mt76_set, mt76_clear
> and mt76_rmw utility routines
> 
> Signed-off-by: Lorenzo Bianconi 
Applied, thanks.

- Felix


Re: [PATCH v2] mt76x0: antenna select corrections

2018-10-18 Thread Felix Fietkau
On 2018-10-18 12:15, Stanislaw Gruszka wrote:
> Update mt76x0_phy_ant_select() to conform vendor driver, most notably
> add dual antenna mode support, read configuration from EEPROM and
> move ant select out of channel config to init phase. Plus small MT7630E
> quirk for MT_CMB_CTRL register which vendor driver dedicated to this
> chip do.
> 
> This make MT7630E workable with mt76x0e driver and do not cause any
> problems on MT7610U for me.
> 
> Signed-off-by: Stanislaw Gruszka 
> Acked-by: Lorenzo Bianconi 
Applied, thanks.

- Felix


Re: [PATCH] mt76: usb: fix static tracepoints

2018-10-18 Thread Felix Fietkau
On 2018-10-18 00:35, Lorenzo Bianconi wrote:
> Add submit_urb and rx_urb static tracepoints in mt76-usb module.
> Move trace_mac_txstat_fetch in mt76x02_mac_load_tx_status routine
> in order to be available to usb drivers. Moreover remove
> no longer used mt76x0/trace.{c,h}
> 
> Signed-off-by: Lorenzo Bianconi 
Applied, thanks.

- Felix


[PATCH 2/2] mt76: mt76x0: handle chip specific initval differences

2018-10-18 Thread Felix Fietkau
Some RF registers need different values for various chips.
For at least mt76x0_rf_central_tab registers, overwriting them later does
not work, as the wrong values can cause the entire system to hang on some
devices with MT7610E

Signed-off-by: Felix Fietkau 
---
 .../wireless/mediatek/mt76/mt76x0/mt76x0.h|  6 ++-
 .../net/wireless/mediatek/mt76/mt76x0/phy.c   | 47 ++-
 2 files changed, 49 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h 
b/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h
index 33475788bc26..989ed00c0b7a 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h
@@ -33,8 +33,10 @@
 
 static inline bool is_mt7610e(struct mt76x02_dev *dev)
 {
-   /* TODO */
-   return false;
+   if (!mt76_is_mmio(dev))
+   return false;
+
+   return mt76_chip(>mt76) == 0x7610;
 }
 
 static inline bool is_mt7630(struct mt76x02_dev *dev)
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/phy.c 
b/drivers/net/wireless/mediatek/mt76/mt76x0/phy.c
index 10041e673c31..d294325221f3 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x0/phy.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x0/phy.c
@@ -775,13 +775,56 @@ static void mt76x0_phy_calibration_work(struct 
work_struct *work)
 MT_CALIBRATE_INTERVAL);
 }
 
+static void mt76x0_rf_patch_reg_array(struct mt76x02_dev *dev,
+ const struct mt76_reg_pair *rp, int len)
+{
+   int i;
+
+   for (i = 0; i < len; i++) {
+   u32 reg = rp[i].reg;
+   u8 val = rp[i].value;
+
+   switch (reg) {
+   case MT_RF(0, 3):
+   if (mt76_is_mmio(dev)) {
+   if (is_mt7630(dev))
+   val = 0x70;
+   else
+   val = 0x63;
+   } else {
+   val = 0x73;
+   }
+   break;
+   case MT_RF(0, 21):
+   if (is_mt7610e(dev))
+   val = 0x10;
+   else
+   val = 0x12;
+   break;
+   case MT_RF(5, 2):
+   if (is_mt7630(dev))
+   val = 0x1d;
+   else if (is_mt7610e(dev))
+   val = 0x00;
+   else
+   val = 0x0c;
+   break;
+   default:
+   break;
+   }
+   mt76x0_rf_wr(dev, reg, val);
+   }
+}
+
 static void mt76x0_phy_rf_init(struct mt76x02_dev *dev)
 {
int i;
u8 val;
 
-   RF_RANDOM_WRITE(dev, mt76x0_rf_central_tab);
-   RF_RANDOM_WRITE(dev, mt76x0_rf_2g_channel_0_tab);
+   mt76x0_rf_patch_reg_array(dev, mt76x0_rf_central_tab,
+ ARRAY_SIZE(mt76x0_rf_central_tab));
+   mt76x0_rf_patch_reg_array(dev, mt76x0_rf_2g_channel_0_tab,
+ ARRAY_SIZE(mt76x0_rf_2g_channel_0_tab));
RF_RANDOM_WRITE(dev, mt76x0_rf_5g_channel_0_tab);
RF_RANDOM_WRITE(dev, mt76x0_rf_vga_channel_0_tab);
mt76x0_phy_rf_switch_band(dev, NULL);
-- 
2.17.0



[PATCH 1/2] mt76: mt76x0: reduce duplication in setting rf bandwidth parameters

2018-10-18 Thread Felix Fietkau
Remove initval table with duplicated registers and driver specific flags
in favor of a function that sets the registers directly

Signed-off-by: Felix Fietkau 
---
 .../mediatek/mt76/mt76x0/initvals_phy.h   | 45 
 .../net/wireless/mediatek/mt76/mt76x0/phy.c   | 73 +--
 2 files changed, 49 insertions(+), 69 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/initvals_phy.h 
b/drivers/net/wireless/mediatek/mt76/mt76x0/initvals_phy.h
index 56c6fa73daf5..755dd6749b65 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x0/initvals_phy.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76x0/initvals_phy.h
@@ -233,51 +233,6 @@ static const struct mt76_reg_pair 
mt76x0_rf_vga_channel_0_tab[] = {
{ MT_RF(7, 74), 0x00 },
 };
 
-static const struct mt76x0_rf_switch_item mt76x0_rf_bw_switch_tab[] = {
-   /* bank, regbw/band value */
-   { MT_RF(0, 17), RF_G_BAND | RF_BW_20,   0x00 },
-   { MT_RF(0, 17), RF_G_BAND | RF_BW_40,   0x00 },
-   { MT_RF(0, 17), RF_A_BAND | RF_BW_20,   0x00 },
-   { MT_RF(0, 17), RF_A_BAND | RF_BW_40,   0x00 },
-   { MT_RF(0, 17), RF_A_BAND | RF_BW_80,   0x00 },
-   { MT_RF(7,  6), RF_G_BAND | RF_BW_20,   0x40 },
-   { MT_RF(7,  6), RF_G_BAND | RF_BW_40,   0x1C },
-   { MT_RF(7,  6), RF_A_BAND | RF_BW_20,   0x40 },
-   { MT_RF(7,  6), RF_A_BAND | RF_BW_40,   0x20 },
-   { MT_RF(7,  6), RF_A_BAND | RF_BW_80,   0x10 },
-   { MT_RF(7,  7), RF_G_BAND | RF_BW_20,   0x40 },
-   { MT_RF(7,  7), RF_G_BAND | RF_BW_40,   0x20 },
-   { MT_RF(7,  7), RF_A_BAND | RF_BW_20,   0x40 },
-   { MT_RF(7,  7), RF_A_BAND | RF_BW_40,   0x20 },
-   { MT_RF(7,  7), RF_A_BAND | RF_BW_80,   0x10 },
-   { MT_RF(7,  8), RF_G_BAND | RF_BW_20,   0x03 },
-   { MT_RF(7,  8), RF_G_BAND | RF_BW_40,   0x01 },
-   { MT_RF(7,  8), RF_A_BAND | RF_BW_20,   0x03 },
-   { MT_RF(7,  8), RF_A_BAND | RF_BW_40,   0x01 },
-   { MT_RF(7,  8), RF_A_BAND | RF_BW_80,   0x00 },
-   { MT_RF(7, 58), RF_G_BAND | RF_BW_20,   0x40 },
-   { MT_RF(7, 58), RF_G_BAND | RF_BW_40,   0x40 },
-   { MT_RF(7, 58), RF_A_BAND | RF_BW_20,   0x40 },
-   { MT_RF(7, 58), RF_A_BAND | RF_BW_40,   0x40 },
-   { MT_RF(7, 58), RF_A_BAND | RF_BW_80,   0x10 },
-   { MT_RF(7, 59), RF_G_BAND | RF_BW_20,   0x40 },
-   { MT_RF(7, 59), RF_G_BAND | RF_BW_40,   0x40 },
-   { MT_RF(7, 59), RF_A_BAND | RF_BW_20,   0x40 },
-   { MT_RF(7, 59), RF_A_BAND | RF_BW_40,   0x40 },
-   { MT_RF(7, 59), RF_A_BAND | RF_BW_80,   0x10 },
-   { MT_RF(7, 60), RF_G_BAND | RF_BW_20,   0xAA },
-   { MT_RF(7, 60), RF_G_BAND | RF_BW_40,   0xAA },
-   { MT_RF(7, 60), RF_A_BAND | RF_BW_20,   0xAA },
-   { MT_RF(7, 60), RF_A_BAND | RF_BW_40,   0xAA },
-   { MT_RF(7, 60), RF_A_BAND | RF_BW_80,   0xAA },
-   { MT_RF(7, 76), RF_BW_20,   0x40 },
-   { MT_RF(7, 76), RF_BW_40,   0x40 },
-   { MT_RF(7, 76), RF_BW_80,   0x10 },
-   { MT_RF(7, 77), RF_BW_20,   0x40 },
-   { MT_RF(7, 77), RF_BW_40,   0x40 },
-   { MT_RF(7, 77), RF_BW_80,   0x10 },
-};
-
 static const struct mt76x0_rf_switch_item mt76x0_rf_band_switch_tab[] = {
/* bank, regbw/band value */
{ MT_RF(0,  16),RF_G_BAND,  0x20 },
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/phy.c 
b/drivers/net/wireless/mediatek/mt76/mt76x0/phy.c
index 37e1ead1dc85..10041e673c31 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x0/phy.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x0/phy.c
@@ -239,17 +239,61 @@ mt76x0_phy_set_band(struct mt76x02_dev *dev, enum 
nl80211_band band)
}
 }
 
+
+static void mt76x0_phy_rf_switch_band(struct mt76x02_dev *dev,
+ struct cfg80211_chan_def *chandef)
+{
+   enum nl80211_chan_width width = NL80211_CHAN_WIDTH_20;
+   enum nl80211_band band = NL80211_BAND_2GHZ;
+   u8 r6, r7, r8;
+   u8 r58_59_76 = 0x40;
+
+   if (chandef) {
+   band = chandef->chan->band;
+   width = chandef->width;
+   }
+
+   switch (width) {
+   case NL80211_CHAN_WIDTH_80:
+   r6 = r7 = 0x10;
+   r8 = 0x00;
+   r58_59_76 = 0x10;
+   break;
+   case NL80211_CHAN_WIDTH_40:
+   r6 = r7 = 0x20;
+   if (band == NL80211_BAND_2GHZ)
+   r6 = 0x1c;
+   r8 = 0x01;
+   break;
+   default:
+   r6 = r7 = 0x40;
+   r8 = 0x03;
+   break;
+   }
+
+   mt76x0_rf_wr(dev, MT_RF(0, 17), 0x00);
+   mt76x0_rf_wr(dev, MT_RF(7, 6), r6);
+   mt76x0_rf_wr(dev, MT_RF(7, 7), r7);
+   mt76x0_rf_wr(dev, MT_RF(7, 8), r8);
+   mt76x0_rf_wr(dev, MT_RF(7, 58), r58_59_76);
+   mt76x0_rf_wr(dev, MT_RF(7, 59), r58_59_76);
+   mt76x0_rf_wr(d

[PATCH] mt76: clean up unused leftover EXPORT_SYMBOLs

2018-10-17 Thread Felix Fietkau
Make previously exported functions static where possible

Signed-off-by: Felix Fietkau 
---
 drivers/net/wireless/mediatek/mt76/mt76.h | 2 --
 drivers/net/wireless/mediatek/mt76/mt76x02_mac.c  | 8 +---
 drivers/net/wireless/mediatek/mt76/mt76x02_mac.h  | 2 --
 drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c | 1 -
 drivers/net/wireless/mediatek/mt76/mt76x02_txrx.c | 2 --
 drivers/net/wireless/mediatek/mt76/usb.c  | 6 ++
 6 files changed, 3 insertions(+), 18 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h 
b/drivers/net/wireless/mediatek/mt76/mt76.h
index 3bfa7f5e3513..53ddc4fa5884 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76.h
@@ -668,8 +668,6 @@ int mt76u_vendor_request(struct mt76_dev *dev, u8 req,
 void *buf, size_t len);
 void mt76u_single_wr(struct mt76_dev *dev, const u8 req,
 const u16 offset, const u32 val);
-u32 mt76u_rr(struct mt76_dev *dev, u32 addr);
-void mt76u_wr(struct mt76_dev *dev, u32 addr, u32 val);
 int mt76u_init(struct mt76_dev *dev, struct usb_interface *intf);
 void mt76u_deinit(struct mt76_dev *dev);
 int mt76u_buf_alloc(struct mt76_dev *dev, struct mt76u_buf *buf,
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c 
b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
index 3896da690b83..899ffd026e62 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
@@ -18,7 +18,7 @@
 #include "mt76x02.h"
 #include "mt76x02_trace.h"
 
-enum mt76x02_cipher_type
+static enum mt76x02_cipher_type
 mt76x02_mac_get_key_info(struct ieee80211_key_conf *key, u8 *key_data)
 {
memset(key_data, 0, 32);
@@ -43,7 +43,6 @@ mt76x02_mac_get_key_info(struct ieee80211_key_conf *key, u8 
*key_data)
return MT_CIPHER_NONE;
}
 }
-EXPORT_SYMBOL_GPL(mt76x02_mac_get_key_info);
 
 int mt76x02_mac_shared_key_setup(struct mt76x02_dev *dev, u8 vif_idx,
 u8 key_idx, struct ieee80211_key_conf *key)
@@ -95,7 +94,6 @@ int mt76x02_mac_wcid_set_key(struct mt76x02_dev *dev, u8 idx,
 
return 0;
 }
-EXPORT_SYMBOL_GPL(mt76x02_mac_wcid_set_key);
 
 void mt76x02_mac_wcid_setup(struct mt76x02_dev *dev, u8 idx,
u8 vif_idx, u8 *mac)
@@ -154,7 +152,6 @@ void mt76x02_txq_init(struct mt76x02_dev *dev, struct 
ieee80211_txq *txq)
 
mt76_txq_init(>mt76, txq);
 }
-EXPORT_SYMBOL_GPL(mt76x02_txq_init);
 
 static __le16
 mt76x02_mac_tx_rate_val(struct mt76x02_dev *dev,
@@ -239,7 +236,6 @@ bool mt76x02_mac_load_tx_status(struct mt76x02_dev *dev,
 
return true;
 }
-EXPORT_SYMBOL_GPL(mt76x02_mac_load_tx_status);
 
 static int
 mt76x02_mac_process_tx_rate(struct ieee80211_tx_rate *txrate, u16 rate,
@@ -483,7 +479,6 @@ void mt76x02_send_tx_status(struct mt76x02_dev *dev,
 out:
rcu_read_unlock();
 }
-EXPORT_SYMBOL_GPL(mt76x02_send_tx_status);
 
 int
 mt76x02_mac_process_rate(struct mt76_rx_status *status, u16 rate)
@@ -705,7 +700,6 @@ void mt76x02_mac_poll_tx_status(struct mt76x02_dev *dev, 
bool irq)
kfifo_put(>txstatus_fifo, stat);
}
 }
-EXPORT_SYMBOL_GPL(mt76x02_mac_poll_tx_status);
 
 static void
 mt76x02_mac_queue_txdone(struct mt76x02_dev *dev, struct sk_buff *skb,
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.h 
b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.h
index c1936e2277d1..81c16aef6a94 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.h
@@ -199,8 +199,6 @@ mt76x02_skb_tx_info(struct sk_buff *skb)
 }
 
 void mt76x02_txq_init(struct mt76x02_dev *dev, struct ieee80211_txq *txq);
-enum mt76x02_cipher_type
-mt76x02_mac_get_key_info(struct ieee80211_key_conf *key, u8 *key_data);
 
 int mt76x02_mac_shared_key_setup(struct mt76x02_dev *dev, u8 vif_idx,
 u8 key_idx, struct ieee80211_key_conf *key);
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c 
b/drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c
index 39f092034240..784b76e08382 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c
@@ -225,7 +225,6 @@ static void mt76x02_dma_enable(struct mt76x02_dev *dev)
mt76_clear(dev, MT_WPDMA_GLO_CFG,
   MT_WPDMA_GLO_CFG_TX_WRITEBACK_DONE);
 }
-EXPORT_SYMBOL_GPL(mt76x02_dma_enable);
 
 void mt76x02_dma_cleanup(struct mt76x02_dev *dev)
 {
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_txrx.c 
b/drivers/net/wireless/mediatek/mt76/mt76x02_txrx.c
index d3de08872d6e..7ec3f8f5f228 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_txrx.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_txrx.c
@@ -110,7 +110,6 @@ s8 mt76x02_tx_get_max_txpwr_adj(struct mt76x02_dev *dev,
 
return max_txpwr;
 }
-EXPORT_SYMBOL_GPL(mt76x02_tx_get_max_txpwr_adj);
 
 s

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 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] 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: [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: [PATCH v2 0/2] update firmware used on mt76x2u driver

2018-10-15 Thread Felix Fietkau
On 2018-10-14 20:27, Lorenzo Bianconi wrote:
> Align mt76x2 pcie/usb firmware.
> Update vga logic on mt76x2u driver
Applied, thanks.

- Felix


pull request: mt76 2018-10-13 v2

2018-10-13 Thread Felix Fietkau
Hi Kalle,

Here's another large batch of mt76 code cleanup / deduplication / fixes
v2: add missing S-o-b.

- Felix

The following changes since commit c894696188d5c2af1e636e458190e80c53fb893d:

  rtlwifi: rtl8821ae: replace _rtl8821ae_mrate_idx_to_arfr_id with generic 
version (2018-10-13 15:00:37 +0300)

are available in the Git repository at:

  https://github.com/nbd168/wireless tags/mt76-for-kvalo-2018-10-13

for you to fetch changes up to f27a058199ee6da50d724302d42fff94a00851c7:

  mt76x0: phy: do not run calibration during channel switch (2018-10-13 
16:35:16 +0200)


mt76 patches for 4.20

* mt76x0 fixes
* mt76x0e improvements (should be usable now)
* usb support improvements
* more mt76x0/mt76x2 unification work
* minor fix for aggregation + powersave clients


Felix Fietkau (2):
  mt76: do not store aggregation sequence number for null-data frames
  mt76: mt76x0e: another fix for the external PA current setting

Lorenzo Bianconi (26):
  mt76x0: phy: fix bank check in mt76x0_rf_csr_{wr,rr}
  mt76: use mt76x02_dev instead of mt76_dev in mt76x02_mcu.c
  mt76: use mt76x02_dev instead of mt76_dev in mt76x02_phy.c
  mt76: use mt76x02_dev instead of mt76_dev in mt76x02_util.c
  mt76: use mt76x02_dev instead of mt76_dev in mt76x02_usb_mcu.c
  mt76: use mt76x02_dev instead of mt76_dev in mt76x02_mac.c
  mt76: use mt76x02_dev instead of mt76_dev in mt76x02_txrx.c
  mt76: use mt76x02_dev instead of mt76_dev in mt76x02_eeprom.c
  mt76x0: pci: report firmware version using ethtool
  mt76x0: pci: add missing mac80211 callbacks
  mt76: disable ldpc coding for mt76x0 devices
  mt76x0: pci: add mt76x0_register_device in mt76x0e_register_device
  mt76x0: phy: fix restore phase in mt76x0_phy_recalibrate_after_assoc
  mt76x0: phy: remove channel parameter from mt76x0_phy_set_chan_bbp_params
  mt76: move mt76x02_phy_set_bw in mt76x02-lib module
  mt76: move mt76x02_phy_set_band in mt76x02-lib module
  mt76x0: pci: rename mt76x0_phy_calibrate
  mt76x0: pci: introduce mt76x0_phy_calirate routine
  mt76x0: phy: update set_channel for mt76x0e devices
  mt76x0: eeprom: introduce mt76x0_tssi_enabled routine
  mt76x0: phy: add phy/vco temperature compensation
  mt76: move rssi_gain_thresh routines in mt76x02-lib module
  mt76: move mt76x02_phy_adjust_vga_gain in mt76/mt76x02_phy.c
  mt76: introduce mt76x02_init_agc_gain routine
  mt76x0: phy: align channel gain logic to mt76x2 one
  mt76x0: phy: do not run calibration during channel switch

Stanislaw Gruszka (7):
  mt76x0: print BBP version only for debug
  mt76x0: correct RF access via RF_CSR register.
  mt76: allow to identify bus
  mt76x0: correct RF reg pairs write for PCIe
  mt76x0: use bus helper to identify rf access method
  mt76: reserve enough room for USB tx skbs
  mt76x0: remove dma.h

YueHaibing (1):
  mt76x0: pci: fix set external PA I/O current

 drivers/net/wireless/mediatek/mt76/mmio.c |   1 +
 drivers/net/wireless/mediatek/mt76/mt76.h |   9 +++
 drivers/net/wireless/mediatek/mt76/mt76x0/dma.h   | 126 
---
 drivers/net/wireless/mediatek/mt76/mt76x0/eeprom.c|  55 -
 drivers/net/wireless/mediatek/mt76/mt76x0/eeprom.h|   6 ++
 drivers/net/wireless/mediatek/mt76/mt76x0/init.c  |   9 ++-
 drivers/net/wireless/mediatek/mt76/mt76x0/main.c  |  22 ---
 drivers/net/wireless/mediatek/mt76/mt76x0/mcu.h   |   3 +
 drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h|   3 +-
 drivers/net/wireless/mediatek/mt76/mt76x0/pci.c   |  49 ++-
 drivers/net/wireless/mediatek/mt76/mt76x0/pci_mcu.c   |   1 +
 drivers/net/wireless/mediatek/mt76/mt76x0/phy.c   | 311 
++--
 drivers/net/wireless/mediatek/mt76/mt76x0/usb_mcu.c   |   7 +--
 drivers/net/wireless/mediatek/mt76/mt76x02.h  |  25 +---
 drivers/net/wireless/mediatek/mt76/mt76x02_eeprom.c   |  33 +--
 drivers/net/wireless/mediatek/mt76/mt76x02_eeprom.h   |  37 +++-
 drivers/net/wireless/mediatek/mt76/mt76x02_mac.c  | 206 
+++
 drivers/net/wireless/mediatek/mt76/mt76x02_mac.h  |  31 +-
 drivers/net/wireless/mediatek/mt76/mt76x02_mcu.c  |  74 
+++
 drivers/net/wireless/mediatek/mt76/mt76x02_mcu.h  |  14 +++--
 drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c |   2 +-
 drivers/net/wireless/mediatek/mt76/mt76x02_phy.c  | 167 
+---
 drivers/net/wireless/mediatek/mt76/mt76x02_phy.h  |  39 ++--
 drivers/net/wireless/mediatek/mt76/mt76x02_regs.h |   4

pull request: mt76 2018-10-13

2018-10-13 Thread Felix Fietkau
Hi Kalle,

Here's another batch of mt76 code cleanup / deduplication / fixes

- Felix

The following changes since commit c894696188d5c2af1e636e458190e80c53fb893d:

  rtlwifi: rtl8821ae: replace _rtl8821ae_mrate_idx_to_arfr_id with generic 
version (2018-10-13 15:00:37 +0300)

are available in the Git repository at:

  https://github.com/nbd168/wireless tags/mt76-for-kvalo-2018-10-13

for you to fetch changes up to f27a058199ee6da50d724302d42fff94a00851c7:

  mt76x0: phy: do not run calibration during channel switch (2018-10-13 
16:35:16 +0200)


mt76 patches for 4.20

* mt76x0 fixes
* mt76x0e improvements (should be usable now)
* usb support improvements
* more mt76x0/mt76x2 unification work
* minor fix for aggregation + powersave clients


Felix Fietkau (2):
  mt76: do not store aggregation sequence number for null-data frames
  mt76: mt76x0e: another fix for the external PA current setting

Lorenzo Bianconi (26):
  mt76x0: phy: fix bank check in mt76x0_rf_csr_{wr,rr}
  mt76: use mt76x02_dev instead of mt76_dev in mt76x02_mcu.c
  mt76: use mt76x02_dev instead of mt76_dev in mt76x02_phy.c
  mt76: use mt76x02_dev instead of mt76_dev in mt76x02_util.c
  mt76: use mt76x02_dev instead of mt76_dev in mt76x02_usb_mcu.c
  mt76: use mt76x02_dev instead of mt76_dev in mt76x02_mac.c
  mt76: use mt76x02_dev instead of mt76_dev in mt76x02_txrx.c
  mt76: use mt76x02_dev instead of mt76_dev in mt76x02_eeprom.c
  mt76x0: pci: report firmware version using ethtool
  mt76x0: pci: add missing mac80211 callbacks
  mt76: disable ldpc coding for mt76x0 devices
  mt76x0: pci: add mt76x0_register_device in mt76x0e_register_device
  mt76x0: phy: fix restore phase in mt76x0_phy_recalibrate_after_assoc
  mt76x0: phy: remove channel parameter from mt76x0_phy_set_chan_bbp_params
  mt76: move mt76x02_phy_set_bw in mt76x02-lib module
  mt76: move mt76x02_phy_set_band in mt76x02-lib module
  mt76x0: pci: rename mt76x0_phy_calibrate
  mt76x0: pci: introduce mt76x0_phy_calirate routine
  mt76x0: phy: update set_channel for mt76x0e devices
  mt76x0: eeprom: introduce mt76x0_tssi_enabled routine
  mt76x0: phy: add phy/vco temperature compensation
  mt76: move rssi_gain_thresh routines in mt76x02-lib module
  mt76: move mt76x02_phy_adjust_vga_gain in mt76/mt76x02_phy.c
  mt76: introduce mt76x02_init_agc_gain routine
  mt76x0: phy: align channel gain logic to mt76x2 one
  mt76x0: phy: do not run calibration during channel switch

Stanislaw Gruszka (7):
  mt76x0: print BBP version only for debug
  mt76x0: correct RF access via RF_CSR register.
  mt76: allow to identify bus
  mt76x0: correct RF reg pairs write for PCIe
  mt76x0: use bus helper to identify rf access method
  mt76: reserve enough room for USB tx skbs
  mt76x0: remove dma.h

YueHaibing (1):
  mt76x0: pci: fix set external PA I/O current

 drivers/net/wireless/mediatek/mt76/mmio.c |   1 +
 drivers/net/wireless/mediatek/mt76/mt76.h |   9 +++
 drivers/net/wireless/mediatek/mt76/mt76x0/dma.h   | 126 
---
 drivers/net/wireless/mediatek/mt76/mt76x0/eeprom.c|  55 -
 drivers/net/wireless/mediatek/mt76/mt76x0/eeprom.h|   6 ++
 drivers/net/wireless/mediatek/mt76/mt76x0/init.c  |   9 ++-
 drivers/net/wireless/mediatek/mt76/mt76x0/main.c  |  22 ---
 drivers/net/wireless/mediatek/mt76/mt76x0/mcu.h   |   3 +
 drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h|   3 +-
 drivers/net/wireless/mediatek/mt76/mt76x0/pci.c   |  49 ++-
 drivers/net/wireless/mediatek/mt76/mt76x0/pci_mcu.c   |   1 +
 drivers/net/wireless/mediatek/mt76/mt76x0/phy.c   | 311 
++--
 drivers/net/wireless/mediatek/mt76/mt76x0/usb_mcu.c   |   7 +--
 drivers/net/wireless/mediatek/mt76/mt76x02.h  |  25 +---
 drivers/net/wireless/mediatek/mt76/mt76x02_eeprom.c   |  33 +--
 drivers/net/wireless/mediatek/mt76/mt76x02_eeprom.h   |  37 +++-
 drivers/net/wireless/mediatek/mt76/mt76x02_mac.c  | 206 
+++
 drivers/net/wireless/mediatek/mt76/mt76x02_mac.h  |  31 +-
 drivers/net/wireless/mediatek/mt76/mt76x02_mcu.c  |  74 
+++
 drivers/net/wireless/mediatek/mt76/mt76x02_mcu.h  |  14 +++--
 drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c |   2 +-
 drivers/net/wireless/mediatek/mt76/mt76x02_phy.c  | 167 
+---
 drivers/net/wireless/mediatek/mt76/mt76x02_phy.h  |  39 ++--
 drivers/net/wireless/mediatek/mt76/mt76x02_regs.h |   4 +-
 drivers/net/wireless

Re: [PATCH 00/13] add calibration logics for mt76x0e driver

2018-10-12 Thread Felix Fietkau
On 2018-10-12 12:16, Lorenzo Bianconi wrote:
> Introduce vga, temperature and phy calibration routines for
> mt76x0e driver. Move phy shared code in mt76x02-lib module.
> Moreover do not run calibration during channel switch
> 
> Changes since rfc:
> - run vco calibration during freq scanning
> - use mt76x0_phy as prefix for phy routines
> 
> Lorenzo Bianconi (13):
>   mt76: move mt76x02_phy_set_bw in mt76x02-lib module
>   mt76: move mt76x02_phy_set_band in mt76x02-lib module
>   mt76x0: pci: rename mt76x0_phy_calibrate
>   mt76x0: pci: introduce mt76x0_phy_calirate routine
>   mt76x0: phy: update set_channel for mt76x0e devices
>   mt76x0: eeprom: introduce mt76x0_tssi_enabled routine
>   mt76x0: phy: add phy/vco temperature compensation
>   mt76: move rssi_gain_thresh routines in mt76x02-lib module
>   mt76: move mt76x02_phy_adjust_vga_gain in mt76/mt76x02_phy.c
>   mt76: introduce mt76x02_init_agc_gain routine
>   mt76x0: phy: align channel gain logic to mt76x2 one
>   mt76x0: phy: do not run calibration during channel switch
>   mt76x0: phy: use proper name convetion
Merged the series except for the last patch. I will send out the new
pull request tomorrow

Thanks,

- Felix


Re: [PATCH] mt76x0: phy: remove channel parameter from mt76x0_phy_set_chan_bbp_params

2018-10-12 Thread Felix Fietkau
On 2018-10-10 12:31, Lorenzo Bianconi wrote:
> Remove unused channel parameter from mt76x0_phy_set_chan_bbp_params
> routine signature
> 
> Signed-off-by: Lorenzo Bianconi 
Merged, thanks.

- Felix


Re: [PATCH v2] mt76x0: phy: fix restore phase in mt76x0_phy_recalibrate_after_assoc

2018-10-09 Thread Felix Fietkau
On 2018-10-09 10:57, Lorenzo Bianconi wrote:
> Fix restore value configured in MT_BBP(IBI, 9) register in
> mt76x0_phy_recalibrate_after_assoc routine.
> 
> Fixes: 10de7a8b4ab9 ("mt76x0: phy files")
> Signed-off-by: Lorenzo Bianconi 
Merged, thanks.

- Felix


[PATCH] mt76: mt76x0e: another fix for the external PA current setting

2018-10-09 Thread Felix Fietkau
- Use the register number define instead of a magic value
- Fix inverted bit test (override needs to be applied if the bit is not set)

Fixes: 2b2cb40bcd7d ("mt76x0: pci: add hw initialization at bootstrap")
Signed-off-by: Felix Fietkau 
---
 drivers/net/wireless/mediatek/mt76/mt76x0/pci.c | 13 +++--
 1 file changed, 3 insertions(+), 10 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/pci.c 
b/drivers/net/wireless/mediatek/mt76/mt76x0/pci.c
index cc8af17dc9c7..fd2dc7efeea3 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x0/pci.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x0/pci.c
@@ -111,17 +111,10 @@ static int mt76x0e_register_device(struct mt76x02_dev 
*dev)
u16 val;
 
mt76_clear(dev, MT_COEXCFG0, BIT(0));
+
val = mt76x02_eeprom_get(dev, MT_EE_NIC_CONF_0);
-   if (val & MT_EE_NIC_CONF_0_PA_IO_CURRENT) {
-   u32 data;
-
-   /* set external PA I/O
-* current to 16mA
-*/
-   data = mt76_rr(dev, 0x11c);
-   data |= 0xc03;
-   mt76_wr(dev, 0x11c, data);
-   }
+   if (!(val & MT_EE_NIC_CONF_0_PA_IO_CURRENT))
+   mt76_set(dev, MT_XO_CTRL7, 0xc03);
}
 
mt76_clear(dev, 0x110, BIT(9));
-- 
2.17.0



Re: [PATCH] mt76x0: phy: fix restore phase in mt76x0_phy_recalibrate_after_assoc

2018-10-09 Thread Felix Fietkau
On 2018-10-09 09:35, Stanislaw Gruszka wrote:
> On Mon, Oct 08, 2018 at 08:11:45PM +0200, Felix Fietkau wrote:
>> On 2018-10-08 14:40, Lorenzo Bianconi wrote:
>> > Fix restore value configured in 0x2124 register in
>> > mt76x0_phy_recalibrate_after_assoc routine.
>> > 
>> > Fixes: 10de7a8b4ab9 ("mt76x0: phy files")
>> > Signed-off-by: Lorenzo Bianconi 
>> > ---
>> >  drivers/net/wireless/mediatek/mt76/mt76x0/phy.c | 3 +--
>> >  1 file changed, 1 insertion(+), 2 deletions(-)
>> > 
>> > diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/phy.c 
>> > b/drivers/net/wireless/mediatek/mt76/mt76x0/phy.c
>> > index 99e0a91a2f99..d18942e54048 100644
>> > --- a/drivers/net/wireless/mediatek/mt76/mt76x0/phy.c
>> > +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/phy.c
>> > @@ -734,8 +734,7 @@ void mt76x0_phy_recalibrate_after_assoc(struct 
>> > mt76x02_dev *dev)
>> >usleep_range(500, 700);
>> >  
>> >reg_val = mt76_rr(dev, 0x2124);
>> > -  reg_val &= 0xff7e;
>> > -  mt76_wr(dev, 0x2124, reg_val);
>> > +  mt76_wr(dev, 0x2124, 0xff7e);
>> I'm pretty sure you can drop the mt76_rr as well. Also, you can refer to
>> 0x2124 as MT_BBP(IBI, 9).
> 
> I think is needed we do:
> 
>   reg_val = mt76_rr(dev, 0x2124); 
>   mt76_wr(dev, 0x2124, 0xff7e);
> 
>   CALIBRATE
> 
>   mt76_wr(dev, 0x2124, reg_val);
> 
> so seems we have to restore orginal value after calibration.
> 
> Referencing as MT_BBP(IBI, 9) is obviously fine.
Yes, that makes more sense.

- Felix


Re: [PATCH] mt76x0: phy: fix restore phase in mt76x0_phy_recalibrate_after_assoc

2018-10-08 Thread Felix Fietkau
On 2018-10-08 14:40, Lorenzo Bianconi wrote:
> Fix restore value configured in 0x2124 register in
> mt76x0_phy_recalibrate_after_assoc routine.
> 
> Fixes: 10de7a8b4ab9 ("mt76x0: phy files")
> Signed-off-by: Lorenzo Bianconi 
> ---
>  drivers/net/wireless/mediatek/mt76/mt76x0/phy.c | 3 +--
>  1 file changed, 1 insertion(+), 2 deletions(-)
> 
> diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/phy.c 
> b/drivers/net/wireless/mediatek/mt76/mt76x0/phy.c
> index 99e0a91a2f99..d18942e54048 100644
> --- a/drivers/net/wireless/mediatek/mt76/mt76x0/phy.c
> +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/phy.c
> @@ -734,8 +734,7 @@ void mt76x0_phy_recalibrate_after_assoc(struct 
> mt76x02_dev *dev)
>   usleep_range(500, 700);
>  
>   reg_val = mt76_rr(dev, 0x2124);
> - reg_val &= 0xff7e;
> - mt76_wr(dev, 0x2124, reg_val);
> + mt76_wr(dev, 0x2124, 0xff7e);
I'm pretty sure you can drop the mt76_rr as well. Also, you can refer to
0x2124 as MT_BBP(IBI, 9).

- Felix


Re: [PATCH] mt76x0: remove dma.h

2018-10-08 Thread Felix Fietkau
On 2018-10-08 13:22, Stanislaw Gruszka wrote:
> dma.h is not used any longer.
> 
> Signed-off-by: Stanislaw Gruszka 

Merged, thanks.

- Felix


Re: [PATCH] mt76: reserve enough room for USB tx skbs

2018-10-08 Thread Felix Fietkau
On 2018-10-08 13:22, Stanislaw Gruszka wrote:
> Reserve enough room for USB skb, so we don not need to check
> the room every time we send frame.
> 
> Signed-off-by: Stanislaw Gruszka 

Merged, thanks.

- Felix


Re: [PATCH 0/3] enable sta mode in mt76x0e driver

2018-10-08 Thread Felix Fietkau
On 2018-10-07 11:57, Lorenzo Bianconi wrote:
> Enable client mode in mt76x0e driver registering the device to the mac80211
> layer. Moreover add missing mac80211 callbacks in mt76x0e_ops data structure.
> Sta mode has been tested connecting to a 802.11ac AP on 5GHz band
> 
Merged, thanks.

- Felix


Re: [PATCH v2] mt76x0: pci: report firmware version using ethtool

2018-10-08 Thread Felix Fietkau
On 2018-10-07 11:51, Lorenzo Bianconi wrote:
> Report via ethtool fw_ver and build_ver members of mt76x02_fw_header
> data structure similarly to what is reported in the syslog
> 
> Signed-off-by: Lorenzo Bianconi 

Merged, thanks.

- Felix


Re: [PATCH 0/7] use mt76x02_dev instead of mt76_dev as reference

2018-10-08 Thread Felix Fietkau
On 2018-10-07 11:45, Lorenzo Bianconi wrote:
> Use mt76x02_dev data structure as reference in mt76x02 code
> instead of mt76_dev one

Merged, thanks.

- Felix



Re: [PATCH] mt76x0: phy: fix bank check in mt76x0_rf_csr_{wr,rr}

2018-10-08 Thread Felix Fietkau
On 2018-10-07 11:37, Lorenzo Bianconi wrote:
> Fix typo in bank check in mt76x0_rf_csr_{wr,rr} routines.
> This issue has never been hit since mt76x0_rf_csr_{wr,rr}
> are actually used just by pci code
> 
> Fixes: 10de7a8b4ab9 ("mt76x0: phy files")
> Signed-off-by: Lorenzo Bianconi 

Merged, thanks.

- Felix


[PATCH] mt76: do not store aggregation sequence number for null-data frames

2018-10-08 Thread Felix Fietkau
Fixes a rare corner case where a BlockAckReq might get the wrong
sequence number.

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

diff --git a/drivers/net/wireless/mediatek/mt76/tx.c 
b/drivers/net/wireless/mediatek/mt76/tx.c
index bf0e9e666bc4..7cbce03aa65b 100644
--- a/drivers/net/wireless/mediatek/mt76/tx.c
+++ b/drivers/net/wireless/mediatek/mt76/tx.c
@@ -96,7 +96,8 @@ mt76_check_agg_ssn(struct mt76_txq *mtxq, struct sk_buff *skb)
 {
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
 
-   if (!ieee80211_is_data_qos(hdr->frame_control))
+   if (!ieee80211_is_data_qos(hdr->frame_control) ||
+   !ieee80211_is_data_present(hdr->frame_control))
return;
 
mtxq->agg_ssn = le16_to_cpu(hdr->seq_ctrl) + 0x10;
-- 
2.17.0



Re: [PATCH 9/9] mac80211: rc80211_minstrel: remove variance / stddev calculation

2018-10-06 Thread Felix Fietkau
On 2018-10-06 19:59, Dave Taht wrote:
> On Sat, Oct 6, 2018 at 10:37 AM Felix Fietkau  wrote:
>>
>> When there are few packets (e.g. for sampling attempts), the exponentially
>> weighted variance is usually vastly overestimated, making the resulting data
>> essentially useless. As far as I know, there has not been any practical use
>> for this, so let's not waste any cycles on it.
>>
>> Signed-off-by: Felix Fietkau 
>> ---
>>  net/mac80211/rc80211_minstrel.c|  6 -
>>  net/mac80211/rc80211_minstrel.h| 26 +-
>>  net/mac80211/rc80211_minstrel_debugfs.c| 14 
>>  net/mac80211/rc80211_minstrel_ht_debugfs.c | 14 
>>  4 files changed, 9 insertions(+), 51 deletions(-)
>>
>> diff --git a/net/mac80211/rc80211_minstrel.c 
>> b/net/mac80211/rc80211_minstrel.c
>> index dead57ba9eac..a34e9c2ca626 100644
>> --- a/net/mac80211/rc80211_minstrel.c
>> +++ b/net/mac80211/rc80211_minstrel.c
>> @@ -167,12 +167,6 @@ minstrel_calc_rate_stats(struct minstrel_rate_stats 
>> *mrs)
>> if (unlikely(!mrs->att_hist)) {
>> mrs->prob_ewma = cur_prob;
>> } else {
>> -   /* update exponential weighted moving variance */
>> -   mrs->prob_ewmv = minstrel_ewmv(mrs->prob_ewmv,
>> -   cur_prob,
>> -   mrs->prob_ewma,
>> -   EWMA_LEVEL);
>> -
>> /*update exponential weighted moving avarage */
>> mrs->prob_ewma = minstrel_ewma(mrs->prob_ewma,
>>cur_prob,
>> diff --git a/net/mac80211/rc80211_minstrel.h 
>> b/net/mac80211/rc80211_minstrel.h
>> index 54b2b2c3e10a..23ec953e3a24 100644
>> --- a/net/mac80211/rc80211_minstrel.h
>> +++ b/net/mac80211/rc80211_minstrel.h
>> @@ -35,19 +35,6 @@ minstrel_ewma(int old, int new, int weight)
>> return old + incr;
>>  }
>>
>> -/*
>> - * Perform EWMV (Exponentially Weighted Moving Variance) calculation
>> - */
> 
> I worry about this one. where are you getting your proof from?
I've done quite a few measurements myself to see if this can be usable
for further rate control improvements or for the upcoming TPC work.
The data this generates simply fluctuates wildly and incoherently based
on the sampling behavior, making it completely useless.
Together with Thomas (who introduced this code), I tried a few times to
fix this, but couldn't find any way to make it coherent and usable.

Thomas and I both agreed that it's better to just remove it until
somebody has a better idea what to do.

Also, this was only used for debugfs statistics, not for any actual rate
control behavior.

- Felix


[PATCH 9/9] mac80211: rc80211_minstrel: remove variance / stddev calculation

2018-10-06 Thread Felix Fietkau
When there are few packets (e.g. for sampling attempts), the exponentially
weighted variance is usually vastly overestimated, making the resulting data
essentially useless. As far as I know, there has not been any practical use
for this, so let's not waste any cycles on it.

Signed-off-by: Felix Fietkau 
---
 net/mac80211/rc80211_minstrel.c|  6 -
 net/mac80211/rc80211_minstrel.h| 26 +-
 net/mac80211/rc80211_minstrel_debugfs.c| 14 
 net/mac80211/rc80211_minstrel_ht_debugfs.c | 14 
 4 files changed, 9 insertions(+), 51 deletions(-)

diff --git a/net/mac80211/rc80211_minstrel.c b/net/mac80211/rc80211_minstrel.c
index dead57ba9eac..a34e9c2ca626 100644
--- a/net/mac80211/rc80211_minstrel.c
+++ b/net/mac80211/rc80211_minstrel.c
@@ -167,12 +167,6 @@ minstrel_calc_rate_stats(struct minstrel_rate_stats *mrs)
if (unlikely(!mrs->att_hist)) {
mrs->prob_ewma = cur_prob;
} else {
-   /* update exponential weighted moving variance */
-   mrs->prob_ewmv = minstrel_ewmv(mrs->prob_ewmv,
-   cur_prob,
-   mrs->prob_ewma,
-   EWMA_LEVEL);
-
/*update exponential weighted moving avarage */
mrs->prob_ewma = minstrel_ewma(mrs->prob_ewma,
   cur_prob,
diff --git a/net/mac80211/rc80211_minstrel.h b/net/mac80211/rc80211_minstrel.h
index 54b2b2c3e10a..23ec953e3a24 100644
--- a/net/mac80211/rc80211_minstrel.h
+++ b/net/mac80211/rc80211_minstrel.h
@@ -35,19 +35,6 @@ minstrel_ewma(int old, int new, int weight)
return old + incr;
 }
 
-/*
- * Perform EWMV (Exponentially Weighted Moving Variance) calculation
- */
-static inline int
-minstrel_ewmv(int old_ewmv, int cur_prob, int prob_ewma, int weight)
-{
-   int diff, incr;
-
-   diff = cur_prob - prob_ewma;
-   incr = (EWMA_DIV - weight) * diff / EWMA_DIV;
-   return weight * (old_ewmv + MINSTREL_TRUNC(diff * incr)) / EWMA_DIV;
-}
-
 struct minstrel_rate_stats {
/* current / last sampling period attempts/success counters */
u16 attempts, last_attempts;
@@ -56,11 +43,8 @@ struct minstrel_rate_stats {
/* total attempts/success counters */
u32 att_hist, succ_hist;
 
-   /* statistis of packet delivery probability
-*  prob_ewma - exponential weighted moving average of prob
-*  prob_ewmsd - exp. weighted moving standard deviation of prob */
+   /* prob_ewma - exponential weighted moving average of prob */
u16 prob_ewma;
-   u16 prob_ewmv;
 
/* maximum retry counts */
u8 retry_count;
@@ -140,14 +124,6 @@ struct minstrel_debugfs_info {
char buf[];
 };
 
-/* Get EWMSD (Exponentially Weighted Moving Standard Deviation) * 10 */
-static inline int
-minstrel_get_ewmsd10(struct minstrel_rate_stats *mrs)
-{
-   unsigned int ewmv = mrs->prob_ewmv;
-   return int_sqrt(MINSTREL_TRUNC(ewmv * 1000 * 1000));
-}
-
 extern const struct rate_control_ops mac80211_minstrel;
 void minstrel_add_sta_debugfs(void *priv, void *priv_sta, struct dentry *dir);
 
diff --git a/net/mac80211/rc80211_minstrel_debugfs.c 
b/net/mac80211/rc80211_minstrel_debugfs.c
index 698a668b5316..c8afd85b51a0 100644
--- a/net/mac80211/rc80211_minstrel_debugfs.c
+++ b/net/mac80211/rc80211_minstrel_debugfs.c
@@ -70,14 +70,13 @@ minstrel_stats_open(struct inode *inode, struct file *file)
p = ms->buf;
p += sprintf(p, "\n");
p += sprintf(p,
-"best   __rate_
statisticslast___sum-of\n");
+"best   __rate_statistics___
last___sum-of\n");
p += sprintf(p,
-"rate  [name idx airtime max_tp]  [avg(tp) avg(prob) 
sd(prob)]  [retry|suc|att]  [#success | #attempts]\n");
+"rate  [name idx airtime max_tp]  [avg(tp) avg(prob)]  
[retry|suc|att]  [#success | #attempts]\n");
 
for (i = 0; i < mi->n_rates; i++) {
struct minstrel_rate *mr = >r[i];
struct minstrel_rate_stats *mrs = >r[i].stats;
-   unsigned int prob_ewmsd;
 
*(p++) = (i == mi->max_tp_rate[0]) ? 'A' : ' ';
*(p++) = (i == mi->max_tp_rate[1]) ? 'B' : ' ';
@@ -93,15 +92,13 @@ minstrel_stats_open(struct inode *inode, struct file *file)
tp_max = minstrel_get_tp_avg(mr, MINSTREL_FRAC(100,100));
tp_avg = minstrel_get_tp_avg(mr, mrs->prob_ewma);
eprob = MINSTREL_TRUNC(mrs->prob_ewma * 1000);
-   prob

[PATCH 4/9] mac80211: minstrel: reduce minstrel_mcs_groups size

2018-10-06 Thread Felix Fietkau
By storing a shift value for all duration values of a group, we can
reduce precision by a neglegible amount to make it fit into a u16 value.
This improves cache footprint and reduces size:

Before:
   textdata bss dec hex filename
  10024 116   0   10140279c rc80211_minstrel_ht.o

After:
   textdata bss dec hex filename
   9368 116   09484250c rc80211_minstrel_ht.o

Signed-off-by: Felix Fietkau 
---
 net/mac80211/rc80211_minstrel_ht.c | 153 +++--
 net/mac80211/rc80211_minstrel_ht.h |   7 +-
 net/mac80211/rc80211_minstrel_ht_debugfs.c |  11 +-
 3 files changed, 93 insertions(+), 78 deletions(-)

diff --git a/net/mac80211/rc80211_minstrel_ht.c 
b/net/mac80211/rc80211_minstrel_ht.c
index 0aec00990d1e..38e17ed20d41 100644
--- a/net/mac80211/rc80211_minstrel_ht.c
+++ b/net/mac80211/rc80211_minstrel_ht.c
@@ -52,22 +52,23 @@
_streams - 1
 
 /* MCS rate information for an MCS group */
-#define MCS_GROUP(_streams, _sgi, _ht40)   \
+#define MCS_GROUP(_streams, _sgi, _ht40, _s)   \
[GROUP_IDX(_streams, _sgi, _ht40)] = {  \
.streams = _streams,\
+   .shift = _s,\
.flags =\
IEEE80211_TX_RC_MCS |   \
(_sgi ? IEEE80211_TX_RC_SHORT_GI : 0) | \
(_ht40 ? IEEE80211_TX_RC_40_MHZ_WIDTH : 0), \
.duration = {   \
-   MCS_DURATION(_streams, _sgi, _ht40 ? 54 : 26),  \
-   MCS_DURATION(_streams, _sgi, _ht40 ? 108 : 52), \
-   MCS_DURATION(_streams, _sgi, _ht40 ? 162 : 78), \
-   MCS_DURATION(_streams, _sgi, _ht40 ? 216 : 104),\
-   MCS_DURATION(_streams, _sgi, _ht40 ? 324 : 156),\
-   MCS_DURATION(_streams, _sgi, _ht40 ? 432 : 208),\
-   MCS_DURATION(_streams, _sgi, _ht40 ? 486 : 234),\
-   MCS_DURATION(_streams, _sgi, _ht40 ? 540 : 260) \
+   MCS_DURATION(_streams, _sgi, _ht40 ? 54 : 26) >> _s,\
+   MCS_DURATION(_streams, _sgi, _ht40 ? 108 : 52) >> _s,   \
+   MCS_DURATION(_streams, _sgi, _ht40 ? 162 : 78) >> _s,   \
+   MCS_DURATION(_streams, _sgi, _ht40 ? 216 : 104) >> _s,  \
+   MCS_DURATION(_streams, _sgi, _ht40 ? 324 : 156) >> _s,  \
+   MCS_DURATION(_streams, _sgi, _ht40 ? 432 : 208) >> _s,  \
+   MCS_DURATION(_streams, _sgi, _ht40 ? 486 : 234) >> _s,  \
+   MCS_DURATION(_streams, _sgi, _ht40 ? 540 : 260) >> _s   \
}   \
 }
 
@@ -80,9 +81,10 @@
 #define BW2VBPS(_bw, r3, r2, r1)   \
(_bw == BW_80 ? r3 : _bw == BW_40 ? r2 : r1)
 
-#define VHT_GROUP(_streams, _sgi, _bw) \
+#define VHT_GROUP(_streams, _sgi, _bw, _s) \
[VHT_GROUP_IDX(_streams, _sgi, _bw)] = {\
.streams = _streams,\
+   .shift = _s,\
.flags =\
IEEE80211_TX_RC_VHT_MCS |   \
(_sgi ? IEEE80211_TX_RC_SHORT_GI : 0) | \
@@ -90,25 +92,25 @@
 _bw == BW_40 ? IEEE80211_TX_RC_40_MHZ_WIDTH : 0),  \
.duration = {   \
MCS_DURATION(_streams, _sgi,\
-BW2VBPS(_bw,  117,  54,  26)), \
+BW2VBPS(_bw,  117,  54,  26)) >> _s,   \
MCS_DURATION(_streams, _sgi,\
-BW2VBPS(_bw,  234, 108,  52)), \
+BW2VBPS(_bw,  234, 108,  52)) >> _s,   \
MCS_DURATION(_streams, _sgi,\
-BW2VBPS(_bw,  351, 162,  78)), \
+BW2VBPS(_bw,  351, 162,  78)) >> _s,   \
MCS_DURATION(_streams, _sgi,\
-BW2VBPS(_bw,  468, 216, 104)), \
+BW2VBPS(_bw,  468, 216, 104)) >> _s,   \
MCS_DURATION(_streams, _sgi,\
-BW2VBPS(_bw,  702, 324, 156))

[PATCH 3/9] mac80211: minstrel: merge with minstrel_ht, always enable VHT support

2018-10-06 Thread Felix Fietkau
Legacy-only devices are not very common and the overhead of the extra
code for HT and VHT rates is not big enough to justify all those extra
lines of code to make it optional.

Signed-off-by: Felix Fietkau 
---
 net/mac80211/Kconfig   |  17 +--
 net/mac80211/Makefile  |  11 +-
 net/mac80211/main.c|   7 -
 net/mac80211/rate.h|  13 --
 net/mac80211/rc80211_minstrel.c| 152 -
 net/mac80211/rc80211_minstrel.h|   2 -
 net/mac80211/rc80211_minstrel_debugfs.c|  42 --
 net/mac80211/rc80211_minstrel_ht.c |  91 ++--
 net/mac80211/rc80211_minstrel_ht.h |   8 --
 net/mac80211/rc80211_minstrel_ht_debugfs.c |  16 +++
 10 files changed, 101 insertions(+), 258 deletions(-)

diff --git a/net/mac80211/Kconfig b/net/mac80211/Kconfig
index 76e30f4797fb..f869e35d0974 100644
--- a/net/mac80211/Kconfig
+++ b/net/mac80211/Kconfig
@@ -27,20 +27,6 @@ config MAC80211_RC_MINSTREL
---help---
  This option enables the 'minstrel' TX rate control algorithm
 
-config MAC80211_RC_MINSTREL_HT
-   bool "Minstrel 802.11n support" if EXPERT
-   depends on MAC80211_RC_MINSTREL
-   default y
-   ---help---
- This option enables the 'minstrel_ht' TX rate control algorithm
-
-config MAC80211_RC_MINSTREL_VHT
-   bool "Minstrel 802.11ac support" if EXPERT
-   depends on MAC80211_RC_MINSTREL_HT
-   default n
-   ---help---
- This option enables VHT in the 'minstrel_ht' TX rate control algorithm
-
 choice
prompt "Default rate control algorithm"
depends on MAC80211_HAS_RC
@@ -62,8 +48,7 @@ endchoice
 
 config MAC80211_RC_DEFAULT
string
-   default "minstrel_ht" if MAC80211_RC_DEFAULT_MINSTREL && 
MAC80211_RC_MINSTREL_HT
-   default "minstrel" if MAC80211_RC_DEFAULT_MINSTREL
+   default "minstrel_ht" if MAC80211_RC_DEFAULT_MINSTREL
default ""
 
 endif
diff --git a/net/mac80211/Makefile b/net/mac80211/Makefile
index bb707789ef2b..4f03ebe732fa 100644
--- a/net/mac80211/Makefile
+++ b/net/mac80211/Makefile
@@ -53,13 +53,14 @@ mac80211-$(CONFIG_PM) += pm.o
 
 CFLAGS_trace.o := -I$(src)
 
-rc80211_minstrel-y := rc80211_minstrel.o
-rc80211_minstrel-$(CONFIG_MAC80211_DEBUGFS) += rc80211_minstrel_debugfs.o
+rc80211_minstrel-y := \
+   rc80211_minstrel.o \
+   rc80211_minstrel_ht.o
 
-rc80211_minstrel_ht-y := rc80211_minstrel_ht.o
-rc80211_minstrel_ht-$(CONFIG_MAC80211_DEBUGFS) += rc80211_minstrel_ht_debugfs.o
+rc80211_minstrel-$(CONFIG_MAC80211_DEBUGFS) += \
+   rc80211_minstrel_debugfs.o \
+   rc80211_minstrel_ht_debugfs.o
 
 mac80211-$(CONFIG_MAC80211_RC_MINSTREL) += $(rc80211_minstrel-y)
-mac80211-$(CONFIG_MAC80211_RC_MINSTREL_HT) += $(rc80211_minstrel_ht-y)
 
 ccflags-y += -DDEBUG
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index e6375d035355..83e71e6b2ebe 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -1375,18 +1375,12 @@ static int __init ieee80211_init(void)
if (ret)
return ret;
 
-   ret = rc80211_minstrel_ht_init();
-   if (ret)
-   goto err_minstrel;
-
ret = ieee80211_iface_init();
if (ret)
goto err_netdev;
 
return 0;
  err_netdev:
-   rc80211_minstrel_ht_exit();
- err_minstrel:
rc80211_minstrel_exit();
 
return ret;
@@ -1394,7 +1388,6 @@ static int __init ieee80211_init(void)
 
 static void __exit ieee80211_exit(void)
 {
-   rc80211_minstrel_ht_exit();
rc80211_minstrel_exit();
 
ieee80211s_stop();
diff --git a/net/mac80211/rate.h b/net/mac80211/rate.h
index 8212bfeb71d6..d59198191a79 100644
--- a/net/mac80211/rate.h
+++ b/net/mac80211/rate.h
@@ -95,18 +95,5 @@ static inline void rc80211_minstrel_exit(void)
 }
 #endif
 
-#ifdef CONFIG_MAC80211_RC_MINSTREL_HT
-int rc80211_minstrel_ht_init(void);
-void rc80211_minstrel_ht_exit(void);
-#else
-static inline int rc80211_minstrel_ht_init(void)
-{
-   return 0;
-}
-static inline void rc80211_minstrel_ht_exit(void)
-{
-}
-#endif
-
 
 #endif /* IEEE80211_RATE_H */
diff --git a/net/mac80211/rc80211_minstrel.c b/net/mac80211/rc80211_minstrel.c
index eac61242238a..dead57ba9eac 100644
--- a/net/mac80211/rc80211_minstrel.c
+++ b/net/mac80211/rc80211_minstrel.c
@@ -572,138 +572,6 @@ minstrel_rate_init(void *priv, struct 
ieee80211_supported_band *sband,
minstrel_update_rates(mp, mi);
 }
 
-static void *
-minstrel_alloc_sta(void *priv, struct ieee80211_sta *sta, gfp_t gfp)
-{
-   struct ieee80211_supported_band *sband;
-   struct minstrel_sta_info *mi;
-   struct minstrel_priv *mp = priv;
-   struct ieee80211_hw *hw = mp->hw;
-   int max_rates = 0;
-   int i;
-
-   mi = kzalloc(sizeof(struct minstrel_sta_info), gfp);
-   if (!mi)
-   return NULL;
-
- 

[PATCH 6/9] mac80211: minstrel: fix CCK rate group streams value

2018-10-06 Thread Felix Fietkau
Fixes a harmless underflow issue when CCK rates are actively being used

Signed-off-by: Felix Fietkau 
---
 net/mac80211/rc80211_minstrel_ht.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/net/mac80211/rc80211_minstrel_ht.c 
b/net/mac80211/rc80211_minstrel_ht.c
index 118ffe7f88c4..6cc28ca5d4a6 100644
--- a/net/mac80211/rc80211_minstrel_ht.c
+++ b/net/mac80211/rc80211_minstrel_ht.c
@@ -131,7 +131,7 @@
 
 #define CCK_GROUP(_s)  \
[MINSTREL_CCK_GROUP] = {\
-   .streams = 0,   \
+   .streams = 1,   \
.flags = 0, \
.shift = _s,\
.duration = {   \
-- 
2.17.0



[PATCH 2/9] mac80211: minstrel: remove unnecessary debugfs cleanup code

2018-10-06 Thread Felix Fietkau
debugfs entries are cleaned up by debugfs_remove_recursive already.

Signed-off-by: Felix Fietkau 
---
 net/mac80211/rc80211_minstrel.c|  8 ++--
 net/mac80211/rc80211_minstrel.h|  7 ---
 net/mac80211/rc80211_minstrel_debugfs.c| 18 +++---
 net/mac80211/rc80211_minstrel_ht.c |  1 -
 net/mac80211/rc80211_minstrel_ht.h |  5 -
 net/mac80211/rc80211_minstrel_ht_debugfs.c | 17 -
 6 files changed, 9 insertions(+), 47 deletions(-)

diff --git a/net/mac80211/rc80211_minstrel.c b/net/mac80211/rc80211_minstrel.c
index fc6134c01a76..eac61242238a 100644
--- a/net/mac80211/rc80211_minstrel.c
+++ b/net/mac80211/rc80211_minstrel.c
@@ -689,8 +689,8 @@ minstrel_alloc(struct ieee80211_hw *hw, struct dentry 
*debugfsdir)
 
 #ifdef CONFIG_MAC80211_DEBUGFS
mp->fixed_rate_idx = (u32) -1;
-   mp->dbg_fixed_rate = debugfs_create_u32("fixed_rate_idx",
-   0666, debugfsdir, >fixed_rate_idx);
+   debugfs_create_u32("fixed_rate_idx", 0666, debugfsdir,
+  >fixed_rate_idx);
 #endif
 
minstrel_init_cck_rates(mp);
@@ -701,9 +701,6 @@ minstrel_alloc(struct ieee80211_hw *hw, struct dentry 
*debugfsdir)
 static void
 minstrel_free(void *priv)
 {
-#ifdef CONFIG_MAC80211_DEBUGFS
-   debugfs_remove(((struct minstrel_priv *)priv)->dbg_fixed_rate);
-#endif
kfree(priv);
 }
 
@@ -735,7 +732,6 @@ const struct rate_control_ops mac80211_minstrel = {
.free_sta = minstrel_free_sta,
 #ifdef CONFIG_MAC80211_DEBUGFS
.add_sta_debugfs = minstrel_add_sta_debugfs,
-   .remove_sta_debugfs = minstrel_remove_sta_debugfs,
 #endif
.get_expected_throughput = minstrel_get_expected_throughput,
 };
diff --git a/net/mac80211/rc80211_minstrel.h b/net/mac80211/rc80211_minstrel.h
index be6c3f35f48b..6abe8bf603e2 100644
--- a/net/mac80211/rc80211_minstrel.h
+++ b/net/mac80211/rc80211_minstrel.h
@@ -109,11 +109,6 @@ struct minstrel_sta_info {
 
/* sampling table */
u8 *sample_table;
-
-#ifdef CONFIG_MAC80211_DEBUGFS
-   struct dentry *dbg_stats;
-   struct dentry *dbg_stats_csv;
-#endif
 };
 
 struct minstrel_priv {
@@ -137,7 +132,6 @@ struct minstrel_priv {
 *   - setting will be applied on next update
 */
u32 fixed_rate_idx;
-   struct dentry *dbg_fixed_rate;
 #endif
 };
 
@@ -156,7 +150,6 @@ minstrel_get_ewmsd10(struct minstrel_rate_stats *mrs)
 
 extern const struct rate_control_ops mac80211_minstrel;
 void minstrel_add_sta_debugfs(void *priv, void *priv_sta, struct dentry *dir);
-void minstrel_remove_sta_debugfs(void *priv, void *priv_sta);
 
 /* Recalculate success probabilities and counters for a given rate using EWMA 
*/
 void minstrel_calc_rate_stats(struct minstrel_rate_stats *mrs);
diff --git a/net/mac80211/rc80211_minstrel_debugfs.c 
b/net/mac80211/rc80211_minstrel_debugfs.c
index 9ad7d63d3e5b..2e7266b81b19 100644
--- a/net/mac80211/rc80211_minstrel_debugfs.c
+++ b/net/mac80211/rc80211_minstrel_debugfs.c
@@ -214,19 +214,7 @@ minstrel_add_sta_debugfs(void *priv, void *priv_sta, 
struct dentry *dir)
 {
struct minstrel_sta_info *mi = priv_sta;
 
-   mi->dbg_stats = debugfs_create_file("rc_stats", 0444, dir, mi,
-   _stat_fops);
-
-   mi->dbg_stats_csv = debugfs_create_file("rc_stats_csv", 0444, dir, mi,
-   _stat_csv_fops);
-}
-
-void
-minstrel_remove_sta_debugfs(void *priv, void *priv_sta)
-{
-   struct minstrel_sta_info *mi = priv_sta;
-
-   debugfs_remove(mi->dbg_stats);
-
-   debugfs_remove(mi->dbg_stats_csv);
+   debugfs_create_file("rc_stats", 0444, dir, mi, _stat_fops);
+   debugfs_create_file("rc_stats_csv", 0444, dir, mi,
+   _stat_csv_fops);
 }
diff --git a/net/mac80211/rc80211_minstrel_ht.c 
b/net/mac80211/rc80211_minstrel_ht.c
index 16d1ac30978d..818552ba61d0 100644
--- a/net/mac80211/rc80211_minstrel_ht.c
+++ b/net/mac80211/rc80211_minstrel_ht.c
@@ -1391,7 +1391,6 @@ static const struct rate_control_ops mac80211_minstrel_ht 
= {
.free = minstrel_ht_free,
 #ifdef CONFIG_MAC80211_DEBUGFS
.add_sta_debugfs = minstrel_ht_add_sta_debugfs,
-   .remove_sta_debugfs = minstrel_ht_remove_sta_debugfs,
 #endif
.get_expected_throughput = minstrel_ht_get_expected_throughput,
 };
diff --git a/net/mac80211/rc80211_minstrel_ht.h 
b/net/mac80211/rc80211_minstrel_ht.h
index de1646c42e82..50f2a8d004c4 100644
--- a/net/mac80211/rc80211_minstrel_ht.h
+++ b/net/mac80211/rc80211_minstrel_ht.h
@@ -110,17 +110,12 @@ struct minstrel_ht_sta_priv {
struct minstrel_ht_sta ht;
struct minstrel_sta_info legacy;
};
-#ifdef CONFIG_MAC80211_DEBUGFS
-   struct dentry *dbg_stats;
-   struct dentry *dbg_stats_csv;
-#endif
void *ratelist;
 

[PATCH 5/9] mac80211: minstrel: fix using short preamble CCK rates on HT clients

2018-10-06 Thread Felix Fietkau
mi->supported[MINSTREL_CCK_GROUP] needs to be updated
short preamble rates need to be marked as supported regardless of
whether it's currently enabled. Its state can change at any time without
a rate_update call.

Fixes: 782dda00ab8e ("mac80211: minstrel_ht: move short preamble check out of 
get_rate")
Signed-off-by: Felix Fietkau 
---
 net/mac80211/rc80211_minstrel_ht.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/net/mac80211/rc80211_minstrel_ht.c 
b/net/mac80211/rc80211_minstrel_ht.c
index 38e17ed20d41..118ffe7f88c4 100644
--- a/net/mac80211/rc80211_minstrel_ht.c
+++ b/net/mac80211/rc80211_minstrel_ht.c
@@ -1135,7 +1135,6 @@ minstrel_ht_update_caps(void *priv, struct 
ieee80211_supported_band *sband,
struct ieee80211_mcs_info *mcs = >ht_cap.mcs;
u16 ht_cap = sta->ht_cap.cap;
struct ieee80211_sta_vht_cap *vht_cap = >vht_cap;
-   struct sta_info *sinfo = container_of(sta, struct sta_info, sta);
int use_vht;
int n_supported = 0;
int ack_dur;
@@ -1265,8 +1264,7 @@ minstrel_ht_update_caps(void *priv, struct 
ieee80211_supported_band *sband,
if (!n_supported)
goto use_legacy;
 
-   if (test_sta_flag(sinfo, WLAN_STA_SHORT_PREAMBLE))
-   mi->cck_supported_short |= mi->cck_supported_short << 4;
+   mi->supported[MINSTREL_CCK_GROUP] |= mi->cck_supported_short << 4;
 
/* create an initial rate table with the lowest supported rates */
minstrel_ht_update_stats(mp, mi);
-- 
2.17.0



[PATCH 7/9] mac80211: minstrel: fix sampling/reporting of CCK rates in HT mode

2018-10-06 Thread Felix Fietkau
Long/short preamble selection cannot be sampled separately, since it
depends on the BSS state. Because of that, sampling attempts to
currently not used preamble modes are not counted in the statistics,
which leads to CCK rates being sampled too often.

Fix statistics accounting for long/short preamble by increasing the
index where necessary.
Fix excessive CCK rate sampling by dropping unsupported sample attempts.

This improves throughput on 2.4 GHz channels

Signed-off-by: Felix Fietkau 
---
 net/mac80211/rc80211_minstrel_ht.c | 14 ++
 1 file changed, 10 insertions(+), 4 deletions(-)

diff --git a/net/mac80211/rc80211_minstrel_ht.c 
b/net/mac80211/rc80211_minstrel_ht.c
index 6cc28ca5d4a6..fdcb4e9b4560 100644
--- a/net/mac80211/rc80211_minstrel_ht.c
+++ b/net/mac80211/rc80211_minstrel_ht.c
@@ -281,7 +281,8 @@ minstrel_ht_get_stats(struct minstrel_priv *mp, struct 
minstrel_ht_sta *mi,
break;
 
/* short preamble */
-   if (!(mi->supported[group] & BIT(idx)))
+   if ((mi->supported[group] & BIT(idx + 4)) &&
+   (rate->flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE))
idx += 4;
}
return >groups[group].rates[idx];
@@ -1080,18 +1081,23 @@ minstrel_ht_get_rate(void *priv, struct ieee80211_sta 
*sta, void *priv_sta,
return;
 
sample_group = _mcs_groups[sample_idx / MCS_GROUP_RATES];
+   sample_idx %= MCS_GROUP_RATES;
+
+   if (sample_group == _mcs_groups[MINSTREL_CCK_GROUP] &&
+   (sample_idx >= 4) != txrc->short_preamble)
+   return;
+
info->flags |= IEEE80211_TX_CTL_RATE_CTRL_PROBE;
rate->count = 1;
 
-   if (sample_idx / MCS_GROUP_RATES == MINSTREL_CCK_GROUP) {
+   if (sample_group == _mcs_groups[MINSTREL_CCK_GROUP]) {
int idx = sample_idx % ARRAY_SIZE(mp->cck_rates);
rate->idx = mp->cck_rates[idx];
} else if (sample_group->flags & IEEE80211_TX_RC_VHT_MCS) {
ieee80211_rate_set_vht(rate, sample_idx % MCS_GROUP_RATES,
   sample_group->streams);
} else {
-   rate->idx = sample_idx % MCS_GROUP_RATES +
-   (sample_group->streams - 1) * 8;
+   rate->idx = sample_idx + (sample_group->streams - 1) * 8;
}
 
rate->flags = sample_group->flags;
-- 
2.17.0



[PATCH 1/9] mac80211: minstrel: Enable STBC and LDPC for VHT Rates

2018-10-06 Thread Felix Fietkau
From: Chaitanya T K 

If peer support reception of STBC and LDPC, enable them for better
performance.

Signed-off-by: Chaitanya TK 
Signed-off-by: Felix Fietkau 
---
 include/linux/ieee80211.h  |  1 +
 net/mac80211/rc80211_minstrel_ht.c | 23 +++
 2 files changed, 16 insertions(+), 8 deletions(-)

diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h
index c4809ad8ab46..0ef67f837ae1 100644
--- a/include/linux/ieee80211.h
+++ b/include/linux/ieee80211.h
@@ -1670,6 +1670,7 @@ struct ieee80211_mu_edca_param_set {
 #define IEEE80211_VHT_CAP_RXSTBC_3 0x0300
 #define IEEE80211_VHT_CAP_RXSTBC_4 0x0400
 #define IEEE80211_VHT_CAP_RXSTBC_MASK  0x0700
+#define IEEE80211_VHT_CAP_RXSTBC_SHIFT 8
 #define IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE
0x0800
 #define IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE
0x1000
 #define IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT  13
diff --git a/net/mac80211/rc80211_minstrel_ht.c 
b/net/mac80211/rc80211_minstrel_ht.c
index 67ebdeaffbbc..16d1ac30978d 100644
--- a/net/mac80211/rc80211_minstrel_ht.c
+++ b/net/mac80211/rc80211_minstrel_ht.c
@@ -1130,7 +1130,7 @@ minstrel_ht_update_caps(void *priv, struct 
ieee80211_supported_band *sband,
struct minstrel_ht_sta_priv *msp = priv_sta;
struct minstrel_ht_sta *mi = >ht;
struct ieee80211_mcs_info *mcs = >ht_cap.mcs;
-   u16 sta_cap = sta->ht_cap.cap;
+   u16 ht_cap = sta->ht_cap.cap;
struct ieee80211_sta_vht_cap *vht_cap = >vht_cap;
struct sta_info *sinfo = container_of(sta, struct sta_info, sta);
int use_vht;
@@ -1138,6 +1138,7 @@ minstrel_ht_update_caps(void *priv, struct 
ieee80211_supported_band *sband,
int ack_dur;
int stbc;
int i;
+   bool ldpc;
 
/* fall back to the old minstrel for legacy stations */
if (!sta->ht_cap.ht_supported)
@@ -1175,16 +1176,22 @@ minstrel_ht_update_caps(void *priv, struct 
ieee80211_supported_band *sband,
}
mi->sample_tries = 4;
 
-   /* TODO tx_flags for vht - ATM the RC API is not fine-grained enough */
if (!use_vht) {
-   stbc = (sta_cap & IEEE80211_HT_CAP_RX_STBC) >>
+   stbc = (ht_cap & IEEE80211_HT_CAP_RX_STBC) >>
IEEE80211_HT_CAP_RX_STBC_SHIFT;
-   mi->tx_flags |= stbc << IEEE80211_TX_CTL_STBC_SHIFT;
 
-   if (sta_cap & IEEE80211_HT_CAP_LDPC_CODING)
-   mi->tx_flags |= IEEE80211_TX_CTL_LDPC;
+   ldpc = ht_cap & IEEE80211_HT_CAP_LDPC_CODING;
+   } else {
+   stbc = (vht_cap->cap & IEEE80211_VHT_CAP_RXSTBC_MASK) >>
+   IEEE80211_VHT_CAP_RXSTBC_SHIFT;
+
+   ldpc = vht_cap->cap & IEEE80211_VHT_CAP_RXLDPC;
}
 
+   mi->tx_flags |= stbc << IEEE80211_TX_CTL_STBC_SHIFT;
+   if (ldpc)
+   mi->tx_flags |= IEEE80211_TX_CTL_LDPC;
+
for (i = 0; i < ARRAY_SIZE(mi->groups); i++) {
u32 gflags = minstrel_mcs_groups[i].flags;
int bw, nss;
@@ -1197,10 +1204,10 @@ minstrel_ht_update_caps(void *priv, struct 
ieee80211_supported_band *sband,
 
if (gflags & IEEE80211_TX_RC_SHORT_GI) {
if (gflags & IEEE80211_TX_RC_40_MHZ_WIDTH) {
-   if (!(sta_cap & IEEE80211_HT_CAP_SGI_40))
+   if (!(ht_cap & IEEE80211_HT_CAP_SGI_40))
continue;
} else {
-   if (!(sta_cap & IEEE80211_HT_CAP_SGI_20))
+   if (!(ht_cap & IEEE80211_HT_CAP_SGI_20))
continue;
}
}
-- 
2.17.0



[PATCH 8/9] mac80211: minstrel: do not sample rates 3 times slower than max_prob_rate

2018-10-06 Thread Felix Fietkau
These rates are highly unlikely to be used quickly, even if the link
deteriorates rapidly. This improves throughput in cases where CCK rates
are not reliable enough to be skipped entirely during sampling.
Sampling these rates regularly can cost a lot of airtime.

Signed-off-by: Felix Fietkau 
---
 net/mac80211/rc80211_minstrel_ht.c | 10 ++
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/net/mac80211/rc80211_minstrel_ht.c 
b/net/mac80211/rc80211_minstrel_ht.c
index fdcb4e9b4560..f466ec37d161 100644
--- a/net/mac80211/rc80211_minstrel_ht.c
+++ b/net/mac80211/rc80211_minstrel_ht.c
@@ -1004,10 +1004,13 @@ minstrel_get_sample_rate(struct minstrel_priv *mp, 
struct minstrel_ht_sta *mi)
return -1;
 
/*
-* Do not sample if the probability is already higher than 95%
-* to avoid wasting airtime.
+* Do not sample if the probability is already higher than 95%,
+* or if the rate is 3 times slower than the current max probability
+* rate, to avoid wasting airtime.
 */
-   if (mrs->prob_ewma > MINSTREL_FRAC(95, 100))
+   sample_dur = minstrel_get_duration(sample_idx);
+   if (mrs->prob_ewma > MINSTREL_FRAC(95, 100) ||
+   minstrel_get_duration(mi->max_prob_rate) * 3 < sample_dur)
return -1;
 
/*
@@ -1017,7 +1020,6 @@ minstrel_get_sample_rate(struct minstrel_priv *mp, struct 
minstrel_ht_sta *mi)
 
cur_max_tp_streams = minstrel_mcs_groups[tp_rate1 /
MCS_GROUP_RATES].streams;
-   sample_dur = minstrel_get_duration(sample_idx);
if (sample_dur >= minstrel_get_duration(tp_rate2) &&
(cur_max_tp_streams - 1 <
 minstrel_mcs_groups[sample_group].streams ||
-- 
2.17.0



pull request: mt76 2018-10-05 v2

2018-10-06 Thread Felix Fietkau
Hi Kalle,

here's the fixed version of the previous pull request. I've dropped
the broken patch from the previous round.

- Felix

The following changes since commit e1c02eb16a9c742178874a7d1a08d300981715fb:

  qtnfmac: implement dump_station support for STA mode (2018-10-05 14:01:44 
+0300)

are available in the Git repository at:

  https://github.com/nbd168/wireless tags/mt76-for-kvalo-2018-10-05

for you to fetch changes up to 9b43960b899c71c758209a58c7e8d7d6e481e272:

  mt76: move irq handler in mt76x02-lib moudle (2018-10-05 20:05:46 +0200)


mt76 patches for 4.20

* unify code between mt76x0, mt76x2
* mt76x0 fixes
* another fix for rx buffer allocation regression on usb
* move mt76x2 source files to mt76x2 folder
* more work on mt76x0e support


Colin Ian King (1):
  mt76: fix header guard macro define names

Lorenzo Bianconi (30):
  mt76x0: pci: add mt76x0e_cleanup routine
  mt76x2: move mt76x2 source files to mt76x2 folder
  mt76: usb: fix hw initialization sequence
  mt76x0: usb: stop cal/mac workqueues at hw stop
  mt76: move mt76x02_tx_get_max_txpwr_adj in mt76x02_util.c
  mt76: add get_tx_txpwr_adj function pointer to mt76_driver_ops
  mt76: move mt76x02_mac_write_txwi in mt76x02-lib module
  mt76: usb: use mt76x02u_tx_prepare_skb to fill txwi
  mt76x0: init: remove unnecessary configurations
  mt76: move mt76x02_phy_get_min_avg_rssi in mt76x02_phy.c
  mt76: move mt76x02_rx_get_sta and mt76x02_rx_get_sta_wcid in 
mt76x02_util.h
  mt76x0: mac: use sta ewma estimation for rssi tracking
  mt76x0: remove unused variable in mt76x0_dev
  mt76x0: remove hw_atomic_mutex mutex in mt76x0_dev
  mt76x2: move mt76x2_dev in mt76x02_util.h
  mt76x0: merge mt76x0_dev in mt76x02_dev
  mt76: move mt76x02_mac_process_rx in mt76x02-lib module
  mt76: unify rxwi parsing between mt76x2 and mt76x0 drivers
  mt76: move mt76x02_tx in mt76x02-lib module
  mt76: move txrx shared routines in mt76x02_txrx.c
  mt76: rename mt76x02_util.h in mt76x02.h
  mt76x2: remove leftover function declatarions
  mt76: move tpc routines in mt76x02-lib module
  mt76: move mt76x02_tx_prepare_skb in mt76x02_txrx.c
  mt76: usb: move mt76x02u_tx_complete_skb in mt76x02_usb_core.c
  mt76: move mt76x02_mac_poll_tx_status in mt76x02-lib moudle
  mt76: move mt76x02_tx_complete in mt76x02-lib module
  mt76: use mt76x02_dev instead of mt76_dev in mt76x02_mmio.c
  mt76: move tx_tasklet management in mt76x02-lib moudle
  mt76: move irq handler in mt76x02-lib moudle

Stanislaw Gruszka (1):
  mt76: fix frag length allocation for usb

 drivers/net/wireless/mediatek/mt76/Kconfig |  
43 +-
 drivers/net/wireless/mediatek/mt76/Makefile|  
26 ++---
 drivers/net/wireless/mediatek/mt76/mt76.h  |   
6 +-
 drivers/net/wireless/mediatek/mt76/mt76x0/Kconfig  |  
20 +++
 drivers/net/wireless/mediatek/mt76/mt76x0/Makefile |   
2 +-
 drivers/net/wireless/mediatek/mt76/mt76x0/debugfs.c|   
4 +-
 drivers/net/wireless/mediatek/mt76/mt76x0/eeprom.c |  
28 -
 drivers/net/wireless/mediatek/mt76/mt76x0/eeprom.h |  
18 ++
 drivers/net/wireless/mediatek/mt76/mt76x0/init.c   |  
50 ++--
 drivers/net/wireless/mediatek/mt76/mt76x0/initvals.h   |   
3 +-
 drivers/net/wireless/mediatek/mt76/mt76x0/mac.c|  
82 +++---
 drivers/net/wireless/mediatek/mt76/mt76x0/mac.h|  
20 ---
 drivers/net/wireless/mediatek/mt76/mt76x0/main.c   |  
19 +++---
 drivers/net/wireless/mediatek/mt76/mt76x0/mcu.h|   
8 +--
 drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h | 
135 +++---
 drivers/net/wireless/mediatek/mt76/mt76x0/pci.c|  
44 +-
 drivers/net/wireless/mediatek/mt76/mt76x0/pci_mcu.c|   
4 +-
 drivers/net/wireless/mediatek/mt76/mt76x0/phy.c| 
112 +--
 drivers/net/wireless/mediatek/mt76/mt76x0/trace.h  |   
1 -
 drivers/net/wireless/mediatek/mt76/mt76x0/tx.c | 
101 
 drivers/net/wireless/mediatek/mt76/mt76x0/usb.c|  
68 +-
 drivers/net/wireless/mediatek/mt76/mt76x0/usb_mcu.c|   
6 +-
 drivers/net/wireless/mediatek/mt76/mt76x02.h   | 
208 

  1   2   3   4   5   6   7   >