Skip to content

Commit

Permalink
wifi: mt76: mt7996: fix TWT issues
Browse files Browse the repository at this point in the history
[ Upstream commit 5c832c228f6a7ba7e900c5296ce0fb3844bafec5 ]

This patch fixes the following TWT issues:
- Change table_mask to u16 to support up to 16 TWT stations
- Reject TWT flows for duplicated establishment
- Fix possible unaligned pointer
- Remove unsupported TWT_CONTROL_WAKE_DUR_UNIT flag
- The minimum TWT duration supported by mt7996 chipsets is 64. Reply
  with TWT_SETUP_CMD_DICTATE if the min_twt_dur is smaller than 64

Fixes: 98686cd ("wifi: mt76: mt7996: add driver for MediaTek Wi-Fi 7 (802.11be) devices")
Signed-off-by: Peter Chiu <chui-hao.chiu@mediatek.com>
Signed-off-by: Shayne Chen <shayne.chen@mediatek.com>
Signed-off-by: Felix Fietkau <nbd@nbd.name>
Signed-off-by: Sasha Levin <sashal@kernel.org>
  • Loading branch information
Peter Chiu authored and Sasha Levin committed Mar 26, 2024
1 parent f1773a1 commit e6ed68c
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 9 deletions.
53 changes: 45 additions & 8 deletions drivers/net/wireless/mediatek/mt76/mt7996/mac.c
Expand Up @@ -2433,6 +2433,34 @@ static int mt7996_mac_check_twt_req(struct ieee80211_twt_setup *twt)
return 0;
}

static bool
mt7996_mac_twt_param_equal(struct mt7996_sta *msta,
struct ieee80211_twt_params *twt_agrt)
{
u16 type = le16_to_cpu(twt_agrt->req_type);
u8 exp;
int i;

exp = FIELD_GET(IEEE80211_TWT_REQTYPE_WAKE_INT_EXP, type);
for (i = 0; i < MT7996_MAX_STA_TWT_AGRT; i++) {
struct mt7996_twt_flow *f;

if (!(msta->twt.flowid_mask & BIT(i)))
continue;

f = &msta->twt.flow[i];
if (f->duration == twt_agrt->min_twt_dur &&
f->mantissa == twt_agrt->mantissa &&
f->exp == exp &&
f->protection == !!(type & IEEE80211_TWT_REQTYPE_PROTECTION) &&
f->flowtype == !!(type & IEEE80211_TWT_REQTYPE_FLOWTYPE) &&
f->trigger == !!(type & IEEE80211_TWT_REQTYPE_TRIGGER))
return true;
}

return false;
}

void mt7996_mac_add_twt_setup(struct ieee80211_hw *hw,
struct ieee80211_sta *sta,
struct ieee80211_twt_setup *twt)
Expand All @@ -2444,8 +2472,7 @@ void mt7996_mac_add_twt_setup(struct ieee80211_hw *hw,
enum ieee80211_twt_setup_cmd sta_setup_cmd;
struct mt7996_dev *dev = mt7996_hw_dev(hw);
struct mt7996_twt_flow *flow;
int flowid, table_id;
u8 exp;
u8 flowid, table_id, exp;

if (mt7996_mac_check_twt_req(twt))
goto out;
Expand All @@ -2458,9 +2485,19 @@ void mt7996_mac_add_twt_setup(struct ieee80211_hw *hw,
if (hweight8(msta->twt.flowid_mask) == ARRAY_SIZE(msta->twt.flow))
goto unlock;

if (twt_agrt->min_twt_dur < MT7996_MIN_TWT_DUR) {
setup_cmd = TWT_SETUP_CMD_DICTATE;
twt_agrt->min_twt_dur = MT7996_MIN_TWT_DUR;
goto unlock;
}

if (mt7996_mac_twt_param_equal(msta, twt_agrt))
goto unlock;

flowid = ffs(~msta->twt.flowid_mask) - 1;
le16p_replace_bits(&twt_agrt->req_type, flowid,
IEEE80211_TWT_REQTYPE_FLOWID);
twt_agrt->req_type &= ~cpu_to_le16(IEEE80211_TWT_REQTYPE_FLOWID);
twt_agrt->req_type |= le16_encode_bits(flowid,
IEEE80211_TWT_REQTYPE_FLOWID);

table_id = ffs(~dev->twt.table_mask) - 1;
exp = FIELD_GET(IEEE80211_TWT_REQTYPE_WAKE_INT_EXP, req_type);
Expand Down Expand Up @@ -2507,10 +2544,10 @@ void mt7996_mac_add_twt_setup(struct ieee80211_hw *hw,
unlock:
mutex_unlock(&dev->mt76.mutex);
out:
le16p_replace_bits(&twt_agrt->req_type, setup_cmd,
IEEE80211_TWT_REQTYPE_SETUP_CMD);
twt->control = (twt->control & IEEE80211_TWT_CONTROL_WAKE_DUR_UNIT) |
(twt->control & IEEE80211_TWT_CONTROL_RX_DISABLED);
twt_agrt->req_type &= ~cpu_to_le16(IEEE80211_TWT_REQTYPE_SETUP_CMD);
twt_agrt->req_type |=
le16_encode_bits(setup_cmd, IEEE80211_TWT_REQTYPE_SETUP_CMD);
twt->control = twt->control & IEEE80211_TWT_CONTROL_RX_DISABLED;
}

void mt7996_mac_twt_teardown_flow(struct mt7996_dev *dev,
Expand Down
3 changes: 2 additions & 1 deletion drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h
Expand Up @@ -43,6 +43,7 @@

#define MT7996_MAX_TWT_AGRT 16
#define MT7996_MAX_STA_TWT_AGRT 8
#define MT7996_MIN_TWT_DUR 64
#define MT7996_MAX_QUEUE (__MT_RXQ_MAX + __MT_MCUQ_MAX + 3)

/* NOTE: used to map mt76_rates. idx may change if firmware expands table */
Expand Down Expand Up @@ -237,7 +238,7 @@ struct mt7996_dev {
struct rchan *relay_fwlog;

struct {
u8 table_mask;
u16 table_mask;
u8 n_agrt;
} twt;

Expand Down

0 comments on commit e6ed68c

Please sign in to comment.