2019-02-26 09:29:53

by Felix Fietkau

[permalink] [raw]
Subject: [PATCH 1/8] mt76: mt76x02: fix TSF sync mode

MT_BEACON_TIME_CFG_SYNC_MODE needs to be set for AP mode, according to the
documentation. For other modes it should be irrelevant in this case.

Signed-off-by: Felix Fietkau <[email protected]>
---
drivers/net/wireless/mediatek/mt76/mt76x02_util.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
index 11b5f664f5b1..7b9b1956111b 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
@@ -679,9 +679,9 @@ void mt76x02_init_beacon_config(struct mt76x02_dev *dev)
}

mt76_clear(dev, MT_BEACON_TIME_CFG, (MT_BEACON_TIME_CFG_TIMER_EN |
- MT_BEACON_TIME_CFG_SYNC_MODE |
MT_BEACON_TIME_CFG_TBTT_EN |
MT_BEACON_TIME_CFG_BEACON_TX));
+ mt76_set(dev, MT_BEACON_TIME_CFG, MT_BEACON_TIME_CFG_SYNC_MODE);
mt76_wr(dev, MT_BCN_BYPASS_MASK, 0xffff);

for (i = 0; i < 8; i++)
--
2.17.0



2019-02-26 09:29:49

by Felix Fietkau

[permalink] [raw]
Subject: [PATCH 7/8] mt76: mt76x2: unify mt76x2[u]_mac_resume

They are now the same and short enough to be turned into an inline function

Signed-off-by: Felix Fietkau <[email protected]>
---
drivers/net/wireless/mediatek/mt76/mt76x2/mac.h | 8 +++++++-
drivers/net/wireless/mediatek/mt76/mt76x2/mt76x2u.h | 1 -
drivers/net/wireless/mediatek/mt76/mt76x2/pci_init.c | 7 -------
drivers/net/wireless/mediatek/mt76/mt76x2/usb_mac.c | 7 -------
drivers/net/wireless/mediatek/mt76/mt76x2/usb_main.c | 2 +-
drivers/net/wireless/mediatek/mt76/mt76x2/usb_phy.c | 2 +-
6 files changed, 9 insertions(+), 18 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/mac.h b/drivers/net/wireless/mediatek/mt76/mt76x2/mac.h
index 4c8e20bce920..42ff221d7706 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x2/mac.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76x2/mac.h
@@ -25,6 +25,12 @@ struct mt76x02_vif;

int mt76x2_mac_start(struct mt76x02_dev *dev);
void mt76x2_mac_stop(struct mt76x02_dev *dev, bool force);
-void mt76x2_mac_resume(struct mt76x02_dev *dev);
+
+static inline void mt76x2_mac_resume(struct mt76x02_dev *dev)
+{
+ mt76_wr(dev, MT_MAC_SYS_CTRL,
+ MT_MAC_SYS_CTRL_ENABLE_TX |
+ MT_MAC_SYS_CTRL_ENABLE_RX);
+}

#endif
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/mt76x2u.h b/drivers/net/wireless/mediatek/mt76/mt76x2/mt76x2u.h
index 787cdfdf5db5..76cb1f84eff5 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x2/mt76x2u.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76x2/mt76x2u.h
@@ -35,7 +35,6 @@ void mt76x2u_cleanup(struct mt76x02_dev *dev);
void mt76x2u_stop_hw(struct mt76x02_dev *dev);

int mt76x2u_mac_reset(struct mt76x02_dev *dev);
-void mt76x2u_mac_resume(struct mt76x02_dev *dev);
int mt76x2u_mac_start(struct mt76x02_dev *dev);
int mt76x2u_mac_stop(struct mt76x02_dev *dev);

diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/pci_init.c b/drivers/net/wireless/mediatek/mt76/mt76x2/pci_init.c
index d4e3d7c11d74..984d9c4c2e1a 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x2/pci_init.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x2/pci_init.c
@@ -173,13 +173,6 @@ int mt76x2_mac_start(struct mt76x02_dev *dev)
return 0;
}

-void mt76x2_mac_resume(struct mt76x02_dev *dev)
-{
- mt76_wr(dev, MT_MAC_SYS_CTRL,
- MT_MAC_SYS_CTRL_ENABLE_TX |
- MT_MAC_SYS_CTRL_ENABLE_RX);
-}
-
static void
mt76x2_power_on_rf_patch(struct mt76x02_dev *dev)
{
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/usb_mac.c b/drivers/net/wireless/mediatek/mt76/mt76x2/usb_mac.c
index 361eb4fb979d..5e84b4535cb1 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x2/usb_mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x2/usb_mac.c
@@ -211,10 +211,3 @@ int mt76x2u_mac_stop(struct mt76x02_dev *dev)

return 0;
}
-
-void mt76x2u_mac_resume(struct mt76x02_dev *dev)
-{
- mt76_wr(dev, MT_MAC_SYS_CTRL,
- MT_MAC_SYS_CTRL_ENABLE_TX |
- MT_MAC_SYS_CTRL_ENABLE_RX);
-}
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/usb_main.c b/drivers/net/wireless/mediatek/mt76/mt76x2/usb_main.c
index 9b438adfc56c..2ac78e4dc41a 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x2/usb_main.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x2/usb_main.c
@@ -61,7 +61,7 @@ mt76x2u_set_channel(struct mt76x02_dev *dev,

err = mt76x2u_phy_set_channel(dev, chandef);

- mt76x2u_mac_resume(dev);
+ mt76x2_mac_resume(dev);
mt76x02_edcca_init(dev, true);

clear_bit(MT76_RESET, &dev->mt76.state);
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/usb_phy.c b/drivers/net/wireless/mediatek/mt76/mt76x2/usb_phy.c
index c8b4a17302da..07f67cb6854c 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x2/usb_phy.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x2/usb_phy.c
@@ -43,7 +43,7 @@ mt76x2u_phy_channel_calibrate(struct mt76x02_dev *dev, bool mac_stopped)
mt76x02_mcu_calibrate(dev, MCU_CAL_TX_SHAPING, 0);

if (!mac_stopped)
- mt76x2u_mac_resume(dev);
+ mt76x2_mac_resume(dev);
mt76x2_apply_gain_adj(dev);
mt76x02_edcca_init(dev, true);

--
2.17.0


2019-02-26 09:29:49

by Felix Fietkau

[permalink] [raw]
Subject: [PATCH 3/8] mt76: mt76x02: fix beacon timer issue

When mt76x0 and mt76x2 beacon code was unified, it changed the order in which
beacon enable and beacon interval are configured.
Configuring beacon enable before beacon interval can in some cases cause
problems with the beacon timer, leading to clients not waking up properly
from powersave mode.
Fix this by changing the order back to interval first, then enable.

Fixes: cc726268e4dce ("mt76: move mt76x02_bss_info_changed in mt76x02-lib module")
Cc: [email protected]
Signed-off-by: Felix Fietkau <[email protected]>
---
drivers/net/wireless/mediatek/mt76/mt76x02_util.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
index 7b9b1956111b..2e899d30e00d 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
@@ -704,9 +704,6 @@ void mt76x02_bss_info_changed(struct ieee80211_hw *hw,
if (changed & BSS_CHANGED_BSSID)
mt76x02_mac_set_bssid(dev, mvif->idx, info->bssid);

- if (changed & BSS_CHANGED_BEACON_ENABLED)
- mt76x02_mac_set_beacon_enable(dev, vif, info->enable_beacon);
-
if (changed & BSS_CHANGED_HT || changed & BSS_CHANGED_ERP_CTS_PROT)
mt76x02_mac_set_tx_protection(dev, info->use_cts_prot,
info->ht_operation_mode);
@@ -719,6 +716,9 @@ void mt76x02_bss_info_changed(struct ieee80211_hw *hw,
dev->tbtt_count = 0;
}

+ if (changed & BSS_CHANGED_BEACON_ENABLED)
+ mt76x02_mac_set_beacon_enable(dev, vif, info->enable_beacon);
+
if (changed & BSS_CHANGED_ERP_PREAMBLE)
mt76x02_mac_set_short_preamble(dev, info->use_short_preamble);

--
2.17.0


2019-02-26 09:29:49

by Felix Fietkau

[permalink] [raw]
Subject: [PATCH 5/8] mt76: mt76x02: issue watchdog reset on MCU request timeout

MCU request timeout usually indicates that the device is no longer responsive,
and it usually does not recover without a reset

Signed-off-by: Felix Fietkau <[email protected]>
---
drivers/net/wireless/mediatek/mt76/mt76x02.h | 1 +
.../net/wireless/mediatek/mt76/mt76x02_mcu.c | 1 +
.../net/wireless/mediatek/mt76/mt76x02_mmio.c | 28 +++++++++++++------
3 files changed, 21 insertions(+), 9 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02.h b/drivers/net/wireless/mediatek/mt76/mt76x02.h
index 3464b4ca2ea8..6915cce5def9 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02.h
@@ -98,6 +98,7 @@ struct mt76x02_dev {

u32 tx_hang_reset;
u8 tx_hang_check;
+ u8 mcu_timeout;

struct mt76x02_calibration cal;

diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_mcu.c b/drivers/net/wireless/mediatek/mt76/mt76x02_mcu.c
index 4752c104abf3..6501b853b65c 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_mcu.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_mcu.c
@@ -61,6 +61,7 @@ int mt76x02_mcu_msg_send(struct mt76_dev *mdev, int cmd, const void *data,
"MCU message %d (seq %d) timed out\n", cmd,
seq);
ret = -ETIMEDOUT;
+ dev->mcu_timeout = 1;
break;
}

diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c b/drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c
index f0198eea2bb8..1229f19f2b02 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c
@@ -494,18 +494,28 @@ static void mt76x02_watchdog_reset(struct mt76x02_dev *dev)
static void mt76x02_check_tx_hang(struct mt76x02_dev *dev)
{
if (mt76x02_tx_hang(dev)) {
- if (++dev->tx_hang_check < MT_TX_HANG_TH)
- return;
-
- mt76x02_watchdog_reset(dev);
-
- dev->tx_hang_reset++;
- dev->tx_hang_check = 0;
- memset(dev->mt76.tx_dma_idx, 0xff,
- sizeof(dev->mt76.tx_dma_idx));
+ if (++dev->tx_hang_check >= MT_TX_HANG_TH)
+ goto restart;
} else {
dev->tx_hang_check = 0;
}
+
+ if (dev->mcu_timeout)
+ goto restart;
+
+ return;
+
+restart:
+ mt76x02_watchdog_reset(dev);
+
+ mutex_lock(&dev->mt76.mmio.mcu.mutex);
+ dev->mcu_timeout = 0;
+ mutex_unlock(&dev->mt76.mmio.mcu.mutex);
+
+ dev->tx_hang_reset++;
+ dev->tx_hang_check = 0;
+ memset(dev->mt76.tx_dma_idx, 0xff,
+ sizeof(dev->mt76.tx_dma_idx));
}

void mt76x02_wdt_work(struct work_struct *work)
--
2.17.0


2019-02-26 09:29:51

by Felix Fietkau

[permalink] [raw]
Subject: [PATCH 6/8] mt76: mt76x02: fix ED/CCA enabling/disabling

ED/CCA needs to be disable before stopping the MAC to avoid hangs from tx
being blocked. It must only be enabled again after the MAC has been started
again.
In many places this wasn't done properly, so fix this by always clearing
the relevant ED/CCA bits in mt76x2_mac_stop and set it up again after
channel change or calibration is done

Signed-off-by: Felix Fietkau <[email protected]>
---
drivers/net/wireless/mediatek/mt76/mt76x0/init.c | 2 ++
drivers/net/wireless/mediatek/mt76/mt76x0/main.c | 2 ++
drivers/net/wireless/mediatek/mt76/mt76x0/phy.c | 6 +-----
drivers/net/wireless/mediatek/mt76/mt76x2/mac.c | 3 +++
drivers/net/wireless/mediatek/mt76/mt76x2/pci_phy.c | 7 ++-----
drivers/net/wireless/mediatek/mt76/mt76x2/usb_mac.c | 6 ++----
drivers/net/wireless/mediatek/mt76/mt76x2/usb_main.c | 3 +--
drivers/net/wireless/mediatek/mt76/mt76x2/usb_phy.c | 1 +
8 files changed, 14 insertions(+), 16 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/init.c b/drivers/net/wireless/mediatek/mt76/mt76x0/init.c
index a529ce111c20..bcb72e019fd2 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x0/init.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x0/init.c
@@ -187,6 +187,8 @@ void mt76x0_mac_stop(struct mt76x02_dev *dev)
{
int i = 200, ok = 0;

+ mt76_clear(dev, MT_TXOP_CTRL_CFG, MT_TXOP_ED_CCA_EN);
+
/* Page count on TxQ */
while (i-- && ((mt76_rr(dev, 0x0438) & 0xffffffff) ||
(mt76_rr(dev, 0x0a30) & 0x000000ff) ||
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/main.c b/drivers/net/wireless/mediatek/mt76/mt76x0/main.c
index a803a9b6a4c5..fee16ab21edb 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x0/main.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x0/main.c
@@ -34,6 +34,8 @@ mt76x0_set_channel(struct mt76x02_dev *dev, struct cfg80211_chan_def *chandef)
mt76_rr(dev, MT_CH_IDLE);
mt76_rr(dev, MT_CH_BUSY);

+ mt76x02_edcca_init(dev, true);
+
if (mt76_is_mmio(dev)) {
mt76x02_dfs_init_params(dev);
tasklet_enable(&dev->pre_tbtt_tasklet);
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/phy.c b/drivers/net/wireless/mediatek/mt76/mt76x0/phy.c
index 3467a32f5fda..1fd22eb841c3 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x0/phy.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x0/phy.c
@@ -1007,17 +1007,13 @@ int mt76x0_phy_set_channel(struct mt76x02_dev *dev,

/* enable vco */
mt76x0_rf_set(dev, MT_RF(0, 4), BIT(7));
- if (scan) {
- mt76x02_edcca_init(dev, false);
+ if (scan)
return 0;
- }

mt76x02_init_agc_gain(dev);
mt76x0_phy_calibrate(dev, false);
mt76x0_phy_set_txpower(dev);

- mt76x02_edcca_init(dev, true);
-
ieee80211_queue_delayed_work(dev->mt76.hw, &dev->cal_work,
MT_CALIBRATE_INTERVAL);

diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/mac.c b/drivers/net/wireless/mediatek/mt76/mt76x2/mac.c
index e25905c91ee2..e99d4c9bd428 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x2/mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x2/mac.c
@@ -23,6 +23,9 @@ void mt76x2_mac_stop(struct mt76x02_dev *dev, bool force)
u32 rts_cfg;
int i;

+ mt76_clear(dev, MT_TXOP_CTRL_CFG, MT_TXOP_ED_CCA_EN);
+ mt76_clear(dev, MT_TXOP_HLDR_ET, MT_TXOP_HLDR_TX40M_BLK_EN);
+
mt76_wr(dev, MT_MAC_SYS_CTRL, 0);

rts_cfg = mt76_rr(dev, MT_TX_RTS_CFG);
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/pci_phy.c b/drivers/net/wireless/mediatek/mt76/mt76x2/pci_phy.c
index 97ec575699d0..cc1aebcb0696 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x2/pci_phy.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x2/pci_phy.c
@@ -74,6 +74,7 @@ mt76x2_phy_channel_calibrate(struct mt76x02_dev *dev, bool mac_stopped)
mt76x2_mac_resume(dev);

mt76x2_apply_gain_adj(dev);
+ mt76x02_edcca_init(dev, true);

dev->cal.channel_cal_done = true;
}
@@ -240,10 +241,8 @@ int mt76x2_phy_set_channel(struct mt76x02_dev *dev,
mt76_wr(dev, MT_BBP(AGC, 2), 0x00007070);
mt76_wr(dev, MT_TXOP_CTRL_CFG, 0x04101B3F);

- if (scan) {
- mt76x02_edcca_init(dev, false);
+ if (scan)
return 0;
- }

mt76x2_phy_channel_calibrate(dev, true);
mt76x02_init_agc_gain(dev);
@@ -256,8 +255,6 @@ int mt76x2_phy_set_channel(struct mt76x02_dev *dev,
0x38);
}

- mt76x02_edcca_init(dev, true);
-
ieee80211_queue_delayed_work(mt76_hw(dev), &dev->cal_work,
MT_CALIBRATE_INTERVAL);

diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/usb_mac.c b/drivers/net/wireless/mediatek/mt76/mt76x2/usb_mac.c
index db2194a92e67..361eb4fb979d 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x2/usb_mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x2/usb_mac.c
@@ -143,8 +143,8 @@ int mt76x2u_mac_stop(struct mt76x02_dev *dev)
rts_cfg = mt76_rr(dev, MT_TX_RTS_CFG);
mt76_wr(dev, MT_TX_RTS_CFG, rts_cfg & ~MT_TX_RTS_CFG_RETRY_LIMIT);

- mt76_clear(dev, MT_TXOP_CTRL_CFG, BIT(20));
- mt76_clear(dev, MT_TXOP_HLDR_ET, BIT(1));
+ mt76_clear(dev, MT_TXOP_CTRL_CFG, MT_TXOP_ED_CCA_EN);
+ mt76_clear(dev, MT_TXOP_HLDR_ET, MT_TXOP_HLDR_TX40M_BLK_EN);

/* wait tx dma to stop */
for (i = 0; i < 2000; i++) {
@@ -217,6 +217,4 @@ void mt76x2u_mac_resume(struct mt76x02_dev *dev)
mt76_wr(dev, MT_MAC_SYS_CTRL,
MT_MAC_SYS_CTRL_ENABLE_TX |
MT_MAC_SYS_CTRL_ENABLE_RX);
- mt76_set(dev, MT_TXOP_CTRL_CFG, BIT(20));
- mt76_set(dev, MT_TXOP_HLDR_ET, BIT(1));
}
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/usb_main.c b/drivers/net/wireless/mediatek/mt76/mt76x2/usb_main.c
index 10633b8de8e8..9b438adfc56c 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x2/usb_main.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x2/usb_main.c
@@ -57,13 +57,12 @@ mt76x2u_set_channel(struct mt76x02_dev *dev,

mt76_set_channel(&dev->mt76);

- mt76_clear(dev, MT_TXOP_CTRL_CFG, BIT(20));
- mt76_clear(dev, MT_TXOP_HLDR_ET, BIT(1));
mt76x2_mac_stop(dev, false);

err = mt76x2u_phy_set_channel(dev, chandef);

mt76x2u_mac_resume(dev);
+ mt76x02_edcca_init(dev, true);

clear_bit(MT76_RESET, &dev->mt76.state);
mt76_txq_schedule_all(&dev->mt76);
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/usb_phy.c b/drivers/net/wireless/mediatek/mt76/mt76x2/usb_phy.c
index 11d414d86c68..c8b4a17302da 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x2/usb_phy.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x2/usb_phy.c
@@ -45,6 +45,7 @@ mt76x2u_phy_channel_calibrate(struct mt76x02_dev *dev, bool mac_stopped)
if (!mac_stopped)
mt76x2u_mac_resume(dev);
mt76x2_apply_gain_adj(dev);
+ mt76x02_edcca_init(dev, true);

dev->cal.channel_cal_done = true;
}
--
2.17.0


2019-02-26 09:29:53

by Felix Fietkau

[permalink] [raw]
Subject: [PATCH 4/8] mt76: mt76x02: only reset beacon drift counter when enabling beacons

When the timer is already running, there is no need to reset the counter,
because the drift will remain the same.

Signed-off-by: Felix Fietkau <[email protected]>
---
drivers/net/wireless/mediatek/mt76/mt76x02_mac.c | 3 +++
drivers/net/wireless/mediatek/mt76/mt76x02_util.c | 1 -
2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
index be2979f34f31..82b178fa83bb 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
@@ -1126,6 +1126,9 @@ void mt76x02_mac_set_beacon_enable(struct mt76x02_dev *dev,
else if (val)
skb = ieee80211_beacon_get(mt76_hw(dev), vif);

+ if (!dev->beacon_mask)
+ dev->tbtt_count = 0;
+
__mt76x02_mac_set_beacon_enable(dev, vif_idx, val, skb);

if (mt76_is_mmio(dev))
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
index 2e899d30e00d..a48c261b0c63 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
@@ -713,7 +713,6 @@ void mt76x02_bss_info_changed(struct ieee80211_hw *hw,
MT_BEACON_TIME_CFG_INTVAL,
info->beacon_int << 4);
dev->beacon_int = info->beacon_int;
- dev->tbtt_count = 0;
}

if (changed & BSS_CHANGED_BEACON_ENABLED)
--
2.17.0


2019-02-26 09:29:55

by Felix Fietkau

[permalink] [raw]
Subject: [PATCH 2/8] mt76: mt76x02: fix beacon timer drift adjustment

Check the count before incrementing it to match vendor code behavior.
This defers the adjustment by one more tick, which should improve accuracy

Signed-off-by: Felix Fietkau <[email protected]>
---
drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c b/drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c
index 374bc9d91f12..f0198eea2bb8 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c
@@ -79,24 +79,24 @@ mt76x02_resync_beacon_timer(struct mt76x02_dev *dev)
* Beacon timer drifts by 1us every tick, the timer is configured
* in 1/16 TU (64us) units.
*/
- if (dev->tbtt_count < 62)
+ if (dev->tbtt_count < 63)
return;

- if (dev->tbtt_count >= 64) {
- dev->tbtt_count = 0;
- return;
- }
-
/*
* The updated beacon interval takes effect after two TBTT, because
* at this point the original interval has already been loaded into
* the next TBTT_TIMER value
*/
- if (dev->tbtt_count == 62)
+ if (dev->tbtt_count == 63)
timer_val -= 1;

mt76_rmw_field(dev, MT_BEACON_TIME_CFG,
MT_BEACON_TIME_CFG_INTVAL, timer_val);
+
+ if (dev->tbtt_count >= 64) {
+ dev->tbtt_count = 0;
+ return;
+ }
}

static void mt76x02_pre_tbtt_tasklet(unsigned long arg)
--
2.17.0


2019-02-26 09:29:56

by Felix Fietkau

[permalink] [raw]
Subject: [PATCH 8/8] mt76: mt76x02: set MT_TXOP_HLDR_TX40M_BLK_EN for mt76x2

It needs to be always enabled for 76x2 and conditionally enabled/disabled
for 76x0. Since mt76x2_mac_stop clears this bit, ensure that it is enabled
in mt76x02_edcca_init

Signed-off-by: Felix Fietkau <[email protected]>
---
drivers/net/wireless/mediatek/mt76/mt76x02_mac.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
index 82b178fa83bb..91ff6598eccf 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
@@ -905,14 +905,14 @@ void mt76x02_edcca_init(struct mt76x02_dev *dev, bool enable)
mt76_set(dev, MT_TXOP_CTRL_CFG, MT_TXOP_ED_CCA_EN);
mt76_rmw(dev, MT_BBP(AGC, 2), GENMASK(15, 0),
ed_th << 8 | ed_th);
- if (!is_mt76x2(dev))
- mt76_set(dev, MT_TXOP_HLDR_ET,
- MT_TXOP_HLDR_TX40M_BLK_EN);
+ mt76_set(dev, MT_TXOP_HLDR_ET, MT_TXOP_HLDR_TX40M_BLK_EN);
} else {
mt76_set(dev, MT_TX_LINK_CFG, MT_TX_CFACK_EN);
mt76_clear(dev, MT_TXOP_CTRL_CFG, MT_TXOP_ED_CCA_EN);
if (is_mt76x2(dev)) {
mt76_wr(dev, MT_BBP(AGC, 2), 0x00007070);
+ mt76_set(dev, MT_TXOP_HLDR_ET,
+ MT_TXOP_HLDR_TX40M_BLK_EN);
} else {
mt76_wr(dev, MT_BBP(AGC, 2), 0x003a6464);
mt76_clear(dev, MT_TXOP_HLDR_ET,
--
2.17.0