// SPDX-License-Identifier: ISC
/* Copyright (C) 2021 MediaTek Inc.
 *
 */

#include <linux/kernel.h>
#include <linux/iopoll.h>
#include <linux/module.h>

#include <linux/mmc/host.h>
#include <linux/mmc/sdio_ids.h>
#include <linux/mmc/sdio_func.h>

#include "mt7921.h"
#include "../sdio.h"
#include "mac.h"
#include "mcu.h"

static const struct sdio_device_id mt7921s_table[] = {
	{ SDIO_DEVICE(SDIO_VENDOR_ID_MEDIATEK, 0x7901) },
	{ }	/* Terminating entry */
};

static void mt7921s_txrx_worker(struct mt76_worker *w)
{
	struct mt76_sdio *sdio = container_of(w, struct mt76_sdio,
					      txrx_worker);
	struct mt76_dev *mdev = container_of(sdio, struct mt76_dev, sdio);
	struct mt7921_dev *dev = container_of(mdev, struct mt7921_dev, mt76);

	if (!mt76_connac_pm_ref(&dev->mphy, &dev->pm)) {
		queue_work(mdev->wq, &dev->pm.wake_work);
		return;
	}

	mt76s_txrx_worker(sdio);
	mt76_connac_pm_unref(&dev->mphy, &dev->pm);
}

static void mt7921s_unregister_device(struct mt7921_dev *dev)
{
	struct mt76_connac_pm *pm = &dev->pm;

	cancel_work_sync(&dev->init_work);
	mt76_unregister_device(&dev->mt76);
	cancel_delayed_work_sync(&pm->ps_work);
	cancel_work_sync(&pm->wake_work);

	mt76s_deinit(&dev->mt76);
	mt7921s_wfsys_reset(dev);
	skb_queue_purge(&dev->mt76.mcu.res_q);

	mt76_free_device(&dev->mt76);
}

static int mt7921s_parse_intr(struct mt76_dev *dev, struct mt76s_intr *intr)
{
	struct mt76_sdio *sdio = &dev->sdio;
	struct mt7921_sdio_intr *irq_data = sdio->intr_data;
	int i, err;

	sdio_claim_host(sdio->func);
	err = sdio_readsb(sdio->func, irq_data, MCR_WHISR, sizeof(*irq_data));
	sdio_release_host(sdio->func);

	if (err < 0)
		return err;

	if (irq_data->rx.num[0] > 16 ||
	    irq_data->rx.num[1] > 128)
		return -EINVAL;

	intr->isr = irq_data->isr;
	intr->rec_mb = irq_data->rec_mb;
	intr->tx.wtqcr = irq_data->tx.wtqcr;
	intr->rx.num = irq_data->rx.num;
	for (i = 0; i < 2 ; i++) {
		if (!i)
			intr->rx.len[0] = irq_data->rx.len0;
		else
			intr->rx.len[1] = irq_data->rx.len1;
	}

	return 0;
}

static int mt7921s_probe(struct sdio_func *func,
			 const struct sdio_device_id *id)
{
	static const struct mt76_driver_ops drv_ops = {
		.txwi_size = MT_SDIO_TXD_SIZE,
		.survey_flags = SURVEY_INFO_TIME_TX |
				SURVEY_INFO_TIME_RX |
				SURVEY_INFO_TIME_BSS_RX,
		.tx_prepare_skb = mt7921_usb_sdio_tx_prepare_skb,
		.tx_complete_skb = mt7921_usb_sdio_tx_complete_skb,
		.tx_status_data = mt7921_usb_sdio_tx_status_data,
		.rx_skb = mt7921_queue_rx_skb,
		.sta_ps = mt7921_sta_ps,
		.sta_add = mt7921_mac_sta_add,
		.sta_assoc = mt7921_mac_sta_assoc,
		.sta_remove = mt7921_mac_sta_remove,
		.update_survey = mt7921_update_channel,
	};
	static const struct mt76_bus_ops mt7921s_ops = {
		.rr = mt76s_rr,
		.rmw = mt76s_rmw,
		.wr = mt76s_wr,
		.write_copy = mt76s_write_copy,
		.read_copy = mt76s_read_copy,
		.wr_rp = mt76s_wr_rp,
		.rd_rp = mt76s_rd_rp,
		.type = MT76_BUS_SDIO,
	};
	static const struct mt7921_hif_ops mt7921_sdio_ops = {
		.init_reset = mt7921s_init_reset,
		.reset = mt7921s_mac_reset,
		.mcu_init = mt7921s_mcu_init,
		.drv_own = mt7921s_mcu_drv_pmctrl,
		.fw_own = mt7921s_mcu_fw_pmctrl,
	};

	struct mt7921_dev *dev;
	struct mt76_dev *mdev;
	int ret;

	mdev = mt76_alloc_device(&func->dev, sizeof(*dev), &mt7921_ops,
				 &drv_ops);
	if (!mdev)
		return -ENOMEM;

	dev = container_of(mdev, struct mt7921_dev, mt76);
	dev->hif_ops = &mt7921_sdio_ops;

	sdio_set_drvdata(func, dev);

	ret = mt76s_init(mdev, func, &mt7921s_ops);
	if (ret < 0)
		goto error;

	ret = mt76s_hw_init(mdev, func, MT76_CONNAC2_SDIO);
	if (ret)
		goto error;

	mdev->rev = (mt76_rr(dev, MT_HW_CHIPID) << 16) |
		    (mt76_rr(dev, MT_HW_REV) & 0xff);
	dev_dbg(mdev->dev, "ASIC revision: %04x\n", mdev->rev);

	mdev->sdio.parse_irq = mt7921s_parse_intr;
	mdev->sdio.intr_data = devm_kmalloc(mdev->dev,
					    sizeof(struct mt7921_sdio_intr),
					    GFP_KERNEL);
	if (!mdev->sdio.intr_data) {
		ret = -ENOMEM;
		goto error;
	}

	ret = mt76s_alloc_rx_queue(mdev, MT_RXQ_MAIN);
	if (ret)
		goto error;

	ret = mt76s_alloc_rx_queue(mdev, MT_RXQ_MCU);
	if (ret)
		goto error;

	ret = mt76s_alloc_tx(mdev);
	if (ret)
		goto error;

	ret = mt76_worker_setup(mt76_hw(dev), &mdev->sdio.txrx_worker,
				mt7921s_txrx_worker, "sdio-txrx");
	if (ret)
		goto error;

	sched_set_fifo_low(mdev->sdio.txrx_worker.task);

	ret = mt7921_register_device(dev);
	if (ret)
		goto error;

	return 0;

error:
	mt76s_deinit(&dev->mt76);
	mt76_free_device(&dev->mt76);

	return ret;
}

static void mt7921s_remove(struct sdio_func *func)
{
	struct mt7921_dev *dev = sdio_get_drvdata(func);

	mt7921s_unregister_device(dev);
}

#ifdef CONFIG_PM
static int mt7921s_suspend(struct device *__dev)
{
	struct sdio_func *func = dev_to_sdio_func(__dev);
	struct mt7921_dev *dev = sdio_get_drvdata(func);
	struct mt76_connac_pm *pm = &dev->pm;
	struct mt76_dev *mdev = &dev->mt76;
	int err;

	pm->suspended = true;
	set_bit(MT76_STATE_SUSPEND, &mdev->phy.state);

	flush_work(&dev->reset_work);
	cancel_delayed_work_sync(&pm->ps_work);
	cancel_work_sync(&pm->wake_work);

	err = mt7921_mcu_drv_pmctrl(dev);
	if (err < 0)
		goto restore_suspend;

	/* always enable deep sleep during suspend to reduce
	 * power consumption
	 */
	mt76_connac_mcu_set_deep_sleep(mdev, true);

	mt76_txq_schedule_all(&dev->mphy);
	mt76_worker_disable(&mdev->tx_worker);
	mt76_worker_disable(&mdev->sdio.status_worker);
	cancel_work_sync(&mdev->sdio.stat_work);
	clear_bit(MT76_READING_STATS, &dev->mphy.state);
	mt76_tx_status_check(mdev, true);

	mt76_worker_schedule(&mdev->sdio.txrx_worker);
	wait_event_timeout(dev->mt76.sdio.wait,
			   mt76s_txqs_empty(&dev->mt76), 5 * HZ);

	/* It is supposed that SDIO bus is idle at the point */
	err = mt76_connac_mcu_set_hif_suspend(mdev, true);
	if (err)
		goto restore_worker;

	mt76_worker_disable(&mdev->sdio.txrx_worker);
	mt76_worker_disable(&mdev->sdio.net_worker);

	err = mt7921_mcu_fw_pmctrl(dev);
	if (err)
		goto restore_txrx_worker;

	sdio_set_host_pm_flags(func, MMC_PM_KEEP_POWER);

	return 0;

restore_txrx_worker:
	mt76_worker_enable(&mdev->sdio.net_worker);
	mt76_worker_enable(&mdev->sdio.txrx_worker);
	mt76_connac_mcu_set_hif_suspend(mdev, false);

restore_worker:
	mt76_worker_enable(&mdev->tx_worker);
	mt76_worker_enable(&mdev->sdio.status_worker);

	if (!pm->ds_enable)
		mt76_connac_mcu_set_deep_sleep(mdev, false);

restore_suspend:
	clear_bit(MT76_STATE_SUSPEND, &mdev->phy.state);
	pm->suspended = false;

	if (err < 0)
		mt7921_reset(&dev->mt76);

	return err;
}

static int mt7921s_resume(struct device *__dev)
{
	struct sdio_func *func = dev_to_sdio_func(__dev);
	struct mt7921_dev *dev = sdio_get_drvdata(func);
	struct mt76_connac_pm *pm = &dev->pm;
	struct mt76_dev *mdev = &dev->mt76;
	int err;

	clear_bit(MT76_STATE_SUSPEND, &mdev->phy.state);

	err = mt7921_mcu_drv_pmctrl(dev);
	if (err < 0)
		goto failed;

	mt76_worker_enable(&mdev->tx_worker);
	mt76_worker_enable(&mdev->sdio.txrx_worker);
	mt76_worker_enable(&mdev->sdio.status_worker);
	mt76_worker_enable(&mdev->sdio.net_worker);

	/* restore previous ds setting */
	if (!pm->ds_enable)
		mt76_connac_mcu_set_deep_sleep(mdev, false);

	err = mt76_connac_mcu_set_hif_suspend(mdev, false);
failed:
	pm->suspended = false;

	if (err < 0)
		mt7921_reset(&dev->mt76);

	return err;
}

static const struct dev_pm_ops mt7921s_pm_ops = {
	.suspend = mt7921s_suspend,
	.resume = mt7921s_resume,
};
#endif

MODULE_DEVICE_TABLE(sdio, mt7921s_table);
MODULE_FIRMWARE(MT7921_FIRMWARE_WM);
MODULE_FIRMWARE(MT7921_ROM_PATCH);

static struct sdio_driver mt7921s_driver = {
	.name		= KBUILD_MODNAME,
	.probe		= mt7921s_probe,
	.remove		= mt7921s_remove,
	.id_table	= mt7921s_table,
#ifdef CONFIG_PM
	.drv = {
		.pm = &mt7921s_pm_ops,
	}
#endif
};
module_sdio_driver(mt7921s_driver);
MODULE_AUTHOR("Sean Wang <sean.wang@mediatek.com>");
MODULE_LICENSE("Dual BSD/GPL");
