Commit 186b659c authored by Lorenzo Bianconi's avatar Lorenzo Bianconi Committed by Felix Fietkau
Browse files

mt76: mt7615: move drv_own/fw_own in mt7615_mcu_ops



Introduce set_drv_ctrl and set_fw_ctrl function pointers in
mt7615_mcu_ops data structure. This is a preliminary patch to enable
runtime-pm for non-pci chipsets

Signed-off-by: default avatarLorenzo Bianconi <lorenzo@kernel.org>
Signed-off-by: default avatarFelix Fietkau <nbd@nbd.name>
parent 7660a1bd
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -1845,7 +1845,7 @@ void mt7615_pm_wake_work(struct work_struct *work)
						pm.wake_work);
	mphy = dev->phy.mt76;

	if (mt7615_driver_own(dev)) {
	if (mt7615_mcu_set_drv_ctrl(dev)) {
		dev_err(mphy->dev->dev, "failed to wake device\n");
		goto out;
	}
@@ -1943,7 +1943,7 @@ void mt7615_pm_power_save_work(struct work_struct *work)
		goto out;
	}

	if (!mt7615_firmware_own(dev))
	if (!mt7615_mcu_set_fw_ctrl(dev))
		return;
out:
	queue_delayed_work(dev->mt76.wq, &dev->pm.ps_work, delta);
+81 −77
Original line number Diff line number Diff line
@@ -324,6 +324,79 @@ int mt7615_rf_wr(struct mt7615_dev *dev, u32 wf, u32 reg, u32 val)
				   sizeof(req), false);
}

static void mt7622_trigger_hif_int(struct mt7615_dev *dev, bool en)
{
	if (!is_mt7622(&dev->mt76))
		return;

	regmap_update_bits(dev->infracfg, MT_INFRACFG_MISC,
			   MT_INFRACFG_MISC_AP2CONN_WAKE,
			   !en * MT_INFRACFG_MISC_AP2CONN_WAKE);
}

static int mt7615_mcu_drv_pmctrl(struct mt7615_dev *dev)
{
	struct mt76_phy *mphy = &dev->mt76.phy;
	struct mt76_dev *mdev = &dev->mt76;
	int i;

	if (!test_and_clear_bit(MT76_STATE_PM, &mphy->state))
		goto out;

	mt7622_trigger_hif_int(dev, true);

	for (i = 0; i < MT7615_DRV_OWN_RETRY_COUNT; i++) {
		u32 addr;

		addr = is_mt7663(mdev) ? MT_PCIE_DOORBELL_PUSH : MT_CFG_LPCR_HOST;
		mt76_wr(dev, addr, MT_CFG_LPCR_HOST_DRV_OWN);

		addr = is_mt7663(mdev) ? MT_CONN_HIF_ON_LPCTL : MT_CFG_LPCR_HOST;
		if (mt76_poll_msec(dev, addr, MT_CFG_LPCR_HOST_FW_OWN, 0, 50))
			break;
	}

	mt7622_trigger_hif_int(dev, false);

	if (i == MT7615_DRV_OWN_RETRY_COUNT) {
		dev_err(mdev->dev, "driver own failed\n");
		set_bit(MT76_STATE_PM, &mphy->state);
		return -EIO;
	}

out:
	dev->pm.last_activity = jiffies;

	return 0;
}

static int mt7615_mcu_fw_pmctrl(struct mt7615_dev *dev)
{
	struct mt76_phy *mphy = &dev->mt76.phy;
	int err = 0;
	u32 addr;

	if (test_and_set_bit(MT76_STATE_PM, &mphy->state))
		return 0;

	mt7622_trigger_hif_int(dev, true);

	addr = is_mt7663(&dev->mt76) ? MT_CONN_HIF_ON_LPCTL : MT_CFG_LPCR_HOST;
	mt76_wr(dev, addr, MT_CFG_LPCR_HOST_FW_OWN);

	if (is_mt7622(&dev->mt76) &&
	    !mt76_poll_msec(dev, addr, MT_CFG_LPCR_HOST_FW_OWN,
			    MT_CFG_LPCR_HOST_FW_OWN, 300)) {
		dev_err(dev->mt76.dev, "Timeout for firmware own\n");
		clear_bit(MT76_STATE_PM, &mphy->state);
		err = -EIO;
	}

	mt7622_trigger_hif_int(dev, false);

	return err;
}

static void
mt7615_mcu_csa_finish(void *priv, u8 *mac, struct ieee80211_vif *vif)
{
@@ -1314,6 +1387,8 @@ static const struct mt7615_mcu_ops wtbl_update_ops = {
	.add_tx_ba = mt7615_mcu_wtbl_tx_ba,
	.add_rx_ba = mt7615_mcu_wtbl_rx_ba,
	.sta_add = mt7615_mcu_wtbl_sta_add,
	.set_drv_ctrl = mt7615_mcu_drv_pmctrl,
	.set_fw_ctrl = mt7615_mcu_fw_pmctrl,
};

static int
@@ -1410,6 +1485,8 @@ static const struct mt7615_mcu_ops sta_update_ops = {
	.add_tx_ba = mt7615_mcu_sta_tx_ba,
	.add_rx_ba = mt7615_mcu_sta_rx_ba,
	.sta_add = mt7615_mcu_add_sta,
	.set_drv_ctrl = mt7615_mcu_drv_pmctrl,
	.set_fw_ctrl = mt7615_mcu_fw_pmctrl,
};

static int
@@ -1823,6 +1900,8 @@ static const struct mt7615_mcu_ops uni_update_ops = {
	.add_tx_ba = mt7615_mcu_uni_tx_ba,
	.add_rx_ba = mt7615_mcu_uni_rx_ba,
	.sta_add = mt7615_mcu_uni_add_sta,
	.set_drv_ctrl = mt7615_mcu_drv_pmctrl,
	.set_fw_ctrl = mt7615_mcu_fw_pmctrl,
};

static int mt7615_mcu_send_firmware(struct mt7615_dev *dev, const void *data,
@@ -1895,81 +1974,6 @@ static int mt7615_mcu_start_patch(struct mt7615_dev *dev)
				   &req, sizeof(req), true);
}

static void mt7622_trigger_hif_int(struct mt7615_dev *dev, bool en)
{
	if (!is_mt7622(&dev->mt76))
		return;

	regmap_update_bits(dev->infracfg, MT_INFRACFG_MISC,
			   MT_INFRACFG_MISC_AP2CONN_WAKE,
			   !en * MT_INFRACFG_MISC_AP2CONN_WAKE);
}

int mt7615_driver_own(struct mt7615_dev *dev)
{
	struct mt76_phy *mphy = &dev->mt76.phy;
	struct mt76_dev *mdev = &dev->mt76;
	int i;

	if (!test_and_clear_bit(MT76_STATE_PM, &mphy->state))
		goto out;

	mt7622_trigger_hif_int(dev, true);

	for (i = 0; i < MT7615_DRV_OWN_RETRY_COUNT; i++) {
		u32 addr;

		addr = is_mt7663(mdev) ? MT_PCIE_DOORBELL_PUSH : MT_CFG_LPCR_HOST;
		mt76_wr(dev, addr, MT_CFG_LPCR_HOST_DRV_OWN);

		addr = is_mt7663(mdev) ? MT_CONN_HIF_ON_LPCTL : MT_CFG_LPCR_HOST;
		if (mt76_poll_msec(dev, addr, MT_CFG_LPCR_HOST_FW_OWN, 0, 50))
			break;
	}

	mt7622_trigger_hif_int(dev, false);

	if (i == MT7615_DRV_OWN_RETRY_COUNT) {
		dev_err(mdev->dev, "driver own failed\n");
		set_bit(MT76_STATE_PM, &mphy->state);
		return -EIO;
	}

out:
	dev->pm.last_activity = jiffies;

	return 0;
}
EXPORT_SYMBOL_GPL(mt7615_driver_own);

int mt7615_firmware_own(struct mt7615_dev *dev)
{
	struct mt76_phy *mphy = &dev->mt76.phy;
	int err = 0;
	u32 addr;

	if (test_and_set_bit(MT76_STATE_PM, &mphy->state))
		return 0;

	mt7622_trigger_hif_int(dev, true);

	addr = is_mt7663(&dev->mt76) ? MT_CONN_HIF_ON_LPCTL : MT_CFG_LPCR_HOST;
	mt76_wr(dev, addr, MT_CFG_LPCR_HOST_FW_OWN);

	if (is_mt7622(&dev->mt76) &&
	    !mt76_poll_msec(dev, addr, MT_CFG_LPCR_HOST_FW_OWN,
			    MT_CFG_LPCR_HOST_FW_OWN, 300)) {
		dev_err(dev->mt76.dev, "Timeout for firmware own\n");
		clear_bit(MT76_STATE_PM, &mphy->state);
		err = -EIO;
	}

	mt7622_trigger_hif_int(dev, false);

	return err;
}
EXPORT_SYMBOL_GPL(mt7615_firmware_own);

static int mt7615_load_patch(struct mt7615_dev *dev, u32 addr, const char *name)
{
	const struct mt7615_patch_hdr *hdr;
@@ -2451,7 +2455,7 @@ int mt7615_mcu_init(struct mt7615_dev *dev)

	dev->mt76.mcu_ops = &mt7615_mcu_ops,

	ret = mt7615_driver_own(dev);
	ret = mt7615_mcu_drv_pmctrl(dev);
	if (ret)
		return ret;

@@ -2481,7 +2485,7 @@ EXPORT_SYMBOL_GPL(mt7615_mcu_init);
void mt7615_mcu_exit(struct mt7615_dev *dev)
{
	__mt76_mcu_restart(&dev->mt76);
	mt7615_firmware_own(dev);
	mt7615_mcu_set_fw_ctrl(dev);
	skb_queue_purge(&dev->mt76.mcu.res_q);
}
EXPORT_SYMBOL_GPL(mt7615_mcu_exit);
+4 −2
Original line number Diff line number Diff line
@@ -220,6 +220,8 @@ struct mt7615_phy {
#define mt7615_mcu_add_bss_info(phy, ...) (phy->dev)->mcu_ops->add_bss_info((phy),  __VA_ARGS__)
#define mt7615_mcu_add_beacon(dev, ...)	(dev)->mcu_ops->add_beacon_offload((dev),  __VA_ARGS__)
#define mt7615_mcu_set_pm(dev, ...)	(dev)->mcu_ops->set_pm_state((dev),  __VA_ARGS__)
#define mt7615_mcu_set_drv_ctrl(dev)	(dev)->mcu_ops->set_drv_ctrl((dev))
#define mt7615_mcu_set_fw_ctrl(dev)	(dev)->mcu_ops->set_fw_ctrl((dev))
struct mt7615_mcu_ops {
	int (*add_tx_ba)(struct mt7615_dev *dev,
			 struct ieee80211_ampdu_params *params,
@@ -238,6 +240,8 @@ struct mt7615_mcu_ops {
				  struct ieee80211_hw *hw,
				  struct ieee80211_vif *vif, bool enable);
	int (*set_pm_state)(struct mt7615_dev *dev, int band, int state);
	int (*set_drv_ctrl)(struct mt7615_dev *dev);
	int (*set_fw_ctrl)(struct mt7615_dev *dev);
};

struct mt7615_dev {
@@ -639,8 +643,6 @@ int mt7615_mcu_set_p2p_oppps(struct ieee80211_hw *hw,
			     struct ieee80211_vif *vif);
int mt7615_mcu_set_roc(struct mt7615_phy *phy, struct ieee80211_vif *vif,
		       struct ieee80211_channel *chan, int duration);
int mt7615_firmware_own(struct mt7615_dev *dev);
int mt7615_driver_own(struct mt7615_dev *dev);

int mt7615_init_debugfs(struct mt7615_dev *dev);
int mt7615_mcu_wait_response(struct mt7615_dev *dev, int cmd, int seq);
+2 −2
Original line number Diff line number Diff line
@@ -118,7 +118,7 @@ static int mt7615_pci_suspend(struct pci_dev *pdev, pm_message_t state)
	if (err)
		goto restore;

	err = mt7615_firmware_own(dev);
	err = mt7615_mcu_set_fw_ctrl(dev);
	if (err)
		goto restore;

@@ -142,7 +142,7 @@ static int mt7615_pci_resume(struct pci_dev *pdev)
	bool pdma_reset;
	int i, err;

	err = mt7615_driver_own(dev);
	err = mt7615_mcu_set_drv_ctrl(dev);
	if (err < 0)
		return err;