1 // SPDX-License-Identifier: ISC 2 /* 3 * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name> 4 * Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com> 5 */ 6 7 #include <linux/kernel.h> 8 #include <linux/firmware.h> 9 #include <linux/delay.h> 10 11 #include "mt76x02_mcu.h" 12 13 int mt76x02_mcu_msg_send(struct mt76_dev *mdev, int cmd, const void *data, 14 int len, bool wait_resp) 15 { 16 struct mt76x02_dev *dev = container_of(mdev, struct mt76x02_dev, mt76); 17 unsigned long expires = jiffies + HZ; 18 struct sk_buff *skb; 19 u32 tx_info; 20 int ret; 21 u8 seq; 22 23 if (dev->mcu_timeout) 24 return -EIO; 25 26 skb = mt76_mcu_msg_alloc(mdev, data, len); 27 if (!skb) 28 return -ENOMEM; 29 30 mutex_lock(&mdev->mcu.mutex); 31 32 seq = ++mdev->mcu.msg_seq & 0xf; 33 if (!seq) 34 seq = ++mdev->mcu.msg_seq & 0xf; 35 36 tx_info = MT_MCU_MSG_TYPE_CMD | 37 FIELD_PREP(MT_MCU_MSG_CMD_TYPE, cmd) | 38 FIELD_PREP(MT_MCU_MSG_CMD_SEQ, seq) | 39 FIELD_PREP(MT_MCU_MSG_PORT, CPU_TX_PORT) | 40 FIELD_PREP(MT_MCU_MSG_LEN, skb->len); 41 42 ret = mt76_tx_queue_skb_raw(dev, MT_TXQ_MCU, skb, tx_info); 43 if (ret) 44 goto out; 45 46 while (wait_resp) { 47 u32 *rxfce; 48 bool check_seq = false; 49 50 skb = mt76_mcu_get_response(&dev->mt76, expires); 51 if (!skb) { 52 dev_err(mdev->dev, 53 "MCU message %d (seq %d) timed out\n", cmd, 54 seq); 55 ret = -ETIMEDOUT; 56 dev->mcu_timeout = 1; 57 break; 58 } 59 60 rxfce = (u32 *)skb->cb; 61 62 if (seq == FIELD_GET(MT_RX_FCE_INFO_CMD_SEQ, *rxfce)) 63 check_seq = true; 64 65 dev_kfree_skb(skb); 66 if (check_seq) 67 break; 68 } 69 70 out: 71 mutex_unlock(&mdev->mcu.mutex); 72 73 return ret; 74 } 75 EXPORT_SYMBOL_GPL(mt76x02_mcu_msg_send); 76 77 int mt76x02_mcu_function_select(struct mt76x02_dev *dev, enum mcu_function func, 78 u32 val) 79 { 80 struct { 81 __le32 id; 82 __le32 value; 83 } __packed __aligned(4) msg = { 84 .id = cpu_to_le32(func), 85 .value = cpu_to_le32(val), 86 }; 87 bool wait = false; 88 89 if (func != Q_SELECT) 90 wait = true; 91 92 return mt76_mcu_send_msg(&dev->mt76, CMD_FUN_SET_OP, &msg, 93 sizeof(msg), wait); 94 } 95 EXPORT_SYMBOL_GPL(mt76x02_mcu_function_select); 96 97 int mt76x02_mcu_set_radio_state(struct mt76x02_dev *dev, bool on) 98 { 99 struct { 100 __le32 mode; 101 __le32 level; 102 } __packed __aligned(4) msg = { 103 .mode = cpu_to_le32(on ? RADIO_ON : RADIO_OFF), 104 .level = cpu_to_le32(0), 105 }; 106 107 return mt76_mcu_send_msg(&dev->mt76, CMD_POWER_SAVING_OP, &msg, 108 sizeof(msg), false); 109 } 110 EXPORT_SYMBOL_GPL(mt76x02_mcu_set_radio_state); 111 112 int mt76x02_mcu_calibrate(struct mt76x02_dev *dev, int type, u32 param) 113 { 114 struct { 115 __le32 id; 116 __le32 value; 117 } __packed __aligned(4) msg = { 118 .id = cpu_to_le32(type), 119 .value = cpu_to_le32(param), 120 }; 121 bool is_mt76x2e = mt76_is_mmio(&dev->mt76) && is_mt76x2(dev); 122 int ret; 123 124 if (is_mt76x2e) 125 mt76_rmw(dev, MT_MCU_COM_REG0, BIT(31), 0); 126 127 ret = mt76_mcu_send_msg(&dev->mt76, CMD_CALIBRATION_OP, &msg, 128 sizeof(msg), true); 129 if (ret) 130 return ret; 131 132 if (is_mt76x2e && 133 WARN_ON(!mt76_poll_msec(dev, MT_MCU_COM_REG0, 134 BIT(31), BIT(31), 100))) 135 return -ETIMEDOUT; 136 137 return 0; 138 } 139 EXPORT_SYMBOL_GPL(mt76x02_mcu_calibrate); 140 141 int mt76x02_mcu_cleanup(struct mt76x02_dev *dev) 142 { 143 struct sk_buff *skb; 144 145 mt76_wr(dev, MT_MCU_INT_LEVEL, 1); 146 usleep_range(20000, 30000); 147 148 while ((skb = skb_dequeue(&dev->mt76.mcu.res_q)) != NULL) 149 dev_kfree_skb(skb); 150 151 return 0; 152 } 153 EXPORT_SYMBOL_GPL(mt76x02_mcu_cleanup); 154 155 void mt76x02_set_ethtool_fwver(struct mt76x02_dev *dev, 156 const struct mt76x02_fw_header *h) 157 { 158 u16 bld = le16_to_cpu(h->build_ver); 159 u16 ver = le16_to_cpu(h->fw_ver); 160 161 snprintf(dev->mt76.hw->wiphy->fw_version, 162 sizeof(dev->mt76.hw->wiphy->fw_version), 163 "%d.%d.%02d-b%x", 164 (ver >> 12) & 0xf, (ver >> 8) & 0xf, ver & 0xf, bld); 165 } 166 EXPORT_SYMBOL_GPL(mt76x02_set_ethtool_fwver); 167