0001
0002
0003
0004
0005
0006 #include <linux/kernel.h>
0007 #include <linux/iopoll.h>
0008 #include <linux/module.h>
0009
0010 #include <linux/mmc/host.h>
0011 #include <linux/mmc/sdio_ids.h>
0012 #include <linux/mmc/sdio_func.h>
0013
0014 #include "mt7921.h"
0015 #include "../sdio.h"
0016 #include "mac.h"
0017 #include "mcu.h"
0018
0019 static const struct sdio_device_id mt7921s_table[] = {
0020 { SDIO_DEVICE(SDIO_VENDOR_ID_MEDIATEK, 0x7901) },
0021 { }
0022 };
0023
0024 static void mt7921s_txrx_worker(struct mt76_worker *w)
0025 {
0026 struct mt76_sdio *sdio = container_of(w, struct mt76_sdio,
0027 txrx_worker);
0028 struct mt76_dev *mdev = container_of(sdio, struct mt76_dev, sdio);
0029 struct mt7921_dev *dev = container_of(mdev, struct mt7921_dev, mt76);
0030
0031 if (!mt76_connac_pm_ref(&dev->mphy, &dev->pm)) {
0032 queue_work(mdev->wq, &dev->pm.wake_work);
0033 return;
0034 }
0035
0036 mt76s_txrx_worker(sdio);
0037 mt76_connac_pm_unref(&dev->mphy, &dev->pm);
0038 }
0039
0040 static void mt7921s_unregister_device(struct mt7921_dev *dev)
0041 {
0042 struct mt76_connac_pm *pm = &dev->pm;
0043
0044 cancel_work_sync(&dev->init_work);
0045 mt76_unregister_device(&dev->mt76);
0046 cancel_delayed_work_sync(&pm->ps_work);
0047 cancel_work_sync(&pm->wake_work);
0048
0049 mt76s_deinit(&dev->mt76);
0050 mt7921s_wfsys_reset(dev);
0051 skb_queue_purge(&dev->mt76.mcu.res_q);
0052
0053 mt76_free_device(&dev->mt76);
0054 }
0055
0056 static int mt7921s_parse_intr(struct mt76_dev *dev, struct mt76s_intr *intr)
0057 {
0058 struct mt76_sdio *sdio = &dev->sdio;
0059 struct mt7921_sdio_intr *irq_data = sdio->intr_data;
0060 int i, err;
0061
0062 sdio_claim_host(sdio->func);
0063 err = sdio_readsb(sdio->func, irq_data, MCR_WHISR, sizeof(*irq_data));
0064 sdio_release_host(sdio->func);
0065
0066 if (err < 0)
0067 return err;
0068
0069 if (irq_data->rx.num[0] > 16 ||
0070 irq_data->rx.num[1] > 128)
0071 return -EINVAL;
0072
0073 intr->isr = irq_data->isr;
0074 intr->rec_mb = irq_data->rec_mb;
0075 intr->tx.wtqcr = irq_data->tx.wtqcr;
0076 intr->rx.num = irq_data->rx.num;
0077 for (i = 0; i < 2 ; i++) {
0078 if (!i)
0079 intr->rx.len[0] = irq_data->rx.len0;
0080 else
0081 intr->rx.len[1] = irq_data->rx.len1;
0082 }
0083
0084 return 0;
0085 }
0086
0087 static int mt7921s_probe(struct sdio_func *func,
0088 const struct sdio_device_id *id)
0089 {
0090 static const struct mt76_driver_ops drv_ops = {
0091 .txwi_size = MT_SDIO_TXD_SIZE,
0092 .survey_flags = SURVEY_INFO_TIME_TX |
0093 SURVEY_INFO_TIME_RX |
0094 SURVEY_INFO_TIME_BSS_RX,
0095 .tx_prepare_skb = mt7921_usb_sdio_tx_prepare_skb,
0096 .tx_complete_skb = mt7921_usb_sdio_tx_complete_skb,
0097 .tx_status_data = mt7921_usb_sdio_tx_status_data,
0098 .rx_skb = mt7921_queue_rx_skb,
0099 .sta_ps = mt7921_sta_ps,
0100 .sta_add = mt7921_mac_sta_add,
0101 .sta_assoc = mt7921_mac_sta_assoc,
0102 .sta_remove = mt7921_mac_sta_remove,
0103 .update_survey = mt7921_update_channel,
0104 };
0105 static const struct mt76_bus_ops mt7921s_ops = {
0106 .rr = mt76s_rr,
0107 .rmw = mt76s_rmw,
0108 .wr = mt76s_wr,
0109 .write_copy = mt76s_write_copy,
0110 .read_copy = mt76s_read_copy,
0111 .wr_rp = mt76s_wr_rp,
0112 .rd_rp = mt76s_rd_rp,
0113 .type = MT76_BUS_SDIO,
0114 };
0115 static const struct mt7921_hif_ops mt7921_sdio_ops = {
0116 .init_reset = mt7921s_init_reset,
0117 .reset = mt7921s_mac_reset,
0118 .mcu_init = mt7921s_mcu_init,
0119 .drv_own = mt7921s_mcu_drv_pmctrl,
0120 .fw_own = mt7921s_mcu_fw_pmctrl,
0121 };
0122
0123 struct mt7921_dev *dev;
0124 struct mt76_dev *mdev;
0125 int ret;
0126
0127 mdev = mt76_alloc_device(&func->dev, sizeof(*dev), &mt7921_ops,
0128 &drv_ops);
0129 if (!mdev)
0130 return -ENOMEM;
0131
0132 dev = container_of(mdev, struct mt7921_dev, mt76);
0133 dev->hif_ops = &mt7921_sdio_ops;
0134
0135 sdio_set_drvdata(func, dev);
0136
0137 ret = mt76s_init(mdev, func, &mt7921s_ops);
0138 if (ret < 0)
0139 goto error;
0140
0141 ret = mt76s_hw_init(mdev, func, MT76_CONNAC2_SDIO);
0142 if (ret)
0143 goto error;
0144
0145 mdev->rev = (mt76_rr(dev, MT_HW_CHIPID) << 16) |
0146 (mt76_rr(dev, MT_HW_REV) & 0xff);
0147 dev_dbg(mdev->dev, "ASIC revision: %04x\n", mdev->rev);
0148
0149 mdev->sdio.parse_irq = mt7921s_parse_intr;
0150 mdev->sdio.intr_data = devm_kmalloc(mdev->dev,
0151 sizeof(struct mt7921_sdio_intr),
0152 GFP_KERNEL);
0153 if (!mdev->sdio.intr_data) {
0154 ret = -ENOMEM;
0155 goto error;
0156 }
0157
0158 ret = mt76s_alloc_rx_queue(mdev, MT_RXQ_MAIN);
0159 if (ret)
0160 goto error;
0161
0162 ret = mt76s_alloc_rx_queue(mdev, MT_RXQ_MCU);
0163 if (ret)
0164 goto error;
0165
0166 ret = mt76s_alloc_tx(mdev);
0167 if (ret)
0168 goto error;
0169
0170 ret = mt76_worker_setup(mt76_hw(dev), &mdev->sdio.txrx_worker,
0171 mt7921s_txrx_worker, "sdio-txrx");
0172 if (ret)
0173 goto error;
0174
0175 sched_set_fifo_low(mdev->sdio.txrx_worker.task);
0176
0177 ret = mt7921_register_device(dev);
0178 if (ret)
0179 goto error;
0180
0181 return 0;
0182
0183 error:
0184 mt76s_deinit(&dev->mt76);
0185 mt76_free_device(&dev->mt76);
0186
0187 return ret;
0188 }
0189
0190 static void mt7921s_remove(struct sdio_func *func)
0191 {
0192 struct mt7921_dev *dev = sdio_get_drvdata(func);
0193
0194 mt7921s_unregister_device(dev);
0195 }
0196
0197 #ifdef CONFIG_PM
0198 static int mt7921s_suspend(struct device *__dev)
0199 {
0200 struct sdio_func *func = dev_to_sdio_func(__dev);
0201 struct mt7921_dev *dev = sdio_get_drvdata(func);
0202 struct mt76_connac_pm *pm = &dev->pm;
0203 struct mt76_dev *mdev = &dev->mt76;
0204 int err;
0205
0206 pm->suspended = true;
0207 set_bit(MT76_STATE_SUSPEND, &mdev->phy.state);
0208
0209 cancel_delayed_work_sync(&pm->ps_work);
0210 cancel_work_sync(&pm->wake_work);
0211
0212 err = mt7921_mcu_drv_pmctrl(dev);
0213 if (err < 0)
0214 goto restore_suspend;
0215
0216
0217
0218
0219 mt76_connac_mcu_set_deep_sleep(mdev, true);
0220
0221 mt76_txq_schedule_all(&dev->mphy);
0222 mt76_worker_disable(&mdev->tx_worker);
0223 mt76_worker_disable(&mdev->sdio.status_worker);
0224 cancel_work_sync(&mdev->sdio.stat_work);
0225 clear_bit(MT76_READING_STATS, &dev->mphy.state);
0226 mt76_tx_status_check(mdev, true);
0227
0228 mt76_worker_schedule(&mdev->sdio.txrx_worker);
0229 wait_event_timeout(dev->mt76.sdio.wait,
0230 mt76s_txqs_empty(&dev->mt76), 5 * HZ);
0231
0232
0233 err = mt76_connac_mcu_set_hif_suspend(mdev, true);
0234 if (err)
0235 goto restore_worker;
0236
0237 mt76_worker_disable(&mdev->sdio.txrx_worker);
0238 mt76_worker_disable(&mdev->sdio.net_worker);
0239
0240 err = mt7921_mcu_fw_pmctrl(dev);
0241 if (err)
0242 goto restore_txrx_worker;
0243
0244 sdio_set_host_pm_flags(func, MMC_PM_KEEP_POWER);
0245
0246 return 0;
0247
0248 restore_txrx_worker:
0249 mt76_worker_enable(&mdev->sdio.net_worker);
0250 mt76_worker_enable(&mdev->sdio.txrx_worker);
0251 mt76_connac_mcu_set_hif_suspend(mdev, false);
0252
0253 restore_worker:
0254 mt76_worker_enable(&mdev->tx_worker);
0255 mt76_worker_enable(&mdev->sdio.status_worker);
0256
0257 if (!pm->ds_enable)
0258 mt76_connac_mcu_set_deep_sleep(mdev, false);
0259
0260 restore_suspend:
0261 clear_bit(MT76_STATE_SUSPEND, &mdev->phy.state);
0262 pm->suspended = false;
0263
0264 return err;
0265 }
0266
0267 static int mt7921s_resume(struct device *__dev)
0268 {
0269 struct sdio_func *func = dev_to_sdio_func(__dev);
0270 struct mt7921_dev *dev = sdio_get_drvdata(func);
0271 struct mt76_connac_pm *pm = &dev->pm;
0272 struct mt76_dev *mdev = &dev->mt76;
0273 int err;
0274
0275 clear_bit(MT76_STATE_SUSPEND, &mdev->phy.state);
0276
0277 err = mt7921_mcu_drv_pmctrl(dev);
0278 if (err < 0)
0279 return err;
0280
0281 mt76_worker_enable(&mdev->tx_worker);
0282 mt76_worker_enable(&mdev->sdio.txrx_worker);
0283 mt76_worker_enable(&mdev->sdio.status_worker);
0284 mt76_worker_enable(&mdev->sdio.net_worker);
0285
0286
0287 if (!pm->ds_enable)
0288 mt76_connac_mcu_set_deep_sleep(mdev, false);
0289
0290 err = mt76_connac_mcu_set_hif_suspend(mdev, false);
0291 if (err)
0292 return err;
0293
0294 pm->suspended = false;
0295
0296 return err;
0297 }
0298
0299 static const struct dev_pm_ops mt7921s_pm_ops = {
0300 .suspend = mt7921s_suspend,
0301 .resume = mt7921s_resume,
0302 };
0303 #endif
0304
0305 MODULE_DEVICE_TABLE(sdio, mt7921s_table);
0306 MODULE_FIRMWARE(MT7921_FIRMWARE_WM);
0307 MODULE_FIRMWARE(MT7921_ROM_PATCH);
0308
0309 static struct sdio_driver mt7921s_driver = {
0310 .name = KBUILD_MODNAME,
0311 .probe = mt7921s_probe,
0312 .remove = mt7921s_remove,
0313 .id_table = mt7921s_table,
0314 #ifdef CONFIG_PM
0315 .drv = {
0316 .pm = &mt7921s_pm_ops,
0317 }
0318 #endif
0319 };
0320 module_sdio_driver(mt7921s_driver);
0321 MODULE_AUTHOR("Sean Wang <sean.wang@mediatek.com>");
0322 MODULE_LICENSE("Dual BSD/GPL");