Commit f5056657 authored by Sean Wang's avatar Sean Wang Committed by Felix Fietkau
Browse files

mt76: mt7921: enable deep sleep at runtime



Enable the deep sleep mode with that firmware is able to trap into
the doze state at runtime to reduce the power consumption further.

The deep sleep mode is not allowed in the STA state transition with
the firmware to have the fast connection experience as we've done in
the full power mode

Reviewed-by: default avatarLorenzo Bianconi <lorenzo@kernel.org>
Signed-off-by: default avatarSean Wang <sean.wang@mediatek.com>
Signed-off-by: default avatarFelix Fietkau <nbd@nbd.name>
parent 2707ff4d
Loading
Loading
Loading
Loading
+5 −3
Original line number Diff line number Diff line
@@ -1028,9 +1028,10 @@ mt7615_mcu_wtbl_sta_add(struct mt7615_phy *phy, struct ieee80211_vif *vif,
	if (IS_ERR(sskb))
		return PTR_ERR(sskb);

	mt76_connac_mcu_sta_basic_tlv(sskb, vif, sta, enable);
	mt76_connac_mcu_sta_basic_tlv(sskb, vif, sta, enable, true);
	if (enable && sta)
		mt76_connac_mcu_sta_tlv(phy->mt76, sskb, sta, vif, 0);
		mt76_connac_mcu_sta_tlv(phy->mt76, sskb, sta, vif, 0,
					MT76_STA_INFO_STATE_ASSOC);

	wtbl_hdr = mt76_connac_mcu_alloc_wtbl_req(&dev->mt76, &msta->wcid,
						  WTBL_RESET_AND_SET, NULL,
@@ -1157,11 +1158,12 @@ __mt7615_mcu_add_sta(struct mt76_phy *phy, struct ieee80211_vif *vif,
		.vif = vif,
		.offload_fw = offload_fw,
		.enable = enable,
		.newly = true,
		.cmd = cmd,
	};

	info.wcid = sta ? (struct mt76_wcid *)sta->drv_priv : &mvif->sta.wcid;
	return mt76_connac_mcu_add_sta_cmd(phy, &info);
	return mt76_connac_mcu_sta_cmd(phy, &info);
}

static int
+31 −9
Original line number Diff line number Diff line
@@ -304,7 +304,7 @@ EXPORT_SYMBOL_GPL(mt76_connac_mcu_alloc_wtbl_req);
void mt76_connac_mcu_sta_basic_tlv(struct sk_buff *skb,
				   struct ieee80211_vif *vif,
				   struct ieee80211_sta *sta,
				   bool enable)
				   bool enable, bool newly)
{
	struct sta_rec_basic *basic;
	struct tlv *tlv;
@@ -316,6 +316,7 @@ void mt76_connac_mcu_sta_basic_tlv(struct sk_buff *skb,
	basic->extra_info = cpu_to_le16(EXTRA_INFO_VER);

	if (enable) {
		if (newly)
			basic->extra_info |= cpu_to_le16(EXTRA_INFO_NEW);
		basic->conn_state = CONN_STATE_PORT_SECURE;
	} else {
@@ -709,7 +710,7 @@ mt76_connac_get_phy_mode_v2(struct mt76_phy *mphy, struct ieee80211_vif *vif,
void mt76_connac_mcu_sta_tlv(struct mt76_phy *mphy, struct sk_buff *skb,
			     struct ieee80211_sta *sta,
			     struct ieee80211_vif *vif,
			     u8 rcpi)
			     u8 rcpi, u8 sta_state)
{
	struct cfg80211_chan_def *chandef = &mphy->chandef;
	enum nl80211_band band = chandef->chan->band;
@@ -774,7 +775,7 @@ void mt76_connac_mcu_sta_tlv(struct mt76_phy *mphy, struct sk_buff *skb,

	tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_STATE, sizeof(*state));
	state = (struct sta_rec_state *)tlv;
	state->state = 2;
	state->state = sta_state;

	if (sta->vht_cap.vht_supported) {
		state->vht_opmode = sta->bandwidth;
@@ -866,7 +867,7 @@ void mt76_connac_mcu_wtbl_ht_tlv(struct mt76_dev *dev, struct sk_buff *skb,
}
EXPORT_SYMBOL_GPL(mt76_connac_mcu_wtbl_ht_tlv);

int mt76_connac_mcu_add_sta_cmd(struct mt76_phy *phy,
int mt76_connac_mcu_sta_cmd(struct mt76_phy *phy,
			    struct mt76_sta_cmd_info *info)
{
	struct mt76_vif *mvif = (struct mt76_vif *)info->vif->drv_priv;
@@ -881,10 +882,11 @@ int mt76_connac_mcu_add_sta_cmd(struct mt76_phy *phy,

	if (info->sta || !info->offload_fw)
		mt76_connac_mcu_sta_basic_tlv(skb, info->vif, info->sta,
					      info->enable);
					      info->enable, info->newly);
	if (info->sta && info->enable)
		mt76_connac_mcu_sta_tlv(phy, skb, info->sta,
					info->vif, info->rcpi);
					info->vif, info->rcpi,
					info->state);

	sta_wtbl = mt76_connac_mcu_add_tlv(skb, STA_REC_WTBL,
					   sizeof(struct tlv));
@@ -908,7 +910,7 @@ int mt76_connac_mcu_add_sta_cmd(struct mt76_phy *phy,

	return mt76_mcu_skb_send_msg(dev, skb, info->cmd, true);
}
EXPORT_SYMBOL_GPL(mt76_connac_mcu_add_sta_cmd);
EXPORT_SYMBOL_GPL(mt76_connac_mcu_sta_cmd);

void mt76_connac_mcu_wtbl_ba_tlv(struct mt76_dev *dev, struct sk_buff *skb,
				 struct ieee80211_ampdu_params *params,
@@ -1616,6 +1618,26 @@ int mt76_connac_mcu_set_deep_sleep(struct mt76_dev *dev, bool enable)
}
EXPORT_SYMBOL_GPL(mt76_connac_mcu_set_deep_sleep);

int mt76_connac_sta_state_dp(struct mt76_dev *dev,
			     enum ieee80211_sta_state old_state,
			     enum ieee80211_sta_state new_state)
{
	if ((old_state == IEEE80211_STA_ASSOC &&
	     new_state == IEEE80211_STA_AUTHORIZED) ||
	    (old_state == IEEE80211_STA_NONE &&
	     new_state == IEEE80211_STA_NOTEXIST))
		mt76_connac_mcu_set_deep_sleep(dev, true);

	if ((old_state == IEEE80211_STA_NOTEXIST &&
	     new_state == IEEE80211_STA_NONE) ||
	    (old_state == IEEE80211_STA_AUTHORIZED &&
	     new_state == IEEE80211_STA_ASSOC))
		mt76_connac_mcu_set_deep_sleep(dev, false);

	return 0;
}
EXPORT_SYMBOL_GPL(mt76_connac_sta_state_dp);

void mt76_connac_mcu_coredump_event(struct mt76_dev *dev, struct sk_buff *skb,
				    struct mt76_connac_coredump *coredump)
{
+16 −4
Original line number Diff line number Diff line
@@ -927,6 +927,12 @@ struct mt76_connac_suspend_tlv {
	u8 pad[5];
} __packed;

enum mt76_sta_info_state {
	MT76_STA_INFO_STATE_NONE,
	MT76_STA_INFO_STATE_AUTH,
	MT76_STA_INFO_STATE_ASSOC
};

struct mt76_sta_cmd_info {
	struct ieee80211_sta *sta;
	struct mt76_wcid *wcid;
@@ -935,8 +941,10 @@ struct mt76_sta_cmd_info {

	bool offload_fw;
	bool enable;
	bool newly;
	int cmd;
	u8 rcpi;
	u8 state;
};

#define MT_SKU_POWER_LIMIT	161
@@ -1006,7 +1014,8 @@ int mt76_connac_mcu_set_channel_domain(struct mt76_phy *phy);
int mt76_connac_mcu_set_vif_ps(struct mt76_dev *dev, struct ieee80211_vif *vif);
void mt76_connac_mcu_sta_basic_tlv(struct sk_buff *skb,
				   struct ieee80211_vif *vif,
				   struct ieee80211_sta *sta, bool enable);
				   struct ieee80211_sta *sta, bool enable,
				   bool newly);
void mt76_connac_mcu_wtbl_generic_tlv(struct mt76_dev *dev, struct sk_buff *skb,
				      struct ieee80211_vif *vif,
				      struct ieee80211_sta *sta, void *sta_wtbl,
@@ -1021,7 +1030,7 @@ int mt76_connac_mcu_sta_update_hdr_trans(struct mt76_dev *dev,
void mt76_connac_mcu_sta_tlv(struct mt76_phy *mphy, struct sk_buff *skb,
			     struct ieee80211_sta *sta,
			     struct ieee80211_vif *vif,
			     u8 rcpi);
			     u8 rcpi, u8 state);
void mt76_connac_mcu_wtbl_ht_tlv(struct mt76_dev *dev, struct sk_buff *skb,
				 struct ieee80211_sta *sta, void *sta_wtbl,
				 void *wtbl_tlv);
@@ -1043,7 +1052,7 @@ int mt76_connac_mcu_uni_add_bss(struct mt76_phy *phy,
				struct ieee80211_vif *vif,
				struct mt76_wcid *wcid,
				bool enable);
int mt76_connac_mcu_add_sta_cmd(struct mt76_phy *phy,
int mt76_connac_mcu_sta_cmd(struct mt76_phy *phy,
			    struct mt76_sta_cmd_info *info);
void mt76_connac_mcu_beacon_loss_iter(void *priv, u8 *mac,
				      struct ieee80211_vif *vif);
@@ -1076,6 +1085,9 @@ int mt76_connac_mcu_update_gtk_rekey(struct ieee80211_hw *hw,
int mt76_connac_mcu_set_hif_suspend(struct mt76_dev *dev, bool suspend);
void mt76_connac_mcu_set_suspend_iter(void *priv, u8 *mac,
				      struct ieee80211_vif *vif);
int mt76_connac_sta_state_dp(struct mt76_dev *dev,
			     enum ieee80211_sta_state old_state,
			     enum ieee80211_sta_state new_state);
int mt76_connac_mcu_chip_config(struct mt76_dev *dev);
int mt76_connac_mcu_set_deep_sleep(struct mt76_dev *dev, bool enable);
void mt76_connac_mcu_coredump_event(struct mt76_dev *dev, struct sk_buff *skb,
+5 −1
Original line number Diff line number Diff line
@@ -231,7 +231,11 @@ int mt7921_register_device(struct mt7921_dev *dev)
	if (ret)
		return ret;

	return mt7921_init_debugfs(dev);
	ret = mt7921_init_debugfs(dev);
	if (ret)
		return ret;

	return mt76_connac_mcu_set_deep_sleep(&dev->mt76, dev->pm.enable);
}

void mt7921_unregister_device(struct mt7921_dev *dev)
+41 −22
Original line number Diff line number Diff line
@@ -577,7 +577,8 @@ static void mt7921_bss_info_changed(struct ieee80211_hw *hw,
		mt7921_mcu_uni_bss_ps(dev, vif);

	if (changed & BSS_CHANGED_ASSOC) {
		mt7921_mcu_sta_add(dev, NULL, vif, true);
		mt7921_mcu_sta_update(dev, NULL, vif, true,
				      MT76_STA_INFO_STATE_ASSOC);
		mt7921_bss_bcnft_apply(dev, vif, info->assoc);
	}

@@ -616,17 +617,14 @@ int mt7921_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,
	if (ret)
		return ret;

	if (vif->type == NL80211_IFTYPE_STATION) {
	if (vif->type == NL80211_IFTYPE_STATION)
		mvif->wep_sta = msta;
		if (!sta->tdls)
			mt76_connac_mcu_uni_add_bss(&dev->mphy, vif,
						    &mvif->sta.wcid, true);
	}

	mt7921_mac_wtbl_update(dev, idx,
			       MT_WTBL_UPDATE_ADM_COUNT_CLEAR);

	ret = mt7921_mcu_sta_add(dev, sta, vif, true);
	ret = mt7921_mcu_sta_update(dev, sta, vif, true,
				    MT76_STA_INFO_STATE_NONE);
	if (ret)
		return ret;

@@ -635,6 +633,27 @@ int mt7921_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,
	return 0;
}

void mt7921_mac_sta_assoc(struct mt76_dev *mdev, struct ieee80211_vif *vif,
			  struct ieee80211_sta *sta)
{
	struct mt7921_dev *dev = container_of(mdev, struct mt7921_dev, mt76);
	struct mt7921_sta *msta = (struct mt7921_sta *)sta->drv_priv;
	struct mt7921_vif *mvif = (struct mt7921_vif *)vif->drv_priv;

	mt7921_mutex_acquire(dev);

	if (vif->type == NL80211_IFTYPE_STATION && !sta->tdls)
		mt76_connac_mcu_uni_add_bss(&dev->mphy, vif, &mvif->sta.wcid,
					    true);

	mt7921_mac_wtbl_update(dev, msta->wcid.idx,
			       MT_WTBL_UPDATE_ADM_COUNT_CLEAR);

	mt7921_mcu_sta_update(dev, sta, vif, true, MT76_STA_INFO_STATE_ASSOC);

	mt7921_mutex_release(dev);
}

void mt7921_mac_sta_remove(struct mt76_dev *mdev, struct ieee80211_vif *vif,
			   struct ieee80211_sta *sta)
{
@@ -644,7 +663,7 @@ void mt7921_mac_sta_remove(struct mt76_dev *mdev, struct ieee80211_vif *vif,
	mt76_connac_free_pending_tx_skbs(&dev->pm, &msta->wcid);
	mt76_connac_pm_wake(&dev->mphy, &dev->pm);

	mt7921_mcu_sta_add(dev, sta, vif, false);
	mt7921_mcu_sta_update(dev, sta, vif, false, MT76_STA_INFO_STATE_NONE);
	mt7921_mac_wtbl_update(dev, msta->wcid.idx,
			       MT_WTBL_UPDATE_ADM_COUNT_CLEAR);

@@ -790,20 +809,21 @@ mt7921_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
	return ret;
}

static int
mt7921_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
	       struct ieee80211_sta *sta)
static int mt7921_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)
{
	return mt76_sta_state(hw, vif, sta, IEEE80211_STA_NOTEXIST,
			      IEEE80211_STA_NONE);
	struct mt7921_dev *dev = mt7921_hw_dev(hw);

	if (dev->pm.enable) {
		mt7921_mutex_acquire(dev);
		mt76_connac_sta_state_dp(&dev->mt76, old_state, new_state);
		mt7921_mutex_release(dev);
	}

static int
mt7921_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
		  struct ieee80211_sta *sta)
{
	return mt76_sta_state(hw, vif, sta, IEEE80211_STA_NONE,
			      IEEE80211_STA_NOTEXIST);
	return mt76_sta_state(hw, vif, sta, old_state, new_state);
}

static int
@@ -1149,8 +1169,7 @@ const struct ieee80211_ops mt7921_ops = {
	.conf_tx = mt7921_conf_tx,
	.configure_filter = mt7921_configure_filter,
	.bss_info_changed = mt7921_bss_info_changed,
	.sta_add = mt7921_sta_add,
	.sta_remove = mt7921_sta_remove,
	.sta_state = mt7921_sta_state,
	.sta_pre_rcu_remove = mt76_sta_pre_rcu_remove,
	.set_key = mt7921_set_key,
	.sta_set_decap_offload = mt7921_sta_set_decap_offload,
Loading