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