cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

mt76_connac_mcu.c (74231B)


      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,
     17				 sizeof(req), 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),
     31				 &req, 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),
     45				 &req, 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_connac_v1(dev) && addr == MCU_PATCH_ADDRESS) ||
     66	    (is_mt7921(dev) && 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	int len, i, n_max_channels, n_2ch = 0, n_5ch = 0, n_6ch = 0;
     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		u8 bw_6g;
     88		u8 pad;
     89		u8 n_2ch;
     90		u8 n_5ch;
     91		u8 n_6ch;
     92		u8 pad2;
     93	} __packed hdr = {
     94		.bw_2g = 0,
     95		.bw_5g = 3, /* BW_20_40_80_160M */
     96		.bw_6g = 3,
     97	};
     98	struct mt76_connac_mcu_chan {
     99		__le16 hw_value;
    100		__le16 pad;
    101		__le32 flags;
    102	} __packed channel;
    103	struct mt76_dev *dev = phy->dev;
    104	struct ieee80211_channel *chan;
    105	struct sk_buff *skb;
    106
    107	n_max_channels = phy->sband_2g.sband.n_channels +
    108			 phy->sband_5g.sband.n_channels +
    109			 phy->sband_6g.sband.n_channels;
    110	len = sizeof(hdr) + n_max_channels * sizeof(channel);
    111
    112	skb = mt76_mcu_msg_alloc(dev, NULL, len);
    113	if (!skb)
    114		return -ENOMEM;
    115
    116	skb_reserve(skb, sizeof(hdr));
    117
    118	for (i = 0; i < phy->sband_2g.sband.n_channels; i++) {
    119		chan = &phy->sband_2g.sband.channels[i];
    120		if (chan->flags & IEEE80211_CHAN_DISABLED)
    121			continue;
    122
    123		channel.hw_value = cpu_to_le16(chan->hw_value);
    124		channel.flags = cpu_to_le32(chan->flags);
    125		channel.pad = 0;
    126
    127		skb_put_data(skb, &channel, sizeof(channel));
    128		n_2ch++;
    129	}
    130	for (i = 0; i < phy->sband_5g.sband.n_channels; i++) {
    131		chan = &phy->sband_5g.sband.channels[i];
    132		if (chan->flags & IEEE80211_CHAN_DISABLED)
    133			continue;
    134
    135		channel.hw_value = cpu_to_le16(chan->hw_value);
    136		channel.flags = cpu_to_le32(chan->flags);
    137		channel.pad = 0;
    138
    139		skb_put_data(skb, &channel, sizeof(channel));
    140		n_5ch++;
    141	}
    142	for (i = 0; i < phy->sband_6g.sband.n_channels; i++) {
    143		chan = &phy->sband_6g.sband.channels[i];
    144		if (chan->flags & IEEE80211_CHAN_DISABLED)
    145			continue;
    146
    147		channel.hw_value = cpu_to_le16(chan->hw_value);
    148		channel.flags = cpu_to_le32(chan->flags);
    149		channel.pad = 0;
    150
    151		skb_put_data(skb, &channel, sizeof(channel));
    152		n_6ch++;
    153	}
    154
    155	BUILD_BUG_ON(sizeof(dev->alpha2) > sizeof(hdr.alpha2));
    156	memcpy(hdr.alpha2, dev->alpha2, sizeof(dev->alpha2));
    157	hdr.n_2ch = n_2ch;
    158	hdr.n_5ch = n_5ch;
    159	hdr.n_6ch = n_6ch;
    160
    161	memcpy(__skb_push(skb, sizeof(hdr)), &hdr, sizeof(hdr));
    162
    163	return mt76_mcu_skb_send_msg(dev, skb, MCU_CE_CMD(SET_CHAN_DOMAIN),
    164				     false);
    165}
    166EXPORT_SYMBOL_GPL(mt76_connac_mcu_set_channel_domain);
    167
    168int mt76_connac_mcu_set_mac_enable(struct mt76_dev *dev, int band, bool enable,
    169				   bool hdr_trans)
    170{
    171	struct {
    172		u8 enable;
    173		u8 band;
    174		u8 rsv[2];
    175	} __packed req_mac = {
    176		.enable = enable,
    177		.band = band,
    178	};
    179
    180	return mt76_mcu_send_msg(dev, MCU_EXT_CMD(MAC_INIT_CTRL), &req_mac,
    181				 sizeof(req_mac), true);
    182}
    183EXPORT_SYMBOL_GPL(mt76_connac_mcu_set_mac_enable);
    184
    185int mt76_connac_mcu_set_vif_ps(struct mt76_dev *dev, struct ieee80211_vif *vif)
    186{
    187	struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv;
    188	struct {
    189		u8 bss_idx;
    190		u8 ps_state; /* 0: device awake
    191			      * 1: static power save
    192			      * 2: dynamic power saving
    193			      */
    194	} req = {
    195		.bss_idx = mvif->idx,
    196		.ps_state = vif->bss_conf.ps ? 2 : 0,
    197	};
    198
    199	if (vif->type != NL80211_IFTYPE_STATION)
    200		return -EOPNOTSUPP;
    201
    202	return mt76_mcu_send_msg(dev, MCU_CE_CMD(SET_PS_PROFILE),
    203				 &req, sizeof(req), false);
    204}
    205EXPORT_SYMBOL_GPL(mt76_connac_mcu_set_vif_ps);
    206
    207int mt76_connac_mcu_set_rts_thresh(struct mt76_dev *dev, u32 val, u8 band)
    208{
    209	struct {
    210		u8 prot_idx;
    211		u8 band;
    212		u8 rsv[2];
    213		__le32 len_thresh;
    214		__le32 pkt_thresh;
    215	} __packed req = {
    216		.prot_idx = 1,
    217		.band = band,
    218		.len_thresh = cpu_to_le32(val),
    219		.pkt_thresh = cpu_to_le32(0x2),
    220	};
    221
    222	return mt76_mcu_send_msg(dev, MCU_EXT_CMD(PROTECT_CTRL), &req,
    223				 sizeof(req), true);
    224}
    225EXPORT_SYMBOL_GPL(mt76_connac_mcu_set_rts_thresh);
    226
    227void mt76_connac_mcu_beacon_loss_iter(void *priv, u8 *mac,
    228				      struct ieee80211_vif *vif)
    229{
    230	struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv;
    231	struct mt76_connac_beacon_loss_event *event = priv;
    232
    233	if (mvif->idx != event->bss_idx)
    234		return;
    235
    236	if (!(vif->driver_flags & IEEE80211_VIF_BEACON_FILTER))
    237		return;
    238
    239	ieee80211_beacon_loss(vif);
    240}
    241EXPORT_SYMBOL_GPL(mt76_connac_mcu_beacon_loss_iter);
    242
    243struct tlv *
    244mt76_connac_mcu_add_nested_tlv(struct sk_buff *skb, int tag, int len,
    245			       void *sta_ntlv, void *sta_wtbl)
    246{
    247	struct sta_ntlv_hdr *ntlv_hdr = sta_ntlv;
    248	struct tlv *sta_hdr = sta_wtbl;
    249	struct tlv *ptlv, tlv = {
    250		.tag = cpu_to_le16(tag),
    251		.len = cpu_to_le16(len),
    252	};
    253	u16 ntlv;
    254
    255	ptlv = skb_put(skb, len);
    256	memcpy(ptlv, &tlv, sizeof(tlv));
    257
    258	ntlv = le16_to_cpu(ntlv_hdr->tlv_num);
    259	ntlv_hdr->tlv_num = cpu_to_le16(ntlv + 1);
    260
    261	if (sta_hdr)
    262		le16_add_cpu(&sta_hdr->len, len);
    263
    264	return ptlv;
    265}
    266EXPORT_SYMBOL_GPL(mt76_connac_mcu_add_nested_tlv);
    267
    268struct sk_buff *
    269__mt76_connac_mcu_alloc_sta_req(struct mt76_dev *dev, struct mt76_vif *mvif,
    270				struct mt76_wcid *wcid, int len)
    271{
    272	struct sta_req_hdr hdr = {
    273		.bss_idx = mvif->idx,
    274		.muar_idx = wcid ? mvif->omac_idx : 0,
    275		.is_tlv_append = 1,
    276	};
    277	struct sk_buff *skb;
    278
    279	mt76_connac_mcu_get_wlan_idx(dev, wcid, &hdr.wlan_idx_lo,
    280				     &hdr.wlan_idx_hi);
    281	skb = mt76_mcu_msg_alloc(dev, NULL, len);
    282	if (!skb)
    283		return ERR_PTR(-ENOMEM);
    284
    285	skb_put_data(skb, &hdr, sizeof(hdr));
    286
    287	return skb;
    288}
    289EXPORT_SYMBOL_GPL(__mt76_connac_mcu_alloc_sta_req);
    290
    291struct wtbl_req_hdr *
    292mt76_connac_mcu_alloc_wtbl_req(struct mt76_dev *dev, struct mt76_wcid *wcid,
    293			       int cmd, void *sta_wtbl, struct sk_buff **skb)
    294{
    295	struct tlv *sta_hdr = sta_wtbl;
    296	struct wtbl_req_hdr hdr = {
    297		.operation = cmd,
    298	};
    299	struct sk_buff *nskb = *skb;
    300
    301	mt76_connac_mcu_get_wlan_idx(dev, wcid, &hdr.wlan_idx_lo,
    302				     &hdr.wlan_idx_hi);
    303	if (!nskb) {
    304		nskb = mt76_mcu_msg_alloc(dev, NULL,
    305					  MT76_CONNAC_WTBL_UPDATE_MAX_SIZE);
    306		if (!nskb)
    307			return ERR_PTR(-ENOMEM);
    308
    309		*skb = nskb;
    310	}
    311
    312	if (sta_hdr)
    313		le16_add_cpu(&sta_hdr->len, sizeof(hdr));
    314
    315	return skb_put_data(nskb, &hdr, sizeof(hdr));
    316}
    317EXPORT_SYMBOL_GPL(mt76_connac_mcu_alloc_wtbl_req);
    318
    319void mt76_connac_mcu_bss_omac_tlv(struct sk_buff *skb,
    320				  struct ieee80211_vif *vif)
    321{
    322	struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv;
    323	u8 omac_idx = mvif->omac_idx;
    324	struct bss_info_omac *omac;
    325	struct tlv *tlv;
    326	u32 type = 0;
    327
    328	switch (vif->type) {
    329	case NL80211_IFTYPE_MONITOR:
    330	case NL80211_IFTYPE_MESH_POINT:
    331	case NL80211_IFTYPE_AP:
    332		if (vif->p2p)
    333			type = CONNECTION_P2P_GO;
    334		else
    335			type = CONNECTION_INFRA_AP;
    336		break;
    337	case NL80211_IFTYPE_STATION:
    338		if (vif->p2p)
    339			type = CONNECTION_P2P_GC;
    340		else
    341			type = CONNECTION_INFRA_STA;
    342		break;
    343	case NL80211_IFTYPE_ADHOC:
    344		type = CONNECTION_IBSS_ADHOC;
    345		break;
    346	default:
    347		WARN_ON(1);
    348		break;
    349	}
    350
    351	tlv = mt76_connac_mcu_add_tlv(skb, BSS_INFO_OMAC, sizeof(*omac));
    352
    353	omac = (struct bss_info_omac *)tlv;
    354	omac->conn_type = cpu_to_le32(type);
    355	omac->omac_idx = mvif->omac_idx;
    356	omac->band_idx = mvif->band_idx;
    357	omac->hw_bss_idx = omac_idx > EXT_BSSID_START ? HW_BSSID_0 : omac_idx;
    358}
    359EXPORT_SYMBOL_GPL(mt76_connac_mcu_bss_omac_tlv);
    360
    361void mt76_connac_mcu_sta_basic_tlv(struct sk_buff *skb,
    362				   struct ieee80211_vif *vif,
    363				   struct ieee80211_sta *sta,
    364				   bool enable, bool newly)
    365{
    366	struct sta_rec_basic *basic;
    367	struct tlv *tlv;
    368	int conn_type;
    369
    370	tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_BASIC, sizeof(*basic));
    371
    372	basic = (struct sta_rec_basic *)tlv;
    373	basic->extra_info = cpu_to_le16(EXTRA_INFO_VER);
    374
    375	if (enable) {
    376		if (newly)
    377			basic->extra_info |= cpu_to_le16(EXTRA_INFO_NEW);
    378		basic->conn_state = CONN_STATE_PORT_SECURE;
    379	} else {
    380		basic->conn_state = CONN_STATE_DISCONNECT;
    381	}
    382
    383	if (!sta) {
    384		basic->conn_type = cpu_to_le32(CONNECTION_INFRA_BC);
    385		eth_broadcast_addr(basic->peer_addr);
    386		return;
    387	}
    388
    389	switch (vif->type) {
    390	case NL80211_IFTYPE_MESH_POINT:
    391	case NL80211_IFTYPE_AP:
    392		if (vif->p2p)
    393			conn_type = CONNECTION_P2P_GC;
    394		else
    395			conn_type = CONNECTION_INFRA_STA;
    396		basic->conn_type = cpu_to_le32(conn_type);
    397		basic->aid = cpu_to_le16(sta->aid);
    398		break;
    399	case NL80211_IFTYPE_STATION:
    400		if (vif->p2p)
    401			conn_type = CONNECTION_P2P_GO;
    402		else
    403			conn_type = CONNECTION_INFRA_AP;
    404		basic->conn_type = cpu_to_le32(conn_type);
    405		basic->aid = cpu_to_le16(vif->bss_conf.aid);
    406		break;
    407	case NL80211_IFTYPE_ADHOC:
    408		basic->conn_type = cpu_to_le32(CONNECTION_IBSS_ADHOC);
    409		basic->aid = cpu_to_le16(sta->aid);
    410		break;
    411	default:
    412		WARN_ON(1);
    413		break;
    414	}
    415
    416	memcpy(basic->peer_addr, sta->addr, ETH_ALEN);
    417	basic->qos = sta->wme;
    418}
    419EXPORT_SYMBOL_GPL(mt76_connac_mcu_sta_basic_tlv);
    420
    421void mt76_connac_mcu_sta_uapsd(struct sk_buff *skb, struct ieee80211_vif *vif,
    422			       struct ieee80211_sta *sta)
    423{
    424	struct sta_rec_uapsd *uapsd;
    425	struct tlv *tlv;
    426
    427	if (vif->type != NL80211_IFTYPE_AP || !sta->wme)
    428		return;
    429
    430	tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_APPS, sizeof(*uapsd));
    431	uapsd = (struct sta_rec_uapsd *)tlv;
    432
    433	if (sta->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_VO) {
    434		uapsd->dac_map |= BIT(3);
    435		uapsd->tac_map |= BIT(3);
    436	}
    437	if (sta->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_VI) {
    438		uapsd->dac_map |= BIT(2);
    439		uapsd->tac_map |= BIT(2);
    440	}
    441	if (sta->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_BE) {
    442		uapsd->dac_map |= BIT(1);
    443		uapsd->tac_map |= BIT(1);
    444	}
    445	if (sta->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_BK) {
    446		uapsd->dac_map |= BIT(0);
    447		uapsd->tac_map |= BIT(0);
    448	}
    449	uapsd->max_sp = sta->max_sp;
    450}
    451EXPORT_SYMBOL_GPL(mt76_connac_mcu_sta_uapsd);
    452
    453void mt76_connac_mcu_wtbl_hdr_trans_tlv(struct sk_buff *skb,
    454					struct ieee80211_vif *vif,
    455					struct mt76_wcid *wcid,
    456					void *sta_wtbl, void *wtbl_tlv)
    457{
    458	struct wtbl_hdr_trans *htr;
    459	struct tlv *tlv;
    460
    461	tlv = mt76_connac_mcu_add_nested_tlv(skb, WTBL_HDR_TRANS,
    462					     sizeof(*htr),
    463					     wtbl_tlv, sta_wtbl);
    464	htr = (struct wtbl_hdr_trans *)tlv;
    465	htr->no_rx_trans = true;
    466
    467	if (vif->type == NL80211_IFTYPE_STATION)
    468		htr->to_ds = true;
    469	else
    470		htr->from_ds = true;
    471
    472	if (!wcid)
    473		return;
    474
    475	htr->no_rx_trans = !test_bit(MT_WCID_FLAG_HDR_TRANS, &wcid->flags);
    476	if (test_bit(MT_WCID_FLAG_4ADDR, &wcid->flags)) {
    477		htr->to_ds = true;
    478		htr->from_ds = true;
    479	}
    480}
    481EXPORT_SYMBOL_GPL(mt76_connac_mcu_wtbl_hdr_trans_tlv);
    482
    483int mt76_connac_mcu_sta_update_hdr_trans(struct mt76_dev *dev,
    484					 struct ieee80211_vif *vif,
    485					 struct mt76_wcid *wcid, int cmd)
    486{
    487	struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv;
    488	struct wtbl_req_hdr *wtbl_hdr;
    489	struct tlv *sta_wtbl;
    490	struct sk_buff *skb;
    491
    492	skb = mt76_connac_mcu_alloc_sta_req(dev, mvif, wcid);
    493	if (IS_ERR(skb))
    494		return PTR_ERR(skb);
    495
    496	sta_wtbl = mt76_connac_mcu_add_tlv(skb, STA_REC_WTBL,
    497					   sizeof(struct tlv));
    498
    499	wtbl_hdr = mt76_connac_mcu_alloc_wtbl_req(dev, wcid, WTBL_SET,
    500						  sta_wtbl, &skb);
    501	if (IS_ERR(wtbl_hdr))
    502		return PTR_ERR(wtbl_hdr);
    503
    504	mt76_connac_mcu_wtbl_hdr_trans_tlv(skb, vif, wcid, sta_wtbl, wtbl_hdr);
    505
    506	return mt76_mcu_skb_send_msg(dev, skb, cmd, true);
    507}
    508EXPORT_SYMBOL_GPL(mt76_connac_mcu_sta_update_hdr_trans);
    509
    510int mt76_connac_mcu_wtbl_update_hdr_trans(struct mt76_dev *dev,
    511					  struct ieee80211_vif *vif,
    512					  struct ieee80211_sta *sta)
    513{
    514	struct mt76_wcid *wcid = (struct mt76_wcid *)sta->drv_priv;
    515	struct wtbl_req_hdr *wtbl_hdr;
    516	struct sk_buff *skb = NULL;
    517
    518	wtbl_hdr = mt76_connac_mcu_alloc_wtbl_req(dev, wcid, WTBL_SET, NULL,
    519						  &skb);
    520	if (IS_ERR(wtbl_hdr))
    521		return PTR_ERR(wtbl_hdr);
    522
    523	mt76_connac_mcu_wtbl_hdr_trans_tlv(skb, vif, wcid, NULL, wtbl_hdr);
    524
    525	return mt76_mcu_skb_send_msg(dev, skb, MCU_EXT_CMD(WTBL_UPDATE), true);
    526}
    527EXPORT_SYMBOL_GPL(mt76_connac_mcu_wtbl_update_hdr_trans);
    528
    529void mt76_connac_mcu_wtbl_generic_tlv(struct mt76_dev *dev,
    530				      struct sk_buff *skb,
    531				      struct ieee80211_vif *vif,
    532				      struct ieee80211_sta *sta,
    533				      void *sta_wtbl, void *wtbl_tlv)
    534{
    535	struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv;
    536	struct wtbl_generic *generic;
    537	struct wtbl_rx *rx;
    538	struct wtbl_spe *spe;
    539	struct tlv *tlv;
    540
    541	tlv = mt76_connac_mcu_add_nested_tlv(skb, WTBL_GENERIC,
    542					     sizeof(*generic),
    543					     wtbl_tlv, sta_wtbl);
    544
    545	generic = (struct wtbl_generic *)tlv;
    546
    547	if (sta) {
    548		if (vif->type == NL80211_IFTYPE_STATION)
    549			generic->partial_aid = cpu_to_le16(vif->bss_conf.aid);
    550		else
    551			generic->partial_aid = cpu_to_le16(sta->aid);
    552		memcpy(generic->peer_addr, sta->addr, ETH_ALEN);
    553		generic->muar_idx = mvif->omac_idx;
    554		generic->qos = sta->wme;
    555	} else {
    556		if (!is_connac_v1(dev) && vif->type == NL80211_IFTYPE_STATION)
    557			memcpy(generic->peer_addr, vif->bss_conf.bssid,
    558			       ETH_ALEN);
    559		else
    560			eth_broadcast_addr(generic->peer_addr);
    561
    562		generic->muar_idx = 0xe;
    563	}
    564
    565	tlv = mt76_connac_mcu_add_nested_tlv(skb, WTBL_RX, sizeof(*rx),
    566					     wtbl_tlv, sta_wtbl);
    567
    568	rx = (struct wtbl_rx *)tlv;
    569	rx->rca1 = sta ? vif->type != NL80211_IFTYPE_AP : 1;
    570	rx->rca2 = 1;
    571	rx->rv = 1;
    572
    573	if (!is_connac_v1(dev))
    574		return;
    575
    576	tlv = mt76_connac_mcu_add_nested_tlv(skb, WTBL_SPE, sizeof(*spe),
    577					     wtbl_tlv, sta_wtbl);
    578	spe = (struct wtbl_spe *)tlv;
    579	spe->spe_idx = 24;
    580}
    581EXPORT_SYMBOL_GPL(mt76_connac_mcu_wtbl_generic_tlv);
    582
    583static void
    584mt76_connac_mcu_sta_amsdu_tlv(struct sk_buff *skb, struct ieee80211_sta *sta,
    585			      struct ieee80211_vif *vif)
    586{
    587	struct mt76_wcid *wcid = (struct mt76_wcid *)sta->drv_priv;
    588	struct sta_rec_amsdu *amsdu;
    589	struct tlv *tlv;
    590
    591	if (vif->type != NL80211_IFTYPE_AP &&
    592	    vif->type != NL80211_IFTYPE_STATION)
    593		return;
    594
    595	if (!sta->max_amsdu_len)
    596		return;
    597
    598	tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_HW_AMSDU, sizeof(*amsdu));
    599	amsdu = (struct sta_rec_amsdu *)tlv;
    600	amsdu->max_amsdu_num = 8;
    601	amsdu->amsdu_en = true;
    602	amsdu->max_mpdu_size = sta->max_amsdu_len >=
    603			       IEEE80211_MAX_MPDU_LEN_VHT_7991;
    604
    605	wcid->amsdu = true;
    606}
    607
    608#define HE_PHY(p, c)	u8_get_bits(c, IEEE80211_HE_PHY_##p)
    609#define HE_MAC(m, c)	u8_get_bits(c, IEEE80211_HE_MAC_##m)
    610static void
    611mt76_connac_mcu_sta_he_tlv(struct sk_buff *skb, struct ieee80211_sta *sta)
    612{
    613	struct ieee80211_sta_he_cap *he_cap = &sta->deflink.he_cap;
    614	struct ieee80211_he_cap_elem *elem = &he_cap->he_cap_elem;
    615	struct sta_rec_he *he;
    616	struct tlv *tlv;
    617	u32 cap = 0;
    618
    619	tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_HE, sizeof(*he));
    620
    621	he = (struct sta_rec_he *)tlv;
    622
    623	if (elem->mac_cap_info[0] & IEEE80211_HE_MAC_CAP0_HTC_HE)
    624		cap |= STA_REC_HE_CAP_HTC;
    625
    626	if (elem->mac_cap_info[2] & IEEE80211_HE_MAC_CAP2_BSR)
    627		cap |= STA_REC_HE_CAP_BSR;
    628
    629	if (elem->mac_cap_info[3] & IEEE80211_HE_MAC_CAP3_OMI_CONTROL)
    630		cap |= STA_REC_HE_CAP_OM;
    631
    632	if (elem->mac_cap_info[4] & IEEE80211_HE_MAC_CAP4_AMSDU_IN_AMPDU)
    633		cap |= STA_REC_HE_CAP_AMSDU_IN_AMPDU;
    634
    635	if (elem->mac_cap_info[4] & IEEE80211_HE_MAC_CAP4_BQR)
    636		cap |= STA_REC_HE_CAP_BQR;
    637
    638	if (elem->phy_cap_info[0] &
    639	    (IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_RU_MAPPING_IN_2G |
    640	     IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_RU_MAPPING_IN_5G))
    641		cap |= STA_REC_HE_CAP_BW20_RU242_SUPPORT;
    642
    643	if (elem->phy_cap_info[1] &
    644	    IEEE80211_HE_PHY_CAP1_LDPC_CODING_IN_PAYLOAD)
    645		cap |= STA_REC_HE_CAP_LDPC;
    646
    647	if (elem->phy_cap_info[1] &
    648	    IEEE80211_HE_PHY_CAP1_HE_LTF_AND_GI_FOR_HE_PPDUS_0_8US)
    649		cap |= STA_REC_HE_CAP_SU_PPDU_1LTF_8US_GI;
    650
    651	if (elem->phy_cap_info[2] &
    652	    IEEE80211_HE_PHY_CAP2_NDP_4x_LTF_AND_3_2US)
    653		cap |= STA_REC_HE_CAP_NDP_4LTF_3DOT2MS_GI;
    654
    655	if (elem->phy_cap_info[2] &
    656	    IEEE80211_HE_PHY_CAP2_STBC_TX_UNDER_80MHZ)
    657		cap |= STA_REC_HE_CAP_LE_EQ_80M_TX_STBC;
    658
    659	if (elem->phy_cap_info[2] &
    660	    IEEE80211_HE_PHY_CAP2_STBC_RX_UNDER_80MHZ)
    661		cap |= STA_REC_HE_CAP_LE_EQ_80M_RX_STBC;
    662
    663	if (elem->phy_cap_info[6] &
    664	    IEEE80211_HE_PHY_CAP6_PARTIAL_BW_EXT_RANGE)
    665		cap |= STA_REC_HE_CAP_PARTIAL_BW_EXT_RANGE;
    666
    667	if (elem->phy_cap_info[7] &
    668	    IEEE80211_HE_PHY_CAP7_HE_SU_MU_PPDU_4XLTF_AND_08_US_GI)
    669		cap |= STA_REC_HE_CAP_SU_MU_PPDU_4LTF_8US_GI;
    670
    671	if (elem->phy_cap_info[7] &
    672	    IEEE80211_HE_PHY_CAP7_STBC_TX_ABOVE_80MHZ)
    673		cap |= STA_REC_HE_CAP_GT_80M_TX_STBC;
    674
    675	if (elem->phy_cap_info[7] &
    676	    IEEE80211_HE_PHY_CAP7_STBC_RX_ABOVE_80MHZ)
    677		cap |= STA_REC_HE_CAP_GT_80M_RX_STBC;
    678
    679	if (elem->phy_cap_info[8] &
    680	    IEEE80211_HE_PHY_CAP8_HE_ER_SU_PPDU_4XLTF_AND_08_US_GI)
    681		cap |= STA_REC_HE_CAP_ER_SU_PPDU_4LTF_8US_GI;
    682
    683	if (elem->phy_cap_info[8] &
    684	    IEEE80211_HE_PHY_CAP8_HE_ER_SU_1XLTF_AND_08_US_GI)
    685		cap |= STA_REC_HE_CAP_ER_SU_PPDU_1LTF_8US_GI;
    686
    687	if (elem->phy_cap_info[9] &
    688	    IEEE80211_HE_PHY_CAP9_NON_TRIGGERED_CQI_FEEDBACK)
    689		cap |= STA_REC_HE_CAP_TRIG_CQI_FK;
    690
    691	if (elem->phy_cap_info[9] &
    692	    IEEE80211_HE_PHY_CAP9_TX_1024_QAM_LESS_THAN_242_TONE_RU)
    693		cap |= STA_REC_HE_CAP_TX_1024QAM_UNDER_RU242;
    694
    695	if (elem->phy_cap_info[9] &
    696	    IEEE80211_HE_PHY_CAP9_RX_1024_QAM_LESS_THAN_242_TONE_RU)
    697		cap |= STA_REC_HE_CAP_RX_1024QAM_UNDER_RU242;
    698
    699	he->he_cap = cpu_to_le32(cap);
    700
    701	switch (sta->deflink.bandwidth) {
    702	case IEEE80211_STA_RX_BW_160:
    703		if (elem->phy_cap_info[0] &
    704		    IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_80PLUS80_MHZ_IN_5G)
    705			he->max_nss_mcs[CMD_HE_MCS_BW8080] =
    706				he_cap->he_mcs_nss_supp.rx_mcs_80p80;
    707
    708		he->max_nss_mcs[CMD_HE_MCS_BW160] =
    709				he_cap->he_mcs_nss_supp.rx_mcs_160;
    710		fallthrough;
    711	default:
    712		he->max_nss_mcs[CMD_HE_MCS_BW80] =
    713				he_cap->he_mcs_nss_supp.rx_mcs_80;
    714		break;
    715	}
    716
    717	he->t_frame_dur =
    718		HE_MAC(CAP1_TF_MAC_PAD_DUR_MASK, elem->mac_cap_info[1]);
    719	he->max_ampdu_exp =
    720		HE_MAC(CAP3_MAX_AMPDU_LEN_EXP_MASK, elem->mac_cap_info[3]);
    721
    722	he->bw_set =
    723		HE_PHY(CAP0_CHANNEL_WIDTH_SET_MASK, elem->phy_cap_info[0]);
    724	he->device_class =
    725		HE_PHY(CAP1_DEVICE_CLASS_A, elem->phy_cap_info[1]);
    726	he->punc_pream_rx =
    727		HE_PHY(CAP1_PREAMBLE_PUNC_RX_MASK, elem->phy_cap_info[1]);
    728
    729	he->dcm_tx_mode =
    730		HE_PHY(CAP3_DCM_MAX_CONST_TX_MASK, elem->phy_cap_info[3]);
    731	he->dcm_tx_max_nss =
    732		HE_PHY(CAP3_DCM_MAX_TX_NSS_2, elem->phy_cap_info[3]);
    733	he->dcm_rx_mode =
    734		HE_PHY(CAP3_DCM_MAX_CONST_RX_MASK, elem->phy_cap_info[3]);
    735	he->dcm_rx_max_nss =
    736		HE_PHY(CAP3_DCM_MAX_RX_NSS_2, elem->phy_cap_info[3]);
    737	he->dcm_rx_max_nss =
    738		HE_PHY(CAP8_DCM_MAX_RU_MASK, elem->phy_cap_info[8]);
    739
    740	he->pkt_ext = 2;
    741}
    742
    743static u8
    744mt76_connac_get_phy_mode_v2(struct mt76_phy *mphy, struct ieee80211_vif *vif,
    745			    enum nl80211_band band, struct ieee80211_sta *sta)
    746{
    747	struct ieee80211_sta_ht_cap *ht_cap;
    748	struct ieee80211_sta_vht_cap *vht_cap;
    749	const struct ieee80211_sta_he_cap *he_cap;
    750	u8 mode = 0;
    751
    752	if (sta) {
    753		ht_cap = &sta->deflink.ht_cap;
    754		vht_cap = &sta->deflink.vht_cap;
    755		he_cap = &sta->deflink.he_cap;
    756	} else {
    757		struct ieee80211_supported_band *sband;
    758
    759		sband = mphy->hw->wiphy->bands[band];
    760		ht_cap = &sband->ht_cap;
    761		vht_cap = &sband->vht_cap;
    762		he_cap = ieee80211_get_he_iftype_cap(sband, vif->type);
    763	}
    764
    765	if (band == NL80211_BAND_2GHZ) {
    766		mode |= PHY_TYPE_BIT_HR_DSSS | PHY_TYPE_BIT_ERP;
    767
    768		if (ht_cap->ht_supported)
    769			mode |= PHY_TYPE_BIT_HT;
    770
    771		if (he_cap && he_cap->has_he)
    772			mode |= PHY_TYPE_BIT_HE;
    773	} else if (band == NL80211_BAND_5GHZ || band == NL80211_BAND_6GHZ) {
    774		mode |= PHY_TYPE_BIT_OFDM;
    775
    776		if (ht_cap->ht_supported)
    777			mode |= PHY_TYPE_BIT_HT;
    778
    779		if (vht_cap->vht_supported)
    780			mode |= PHY_TYPE_BIT_VHT;
    781
    782		if (he_cap && he_cap->has_he)
    783			mode |= PHY_TYPE_BIT_HE;
    784	}
    785
    786	return mode;
    787}
    788
    789void mt76_connac_mcu_sta_tlv(struct mt76_phy *mphy, struct sk_buff *skb,
    790			     struct ieee80211_sta *sta,
    791			     struct ieee80211_vif *vif,
    792			     u8 rcpi, u8 sta_state)
    793{
    794	struct cfg80211_chan_def *chandef = &mphy->chandef;
    795	enum nl80211_band band = chandef->chan->band;
    796	struct mt76_dev *dev = mphy->dev;
    797	struct sta_rec_ra_info *ra_info;
    798	struct sta_rec_state *state;
    799	struct sta_rec_phy *phy;
    800	struct tlv *tlv;
    801	u16 supp_rates;
    802
    803	/* starec ht */
    804	if (sta->deflink.ht_cap.ht_supported) {
    805		struct sta_rec_ht *ht;
    806
    807		tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_HT, sizeof(*ht));
    808		ht = (struct sta_rec_ht *)tlv;
    809		ht->ht_cap = cpu_to_le16(sta->deflink.ht_cap.cap);
    810	}
    811
    812	/* starec vht */
    813	if (sta->deflink.vht_cap.vht_supported) {
    814		struct sta_rec_vht *vht;
    815		int len;
    816
    817		len = is_mt7921(dev) ? sizeof(*vht) : sizeof(*vht) - 4;
    818		tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_VHT, len);
    819		vht = (struct sta_rec_vht *)tlv;
    820		vht->vht_cap = cpu_to_le32(sta->deflink.vht_cap.cap);
    821		vht->vht_rx_mcs_map = sta->deflink.vht_cap.vht_mcs.rx_mcs_map;
    822		vht->vht_tx_mcs_map = sta->deflink.vht_cap.vht_mcs.tx_mcs_map;
    823	}
    824
    825	/* starec uapsd */
    826	mt76_connac_mcu_sta_uapsd(skb, vif, sta);
    827
    828	if (!is_mt7921(dev))
    829		return;
    830
    831	if (sta->deflink.ht_cap.ht_supported || sta->deflink.he_cap.has_he)
    832		mt76_connac_mcu_sta_amsdu_tlv(skb, sta, vif);
    833
    834	/* starec he */
    835	if (sta->deflink.he_cap.has_he) {
    836		mt76_connac_mcu_sta_he_tlv(skb, sta);
    837		if (band == NL80211_BAND_6GHZ &&
    838		    sta_state == MT76_STA_INFO_STATE_ASSOC) {
    839			struct sta_rec_he_6g_capa *he_6g_capa;
    840
    841			tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_HE_6G,
    842						      sizeof(*he_6g_capa));
    843			he_6g_capa = (struct sta_rec_he_6g_capa *)tlv;
    844			he_6g_capa->capa = sta->deflink.he_6ghz_capa.capa;
    845		}
    846	}
    847
    848	tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_PHY, sizeof(*phy));
    849	phy = (struct sta_rec_phy *)tlv;
    850	phy->phy_type = mt76_connac_get_phy_mode_v2(mphy, vif, band, sta);
    851	phy->basic_rate = cpu_to_le16((u16)vif->bss_conf.basic_rates);
    852	phy->rcpi = rcpi;
    853	phy->ampdu = FIELD_PREP(IEEE80211_HT_AMPDU_PARM_FACTOR,
    854				sta->deflink.ht_cap.ampdu_factor) |
    855		     FIELD_PREP(IEEE80211_HT_AMPDU_PARM_DENSITY,
    856				sta->deflink.ht_cap.ampdu_density);
    857
    858	tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_RA, sizeof(*ra_info));
    859	ra_info = (struct sta_rec_ra_info *)tlv;
    860
    861	supp_rates = sta->deflink.supp_rates[band];
    862	if (band == NL80211_BAND_2GHZ)
    863		supp_rates = FIELD_PREP(RA_LEGACY_OFDM, supp_rates >> 4) |
    864			     FIELD_PREP(RA_LEGACY_CCK, supp_rates & 0xf);
    865	else
    866		supp_rates = FIELD_PREP(RA_LEGACY_OFDM, supp_rates);
    867
    868	ra_info->legacy = cpu_to_le16(supp_rates);
    869
    870	if (sta->deflink.ht_cap.ht_supported)
    871		memcpy(ra_info->rx_mcs_bitmask,
    872		       sta->deflink.ht_cap.mcs.rx_mask,
    873		       HT_MCS_MASK_NUM);
    874
    875	tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_STATE, sizeof(*state));
    876	state = (struct sta_rec_state *)tlv;
    877	state->state = sta_state;
    878
    879	if (sta->deflink.vht_cap.vht_supported) {
    880		state->vht_opmode = sta->deflink.bandwidth;
    881		state->vht_opmode |= (sta->deflink.rx_nss - 1) <<
    882			IEEE80211_OPMODE_NOTIF_RX_NSS_SHIFT;
    883	}
    884}
    885EXPORT_SYMBOL_GPL(mt76_connac_mcu_sta_tlv);
    886
    887void mt76_connac_mcu_wtbl_smps_tlv(struct sk_buff *skb,
    888				   struct ieee80211_sta *sta,
    889				   void *sta_wtbl, void *wtbl_tlv)
    890{
    891	struct wtbl_smps *smps;
    892	struct tlv *tlv;
    893
    894	tlv = mt76_connac_mcu_add_nested_tlv(skb, WTBL_SMPS, sizeof(*smps),
    895					     wtbl_tlv, sta_wtbl);
    896	smps = (struct wtbl_smps *)tlv;
    897	smps->smps = (sta->smps_mode == IEEE80211_SMPS_DYNAMIC);
    898}
    899EXPORT_SYMBOL_GPL(mt76_connac_mcu_wtbl_smps_tlv);
    900
    901void mt76_connac_mcu_wtbl_ht_tlv(struct mt76_dev *dev, struct sk_buff *skb,
    902				 struct ieee80211_sta *sta, void *sta_wtbl,
    903				 void *wtbl_tlv, bool ht_ldpc, bool vht_ldpc)
    904{
    905	struct wtbl_ht *ht = NULL;
    906	struct tlv *tlv;
    907	u32 flags = 0;
    908
    909	if (sta->deflink.ht_cap.ht_supported || sta->deflink.he_6ghz_capa.capa) {
    910		tlv = mt76_connac_mcu_add_nested_tlv(skb, WTBL_HT, sizeof(*ht),
    911						     wtbl_tlv, sta_wtbl);
    912		ht = (struct wtbl_ht *)tlv;
    913		ht->ldpc = ht_ldpc &&
    914			   !!(sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_LDPC_CODING);
    915
    916		if (sta->deflink.ht_cap.ht_supported) {
    917			ht->af = sta->deflink.ht_cap.ampdu_factor;
    918			ht->mm = sta->deflink.ht_cap.ampdu_density;
    919		} else {
    920			ht->af = le16_get_bits(sta->deflink.he_6ghz_capa.capa,
    921					       IEEE80211_HE_6GHZ_CAP_MAX_AMPDU_LEN_EXP);
    922			ht->mm = le16_get_bits(sta->deflink.he_6ghz_capa.capa,
    923					       IEEE80211_HE_6GHZ_CAP_MIN_MPDU_START);
    924		}
    925
    926		ht->ht = true;
    927	}
    928
    929	if (sta->deflink.vht_cap.vht_supported || sta->deflink.he_6ghz_capa.capa) {
    930		struct wtbl_vht *vht;
    931		u8 af;
    932
    933		tlv = mt76_connac_mcu_add_nested_tlv(skb, WTBL_VHT,
    934						     sizeof(*vht), wtbl_tlv,
    935						     sta_wtbl);
    936		vht = (struct wtbl_vht *)tlv;
    937		vht->ldpc = vht_ldpc &&
    938			    !!(sta->deflink.vht_cap.cap & IEEE80211_VHT_CAP_RXLDPC);
    939		vht->vht = true;
    940
    941		af = FIELD_GET(IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK,
    942			       sta->deflink.vht_cap.cap);
    943		if (ht)
    944			ht->af = max(ht->af, af);
    945	}
    946
    947	mt76_connac_mcu_wtbl_smps_tlv(skb, sta, sta_wtbl, wtbl_tlv);
    948
    949	if (is_connac_v1(dev) && sta->deflink.ht_cap.ht_supported) {
    950		/* sgi */
    951		u32 msk = MT_WTBL_W5_SHORT_GI_20 | MT_WTBL_W5_SHORT_GI_40 |
    952			  MT_WTBL_W5_SHORT_GI_80 | MT_WTBL_W5_SHORT_GI_160;
    953		struct wtbl_raw *raw;
    954
    955		tlv = mt76_connac_mcu_add_nested_tlv(skb, WTBL_RAW_DATA,
    956						     sizeof(*raw), wtbl_tlv,
    957						     sta_wtbl);
    958
    959		if (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SGI_20)
    960			flags |= MT_WTBL_W5_SHORT_GI_20;
    961		if (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SGI_40)
    962			flags |= MT_WTBL_W5_SHORT_GI_40;
    963
    964		if (sta->deflink.vht_cap.vht_supported) {
    965			if (sta->deflink.vht_cap.cap & IEEE80211_VHT_CAP_SHORT_GI_80)
    966				flags |= MT_WTBL_W5_SHORT_GI_80;
    967			if (sta->deflink.vht_cap.cap & IEEE80211_VHT_CAP_SHORT_GI_160)
    968				flags |= MT_WTBL_W5_SHORT_GI_160;
    969		}
    970		raw = (struct wtbl_raw *)tlv;
    971		raw->val = cpu_to_le32(flags);
    972		raw->msk = cpu_to_le32(~msk);
    973		raw->wtbl_idx = 1;
    974		raw->dw = 5;
    975	}
    976}
    977EXPORT_SYMBOL_GPL(mt76_connac_mcu_wtbl_ht_tlv);
    978
    979int mt76_connac_mcu_sta_cmd(struct mt76_phy *phy,
    980			    struct mt76_sta_cmd_info *info)
    981{
    982	struct mt76_vif *mvif = (struct mt76_vif *)info->vif->drv_priv;
    983	struct mt76_dev *dev = phy->dev;
    984	struct wtbl_req_hdr *wtbl_hdr;
    985	struct tlv *sta_wtbl;
    986	struct sk_buff *skb;
    987
    988	skb = mt76_connac_mcu_alloc_sta_req(dev, mvif, info->wcid);
    989	if (IS_ERR(skb))
    990		return PTR_ERR(skb);
    991
    992	if (info->sta || !info->offload_fw)
    993		mt76_connac_mcu_sta_basic_tlv(skb, info->vif, info->sta,
    994					      info->enable, info->newly);
    995	if (info->sta && info->enable)
    996		mt76_connac_mcu_sta_tlv(phy, skb, info->sta,
    997					info->vif, info->rcpi,
    998					info->state);
    999
   1000	sta_wtbl = mt76_connac_mcu_add_tlv(skb, STA_REC_WTBL,
   1001					   sizeof(struct tlv));
   1002
   1003	wtbl_hdr = mt76_connac_mcu_alloc_wtbl_req(dev, info->wcid,
   1004						  WTBL_RESET_AND_SET,
   1005						  sta_wtbl, &skb);
   1006	if (IS_ERR(wtbl_hdr))
   1007		return PTR_ERR(wtbl_hdr);
   1008
   1009	if (info->enable) {
   1010		mt76_connac_mcu_wtbl_generic_tlv(dev, skb, info->vif,
   1011						 info->sta, sta_wtbl,
   1012						 wtbl_hdr);
   1013		mt76_connac_mcu_wtbl_hdr_trans_tlv(skb, info->vif, info->wcid,
   1014						   sta_wtbl, wtbl_hdr);
   1015		if (info->sta)
   1016			mt76_connac_mcu_wtbl_ht_tlv(dev, skb, info->sta,
   1017						    sta_wtbl, wtbl_hdr,
   1018						    true, true);
   1019	}
   1020
   1021	return mt76_mcu_skb_send_msg(dev, skb, info->cmd, true);
   1022}
   1023EXPORT_SYMBOL_GPL(mt76_connac_mcu_sta_cmd);
   1024
   1025void mt76_connac_mcu_wtbl_ba_tlv(struct mt76_dev *dev, struct sk_buff *skb,
   1026				 struct ieee80211_ampdu_params *params,
   1027				 bool enable, bool tx, void *sta_wtbl,
   1028				 void *wtbl_tlv)
   1029{
   1030	struct wtbl_ba *ba;
   1031	struct tlv *tlv;
   1032
   1033	tlv = mt76_connac_mcu_add_nested_tlv(skb, WTBL_BA, sizeof(*ba),
   1034					     wtbl_tlv, sta_wtbl);
   1035
   1036	ba = (struct wtbl_ba *)tlv;
   1037	ba->tid = params->tid;
   1038
   1039	if (tx) {
   1040		ba->ba_type = MT_BA_TYPE_ORIGINATOR;
   1041		ba->sn = enable ? cpu_to_le16(params->ssn) : 0;
   1042		ba->ba_winsize = enable ? cpu_to_le16(params->buf_size) : 0;
   1043		ba->ba_en = enable;
   1044	} else {
   1045		memcpy(ba->peer_addr, params->sta->addr, ETH_ALEN);
   1046		ba->ba_type = MT_BA_TYPE_RECIPIENT;
   1047		ba->rst_ba_tid = params->tid;
   1048		ba->rst_ba_sel = RST_BA_MAC_TID_MATCH;
   1049		ba->rst_ba_sb = 1;
   1050	}
   1051
   1052	if (!is_connac_v1(dev)) {
   1053		ba->ba_winsize = enable ? cpu_to_le16(params->buf_size) : 0;
   1054		return;
   1055	}
   1056
   1057	if (enable && tx) {
   1058		static const u8 ba_range[] = { 4, 8, 12, 24, 36, 48, 54, 64 };
   1059		int i;
   1060
   1061		for (i = 7; i > 0; i--) {
   1062			if (params->buf_size >= ba_range[i])
   1063				break;
   1064		}
   1065		ba->ba_winsize_idx = i;
   1066	}
   1067}
   1068EXPORT_SYMBOL_GPL(mt76_connac_mcu_wtbl_ba_tlv);
   1069
   1070int mt76_connac_mcu_uni_add_dev(struct mt76_phy *phy,
   1071				struct ieee80211_vif *vif,
   1072				struct mt76_wcid *wcid,
   1073				bool enable)
   1074{
   1075	struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv;
   1076	struct mt76_dev *dev = phy->dev;
   1077	struct {
   1078		struct {
   1079			u8 omac_idx;
   1080			u8 band_idx;
   1081			__le16 pad;
   1082		} __packed hdr;
   1083		struct req_tlv {
   1084			__le16 tag;
   1085			__le16 len;
   1086			u8 active;
   1087			u8 pad;
   1088			u8 omac_addr[ETH_ALEN];
   1089		} __packed tlv;
   1090	} dev_req = {
   1091		.hdr = {
   1092			.omac_idx = mvif->omac_idx,
   1093			.band_idx = mvif->band_idx,
   1094		},
   1095		.tlv = {
   1096			.tag = cpu_to_le16(DEV_INFO_ACTIVE),
   1097			.len = cpu_to_le16(sizeof(struct req_tlv)),
   1098			.active = enable,
   1099		},
   1100	};
   1101	struct {
   1102		struct {
   1103			u8 bss_idx;
   1104			u8 pad[3];
   1105		} __packed hdr;
   1106		struct mt76_connac_bss_basic_tlv basic;
   1107	} basic_req = {
   1108		.hdr = {
   1109			.bss_idx = mvif->idx,
   1110		},
   1111		.basic = {
   1112			.tag = cpu_to_le16(UNI_BSS_INFO_BASIC),
   1113			.len = cpu_to_le16(sizeof(struct mt76_connac_bss_basic_tlv)),
   1114			.omac_idx = mvif->omac_idx,
   1115			.band_idx = mvif->band_idx,
   1116			.wmm_idx = mvif->wmm_idx,
   1117			.active = enable,
   1118			.bmc_tx_wlan_idx = cpu_to_le16(wcid->idx),
   1119			.sta_idx = cpu_to_le16(wcid->idx),
   1120			.conn_state = 1,
   1121		},
   1122	};
   1123	int err, idx, cmd, len;
   1124	void *data;
   1125
   1126	switch (vif->type) {
   1127	case NL80211_IFTYPE_MESH_POINT:
   1128	case NL80211_IFTYPE_MONITOR:
   1129	case NL80211_IFTYPE_AP:
   1130		basic_req.basic.conn_type = cpu_to_le32(CONNECTION_INFRA_AP);
   1131		break;
   1132	case NL80211_IFTYPE_STATION:
   1133		basic_req.basic.conn_type = cpu_to_le32(CONNECTION_INFRA_STA);
   1134		break;
   1135	case NL80211_IFTYPE_ADHOC:
   1136		basic_req.basic.conn_type = cpu_to_le32(CONNECTION_IBSS_ADHOC);
   1137		break;
   1138	default:
   1139		WARN_ON(1);
   1140		break;
   1141	}
   1142
   1143	idx = mvif->omac_idx > EXT_BSSID_START ? HW_BSSID_0 : mvif->omac_idx;
   1144	basic_req.basic.hw_bss_idx = idx;
   1145
   1146	memcpy(dev_req.tlv.omac_addr, vif->addr, ETH_ALEN);
   1147
   1148	cmd = enable ? MCU_UNI_CMD(DEV_INFO_UPDATE) : MCU_UNI_CMD(BSS_INFO_UPDATE);
   1149	data = enable ? (void *)&dev_req : (void *)&basic_req;
   1150	len = enable ? sizeof(dev_req) : sizeof(basic_req);
   1151
   1152	err = mt76_mcu_send_msg(dev, cmd, data, len, true);
   1153	if (err < 0)
   1154		return err;
   1155
   1156	cmd = enable ? MCU_UNI_CMD(BSS_INFO_UPDATE) : MCU_UNI_CMD(DEV_INFO_UPDATE);
   1157	data = enable ? (void *)&basic_req : (void *)&dev_req;
   1158	len = enable ? sizeof(basic_req) : sizeof(dev_req);
   1159
   1160	return mt76_mcu_send_msg(dev, cmd, data, len, true);
   1161}
   1162EXPORT_SYMBOL_GPL(mt76_connac_mcu_uni_add_dev);
   1163
   1164void mt76_connac_mcu_sta_ba_tlv(struct sk_buff *skb,
   1165				struct ieee80211_ampdu_params *params,
   1166				bool enable, bool tx)
   1167{
   1168	struct sta_rec_ba *ba;
   1169	struct tlv *tlv;
   1170
   1171	tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_BA, sizeof(*ba));
   1172
   1173	ba = (struct sta_rec_ba *)tlv;
   1174	ba->ba_type = tx ? MT_BA_TYPE_ORIGINATOR : MT_BA_TYPE_RECIPIENT;
   1175	ba->winsize = cpu_to_le16(params->buf_size);
   1176	ba->ssn = cpu_to_le16(params->ssn);
   1177	ba->ba_en = enable << params->tid;
   1178	ba->amsdu = params->amsdu;
   1179	ba->tid = params->tid;
   1180}
   1181EXPORT_SYMBOL_GPL(mt76_connac_mcu_sta_ba_tlv);
   1182
   1183int mt76_connac_mcu_sta_ba(struct mt76_dev *dev, struct mt76_vif *mvif,
   1184			   struct ieee80211_ampdu_params *params,
   1185			   int cmd, bool enable, bool tx)
   1186{
   1187	struct mt76_wcid *wcid = (struct mt76_wcid *)params->sta->drv_priv;
   1188	struct wtbl_req_hdr *wtbl_hdr;
   1189	struct tlv *sta_wtbl;
   1190	struct sk_buff *skb;
   1191	int ret;
   1192
   1193	skb = mt76_connac_mcu_alloc_sta_req(dev, mvif, wcid);
   1194	if (IS_ERR(skb))
   1195		return PTR_ERR(skb);
   1196
   1197	sta_wtbl = mt76_connac_mcu_add_tlv(skb, STA_REC_WTBL,
   1198					   sizeof(struct tlv));
   1199
   1200	wtbl_hdr = mt76_connac_mcu_alloc_wtbl_req(dev, wcid, WTBL_SET,
   1201						  sta_wtbl, &skb);
   1202	if (IS_ERR(wtbl_hdr))
   1203		return PTR_ERR(wtbl_hdr);
   1204
   1205	mt76_connac_mcu_wtbl_ba_tlv(dev, skb, params, enable, tx, sta_wtbl,
   1206				    wtbl_hdr);
   1207
   1208	ret = mt76_mcu_skb_send_msg(dev, skb, cmd, true);
   1209	if (ret)
   1210		return ret;
   1211
   1212	skb = mt76_connac_mcu_alloc_sta_req(dev, mvif, wcid);
   1213	if (IS_ERR(skb))
   1214		return PTR_ERR(skb);
   1215
   1216	mt76_connac_mcu_sta_ba_tlv(skb, params, enable, tx);
   1217
   1218	return mt76_mcu_skb_send_msg(dev, skb, cmd, true);
   1219}
   1220EXPORT_SYMBOL_GPL(mt76_connac_mcu_sta_ba);
   1221
   1222u8 mt76_connac_get_phy_mode(struct mt76_phy *phy, struct ieee80211_vif *vif,
   1223			    enum nl80211_band band, struct ieee80211_sta *sta)
   1224{
   1225	struct mt76_dev *dev = phy->dev;
   1226	const struct ieee80211_sta_he_cap *he_cap;
   1227	struct ieee80211_sta_vht_cap *vht_cap;
   1228	struct ieee80211_sta_ht_cap *ht_cap;
   1229	u8 mode = 0;
   1230
   1231	if (is_connac_v1(dev))
   1232		return 0x38;
   1233
   1234	if (sta) {
   1235		ht_cap = &sta->deflink.ht_cap;
   1236		vht_cap = &sta->deflink.vht_cap;
   1237		he_cap = &sta->deflink.he_cap;
   1238	} else {
   1239		struct ieee80211_supported_band *sband;
   1240
   1241		sband = phy->hw->wiphy->bands[band];
   1242		ht_cap = &sband->ht_cap;
   1243		vht_cap = &sband->vht_cap;
   1244		he_cap = ieee80211_get_he_iftype_cap(sband, vif->type);
   1245	}
   1246
   1247	if (band == NL80211_BAND_2GHZ) {
   1248		mode |= PHY_MODE_B | PHY_MODE_G;
   1249
   1250		if (ht_cap->ht_supported)
   1251			mode |= PHY_MODE_GN;
   1252
   1253		if (he_cap && he_cap->has_he)
   1254			mode |= PHY_MODE_AX_24G;
   1255	} else if (band == NL80211_BAND_5GHZ) {
   1256		mode |= PHY_MODE_A;
   1257
   1258		if (ht_cap->ht_supported)
   1259			mode |= PHY_MODE_AN;
   1260
   1261		if (vht_cap->vht_supported)
   1262			mode |= PHY_MODE_AC;
   1263
   1264		if (he_cap && he_cap->has_he)
   1265			mode |= PHY_MODE_AX_5G;
   1266	} else if (band == NL80211_BAND_6GHZ) {
   1267		mode |= PHY_MODE_A | PHY_MODE_AN |
   1268			PHY_MODE_AC | PHY_MODE_AX_5G;
   1269	}
   1270
   1271	return mode;
   1272}
   1273EXPORT_SYMBOL_GPL(mt76_connac_get_phy_mode);
   1274
   1275const struct ieee80211_sta_he_cap *
   1276mt76_connac_get_he_phy_cap(struct mt76_phy *phy, struct ieee80211_vif *vif)
   1277{
   1278	enum nl80211_band band = phy->chandef.chan->band;
   1279	struct ieee80211_supported_band *sband;
   1280
   1281	sband = phy->hw->wiphy->bands[band];
   1282
   1283	return ieee80211_get_he_iftype_cap(sband, vif->type);
   1284}
   1285EXPORT_SYMBOL_GPL(mt76_connac_get_he_phy_cap);
   1286
   1287#define DEFAULT_HE_PE_DURATION		4
   1288#define DEFAULT_HE_DURATION_RTS_THRES	1023
   1289static void
   1290mt76_connac_mcu_uni_bss_he_tlv(struct mt76_phy *phy, struct ieee80211_vif *vif,
   1291			       struct tlv *tlv)
   1292{
   1293	const struct ieee80211_sta_he_cap *cap;
   1294	struct bss_info_uni_he *he;
   1295
   1296	cap = mt76_connac_get_he_phy_cap(phy, vif);
   1297
   1298	he = (struct bss_info_uni_he *)tlv;
   1299	he->he_pe_duration = vif->bss_conf.htc_trig_based_pkt_ext;
   1300	if (!he->he_pe_duration)
   1301		he->he_pe_duration = DEFAULT_HE_PE_DURATION;
   1302
   1303	he->he_rts_thres = cpu_to_le16(vif->bss_conf.frame_time_rts_th);
   1304	if (!he->he_rts_thres)
   1305		he->he_rts_thres = cpu_to_le16(DEFAULT_HE_DURATION_RTS_THRES);
   1306
   1307	he->max_nss_mcs[CMD_HE_MCS_BW80] = cap->he_mcs_nss_supp.tx_mcs_80;
   1308	he->max_nss_mcs[CMD_HE_MCS_BW160] = cap->he_mcs_nss_supp.tx_mcs_160;
   1309	he->max_nss_mcs[CMD_HE_MCS_BW8080] = cap->he_mcs_nss_supp.tx_mcs_80p80;
   1310}
   1311
   1312int mt76_connac_mcu_uni_add_bss(struct mt76_phy *phy,
   1313				struct ieee80211_vif *vif,
   1314				struct mt76_wcid *wcid,
   1315				bool enable)
   1316{
   1317	struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv;
   1318	struct cfg80211_chan_def *chandef = &phy->chandef;
   1319	int freq1 = chandef->center_freq1, freq2 = chandef->center_freq2;
   1320	enum nl80211_band band = chandef->chan->band;
   1321	struct mt76_dev *mdev = phy->dev;
   1322	struct {
   1323		struct {
   1324			u8 bss_idx;
   1325			u8 pad[3];
   1326		} __packed hdr;
   1327		struct mt76_connac_bss_basic_tlv basic;
   1328		struct mt76_connac_bss_qos_tlv qos;
   1329	} basic_req = {
   1330		.hdr = {
   1331			.bss_idx = mvif->idx,
   1332		},
   1333		.basic = {
   1334			.tag = cpu_to_le16(UNI_BSS_INFO_BASIC),
   1335			.len = cpu_to_le16(sizeof(struct mt76_connac_bss_basic_tlv)),
   1336			.bcn_interval = cpu_to_le16(vif->bss_conf.beacon_int),
   1337			.dtim_period = vif->bss_conf.dtim_period,
   1338			.omac_idx = mvif->omac_idx,
   1339			.band_idx = mvif->band_idx,
   1340			.wmm_idx = mvif->wmm_idx,
   1341			.active = true, /* keep bss deactivated */
   1342			.phymode = mt76_connac_get_phy_mode(phy, vif, band, NULL),
   1343		},
   1344		.qos = {
   1345			.tag = cpu_to_le16(UNI_BSS_INFO_QBSS),
   1346			.len = cpu_to_le16(sizeof(struct mt76_connac_bss_qos_tlv)),
   1347			.qos = vif->bss_conf.qos,
   1348		},
   1349	};
   1350	struct {
   1351		struct {
   1352			u8 bss_idx;
   1353			u8 pad[3];
   1354		} __packed hdr;
   1355		struct rlm_tlv {
   1356			__le16 tag;
   1357			__le16 len;
   1358			u8 control_channel;
   1359			u8 center_chan;
   1360			u8 center_chan2;
   1361			u8 bw;
   1362			u8 tx_streams;
   1363			u8 rx_streams;
   1364			u8 short_st;
   1365			u8 ht_op_info;
   1366			u8 sco;
   1367			u8 band;
   1368			u8 pad[2];
   1369		} __packed rlm;
   1370	} __packed rlm_req = {
   1371		.hdr = {
   1372			.bss_idx = mvif->idx,
   1373		},
   1374		.rlm = {
   1375			.tag = cpu_to_le16(UNI_BSS_INFO_RLM),
   1376			.len = cpu_to_le16(sizeof(struct rlm_tlv)),
   1377			.control_channel = chandef->chan->hw_value,
   1378			.center_chan = ieee80211_frequency_to_channel(freq1),
   1379			.center_chan2 = ieee80211_frequency_to_channel(freq2),
   1380			.tx_streams = hweight8(phy->antenna_mask),
   1381			.ht_op_info = 4, /* set HT 40M allowed */
   1382			.rx_streams = phy->chainmask,
   1383			.short_st = true,
   1384			.band = band,
   1385		},
   1386	};
   1387	int err, conn_type;
   1388	u8 idx, basic_phy;
   1389
   1390	idx = mvif->omac_idx > EXT_BSSID_START ? HW_BSSID_0 : mvif->omac_idx;
   1391	basic_req.basic.hw_bss_idx = idx;
   1392	if (band == NL80211_BAND_6GHZ)
   1393		basic_req.basic.phymode_ext = PHY_MODE_AX_6G;
   1394
   1395	basic_phy = mt76_connac_get_phy_mode_v2(phy, vif, band, NULL);
   1396	basic_req.basic.nonht_basic_phy = cpu_to_le16(basic_phy);
   1397
   1398	switch (vif->type) {
   1399	case NL80211_IFTYPE_MESH_POINT:
   1400	case NL80211_IFTYPE_AP:
   1401		if (vif->p2p)
   1402			conn_type = CONNECTION_P2P_GO;
   1403		else
   1404			conn_type = CONNECTION_INFRA_AP;
   1405		basic_req.basic.conn_type = cpu_to_le32(conn_type);
   1406		break;
   1407	case NL80211_IFTYPE_STATION:
   1408		if (vif->p2p)
   1409			conn_type = CONNECTION_P2P_GC;
   1410		else
   1411			conn_type = CONNECTION_INFRA_STA;
   1412		basic_req.basic.conn_type = cpu_to_le32(conn_type);
   1413		break;
   1414	case NL80211_IFTYPE_ADHOC:
   1415		basic_req.basic.conn_type = cpu_to_le32(CONNECTION_IBSS_ADHOC);
   1416		break;
   1417	default:
   1418		WARN_ON(1);
   1419		break;
   1420	}
   1421
   1422	memcpy(basic_req.basic.bssid, vif->bss_conf.bssid, ETH_ALEN);
   1423	basic_req.basic.bmc_tx_wlan_idx = cpu_to_le16(wcid->idx);
   1424	basic_req.basic.sta_idx = cpu_to_le16(wcid->idx);
   1425	basic_req.basic.conn_state = !enable;
   1426
   1427	err = mt76_mcu_send_msg(mdev, MCU_UNI_CMD(BSS_INFO_UPDATE), &basic_req,
   1428				sizeof(basic_req), true);
   1429	if (err < 0)
   1430		return err;
   1431
   1432	if (vif->bss_conf.he_support) {
   1433		struct {
   1434			struct {
   1435				u8 bss_idx;
   1436				u8 pad[3];
   1437			} __packed hdr;
   1438			struct bss_info_uni_he he;
   1439			struct bss_info_uni_bss_color bss_color;
   1440		} he_req = {
   1441			.hdr = {
   1442				.bss_idx = mvif->idx,
   1443			},
   1444			.he = {
   1445				.tag = cpu_to_le16(UNI_BSS_INFO_HE_BASIC),
   1446				.len = cpu_to_le16(sizeof(struct bss_info_uni_he)),
   1447			},
   1448			.bss_color = {
   1449				.tag = cpu_to_le16(UNI_BSS_INFO_BSS_COLOR),
   1450				.len = cpu_to_le16(sizeof(struct bss_info_uni_bss_color)),
   1451				.enable = 0,
   1452				.bss_color = 0,
   1453			},
   1454		};
   1455
   1456		if (enable) {
   1457			he_req.bss_color.enable =
   1458				vif->bss_conf.he_bss_color.enabled;
   1459			he_req.bss_color.bss_color =
   1460				vif->bss_conf.he_bss_color.color;
   1461		}
   1462
   1463		mt76_connac_mcu_uni_bss_he_tlv(phy, vif,
   1464					       (struct tlv *)&he_req.he);
   1465		err = mt76_mcu_send_msg(mdev, MCU_UNI_CMD(BSS_INFO_UPDATE),
   1466					&he_req, sizeof(he_req), true);
   1467		if (err < 0)
   1468			return err;
   1469	}
   1470
   1471	switch (chandef->width) {
   1472	case NL80211_CHAN_WIDTH_40:
   1473		rlm_req.rlm.bw = CMD_CBW_40MHZ;
   1474		break;
   1475	case NL80211_CHAN_WIDTH_80:
   1476		rlm_req.rlm.bw = CMD_CBW_80MHZ;
   1477		break;
   1478	case NL80211_CHAN_WIDTH_80P80:
   1479		rlm_req.rlm.bw = CMD_CBW_8080MHZ;
   1480		break;
   1481	case NL80211_CHAN_WIDTH_160:
   1482		rlm_req.rlm.bw = CMD_CBW_160MHZ;
   1483		break;
   1484	case NL80211_CHAN_WIDTH_5:
   1485		rlm_req.rlm.bw = CMD_CBW_5MHZ;
   1486		break;
   1487	case NL80211_CHAN_WIDTH_10:
   1488		rlm_req.rlm.bw = CMD_CBW_10MHZ;
   1489		break;
   1490	case NL80211_CHAN_WIDTH_20_NOHT:
   1491	case NL80211_CHAN_WIDTH_20:
   1492	default:
   1493		rlm_req.rlm.bw = CMD_CBW_20MHZ;
   1494		rlm_req.rlm.ht_op_info = 0;
   1495		break;
   1496	}
   1497
   1498	if (rlm_req.rlm.control_channel < rlm_req.rlm.center_chan)
   1499		rlm_req.rlm.sco = 1; /* SCA */
   1500	else if (rlm_req.rlm.control_channel > rlm_req.rlm.center_chan)
   1501		rlm_req.rlm.sco = 3; /* SCB */
   1502
   1503	return mt76_mcu_send_msg(mdev, MCU_UNI_CMD(BSS_INFO_UPDATE), &rlm_req,
   1504				 sizeof(rlm_req), true);
   1505}
   1506EXPORT_SYMBOL_GPL(mt76_connac_mcu_uni_add_bss);
   1507
   1508#define MT76_CONNAC_SCAN_CHANNEL_TIME		60
   1509int mt76_connac_mcu_hw_scan(struct mt76_phy *phy, struct ieee80211_vif *vif,
   1510			    struct ieee80211_scan_request *scan_req)
   1511{
   1512	struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv;
   1513	struct cfg80211_scan_request *sreq = &scan_req->req;
   1514	int n_ssids = 0, err, i, duration;
   1515	int ext_channels_num = max_t(int, sreq->n_channels - 32, 0);
   1516	struct ieee80211_channel **scan_list = sreq->channels;
   1517	struct mt76_dev *mdev = phy->dev;
   1518	struct mt76_connac_mcu_scan_channel *chan;
   1519	struct mt76_connac_hw_scan_req *req;
   1520	struct sk_buff *skb;
   1521
   1522	skb = mt76_mcu_msg_alloc(mdev, NULL, sizeof(*req));
   1523	if (!skb)
   1524		return -ENOMEM;
   1525
   1526	set_bit(MT76_HW_SCANNING, &phy->state);
   1527	mvif->scan_seq_num = (mvif->scan_seq_num + 1) & 0x7f;
   1528
   1529	req = (struct mt76_connac_hw_scan_req *)skb_put(skb, sizeof(*req));
   1530
   1531	req->seq_num = mvif->scan_seq_num | mvif->band_idx << 7;
   1532	req->bss_idx = mvif->idx;
   1533	req->scan_type = sreq->n_ssids ? 1 : 0;
   1534	req->probe_req_num = sreq->n_ssids ? 2 : 0;
   1535	req->version = 1;
   1536
   1537	for (i = 0; i < sreq->n_ssids; i++) {
   1538		if (!sreq->ssids[i].ssid_len)
   1539			continue;
   1540
   1541		req->ssids[i].ssid_len = cpu_to_le32(sreq->ssids[i].ssid_len);
   1542		memcpy(req->ssids[i].ssid, sreq->ssids[i].ssid,
   1543		       sreq->ssids[i].ssid_len);
   1544		n_ssids++;
   1545	}
   1546	req->ssid_type = n_ssids ? BIT(2) : BIT(0);
   1547	req->ssid_type_ext = n_ssids ? BIT(0) : 0;
   1548	req->ssids_num = n_ssids;
   1549
   1550	duration = is_mt7921(phy->dev) ? 0 : MT76_CONNAC_SCAN_CHANNEL_TIME;
   1551	/* increase channel time for passive scan */
   1552	if (!sreq->n_ssids)
   1553		duration *= 2;
   1554	req->timeout_value = cpu_to_le16(sreq->n_channels * duration);
   1555	req->channel_min_dwell_time = cpu_to_le16(duration);
   1556	req->channel_dwell_time = cpu_to_le16(duration);
   1557
   1558	req->channels_num = min_t(u8, sreq->n_channels, 32);
   1559	req->ext_channels_num = min_t(u8, ext_channels_num, 32);
   1560	for (i = 0; i < req->channels_num + req->ext_channels_num; i++) {
   1561		if (i >= 32)
   1562			chan = &req->ext_channels[i - 32];
   1563		else
   1564			chan = &req->channels[i];
   1565
   1566		switch (scan_list[i]->band) {
   1567		case NL80211_BAND_2GHZ:
   1568			chan->band = 1;
   1569			break;
   1570		case NL80211_BAND_6GHZ:
   1571			chan->band = 3;
   1572			break;
   1573		default:
   1574			chan->band = 2;
   1575			break;
   1576		}
   1577		chan->channel_num = scan_list[i]->hw_value;
   1578	}
   1579	req->channel_type = sreq->n_channels ? 4 : 0;
   1580
   1581	if (sreq->ie_len > 0) {
   1582		memcpy(req->ies, sreq->ie, sreq->ie_len);
   1583		req->ies_len = cpu_to_le16(sreq->ie_len);
   1584	}
   1585
   1586	if (is_mt7921(phy->dev))
   1587		req->scan_func |= SCAN_FUNC_SPLIT_SCAN;
   1588
   1589	memcpy(req->bssid, sreq->bssid, ETH_ALEN);
   1590	if (sreq->flags & NL80211_SCAN_FLAG_RANDOM_ADDR) {
   1591		get_random_mask_addr(req->random_mac, sreq->mac_addr,
   1592				     sreq->mac_addr_mask);
   1593		req->scan_func |= SCAN_FUNC_RANDOM_MAC;
   1594	}
   1595
   1596	err = mt76_mcu_skb_send_msg(mdev, skb, MCU_CE_CMD(START_HW_SCAN),
   1597				    false);
   1598	if (err < 0)
   1599		clear_bit(MT76_HW_SCANNING, &phy->state);
   1600
   1601	return err;
   1602}
   1603EXPORT_SYMBOL_GPL(mt76_connac_mcu_hw_scan);
   1604
   1605int mt76_connac_mcu_cancel_hw_scan(struct mt76_phy *phy,
   1606				   struct ieee80211_vif *vif)
   1607{
   1608	struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv;
   1609	struct {
   1610		u8 seq_num;
   1611		u8 is_ext_channel;
   1612		u8 rsv[2];
   1613	} __packed req = {
   1614		.seq_num = mvif->scan_seq_num,
   1615	};
   1616
   1617	if (test_and_clear_bit(MT76_HW_SCANNING, &phy->state)) {
   1618		struct cfg80211_scan_info info = {
   1619			.aborted = true,
   1620		};
   1621
   1622		ieee80211_scan_completed(phy->hw, &info);
   1623	}
   1624
   1625	return mt76_mcu_send_msg(phy->dev, MCU_CE_CMD(CANCEL_HW_SCAN),
   1626				 &req, sizeof(req), false);
   1627}
   1628EXPORT_SYMBOL_GPL(mt76_connac_mcu_cancel_hw_scan);
   1629
   1630int mt76_connac_mcu_sched_scan_req(struct mt76_phy *phy,
   1631				   struct ieee80211_vif *vif,
   1632				   struct cfg80211_sched_scan_request *sreq)
   1633{
   1634	struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv;
   1635	struct ieee80211_channel **scan_list = sreq->channels;
   1636	struct mt76_connac_mcu_scan_channel *chan;
   1637	struct mt76_connac_sched_scan_req *req;
   1638	struct mt76_dev *mdev = phy->dev;
   1639	struct cfg80211_match_set *match;
   1640	struct cfg80211_ssid *ssid;
   1641	struct sk_buff *skb;
   1642	int i;
   1643
   1644	skb = mt76_mcu_msg_alloc(mdev, NULL, sizeof(*req) + sreq->ie_len);
   1645	if (!skb)
   1646		return -ENOMEM;
   1647
   1648	mvif->scan_seq_num = (mvif->scan_seq_num + 1) & 0x7f;
   1649
   1650	req = (struct mt76_connac_sched_scan_req *)skb_put(skb, sizeof(*req));
   1651	req->version = 1;
   1652	req->seq_num = mvif->scan_seq_num | mvif->band_idx << 7;
   1653
   1654	if (sreq->flags & NL80211_SCAN_FLAG_RANDOM_ADDR) {
   1655		u8 *addr = is_mt7663(phy->dev) ? req->mt7663.random_mac
   1656					       : req->mt7921.random_mac;
   1657
   1658		req->scan_func = 1;
   1659		get_random_mask_addr(addr, sreq->mac_addr,
   1660				     sreq->mac_addr_mask);
   1661	}
   1662	if (is_mt7921(phy->dev)) {
   1663		req->mt7921.bss_idx = mvif->idx;
   1664		req->mt7921.delay = cpu_to_le32(sreq->delay);
   1665	}
   1666
   1667	req->ssids_num = sreq->n_ssids;
   1668	for (i = 0; i < req->ssids_num; i++) {
   1669		ssid = &sreq->ssids[i];
   1670		memcpy(req->ssids[i].ssid, ssid->ssid, ssid->ssid_len);
   1671		req->ssids[i].ssid_len = cpu_to_le32(ssid->ssid_len);
   1672	}
   1673
   1674	req->match_num = sreq->n_match_sets;
   1675	for (i = 0; i < req->match_num; i++) {
   1676		match = &sreq->match_sets[i];
   1677		memcpy(req->match[i].ssid, match->ssid.ssid,
   1678		       match->ssid.ssid_len);
   1679		req->match[i].rssi_th = cpu_to_le32(match->rssi_thold);
   1680		req->match[i].ssid_len = match->ssid.ssid_len;
   1681	}
   1682
   1683	req->channel_type = sreq->n_channels ? 4 : 0;
   1684	req->channels_num = min_t(u8, sreq->n_channels, 64);
   1685	for (i = 0; i < req->channels_num; i++) {
   1686		chan = &req->channels[i];
   1687
   1688		switch (scan_list[i]->band) {
   1689		case NL80211_BAND_2GHZ:
   1690			chan->band = 1;
   1691			break;
   1692		case NL80211_BAND_6GHZ:
   1693			chan->band = 3;
   1694			break;
   1695		default:
   1696			chan->band = 2;
   1697			break;
   1698		}
   1699		chan->channel_num = scan_list[i]->hw_value;
   1700	}
   1701
   1702	req->intervals_num = sreq->n_scan_plans;
   1703	for (i = 0; i < req->intervals_num; i++)
   1704		req->intervals[i] = cpu_to_le16(sreq->scan_plans[i].interval);
   1705
   1706	if (sreq->ie_len > 0) {
   1707		req->ie_len = cpu_to_le16(sreq->ie_len);
   1708		memcpy(skb_put(skb, sreq->ie_len), sreq->ie, sreq->ie_len);
   1709	}
   1710
   1711	return mt76_mcu_skb_send_msg(mdev, skb, MCU_CE_CMD(SCHED_SCAN_REQ),
   1712				     false);
   1713}
   1714EXPORT_SYMBOL_GPL(mt76_connac_mcu_sched_scan_req);
   1715
   1716int mt76_connac_mcu_sched_scan_enable(struct mt76_phy *phy,
   1717				      struct ieee80211_vif *vif,
   1718				      bool enable)
   1719{
   1720	struct {
   1721		u8 active; /* 0: enabled 1: disabled */
   1722		u8 rsv[3];
   1723	} __packed req = {
   1724		.active = !enable,
   1725	};
   1726
   1727	if (enable)
   1728		set_bit(MT76_HW_SCHED_SCANNING, &phy->state);
   1729	else
   1730		clear_bit(MT76_HW_SCHED_SCANNING, &phy->state);
   1731
   1732	return mt76_mcu_send_msg(phy->dev, MCU_CE_CMD(SCHED_SCAN_ENABLE),
   1733				 &req, sizeof(req), false);
   1734}
   1735EXPORT_SYMBOL_GPL(mt76_connac_mcu_sched_scan_enable);
   1736
   1737int mt76_connac_mcu_chip_config(struct mt76_dev *dev)
   1738{
   1739	struct mt76_connac_config req = {
   1740		.resp_type = 0,
   1741	};
   1742
   1743	memcpy(req.data, "assert", 7);
   1744
   1745	return mt76_mcu_send_msg(dev, MCU_CE_CMD(CHIP_CONFIG),
   1746				 &req, sizeof(req), false);
   1747}
   1748EXPORT_SYMBOL_GPL(mt76_connac_mcu_chip_config);
   1749
   1750int mt76_connac_mcu_set_deep_sleep(struct mt76_dev *dev, bool enable)
   1751{
   1752	struct mt76_connac_config req = {
   1753		.resp_type = 0,
   1754	};
   1755
   1756	snprintf(req.data, sizeof(req.data), "KeepFullPwr %d", !enable);
   1757
   1758	return mt76_mcu_send_msg(dev, MCU_CE_CMD(CHIP_CONFIG),
   1759				 &req, sizeof(req), false);
   1760}
   1761EXPORT_SYMBOL_GPL(mt76_connac_mcu_set_deep_sleep);
   1762
   1763int mt76_connac_sta_state_dp(struct mt76_dev *dev,
   1764			     enum ieee80211_sta_state old_state,
   1765			     enum ieee80211_sta_state new_state)
   1766{
   1767	if ((old_state == IEEE80211_STA_ASSOC &&
   1768	     new_state == IEEE80211_STA_AUTHORIZED) ||
   1769	    (old_state == IEEE80211_STA_NONE &&
   1770	     new_state == IEEE80211_STA_NOTEXIST))
   1771		mt76_connac_mcu_set_deep_sleep(dev, true);
   1772
   1773	if ((old_state == IEEE80211_STA_NOTEXIST &&
   1774	     new_state == IEEE80211_STA_NONE) ||
   1775	    (old_state == IEEE80211_STA_AUTHORIZED &&
   1776	     new_state == IEEE80211_STA_ASSOC))
   1777		mt76_connac_mcu_set_deep_sleep(dev, false);
   1778
   1779	return 0;
   1780}
   1781EXPORT_SYMBOL_GPL(mt76_connac_sta_state_dp);
   1782
   1783void mt76_connac_mcu_coredump_event(struct mt76_dev *dev, struct sk_buff *skb,
   1784				    struct mt76_connac_coredump *coredump)
   1785{
   1786	spin_lock_bh(&dev->lock);
   1787	__skb_queue_tail(&coredump->msg_list, skb);
   1788	spin_unlock_bh(&dev->lock);
   1789
   1790	coredump->last_activity = jiffies;
   1791
   1792	queue_delayed_work(dev->wq, &coredump->work,
   1793			   MT76_CONNAC_COREDUMP_TIMEOUT);
   1794}
   1795EXPORT_SYMBOL_GPL(mt76_connac_mcu_coredump_event);
   1796
   1797static void mt76_connac_mcu_parse_tx_resource(struct mt76_dev *dev,
   1798					      struct sk_buff *skb)
   1799{
   1800	struct mt76_sdio *sdio = &dev->sdio;
   1801	struct mt76_connac_tx_resource {
   1802		__le32 version;
   1803		__le32 pse_data_quota;
   1804		__le32 pse_mcu_quota;
   1805		__le32 ple_data_quota;
   1806		__le32 ple_mcu_quota;
   1807		__le16 pse_page_size;
   1808		__le16 ple_page_size;
   1809		u8 pp_padding;
   1810		u8 pad[3];
   1811	} __packed * tx_res;
   1812
   1813	tx_res = (struct mt76_connac_tx_resource *)skb->data;
   1814	sdio->sched.pse_data_quota = le32_to_cpu(tx_res->pse_data_quota);
   1815	sdio->sched.pse_mcu_quota = le32_to_cpu(tx_res->pse_mcu_quota);
   1816	sdio->sched.ple_data_quota = le32_to_cpu(tx_res->ple_data_quota);
   1817	sdio->sched.pse_page_size = le16_to_cpu(tx_res->pse_page_size);
   1818	sdio->sched.deficit = tx_res->pp_padding;
   1819}
   1820
   1821static void mt76_connac_mcu_parse_phy_cap(struct mt76_dev *dev,
   1822					  struct sk_buff *skb)
   1823{
   1824	struct mt76_connac_phy_cap {
   1825		u8 ht;
   1826		u8 vht;
   1827		u8 _5g;
   1828		u8 max_bw;
   1829		u8 nss;
   1830		u8 dbdc;
   1831		u8 tx_ldpc;
   1832		u8 rx_ldpc;
   1833		u8 tx_stbc;
   1834		u8 rx_stbc;
   1835		u8 hw_path;
   1836		u8 he;
   1837	} __packed * cap;
   1838
   1839	enum {
   1840		WF0_24G,
   1841		WF0_5G
   1842	};
   1843
   1844	cap = (struct mt76_connac_phy_cap *)skb->data;
   1845
   1846	dev->phy.antenna_mask = BIT(cap->nss) - 1;
   1847	dev->phy.chainmask = dev->phy.antenna_mask;
   1848	dev->phy.cap.has_2ghz = cap->hw_path & BIT(WF0_24G);
   1849	dev->phy.cap.has_5ghz = cap->hw_path & BIT(WF0_5G);
   1850}
   1851
   1852int mt76_connac_mcu_get_nic_capability(struct mt76_phy *phy)
   1853{
   1854	struct mt76_connac_cap_hdr {
   1855		__le16 n_element;
   1856		u8 rsv[2];
   1857	} __packed * hdr;
   1858	struct sk_buff *skb;
   1859	int ret, i;
   1860
   1861	ret = mt76_mcu_send_and_get_msg(phy->dev, MCU_CE_CMD(GET_NIC_CAPAB),
   1862					NULL, 0, true, &skb);
   1863	if (ret)
   1864		return ret;
   1865
   1866	hdr = (struct mt76_connac_cap_hdr *)skb->data;
   1867	if (skb->len < sizeof(*hdr)) {
   1868		ret = -EINVAL;
   1869		goto out;
   1870	}
   1871
   1872	skb_pull(skb, sizeof(*hdr));
   1873
   1874	for (i = 0; i < le16_to_cpu(hdr->n_element); i++) {
   1875		struct tlv_hdr {
   1876			__le32 type;
   1877			__le32 len;
   1878		} __packed * tlv = (struct tlv_hdr *)skb->data;
   1879		int len;
   1880
   1881		if (skb->len < sizeof(*tlv))
   1882			break;
   1883
   1884		skb_pull(skb, sizeof(*tlv));
   1885
   1886		len = le32_to_cpu(tlv->len);
   1887		if (skb->len < len)
   1888			break;
   1889
   1890		switch (le32_to_cpu(tlv->type)) {
   1891		case MT_NIC_CAP_6G:
   1892			phy->cap.has_6ghz = skb->data[0];
   1893			break;
   1894		case MT_NIC_CAP_MAC_ADDR:
   1895			memcpy(phy->macaddr, (void *)skb->data, ETH_ALEN);
   1896			break;
   1897		case MT_NIC_CAP_PHY:
   1898			mt76_connac_mcu_parse_phy_cap(phy->dev, skb);
   1899			break;
   1900		case MT_NIC_CAP_TX_RESOURCE:
   1901			if (mt76_is_sdio(phy->dev))
   1902				mt76_connac_mcu_parse_tx_resource(phy->dev,
   1903								  skb);
   1904			break;
   1905		default:
   1906			break;
   1907		}
   1908		skb_pull(skb, len);
   1909	}
   1910out:
   1911	dev_kfree_skb(skb);
   1912
   1913	return ret;
   1914}
   1915EXPORT_SYMBOL_GPL(mt76_connac_mcu_get_nic_capability);
   1916
   1917static void
   1918mt76_connac_mcu_build_sku(struct mt76_dev *dev, s8 *sku,
   1919			  struct mt76_power_limits *limits,
   1920			  enum nl80211_band band)
   1921{
   1922	int max_power = is_mt7921(dev) ? 127 : 63;
   1923	int i, offset = sizeof(limits->cck);
   1924
   1925	memset(sku, max_power, MT_SKU_POWER_LIMIT);
   1926
   1927	if (band == NL80211_BAND_2GHZ) {
   1928		/* cck */
   1929		memcpy(sku, limits->cck, sizeof(limits->cck));
   1930	}
   1931
   1932	/* ofdm */
   1933	memcpy(&sku[offset], limits->ofdm, sizeof(limits->ofdm));
   1934	offset += sizeof(limits->ofdm);
   1935
   1936	/* ht */
   1937	for (i = 0; i < 2; i++) {
   1938		memcpy(&sku[offset], limits->mcs[i], 8);
   1939		offset += 8;
   1940	}
   1941	sku[offset++] = limits->mcs[0][0];
   1942
   1943	/* vht */
   1944	for (i = 0; i < ARRAY_SIZE(limits->mcs); i++) {
   1945		memcpy(&sku[offset], limits->mcs[i],
   1946		       ARRAY_SIZE(limits->mcs[i]));
   1947		offset += 12;
   1948	}
   1949
   1950	if (!is_mt7921(dev))
   1951		return;
   1952
   1953	/* he */
   1954	for (i = 0; i < ARRAY_SIZE(limits->ru); i++) {
   1955		memcpy(&sku[offset], limits->ru[i], ARRAY_SIZE(limits->ru[i]));
   1956		offset += ARRAY_SIZE(limits->ru[i]);
   1957	}
   1958}
   1959
   1960static s8 mt76_connac_get_ch_power(struct mt76_phy *phy,
   1961				   struct ieee80211_channel *chan,
   1962				   s8 target_power)
   1963{
   1964	struct mt76_dev *dev = phy->dev;
   1965	struct ieee80211_supported_band *sband;
   1966	int i;
   1967
   1968	switch (chan->band) {
   1969	case NL80211_BAND_2GHZ:
   1970		sband = &phy->sband_2g.sband;
   1971		break;
   1972	case NL80211_BAND_5GHZ:
   1973		sband = &phy->sband_5g.sband;
   1974		break;
   1975	case NL80211_BAND_6GHZ:
   1976		sband = &phy->sband_6g.sband;
   1977		break;
   1978	default:
   1979		return target_power;
   1980	}
   1981
   1982	for (i = 0; i < sband->n_channels; i++) {
   1983		struct ieee80211_channel *ch = &sband->channels[i];
   1984
   1985		if (ch->hw_value == chan->hw_value) {
   1986			if (!(ch->flags & IEEE80211_CHAN_DISABLED)) {
   1987				int power = 2 * ch->max_reg_power;
   1988
   1989				if (is_mt7663(dev) && (power > 63 || power < -64))
   1990					power = 63;
   1991				target_power = min_t(s8, power, target_power);
   1992			}
   1993			break;
   1994		}
   1995	}
   1996
   1997	return target_power;
   1998}
   1999
   2000static int
   2001mt76_connac_mcu_rate_txpower_band(struct mt76_phy *phy,
   2002				  enum nl80211_band band)
   2003{
   2004	struct mt76_dev *dev = phy->dev;
   2005	int sku_len, batch_len = is_mt7921(dev) ? 8 : 16;
   2006	static const u8 chan_list_2ghz[] = {
   2007		1, 2,  3,  4,  5,  6,  7,
   2008		8, 9, 10, 11, 12, 13, 14
   2009	};
   2010	static const u8 chan_list_5ghz[] = {
   2011		 36,  38,  40,  42,  44,  46,  48,
   2012		 50,  52,  54,  56,  58,  60,  62,
   2013		 64, 100, 102, 104, 106, 108, 110,
   2014		112, 114, 116, 118, 120, 122, 124,
   2015		126, 128, 132, 134, 136, 138, 140,
   2016		142, 144, 149, 151, 153, 155, 157,
   2017		159, 161, 165
   2018	};
   2019	static const u8 chan_list_6ghz[] = {
   2020		  1,   3,   5,   7,   9,  11,  13,
   2021		 15,  17,  19,  21,  23,  25,  27,
   2022		 29,  33,  35,  37,  39,  41,  43,
   2023		 45,  47,  49,  51,  53,  55,  57,
   2024		 59,  61,  65,  67,  69,  71,  73,
   2025		 75,  77,  79,  81,  83,  85,  87,
   2026		 89,  91,  93,  97,  99, 101, 103,
   2027		105, 107, 109, 111, 113, 115, 117,
   2028		119, 121, 123, 125, 129, 131, 133,
   2029		135, 137, 139, 141, 143, 145, 147,
   2030		149, 151, 153, 155, 157, 161, 163,
   2031		165, 167, 169, 171, 173, 175, 177,
   2032		179, 181, 183, 185, 187, 189, 193,
   2033		195, 197, 199, 201, 203, 205, 207,
   2034		209, 211, 213, 215, 217, 219, 221,
   2035		225, 227, 229, 233
   2036	};
   2037	int i, n_chan, batch_size, idx = 0, tx_power, last_ch;
   2038	struct mt76_connac_sku_tlv sku_tlbv;
   2039	struct mt76_power_limits limits;
   2040	const u8 *ch_list;
   2041
   2042	sku_len = is_mt7921(dev) ? sizeof(sku_tlbv) : sizeof(sku_tlbv) - 92;
   2043	tx_power = 2 * phy->hw->conf.power_level;
   2044	if (!tx_power)
   2045		tx_power = 127;
   2046
   2047	if (band == NL80211_BAND_2GHZ) {
   2048		n_chan = ARRAY_SIZE(chan_list_2ghz);
   2049		ch_list = chan_list_2ghz;
   2050	} else if (band == NL80211_BAND_6GHZ) {
   2051		n_chan = ARRAY_SIZE(chan_list_6ghz);
   2052		ch_list = chan_list_6ghz;
   2053	} else {
   2054		n_chan = ARRAY_SIZE(chan_list_5ghz);
   2055		ch_list = chan_list_5ghz;
   2056	}
   2057	batch_size = DIV_ROUND_UP(n_chan, batch_len);
   2058
   2059	if (phy->cap.has_6ghz)
   2060		last_ch = chan_list_6ghz[ARRAY_SIZE(chan_list_6ghz) - 1];
   2061	else if (phy->cap.has_5ghz)
   2062		last_ch = chan_list_5ghz[ARRAY_SIZE(chan_list_5ghz) - 1];
   2063	else
   2064		last_ch = chan_list_2ghz[ARRAY_SIZE(chan_list_2ghz) - 1];
   2065
   2066	for (i = 0; i < batch_size; i++) {
   2067		struct mt76_connac_tx_power_limit_tlv tx_power_tlv = {};
   2068		int j, err, msg_len, num_ch;
   2069		struct sk_buff *skb;
   2070
   2071		num_ch = i == batch_size - 1 ? n_chan % batch_len : batch_len;
   2072		msg_len = sizeof(tx_power_tlv) + num_ch * sizeof(sku_tlbv);
   2073		skb = mt76_mcu_msg_alloc(dev, NULL, msg_len);
   2074		if (!skb)
   2075			return -ENOMEM;
   2076
   2077		skb_reserve(skb, sizeof(tx_power_tlv));
   2078
   2079		BUILD_BUG_ON(sizeof(dev->alpha2) > sizeof(tx_power_tlv.alpha2));
   2080		memcpy(tx_power_tlv.alpha2, dev->alpha2, sizeof(dev->alpha2));
   2081		tx_power_tlv.n_chan = num_ch;
   2082
   2083		switch (band) {
   2084		case NL80211_BAND_2GHZ:
   2085			tx_power_tlv.band = 1;
   2086			break;
   2087		case NL80211_BAND_6GHZ:
   2088			tx_power_tlv.band = 3;
   2089			break;
   2090		default:
   2091			tx_power_tlv.band = 2;
   2092			break;
   2093		}
   2094
   2095		for (j = 0; j < num_ch; j++, idx++) {
   2096			struct ieee80211_channel chan = {
   2097				.hw_value = ch_list[idx],
   2098				.band = band,
   2099			};
   2100			s8 reg_power, sar_power;
   2101
   2102			reg_power = mt76_connac_get_ch_power(phy, &chan,
   2103							     tx_power);
   2104			sar_power = mt76_get_sar_power(phy, &chan, reg_power);
   2105
   2106			mt76_get_rate_power_limits(phy, &chan, &limits,
   2107						   sar_power);
   2108
   2109			tx_power_tlv.last_msg = ch_list[idx] == last_ch;
   2110			sku_tlbv.channel = ch_list[idx];
   2111
   2112			mt76_connac_mcu_build_sku(dev, sku_tlbv.pwr_limit,
   2113						  &limits, band);
   2114			skb_put_data(skb, &sku_tlbv, sku_len);
   2115		}
   2116		__skb_push(skb, sizeof(tx_power_tlv));
   2117		memcpy(skb->data, &tx_power_tlv, sizeof(tx_power_tlv));
   2118
   2119		err = mt76_mcu_skb_send_msg(dev, skb,
   2120					    MCU_CE_CMD(SET_RATE_TX_POWER),
   2121					    false);
   2122		if (err < 0)
   2123			return err;
   2124	}
   2125
   2126	return 0;
   2127}
   2128
   2129int mt76_connac_mcu_set_rate_txpower(struct mt76_phy *phy)
   2130{
   2131	int err;
   2132
   2133	if (phy->cap.has_2ghz) {
   2134		err = mt76_connac_mcu_rate_txpower_band(phy,
   2135							NL80211_BAND_2GHZ);
   2136		if (err < 0)
   2137			return err;
   2138	}
   2139	if (phy->cap.has_5ghz) {
   2140		err = mt76_connac_mcu_rate_txpower_band(phy,
   2141							NL80211_BAND_5GHZ);
   2142		if (err < 0)
   2143			return err;
   2144	}
   2145	if (phy->cap.has_6ghz) {
   2146		err = mt76_connac_mcu_rate_txpower_band(phy,
   2147							NL80211_BAND_6GHZ);
   2148		if (err < 0)
   2149			return err;
   2150	}
   2151
   2152	return 0;
   2153}
   2154EXPORT_SYMBOL_GPL(mt76_connac_mcu_set_rate_txpower);
   2155
   2156int mt76_connac_mcu_update_arp_filter(struct mt76_dev *dev,
   2157				      struct mt76_vif *vif,
   2158				      struct ieee80211_bss_conf *info)
   2159{
   2160	struct sk_buff *skb;
   2161	int i, len = min_t(int, info->arp_addr_cnt,
   2162			   IEEE80211_BSS_ARP_ADDR_LIST_LEN);
   2163	struct {
   2164		struct {
   2165			u8 bss_idx;
   2166			u8 pad[3];
   2167		} __packed hdr;
   2168		struct mt76_connac_arpns_tlv arp;
   2169	} req_hdr = {
   2170		.hdr = {
   2171			.bss_idx = vif->idx,
   2172		},
   2173		.arp = {
   2174			.tag = cpu_to_le16(UNI_OFFLOAD_OFFLOAD_ARP),
   2175			.len = cpu_to_le16(sizeof(struct mt76_connac_arpns_tlv)),
   2176			.ips_num = len,
   2177			.mode = 2,  /* update */
   2178			.option = 1,
   2179		},
   2180	};
   2181
   2182	skb = mt76_mcu_msg_alloc(dev, NULL,
   2183				 sizeof(req_hdr) + len * sizeof(__be32));
   2184	if (!skb)
   2185		return -ENOMEM;
   2186
   2187	skb_put_data(skb, &req_hdr, sizeof(req_hdr));
   2188	for (i = 0; i < len; i++)
   2189		skb_put_data(skb, &info->arp_addr_list[i], sizeof(__be32));
   2190
   2191	return mt76_mcu_skb_send_msg(dev, skb, MCU_UNI_CMD(OFFLOAD), true);
   2192}
   2193EXPORT_SYMBOL_GPL(mt76_connac_mcu_update_arp_filter);
   2194
   2195int mt76_connac_mcu_set_p2p_oppps(struct ieee80211_hw *hw,
   2196				  struct ieee80211_vif *vif)
   2197{
   2198	struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv;
   2199	int ct_window = vif->bss_conf.p2p_noa_attr.oppps_ctwindow;
   2200	struct mt76_phy *phy = hw->priv;
   2201	struct {
   2202		__le32 ct_win;
   2203		u8 bss_idx;
   2204		u8 rsv[3];
   2205	} __packed req = {
   2206		.ct_win = cpu_to_le32(ct_window),
   2207		.bss_idx = mvif->idx,
   2208	};
   2209
   2210	return mt76_mcu_send_msg(phy->dev, MCU_CE_CMD(SET_P2P_OPPPS),
   2211				 &req, sizeof(req), false);
   2212}
   2213EXPORT_SYMBOL_GPL(mt76_connac_mcu_set_p2p_oppps);
   2214
   2215#ifdef CONFIG_PM
   2216
   2217const struct wiphy_wowlan_support mt76_connac_wowlan_support = {
   2218	.flags = WIPHY_WOWLAN_MAGIC_PKT | WIPHY_WOWLAN_DISCONNECT |
   2219		 WIPHY_WOWLAN_SUPPORTS_GTK_REKEY | WIPHY_WOWLAN_NET_DETECT,
   2220	.n_patterns = 1,
   2221	.pattern_min_len = 1,
   2222	.pattern_max_len = MT76_CONNAC_WOW_PATTEN_MAX_LEN,
   2223	.max_nd_match_sets = 10,
   2224};
   2225EXPORT_SYMBOL_GPL(mt76_connac_wowlan_support);
   2226
   2227static void
   2228mt76_connac_mcu_key_iter(struct ieee80211_hw *hw,
   2229			 struct ieee80211_vif *vif,
   2230			 struct ieee80211_sta *sta,
   2231			 struct ieee80211_key_conf *key,
   2232			 void *data)
   2233{
   2234	struct mt76_connac_gtk_rekey_tlv *gtk_tlv = data;
   2235	u32 cipher;
   2236
   2237	if (key->cipher != WLAN_CIPHER_SUITE_AES_CMAC &&
   2238	    key->cipher != WLAN_CIPHER_SUITE_CCMP &&
   2239	    key->cipher != WLAN_CIPHER_SUITE_TKIP)
   2240		return;
   2241
   2242	if (key->cipher == WLAN_CIPHER_SUITE_TKIP)
   2243		cipher = BIT(3);
   2244	else
   2245		cipher = BIT(4);
   2246
   2247	/* we are assuming here to have a single pairwise key */
   2248	if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) {
   2249		if (key->cipher == WLAN_CIPHER_SUITE_TKIP)
   2250			gtk_tlv->proto = cpu_to_le32(NL80211_WPA_VERSION_1);
   2251		else
   2252			gtk_tlv->proto = cpu_to_le32(NL80211_WPA_VERSION_2);
   2253
   2254		gtk_tlv->pairwise_cipher = cpu_to_le32(cipher);
   2255		gtk_tlv->keyid = key->keyidx;
   2256	} else {
   2257		gtk_tlv->group_cipher = cpu_to_le32(cipher);
   2258	}
   2259}
   2260
   2261int mt76_connac_mcu_update_gtk_rekey(struct ieee80211_hw *hw,
   2262				     struct ieee80211_vif *vif,
   2263				     struct cfg80211_gtk_rekey_data *key)
   2264{
   2265	struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv;
   2266	struct mt76_connac_gtk_rekey_tlv *gtk_tlv;
   2267	struct mt76_phy *phy = hw->priv;
   2268	struct sk_buff *skb;
   2269	struct {
   2270		u8 bss_idx;
   2271		u8 pad[3];
   2272	} __packed hdr = {
   2273		.bss_idx = mvif->idx,
   2274	};
   2275
   2276	skb = mt76_mcu_msg_alloc(phy->dev, NULL,
   2277				 sizeof(hdr) + sizeof(*gtk_tlv));
   2278	if (!skb)
   2279		return -ENOMEM;
   2280
   2281	skb_put_data(skb, &hdr, sizeof(hdr));
   2282	gtk_tlv = (struct mt76_connac_gtk_rekey_tlv *)skb_put(skb,
   2283							 sizeof(*gtk_tlv));
   2284	gtk_tlv->tag = cpu_to_le16(UNI_OFFLOAD_OFFLOAD_GTK_REKEY);
   2285	gtk_tlv->len = cpu_to_le16(sizeof(*gtk_tlv));
   2286	gtk_tlv->rekey_mode = 2;
   2287	gtk_tlv->option = 1;
   2288
   2289	rcu_read_lock();
   2290	ieee80211_iter_keys_rcu(hw, vif, mt76_connac_mcu_key_iter, gtk_tlv);
   2291	rcu_read_unlock();
   2292
   2293	memcpy(gtk_tlv->kek, key->kek, NL80211_KEK_LEN);
   2294	memcpy(gtk_tlv->kck, key->kck, NL80211_KCK_LEN);
   2295	memcpy(gtk_tlv->replay_ctr, key->replay_ctr, NL80211_REPLAY_CTR_LEN);
   2296
   2297	return mt76_mcu_skb_send_msg(phy->dev, skb,
   2298				     MCU_UNI_CMD(OFFLOAD), true);
   2299}
   2300EXPORT_SYMBOL_GPL(mt76_connac_mcu_update_gtk_rekey);
   2301
   2302static int
   2303mt76_connac_mcu_set_arp_filter(struct mt76_dev *dev, struct ieee80211_vif *vif,
   2304			       bool suspend)
   2305{
   2306	struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv;
   2307	struct {
   2308		struct {
   2309			u8 bss_idx;
   2310			u8 pad[3];
   2311		} __packed hdr;
   2312		struct mt76_connac_arpns_tlv arpns;
   2313	} req = {
   2314		.hdr = {
   2315			.bss_idx = mvif->idx,
   2316		},
   2317		.arpns = {
   2318			.tag = cpu_to_le16(UNI_OFFLOAD_OFFLOAD_ARP),
   2319			.len = cpu_to_le16(sizeof(struct mt76_connac_arpns_tlv)),
   2320			.mode = suspend,
   2321		},
   2322	};
   2323
   2324	return mt76_mcu_send_msg(dev, MCU_UNI_CMD(OFFLOAD), &req,
   2325				 sizeof(req), true);
   2326}
   2327
   2328static int
   2329mt76_connac_mcu_set_gtk_rekey(struct mt76_dev *dev, struct ieee80211_vif *vif,
   2330			      bool suspend)
   2331{
   2332	struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv;
   2333	struct {
   2334		struct {
   2335			u8 bss_idx;
   2336			u8 pad[3];
   2337		} __packed hdr;
   2338		struct mt76_connac_gtk_rekey_tlv gtk_tlv;
   2339	} __packed req = {
   2340		.hdr = {
   2341			.bss_idx = mvif->idx,
   2342		},
   2343		.gtk_tlv = {
   2344			.tag = cpu_to_le16(UNI_OFFLOAD_OFFLOAD_GTK_REKEY),
   2345			.len = cpu_to_le16(sizeof(struct mt76_connac_gtk_rekey_tlv)),
   2346			.rekey_mode = !suspend,
   2347		},
   2348	};
   2349
   2350	return mt76_mcu_send_msg(dev, MCU_UNI_CMD(OFFLOAD), &req,
   2351				 sizeof(req), true);
   2352}
   2353
   2354static int
   2355mt76_connac_mcu_set_suspend_mode(struct mt76_dev *dev,
   2356				 struct ieee80211_vif *vif,
   2357				 bool enable, u8 mdtim,
   2358				 bool wow_suspend)
   2359{
   2360	struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv;
   2361	struct {
   2362		struct {
   2363			u8 bss_idx;
   2364			u8 pad[3];
   2365		} __packed hdr;
   2366		struct mt76_connac_suspend_tlv suspend_tlv;
   2367	} req = {
   2368		.hdr = {
   2369			.bss_idx = mvif->idx,
   2370		},
   2371		.suspend_tlv = {
   2372			.tag = cpu_to_le16(UNI_SUSPEND_MODE_SETTING),
   2373			.len = cpu_to_le16(sizeof(struct mt76_connac_suspend_tlv)),
   2374			.enable = enable,
   2375			.mdtim = mdtim,
   2376			.wow_suspend = wow_suspend,
   2377		},
   2378	};
   2379
   2380	return mt76_mcu_send_msg(dev, MCU_UNI_CMD(SUSPEND), &req,
   2381				 sizeof(req), true);
   2382}
   2383
   2384static int
   2385mt76_connac_mcu_set_wow_pattern(struct mt76_dev *dev,
   2386				struct ieee80211_vif *vif,
   2387				u8 index, bool enable,
   2388				struct cfg80211_pkt_pattern *pattern)
   2389{
   2390	struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv;
   2391	struct mt76_connac_wow_pattern_tlv *ptlv;
   2392	struct sk_buff *skb;
   2393	struct req_hdr {
   2394		u8 bss_idx;
   2395		u8 pad[3];
   2396	} __packed hdr = {
   2397		.bss_idx = mvif->idx,
   2398	};
   2399
   2400	skb = mt76_mcu_msg_alloc(dev, NULL, sizeof(hdr) + sizeof(*ptlv));
   2401	if (!skb)
   2402		return -ENOMEM;
   2403
   2404	skb_put_data(skb, &hdr, sizeof(hdr));
   2405	ptlv = (struct mt76_connac_wow_pattern_tlv *)skb_put(skb, sizeof(*ptlv));
   2406	ptlv->tag = cpu_to_le16(UNI_SUSPEND_WOW_PATTERN);
   2407	ptlv->len = cpu_to_le16(sizeof(*ptlv));
   2408	ptlv->data_len = pattern->pattern_len;
   2409	ptlv->enable = enable;
   2410	ptlv->index = index;
   2411
   2412	memcpy(ptlv->pattern, pattern->pattern, pattern->pattern_len);
   2413	memcpy(ptlv->mask, pattern->mask, DIV_ROUND_UP(pattern->pattern_len, 8));
   2414
   2415	return mt76_mcu_skb_send_msg(dev, skb, MCU_UNI_CMD(SUSPEND), true);
   2416}
   2417
   2418static int
   2419mt76_connac_mcu_set_wow_ctrl(struct mt76_phy *phy, struct ieee80211_vif *vif,
   2420			     bool suspend, struct cfg80211_wowlan *wowlan)
   2421{
   2422	struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv;
   2423	struct mt76_dev *dev = phy->dev;
   2424	struct {
   2425		struct {
   2426			u8 bss_idx;
   2427			u8 pad[3];
   2428		} __packed hdr;
   2429		struct mt76_connac_wow_ctrl_tlv wow_ctrl_tlv;
   2430		struct mt76_connac_wow_gpio_param_tlv gpio_tlv;
   2431	} req = {
   2432		.hdr = {
   2433			.bss_idx = mvif->idx,
   2434		},
   2435		.wow_ctrl_tlv = {
   2436			.tag = cpu_to_le16(UNI_SUSPEND_WOW_CTRL),
   2437			.len = cpu_to_le16(sizeof(struct mt76_connac_wow_ctrl_tlv)),
   2438			.cmd = suspend ? 1 : 2,
   2439		},
   2440		.gpio_tlv = {
   2441			.tag = cpu_to_le16(UNI_SUSPEND_WOW_GPIO_PARAM),
   2442			.len = cpu_to_le16(sizeof(struct mt76_connac_wow_gpio_param_tlv)),
   2443			.gpio_pin = 0xff, /* follow fw about GPIO pin */
   2444		},
   2445	};
   2446
   2447	if (wowlan->magic_pkt)
   2448		req.wow_ctrl_tlv.trigger |= UNI_WOW_DETECT_TYPE_MAGIC;
   2449	if (wowlan->disconnect)
   2450		req.wow_ctrl_tlv.trigger |= (UNI_WOW_DETECT_TYPE_DISCONNECT |
   2451					     UNI_WOW_DETECT_TYPE_BCN_LOST);
   2452	if (wowlan->nd_config) {
   2453		mt76_connac_mcu_sched_scan_req(phy, vif, wowlan->nd_config);
   2454		req.wow_ctrl_tlv.trigger |= UNI_WOW_DETECT_TYPE_SCH_SCAN_HIT;
   2455		mt76_connac_mcu_sched_scan_enable(phy, vif, suspend);
   2456	}
   2457	if (wowlan->n_patterns)
   2458		req.wow_ctrl_tlv.trigger |= UNI_WOW_DETECT_TYPE_BITMAP;
   2459
   2460	if (mt76_is_mmio(dev))
   2461		req.wow_ctrl_tlv.wakeup_hif = WOW_PCIE;
   2462	else if (mt76_is_usb(dev))
   2463		req.wow_ctrl_tlv.wakeup_hif = WOW_USB;
   2464	else if (mt76_is_sdio(dev))
   2465		req.wow_ctrl_tlv.wakeup_hif = WOW_GPIO;
   2466
   2467	return mt76_mcu_send_msg(dev, MCU_UNI_CMD(SUSPEND), &req,
   2468				 sizeof(req), true);
   2469}
   2470
   2471int mt76_connac_mcu_set_hif_suspend(struct mt76_dev *dev, bool suspend)
   2472{
   2473	struct {
   2474		struct {
   2475			u8 hif_type; /* 0x0: HIF_SDIO
   2476				      * 0x1: HIF_USB
   2477				      * 0x2: HIF_PCIE
   2478				      */
   2479			u8 pad[3];
   2480		} __packed hdr;
   2481		struct hif_suspend_tlv {
   2482			__le16 tag;
   2483			__le16 len;
   2484			u8 suspend;
   2485		} __packed hif_suspend;
   2486	} req = {
   2487		.hif_suspend = {
   2488			.tag = cpu_to_le16(0), /* 0: UNI_HIF_CTRL_BASIC */
   2489			.len = cpu_to_le16(sizeof(struct hif_suspend_tlv)),
   2490			.suspend = suspend,
   2491		},
   2492	};
   2493
   2494	if (mt76_is_mmio(dev))
   2495		req.hdr.hif_type = 2;
   2496	else if (mt76_is_usb(dev))
   2497		req.hdr.hif_type = 1;
   2498	else if (mt76_is_sdio(dev))
   2499		req.hdr.hif_type = 0;
   2500
   2501	return mt76_mcu_send_msg(dev, MCU_UNI_CMD(HIF_CTRL), &req,
   2502				 sizeof(req), true);
   2503}
   2504EXPORT_SYMBOL_GPL(mt76_connac_mcu_set_hif_suspend);
   2505
   2506void mt76_connac_mcu_set_suspend_iter(void *priv, u8 *mac,
   2507				      struct ieee80211_vif *vif)
   2508{
   2509	struct mt76_phy *phy = priv;
   2510	bool suspend = !test_bit(MT76_STATE_RUNNING, &phy->state);
   2511	struct ieee80211_hw *hw = phy->hw;
   2512	struct cfg80211_wowlan *wowlan = hw->wiphy->wowlan_config;
   2513	int i;
   2514
   2515	mt76_connac_mcu_set_gtk_rekey(phy->dev, vif, suspend);
   2516	mt76_connac_mcu_set_arp_filter(phy->dev, vif, suspend);
   2517
   2518	mt76_connac_mcu_set_suspend_mode(phy->dev, vif, suspend, 1, true);
   2519
   2520	for (i = 0; i < wowlan->n_patterns; i++)
   2521		mt76_connac_mcu_set_wow_pattern(phy->dev, vif, i, suspend,
   2522						&wowlan->patterns[i]);
   2523	mt76_connac_mcu_set_wow_ctrl(phy, vif, suspend, wowlan);
   2524}
   2525EXPORT_SYMBOL_GPL(mt76_connac_mcu_set_suspend_iter);
   2526#endif /* CONFIG_PM */
   2527
   2528u32 mt76_connac_mcu_reg_rr(struct mt76_dev *dev, u32 offset)
   2529{
   2530	struct {
   2531		__le32 addr;
   2532		__le32 val;
   2533	} __packed req = {
   2534		.addr = cpu_to_le32(offset),
   2535	};
   2536
   2537	return mt76_mcu_send_msg(dev, MCU_CE_QUERY(REG_READ), &req,
   2538				 sizeof(req), true);
   2539}
   2540EXPORT_SYMBOL_GPL(mt76_connac_mcu_reg_rr);
   2541
   2542void mt76_connac_mcu_reg_wr(struct mt76_dev *dev, u32 offset, u32 val)
   2543{
   2544	struct {
   2545		__le32 addr;
   2546		__le32 val;
   2547	} __packed req = {
   2548		.addr = cpu_to_le32(offset),
   2549		.val = cpu_to_le32(val),
   2550	};
   2551
   2552	mt76_mcu_send_msg(dev, MCU_CE_CMD(REG_WRITE), &req,
   2553			  sizeof(req), false);
   2554}
   2555EXPORT_SYMBOL_GPL(mt76_connac_mcu_reg_wr);
   2556
   2557static int
   2558mt76_connac_mcu_sta_key_tlv(struct mt76_connac_sta_key_conf *sta_key_conf,
   2559			    struct sk_buff *skb,
   2560			    struct ieee80211_key_conf *key,
   2561			    enum set_key_cmd cmd)
   2562{
   2563	struct sta_rec_sec *sec;
   2564	u32 len = sizeof(*sec);
   2565	struct tlv *tlv;
   2566
   2567	tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_KEY_V2, sizeof(*sec));
   2568	sec = (struct sta_rec_sec *)tlv;
   2569	sec->add = cmd;
   2570
   2571	if (cmd == SET_KEY) {
   2572		struct sec_key *sec_key;
   2573		u8 cipher;
   2574
   2575		cipher = mt76_connac_mcu_get_cipher(key->cipher);
   2576		if (cipher == MCU_CIPHER_NONE)
   2577			return -EOPNOTSUPP;
   2578
   2579		sec_key = &sec->key[0];
   2580		sec_key->cipher_len = sizeof(*sec_key);
   2581
   2582		if (cipher == MCU_CIPHER_BIP_CMAC_128) {
   2583			sec_key->cipher_id = MCU_CIPHER_AES_CCMP;
   2584			sec_key->key_id = sta_key_conf->keyidx;
   2585			sec_key->key_len = 16;
   2586			memcpy(sec_key->key, sta_key_conf->key, 16);
   2587
   2588			sec_key = &sec->key[1];
   2589			sec_key->cipher_id = MCU_CIPHER_BIP_CMAC_128;
   2590			sec_key->cipher_len = sizeof(*sec_key);
   2591			sec_key->key_len = 16;
   2592			memcpy(sec_key->key, key->key, 16);
   2593			sec->n_cipher = 2;
   2594		} else {
   2595			sec_key->cipher_id = cipher;
   2596			sec_key->key_id = key->keyidx;
   2597			sec_key->key_len = key->keylen;
   2598			memcpy(sec_key->key, key->key, key->keylen);
   2599
   2600			if (cipher == MCU_CIPHER_TKIP) {
   2601				/* Rx/Tx MIC keys are swapped */
   2602				memcpy(sec_key->key + 16, key->key + 24, 8);
   2603				memcpy(sec_key->key + 24, key->key + 16, 8);
   2604			}
   2605
   2606			/* store key_conf for BIP batch update */
   2607			if (cipher == MCU_CIPHER_AES_CCMP) {
   2608				memcpy(sta_key_conf->key, key->key, key->keylen);
   2609				sta_key_conf->keyidx = key->keyidx;
   2610			}
   2611
   2612			len -= sizeof(*sec_key);
   2613			sec->n_cipher = 1;
   2614		}
   2615	} else {
   2616		len -= sizeof(sec->key);
   2617		sec->n_cipher = 0;
   2618	}
   2619	sec->len = cpu_to_le16(len);
   2620
   2621	return 0;
   2622}
   2623
   2624int mt76_connac_mcu_add_key(struct mt76_dev *dev, struct ieee80211_vif *vif,
   2625			    struct mt76_connac_sta_key_conf *sta_key_conf,
   2626			    struct ieee80211_key_conf *key, int mcu_cmd,
   2627			    struct mt76_wcid *wcid, enum set_key_cmd cmd)
   2628{
   2629	struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv;
   2630	struct sk_buff *skb;
   2631	int ret;
   2632
   2633	skb = mt76_connac_mcu_alloc_sta_req(dev, mvif, wcid);
   2634	if (IS_ERR(skb))
   2635		return PTR_ERR(skb);
   2636
   2637	ret = mt76_connac_mcu_sta_key_tlv(sta_key_conf, skb, key, cmd);
   2638	if (ret)
   2639		return ret;
   2640
   2641	return mt76_mcu_skb_send_msg(dev, skb, mcu_cmd, true);
   2642}
   2643EXPORT_SYMBOL_GPL(mt76_connac_mcu_add_key);
   2644
   2645/* SIFS 20us + 512 byte beacon tranmitted by 1Mbps (3906us) */
   2646#define BCN_TX_ESTIMATE_TIME (4096 + 20)
   2647void mt76_connac_mcu_bss_ext_tlv(struct sk_buff *skb, struct mt76_vif *mvif)
   2648{
   2649	struct bss_info_ext_bss *ext;
   2650	int ext_bss_idx, tsf_offset;
   2651	struct tlv *tlv;
   2652
   2653	ext_bss_idx = mvif->omac_idx - EXT_BSSID_START;
   2654	if (ext_bss_idx < 0)
   2655		return;
   2656
   2657	tlv = mt76_connac_mcu_add_tlv(skb, BSS_INFO_EXT_BSS, sizeof(*ext));
   2658
   2659	ext = (struct bss_info_ext_bss *)tlv;
   2660	tsf_offset = ext_bss_idx * BCN_TX_ESTIMATE_TIME;
   2661	ext->mbss_tsf_offset = cpu_to_le32(tsf_offset);
   2662}
   2663EXPORT_SYMBOL_GPL(mt76_connac_mcu_bss_ext_tlv);
   2664
   2665int mt76_connac_mcu_bss_basic_tlv(struct sk_buff *skb,
   2666				  struct ieee80211_vif *vif,
   2667				  struct ieee80211_sta *sta,
   2668				  struct mt76_phy *phy, u16 wlan_idx,
   2669				  bool enable)
   2670{
   2671	struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv;
   2672	u32 type = vif->p2p ? NETWORK_P2P : NETWORK_INFRA;
   2673	struct bss_info_basic *bss;
   2674	struct tlv *tlv;
   2675
   2676	tlv = mt76_connac_mcu_add_tlv(skb, BSS_INFO_BASIC, sizeof(*bss));
   2677	bss = (struct bss_info_basic *)tlv;
   2678
   2679	switch (vif->type) {
   2680	case NL80211_IFTYPE_MESH_POINT:
   2681	case NL80211_IFTYPE_MONITOR:
   2682		break;
   2683	case NL80211_IFTYPE_AP:
   2684		if (ieee80211_hw_check(phy->hw, SUPPORTS_MULTI_BSSID)) {
   2685			u8 bssid_id = vif->bss_conf.bssid_indicator;
   2686			struct wiphy *wiphy = phy->hw->wiphy;
   2687
   2688			if (bssid_id > ilog2(wiphy->mbssid_max_interfaces))
   2689				return -EINVAL;
   2690
   2691			bss->non_tx_bssid = vif->bss_conf.bssid_index;
   2692			bss->max_bssid = bssid_id;
   2693		}
   2694		break;
   2695	case NL80211_IFTYPE_STATION:
   2696		if (enable) {
   2697			rcu_read_lock();
   2698			if (!sta)
   2699				sta = ieee80211_find_sta(vif,
   2700							 vif->bss_conf.bssid);
   2701			/* TODO: enable BSS_INFO_UAPSD & BSS_INFO_PM */
   2702			if (sta) {
   2703				struct mt76_wcid *wcid;
   2704
   2705				wcid = (struct mt76_wcid *)sta->drv_priv;
   2706				wlan_idx = wcid->idx;
   2707			}
   2708			rcu_read_unlock();
   2709		}
   2710		break;
   2711	case NL80211_IFTYPE_ADHOC:
   2712		type = NETWORK_IBSS;
   2713		break;
   2714	default:
   2715		WARN_ON(1);
   2716		break;
   2717	}
   2718
   2719	bss->network_type = cpu_to_le32(type);
   2720	bss->bmc_wcid_lo = to_wcid_lo(wlan_idx);
   2721	bss->bmc_wcid_hi = to_wcid_hi(wlan_idx);
   2722	bss->wmm_idx = mvif->wmm_idx;
   2723	bss->active = enable;
   2724	bss->cipher = mvif->cipher;
   2725
   2726	if (vif->type != NL80211_IFTYPE_MONITOR) {
   2727		struct cfg80211_chan_def *chandef = &phy->chandef;
   2728
   2729		memcpy(bss->bssid, vif->bss_conf.bssid, ETH_ALEN);
   2730		bss->bcn_interval = cpu_to_le16(vif->bss_conf.beacon_int);
   2731		bss->dtim_period = vif->bss_conf.dtim_period;
   2732		bss->phy_mode = mt76_connac_get_phy_mode(phy, vif,
   2733							 chandef->chan->band, NULL);
   2734	} else {
   2735		memcpy(bss->bssid, phy->macaddr, ETH_ALEN);
   2736	}
   2737
   2738	return 0;
   2739}
   2740EXPORT_SYMBOL_GPL(mt76_connac_mcu_bss_basic_tlv);
   2741
   2742#define ENTER_PM_STATE		1
   2743#define EXIT_PM_STATE		2
   2744int mt76_connac_mcu_set_pm(struct mt76_dev *dev, int band, int enter)
   2745{
   2746	struct {
   2747		u8 pm_number;
   2748		u8 pm_state;
   2749		u8 bssid[ETH_ALEN];
   2750		u8 dtim_period;
   2751		u8 wlan_idx_lo;
   2752		__le16 bcn_interval;
   2753		__le32 aid;
   2754		__le32 rx_filter;
   2755		u8 band_idx;
   2756		u8 wlan_idx_hi;
   2757		u8 rsv[2];
   2758		__le32 feature;
   2759		u8 omac_idx;
   2760		u8 wmm_idx;
   2761		u8 bcn_loss_cnt;
   2762		u8 bcn_sp_duration;
   2763	} __packed req = {
   2764		.pm_number = 5,
   2765		.pm_state = enter ? ENTER_PM_STATE : EXIT_PM_STATE,
   2766		.band_idx = band,
   2767	};
   2768
   2769	return mt76_mcu_send_msg(dev, MCU_EXT_CMD(PM_STATE_CTRL), &req,
   2770				 sizeof(req), true);
   2771}
   2772EXPORT_SYMBOL_GPL(mt76_connac_mcu_set_pm);
   2773
   2774int mt76_connac_mcu_restart(struct mt76_dev *dev)
   2775{
   2776	struct {
   2777		u8 power_mode;
   2778		u8 rsv[3];
   2779	} req = {
   2780		.power_mode = 1,
   2781	};
   2782
   2783	return mt76_mcu_send_msg(dev, MCU_CMD(NIC_POWER_CTRL), &req,
   2784				 sizeof(req), false);
   2785}
   2786EXPORT_SYMBOL_GPL(mt76_connac_mcu_restart);
   2787
   2788int mt76_connac_mcu_rdd_cmd(struct mt76_dev *dev, int cmd, u8 index,
   2789			    u8 rx_sel, u8 val)
   2790{
   2791	struct {
   2792		u8 ctrl;
   2793		u8 rdd_idx;
   2794		u8 rdd_rx_sel;
   2795		u8 val;
   2796		u8 rsv[4];
   2797	} __packed req = {
   2798		.ctrl = cmd,
   2799		.rdd_idx = index,
   2800		.rdd_rx_sel = rx_sel,
   2801		.val = val,
   2802	};
   2803
   2804	return mt76_mcu_send_msg(dev, MCU_EXT_CMD(SET_RDD_CTRL), &req,
   2805				 sizeof(req), true);
   2806}
   2807EXPORT_SYMBOL_GPL(mt76_connac_mcu_rdd_cmd);
   2808
   2809MODULE_AUTHOR("Lorenzo Bianconi <lorenzo@kernel.org>");
   2810MODULE_LICENSE("Dual BSD/GPL");