2021-09-23 14:31:27

by Lorenzo Bianconi

[permalink] [raw]
Subject: [PATCH v5 0/5] introduce individual TWT support in AP mode

Introduce TWT action frames parsing support to mac80211.
Currently just individual TWT agreement are support in AP mode.
Whenever the AP receives a TWT action frame from an associated client,
after performing sanity checks, it will notify the underlay driver with
requested parameters in order to check if they are supported and if there
is enough room for a new agreement. The hw is expected to set agreement
result and report it to mac80211.
The two following drv callbacks have been added to mac80211:
- add_twt_setup (mandatory)
- twt_teardown_request (optional)

mac80211 will send an action frame reply according to the result
reported by the driver/fw.
Add individual TWT support to mt7915 in AP mode.

Changes since v4:
- drop mac80211 patches since they are already applied
- fix table_id configuration

Changes since v3:
- move twt_setup status management in ieee80211_report_used_skb() in order to
consider when the driver drops the frame on the tx path
- minor changes

Changes since v2:
- introduce status_queue for twt status frame parsing
- add tracing for add_twt_setup/twt_teardown_request
- fix routine naming convention
- always reply with reject frames for broadcast agrt requests

Changes since v1:
- fix rcu unbalance in mt7915/debugfs.c

Changes since rfc:
- run ieee80211_s1g_status_h_twt only for failed twt action frames
- change add_twt_setup return value from int to void

Lorenzo Bianconi (5):
mt76: mt7915: introduce __mt7915_get_tsf routine
mt76: mt7915: introduce mt7915_mcu_twt_agrt_update mcu command
mt76: mt7915: introduce mt7915_mac_add_twt_setup routine
mt76: mt7915: enable twt responder capability
mt76: mt7915: add twt_stats knob in debugfs

.../wireless/mediatek/mt76/mt7915/debugfs.c | 28 +++
.../net/wireless/mediatek/mt76/mt7915/init.c | 3 +
.../net/wireless/mediatek/mt76/mt7915/mac.c | 179 ++++++++++++++++++
.../net/wireless/mediatek/mt76/mt7915/main.c | 39 +++-
.../net/wireless/mediatek/mt76/mt7915/mcu.c | 50 +++++
.../net/wireless/mediatek/mt76/mt7915/mcu.h | 9 +
.../wireless/mediatek/mt76/mt7915/mt7915.h | 42 +++-
7 files changed, 344 insertions(+), 6 deletions(-)

--
2.31.1


2021-09-23 14:31:36

by Lorenzo Bianconi

[permalink] [raw]
Subject: [PATCH v5 5/5] mt76: mt7915: add twt_stats knob in debugfs

Introduce twt_stats knob in debugfs in order to dump established
agreements

Tested-by: Peter Chiu <[email protected]>
Tested-by: Evelyn Tsai <[email protected]>
Signed-off-by: Lorenzo Bianconi <[email protected]>
---
.../wireless/mediatek/mt76/mt7915/debugfs.c | 28 +++++++++++++++++++
1 file changed, 28 insertions(+)

diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c b/drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c
index e1cdfbe52199..1fd4861f17c4 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c
@@ -335,6 +335,32 @@ mt7915_read_rate_txpower(struct seq_file *s, void *data)
return 0;
}

+static int
+mt7915_twt_stats(struct seq_file *s, void *data)
+{
+ struct mt7915_dev *dev = dev_get_drvdata(s->private);
+ struct mt7915_twt_flow *iter;
+
+ rcu_read_lock();
+
+ seq_puts(s, " wcid | id | flags | exp | mantissa");
+ seq_puts(s, " | duration | tsf |\n");
+ list_for_each_entry_rcu(iter, &dev->twt_list, list)
+ seq_printf(s,
+ "%9d | %8d | %5c%c%c%c | %8d | %8d | %8d | %14lld |\n",
+ iter->wcid, iter->id,
+ iter->sched ? 's' : 'u',
+ iter->protection ? 'p' : '-',
+ iter->trigger ? 't' : '-',
+ iter->flowtype ? '-' : 'a',
+ iter->exp, iter->mantissa,
+ iter->duration, iter->tsf);
+
+ rcu_read_unlock();
+
+ return 0;
+}
+
int mt7915_init_debugfs(struct mt7915_dev *dev)
{
struct dentry *dir;
@@ -352,6 +378,8 @@ int mt7915_init_debugfs(struct mt7915_dev *dev)
debugfs_create_file("implicit_txbf", 0600, dir, dev,
&fops_implicit_txbf);
debugfs_create_u32("dfs_hw_pattern", 0400, dir, &dev->hw_pattern);
+ debugfs_create_devm_seqfile(dev->mt76.dev, "twt_stats", dir,
+ mt7915_twt_stats);
/* test knobs */
debugfs_create_file("radar_trigger", 0200, dir, dev,
&fops_radar_trigger);
--
2.31.1

2021-09-23 14:32:51

by Lorenzo Bianconi

[permalink] [raw]
Subject: [PATCH v5 2/5] mt76: mt7915: introduce mt7915_mcu_twt_agrt_update mcu command

This is a preliminary patch to add TWT support to mt7915

Tested-by: Peter Chiu <[email protected]>
Tested-by: Evelyn Tsai <[email protected]>
Signed-off-by: Lorenzo Bianconi <[email protected]>
---
.../net/wireless/mediatek/mt76/mt7915/mcu.c | 50 +++++++++++++++++++
.../net/wireless/mediatek/mt76/mt7915/mcu.h | 9 ++++
.../wireless/mediatek/mt76/mt7915/mt7915.h | 20 ++++++++
3 files changed, 79 insertions(+)

diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c
index 39cba8210242..77d645268c9f 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c
@@ -3966,3 +3966,53 @@ int mt7915_mcu_get_rx_rate(struct mt7915_phy *phy, struct ieee80211_vif *vif,

return ret;
}
+
+#define TWT_AGRT_TRIGGER BIT(0)
+#define TWT_AGRT_ANNOUNCE BIT(1)
+#define TWT_AGRT_PROTECT BIT(2)
+
+int mt7915_mcu_twt_agrt_update(struct mt7915_dev *dev,
+ struct mt7915_vif *mvif,
+ struct mt7915_twt_flow *flow,
+ int cmd)
+{
+ struct {
+ u8 tbl_idx;
+ u8 cmd;
+ u8 own_mac_idx;
+ u8 flowid; /* 0xff for group id */
+ __le16 peer_id; /* specify the peer_id (msb=0)
+ * or group_id (msb=1)
+ */
+ u8 duration; /* 256 us */
+ u8 bss_idx;
+ __le64 start_tsf;
+ __le16 mantissa;
+ u8 exponent;
+ u8 is_ap;
+ u8 agrt_params;
+ u8 rsv[23];
+ } __packed req = {
+ .tbl_idx = flow->table_id,
+ .cmd = cmd,
+ .own_mac_idx = mvif->omac_idx,
+ .flowid = flow->id,
+ .peer_id = cpu_to_le16(flow->wcid),
+ .duration = flow->duration,
+ .bss_idx = mvif->idx,
+ .start_tsf = cpu_to_le64(flow->tsf),
+ .mantissa = flow->mantissa,
+ .exponent = flow->exp,
+ .is_ap = true,
+ };
+
+ if (flow->protection)
+ req.agrt_params |= TWT_AGRT_PROTECT;
+ if (!flow->flowtype)
+ req.agrt_params |= TWT_AGRT_ANNOUNCE;
+ if (flow->trigger)
+ req.agrt_params |= TWT_AGRT_TRIGGER;
+
+ return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(TWT_AGRT_UPDATE),
+ &req, sizeof(req), true);
+}
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.h b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.h
index 9e966cfcf5a2..877c6d81dbf2 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.h
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.h
@@ -275,6 +275,7 @@ enum {
MCU_EXT_CMD_MWDS_SUPPORT = 0x80,
MCU_EXT_CMD_SET_SER_TRIGGER = 0x81,
MCU_EXT_CMD_SCS_CTRL = 0x82,
+ MCU_EXT_CMD_TWT_AGRT_UPDATE = 0x94,
MCU_EXT_CMD_FW_DBG_CTRL = 0x95,
MCU_EXT_CMD_SET_RDD_TH = 0x9d,
MCU_EXT_CMD_MURU_CTRL = 0x9f,
@@ -284,6 +285,14 @@ enum {
MCU_EXT_CMD_PHY_STAT_INFO = 0xad,
};

+enum {
+ MCU_TWT_AGRT_ADD,
+ MCU_TWT_AGRT_MODIFY,
+ MCU_TWT_AGRT_DELETE,
+ MCU_TWT_AGRT_TEARDOWN,
+ MCU_TWT_AGRT_GET_TSF,
+};
+
enum {
MCU_WA_PARAM_CMD_QUERY,
MCU_WA_PARAM_CMD_SET,
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h b/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h
index 5367b92de864..1256c6df4b6c 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h
@@ -67,6 +67,22 @@ struct mt7915_sta_key_conf {
u8 key[16];
};

+struct mt7915_twt_flow {
+ struct list_head list;
+ u64 start_tsf;
+ u64 tsf;
+ u32 duration;
+ u16 wcid;
+ __le16 mantissa;
+ u8 exp;
+ u8 table_id;
+ u8 id;
+ u8 protection:1;
+ u8 flowtype:1;
+ u8 trigger:1;
+ u8 sched:1;
+};
+
struct mt7915_sta {
struct mt76_wcid wcid; /* must be first */

@@ -286,6 +302,10 @@ int mt7915_dma_init(struct mt7915_dev *dev);
void mt7915_dma_prefetch(struct mt7915_dev *dev);
void mt7915_dma_cleanup(struct mt7915_dev *dev);
int mt7915_mcu_init(struct mt7915_dev *dev);
+int mt7915_mcu_twt_agrt_update(struct mt7915_dev *dev,
+ struct mt7915_vif *mvif,
+ struct mt7915_twt_flow *flow,
+ int cmd);
int mt7915_mcu_add_dev_info(struct mt7915_phy *phy,
struct ieee80211_vif *vif, bool enable);
int mt7915_mcu_add_bss_info(struct mt7915_phy *phy,
--
2.31.1

2021-09-23 14:32:51

by Lorenzo Bianconi

[permalink] [raw]
Subject: [PATCH v5 1/5] mt76: mt7915: introduce __mt7915_get_tsf routine

Introduce an unlocked verion of mt7915_get_tsf routine.
This is a preliminary patch to add TWT support to mt7915.

Tested-by: Peter Chiu <[email protected]>
Tested-by: Evelyn Tsai <[email protected]>
Signed-off-by: Lorenzo Bianconi <[email protected]>
---
.../net/wireless/mediatek/mt76/mt7915/main.c | 20 ++++++++++++++-----
.../wireless/mediatek/mt76/mt7915/mt7915.h | 2 +-
2 files changed, 16 insertions(+), 6 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/main.c b/drivers/net/wireless/mediatek/mt76/mt7915/main.c
index 0aea6272fd14..e2d876c96616 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/main.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/main.c
@@ -792,10 +792,8 @@ mt7915_get_stats(struct ieee80211_hw *hw,
return 0;
}

-static u64
-mt7915_get_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
+u64 __mt7915_get_tsf(struct ieee80211_hw *hw, struct mt7915_vif *mvif)
{
- struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv;
struct mt7915_dev *dev = mt7915_hw_dev(hw);
struct mt7915_phy *phy = mt7915_hw_phy(hw);
bool band = phy != &dev->phy;
@@ -805,7 +803,7 @@ mt7915_get_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
} tsf;
u16 n;

- mutex_lock(&dev->mt76.mutex);
+ lockdep_assert_held(&dev->mt76.mutex);

n = mvif->omac_idx > HW_BSSID_MAX ? HW_BSSID_0 : mvif->omac_idx;
/* TSF software read */
@@ -814,9 +812,21 @@ mt7915_get_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
tsf.t32[0] = mt76_rr(dev, MT_LPON_UTTR0(band));
tsf.t32[1] = mt76_rr(dev, MT_LPON_UTTR1(band));

+ return tsf.t64;
+}
+
+static u64
+mt7915_get_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
+{
+ struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv;
+ struct mt7915_dev *dev = mt7915_hw_dev(hw);
+ u64 ret;
+
+ mutex_lock(&dev->mt76.mutex);
+ ret = __mt7915_get_tsf(hw, mvif);
mutex_unlock(&dev->mt76.mutex);

- return tsf.t64;
+ return ret;
}

static void
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h b/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h
index ab8fc27646e0..5367b92de864 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h
@@ -273,7 +273,7 @@ extern const struct ieee80211_ops mt7915_ops;
extern const struct mt76_testmode_ops mt7915_testmode_ops;

u32 mt7915_reg_map(struct mt7915_dev *dev, u32 addr);
-
+u64 __mt7915_get_tsf(struct ieee80211_hw *hw, struct mt7915_vif *mvif);
int mt7915_register_device(struct mt7915_dev *dev);
void mt7915_unregister_device(struct mt7915_dev *dev);
int mt7915_eeprom_init(struct mt7915_dev *dev);
--
2.31.1