Commit 7f8ebafe authored by Lorenzo Bianconi's avatar Lorenzo Bianconi Committed by Felix Fietkau
Browse files

mt76: mt7663: introduce 802.11 PS support in sta mode



Enable 802.11 power-save support available in mt7663 firmware

Co-developed-by: default avatarSean Wang <sean.wang@mediatek.com>
Signed-off-by: default avatarSean Wang <sean.wang@mediatek.com>
Signed-off-by: default avatarLorenzo Bianconi <lorenzo@kernel.org>
Signed-off-by: default avatarFelix Fietkau <nbd@nbd.name>
parent a7df1152
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -286,6 +286,7 @@ enum {
	MT76_REMOVED,
	MT76_READING_STATS,
	MT76_STATE_POWER_OFF,
	MT76_STATE_PS,
};

struct mt76_hw_cap {
+4 −0
Original line number Diff line number Diff line
@@ -323,6 +323,8 @@ int mt7615_register_ext_phy(struct mt7615_dev *dev)
	INIT_DELAYED_WORK(&phy->scan_work, mt7615_scan_work);
	skb_queue_head_init(&phy->scan_event_list);

	INIT_WORK(&dev->phy.ps_work, mt7615_ps_work);

	mt7615_cap_dbdc_enable(dev);
	mphy = mt76_alloc_phy(&dev->mt76, sizeof(*phy), &mt7615_ops);
	if (!mphy)
@@ -386,7 +388,9 @@ void mt7615_init_device(struct mt7615_dev *dev)
	INIT_LIST_HEAD(&dev->sta_poll_list);
	spin_lock_init(&dev->sta_poll_lock);
	init_waitqueue_head(&dev->reset_wait);

	INIT_WORK(&dev->reset_work, mt7615_mac_reset_work);
	INIT_WORK(&dev->phy.ps_work, mt7615_ps_work);

	mt7615_init_wiphy(hw);
	dev->mphy.sband_2g.sband.ht_cap.cap |= IEEE80211_HT_CAP_LDPC_CODING;
+5 −2
Original line number Diff line number Diff line
@@ -605,8 +605,11 @@ int mt7615_mac_write_txwi(struct mt7615_dev *dev, __le32 *txwi,
	}

	if (!ieee80211_is_beacon(fc)) {
		val = MT_TXD5_TX_STATUS_HOST | MT_TXD5_SW_POWER_MGMT |
		      FIELD_PREP(MT_TXD5_PID, pid);
		struct ieee80211_hw *hw = mt76_hw(dev);

		val = MT_TXD5_TX_STATUS_HOST | FIELD_PREP(MT_TXD5_PID, pid);
		if (!ieee80211_hw_check(hw, SUPPORTS_PS))
			val |= MT_TXD5_SW_POWER_MGMT;
		txwi[5] = cpu_to_le32(val);
	} else {
		txwi[5] = 0;
+23 −0
Original line number Diff line number Diff line
@@ -71,6 +71,7 @@ static void mt7615_stop(struct ieee80211_hw *hw)
	struct mt7615_phy *phy = mt7615_hw_phy(hw);

	cancel_delayed_work_sync(&phy->mac_work);
	cancel_work_sync(&phy->ps_work);

	mutex_lock(&dev->mt76.mutex);

@@ -362,6 +363,20 @@ static int mt7615_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
	return mt7615_mac_wtbl_set_key(dev, wcid, key, cmd);
}

void mt7615_ps_work(struct work_struct *work)
{
	struct mt7615_phy *phy;

	phy = (struct mt7615_phy *)container_of(work, struct mt7615_phy,
						ps_work);

	mutex_lock(&phy->dev->mt76.mutex);
	ieee80211_iterate_active_interfaces(phy->mt76->hw,
					    IEEE80211_IFACE_ITER_RESUME_ALL,
					    m7615_mcu_set_ps_iter, phy);
	mutex_unlock(&phy->dev->mt76.mutex);
}

static int mt7615_config(struct ieee80211_hw *hw, u32 changed)
{
	struct mt7615_dev *dev = mt7615_hw_dev(hw);
@@ -387,6 +402,14 @@ static int mt7615_config(struct ieee80211_hw *hw, u32 changed)
		mt76_wr(dev, MT_WF_RFCR(band), phy->rxfilter);
	}

	if (changed & IEEE80211_CONF_CHANGE_PS) {
		if (hw->conf.flags & IEEE80211_CONF_PS)
			set_bit(MT76_STATE_PS, &phy->mt76->state);
		else
			clear_bit(MT76_STATE_PS, &phy->mt76->state);
		ieee80211_queue_work(hw, &phy->ps_work);
	}

	mutex_unlock(&dev->mt76.mutex);

	return ret;
+21 −0
Original line number Diff line number Diff line
@@ -2586,6 +2586,27 @@ int mt7615_mcu_set_sku_en(struct mt7615_phy *phy, bool enable)
				   sizeof(req), true);
}

void m7615_mcu_set_ps_iter(void *priv, u8 *mac, struct ieee80211_vif *vif)
{
	struct mt7615_vif *mvif = (struct mt7615_vif *)vif->drv_priv;
	struct mt7615_phy *phy = priv;
	struct mt76_phy *mphy = phy->mt76;
	struct {
		u8 bss_idx;
		u8 ps_state; /* 0: device awake
			      * 1: static power save
			      * 2: dynamic power saving
			      */
	} req = {
		.bss_idx = mvif->idx,
		.ps_state = test_bit(MT76_STATE_PS, &mphy->state) ? 2 : 0,
	};

	if (vif->type == NL80211_IFTYPE_STATION)
		__mt76_mcu_send_msg(&phy->dev->mt76,  MCU_CMD_SET_PS_PROFILE,
				    &req, sizeof(req), false);
}

int mt7615_mcu_set_channel_domain(struct mt7615_phy *phy)
{
	struct mt76_phy *mphy = phy->mt76;
Loading