0001
0002
0003
0004 #include <linux/kernel.h>
0005 #include <linux/mmc/sdio_func.h>
0006 #include <linux/module.h>
0007 #include <linux/iopoll.h>
0008
0009 #include "mt7921.h"
0010 #include "../sdio.h"
0011 #include "mac.h"
0012 #include "mcu.h"
0013 #include "regs.h"
0014
0015 static int
0016 mt7921s_mcu_send_message(struct mt76_dev *mdev, struct sk_buff *skb,
0017 int cmd, int *seq)
0018 {
0019 struct mt7921_dev *dev = container_of(mdev, struct mt7921_dev, mt76);
0020 enum mt7921_sdio_pkt_type type = MT7921_SDIO_CMD;
0021 enum mt76_mcuq_id txq = MT_MCUQ_WM;
0022 int ret, pad;
0023
0024
0025
0026
0027
0028
0029 if (dev->fw_assert)
0030 return -EBUSY;
0031
0032 ret = mt76_connac2_mcu_fill_message(mdev, skb, cmd, seq);
0033 if (ret)
0034 return ret;
0035
0036 if (cmd == MCU_UNI_CMD(HIF_CTRL) ||
0037 cmd == MCU_UNI_CMD(SUSPEND) ||
0038 cmd == MCU_UNI_CMD(OFFLOAD))
0039 mdev->mcu.timeout = HZ;
0040 else
0041 mdev->mcu.timeout = 3 * HZ;
0042
0043 if (cmd == MCU_CMD(FW_SCATTER))
0044 type = MT7921_SDIO_FWDL;
0045
0046 mt7921_skb_add_usb_sdio_hdr(dev, skb, type);
0047 pad = round_up(skb->len, 4) - skb->len;
0048 __skb_put_zero(skb, pad);
0049
0050 ret = mt76_tx_queue_skb_raw(dev, mdev->q_mcu[txq], skb, 0);
0051 if (ret)
0052 return ret;
0053
0054 mt76_queue_kick(dev, mdev->q_mcu[txq]);
0055
0056 return ret;
0057 }
0058
0059 static u32 mt7921s_read_rm3r(struct mt7921_dev *dev)
0060 {
0061 struct mt76_sdio *sdio = &dev->mt76.sdio;
0062
0063 return sdio_readl(sdio->func, MCR_D2HRM3R, NULL);
0064 }
0065
0066 static u32 mt7921s_clear_rm3r_drv_own(struct mt7921_dev *dev)
0067 {
0068 struct mt76_sdio *sdio = &dev->mt76.sdio;
0069 u32 val;
0070
0071 val = sdio_readl(sdio->func, MCR_D2HRM3R, NULL);
0072 if (val)
0073 sdio_writel(sdio->func, H2D_SW_INT_CLEAR_MAILBOX_ACK,
0074 MCR_WSICR, NULL);
0075
0076 return val;
0077 }
0078
0079 int mt7921s_mcu_init(struct mt7921_dev *dev)
0080 {
0081 static const struct mt76_mcu_ops mt7921s_mcu_ops = {
0082 .headroom = MT_SDIO_HDR_SIZE +
0083 sizeof(struct mt76_connac2_mcu_txd),
0084 .tailroom = MT_SDIO_TAIL_SIZE,
0085 .mcu_skb_send_msg = mt7921s_mcu_send_message,
0086 .mcu_parse_response = mt7921_mcu_parse_response,
0087 .mcu_rr = mt76_connac_mcu_reg_rr,
0088 .mcu_wr = mt76_connac_mcu_reg_wr,
0089 };
0090 int ret;
0091
0092 mt7921s_mcu_drv_pmctrl(dev);
0093
0094 dev->mt76.mcu_ops = &mt7921s_mcu_ops;
0095
0096 ret = mt7921_run_firmware(dev);
0097 if (ret)
0098 return ret;
0099
0100 set_bit(MT76_STATE_MCU_RUNNING, &dev->mphy.state);
0101
0102 return 0;
0103 }
0104
0105 int mt7921s_mcu_drv_pmctrl(struct mt7921_dev *dev)
0106 {
0107 struct sdio_func *func = dev->mt76.sdio.func;
0108 struct mt76_phy *mphy = &dev->mt76.phy;
0109 struct mt76_connac_pm *pm = &dev->pm;
0110 u32 status;
0111 int err;
0112
0113 sdio_claim_host(func);
0114
0115 sdio_writel(func, WHLPCR_FW_OWN_REQ_CLR, MCR_WHLPCR, NULL);
0116
0117 err = readx_poll_timeout(mt76s_read_pcr, &dev->mt76, status,
0118 status & WHLPCR_IS_DRIVER_OWN, 2000, 1000000);
0119
0120 if (!err && test_bit(MT76_STATE_MCU_RUNNING, &dev->mphy.state))
0121 err = readx_poll_timeout(mt7921s_read_rm3r, dev, status,
0122 status & D2HRM3R_IS_DRIVER_OWN,
0123 2000, 1000000);
0124
0125 sdio_release_host(func);
0126
0127 if (err < 0) {
0128 dev_err(dev->mt76.dev, "driver own failed\n");
0129 return -EIO;
0130 }
0131
0132 clear_bit(MT76_STATE_PM, &mphy->state);
0133
0134 pm->stats.last_wake_event = jiffies;
0135 pm->stats.doze_time += pm->stats.last_wake_event -
0136 pm->stats.last_doze_event;
0137
0138 return 0;
0139 }
0140
0141 int mt7921s_mcu_fw_pmctrl(struct mt7921_dev *dev)
0142 {
0143 struct sdio_func *func = dev->mt76.sdio.func;
0144 struct mt76_phy *mphy = &dev->mt76.phy;
0145 struct mt76_connac_pm *pm = &dev->pm;
0146 u32 status;
0147 int err;
0148
0149 sdio_claim_host(func);
0150
0151 if (test_bit(MT76_STATE_MCU_RUNNING, &dev->mphy.state)) {
0152 err = readx_poll_timeout(mt7921s_clear_rm3r_drv_own,
0153 dev, status,
0154 !(status & D2HRM3R_IS_DRIVER_OWN),
0155 2000, 1000000);
0156 if (err < 0) {
0157 dev_err(dev->mt76.dev, "mailbox ACK not cleared\n");
0158 goto out;
0159 }
0160 }
0161
0162 sdio_writel(func, WHLPCR_FW_OWN_REQ_SET, MCR_WHLPCR, NULL);
0163
0164 err = readx_poll_timeout(mt76s_read_pcr, &dev->mt76, status,
0165 !(status & WHLPCR_IS_DRIVER_OWN), 2000, 1000000);
0166 out:
0167 sdio_release_host(func);
0168
0169 if (err < 0) {
0170 dev_err(dev->mt76.dev, "firmware own failed\n");
0171 clear_bit(MT76_STATE_PM, &mphy->state);
0172 return -EIO;
0173 }
0174
0175 pm->stats.last_doze_event = jiffies;
0176 pm->stats.awake_time += pm->stats.last_doze_event -
0177 pm->stats.last_wake_event;
0178
0179 return 0;
0180 }