linux/drivers/net/wireless/mediatek/mt76/mt7603/mcu.c
<<
>>
Prefs
   1// SPDX-License-Identifier: ISC
   2
   3#include <linux/firmware.h>
   4#include "mt7603.h"
   5#include "mcu.h"
   6#include "eeprom.h"
   7
   8#define MCU_SKB_RESERVE 8
   9
  10struct mt7603_fw_trailer {
  11        char fw_ver[10];
  12        char build_date[15];
  13        __le32 dl_len;
  14} __packed;
  15
  16static int
  17mt7603_mcu_parse_response(struct mt76_dev *mdev, int cmd,
  18                          struct sk_buff *skb, int seq)
  19{
  20        struct mt7603_dev *dev = container_of(mdev, struct mt7603_dev, mt76);
  21        struct mt7603_mcu_rxd *rxd;
  22
  23        if (!skb) {
  24                dev_err(mdev->dev, "MCU message %02x (seq %d) timed out\n",
  25                        abs(cmd), seq);
  26                dev->mcu_hang = MT7603_WATCHDOG_TIMEOUT;
  27                return -ETIMEDOUT;
  28        }
  29
  30        rxd = (struct mt7603_mcu_rxd *)skb->data;
  31        if (seq != rxd->seq)
  32                return -EAGAIN;
  33
  34        return 0;
  35}
  36
  37static int
  38mt7603_mcu_skb_send_msg(struct mt76_dev *mdev, struct sk_buff *skb,
  39                        int cmd, int *wait_seq)
  40{
  41        struct mt7603_dev *dev = container_of(mdev, struct mt7603_dev, mt76);
  42        int hdrlen = dev->mcu_running ? sizeof(struct mt7603_mcu_txd) : 12;
  43        struct mt7603_mcu_txd *txd;
  44        u8 seq;
  45
  46        mdev->mcu.timeout = 3 * HZ;
  47
  48        seq = ++mdev->mcu.msg_seq & 0xf;
  49        if (!seq)
  50                seq = ++mdev->mcu.msg_seq & 0xf;
  51
  52        txd = (struct mt7603_mcu_txd *)skb_push(skb, hdrlen);
  53
  54        txd->len = cpu_to_le16(skb->len);
  55        if (cmd == -MCU_CMD_FW_SCATTER)
  56                txd->pq_id = cpu_to_le16(MCU_PORT_QUEUE_FW);
  57        else
  58                txd->pq_id = cpu_to_le16(MCU_PORT_QUEUE);
  59        txd->pkt_type = MCU_PKT_ID;
  60        txd->seq = seq;
  61
  62        if (cmd < 0) {
  63                txd->cid = -cmd;
  64                txd->set_query = MCU_Q_NA;
  65        } else {
  66                txd->cid = MCU_CMD_EXT_CID;
  67                txd->ext_cid = cmd;
  68                txd->set_query = MCU_Q_SET;
  69                txd->ext_cid_ack = 1;
  70        }
  71
  72        if (wait_seq)
  73                *wait_seq = seq;
  74
  75        return mt76_tx_queue_skb_raw(dev, mdev->q_mcu[MT_MCUQ_WM], skb, 0);
  76}
  77
  78static int
  79mt7603_mcu_init_download(struct mt7603_dev *dev, u32 addr, u32 len)
  80{
  81        struct {
  82                __le32 addr;
  83                __le32 len;
  84                __le32 mode;
  85        } req = {
  86                .addr = cpu_to_le32(addr),
  87                .len = cpu_to_le32(len),
  88                .mode = cpu_to_le32(BIT(31)),
  89        };
  90
  91        return mt76_mcu_send_msg(&dev->mt76, -MCU_CMD_TARGET_ADDRESS_LEN_REQ,
  92                                 &req, sizeof(req), true);
  93}
  94
  95static int
  96mt7603_mcu_start_firmware(struct mt7603_dev *dev, u32 addr)
  97{
  98        struct {
  99                __le32 override;
 100                __le32 addr;
 101        } req = {
 102                .override = cpu_to_le32(addr ? 1 : 0),
 103                .addr = cpu_to_le32(addr),
 104        };
 105
 106        return mt76_mcu_send_msg(&dev->mt76, -MCU_CMD_FW_START_REQ, &req,
 107                                 sizeof(req), true);
 108}
 109
 110static int
 111mt7603_mcu_restart(struct mt76_dev *dev)
 112{
 113        return mt76_mcu_send_msg(dev, -MCU_CMD_RESTART_DL_REQ, NULL, 0, true);
 114}
 115
 116static int mt7603_load_firmware(struct mt7603_dev *dev)
 117{
 118        const struct firmware *fw;
 119        const struct mt7603_fw_trailer *hdr;
 120        const char *firmware;
 121        int dl_len;
 122        u32 addr, val;
 123        int ret;
 124
 125        if (is_mt7628(dev)) {
 126                if (mt76xx_rev(dev) == MT7628_REV_E1)
 127                        firmware = MT7628_FIRMWARE_E1;
 128                else
 129                        firmware = MT7628_FIRMWARE_E2;
 130        } else {
 131                if (mt76xx_rev(dev) < MT7603_REV_E2)
 132                        firmware = MT7603_FIRMWARE_E1;
 133                else
 134                        firmware = MT7603_FIRMWARE_E2;
 135        }
 136
 137        ret = request_firmware(&fw, firmware, dev->mt76.dev);
 138        if (ret)
 139                return ret;
 140
 141        if (!fw || !fw->data || fw->size < sizeof(*hdr)) {
 142                dev_err(dev->mt76.dev, "Invalid firmware\n");
 143                ret = -EINVAL;
 144                goto out;
 145        }
 146
 147        hdr = (const struct mt7603_fw_trailer *)(fw->data + fw->size -
 148                                                 sizeof(*hdr));
 149
 150        dev_info(dev->mt76.dev, "Firmware Version: %.10s\n", hdr->fw_ver);
 151        dev_info(dev->mt76.dev, "Build Time: %.15s\n", hdr->build_date);
 152
 153        addr = mt7603_reg_map(dev, 0x50012498);
 154        mt76_wr(dev, addr, 0x5);
 155        mt76_wr(dev, addr, 0x5);
 156        udelay(1);
 157
 158        /* switch to bypass mode */
 159        mt76_rmw(dev, MT_SCH_4, MT_SCH_4_FORCE_QID,
 160                 MT_SCH_4_BYPASS | FIELD_PREP(MT_SCH_4_FORCE_QID, 5));
 161
 162        val = mt76_rr(dev, MT_TOP_MISC2);
 163        if (val & BIT(1)) {
 164                dev_info(dev->mt76.dev, "Firmware already running...\n");
 165                goto running;
 166        }
 167
 168        if (!mt76_poll_msec(dev, MT_TOP_MISC2, BIT(0) | BIT(1), BIT(0), 500)) {
 169                dev_err(dev->mt76.dev, "Timeout waiting for ROM code to become ready\n");
 170                ret = -EIO;
 171                goto out;
 172        }
 173
 174        dl_len = le32_to_cpu(hdr->dl_len) + 4;
 175        ret = mt7603_mcu_init_download(dev, MCU_FIRMWARE_ADDRESS, dl_len);
 176        if (ret) {
 177                dev_err(dev->mt76.dev, "Download request failed\n");
 178                goto out;
 179        }
 180
 181        ret = mt76_mcu_send_firmware(&dev->mt76, -MCU_CMD_FW_SCATTER,
 182                                     fw->data, dl_len);
 183        if (ret) {
 184                dev_err(dev->mt76.dev, "Failed to send firmware to device\n");
 185                goto out;
 186        }
 187
 188        ret = mt7603_mcu_start_firmware(dev, MCU_FIRMWARE_ADDRESS);
 189        if (ret) {
 190                dev_err(dev->mt76.dev, "Failed to start firmware\n");
 191                goto out;
 192        }
 193
 194        if (!mt76_poll_msec(dev, MT_TOP_MISC2, BIT(1), BIT(1), 500)) {
 195                dev_err(dev->mt76.dev, "Timeout waiting for firmware to initialize\n");
 196                ret = -EIO;
 197                goto out;
 198        }
 199
 200running:
 201        mt76_clear(dev, MT_SCH_4, MT_SCH_4_FORCE_QID | MT_SCH_4_BYPASS);
 202
 203        mt76_set(dev, MT_SCH_4, BIT(8));
 204        mt76_clear(dev, MT_SCH_4, BIT(8));
 205
 206        dev->mcu_running = true;
 207        snprintf(dev->mt76.hw->wiphy->fw_version,
 208                 sizeof(dev->mt76.hw->wiphy->fw_version),
 209                 "%.10s-%.15s", hdr->fw_ver, hdr->build_date);
 210        dev_info(dev->mt76.dev, "firmware init done\n");
 211
 212out:
 213        release_firmware(fw);
 214
 215        return ret;
 216}
 217
 218int mt7603_mcu_init(struct mt7603_dev *dev)
 219{
 220        static const struct mt76_mcu_ops mt7603_mcu_ops = {
 221                .headroom = sizeof(struct mt7603_mcu_txd),
 222                .mcu_skb_send_msg = mt7603_mcu_skb_send_msg,
 223                .mcu_parse_response = mt7603_mcu_parse_response,
 224                .mcu_restart = mt7603_mcu_restart,
 225        };
 226
 227        dev->mt76.mcu_ops = &mt7603_mcu_ops;
 228        return mt7603_load_firmware(dev);
 229}
 230
 231void mt7603_mcu_exit(struct mt7603_dev *dev)
 232{
 233        __mt76_mcu_restart(&dev->mt76);
 234        skb_queue_purge(&dev->mt76.mcu.res_q);
 235}
 236
 237int mt7603_mcu_set_eeprom(struct mt7603_dev *dev)
 238{
 239        static const u16 req_fields[] = {
 240#define WORD(_start)                    \
 241                _start,                 \
 242                _start + 1
 243#define GROUP_2G(_start)                \
 244                WORD(_start),           \
 245                WORD(_start + 2),       \
 246                WORD(_start + 4)
 247
 248                MT_EE_NIC_CONF_0 + 1,
 249                WORD(MT_EE_NIC_CONF_1),
 250                MT_EE_WIFI_RF_SETTING,
 251                MT_EE_TX_POWER_DELTA_BW40,
 252                MT_EE_TX_POWER_DELTA_BW80 + 1,
 253                MT_EE_TX_POWER_EXT_PA_5G,
 254                MT_EE_TEMP_SENSOR_CAL,
 255                GROUP_2G(MT_EE_TX_POWER_0_START_2G),
 256                GROUP_2G(MT_EE_TX_POWER_1_START_2G),
 257                WORD(MT_EE_TX_POWER_CCK),
 258                WORD(MT_EE_TX_POWER_OFDM_2G_6M),
 259                WORD(MT_EE_TX_POWER_OFDM_2G_24M),
 260                WORD(MT_EE_TX_POWER_OFDM_2G_54M),
 261                WORD(MT_EE_TX_POWER_HT_BPSK_QPSK),
 262                WORD(MT_EE_TX_POWER_HT_16_64_QAM),
 263                WORD(MT_EE_TX_POWER_HT_64_QAM),
 264                MT_EE_ELAN_RX_MODE_GAIN,
 265                MT_EE_ELAN_RX_MODE_NF,
 266                MT_EE_ELAN_RX_MODE_P1DB,
 267                MT_EE_ELAN_BYPASS_MODE_GAIN,
 268                MT_EE_ELAN_BYPASS_MODE_NF,
 269                MT_EE_ELAN_BYPASS_MODE_P1DB,
 270                WORD(MT_EE_STEP_NUM_NEG_6_7),
 271                WORD(MT_EE_STEP_NUM_NEG_4_5),
 272                WORD(MT_EE_STEP_NUM_NEG_2_3),
 273                WORD(MT_EE_STEP_NUM_NEG_0_1),
 274                WORD(MT_EE_REF_STEP_24G),
 275                WORD(MT_EE_STEP_NUM_PLUS_1_2),
 276                WORD(MT_EE_STEP_NUM_PLUS_3_4),
 277                WORD(MT_EE_STEP_NUM_PLUS_5_6),
 278                MT_EE_STEP_NUM_PLUS_7,
 279                MT_EE_XTAL_FREQ_OFFSET,
 280                MT_EE_XTAL_TRIM_2_COMP,
 281                MT_EE_XTAL_TRIM_3_COMP,
 282                MT_EE_XTAL_WF_RFCAL,
 283
 284                /* unknown fields below */
 285                WORD(0x24),
 286                0x34,
 287                0x39,
 288                0x3b,
 289                WORD(0x42),
 290                WORD(0x9e),
 291                0xf2,
 292                WORD(0xf8),
 293                0xfa,
 294                0x12e,
 295                WORD(0x130), WORD(0x132), WORD(0x134), WORD(0x136),
 296                WORD(0x138), WORD(0x13a), WORD(0x13c), WORD(0x13e),
 297
 298#undef GROUP_2G
 299#undef WORD
 300
 301        };
 302        struct req_data {
 303                __le16 addr;
 304                u8 val;
 305                u8 pad;
 306        } __packed;
 307        struct {
 308                u8 buffer_mode;
 309                u8 len;
 310                u8 pad[2];
 311        } req_hdr = {
 312                .buffer_mode = 1,
 313                .len = ARRAY_SIZE(req_fields) - 1,
 314        };
 315        const int size = 0xff * sizeof(struct req_data);
 316        u8 *req, *eep = (u8 *)dev->mt76.eeprom.data;
 317        int i, ret, len = sizeof(req_hdr) + size;
 318        struct req_data *data;
 319
 320        BUILD_BUG_ON(ARRAY_SIZE(req_fields) * sizeof(*data) > size);
 321
 322        req = kmalloc(len, GFP_KERNEL);
 323        if (!req)
 324                return -ENOMEM;
 325
 326        memcpy(req, &req_hdr, sizeof(req_hdr));
 327        data = (struct req_data *)(req + sizeof(req_hdr));
 328        memset(data, 0, size);
 329        for (i = 0; i < ARRAY_SIZE(req_fields); i++) {
 330                data[i].addr = cpu_to_le16(req_fields[i]);
 331                data[i].val = eep[req_fields[i]];
 332        }
 333
 334        ret = mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD_EFUSE_BUFFER_MODE,
 335                                req, len, true);
 336        kfree(req);
 337
 338        return ret;
 339}
 340
 341static int mt7603_mcu_set_tx_power(struct mt7603_dev *dev)
 342{
 343        struct {
 344                u8 center_channel;
 345                u8 tssi;
 346                u8 temp_comp;
 347                u8 target_power[2];
 348                u8 rate_power_delta[14];
 349                u8 bw_power_delta;
 350                u8 ch_power_delta[6];
 351                u8 temp_comp_power[17];
 352                u8 reserved;
 353        } req = {
 354                .center_channel = dev->mphy.chandef.chan->hw_value,
 355#define EEP_VAL(n) ((u8 *)dev->mt76.eeprom.data)[n]
 356                .tssi = EEP_VAL(MT_EE_NIC_CONF_1 + 1),
 357                .temp_comp = EEP_VAL(MT_EE_NIC_CONF_1),
 358                .target_power = {
 359                        EEP_VAL(MT_EE_TX_POWER_0_START_2G + 2),
 360                        EEP_VAL(MT_EE_TX_POWER_1_START_2G + 2)
 361                },
 362                .bw_power_delta = EEP_VAL(MT_EE_TX_POWER_DELTA_BW40),
 363                .ch_power_delta = {
 364                        EEP_VAL(MT_EE_TX_POWER_0_START_2G + 3),
 365                        EEP_VAL(MT_EE_TX_POWER_0_START_2G + 4),
 366                        EEP_VAL(MT_EE_TX_POWER_0_START_2G + 5),
 367                        EEP_VAL(MT_EE_TX_POWER_1_START_2G + 3),
 368                        EEP_VAL(MT_EE_TX_POWER_1_START_2G + 4),
 369                        EEP_VAL(MT_EE_TX_POWER_1_START_2G + 5)
 370                },
 371#undef EEP_VAL
 372        };
 373        u8 *eep = (u8 *)dev->mt76.eeprom.data;
 374
 375        memcpy(req.rate_power_delta, eep + MT_EE_TX_POWER_CCK,
 376               sizeof(req.rate_power_delta));
 377
 378        memcpy(req.temp_comp_power, eep + MT_EE_STEP_NUM_NEG_6_7,
 379               sizeof(req.temp_comp_power));
 380
 381        return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD_SET_TX_POWER_CTRL,
 382                                 &req, sizeof(req), true);
 383}
 384
 385int mt7603_mcu_set_channel(struct mt7603_dev *dev)
 386{
 387        struct cfg80211_chan_def *chandef = &dev->mphy.chandef;
 388        struct ieee80211_hw *hw = mt76_hw(dev);
 389        int n_chains = hweight8(dev->mphy.antenna_mask);
 390        struct {
 391                u8 control_chan;
 392                u8 center_chan;
 393                u8 bw;
 394                u8 tx_streams;
 395                u8 rx_streams;
 396                u8 _res0[7];
 397                u8 txpower[21];
 398                u8 _res1[3];
 399        } req = {
 400                .control_chan = chandef->chan->hw_value,
 401                .center_chan = chandef->chan->hw_value,
 402                .bw = MT_BW_20,
 403                .tx_streams = n_chains,
 404                .rx_streams = n_chains,
 405        };
 406        s8 tx_power;
 407        int i, ret;
 408
 409        if (dev->mphy.chandef.width == NL80211_CHAN_WIDTH_40) {
 410                req.bw = MT_BW_40;
 411                if (chandef->center_freq1 > chandef->chan->center_freq)
 412                        req.center_chan += 2;
 413                else
 414                        req.center_chan -= 2;
 415        }
 416
 417        tx_power = hw->conf.power_level * 2;
 418        if (dev->mphy.antenna_mask == 3)
 419                tx_power -= 6;
 420        tx_power = min(tx_power, dev->tx_power_limit);
 421
 422        dev->mphy.txpower_cur = tx_power;
 423
 424        for (i = 0; i < ARRAY_SIZE(req.txpower); i++)
 425                req.txpower[i] = tx_power;
 426
 427        ret = mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD_CHANNEL_SWITCH, &req,
 428                                sizeof(req), true);
 429        if (ret)
 430                return ret;
 431
 432        return mt7603_mcu_set_tx_power(dev);
 433}
 434