linux/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c
<<
>>
Prefs
   1// SPDX-License-Identifier: ISC
   2/* Copyright (C) 2020 MediaTek Inc. */
   3
   4#include "mt76_connac_mcu.h"
   5
   6int mt76_connac_mcu_start_firmware(struct mt76_dev *dev, u32 addr, u32 option)
   7{
   8        struct {
   9                __le32 option;
  10                __le32 addr;
  11        } req = {
  12                .option = cpu_to_le32(option),
  13                .addr = cpu_to_le32(addr),
  14        };
  15
  16        return mt76_mcu_send_msg(dev, MCU_CMD_FW_START_REQ, &req, sizeof(req),
  17                                 true);
  18}
  19EXPORT_SYMBOL_GPL(mt76_connac_mcu_start_firmware);
  20
  21int mt76_connac_mcu_patch_sem_ctrl(struct mt76_dev *dev, bool get)
  22{
  23        u32 op = get ? PATCH_SEM_GET : PATCH_SEM_RELEASE;
  24        struct {
  25                __le32 op;
  26        } req = {
  27                .op = cpu_to_le32(op),
  28        };
  29
  30        return mt76_mcu_send_msg(dev, MCU_CMD_PATCH_SEM_CONTROL, &req,
  31                                 sizeof(req), true);
  32}
  33EXPORT_SYMBOL_GPL(mt76_connac_mcu_patch_sem_ctrl);
  34
  35int mt76_connac_mcu_start_patch(struct mt76_dev *dev)
  36{
  37        struct {
  38                u8 check_crc;
  39                u8 reserved[3];
  40        } req = {
  41                .check_crc = 0,
  42        };
  43
  44        return mt76_mcu_send_msg(dev, MCU_CMD_PATCH_FINISH_REQ, &req,
  45                                 sizeof(req), true);
  46}
  47EXPORT_SYMBOL_GPL(mt76_connac_mcu_start_patch);
  48
  49#define MCU_PATCH_ADDRESS       0x200000
  50
  51int mt76_connac_mcu_init_download(struct mt76_dev *dev, u32 addr, u32 len,
  52                                  u32 mode)
  53{
  54        struct {
  55                __le32 addr;
  56                __le32 len;
  57                __le32 mode;
  58        } req = {
  59                .addr = cpu_to_le32(addr),
  60                .len = cpu_to_le32(len),
  61                .mode = cpu_to_le32(mode),
  62        };
  63        int cmd;
  64
  65        if (is_mt7921(dev) &&
  66            (req.addr == cpu_to_le32(MCU_PATCH_ADDRESS) || addr == 0x900000))
  67                cmd = MCU_CMD_PATCH_START_REQ;
  68        else
  69                cmd = MCU_CMD_TARGET_ADDRESS_LEN_REQ;
  70
  71        return mt76_mcu_send_msg(dev, cmd, &req, sizeof(req), true);
  72}
  73EXPORT_SYMBOL_GPL(mt76_connac_mcu_init_download);
  74
  75int mt76_connac_mcu_set_channel_domain(struct mt76_phy *phy)
  76{
  77        struct mt76_dev *dev = phy->dev;
  78        struct mt76_connac_mcu_channel_domain {
  79                u8 alpha2[4]; /* regulatory_request.alpha2 */
  80                u8 bw_2g; /* BW_20_40M          0
  81                           * BW_20M             1
  82                           * BW_20_40_80M       2
  83                           * BW_20_40_80_160M   3
  84                           * BW_20_40_80_8080M  4
  85                           */
  86                u8 bw_5g;
  87                __le16 pad;
  88                u8 n_2ch;
  89                u8 n_5ch;
  90                __le16 pad2;
  91        } __packed hdr = {
  92                .bw_2g = 0,
  93                .bw_5g = 3,
  94        };
  95        struct mt76_connac_mcu_chan {
  96                __le16 hw_value;
  97                __le16 pad;
  98                __le32 flags;
  99        } __packed channel;
 100        int len, i, n_max_channels, n_2ch = 0, n_5ch = 0;
 101        struct ieee80211_channel *chan;
 102        struct sk_buff *skb;
 103
 104        n_max_channels = phy->sband_2g.sband.n_channels +
 105                         phy->sband_5g.sband.n_channels;
 106        len = sizeof(hdr) + n_max_channels * sizeof(channel);
 107
 108        skb = mt76_mcu_msg_alloc(dev, NULL, len);
 109        if (!skb)
 110                return -ENOMEM;
 111
 112        skb_reserve(skb, sizeof(hdr));
 113
 114        for (i = 0; i < phy->sband_2g.sband.n_channels; i++) {
 115                chan = &phy->sband_2g.sband.channels[i];
 116                if (chan->flags & IEEE80211_CHAN_DISABLED)
 117                        continue;
 118
 119                channel.hw_value = cpu_to_le16(chan->hw_value);
 120                channel.flags = cpu_to_le32(chan->flags);
 121                channel.pad = 0;
 122
 123                skb_put_data(skb, &channel, sizeof(channel));
 124                n_2ch++;
 125        }
 126        for (i = 0; i < phy->sband_5g.sband.n_channels; i++) {
 127                chan = &phy->sband_5g.sband.channels[i];
 128                if (chan->flags & IEEE80211_CHAN_DISABLED)
 129                        continue;
 130
 131                channel.hw_value = cpu_to_le16(chan->hw_value);
 132                channel.flags = cpu_to_le32(chan->flags);
 133                channel.pad = 0;
 134
 135                skb_put_data(skb, &channel, sizeof(channel));
 136                n_5ch++;
 137        }
 138
 139        BUILD_BUG_ON(sizeof(dev->alpha2) > sizeof(hdr.alpha2));
 140        memcpy(hdr.alpha2, dev->alpha2, sizeof(dev->alpha2));
 141        hdr.n_2ch = n_2ch;
 142        hdr.n_5ch = n_5ch;
 143
 144        memcpy(__skb_push(skb, sizeof(hdr)), &hdr, sizeof(hdr));
 145
 146        return mt76_mcu_skb_send_msg(dev, skb, MCU_CMD_SET_CHAN_DOMAIN, false);
 147}
 148EXPORT_SYMBOL_GPL(mt76_connac_mcu_set_channel_domain);
 149
 150int mt76_connac_mcu_set_mac_enable(struct mt76_dev *dev, int band, bool enable,
 151                                   bool hdr_trans)
 152{
 153        struct {
 154                u8 enable;
 155                u8 band;
 156                u8 rsv[2];
 157        } __packed req_mac = {
 158                .enable = enable,
 159                .band = band,
 160        };
 161
 162        return mt76_mcu_send_msg(dev, MCU_EXT_CMD_MAC_INIT_CTRL, &req_mac,
 163                                 sizeof(req_mac), true);
 164}
 165EXPORT_SYMBOL_GPL(mt76_connac_mcu_set_mac_enable);
 166
 167int mt76_connac_mcu_set_vif_ps(struct mt76_dev *dev, struct ieee80211_vif *vif)
 168{
 169        struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv;
 170        struct {
 171                u8 bss_idx;
 172                u8 ps_state; /* 0: device awake
 173                              * 1: static power save
 174                              * 2: dynamic power saving
 175                              */
 176        } req = {
 177                .bss_idx = mvif->idx,
 178                .ps_state = vif->bss_conf.ps ? 2 : 0,
 179        };
 180
 181        if (vif->type != NL80211_IFTYPE_STATION)
 182                return -EOPNOTSUPP;
 183
 184        return mt76_mcu_send_msg(dev, MCU_CMD_SET_PS_PROFILE, &req,
 185                                 sizeof(req), false);
 186}
 187EXPORT_SYMBOL_GPL(mt76_connac_mcu_set_vif_ps);
 188
 189int mt76_connac_mcu_set_rts_thresh(struct mt76_dev *dev, u32 val, u8 band)
 190{
 191        struct {
 192                u8 prot_idx;
 193                u8 band;
 194                u8 rsv[2];
 195                __le32 len_thresh;
 196                __le32 pkt_thresh;
 197        } __packed req = {
 198                .prot_idx = 1,
 199                .band = band,
 200                .len_thresh = cpu_to_le32(val),
 201                .pkt_thresh = cpu_to_le32(0x2),
 202        };
 203
 204        return mt76_mcu_send_msg(dev, MCU_EXT_CMD_PROTECT_CTRL, &req,
 205                                 sizeof(req), true);
 206}
 207EXPORT_SYMBOL_GPL(mt76_connac_mcu_set_rts_thresh);
 208
 209void mt76_connac_mcu_beacon_loss_iter(void *priv, u8 *mac,
 210                                      struct ieee80211_vif *vif)
 211{
 212        struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv;
 213        struct mt76_connac_beacon_loss_event *event = priv;
 214
 215        if (mvif->idx != event->bss_idx)
 216                return;
 217
 218        if (!(vif->driver_flags & IEEE80211_VIF_BEACON_FILTER))
 219                return;
 220
 221        ieee80211_beacon_loss(vif);
 222}
 223EXPORT_SYMBOL_GPL(mt76_connac_mcu_beacon_loss_iter);
 224
 225struct tlv *
 226mt76_connac_mcu_add_nested_tlv(struct sk_buff *skb, int tag, int len,
 227                               void *sta_ntlv, void *sta_wtbl)
 228{
 229        struct sta_ntlv_hdr *ntlv_hdr = sta_ntlv;
 230        struct tlv *sta_hdr = sta_wtbl;
 231        struct tlv *ptlv, tlv = {
 232                .tag = cpu_to_le16(tag),
 233                .len = cpu_to_le16(len),
 234        };
 235        u16 ntlv;
 236
 237        ptlv = skb_put(skb, len);
 238        memcpy(ptlv, &tlv, sizeof(tlv));
 239
 240        ntlv = le16_to_cpu(ntlv_hdr->tlv_num);
 241        ntlv_hdr->tlv_num = cpu_to_le16(ntlv + 1);
 242
 243        if (sta_hdr) {
 244                u16 size = le16_to_cpu(sta_hdr->len);
 245
 246                sta_hdr->len = cpu_to_le16(size + len);
 247        }
 248
 249        return ptlv;
 250}
 251EXPORT_SYMBOL_GPL(mt76_connac_mcu_add_nested_tlv);
 252
 253struct sk_buff *
 254mt76_connac_mcu_alloc_sta_req(struct mt76_dev *dev, struct mt76_vif *mvif,
 255                              struct mt76_wcid *wcid)
 256{
 257        struct sta_req_hdr hdr = {
 258                .bss_idx = mvif->idx,
 259                .muar_idx = wcid ? mvif->omac_idx : 0,
 260                .is_tlv_append = 1,
 261        };
 262        struct sk_buff *skb;
 263
 264        mt76_connac_mcu_get_wlan_idx(dev, wcid, &hdr.wlan_idx_lo,
 265                                     &hdr.wlan_idx_hi);
 266        skb = mt76_mcu_msg_alloc(dev, NULL, MT76_CONNAC_STA_UPDATE_MAX_SIZE);
 267        if (!skb)
 268                return ERR_PTR(-ENOMEM);
 269
 270        skb_put_data(skb, &hdr, sizeof(hdr));
 271
 272        return skb;
 273}
 274EXPORT_SYMBOL_GPL(mt76_connac_mcu_alloc_sta_req);
 275
 276struct wtbl_req_hdr *
 277mt76_connac_mcu_alloc_wtbl_req(struct mt76_dev *dev, struct mt76_wcid *wcid,
 278                               int cmd, void *sta_wtbl, struct sk_buff **skb)
 279{
 280        struct tlv *sta_hdr = sta_wtbl;
 281        struct wtbl_req_hdr hdr = {
 282                .operation = cmd,
 283        };
 284        struct sk_buff *nskb = *skb;
 285
 286        mt76_connac_mcu_get_wlan_idx(dev, wcid, &hdr.wlan_idx_lo,
 287                                     &hdr.wlan_idx_hi);
 288        if (!nskb) {
 289                nskb = mt76_mcu_msg_alloc(dev, NULL,
 290                                          MT76_CONNAC_WTBL_UPDATE_MAX_SIZE);
 291                if (!nskb)
 292                        return ERR_PTR(-ENOMEM);
 293
 294                *skb = nskb;
 295        }
 296
 297        if (sta_hdr)
 298                sta_hdr->len = cpu_to_le16(sizeof(hdr));
 299
 300        return skb_put_data(nskb, &hdr, sizeof(hdr));
 301}
 302EXPORT_SYMBOL_GPL(mt76_connac_mcu_alloc_wtbl_req);
 303
 304void mt76_connac_mcu_sta_basic_tlv(struct sk_buff *skb,
 305                                   struct ieee80211_vif *vif,
 306                                   struct ieee80211_sta *sta,
 307                                   bool enable, bool newly)
 308{
 309        struct sta_rec_basic *basic;
 310        struct tlv *tlv;
 311        int conn_type;
 312
 313        tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_BASIC, sizeof(*basic));
 314
 315        basic = (struct sta_rec_basic *)tlv;
 316        basic->extra_info = cpu_to_le16(EXTRA_INFO_VER);
 317
 318        if (enable) {
 319                if (newly)
 320                        basic->extra_info |= cpu_to_le16(EXTRA_INFO_NEW);
 321                basic->conn_state = CONN_STATE_PORT_SECURE;
 322        } else {
 323                basic->conn_state = CONN_STATE_DISCONNECT;
 324        }
 325
 326        if (!sta) {
 327                basic->conn_type = cpu_to_le32(CONNECTION_INFRA_BC);
 328                eth_broadcast_addr(basic->peer_addr);
 329                return;
 330        }
 331
 332        switch (vif->type) {
 333        case NL80211_IFTYPE_MESH_POINT:
 334        case NL80211_IFTYPE_AP:
 335                if (vif->p2p)
 336                        conn_type = CONNECTION_P2P_GC;
 337                else
 338                        conn_type = CONNECTION_INFRA_STA;
 339                basic->conn_type = cpu_to_le32(conn_type);
 340                basic->aid = cpu_to_le16(sta->aid);
 341                break;
 342        case NL80211_IFTYPE_STATION:
 343                if (vif->p2p)
 344                        conn_type = CONNECTION_P2P_GO;
 345                else
 346                        conn_type = CONNECTION_INFRA_AP;
 347                basic->conn_type = cpu_to_le32(conn_type);
 348                basic->aid = cpu_to_le16(vif->bss_conf.aid);
 349                break;
 350        case NL80211_IFTYPE_ADHOC:
 351                basic->conn_type = cpu_to_le32(CONNECTION_IBSS_ADHOC);
 352                basic->aid = cpu_to_le16(sta->aid);
 353                break;
 354        default:
 355                WARN_ON(1);
 356                break;
 357        }
 358
 359        memcpy(basic->peer_addr, sta->addr, ETH_ALEN);
 360        basic->qos = sta->wme;
 361}
 362EXPORT_SYMBOL_GPL(mt76_connac_mcu_sta_basic_tlv);
 363
 364static void
 365mt76_connac_mcu_sta_uapsd(struct sk_buff *skb, struct ieee80211_vif *vif,
 366                          struct ieee80211_sta *sta)
 367{
 368        struct sta_rec_uapsd *uapsd;
 369        struct tlv *tlv;
 370
 371        if (vif->type != NL80211_IFTYPE_AP || !sta->wme)
 372                return;
 373
 374        tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_APPS, sizeof(*uapsd));
 375        uapsd = (struct sta_rec_uapsd *)tlv;
 376
 377        if (sta->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_VO) {
 378                uapsd->dac_map |= BIT(3);
 379                uapsd->tac_map |= BIT(3);
 380        }
 381        if (sta->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_VI) {
 382                uapsd->dac_map |= BIT(2);
 383                uapsd->tac_map |= BIT(2);
 384        }
 385        if (sta->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_BE) {
 386                uapsd->dac_map |= BIT(1);
 387                uapsd->tac_map |= BIT(1);
 388        }
 389        if (sta->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_BK) {
 390                uapsd->dac_map |= BIT(0);
 391                uapsd->tac_map |= BIT(0);
 392        }
 393        uapsd->max_sp = sta->max_sp;
 394}
 395
 396void mt76_connac_mcu_wtbl_hdr_trans_tlv(struct sk_buff *skb,
 397                                        struct ieee80211_vif *vif,
 398                                        struct mt76_wcid *wcid,
 399                                        void *sta_wtbl, void *wtbl_tlv)
 400{
 401        struct wtbl_hdr_trans *htr;
 402        struct tlv *tlv;
 403
 404        tlv = mt76_connac_mcu_add_nested_tlv(skb, WTBL_HDR_TRANS,
 405                                             sizeof(*htr),
 406                                             wtbl_tlv, sta_wtbl);
 407        htr = (struct wtbl_hdr_trans *)tlv;
 408        htr->no_rx_trans = !test_bit(MT_WCID_FLAG_HDR_TRANS, &wcid->flags);
 409
 410        if (vif->type == NL80211_IFTYPE_STATION)
 411                htr->to_ds = true;
 412        else
 413                htr->from_ds = true;
 414
 415        if (test_bit(MT_WCID_FLAG_4ADDR, &wcid->flags)) {
 416                htr->to_ds = true;
 417                htr->from_ds = true;
 418        }
 419}
 420EXPORT_SYMBOL_GPL(mt76_connac_mcu_wtbl_hdr_trans_tlv);
 421
 422int mt76_connac_mcu_sta_update_hdr_trans(struct mt76_dev *dev,
 423                                         struct ieee80211_vif *vif,
 424                                         struct mt76_wcid *wcid, int cmd)
 425{
 426        struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv;
 427        struct wtbl_req_hdr *wtbl_hdr;
 428        struct tlv *sta_wtbl;
 429        struct sk_buff *skb;
 430
 431        skb = mt76_connac_mcu_alloc_sta_req(dev, mvif, wcid);
 432        if (IS_ERR(skb))
 433                return PTR_ERR(skb);
 434
 435        sta_wtbl = mt76_connac_mcu_add_tlv(skb, STA_REC_WTBL,
 436                                           sizeof(struct tlv));
 437
 438        wtbl_hdr = mt76_connac_mcu_alloc_wtbl_req(dev, wcid, WTBL_SET,
 439                                                  sta_wtbl, &skb);
 440        if (IS_ERR(wtbl_hdr))
 441                return PTR_ERR(wtbl_hdr);
 442
 443        mt76_connac_mcu_wtbl_hdr_trans_tlv(skb, vif, wcid, sta_wtbl, wtbl_hdr);
 444
 445        return mt76_mcu_skb_send_msg(dev, skb, cmd, true);
 446}
 447EXPORT_SYMBOL_GPL(mt76_connac_mcu_sta_update_hdr_trans);
 448
 449void mt76_connac_mcu_wtbl_generic_tlv(struct mt76_dev *dev,
 450                                      struct sk_buff *skb,
 451                                      struct ieee80211_vif *vif,
 452                                      struct ieee80211_sta *sta,
 453                                      void *sta_wtbl, void *wtbl_tlv)
 454{
 455        struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv;
 456        struct wtbl_generic *generic;
 457        struct wtbl_rx *rx;
 458        struct wtbl_spe *spe;
 459        struct tlv *tlv;
 460
 461        tlv = mt76_connac_mcu_add_nested_tlv(skb, WTBL_GENERIC,
 462                                             sizeof(*generic),
 463                                             wtbl_tlv, sta_wtbl);
 464
 465        generic = (struct wtbl_generic *)tlv;
 466
 467        if (sta) {
 468                if (vif->type == NL80211_IFTYPE_STATION)
 469                        generic->partial_aid = cpu_to_le16(vif->bss_conf.aid);
 470                else
 471                        generic->partial_aid = cpu_to_le16(sta->aid);
 472                memcpy(generic->peer_addr, sta->addr, ETH_ALEN);
 473                generic->muar_idx = mvif->omac_idx;
 474                generic->qos = sta->wme;
 475        } else {
 476                if (is_mt7921(dev) &&
 477                    vif->type == NL80211_IFTYPE_STATION)
 478                        memcpy(generic->peer_addr, vif->bss_conf.bssid,
 479                               ETH_ALEN);
 480                else
 481                        eth_broadcast_addr(generic->peer_addr);
 482
 483                generic->muar_idx = 0xe;
 484        }
 485
 486        tlv = mt76_connac_mcu_add_nested_tlv(skb, WTBL_RX, sizeof(*rx),
 487                                             wtbl_tlv, sta_wtbl);
 488
 489        rx = (struct wtbl_rx *)tlv;
 490        rx->rca1 = sta ? vif->type != NL80211_IFTYPE_AP : 1;
 491        rx->rca2 = 1;
 492        rx->rv = 1;
 493
 494        if (is_mt7921(dev))
 495                return;
 496
 497        tlv = mt76_connac_mcu_add_nested_tlv(skb, WTBL_SPE, sizeof(*spe),
 498                                             wtbl_tlv, sta_wtbl);
 499        spe = (struct wtbl_spe *)tlv;
 500        spe->spe_idx = 24;
 501}
 502EXPORT_SYMBOL_GPL(mt76_connac_mcu_wtbl_generic_tlv);
 503
 504static void
 505mt76_connac_mcu_sta_amsdu_tlv(struct sk_buff *skb, struct ieee80211_sta *sta,
 506                              struct ieee80211_vif *vif)
 507{
 508        struct mt76_wcid *wcid = (struct mt76_wcid *)sta->drv_priv;
 509        struct sta_rec_amsdu *amsdu;
 510        struct tlv *tlv;
 511
 512        if (vif->type != NL80211_IFTYPE_AP &&
 513            vif->type != NL80211_IFTYPE_STATION)
 514                return;
 515
 516        if (!sta->max_amsdu_len)
 517                return;
 518
 519        tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_HW_AMSDU, sizeof(*amsdu));
 520        amsdu = (struct sta_rec_amsdu *)tlv;
 521        amsdu->max_amsdu_num = 8;
 522        amsdu->amsdu_en = true;
 523        amsdu->max_mpdu_size = sta->max_amsdu_len >=
 524                               IEEE80211_MAX_MPDU_LEN_VHT_7991;
 525
 526        wcid->amsdu = true;
 527}
 528
 529#define HE_PHY(p, c)    u8_get_bits(c, IEEE80211_HE_PHY_##p)
 530#define HE_MAC(m, c)    u8_get_bits(c, IEEE80211_HE_MAC_##m)
 531static void
 532mt76_connac_mcu_sta_he_tlv(struct sk_buff *skb, struct ieee80211_sta *sta)
 533{
 534        struct ieee80211_sta_he_cap *he_cap = &sta->he_cap;
 535        struct ieee80211_he_cap_elem *elem = &he_cap->he_cap_elem;
 536        struct sta_rec_he *he;
 537        struct tlv *tlv;
 538        u32 cap = 0;
 539
 540        tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_HE, sizeof(*he));
 541
 542        he = (struct sta_rec_he *)tlv;
 543
 544        if (elem->mac_cap_info[0] & IEEE80211_HE_MAC_CAP0_HTC_HE)
 545                cap |= STA_REC_HE_CAP_HTC;
 546
 547        if (elem->mac_cap_info[2] & IEEE80211_HE_MAC_CAP2_BSR)
 548                cap |= STA_REC_HE_CAP_BSR;
 549
 550        if (elem->mac_cap_info[3] & IEEE80211_HE_MAC_CAP3_OMI_CONTROL)
 551                cap |= STA_REC_HE_CAP_OM;
 552
 553        if (elem->mac_cap_info[4] & IEEE80211_HE_MAC_CAP4_AMSDU_IN_AMPDU)
 554                cap |= STA_REC_HE_CAP_AMSDU_IN_AMPDU;
 555
 556        if (elem->mac_cap_info[4] & IEEE80211_HE_MAC_CAP4_BQR)
 557                cap |= STA_REC_HE_CAP_BQR;
 558
 559        if (elem->phy_cap_info[0] &
 560            (IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_RU_MAPPING_IN_2G |
 561             IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_RU_MAPPING_IN_5G))
 562                cap |= STA_REC_HE_CAP_BW20_RU242_SUPPORT;
 563
 564        if (elem->phy_cap_info[1] &
 565            IEEE80211_HE_PHY_CAP1_LDPC_CODING_IN_PAYLOAD)
 566                cap |= STA_REC_HE_CAP_LDPC;
 567
 568        if (elem->phy_cap_info[1] &
 569            IEEE80211_HE_PHY_CAP1_HE_LTF_AND_GI_FOR_HE_PPDUS_0_8US)
 570                cap |= STA_REC_HE_CAP_SU_PPDU_1LTF_8US_GI;
 571
 572        if (elem->phy_cap_info[2] &
 573            IEEE80211_HE_PHY_CAP2_NDP_4x_LTF_AND_3_2US)
 574                cap |= STA_REC_HE_CAP_NDP_4LTF_3DOT2MS_GI;
 575
 576        if (elem->phy_cap_info[2] &
 577            IEEE80211_HE_PHY_CAP2_STBC_TX_UNDER_80MHZ)
 578                cap |= STA_REC_HE_CAP_LE_EQ_80M_TX_STBC;
 579
 580        if (elem->phy_cap_info[2] &
 581            IEEE80211_HE_PHY_CAP2_STBC_RX_UNDER_80MHZ)
 582                cap |= STA_REC_HE_CAP_LE_EQ_80M_RX_STBC;
 583
 584        if (elem->phy_cap_info[6] &
 585            IEEE80211_HE_PHY_CAP6_PARTIAL_BW_EXT_RANGE)
 586                cap |= STA_REC_HE_CAP_PARTIAL_BW_EXT_RANGE;
 587
 588        if (elem->phy_cap_info[7] &
 589            IEEE80211_HE_PHY_CAP7_HE_SU_MU_PPDU_4XLTF_AND_08_US_GI)
 590                cap |= STA_REC_HE_CAP_SU_MU_PPDU_4LTF_8US_GI;
 591
 592        if (elem->phy_cap_info[7] &
 593            IEEE80211_HE_PHY_CAP7_STBC_TX_ABOVE_80MHZ)
 594                cap |= STA_REC_HE_CAP_GT_80M_TX_STBC;
 595
 596        if (elem->phy_cap_info[7] &
 597            IEEE80211_HE_PHY_CAP7_STBC_RX_ABOVE_80MHZ)
 598                cap |= STA_REC_HE_CAP_GT_80M_RX_STBC;
 599
 600        if (elem->phy_cap_info[8] &
 601            IEEE80211_HE_PHY_CAP8_HE_ER_SU_PPDU_4XLTF_AND_08_US_GI)
 602                cap |= STA_REC_HE_CAP_ER_SU_PPDU_4LTF_8US_GI;
 603
 604        if (elem->phy_cap_info[8] &
 605            IEEE80211_HE_PHY_CAP8_HE_ER_SU_1XLTF_AND_08_US_GI)
 606                cap |= STA_REC_HE_CAP_ER_SU_PPDU_1LTF_8US_GI;
 607
 608        if (elem->phy_cap_info[9] &
 609            IEEE80211_HE_PHY_CAP9_NON_TRIGGERED_CQI_FEEDBACK)
 610                cap |= STA_REC_HE_CAP_TRIG_CQI_FK;
 611
 612        if (elem->phy_cap_info[9] &
 613            IEEE80211_HE_PHY_CAP9_TX_1024_QAM_LESS_THAN_242_TONE_RU)
 614                cap |= STA_REC_HE_CAP_TX_1024QAM_UNDER_RU242;
 615
 616        if (elem->phy_cap_info[9] &
 617            IEEE80211_HE_PHY_CAP9_RX_1024_QAM_LESS_THAN_242_TONE_RU)
 618                cap |= STA_REC_HE_CAP_RX_1024QAM_UNDER_RU242;
 619
 620        he->he_cap = cpu_to_le32(cap);
 621
 622        switch (sta->bandwidth) {
 623        case IEEE80211_STA_RX_BW_160:
 624                if (elem->phy_cap_info[0] &
 625                    IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_80PLUS80_MHZ_IN_5G)
 626                        he->max_nss_mcs[CMD_HE_MCS_BW8080] =
 627                                he_cap->he_mcs_nss_supp.rx_mcs_80p80;
 628
 629                he->max_nss_mcs[CMD_HE_MCS_BW160] =
 630                                he_cap->he_mcs_nss_supp.rx_mcs_160;
 631                fallthrough;
 632        default:
 633                he->max_nss_mcs[CMD_HE_MCS_BW80] =
 634                                he_cap->he_mcs_nss_supp.rx_mcs_80;
 635                break;
 636        }
 637
 638        he->t_frame_dur =
 639                HE_MAC(CAP1_TF_MAC_PAD_DUR_MASK, elem->mac_cap_info[1]);
 640        he->max_ampdu_exp =
 641                HE_MAC(CAP3_MAX_AMPDU_LEN_EXP_MASK, elem->mac_cap_info[3]);
 642
 643        he->bw_set =
 644                HE_PHY(CAP0_CHANNEL_WIDTH_SET_MASK, elem->phy_cap_info[0]);
 645        he->device_class =
 646                HE_PHY(CAP1_DEVICE_CLASS_A, elem->phy_cap_info[1]);
 647        he->punc_pream_rx =
 648                HE_PHY(CAP1_PREAMBLE_PUNC_RX_MASK, elem->phy_cap_info[1]);
 649
 650        he->dcm_tx_mode =
 651                HE_PHY(CAP3_DCM_MAX_CONST_TX_MASK, elem->phy_cap_info[3]);
 652        he->dcm_tx_max_nss =
 653                HE_PHY(CAP3_DCM_MAX_TX_NSS_2, elem->phy_cap_info[3]);
 654        he->dcm_rx_mode =
 655                HE_PHY(CAP3_DCM_MAX_CONST_RX_MASK, elem->phy_cap_info[3]);
 656        he->dcm_rx_max_nss =
 657                HE_PHY(CAP3_DCM_MAX_RX_NSS_2, elem->phy_cap_info[3]);
 658        he->dcm_rx_max_nss =
 659                HE_PHY(CAP8_DCM_MAX_RU_MASK, elem->phy_cap_info[8]);
 660
 661        he->pkt_ext = 2;
 662}
 663
 664static u8
 665mt76_connac_get_phy_mode_v2(struct mt76_phy *mphy, struct ieee80211_vif *vif,
 666                            enum nl80211_band band, struct ieee80211_sta *sta)
 667{
 668        struct ieee80211_sta_ht_cap *ht_cap;
 669        struct ieee80211_sta_vht_cap *vht_cap;
 670        const struct ieee80211_sta_he_cap *he_cap;
 671        u8 mode = 0;
 672
 673        if (sta) {
 674                ht_cap = &sta->ht_cap;
 675                vht_cap = &sta->vht_cap;
 676                he_cap = &sta->he_cap;
 677        } else {
 678                struct ieee80211_supported_band *sband;
 679
 680                sband = mphy->hw->wiphy->bands[band];
 681                ht_cap = &sband->ht_cap;
 682                vht_cap = &sband->vht_cap;
 683                he_cap = ieee80211_get_he_iftype_cap(sband, vif->type);
 684        }
 685
 686        if (band == NL80211_BAND_2GHZ) {
 687                mode |= PHY_TYPE_BIT_HR_DSSS | PHY_TYPE_BIT_ERP;
 688
 689                if (ht_cap->ht_supported)
 690                        mode |= PHY_TYPE_BIT_HT;
 691
 692                if (he_cap->has_he)
 693                        mode |= PHY_TYPE_BIT_HE;
 694        } else if (band == NL80211_BAND_5GHZ) {
 695                mode |= PHY_TYPE_BIT_OFDM;
 696
 697                if (ht_cap->ht_supported)
 698                        mode |= PHY_TYPE_BIT_HT;
 699
 700                if (vht_cap->vht_supported)
 701                        mode |= PHY_TYPE_BIT_VHT;
 702
 703                if (he_cap->has_he)
 704                        mode |= PHY_TYPE_BIT_HE;
 705        }
 706
 707        return mode;
 708}
 709
 710void mt76_connac_mcu_sta_tlv(struct mt76_phy *mphy, struct sk_buff *skb,
 711                             struct ieee80211_sta *sta,
 712                             struct ieee80211_vif *vif,
 713                             u8 rcpi, u8 sta_state)
 714{
 715        struct cfg80211_chan_def *chandef = &mphy->chandef;
 716        enum nl80211_band band = chandef->chan->band;
 717        struct mt76_dev *dev = mphy->dev;
 718        struct sta_rec_ra_info *ra_info;
 719        struct sta_rec_state *state;
 720        struct sta_rec_phy *phy;
 721        struct tlv *tlv;
 722
 723        /* starec ht */
 724        if (sta->ht_cap.ht_supported) {
 725                struct sta_rec_ht *ht;
 726
 727                tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_HT, sizeof(*ht));
 728                ht = (struct sta_rec_ht *)tlv;
 729                ht->ht_cap = cpu_to_le16(sta->ht_cap.cap);
 730        }
 731
 732        /* starec vht */
 733        if (sta->vht_cap.vht_supported) {
 734                struct sta_rec_vht *vht;
 735                int len;
 736
 737                len = is_mt7921(dev) ? sizeof(*vht) : sizeof(*vht) - 4;
 738                tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_VHT, len);
 739                vht = (struct sta_rec_vht *)tlv;
 740                vht->vht_cap = cpu_to_le32(sta->vht_cap.cap);
 741                vht->vht_rx_mcs_map = sta->vht_cap.vht_mcs.rx_mcs_map;
 742                vht->vht_tx_mcs_map = sta->vht_cap.vht_mcs.tx_mcs_map;
 743        }
 744
 745        /* starec uapsd */
 746        mt76_connac_mcu_sta_uapsd(skb, vif, sta);
 747
 748        if (!is_mt7921(dev))
 749                return;
 750
 751        if (sta->ht_cap.ht_supported)
 752                mt76_connac_mcu_sta_amsdu_tlv(skb, sta, vif);
 753
 754        /* starec he */
 755        if (sta->he_cap.has_he)
 756                mt76_connac_mcu_sta_he_tlv(skb, sta);
 757
 758        tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_PHY, sizeof(*phy));
 759        phy = (struct sta_rec_phy *)tlv;
 760        phy->phy_type = mt76_connac_get_phy_mode_v2(mphy, vif, band, sta);
 761        phy->basic_rate = cpu_to_le16((u16)vif->bss_conf.basic_rates);
 762        phy->rcpi = rcpi;
 763        phy->ampdu = FIELD_PREP(IEEE80211_HT_AMPDU_PARM_FACTOR,
 764                                sta->ht_cap.ampdu_factor) |
 765                     FIELD_PREP(IEEE80211_HT_AMPDU_PARM_DENSITY,
 766                                sta->ht_cap.ampdu_density);
 767
 768        tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_RA, sizeof(*ra_info));
 769        ra_info = (struct sta_rec_ra_info *)tlv;
 770        ra_info->legacy = cpu_to_le16((u16)sta->supp_rates[band]);
 771
 772        if (sta->ht_cap.ht_supported)
 773                memcpy(ra_info->rx_mcs_bitmask, sta->ht_cap.mcs.rx_mask,
 774                       HT_MCS_MASK_NUM);
 775
 776        tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_STATE, sizeof(*state));
 777        state = (struct sta_rec_state *)tlv;
 778        state->state = sta_state;
 779
 780        if (sta->vht_cap.vht_supported) {
 781                state->vht_opmode = sta->bandwidth;
 782                state->vht_opmode |= (sta->rx_nss - 1) <<
 783                        IEEE80211_OPMODE_NOTIF_RX_NSS_SHIFT;
 784        }
 785}
 786EXPORT_SYMBOL_GPL(mt76_connac_mcu_sta_tlv);
 787
 788static void
 789mt76_connac_mcu_wtbl_smps_tlv(struct sk_buff *skb, struct ieee80211_sta *sta,
 790                              void *sta_wtbl, void *wtbl_tlv)
 791{
 792        struct wtbl_smps *smps;
 793        struct tlv *tlv;
 794
 795        tlv = mt76_connac_mcu_add_nested_tlv(skb, WTBL_SMPS, sizeof(*smps),
 796                                             wtbl_tlv, sta_wtbl);
 797        smps = (struct wtbl_smps *)tlv;
 798
 799        if (sta->smps_mode == IEEE80211_SMPS_DYNAMIC)
 800                smps->smps = true;
 801}
 802
 803void mt76_connac_mcu_wtbl_ht_tlv(struct mt76_dev *dev, struct sk_buff *skb,
 804                                 struct ieee80211_sta *sta, void *sta_wtbl,
 805                                 void *wtbl_tlv)
 806{
 807        struct wtbl_ht *ht = NULL;
 808        struct tlv *tlv;
 809        u32 flags = 0;
 810
 811        if (sta->ht_cap.ht_supported) {
 812                tlv = mt76_connac_mcu_add_nested_tlv(skb, WTBL_HT, sizeof(*ht),
 813                                                     wtbl_tlv, sta_wtbl);
 814                ht = (struct wtbl_ht *)tlv;
 815                ht->ldpc = !!(sta->ht_cap.cap & IEEE80211_HT_CAP_LDPC_CODING);
 816                ht->af = sta->ht_cap.ampdu_factor;
 817                ht->mm = sta->ht_cap.ampdu_density;
 818                ht->ht = true;
 819        }
 820
 821        if (sta->vht_cap.vht_supported) {
 822                struct wtbl_vht *vht;
 823                u8 af;
 824
 825                tlv = mt76_connac_mcu_add_nested_tlv(skb, WTBL_VHT,
 826                                                     sizeof(*vht), wtbl_tlv,
 827                                                     sta_wtbl);
 828                vht = (struct wtbl_vht *)tlv;
 829                vht->ldpc = !!(sta->vht_cap.cap & IEEE80211_VHT_CAP_RXLDPC);
 830                vht->vht = true;
 831
 832                af = FIELD_GET(IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK,
 833                               sta->vht_cap.cap);
 834                if (ht)
 835                        ht->af = max(ht->af, af);
 836        }
 837
 838        mt76_connac_mcu_wtbl_smps_tlv(skb, sta, sta_wtbl, wtbl_tlv);
 839
 840        if (!is_mt7921(dev) && sta->ht_cap.ht_supported) {
 841                /* sgi */
 842                u32 msk = MT_WTBL_W5_SHORT_GI_20 | MT_WTBL_W5_SHORT_GI_40 |
 843                          MT_WTBL_W5_SHORT_GI_80 | MT_WTBL_W5_SHORT_GI_160;
 844                struct wtbl_raw *raw;
 845
 846                tlv = mt76_connac_mcu_add_nested_tlv(skb, WTBL_RAW_DATA,
 847                                                     sizeof(*raw), wtbl_tlv,
 848                                                     sta_wtbl);
 849
 850                if (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20)
 851                        flags |= MT_WTBL_W5_SHORT_GI_20;
 852                if (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40)
 853                        flags |= MT_WTBL_W5_SHORT_GI_40;
 854
 855                if (sta->vht_cap.vht_supported) {
 856                        if (sta->vht_cap.cap & IEEE80211_VHT_CAP_SHORT_GI_80)
 857                                flags |= MT_WTBL_W5_SHORT_GI_80;
 858                        if (sta->vht_cap.cap & IEEE80211_VHT_CAP_SHORT_GI_160)
 859                                flags |= MT_WTBL_W5_SHORT_GI_160;
 860                }
 861                raw = (struct wtbl_raw *)tlv;
 862                raw->val = cpu_to_le32(flags);
 863                raw->msk = cpu_to_le32(~msk);
 864                raw->wtbl_idx = 1;
 865                raw->dw = 5;
 866        }
 867}
 868EXPORT_SYMBOL_GPL(mt76_connac_mcu_wtbl_ht_tlv);
 869
 870int mt76_connac_mcu_sta_cmd(struct mt76_phy *phy,
 871                            struct mt76_sta_cmd_info *info)
 872{
 873        struct mt76_vif *mvif = (struct mt76_vif *)info->vif->drv_priv;
 874        struct mt76_dev *dev = phy->dev;
 875        struct wtbl_req_hdr *wtbl_hdr;
 876        struct tlv *sta_wtbl;
 877        struct sk_buff *skb;
 878
 879        skb = mt76_connac_mcu_alloc_sta_req(dev, mvif, info->wcid);
 880        if (IS_ERR(skb))
 881                return PTR_ERR(skb);
 882
 883        if (info->sta || !info->offload_fw)
 884                mt76_connac_mcu_sta_basic_tlv(skb, info->vif, info->sta,
 885                                              info->enable, info->newly);
 886        if (info->sta && info->enable)
 887                mt76_connac_mcu_sta_tlv(phy, skb, info->sta,
 888                                        info->vif, info->rcpi,
 889                                        info->state);
 890
 891        sta_wtbl = mt76_connac_mcu_add_tlv(skb, STA_REC_WTBL,
 892                                           sizeof(struct tlv));
 893
 894        wtbl_hdr = mt76_connac_mcu_alloc_wtbl_req(dev, info->wcid,
 895                                                  WTBL_RESET_AND_SET,
 896                                                  sta_wtbl, &skb);
 897        if (IS_ERR(wtbl_hdr))
 898                return PTR_ERR(wtbl_hdr);
 899
 900        if (info->enable) {
 901                mt76_connac_mcu_wtbl_generic_tlv(dev, skb, info->vif,
 902                                                 info->sta, sta_wtbl,
 903                                                 wtbl_hdr);
 904                mt76_connac_mcu_wtbl_hdr_trans_tlv(skb, info->vif, info->wcid,
 905                                                   sta_wtbl, wtbl_hdr);
 906                if (info->sta)
 907                        mt76_connac_mcu_wtbl_ht_tlv(dev, skb, info->sta,
 908                                                    sta_wtbl, wtbl_hdr);
 909        }
 910
 911        return mt76_mcu_skb_send_msg(dev, skb, info->cmd, true);
 912}
 913EXPORT_SYMBOL_GPL(mt76_connac_mcu_sta_cmd);
 914
 915void mt76_connac_mcu_wtbl_ba_tlv(struct mt76_dev *dev, struct sk_buff *skb,
 916                                 struct ieee80211_ampdu_params *params,
 917                                 bool enable, bool tx, void *sta_wtbl,
 918                                 void *wtbl_tlv)
 919{
 920        struct wtbl_ba *ba;
 921        struct tlv *tlv;
 922
 923        tlv = mt76_connac_mcu_add_nested_tlv(skb, WTBL_BA, sizeof(*ba),
 924                                             wtbl_tlv, sta_wtbl);
 925
 926        ba = (struct wtbl_ba *)tlv;
 927        ba->tid = params->tid;
 928
 929        if (tx) {
 930                ba->ba_type = MT_BA_TYPE_ORIGINATOR;
 931                ba->sn = enable ? cpu_to_le16(params->ssn) : 0;
 932                ba->ba_winsize = enable ? cpu_to_le16(params->buf_size) : 0;
 933                ba->ba_en = enable;
 934        } else {
 935                memcpy(ba->peer_addr, params->sta->addr, ETH_ALEN);
 936                ba->ba_type = MT_BA_TYPE_RECIPIENT;
 937                ba->rst_ba_tid = params->tid;
 938                ba->rst_ba_sel = RST_BA_MAC_TID_MATCH;
 939                ba->rst_ba_sb = 1;
 940        }
 941
 942        if (is_mt7921(dev)) {
 943                ba->ba_winsize = enable ? cpu_to_le16(params->buf_size) : 0;
 944                return;
 945        }
 946
 947        if (enable && tx) {
 948                u8 ba_range[] = { 4, 8, 12, 24, 36, 48, 54, 64 };
 949                int i;
 950
 951                for (i = 7; i > 0; i--) {
 952                        if (params->buf_size >= ba_range[i])
 953                                break;
 954                }
 955                ba->ba_winsize_idx = i;
 956        }
 957}
 958EXPORT_SYMBOL_GPL(mt76_connac_mcu_wtbl_ba_tlv);
 959
 960int mt76_connac_mcu_uni_add_dev(struct mt76_phy *phy,
 961                                struct ieee80211_vif *vif,
 962                                struct mt76_wcid *wcid,
 963                                bool enable)
 964{
 965        struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv;
 966        struct mt76_dev *dev = phy->dev;
 967        struct {
 968                struct {
 969                        u8 omac_idx;
 970                        u8 band_idx;
 971                        __le16 pad;
 972                } __packed hdr;
 973                struct req_tlv {
 974                        __le16 tag;
 975                        __le16 len;
 976                        u8 active;
 977                        u8 pad;
 978                        u8 omac_addr[ETH_ALEN];
 979                } __packed tlv;
 980        } dev_req = {
 981                .hdr = {
 982                        .omac_idx = mvif->omac_idx,
 983                        .band_idx = mvif->band_idx,
 984                },
 985                .tlv = {
 986                        .tag = cpu_to_le16(DEV_INFO_ACTIVE),
 987                        .len = cpu_to_le16(sizeof(struct req_tlv)),
 988                        .active = enable,
 989                },
 990        };
 991        struct {
 992                struct {
 993                        u8 bss_idx;
 994                        u8 pad[3];
 995                } __packed hdr;
 996                struct mt76_connac_bss_basic_tlv basic;
 997        } basic_req = {
 998                .hdr = {
 999                        .bss_idx = mvif->idx,
1000                },
1001                .basic = {
1002                        .tag = cpu_to_le16(UNI_BSS_INFO_BASIC),
1003                        .len = cpu_to_le16(sizeof(struct mt76_connac_bss_basic_tlv)),
1004                        .omac_idx = mvif->omac_idx,
1005                        .band_idx = mvif->band_idx,
1006                        .wmm_idx = mvif->wmm_idx,
1007                        .active = enable,
1008                        .bmc_tx_wlan_idx = cpu_to_le16(wcid->idx),
1009                        .sta_idx = cpu_to_le16(wcid->idx),
1010                        .conn_state = 1,
1011                },
1012        };
1013        int err, idx, cmd, len;
1014        void *data;
1015
1016        switch (vif->type) {
1017        case NL80211_IFTYPE_MESH_POINT:
1018        case NL80211_IFTYPE_MONITOR:
1019        case NL80211_IFTYPE_AP:
1020                basic_req.basic.conn_type = cpu_to_le32(CONNECTION_INFRA_AP);
1021                break;
1022        case NL80211_IFTYPE_STATION:
1023                basic_req.basic.conn_type = cpu_to_le32(CONNECTION_INFRA_STA);
1024                break;
1025        case NL80211_IFTYPE_ADHOC:
1026                basic_req.basic.conn_type = cpu_to_le32(CONNECTION_IBSS_ADHOC);
1027                break;
1028        default:
1029                WARN_ON(1);
1030                break;
1031        }
1032
1033        idx = mvif->omac_idx > EXT_BSSID_START ? HW_BSSID_0 : mvif->omac_idx;
1034        basic_req.basic.hw_bss_idx = idx;
1035
1036        memcpy(dev_req.tlv.omac_addr, vif->addr, ETH_ALEN);
1037
1038        cmd = enable ? MCU_UNI_CMD_DEV_INFO_UPDATE : MCU_UNI_CMD_BSS_INFO_UPDATE;
1039        data = enable ? (void *)&dev_req : (void *)&basic_req;
1040        len = enable ? sizeof(dev_req) : sizeof(basic_req);
1041
1042        err = mt76_mcu_send_msg(dev, cmd, data, len, true);
1043        if (err < 0)
1044                return err;
1045
1046        cmd = enable ? MCU_UNI_CMD_BSS_INFO_UPDATE : MCU_UNI_CMD_DEV_INFO_UPDATE;
1047        data = enable ? (void *)&basic_req : (void *)&dev_req;
1048        len = enable ? sizeof(basic_req) : sizeof(dev_req);
1049
1050        return mt76_mcu_send_msg(dev, cmd, data, len, true);
1051}
1052EXPORT_SYMBOL_GPL(mt76_connac_mcu_uni_add_dev);
1053
1054void mt76_connac_mcu_sta_ba_tlv(struct sk_buff *skb,
1055                                struct ieee80211_ampdu_params *params,
1056                                bool enable, bool tx)
1057{
1058        struct sta_rec_ba *ba;
1059        struct tlv *tlv;
1060
1061        tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_BA, sizeof(*ba));
1062
1063        ba = (struct sta_rec_ba *)tlv;
1064        ba->ba_type = tx ? MT_BA_TYPE_ORIGINATOR : MT_BA_TYPE_RECIPIENT;
1065        ba->winsize = cpu_to_le16(params->buf_size);
1066        ba->ssn = cpu_to_le16(params->ssn);
1067        ba->ba_en = enable << params->tid;
1068        ba->amsdu = params->amsdu;
1069        ba->tid = params->tid;
1070}
1071EXPORT_SYMBOL_GPL(mt76_connac_mcu_sta_ba_tlv);
1072
1073int mt76_connac_mcu_sta_ba(struct mt76_dev *dev, struct mt76_vif *mvif,
1074                           struct ieee80211_ampdu_params *params,
1075                           bool enable, bool tx)
1076{
1077        struct mt76_wcid *wcid = (struct mt76_wcid *)params->sta->drv_priv;
1078        struct wtbl_req_hdr *wtbl_hdr;
1079        struct tlv *sta_wtbl;
1080        struct sk_buff *skb;
1081        int ret;
1082
1083        skb = mt76_connac_mcu_alloc_sta_req(dev, mvif, wcid);
1084        if (IS_ERR(skb))
1085                return PTR_ERR(skb);
1086
1087        sta_wtbl = mt76_connac_mcu_add_tlv(skb, STA_REC_WTBL,
1088                                           sizeof(struct tlv));
1089
1090        wtbl_hdr = mt76_connac_mcu_alloc_wtbl_req(dev, wcid, WTBL_SET,
1091                                                  sta_wtbl, &skb);
1092        if (IS_ERR(wtbl_hdr))
1093                return PTR_ERR(wtbl_hdr);
1094
1095        mt76_connac_mcu_wtbl_ba_tlv(dev, skb, params, enable, tx, sta_wtbl,
1096                                    wtbl_hdr);
1097
1098        ret = mt76_mcu_skb_send_msg(dev, skb, MCU_UNI_CMD_STA_REC_UPDATE, true);
1099        if (ret)
1100                return ret;
1101
1102        skb = mt76_connac_mcu_alloc_sta_req(dev, mvif, wcid);
1103        if (IS_ERR(skb))
1104                return PTR_ERR(skb);
1105
1106        mt76_connac_mcu_sta_ba_tlv(skb, params, enable, tx);
1107
1108        return mt76_mcu_skb_send_msg(dev, skb, MCU_UNI_CMD_STA_REC_UPDATE,
1109                                     true);
1110}
1111EXPORT_SYMBOL_GPL(mt76_connac_mcu_sta_ba);
1112
1113static u8
1114mt76_connac_get_phy_mode(struct mt76_phy *phy, struct ieee80211_vif *vif,
1115                         enum nl80211_band band,
1116                         struct ieee80211_sta *sta)
1117{
1118        struct mt76_dev *dev = phy->dev;
1119        const struct ieee80211_sta_he_cap *he_cap;
1120        struct ieee80211_sta_vht_cap *vht_cap;
1121        struct ieee80211_sta_ht_cap *ht_cap;
1122        u8 mode = 0;
1123
1124        if (!is_mt7921(dev))
1125                return 0x38;
1126
1127        if (sta) {
1128                ht_cap = &sta->ht_cap;
1129                vht_cap = &sta->vht_cap;
1130                he_cap = &sta->he_cap;
1131        } else {
1132                struct ieee80211_supported_band *sband;
1133
1134                sband = phy->hw->wiphy->bands[band];
1135                ht_cap = &sband->ht_cap;
1136                vht_cap = &sband->vht_cap;
1137                he_cap = ieee80211_get_he_iftype_cap(sband, vif->type);
1138        }
1139
1140        if (band == NL80211_BAND_2GHZ) {
1141                mode |= PHY_MODE_B | PHY_MODE_G;
1142
1143                if (ht_cap->ht_supported)
1144                        mode |= PHY_MODE_GN;
1145
1146                if (he_cap->has_he)
1147                        mode |= PHY_MODE_AX_24G;
1148        } else if (band == NL80211_BAND_5GHZ) {
1149                mode |= PHY_MODE_A;
1150
1151                if (ht_cap->ht_supported)
1152                        mode |= PHY_MODE_AN;
1153
1154                if (vht_cap->vht_supported)
1155                        mode |= PHY_MODE_AC;
1156
1157                if (he_cap->has_he)
1158                        mode |= PHY_MODE_AX_5G;
1159        }
1160
1161        return mode;
1162}
1163
1164static const struct ieee80211_sta_he_cap *
1165mt76_connac_get_he_phy_cap(struct mt76_phy *phy, struct ieee80211_vif *vif)
1166{
1167        enum nl80211_band band = phy->chandef.chan->band;
1168        struct ieee80211_supported_band *sband;
1169
1170        sband = phy->hw->wiphy->bands[band];
1171
1172        return ieee80211_get_he_iftype_cap(sband, vif->type);
1173}
1174
1175#define DEFAULT_HE_PE_DURATION          4
1176#define DEFAULT_HE_DURATION_RTS_THRES   1023
1177static void
1178mt76_connac_mcu_uni_bss_he_tlv(struct mt76_phy *phy, struct ieee80211_vif *vif,
1179                               struct tlv *tlv)
1180{
1181        const struct ieee80211_sta_he_cap *cap;
1182        struct bss_info_uni_he *he;
1183
1184        cap = mt76_connac_get_he_phy_cap(phy, vif);
1185
1186        he = (struct bss_info_uni_he *)tlv;
1187        he->he_pe_duration = vif->bss_conf.htc_trig_based_pkt_ext;
1188        if (!he->he_pe_duration)
1189                he->he_pe_duration = DEFAULT_HE_PE_DURATION;
1190
1191        he->he_rts_thres = cpu_to_le16(vif->bss_conf.frame_time_rts_th);
1192        if (!he->he_rts_thres)
1193                he->he_rts_thres = cpu_to_le16(DEFAULT_HE_DURATION_RTS_THRES);
1194
1195        he->max_nss_mcs[CMD_HE_MCS_BW80] = cap->he_mcs_nss_supp.tx_mcs_80;
1196        he->max_nss_mcs[CMD_HE_MCS_BW160] = cap->he_mcs_nss_supp.tx_mcs_160;
1197        he->max_nss_mcs[CMD_HE_MCS_BW8080] = cap->he_mcs_nss_supp.tx_mcs_80p80;
1198}
1199
1200int mt76_connac_mcu_uni_add_bss(struct mt76_phy *phy,
1201                                struct ieee80211_vif *vif,
1202                                struct mt76_wcid *wcid,
1203                                bool enable)
1204{
1205        struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv;
1206        struct cfg80211_chan_def *chandef = &phy->chandef;
1207        int freq1 = chandef->center_freq1, freq2 = chandef->center_freq2;
1208        enum nl80211_band band = chandef->chan->band;
1209        struct mt76_dev *mdev = phy->dev;
1210        struct {
1211                struct {
1212                        u8 bss_idx;
1213                        u8 pad[3];
1214                } __packed hdr;
1215                struct mt76_connac_bss_basic_tlv basic;
1216                struct mt76_connac_bss_qos_tlv qos;
1217        } basic_req = {
1218                .hdr = {
1219                        .bss_idx = mvif->idx,
1220                },
1221                .basic = {
1222                        .tag = cpu_to_le16(UNI_BSS_INFO_BASIC),
1223                        .len = cpu_to_le16(sizeof(struct mt76_connac_bss_basic_tlv)),
1224                        .bcn_interval = cpu_to_le16(vif->bss_conf.beacon_int),
1225                        .dtim_period = vif->bss_conf.dtim_period,
1226                        .omac_idx = mvif->omac_idx,
1227                        .band_idx = mvif->band_idx,
1228                        .wmm_idx = mvif->wmm_idx,
1229                        .active = true, /* keep bss deactivated */
1230                        .phymode = mt76_connac_get_phy_mode(phy, vif, band, NULL),
1231                },
1232                .qos = {
1233                        .tag = cpu_to_le16(UNI_BSS_INFO_QBSS),
1234                        .len = cpu_to_le16(sizeof(struct mt76_connac_bss_qos_tlv)),
1235                        .qos = vif->bss_conf.qos,
1236                },
1237        };
1238        struct {
1239                struct {
1240                        u8 bss_idx;
1241                        u8 pad[3];
1242                } __packed hdr;
1243                struct rlm_tlv {
1244                        __le16 tag;
1245                        __le16 len;
1246                        u8 control_channel;
1247                        u8 center_chan;
1248                        u8 center_chan2;
1249                        u8 bw;
1250                        u8 tx_streams;
1251                        u8 rx_streams;
1252                        u8 short_st;
1253                        u8 ht_op_info;
1254                        u8 sco;
1255                        u8 pad[3];
1256                } __packed rlm;
1257        } __packed rlm_req = {
1258                .hdr = {
1259                        .bss_idx = mvif->idx,
1260                },
1261                .rlm = {
1262                        .tag = cpu_to_le16(UNI_BSS_INFO_RLM),
1263                        .len = cpu_to_le16(sizeof(struct rlm_tlv)),
1264                        .control_channel = chandef->chan->hw_value,
1265                        .center_chan = ieee80211_frequency_to_channel(freq1),
1266                        .center_chan2 = ieee80211_frequency_to_channel(freq2),
1267                        .tx_streams = hweight8(phy->antenna_mask),
1268                        .ht_op_info = 4, /* set HT 40M allowed */
1269                        .rx_streams = phy->chainmask,
1270                        .short_st = true,
1271                },
1272        };
1273        int err, conn_type;
1274        u8 idx;
1275
1276        idx = mvif->omac_idx > EXT_BSSID_START ? HW_BSSID_0 : mvif->omac_idx;
1277        basic_req.basic.hw_bss_idx = idx;
1278
1279        switch (vif->type) {
1280        case NL80211_IFTYPE_MESH_POINT:
1281        case NL80211_IFTYPE_AP:
1282                if (vif->p2p)
1283                        conn_type = CONNECTION_P2P_GO;
1284                else
1285                        conn_type = CONNECTION_INFRA_AP;
1286                basic_req.basic.conn_type = cpu_to_le32(conn_type);
1287                break;
1288        case NL80211_IFTYPE_STATION:
1289                if (vif->p2p)
1290                        conn_type = CONNECTION_P2P_GC;
1291                else
1292                        conn_type = CONNECTION_INFRA_STA;
1293                basic_req.basic.conn_type = cpu_to_le32(conn_type);
1294                break;
1295        case NL80211_IFTYPE_ADHOC:
1296                basic_req.basic.conn_type = cpu_to_le32(CONNECTION_IBSS_ADHOC);
1297                break;
1298        default:
1299                WARN_ON(1);
1300                break;
1301        }
1302
1303        memcpy(basic_req.basic.bssid, vif->bss_conf.bssid, ETH_ALEN);
1304        basic_req.basic.bmc_tx_wlan_idx = cpu_to_le16(wcid->idx);
1305        basic_req.basic.sta_idx = cpu_to_le16(wcid->idx);
1306        basic_req.basic.conn_state = !enable;
1307
1308        err = mt76_mcu_send_msg(mdev, MCU_UNI_CMD_BSS_INFO_UPDATE, &basic_req,
1309                                sizeof(basic_req), true);
1310        if (err < 0)
1311                return err;
1312
1313        if (vif->bss_conf.he_support) {
1314                struct {
1315                        struct {
1316                                u8 bss_idx;
1317                                u8 pad[3];
1318                        } __packed hdr;
1319                        struct bss_info_uni_he he;
1320                        struct bss_info_uni_bss_color bss_color;
1321                } he_req = {
1322                        .hdr = {
1323                                .bss_idx = mvif->idx,
1324                        },
1325                        .he = {
1326                                .tag = cpu_to_le16(UNI_BSS_INFO_HE_BASIC),
1327                                .len = cpu_to_le16(sizeof(struct bss_info_uni_he)),
1328                        },
1329                        .bss_color = {
1330                                .tag = cpu_to_le16(UNI_BSS_INFO_BSS_COLOR),
1331                                .len = cpu_to_le16(sizeof(struct bss_info_uni_bss_color)),
1332                                .enable = 0,
1333                                .bss_color = 0,
1334                        },
1335                };
1336
1337                if (enable) {
1338                        he_req.bss_color.enable =
1339                                vif->bss_conf.he_bss_color.enabled;
1340                        he_req.bss_color.bss_color =
1341                                vif->bss_conf.he_bss_color.color;
1342                }
1343
1344                mt76_connac_mcu_uni_bss_he_tlv(phy, vif,
1345                                               (struct tlv *)&he_req.he);
1346                err = mt76_mcu_send_msg(mdev, MCU_UNI_CMD_BSS_INFO_UPDATE,
1347                                        &he_req, sizeof(he_req), true);
1348                if (err < 0)
1349                        return err;
1350        }
1351
1352        switch (chandef->width) {
1353        case NL80211_CHAN_WIDTH_40:
1354                rlm_req.rlm.bw = CMD_CBW_40MHZ;
1355                break;
1356        case NL80211_CHAN_WIDTH_80:
1357                rlm_req.rlm.bw = CMD_CBW_80MHZ;
1358                break;
1359        case NL80211_CHAN_WIDTH_80P80:
1360                rlm_req.rlm.bw = CMD_CBW_8080MHZ;
1361                break;
1362        case NL80211_CHAN_WIDTH_160:
1363                rlm_req.rlm.bw = CMD_CBW_160MHZ;
1364                break;
1365        case NL80211_CHAN_WIDTH_5:
1366                rlm_req.rlm.bw = CMD_CBW_5MHZ;
1367                break;
1368        case NL80211_CHAN_WIDTH_10:
1369                rlm_req.rlm.bw = CMD_CBW_10MHZ;
1370                break;
1371        case NL80211_CHAN_WIDTH_20_NOHT:
1372        case NL80211_CHAN_WIDTH_20:
1373        default:
1374                rlm_req.rlm.bw = CMD_CBW_20MHZ;
1375                rlm_req.rlm.ht_op_info = 0;
1376                break;
1377        }
1378
1379        if (rlm_req.rlm.control_channel < rlm_req.rlm.center_chan)
1380                rlm_req.rlm.sco = 1; /* SCA */
1381        else if (rlm_req.rlm.control_channel > rlm_req.rlm.center_chan)
1382                rlm_req.rlm.sco = 3; /* SCB */
1383
1384        return mt76_mcu_send_msg(mdev, MCU_UNI_CMD_BSS_INFO_UPDATE, &rlm_req,
1385                                 sizeof(rlm_req), true);
1386}
1387EXPORT_SYMBOL_GPL(mt76_connac_mcu_uni_add_bss);
1388
1389#define MT76_CONNAC_SCAN_CHANNEL_TIME           60
1390int mt76_connac_mcu_hw_scan(struct mt76_phy *phy, struct ieee80211_vif *vif,
1391                            struct ieee80211_scan_request *scan_req)
1392{
1393        struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv;
1394        struct cfg80211_scan_request *sreq = &scan_req->req;
1395        int n_ssids = 0, err, i, duration;
1396        int ext_channels_num = max_t(int, sreq->n_channels - 32, 0);
1397        struct ieee80211_channel **scan_list = sreq->channels;
1398        struct mt76_dev *mdev = phy->dev;
1399        bool ext_phy = phy == mdev->phy2;
1400        struct mt76_connac_mcu_scan_channel *chan;
1401        struct mt76_connac_hw_scan_req *req;
1402        struct sk_buff *skb;
1403
1404        skb = mt76_mcu_msg_alloc(mdev, NULL, sizeof(*req));
1405        if (!skb)
1406                return -ENOMEM;
1407
1408        set_bit(MT76_HW_SCANNING, &phy->state);
1409        mvif->scan_seq_num = (mvif->scan_seq_num + 1) & 0x7f;
1410
1411        req = (struct mt76_connac_hw_scan_req *)skb_put(skb, sizeof(*req));
1412
1413        req->seq_num = mvif->scan_seq_num | ext_phy << 7;
1414        req->bss_idx = mvif->idx;
1415        req->scan_type = sreq->n_ssids ? 1 : 0;
1416        req->probe_req_num = sreq->n_ssids ? 2 : 0;
1417        req->version = 1;
1418
1419        for (i = 0; i < sreq->n_ssids; i++) {
1420                if (!sreq->ssids[i].ssid_len)
1421                        continue;
1422
1423                req->ssids[i].ssid_len = cpu_to_le32(sreq->ssids[i].ssid_len);
1424                memcpy(req->ssids[i].ssid, sreq->ssids[i].ssid,
1425                       sreq->ssids[i].ssid_len);
1426                n_ssids++;
1427        }
1428        req->ssid_type = n_ssids ? BIT(2) : BIT(0);
1429        req->ssid_type_ext = n_ssids ? BIT(0) : 0;
1430        req->ssids_num = n_ssids;
1431
1432        duration = is_mt7921(phy->dev) ? 0 : MT76_CONNAC_SCAN_CHANNEL_TIME;
1433        /* increase channel time for passive scan */
1434        if (!sreq->n_ssids)
1435                duration *= 2;
1436        req->timeout_value = cpu_to_le16(sreq->n_channels * duration);
1437        req->channel_min_dwell_time = cpu_to_le16(duration);
1438        req->channel_dwell_time = cpu_to_le16(duration);
1439
1440        req->channels_num = min_t(u8, sreq->n_channels, 32);
1441        req->ext_channels_num = min_t(u8, ext_channels_num, 32);
1442        for (i = 0; i < req->channels_num + req->ext_channels_num; i++) {
1443                if (i >= 32)
1444                        chan = &req->ext_channels[i - 32];
1445                else
1446                        chan = &req->channels[i];
1447
1448                chan->band = scan_list[i]->band == NL80211_BAND_2GHZ ? 1 : 2;
1449                chan->channel_num = scan_list[i]->hw_value;
1450        }
1451        req->channel_type = sreq->n_channels ? 4 : 0;
1452
1453        if (sreq->ie_len > 0) {
1454                memcpy(req->ies, sreq->ie, sreq->ie_len);
1455                req->ies_len = cpu_to_le16(sreq->ie_len);
1456        }
1457
1458        if (is_mt7921(phy->dev))
1459                req->scan_func |= SCAN_FUNC_SPLIT_SCAN;
1460
1461        memcpy(req->bssid, sreq->bssid, ETH_ALEN);
1462        if (sreq->flags & NL80211_SCAN_FLAG_RANDOM_ADDR) {
1463                get_random_mask_addr(req->random_mac, sreq->mac_addr,
1464                                     sreq->mac_addr_mask);
1465                req->scan_func |= SCAN_FUNC_RANDOM_MAC;
1466        }
1467
1468        err = mt76_mcu_skb_send_msg(mdev, skb, MCU_CMD_START_HW_SCAN, false);
1469        if (err < 0)
1470                clear_bit(MT76_HW_SCANNING, &phy->state);
1471
1472        return err;
1473}
1474EXPORT_SYMBOL_GPL(mt76_connac_mcu_hw_scan);
1475
1476int mt76_connac_mcu_cancel_hw_scan(struct mt76_phy *phy,
1477                                   struct ieee80211_vif *vif)
1478{
1479        struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv;
1480        struct {
1481                u8 seq_num;
1482                u8 is_ext_channel;
1483                u8 rsv[2];
1484        } __packed req = {
1485                .seq_num = mvif->scan_seq_num,
1486        };
1487
1488        if (test_and_clear_bit(MT76_HW_SCANNING, &phy->state)) {
1489                struct cfg80211_scan_info info = {
1490                        .aborted = true,
1491                };
1492
1493                ieee80211_scan_completed(phy->hw, &info);
1494        }
1495
1496        return mt76_mcu_send_msg(phy->dev, MCU_CMD_CANCEL_HW_SCAN, &req,
1497                                 sizeof(req), false);
1498}
1499EXPORT_SYMBOL_GPL(mt76_connac_mcu_cancel_hw_scan);
1500
1501int mt76_connac_mcu_sched_scan_req(struct mt76_phy *phy,
1502                                   struct ieee80211_vif *vif,
1503                                   struct cfg80211_sched_scan_request *sreq)
1504{
1505        struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv;
1506        struct ieee80211_channel **scan_list = sreq->channels;
1507        struct mt76_connac_mcu_scan_channel *chan;
1508        struct mt76_connac_sched_scan_req *req;
1509        struct mt76_dev *mdev = phy->dev;
1510        bool ext_phy = phy == mdev->phy2;
1511        struct cfg80211_match_set *match;
1512        struct cfg80211_ssid *ssid;
1513        struct sk_buff *skb;
1514        int i;
1515
1516        skb = mt76_mcu_msg_alloc(mdev, NULL, sizeof(*req) + sreq->ie_len);
1517        if (!skb)
1518                return -ENOMEM;
1519
1520        mvif->scan_seq_num = (mvif->scan_seq_num + 1) & 0x7f;
1521
1522        req = (struct mt76_connac_sched_scan_req *)skb_put(skb, sizeof(*req));
1523        req->version = 1;
1524        req->seq_num = mvif->scan_seq_num | ext_phy << 7;
1525
1526        if (sreq->flags & NL80211_SCAN_FLAG_RANDOM_ADDR) {
1527                u8 *addr = is_mt7663(phy->dev) ? req->mt7663.random_mac
1528                                               : req->mt7921.random_mac;
1529
1530                req->scan_func = 1;
1531                get_random_mask_addr(addr, sreq->mac_addr,
1532                                     sreq->mac_addr_mask);
1533        }
1534        if (is_mt7921(phy->dev))
1535                req->mt7921.bss_idx = mvif->idx;
1536
1537        req->ssids_num = sreq->n_ssids;
1538        for (i = 0; i < req->ssids_num; i++) {
1539                ssid = &sreq->ssids[i];
1540                memcpy(req->ssids[i].ssid, ssid->ssid, ssid->ssid_len);
1541                req->ssids[i].ssid_len = cpu_to_le32(ssid->ssid_len);
1542        }
1543
1544        req->match_num = sreq->n_match_sets;
1545        for (i = 0; i < req->match_num; i++) {
1546                match = &sreq->match_sets[i];
1547                memcpy(req->match[i].ssid, match->ssid.ssid,
1548                       match->ssid.ssid_len);
1549                req->match[i].rssi_th = cpu_to_le32(match->rssi_thold);
1550                req->match[i].ssid_len = match->ssid.ssid_len;
1551        }
1552
1553        req->channel_type = sreq->n_channels ? 4 : 0;
1554        req->channels_num = min_t(u8, sreq->n_channels, 64);
1555        for (i = 0; i < req->channels_num; i++) {
1556                chan = &req->channels[i];
1557                chan->band = scan_list[i]->band == NL80211_BAND_2GHZ ? 1 : 2;
1558                chan->channel_num = scan_list[i]->hw_value;
1559        }
1560
1561        req->intervals_num = sreq->n_scan_plans;
1562        for (i = 0; i < req->intervals_num; i++)
1563                req->intervals[i] = cpu_to_le16(sreq->scan_plans[i].interval);
1564
1565        if (sreq->ie_len > 0) {
1566                req->ie_len = cpu_to_le16(sreq->ie_len);
1567                memcpy(skb_put(skb, sreq->ie_len), sreq->ie, sreq->ie_len);
1568        }
1569
1570        return mt76_mcu_skb_send_msg(mdev, skb, MCU_CMD_SCHED_SCAN_REQ, false);
1571}
1572EXPORT_SYMBOL_GPL(mt76_connac_mcu_sched_scan_req);
1573
1574int mt76_connac_mcu_sched_scan_enable(struct mt76_phy *phy,
1575                                      struct ieee80211_vif *vif,
1576                                      bool enable)
1577{
1578        struct {
1579                u8 active; /* 0: enabled 1: disabled */
1580                u8 rsv[3];
1581        } __packed req = {
1582                .active = !enable,
1583        };
1584
1585        if (enable)
1586                set_bit(MT76_HW_SCHED_SCANNING, &phy->state);
1587        else
1588                clear_bit(MT76_HW_SCHED_SCANNING, &phy->state);
1589
1590        return mt76_mcu_send_msg(phy->dev, MCU_CMD_SCHED_SCAN_ENABLE, &req,
1591                                 sizeof(req), false);
1592}
1593EXPORT_SYMBOL_GPL(mt76_connac_mcu_sched_scan_enable);
1594
1595int mt76_connac_mcu_chip_config(struct mt76_dev *dev)
1596{
1597        struct mt76_connac_config req = {
1598                .resp_type = 0,
1599        };
1600
1601        memcpy(req.data, "assert", 7);
1602
1603        return mt76_mcu_send_msg(dev, MCU_CMD_CHIP_CONFIG, &req, sizeof(req),
1604                                 false);
1605}
1606EXPORT_SYMBOL_GPL(mt76_connac_mcu_chip_config);
1607
1608int mt76_connac_mcu_set_deep_sleep(struct mt76_dev *dev, bool enable)
1609{
1610        struct mt76_connac_config req = {
1611                .resp_type = 0,
1612        };
1613
1614        snprintf(req.data, sizeof(req.data), "KeepFullPwr %d", !enable);
1615
1616        return mt76_mcu_send_msg(dev, MCU_CMD_CHIP_CONFIG, &req, sizeof(req),
1617                                 false);
1618}
1619EXPORT_SYMBOL_GPL(mt76_connac_mcu_set_deep_sleep);
1620
1621int mt76_connac_sta_state_dp(struct mt76_dev *dev,
1622                             enum ieee80211_sta_state old_state,
1623                             enum ieee80211_sta_state new_state)
1624{
1625        if ((old_state == IEEE80211_STA_ASSOC &&
1626             new_state == IEEE80211_STA_AUTHORIZED) ||
1627            (old_state == IEEE80211_STA_NONE &&
1628             new_state == IEEE80211_STA_NOTEXIST))
1629                mt76_connac_mcu_set_deep_sleep(dev, true);
1630
1631        if ((old_state == IEEE80211_STA_NOTEXIST &&
1632             new_state == IEEE80211_STA_NONE) ||
1633            (old_state == IEEE80211_STA_AUTHORIZED &&
1634             new_state == IEEE80211_STA_ASSOC))
1635                mt76_connac_mcu_set_deep_sleep(dev, false);
1636
1637        return 0;
1638}
1639EXPORT_SYMBOL_GPL(mt76_connac_sta_state_dp);
1640
1641void mt76_connac_mcu_coredump_event(struct mt76_dev *dev, struct sk_buff *skb,
1642                                    struct mt76_connac_coredump *coredump)
1643{
1644        spin_lock_bh(&dev->lock);
1645        __skb_queue_tail(&coredump->msg_list, skb);
1646        spin_unlock_bh(&dev->lock);
1647
1648        coredump->last_activity = jiffies;
1649
1650        queue_delayed_work(dev->wq, &coredump->work,
1651                           MT76_CONNAC_COREDUMP_TIMEOUT);
1652}
1653EXPORT_SYMBOL_GPL(mt76_connac_mcu_coredump_event);
1654
1655int mt76_connac_mcu_get_nic_capability(struct mt76_phy *phy)
1656{
1657        struct mt76_connac_cap_hdr {
1658                __le16 n_element;
1659                u8 rsv[2];
1660        } __packed * hdr;
1661        struct sk_buff *skb;
1662        int ret, i;
1663
1664        ret = mt76_mcu_send_and_get_msg(phy->dev, MCU_CMD_GET_NIC_CAPAB, NULL,
1665                                        0, true, &skb);
1666        if (ret)
1667                return ret;
1668
1669        hdr = (struct mt76_connac_cap_hdr *)skb->data;
1670        if (skb->len < sizeof(*hdr)) {
1671                ret = -EINVAL;
1672                goto out;
1673        }
1674
1675        skb_pull(skb, sizeof(*hdr));
1676
1677        for (i = 0; i < le16_to_cpu(hdr->n_element); i++) {
1678                struct tlv_hdr {
1679                        __le32 type;
1680                        __le32 len;
1681                } __packed * tlv = (struct tlv_hdr *)skb->data;
1682                int len;
1683
1684                if (skb->len < sizeof(*tlv))
1685                        break;
1686
1687                skb_pull(skb, sizeof(*tlv));
1688
1689                len = le32_to_cpu(tlv->len);
1690                if (skb->len < len)
1691                        break;
1692
1693                switch (le32_to_cpu(tlv->type)) {
1694                case MT_NIC_CAP_6G:
1695                        phy->cap.has_6ghz = skb->data[0];
1696                        break;
1697                default:
1698                        break;
1699                }
1700                skb_pull(skb, len);
1701        }
1702out:
1703        dev_kfree_skb(skb);
1704
1705        return ret;
1706}
1707EXPORT_SYMBOL_GPL(mt76_connac_mcu_get_nic_capability);
1708
1709static void
1710mt76_connac_mcu_build_sku(struct mt76_dev *dev, s8 *sku,
1711                          struct mt76_power_limits *limits,
1712                          enum nl80211_band band)
1713{
1714        int max_power = is_mt7921(dev) ? 127 : 63;
1715        int i, offset = sizeof(limits->cck);
1716
1717        memset(sku, max_power, MT_SKU_POWER_LIMIT);
1718
1719        if (band == NL80211_BAND_2GHZ) {
1720                /* cck */
1721                memcpy(sku, limits->cck, sizeof(limits->cck));
1722        }
1723
1724        /* ofdm */
1725        memcpy(&sku[offset], limits->ofdm, sizeof(limits->ofdm));
1726        offset += sizeof(limits->ofdm);
1727
1728        /* ht */
1729        for (i = 0; i < 2; i++) {
1730                memcpy(&sku[offset], limits->mcs[i], 8);
1731                offset += 8;
1732        }
1733        sku[offset++] = limits->mcs[0][0];
1734
1735        /* vht */
1736        for (i = 0; i < ARRAY_SIZE(limits->mcs); i++) {
1737                memcpy(&sku[offset], limits->mcs[i],
1738                       ARRAY_SIZE(limits->mcs[i]));
1739                offset += 12;
1740        }
1741
1742        if (!is_mt7921(dev))
1743                return;
1744
1745        /* he */
1746        for (i = 0; i < ARRAY_SIZE(limits->ru); i++) {
1747                memcpy(&sku[offset], limits->ru[i], ARRAY_SIZE(limits->ru[i]));
1748                offset += ARRAY_SIZE(limits->ru[i]);
1749        }
1750}
1751
1752static int
1753mt76_connac_mcu_rate_txpower_band(struct mt76_phy *phy,
1754                                  enum nl80211_band band)
1755{
1756        struct mt76_dev *dev = phy->dev;
1757        int sku_len, batch_len = is_mt7921(dev) ? 8 : 16;
1758        static const u8 chan_list_2ghz[] = {
1759                1, 2,  3,  4,  5,  6,  7,
1760                8, 9, 10, 11, 12, 13, 14
1761        };
1762        static const u8 chan_list_5ghz[] = {
1763                 36,  38,  40,  42,  44,  46,  48,
1764                 50,  52,  54,  56,  58,  60,  62,
1765                 64, 100, 102, 104, 106, 108, 110,
1766                112, 114, 116, 118, 120, 122, 124,
1767                126, 128, 132, 134, 136, 138, 140,
1768                142, 144, 149, 151, 153, 155, 157,
1769                159, 161, 165
1770        };
1771        int i, n_chan, batch_size, idx = 0, tx_power, last_ch;
1772        struct mt76_connac_sku_tlv sku_tlbv;
1773        struct mt76_power_limits limits;
1774        const u8 *ch_list;
1775
1776        sku_len = is_mt7921(dev) ? sizeof(sku_tlbv) : sizeof(sku_tlbv) - 92;
1777        tx_power = 2 * phy->hw->conf.power_level;
1778        if (!tx_power)
1779                tx_power = 127;
1780
1781        if (band == NL80211_BAND_2GHZ) {
1782                n_chan = ARRAY_SIZE(chan_list_2ghz);
1783                ch_list = chan_list_2ghz;
1784        } else {
1785                n_chan = ARRAY_SIZE(chan_list_5ghz);
1786                ch_list = chan_list_5ghz;
1787        }
1788        batch_size = DIV_ROUND_UP(n_chan, batch_len);
1789
1790        if (!phy->cap.has_5ghz)
1791                last_ch = chan_list_2ghz[n_chan - 1];
1792        else
1793                last_ch = chan_list_5ghz[n_chan - 1];
1794
1795        for (i = 0; i < batch_size; i++) {
1796                struct mt76_connac_tx_power_limit_tlv tx_power_tlv = {
1797                        .band = band == NL80211_BAND_2GHZ ? 1 : 2,
1798                };
1799                int j, err, msg_len, num_ch;
1800                struct sk_buff *skb;
1801
1802                num_ch = i == batch_size - 1 ? n_chan % batch_len : batch_len;
1803                msg_len = sizeof(tx_power_tlv) + num_ch * sizeof(sku_tlbv);
1804                skb = mt76_mcu_msg_alloc(dev, NULL, msg_len);
1805                if (!skb)
1806                        return -ENOMEM;
1807
1808                skb_reserve(skb, sizeof(tx_power_tlv));
1809
1810                BUILD_BUG_ON(sizeof(dev->alpha2) > sizeof(tx_power_tlv.alpha2));
1811                memcpy(tx_power_tlv.alpha2, dev->alpha2, sizeof(dev->alpha2));
1812                tx_power_tlv.n_chan = num_ch;
1813
1814                for (j = 0; j < num_ch; j++, idx++) {
1815                        struct ieee80211_channel chan = {
1816                                .hw_value = ch_list[idx],
1817                                .band = band,
1818                        };
1819
1820                        mt76_get_rate_power_limits(phy, &chan, &limits,
1821                                                   tx_power);
1822
1823                        tx_power_tlv.last_msg = ch_list[idx] == last_ch;
1824                        sku_tlbv.channel = ch_list[idx];
1825
1826                        mt76_connac_mcu_build_sku(dev, sku_tlbv.pwr_limit,
1827                                                  &limits, band);
1828                        skb_put_data(skb, &sku_tlbv, sku_len);
1829                }
1830                __skb_push(skb, sizeof(tx_power_tlv));
1831                memcpy(skb->data, &tx_power_tlv, sizeof(tx_power_tlv));
1832
1833                err = mt76_mcu_skb_send_msg(dev, skb,
1834                                            MCU_CMD_SET_RATE_TX_POWER, false);
1835                if (err < 0)
1836                        return err;
1837        }
1838
1839        return 0;
1840}
1841
1842int mt76_connac_mcu_set_rate_txpower(struct mt76_phy *phy)
1843{
1844        int err;
1845
1846        if (phy->cap.has_2ghz) {
1847                err = mt76_connac_mcu_rate_txpower_band(phy,
1848                                                        NL80211_BAND_2GHZ);
1849                if (err < 0)
1850                        return err;
1851        }
1852        if (phy->cap.has_5ghz) {
1853                err = mt76_connac_mcu_rate_txpower_band(phy,
1854                                                        NL80211_BAND_5GHZ);
1855                if (err < 0)
1856                        return err;
1857        }
1858
1859        return 0;
1860}
1861EXPORT_SYMBOL_GPL(mt76_connac_mcu_set_rate_txpower);
1862
1863int mt76_connac_mcu_update_arp_filter(struct mt76_dev *dev,
1864                                      struct mt76_vif *vif,
1865                                      struct ieee80211_bss_conf *info)
1866{
1867        struct sk_buff *skb;
1868        int i, len = min_t(int, info->arp_addr_cnt,
1869                           IEEE80211_BSS_ARP_ADDR_LIST_LEN);
1870        struct {
1871                struct {
1872                        u8 bss_idx;
1873                        u8 pad[3];
1874                } __packed hdr;
1875                struct mt76_connac_arpns_tlv arp;
1876        } req_hdr = {
1877                .hdr = {
1878                        .bss_idx = vif->idx,
1879                },
1880                .arp = {
1881                        .tag = cpu_to_le16(UNI_OFFLOAD_OFFLOAD_ARP),
1882                        .len = cpu_to_le16(sizeof(struct mt76_connac_arpns_tlv)),
1883                        .ips_num = len,
1884                        .mode = 2,  /* update */
1885                        .option = 1,
1886                },
1887        };
1888
1889        skb = mt76_mcu_msg_alloc(dev, NULL,
1890                                 sizeof(req_hdr) + len * sizeof(__be32));
1891        if (!skb)
1892                return -ENOMEM;
1893
1894        skb_put_data(skb, &req_hdr, sizeof(req_hdr));
1895        for (i = 0; i < len; i++) {
1896                u8 *addr = (u8 *)skb_put(skb, sizeof(__be32));
1897
1898                memcpy(addr, &info->arp_addr_list[i], sizeof(__be32));
1899        }
1900
1901        return mt76_mcu_skb_send_msg(dev, skb, MCU_UNI_CMD_OFFLOAD, true);
1902}
1903EXPORT_SYMBOL_GPL(mt76_connac_mcu_update_arp_filter);
1904
1905#ifdef CONFIG_PM
1906
1907const struct wiphy_wowlan_support mt76_connac_wowlan_support = {
1908        .flags = WIPHY_WOWLAN_MAGIC_PKT | WIPHY_WOWLAN_DISCONNECT |
1909                 WIPHY_WOWLAN_SUPPORTS_GTK_REKEY | WIPHY_WOWLAN_NET_DETECT,
1910        .n_patterns = 1,
1911        .pattern_min_len = 1,
1912        .pattern_max_len = MT76_CONNAC_WOW_PATTEN_MAX_LEN,
1913        .max_nd_match_sets = 10,
1914};
1915EXPORT_SYMBOL_GPL(mt76_connac_wowlan_support);
1916
1917static void
1918mt76_connac_mcu_key_iter(struct ieee80211_hw *hw,
1919                         struct ieee80211_vif *vif,
1920                         struct ieee80211_sta *sta,
1921                         struct ieee80211_key_conf *key,
1922                         void *data)
1923{
1924        struct mt76_connac_gtk_rekey_tlv *gtk_tlv = data;
1925        u32 cipher;
1926
1927        if (key->cipher != WLAN_CIPHER_SUITE_AES_CMAC &&
1928            key->cipher != WLAN_CIPHER_SUITE_CCMP &&
1929            key->cipher != WLAN_CIPHER_SUITE_TKIP)
1930                return;
1931
1932        if (key->cipher == WLAN_CIPHER_SUITE_TKIP) {
1933                gtk_tlv->proto = cpu_to_le32(NL80211_WPA_VERSION_1);
1934                cipher = BIT(3);
1935        } else {
1936                gtk_tlv->proto = cpu_to_le32(NL80211_WPA_VERSION_2);
1937                cipher = BIT(4);
1938        }
1939
1940        /* we are assuming here to have a single pairwise key */
1941        if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) {
1942                gtk_tlv->pairwise_cipher = cpu_to_le32(cipher);
1943                gtk_tlv->group_cipher = cpu_to_le32(cipher);
1944                gtk_tlv->keyid = key->keyidx;
1945        }
1946}
1947
1948int mt76_connac_mcu_update_gtk_rekey(struct ieee80211_hw *hw,
1949                                     struct ieee80211_vif *vif,
1950                                     struct cfg80211_gtk_rekey_data *key)
1951{
1952        struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv;
1953        struct mt76_connac_gtk_rekey_tlv *gtk_tlv;
1954        struct mt76_phy *phy = hw->priv;
1955        struct sk_buff *skb;
1956        struct {
1957                u8 bss_idx;
1958                u8 pad[3];
1959        } __packed hdr = {
1960                .bss_idx = mvif->idx,
1961        };
1962
1963        skb = mt76_mcu_msg_alloc(phy->dev, NULL,
1964                                 sizeof(hdr) + sizeof(*gtk_tlv));
1965        if (!skb)
1966                return -ENOMEM;
1967
1968        skb_put_data(skb, &hdr, sizeof(hdr));
1969        gtk_tlv = (struct mt76_connac_gtk_rekey_tlv *)skb_put(skb,
1970                                                         sizeof(*gtk_tlv));
1971        gtk_tlv->tag = cpu_to_le16(UNI_OFFLOAD_OFFLOAD_GTK_REKEY);
1972        gtk_tlv->len = cpu_to_le16(sizeof(*gtk_tlv));
1973        gtk_tlv->rekey_mode = 2;
1974        gtk_tlv->option = 1;
1975
1976        rcu_read_lock();
1977        ieee80211_iter_keys_rcu(hw, vif, mt76_connac_mcu_key_iter, gtk_tlv);
1978        rcu_read_unlock();
1979
1980        memcpy(gtk_tlv->kek, key->kek, NL80211_KEK_LEN);
1981        memcpy(gtk_tlv->kck, key->kck, NL80211_KCK_LEN);
1982        memcpy(gtk_tlv->replay_ctr, key->replay_ctr, NL80211_REPLAY_CTR_LEN);
1983
1984        return mt76_mcu_skb_send_msg(phy->dev, skb, MCU_UNI_CMD_OFFLOAD, true);
1985}
1986EXPORT_SYMBOL_GPL(mt76_connac_mcu_update_gtk_rekey);
1987
1988static int
1989mt76_connac_mcu_set_arp_filter(struct mt76_dev *dev, struct ieee80211_vif *vif,
1990                               bool suspend)
1991{
1992        struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv;
1993        struct {
1994                struct {
1995                        u8 bss_idx;
1996                        u8 pad[3];
1997                } __packed hdr;
1998                struct mt76_connac_arpns_tlv arpns;
1999        } req = {
2000                .hdr = {
2001                        .bss_idx = mvif->idx,
2002                },
2003                .arpns = {
2004                        .tag = cpu_to_le16(UNI_OFFLOAD_OFFLOAD_ARP),
2005                        .len = cpu_to_le16(sizeof(struct mt76_connac_arpns_tlv)),
2006                        .mode = suspend,
2007                },
2008        };
2009
2010        return mt76_mcu_send_msg(dev, MCU_UNI_CMD_OFFLOAD, &req, sizeof(req),
2011                                 true);
2012}
2013
2014static int
2015mt76_connac_mcu_set_gtk_rekey(struct mt76_dev *dev, struct ieee80211_vif *vif,
2016                              bool suspend)
2017{
2018        struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv;
2019        struct {
2020                struct {
2021                        u8 bss_idx;
2022                        u8 pad[3];
2023                } __packed hdr;
2024                struct mt76_connac_gtk_rekey_tlv gtk_tlv;
2025        } __packed req = {
2026                .hdr = {
2027                        .bss_idx = mvif->idx,
2028                },
2029                .gtk_tlv = {
2030                        .tag = cpu_to_le16(UNI_OFFLOAD_OFFLOAD_GTK_REKEY),
2031                        .len = cpu_to_le16(sizeof(struct mt76_connac_gtk_rekey_tlv)),
2032                        .rekey_mode = !suspend,
2033                },
2034        };
2035
2036        return mt76_mcu_send_msg(dev, MCU_UNI_CMD_OFFLOAD, &req, sizeof(req),
2037                                 true);
2038}
2039
2040static int
2041mt76_connac_mcu_set_suspend_mode(struct mt76_dev *dev,
2042                                 struct ieee80211_vif *vif,
2043                                 bool enable, u8 mdtim,
2044                                 bool wow_suspend)
2045{
2046        struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv;
2047        struct {
2048                struct {
2049                        u8 bss_idx;
2050                        u8 pad[3];
2051                } __packed hdr;
2052                struct mt76_connac_suspend_tlv suspend_tlv;
2053        } req = {
2054                .hdr = {
2055                        .bss_idx = mvif->idx,
2056                },
2057                .suspend_tlv = {
2058                        .tag = cpu_to_le16(UNI_SUSPEND_MODE_SETTING),
2059                        .len = cpu_to_le16(sizeof(struct mt76_connac_suspend_tlv)),
2060                        .enable = enable,
2061                        .mdtim = mdtim,
2062                        .wow_suspend = wow_suspend,
2063                },
2064        };
2065
2066        return mt76_mcu_send_msg(dev, MCU_UNI_CMD_SUSPEND, &req, sizeof(req),
2067                                 true);
2068}
2069
2070static int
2071mt76_connac_mcu_set_wow_pattern(struct mt76_dev *dev,
2072                                struct ieee80211_vif *vif,
2073                                u8 index, bool enable,
2074                                struct cfg80211_pkt_pattern *pattern)
2075{
2076        struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv;
2077        struct mt76_connac_wow_pattern_tlv *ptlv;
2078        struct sk_buff *skb;
2079        struct req_hdr {
2080                u8 bss_idx;
2081                u8 pad[3];
2082        } __packed hdr = {
2083                .bss_idx = mvif->idx,
2084        };
2085
2086        skb = mt76_mcu_msg_alloc(dev, NULL, sizeof(hdr) + sizeof(*ptlv));
2087        if (!skb)
2088                return -ENOMEM;
2089
2090        skb_put_data(skb, &hdr, sizeof(hdr));
2091        ptlv = (struct mt76_connac_wow_pattern_tlv *)skb_put(skb, sizeof(*ptlv));
2092        ptlv->tag = cpu_to_le16(UNI_SUSPEND_WOW_PATTERN);
2093        ptlv->len = cpu_to_le16(sizeof(*ptlv));
2094        ptlv->data_len = pattern->pattern_len;
2095        ptlv->enable = enable;
2096        ptlv->index = index;
2097
2098        memcpy(ptlv->pattern, pattern->pattern, pattern->pattern_len);
2099        memcpy(ptlv->mask, pattern->mask, DIV_ROUND_UP(pattern->pattern_len, 8));
2100
2101        return mt76_mcu_skb_send_msg(dev, skb, MCU_UNI_CMD_SUSPEND, true);
2102}
2103
2104static int
2105mt76_connac_mcu_set_wow_ctrl(struct mt76_phy *phy, struct ieee80211_vif *vif,
2106                             bool suspend, struct cfg80211_wowlan *wowlan)
2107{
2108        struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv;
2109        struct mt76_dev *dev = phy->dev;
2110        struct {
2111                struct {
2112                        u8 bss_idx;
2113                        u8 pad[3];
2114                } __packed hdr;
2115                struct mt76_connac_wow_ctrl_tlv wow_ctrl_tlv;
2116                struct mt76_connac_wow_gpio_param_tlv gpio_tlv;
2117        } req = {
2118                .hdr = {
2119                        .bss_idx = mvif->idx,
2120                },
2121                .wow_ctrl_tlv = {
2122                        .tag = cpu_to_le16(UNI_SUSPEND_WOW_CTRL),
2123                        .len = cpu_to_le16(sizeof(struct mt76_connac_wow_ctrl_tlv)),
2124                        .cmd = suspend ? 1 : 2,
2125                },
2126                .gpio_tlv = {
2127                        .tag = cpu_to_le16(UNI_SUSPEND_WOW_GPIO_PARAM),
2128                        .len = cpu_to_le16(sizeof(struct mt76_connac_wow_gpio_param_tlv)),
2129                        .gpio_pin = 0xff, /* follow fw about GPIO pin */
2130                },
2131        };
2132
2133        if (wowlan->magic_pkt)
2134                req.wow_ctrl_tlv.trigger |= UNI_WOW_DETECT_TYPE_MAGIC;
2135        if (wowlan->disconnect)
2136                req.wow_ctrl_tlv.trigger |= (UNI_WOW_DETECT_TYPE_DISCONNECT |
2137                                             UNI_WOW_DETECT_TYPE_BCN_LOST);
2138        if (wowlan->nd_config) {
2139                mt76_connac_mcu_sched_scan_req(phy, vif, wowlan->nd_config);
2140                req.wow_ctrl_tlv.trigger |= UNI_WOW_DETECT_TYPE_SCH_SCAN_HIT;
2141                mt76_connac_mcu_sched_scan_enable(phy, vif, suspend);
2142        }
2143        if (wowlan->n_patterns)
2144                req.wow_ctrl_tlv.trigger |= UNI_WOW_DETECT_TYPE_BITMAP;
2145
2146        if (mt76_is_mmio(dev))
2147                req.wow_ctrl_tlv.wakeup_hif = WOW_PCIE;
2148        else if (mt76_is_usb(dev))
2149                req.wow_ctrl_tlv.wakeup_hif = WOW_USB;
2150        else if (mt76_is_sdio(dev))
2151                req.wow_ctrl_tlv.wakeup_hif = WOW_GPIO;
2152
2153        return mt76_mcu_send_msg(dev, MCU_UNI_CMD_SUSPEND, &req, sizeof(req),
2154                                 true);
2155}
2156
2157int mt76_connac_mcu_set_hif_suspend(struct mt76_dev *dev, bool suspend)
2158{
2159        struct {
2160                struct {
2161                        u8 hif_type; /* 0x0: HIF_SDIO
2162                                      * 0x1: HIF_USB
2163                                      * 0x2: HIF_PCIE
2164                                      */
2165                        u8 pad[3];
2166                } __packed hdr;
2167                struct hif_suspend_tlv {
2168                        __le16 tag;
2169                        __le16 len;
2170                        u8 suspend;
2171                } __packed hif_suspend;
2172        } req = {
2173                .hif_suspend = {
2174                        .tag = cpu_to_le16(0), /* 0: UNI_HIF_CTRL_BASIC */
2175                        .len = cpu_to_le16(sizeof(struct hif_suspend_tlv)),
2176                        .suspend = suspend,
2177                },
2178        };
2179
2180        if (mt76_is_mmio(dev))
2181                req.hdr.hif_type = 2;
2182        else if (mt76_is_usb(dev))
2183                req.hdr.hif_type = 1;
2184        else if (mt76_is_sdio(dev))
2185                req.hdr.hif_type = 0;
2186
2187        return mt76_mcu_send_msg(dev, MCU_UNI_CMD_HIF_CTRL, &req, sizeof(req),
2188                                 true);
2189}
2190EXPORT_SYMBOL_GPL(mt76_connac_mcu_set_hif_suspend);
2191
2192void mt76_connac_mcu_set_suspend_iter(void *priv, u8 *mac,
2193                                      struct ieee80211_vif *vif)
2194{
2195        struct mt76_phy *phy = priv;
2196        bool suspend = test_bit(MT76_STATE_SUSPEND, &phy->state);
2197        struct ieee80211_hw *hw = phy->hw;
2198        struct cfg80211_wowlan *wowlan = hw->wiphy->wowlan_config;
2199        int i;
2200
2201        mt76_connac_mcu_set_gtk_rekey(phy->dev, vif, suspend);
2202        mt76_connac_mcu_set_arp_filter(phy->dev, vif, suspend);
2203
2204        mt76_connac_mcu_set_suspend_mode(phy->dev, vif, suspend, 1, true);
2205
2206        for (i = 0; i < wowlan->n_patterns; i++)
2207                mt76_connac_mcu_set_wow_pattern(phy->dev, vif, i, suspend,
2208                                                &wowlan->patterns[i]);
2209        mt76_connac_mcu_set_wow_ctrl(phy, vif, suspend, wowlan);
2210}
2211EXPORT_SYMBOL_GPL(mt76_connac_mcu_set_suspend_iter);
2212
2213#endif /* CONFIG_PM */
2214
2215MODULE_AUTHOR("Lorenzo Bianconi <lorenzo@kernel.org>");
2216MODULE_LICENSE("Dual BSD/GPL");
2217