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: Lorenzo Bianconi <lorenzo@kernel.org> Signed-off-by: Felix Fietkau <nbd@nbd.name>
This commit is contained in:
parent
7660a1bd0c
commit
186b659c08
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user