blob: 00acb096dff030fcb1866df6ff1d51cd931c71bc [file] [log] [blame]
developerb11a5392022-03-31 00:34:47 +08001// SPDX-License-Identifier: ISC
2/* Copyright (C) 2020 MediaTek Inc. */
3
4#include <linux/firmware.h>
5#include <linux/fs.h>
developer7800b8d2022-06-23 22:15:56 +08006#include "besra.h"
developerb11a5392022-03-31 00:34:47 +08007#include "mcu.h"
8#include "mac.h"
9#include "eeprom.h"
10
developer7800b8d2022-06-23 22:15:56 +080011struct besra_patch_hdr {
developerb11a5392022-03-31 00:34:47 +080012 char build_date[16];
13 char platform[4];
14 __be32 hw_sw_ver;
15 __be32 patch_ver;
16 __be16 checksum;
17 u16 reserved;
18 struct {
19 __be32 patch_ver;
20 __be32 subsys;
21 __be32 feature;
22 __be32 n_region;
23 __be32 crc;
24 u32 reserved[11];
25 } desc;
26} __packed;
27
developer7800b8d2022-06-23 22:15:56 +080028struct besra_patch_sec {
developerb11a5392022-03-31 00:34:47 +080029 __be32 type;
30 __be32 offs;
31 __be32 size;
32 union {
33 __be32 spec[13];
34 struct {
35 __be32 addr;
36 __be32 len;
37 __be32 sec_key_idx;
38 __be32 align_len;
39 u32 reserved[9];
40 } info;
41 };
42} __packed;
43
developer7800b8d2022-06-23 22:15:56 +080044struct besra_fw_trailer {
developerb11a5392022-03-31 00:34:47 +080045 u8 chip_id;
46 u8 eco_code;
47 u8 n_region;
48 u8 format_ver;
49 u8 format_flag;
50 u8 reserved[2];
51 char fw_ver[10];
52 char build_date[15];
53 u32 crc;
54} __packed;
55
developer7800b8d2022-06-23 22:15:56 +080056struct besra_fw_region {
developerb11a5392022-03-31 00:34:47 +080057 __le32 decomp_crc;
58 __le32 decomp_len;
59 __le32 decomp_blk_sz;
60 u8 reserved[4];
61 __le32 addr;
62 __le32 len;
63 u8 feature_set;
64 u8 reserved1[15];
65} __packed;
66
67#define MCU_PATCH_ADDRESS 0x200000
68
69#define HE_PHY(p, c) u8_get_bits(c, IEEE80211_HE_PHY_##p)
70#define HE_MAC(m, c) u8_get_bits(c, IEEE80211_HE_MAC_##m)
71
72static u8
developer7800b8d2022-06-23 22:15:56 +080073besra_mcu_get_sta_nss(u16 mcs_map)
developerb11a5392022-03-31 00:34:47 +080074{
75 u8 nss;
76
77 for (nss = 8; nss > 0; nss--) {
78 u8 nss_mcs = (mcs_map >> (2 * (nss - 1))) & 3;
79
80 if (nss_mcs != IEEE80211_VHT_MCS_NOT_SUPPORTED)
81 break;
82 }
83
84 return nss - 1;
85}
86
87static void
developer7800b8d2022-06-23 22:15:56 +080088besra_mcu_set_sta_he_mcs(struct ieee80211_sta *sta, __le16 *he_mcs,
developerb11a5392022-03-31 00:34:47 +080089 u16 mcs_map)
90{
developer7800b8d2022-06-23 22:15:56 +080091 struct besra_sta *msta = (struct besra_sta *)sta->drv_priv;
developerb11a5392022-03-31 00:34:47 +080092 enum nl80211_band band = msta->vif->phy->mt76->chandef.chan->band;
93 const u16 *mask = msta->vif->bitrate_mask.control[band].he_mcs;
94 int nss, max_nss = sta->rx_nss > 3 ? 4 : sta->rx_nss;
95
96 for (nss = 0; nss < max_nss; nss++) {
97 int mcs;
98
99 switch ((mcs_map >> (2 * nss)) & 0x3) {
100 case IEEE80211_HE_MCS_SUPPORT_0_11:
101 mcs = GENMASK(11, 0);
102 break;
103 case IEEE80211_HE_MCS_SUPPORT_0_9:
104 mcs = GENMASK(9, 0);
105 break;
106 case IEEE80211_HE_MCS_SUPPORT_0_7:
107 mcs = GENMASK(7, 0);
108 break;
109 default:
110 mcs = 0;
111 }
112
113 mcs = mcs ? fls(mcs & mask[nss]) - 1 : -1;
114
115 switch (mcs) {
116 case 0 ... 7:
117 mcs = IEEE80211_HE_MCS_SUPPORT_0_7;
118 break;
119 case 8 ... 9:
120 mcs = IEEE80211_HE_MCS_SUPPORT_0_9;
121 break;
122 case 10 ... 11:
123 mcs = IEEE80211_HE_MCS_SUPPORT_0_11;
124 break;
125 default:
126 mcs = IEEE80211_HE_MCS_NOT_SUPPORTED;
127 break;
128 }
129 mcs_map &= ~(0x3 << (nss * 2));
130 mcs_map |= mcs << (nss * 2);
131 }
132
133 *he_mcs = cpu_to_le16(mcs_map);
134}
135
136static void
developer7800b8d2022-06-23 22:15:56 +0800137besra_mcu_set_sta_vht_mcs(struct ieee80211_sta *sta, __le16 *vht_mcs,
developerb11a5392022-03-31 00:34:47 +0800138 const u16 *mask)
139{
140 u16 mcs_map = le16_to_cpu(sta->vht_cap.vht_mcs.rx_mcs_map);
141 int nss, max_nss = sta->rx_nss > 3 ? 4 : sta->rx_nss;
142 u16 mcs;
143
144 for (nss = 0; nss < max_nss; nss++, mcs_map >>= 2) {
145 switch (mcs_map & 0x3) {
146 case IEEE80211_VHT_MCS_SUPPORT_0_9:
147 mcs = GENMASK(9, 0);
148 break;
149 case IEEE80211_VHT_MCS_SUPPORT_0_8:
150 mcs = GENMASK(8, 0);
151 break;
152 case IEEE80211_VHT_MCS_SUPPORT_0_7:
153 mcs = GENMASK(7, 0);
154 break;
155 default:
156 mcs = 0;
157 }
158
159 vht_mcs[nss] = cpu_to_le16(mcs & mask[nss]);
160 }
161}
162
163static void
developer7800b8d2022-06-23 22:15:56 +0800164besra_mcu_set_sta_ht_mcs(struct ieee80211_sta *sta, u8 *ht_mcs,
developerb11a5392022-03-31 00:34:47 +0800165 const u8 *mask)
166{
167 int nss, max_nss = sta->rx_nss > 3 ? 4 : sta->rx_nss;
168
169 for (nss = 0; nss < max_nss; nss++)
170 ht_mcs[nss] = sta->ht_cap.mcs.rx_mask[nss] & mask[nss];
171}
172
173static int
developer7800b8d2022-06-23 22:15:56 +0800174besra_mcu_parse_response(struct mt76_dev *mdev, int cmd,
developerb11a5392022-03-31 00:34:47 +0800175 struct sk_buff *skb, int seq)
176{
developer7800b8d2022-06-23 22:15:56 +0800177 struct besra_mcu_rxd *rxd;
178 struct besra_mcu_uni_event *event;
developerb11a5392022-03-31 00:34:47 +0800179 int mcu_cmd = FIELD_GET(__MCU_CMD_FIELD_ID, cmd);
180 int ret = 0;
181
182 if (!skb) {
183 dev_err(mdev->dev, "Message %08x (seq %d) timeout\n",
184 cmd, seq);
185 return -ETIMEDOUT;
186 }
187
developer7800b8d2022-06-23 22:15:56 +0800188 rxd = (struct besra_mcu_rxd *)skb->data;
developerb11a5392022-03-31 00:34:47 +0800189 if (seq != rxd->seq)
190 return -EAGAIN;
191
192 if (cmd == MCU_CMD(PATCH_SEM_CONTROL)) {
193 skb_pull(skb, sizeof(*rxd) - 4);
194 ret = *skb->data;
195 } else if (cmd == MCU_EXT_CMD(THERMAL_CTRL)) {
196 skb_pull(skb, sizeof(*rxd) + 4);
197 ret = le32_to_cpu(*(__le32 *)skb->data);
198 } else if ((rxd->option & MCU_UNI_CMD_EVENT) &&
199 rxd->eid == MCU_UNI_EVENT_RESULT) {
200 skb_pull(skb, sizeof(*rxd));
developer7800b8d2022-06-23 22:15:56 +0800201 event = (struct besra_mcu_uni_event *)skb->data;
developerb11a5392022-03-31 00:34:47 +0800202 ret = le32_to_cpu(event->status);
203 /* skip invalid event */
204 if (mcu_cmd != event->cid)
205 ret = -EAGAIN;
206 } else {
developer7800b8d2022-06-23 22:15:56 +0800207 skb_pull(skb, sizeof(struct besra_mcu_rxd));
developerb11a5392022-03-31 00:34:47 +0800208 }
209
210 return ret;
211}
212
213static int
developer7800b8d2022-06-23 22:15:56 +0800214besra_mcu_send_message(struct mt76_dev *mdev, struct sk_buff *skb,
developerb11a5392022-03-31 00:34:47 +0800215 int cmd, int *wait_seq)
216{
developer7800b8d2022-06-23 22:15:56 +0800217 struct besra_dev *dev = container_of(mdev, struct besra_dev, mt76);
developerb11a5392022-03-31 00:34:47 +0800218 int txd_len, mcu_cmd = FIELD_GET(__MCU_CMD_FIELD_ID, cmd);
developer7800b8d2022-06-23 22:15:56 +0800219 struct besra_uni_txd *uni_txd;
220 struct besra_mcu_txd *mcu_txd;
developerb11a5392022-03-31 00:34:47 +0800221 enum mt76_mcuq_id qid;
222 __le32 *txd;
223 u32 val;
224 u8 seq;
225
226 /* TODO: make dynamic based on msg type */
227 mdev->mcu.timeout = 20 * HZ;
228
229 seq = ++dev->mt76.mcu.msg_seq & 0xf;
230 if (!seq)
231 seq = ++dev->mt76.mcu.msg_seq & 0xf;
232
233 if (cmd == MCU_CMD(FW_SCATTER)) {
234 qid = MT_MCUQ_FWDL;
235 goto exit;
236 }
237
238 txd_len = cmd & __MCU_CMD_FIELD_UNI ? sizeof(*uni_txd) : sizeof(*mcu_txd);
239 txd = (__le32 *)skb_push(skb, txd_len);
240 if (test_bit(MT76_STATE_MCU_RUNNING, &dev->mphy.state))
241 qid = MT_MCUQ_WA;
242 else
243 qid = MT_MCUQ_WM;
244
245 val = FIELD_PREP(MT_TXD0_TX_BYTES, skb->len) |
246 FIELD_PREP(MT_TXD0_PKT_FMT, MT_TX_TYPE_CMD) |
247 FIELD_PREP(MT_TXD0_Q_IDX, MT_TX_MCU_PORT_RX_Q0);
248 txd[0] = cpu_to_le32(val);
249
250 val = FIELD_PREP(MT_TXD1_HDR_FORMAT, MT_HDR_FORMAT_CMD);
251 txd[1] = cpu_to_le32(val);
252
253 if (cmd & __MCU_CMD_FIELD_UNI) {
developer7800b8d2022-06-23 22:15:56 +0800254 uni_txd = (struct besra_uni_txd *)txd;
developerb11a5392022-03-31 00:34:47 +0800255 uni_txd->len = cpu_to_le16(skb->len - sizeof(uni_txd->txd));
256 uni_txd->cid = cpu_to_le16(mcu_cmd);
257 uni_txd->s2d_index = MCU_S2D_H2CN;
258 uni_txd->pkt_type = MCU_PKT_ID;
259 uni_txd->seq = seq;
260
261 if (cmd & __MCU_CMD_FIELD_QUERY)
262 uni_txd->option = MCU_CMD_UNI_QUERY_ACK;
263 else
264 uni_txd->option = MCU_CMD_UNI_EXT_ACK;
265
266 if ((cmd & __MCU_CMD_FIELD_WA) && (cmd & __MCU_CMD_FIELD_WM))
267 uni_txd->s2d_index = MCU_S2D_H2CN;
268 else if (cmd & __MCU_CMD_FIELD_WA)
269 uni_txd->s2d_index = MCU_S2D_H2C;
270 else if (cmd & __MCU_CMD_FIELD_WM)
271 uni_txd->s2d_index = MCU_S2D_H2N;
272
273 goto exit;
274 }
275
developer7800b8d2022-06-23 22:15:56 +0800276 mcu_txd = (struct besra_mcu_txd *)txd;
developerb11a5392022-03-31 00:34:47 +0800277 mcu_txd->len = cpu_to_le16(skb->len - sizeof(mcu_txd->txd));
278 mcu_txd->pq_id = cpu_to_le16(MCU_PQ_ID(MT_TX_PORT_IDX_MCU,
279 MT_TX_MCU_PORT_RX_Q0));
280 mcu_txd->pkt_type = MCU_PKT_ID;
281 mcu_txd->seq = seq;
282
283 mcu_txd->cid = FIELD_GET(__MCU_CMD_FIELD_ID, cmd);
284 mcu_txd->set_query = MCU_Q_NA;
285 mcu_txd->ext_cid = FIELD_GET(__MCU_CMD_FIELD_EXT_ID, cmd);
286 if (mcu_txd->ext_cid) {
287 mcu_txd->ext_cid_ack = 1;
288
289 /* do not use Q_SET for efuse */
290 if (cmd & __MCU_CMD_FIELD_QUERY)
291 mcu_txd->set_query = MCU_Q_QUERY;
292 else
293 mcu_txd->set_query = MCU_Q_SET;
294 }
295
296 if (cmd & __MCU_CMD_FIELD_WA)
297 mcu_txd->s2d_index = MCU_S2D_H2C;
298 else
299 mcu_txd->s2d_index = MCU_S2D_H2N;
300
301exit:
302 if (wait_seq)
303 *wait_seq = seq;
304
305 return mt76_tx_queue_skb_raw(dev, mdev->q_mcu[qid], skb, 0);
306}
307
developer7800b8d2022-06-23 22:15:56 +0800308int besra_mcu_wa_cmd(struct besra_dev *dev, int cmd, u32 a1, u32 a2, u32 a3)
developerb11a5392022-03-31 00:34:47 +0800309{
310 struct {
311 __le32 args[3];
312 } req = {
313 .args = {
314 cpu_to_le32(a1),
315 cpu_to_le32(a2),
316 cpu_to_le32(a3),
317 },
318 };
319
320 return mt76_mcu_send_msg(&dev->mt76, cmd, &req, sizeof(req), false);
321}
322
323static void
developer7800b8d2022-06-23 22:15:56 +0800324besra_mcu_csa_finish(void *priv, u8 *mac, struct ieee80211_vif *vif)
developerb11a5392022-03-31 00:34:47 +0800325{
326 if (vif->csa_active)
327 ieee80211_csa_finish(vif);
328}
329
330static void
developer7800b8d2022-06-23 22:15:56 +0800331besra_mcu_rx_thermal_notify(struct besra_dev *dev, struct sk_buff *skb)
developerb11a5392022-03-31 00:34:47 +0800332{
333 struct mt76_phy *mphy = &dev->mt76.phy;
developer7800b8d2022-06-23 22:15:56 +0800334 struct besra_mcu_thermal_notify *t;
335 struct besra_phy *phy;
developerb11a5392022-03-31 00:34:47 +0800336
developer7800b8d2022-06-23 22:15:56 +0800337 t = (struct besra_mcu_thermal_notify *)skb->data;
developerb11a5392022-03-31 00:34:47 +0800338 if (t->ctrl.ctrl_id != THERMAL_PROTECT_ENABLE)
339 return;
340
341 mphy = mt76_dev_phy_by_band(&dev->mt76, t->ctrl.ctrl_id);
342
developer7800b8d2022-06-23 22:15:56 +0800343 phy = (struct besra_phy *)mphy->priv;
developerb11a5392022-03-31 00:34:47 +0800344 phy->throttle_state = t->ctrl.duty.duty_cycle;
345}
346
347static void
developer7800b8d2022-06-23 22:15:56 +0800348besra_mcu_rx_radar_detected(struct besra_dev *dev, struct sk_buff *skb)
developerb11a5392022-03-31 00:34:47 +0800349{
350 struct mt76_phy *mphy = &dev->mt76.phy;
developer7800b8d2022-06-23 22:15:56 +0800351 struct besra_mcu_rdd_report *r;
developerb11a5392022-03-31 00:34:47 +0800352
developer7800b8d2022-06-23 22:15:56 +0800353 r = (struct besra_mcu_rdd_report *)skb->data;
developerb11a5392022-03-31 00:34:47 +0800354
355 mphy = mt76_dev_phy_by_band(&dev->mt76, r->band_idx);
356
357 if (r->band_idx == MT_RX_SEL2)
358 cfg80211_background_radar_event(mphy->hw->wiphy,
359 &dev->rdd2_chandef,
360 GFP_ATOMIC);
361 else
362 ieee80211_radar_detected(mphy->hw);
363 dev->hw_pattern++;
364}
365
366static void
developer7800b8d2022-06-23 22:15:56 +0800367besra_mcu_rx_log_message(struct besra_dev *dev, struct sk_buff *skb)
developerb11a5392022-03-31 00:34:47 +0800368{
369#define UNI_EVENT_FW_LOG_FORMAT 0
developer7800b8d2022-06-23 22:15:56 +0800370 struct besra_mcu_rxd *rxd = (struct besra_mcu_rxd *)skb->data;
developerb11a5392022-03-31 00:34:47 +0800371 const char *data = (char *)&rxd[1] + 4, *type;
372 struct tlv *tlv = (struct tlv *)data;
373 int len;
374
375 if (le16_to_cpu(tlv->tag) != UNI_EVENT_FW_LOG_FORMAT)
376 return;
377
378 data += sizeof(*tlv) + 4;
379 len = le16_to_cpu(tlv->len) - sizeof(*tlv) - 4;
380
381 switch (rxd->s2d_index) {
382 case 0:
developer7800b8d2022-06-23 22:15:56 +0800383 if (besra_debugfs_rx_log(dev, data, len))
developerb11a5392022-03-31 00:34:47 +0800384 return;
385
386 type = "WM";
387 break;
388 case 2:
389 type = "WA";
390 break;
391 default:
392 type = "unknown";
393 break;
394 }
395
396 wiphy_info(mt76_hw(dev)->wiphy, "%s: %.*s", type, len, data);
397}
398
399static void
developer7800b8d2022-06-23 22:15:56 +0800400besra_mcu_cca_finish(void *priv, u8 *mac, struct ieee80211_vif *vif)
developerb11a5392022-03-31 00:34:47 +0800401{
402 if (!vif->color_change_active)
403 return;
404
405 ieee80211_color_change_finish(vif);
406}
407
408static void
developer7800b8d2022-06-23 22:15:56 +0800409besra_mcu_ie_countdown(struct besra_dev *dev, struct sk_buff *skb)
developerb11a5392022-03-31 00:34:47 +0800410{
411#define UNI_EVENT_IE_COUNTDOWN_CSA 0
412#define UNI_EVENT_IE_COUNTDOWN_BCC 1
413 struct header {
414 u8 band;
415 u8 rsv[3];
416 };
417 struct mt76_phy *mphy = &dev->mt76.phy;
developer7800b8d2022-06-23 22:15:56 +0800418 struct besra_mcu_rxd *rxd = (struct besra_mcu_rxd *)skb->data;
developerb11a5392022-03-31 00:34:47 +0800419 const char *data = (char *)&rxd[1], *tail;
420 struct header *hdr = (struct header *) data;
421 struct tlv *tlv = (struct tlv *)(data + 4);
422 int len;
423
424 if ((hdr->band && !dev->phy.band_idx) && dev->mt76.phy2)
425 mphy = dev->mt76.phy2;
426
427 tail = skb->data + le16_to_cpu(rxd->len);
428 while (data + sizeof(struct tlv) < tail && le16_to_cpu(tlv->len)) {
429 switch (le16_to_cpu(tlv->tag)) {
430 case UNI_EVENT_IE_COUNTDOWN_CSA:
431 ieee80211_iterate_active_interfaces_atomic(mphy->hw,
432 IEEE80211_IFACE_ITER_RESUME_ALL,
developer7800b8d2022-06-23 22:15:56 +0800433 besra_mcu_csa_finish, mphy->hw);
developerb11a5392022-03-31 00:34:47 +0800434 break;
435 case UNI_EVENT_IE_COUNTDOWN_BCC:
436 ieee80211_iterate_active_interfaces_atomic(mphy->hw,
437 IEEE80211_IFACE_ITER_RESUME_ALL,
developer7800b8d2022-06-23 22:15:56 +0800438 besra_mcu_cca_finish, mphy->hw);
developerb11a5392022-03-31 00:34:47 +0800439 break;
440 }
441
442 data += le16_to_cpu(tlv->len);
443 tlv = (struct tlv *)data;
444 }
445}
446
447#if 0
448static void
developer7800b8d2022-06-23 22:15:56 +0800449besra_mcu_rx_ext_event(struct besra_dev *dev, struct sk_buff *skb)
developerb11a5392022-03-31 00:34:47 +0800450{
developer7800b8d2022-06-23 22:15:56 +0800451 struct besra_mcu_rxd *rxd = (struct besra_mcu_rxd *)skb->data;
developerb11a5392022-03-31 00:34:47 +0800452
453 switch (rxd->ext_eid) {
454 case MCU_EXT_EVENT_THERMAL_PROTECT:
developer7800b8d2022-06-23 22:15:56 +0800455 besra_mcu_rx_thermal_notify(dev, skb);
developerb11a5392022-03-31 00:34:47 +0800456 break;
457 case MCU_EXT_EVENT_RDD_REPORT:
developer7800b8d2022-06-23 22:15:56 +0800458 besra_mcu_rx_radar_detected(dev, skb);
developerb11a5392022-03-31 00:34:47 +0800459 break;
460 case MCU_EXT_EVENT_CSA_NOTIFY:
developer7800b8d2022-06-23 22:15:56 +0800461 besra_mcu_rx_csa_notify(dev, skb);
developerb11a5392022-03-31 00:34:47 +0800462 break;
463 case MCU_EXT_EVENT_BCC_NOTIFY:
464 ieee80211_iterate_active_interfaces_atomic(dev->mt76.hw,
465 IEEE80211_IFACE_ITER_RESUME_ALL,
developer7800b8d2022-06-23 22:15:56 +0800466 besra_mcu_cca_finish, dev);
developerb11a5392022-03-31 00:34:47 +0800467 break;
468 default:
469 break;
470 }
471}
472
473static void
developer7800b8d2022-06-23 22:15:56 +0800474besra_mcu_rx_unsolicited_event(struct besra_dev *dev, struct sk_buff *skb)
developerb11a5392022-03-31 00:34:47 +0800475{
developer7800b8d2022-06-23 22:15:56 +0800476 struct besra_mcu_rxd *rxd = (struct besra_mcu_rxd *)skb->data;
developerb11a5392022-03-31 00:34:47 +0800477
478 switch (rxd->eid) {
479 case MCU_EVENT_EXT:
developer7800b8d2022-06-23 22:15:56 +0800480 besra_mcu_rx_ext_event(dev, skb);
developerb11a5392022-03-31 00:34:47 +0800481 break;
482 default:
483 break;
484 }
485 dev_kfree_skb(skb);
486}
487#endif
488
489static void
developer7800b8d2022-06-23 22:15:56 +0800490besra_mcu_uni_rx_unsolicited_event(struct besra_dev *dev, struct sk_buff *skb)
developerb11a5392022-03-31 00:34:47 +0800491{
developer7800b8d2022-06-23 22:15:56 +0800492 struct besra_mcu_rxd *rxd = (struct besra_mcu_rxd *)skb->data;
developerb11a5392022-03-31 00:34:47 +0800493
494 switch (rxd->eid) {
495 case MCU_UNI_EVENT_FW_LOG_2_HOST:
developer7800b8d2022-06-23 22:15:56 +0800496 besra_mcu_rx_log_message(dev, skb);
developerb11a5392022-03-31 00:34:47 +0800497 break;
498 case MCU_UNI_EVENT_IE_COUNTDOWN:
developer7800b8d2022-06-23 22:15:56 +0800499 besra_mcu_ie_countdown(dev, skb);
developerb11a5392022-03-31 00:34:47 +0800500 break;
501 default:
502 break;
503 }
504 dev_kfree_skb(skb);
505}
506
developer7800b8d2022-06-23 22:15:56 +0800507void besra_mcu_rx_event(struct besra_dev *dev, struct sk_buff *skb)
developerb11a5392022-03-31 00:34:47 +0800508{
developer7800b8d2022-06-23 22:15:56 +0800509 struct besra_mcu_rxd *rxd = (struct besra_mcu_rxd *)skb->data;
developerb11a5392022-03-31 00:34:47 +0800510
511 if (rxd->option & MCU_UNI_CMD_UNSOLICITED_EVENT) {
developer7800b8d2022-06-23 22:15:56 +0800512 besra_mcu_uni_rx_unsolicited_event(dev, skb);
developerb11a5392022-03-31 00:34:47 +0800513 return;
514 }
515
516 /* TODO: to be changed to uni cmd */
517 /* if (!(rxd->option & MCU_UNI_CMD_UNI_EVENT) && */
518 /* (rxd->ext_eid == MCU_EXT_EVENT_THERMAL_PROTECT || */
519 /* rxd->ext_eid == MCU_EXT_EVENT_ASSERT_DUMP || */
520 /* rxd->ext_eid == MCU_EXT_EVENT_PS_SYNC || */
521 /* rxd->ext_eid == MCU_EXT_EVENT_BCC_NOTIFY || */
522 /* !rxd->seq)) { */
developer7800b8d2022-06-23 22:15:56 +0800523 /* besra_mcu_rx_unsolicited_event(dev, skb); */
developerb11a5392022-03-31 00:34:47 +0800524 /* return; */
525 /* } */
526
527 mt76_mcu_rx_event(&dev->mt76, skb);
528}
529
530static struct tlv *
developer7800b8d2022-06-23 22:15:56 +0800531besra_mcu_add_uni_tlv(struct sk_buff *skb, int tag, int len)
developerb11a5392022-03-31 00:34:47 +0800532{
533 struct tlv *ptlv, tlv = {
534 .tag = cpu_to_le16(tag),
535 .len = cpu_to_le16(len),
536 };
537
538 ptlv = skb_put(skb, len);
539 memcpy(ptlv, &tlv, sizeof(tlv));
540
541 return ptlv;
542}
543
544/** bss info **/
developer7800b8d2022-06-23 22:15:56 +0800545struct besra_he_obss_narrow_bw_ru_data {
developerb11a5392022-03-31 00:34:47 +0800546 bool tolerated;
547};
548
developer7800b8d2022-06-23 22:15:56 +0800549static inline u8 besra_get_band(enum nl80211_band band)
developerb11a5392022-03-31 00:34:47 +0800550{
551 static const u8 convert_to_fw[] = {
552 [NL80211_BAND_2GHZ] = CMD_BAND_24G,
553 [NL80211_BAND_5GHZ] = CMD_BAND_5G,
554 [NL80211_BAND_6GHZ] = CMD_BAND_6G,
555 };
556
557 if (band >= ARRAY_SIZE(convert_to_fw))
558 return 0;
559
560 return convert_to_fw[band];
561}
562
563static void
developer7800b8d2022-06-23 22:15:56 +0800564besra_mcu_bss_rfch_tlv(struct sk_buff *skb, struct ieee80211_vif *vif,
565 struct besra_phy *phy)
developerb11a5392022-03-31 00:34:47 +0800566{
567 struct cfg80211_chan_def *chandef = &phy->mt76->chandef;
568 struct bss_rlm_tlv *ch;
569 struct tlv *tlv;
570 int freq1 = chandef->center_freq1;
571
developer7800b8d2022-06-23 22:15:56 +0800572 tlv = besra_mcu_add_uni_tlv(skb, UNI_BSS_INFO_RLM, sizeof(*ch));
developerb11a5392022-03-31 00:34:47 +0800573
574 ch = (struct bss_rlm_tlv *)tlv;
575 ch->control_channel = chandef->chan->hw_value;
576 ch->center_chan = ieee80211_frequency_to_channel(freq1);
577 ch->bw = mt76_connac_chan_bw(chandef);
578 ch->tx_streams = hweight8(phy->mt76->antenna_mask);
579 ch->rx_streams = hweight8(phy->mt76->antenna_mask);
developer7800b8d2022-06-23 22:15:56 +0800580 ch->band = besra_get_band(chandef->chan->band);
developerb11a5392022-03-31 00:34:47 +0800581
582 if (chandef->width == NL80211_CHAN_WIDTH_80P80) {
583 int freq2 = chandef->center_freq2;
584
585 ch->center_chan2 = ieee80211_frequency_to_channel(freq2);
586 }
587}
588
589static void
developer7800b8d2022-06-23 22:15:56 +0800590besra_mcu_bss_ra_tlv(struct sk_buff *skb, struct ieee80211_vif *vif,
591 struct besra_phy *phy)
developerb11a5392022-03-31 00:34:47 +0800592{
593 struct bss_ra_tlv *ra;
594 struct tlv *tlv;
595
developer7800b8d2022-06-23 22:15:56 +0800596 tlv = besra_mcu_add_uni_tlv(skb, UNI_BSS_INFO_RA, sizeof(*ra));
developerb11a5392022-03-31 00:34:47 +0800597
598 ra = (struct bss_ra_tlv *)tlv;
599 ra->short_preamble = true;
600}
601
602static void
developer7800b8d2022-06-23 22:15:56 +0800603besra_mcu_bss_he_tlv(struct sk_buff *skb, struct ieee80211_vif *vif,
604 struct besra_phy *phy)
developerb11a5392022-03-31 00:34:47 +0800605{
606#define DEFAULT_HE_PE_DURATION 4
607#define DEFAULT_HE_DURATION_RTS_THRES 1023
608 const struct ieee80211_sta_he_cap *cap;
609 struct bss_info_uni_he *he;
610 struct tlv *tlv;
611
612 cap = mt76_connac_get_he_phy_cap(phy->mt76, vif);
613
developer7800b8d2022-06-23 22:15:56 +0800614 tlv = besra_mcu_add_uni_tlv(skb, UNI_BSS_INFO_HE_BASIC, sizeof(*he));
developerb11a5392022-03-31 00:34:47 +0800615
616 he = (struct bss_info_uni_he *)tlv;
617 he->he_pe_duration = vif->bss_conf.htc_trig_based_pkt_ext;
618 if (!he->he_pe_duration)
619 he->he_pe_duration = DEFAULT_HE_PE_DURATION;
620
621 he->he_rts_thres = cpu_to_le16(vif->bss_conf.frame_time_rts_th);
622 if (!he->he_rts_thres)
623 he->he_rts_thres = cpu_to_le16(DEFAULT_HE_DURATION_RTS_THRES);
624
625 he->max_nss_mcs[CMD_HE_MCS_BW80] = cap->he_mcs_nss_supp.tx_mcs_80;
626 he->max_nss_mcs[CMD_HE_MCS_BW160] = cap->he_mcs_nss_supp.tx_mcs_160;
627 he->max_nss_mcs[CMD_HE_MCS_BW8080] = cap->he_mcs_nss_supp.tx_mcs_80p80;
628}
629
630static void
developer7800b8d2022-06-23 22:15:56 +0800631besra_mcu_bss_bmc_tlv(struct sk_buff *skb, struct besra_phy *phy)
developerb11a5392022-03-31 00:34:47 +0800632{
633 struct bss_rate_tlv *bmc;
634 struct cfg80211_chan_def *chandef = &phy->mt76->chandef;
635 enum nl80211_band band = chandef->chan->band;
636 struct tlv *tlv;
637
developer7800b8d2022-06-23 22:15:56 +0800638 tlv = besra_mcu_add_uni_tlv(skb, UNI_BSS_INFO_RATE, sizeof(*bmc));
developerb11a5392022-03-31 00:34:47 +0800639
640 bmc = (struct bss_rate_tlv *)tlv;
641 if (band == NL80211_BAND_2GHZ) {
642 bmc->short_preamble = true;
643 } else {
644 bmc->bc_trans = cpu_to_le16(0x8080);
645 bmc->mc_trans = cpu_to_le16(0x8080);
646 bmc->bc_fixed_rate = 1;
647 bmc->mc_fixed_rate = 1;
648 bmc->short_preamble = 1;
649 }
650}
651
652static void
developer7800b8d2022-06-23 22:15:56 +0800653besra_mcu_bss_txcmd_tlv(struct sk_buff *skb, bool en)
developerb11a5392022-03-31 00:34:47 +0800654{
655 struct bss_txcmd_tlv *txcmd;
656 struct tlv *tlv;
657
developer7800b8d2022-06-23 22:15:56 +0800658 tlv = besra_mcu_add_uni_tlv(skb, UNI_BSS_INFO_TXCMD, sizeof(*txcmd));
developerb11a5392022-03-31 00:34:47 +0800659
660 txcmd = (struct bss_txcmd_tlv *)tlv;
661 txcmd->txcmd_mode = en;
662}
663
664static void
developer7800b8d2022-06-23 22:15:56 +0800665besra_mcu_bss_mld_tlv(struct sk_buff *skb)
developerb11a5392022-03-31 00:34:47 +0800666{
667 struct bss_mld_tlv *mld;
668 struct tlv *tlv;
669
developer7800b8d2022-06-23 22:15:56 +0800670 tlv = besra_mcu_add_uni_tlv(skb, UNI_BSS_INFO_MLD, sizeof(*mld));
developerb11a5392022-03-31 00:34:47 +0800671
672 mld = (struct bss_mld_tlv *)tlv;
673 mld->group_mld_id = 0xff;
674 mld->remap_idx = 0xff;
675}
676
677static void
developer7800b8d2022-06-23 22:15:56 +0800678besra_mcu_bss_sec_tlv(struct sk_buff *skb, struct ieee80211_vif *vif)
developerb11a5392022-03-31 00:34:47 +0800679{
680 struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv;
681 struct bss_sec_tlv *sec;
682 struct tlv *tlv;
683
developer7800b8d2022-06-23 22:15:56 +0800684 tlv = besra_mcu_add_uni_tlv(skb, UNI_BSS_INFO_SEC, sizeof(*sec));
developerb11a5392022-03-31 00:34:47 +0800685
686 sec = (struct bss_sec_tlv *)tlv;
687 sec->cipher = mvif->cipher;
688}
689
690static int
developer7800b8d2022-06-23 22:15:56 +0800691besra_mcu_muar_config(struct besra_phy *phy, struct ieee80211_vif *vif,
developerb11a5392022-03-31 00:34:47 +0800692 bool bssid, bool enable)
693{
developer7800b8d2022-06-23 22:15:56 +0800694 struct besra_dev *dev = phy->dev;
695 struct besra_vif *mvif = (struct besra_vif *)vif->drv_priv;
developerb11a5392022-03-31 00:34:47 +0800696 u32 idx = mvif->mt76.omac_idx - REPEATER_BSSID_START;
697 u32 mask = phy->omac_mask >> 32 & ~BIT(idx);
698 const u8 *addr = vif->addr;
699 struct {
700 u8 mode;
701 u8 force_clear;
702 u8 clear_bitmap[8];
703 u8 entry_count;
704 u8 write;
705 u8 band;
706
707 u8 index;
708 u8 bssid;
709 u8 addr[ETH_ALEN];
710 } __packed req = {
711 .mode = !!mask || enable,
712 .entry_count = 1,
713 .write = 1,
714 .band = phy->band_idx,
715 .index = idx * 2 + bssid,
716 };
717
718 if (bssid)
719 addr = vif->bss_conf.bssid;
720
721 if (enable)
722 ether_addr_copy(req.addr, addr);
723
724 return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(MUAR_UPDATE), &req,
725 sizeof(req), true);
726}
727
728static int
developer7800b8d2022-06-23 22:15:56 +0800729besra_mcu_bss_basic_tlv(struct sk_buff *skb,
developerb11a5392022-03-31 00:34:47 +0800730 struct ieee80211_vif *vif,
731 struct ieee80211_sta *sta,
732 struct mt76_phy *phy, u16 wlan_idx,
733 bool enable)
734{
735 struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv;
736 struct cfg80211_chan_def *chandef = &phy->chandef;
737 struct mt76_connac_bss_basic_tlv *bss;
738 struct tlv *tlv;
739 u32 type;
740 int idx;
741
742 switch (vif->type) {
743 case NL80211_IFTYPE_MESH_POINT:
744 case NL80211_IFTYPE_AP:
745 case NL80211_IFTYPE_MONITOR:
746 type = CONNECTION_INFRA_AP;
747 break;
748 case NL80211_IFTYPE_STATION:
749 if (enable) {
750 rcu_read_lock();
751 if (!sta)
752 sta = ieee80211_find_sta(vif,
753 vif->bss_conf.bssid);
754 /* TODO: enable BSS_INFO_UAPSD & BSS_INFO_PM */
755 if (sta) {
756 struct mt76_wcid *wcid;
757
758 wcid = (struct mt76_wcid *)sta->drv_priv;
759 wlan_idx = wcid->idx;
760 }
761 rcu_read_unlock();
762 }
763 type = CONNECTION_INFRA_STA;
764 break;
765 case NL80211_IFTYPE_ADHOC:
766 type = CONNECTION_IBSS_ADHOC;
767 break;
768 default:
769 WARN_ON(1);
770 break;
771 }
772
developer7800b8d2022-06-23 22:15:56 +0800773 tlv = besra_mcu_add_uni_tlv(skb, UNI_BSS_INFO_BASIC, sizeof(*bss));
developerb11a5392022-03-31 00:34:47 +0800774
775 bss = (struct mt76_connac_bss_basic_tlv *)tlv;
776 bss->bcn_interval = cpu_to_le16(vif->bss_conf.beacon_int);
777 bss->dtim_period = vif->bss_conf.dtim_period;
778 bss->bmc_tx_wlan_idx = cpu_to_le16(wlan_idx);
779 bss->sta_idx = cpu_to_le16(wlan_idx);
780 bss->conn_type = cpu_to_le32(type);
781 bss->omac_idx = mvif->omac_idx;
782 bss->band_idx = mvif->band_idx;
783 bss->wmm_idx = mvif->wmm_idx;
784 bss->conn_state = !enable;
785 bss->active = enable;
786
787 idx = mvif->omac_idx > EXT_BSSID_START ? HW_BSSID_0 : mvif->omac_idx;
788 bss->hw_bss_idx = idx;
789
790 if (vif->type != NL80211_IFTYPE_MONITOR) {
791 memcpy(bss->bssid, vif->bss_conf.bssid, ETH_ALEN);
792 bss->bcn_interval = cpu_to_le16(vif->bss_conf.beacon_int);
793 bss->dtim_period = vif->bss_conf.dtim_period;
794 bss->phymode = mt76_connac_get_phy_mode(phy, vif,
795 chandef->chan->band, NULL);
796 } else {
797 memcpy(bss->bssid, phy->macaddr, ETH_ALEN);
798 }
799
800 if (chandef->chan->band == NL80211_BAND_6GHZ)
801 bss->phymode_ext |= BIT(0);
802
803 return 0;
804}
805
806static struct sk_buff *
developer7800b8d2022-06-23 22:15:56 +0800807__besra_mcu_alloc_bss_req(struct mt76_dev *dev, struct mt76_vif *mvif, int len)
developerb11a5392022-03-31 00:34:47 +0800808{
809 struct bss_req_hdr hdr = {
810 .bss_idx = mvif->idx,
811 };
812 struct sk_buff *skb;
813
814 skb = mt76_mcu_msg_alloc(dev, NULL, len);
815 if (!skb)
816 return ERR_PTR(-ENOMEM);
817
818 skb_put_data(skb, &hdr, sizeof(hdr));
819
820 return skb;
821}
822
developer7800b8d2022-06-23 22:15:56 +0800823int besra_mcu_add_bss_info(struct besra_phy *phy,
developerb11a5392022-03-31 00:34:47 +0800824 struct ieee80211_vif *vif, int enable)
825{
developer7800b8d2022-06-23 22:15:56 +0800826 struct besra_vif *mvif = (struct besra_vif *)vif->drv_priv;
827 struct besra_dev *dev = phy->dev;
developerb11a5392022-03-31 00:34:47 +0800828 struct sk_buff *skb;
829
830 if (mvif->mt76.omac_idx >= REPEATER_BSSID_START) {
developer7800b8d2022-06-23 22:15:56 +0800831 besra_mcu_muar_config(phy, vif, false, enable);
832 besra_mcu_muar_config(phy, vif, true, enable);
developerb11a5392022-03-31 00:34:47 +0800833 }
834
developer7800b8d2022-06-23 22:15:56 +0800835 skb = __besra_mcu_alloc_bss_req(&dev->mt76, &mvif->mt76,
836 BESRA_BSS_UPDATE_MAX_SIZE);
developerb11a5392022-03-31 00:34:47 +0800837 if (IS_ERR(skb))
838 return PTR_ERR(skb);
839
840 /* bss_basic must be first */
developer7800b8d2022-06-23 22:15:56 +0800841 besra_mcu_bss_basic_tlv(skb, vif, NULL, phy->mt76,
developerb11a5392022-03-31 00:34:47 +0800842 mvif->sta.wcid.idx, enable);
developer7800b8d2022-06-23 22:15:56 +0800843 besra_mcu_bss_sec_tlv(skb, vif);
developerb11a5392022-03-31 00:34:47 +0800844
845 if (vif->type == NL80211_IFTYPE_MONITOR)
846 goto out;
847
848 if (enable) {
developer7800b8d2022-06-23 22:15:56 +0800849 besra_mcu_bss_rfch_tlv(skb, vif, phy);
850 besra_mcu_bss_bmc_tlv(skb, phy);
851 besra_mcu_bss_ra_tlv(skb, vif, phy);
852 besra_mcu_bss_txcmd_tlv(skb, true);
developerb11a5392022-03-31 00:34:47 +0800853
854 if (vif->bss_conf.he_support)
developer7800b8d2022-06-23 22:15:56 +0800855 besra_mcu_bss_he_tlv(skb, vif, phy);
developerb11a5392022-03-31 00:34:47 +0800856
857 /* all besra ic need this tlv, no matter it supports EHT or not */
developer7800b8d2022-06-23 22:15:56 +0800858 besra_mcu_bss_mld_tlv(skb);
developerb11a5392022-03-31 00:34:47 +0800859 }
860out:
861 return mt76_mcu_skb_send_msg(&dev->mt76, skb,
862 MCU_WMWA_UNI_CMD(BSS_INFO_UPDATE), true);
863}
864
developer7800b8d2022-06-23 22:15:56 +0800865int besra_mcu_sta_ba(struct mt76_dev *dev, struct mt76_vif *mvif,
developerb11a5392022-03-31 00:34:47 +0800866 struct ieee80211_ampdu_params *params,
867 bool enable, bool tx)
868{
869 struct mt76_wcid *wcid = (struct mt76_wcid *)params->sta->drv_priv;
870 struct uni_sta_rec_ba *ba;
871 struct sk_buff *skb;
872 struct tlv *tlv;
873
874 skb = mt76_connac_mcu_alloc_sta_req(dev, mvif, wcid);
875 if (IS_ERR(skb))
876 return PTR_ERR(skb);
877
878 tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_BA, sizeof(*ba));
879
880 ba = (struct uni_sta_rec_ba *)tlv;
881 ba->ba_type = tx ? MT_BA_TYPE_ORIGINATOR : MT_BA_TYPE_RECIPIENT;
882 ba->winsize = cpu_to_le16(params->buf_size);
883 ba->ssn = cpu_to_le16(params->ssn);
884 ba->ba_en = enable << params->tid;
885 ba->amsdu = params->amsdu;
886 ba->tid = params->tid;
887
888 return mt76_mcu_skb_send_msg(dev, skb,
889 MCU_WMWA_UNI_CMD(STA_REC_UPDATE), true);
890}
891
892/** starec & wtbl **/
developer7800b8d2022-06-23 22:15:56 +0800893int besra_mcu_add_tx_ba(struct besra_dev *dev,
developerb11a5392022-03-31 00:34:47 +0800894 struct ieee80211_ampdu_params *params,
895 bool enable)
896{
developer7800b8d2022-06-23 22:15:56 +0800897 struct besra_sta *msta = (struct besra_sta *)params->sta->drv_priv;
898 struct besra_vif *mvif = msta->vif;
developerb11a5392022-03-31 00:34:47 +0800899
900 if (enable && !params->amsdu)
901 msta->wcid.amsdu = false;
902
developer7800b8d2022-06-23 22:15:56 +0800903 return besra_mcu_sta_ba(&dev->mt76, &mvif->mt76, params,
developerb11a5392022-03-31 00:34:47 +0800904 enable, true);
905}
906
developer7800b8d2022-06-23 22:15:56 +0800907int besra_mcu_add_rx_ba(struct besra_dev *dev,
developerb11a5392022-03-31 00:34:47 +0800908 struct ieee80211_ampdu_params *params,
909 bool enable)
910{
developer7800b8d2022-06-23 22:15:56 +0800911 struct besra_sta *msta = (struct besra_sta *)params->sta->drv_priv;
912 struct besra_vif *mvif = msta->vif;
developerb11a5392022-03-31 00:34:47 +0800913
developer7800b8d2022-06-23 22:15:56 +0800914 return besra_mcu_sta_ba(&dev->mt76, &mvif->mt76, params,
developerb11a5392022-03-31 00:34:47 +0800915 enable, false);
916}
917
918static void
developer7800b8d2022-06-23 22:15:56 +0800919besra_mcu_sta_he_tlv(struct sk_buff *skb, struct ieee80211_sta *sta,
developerb11a5392022-03-31 00:34:47 +0800920 struct ieee80211_vif *vif)
921{
922 struct ieee80211_he_cap_elem *elem = &sta->he_cap.he_cap_elem;
923 struct ieee80211_he_mcs_nss_supp mcs_map;
924 struct sta_rec_he_v2 *he;
925 struct tlv *tlv;
926 int i = 0;
927
928 if (!sta->he_cap.has_he)
929 return;
930
931 tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_HE_V2, sizeof(*he));
932
933 he = (struct sta_rec_he_v2 *)tlv;
934 for (i = 0; i < 11; i++){
935 if (i < 6)
936 he->he_mac_cap[i] = cpu_to_le16(elem->mac_cap_info[i]);
937 he->he_phy_cap[i] = cpu_to_le16(elem->phy_cap_info[i]);
938 }
939
940 mcs_map = sta->he_cap.he_mcs_nss_supp;
941 switch (sta->bandwidth) {
942 case IEEE80211_STA_RX_BW_160:
943 if (elem->phy_cap_info[0] &
944 IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_80PLUS80_MHZ_IN_5G)
developer7800b8d2022-06-23 22:15:56 +0800945 besra_mcu_set_sta_he_mcs(sta,
developerb11a5392022-03-31 00:34:47 +0800946 &he->max_nss_mcs[CMD_HE_MCS_BW8080],
947 le16_to_cpu(mcs_map.rx_mcs_80p80));
948
developer7800b8d2022-06-23 22:15:56 +0800949 besra_mcu_set_sta_he_mcs(sta,
developerb11a5392022-03-31 00:34:47 +0800950 &he->max_nss_mcs[CMD_HE_MCS_BW160],
951 le16_to_cpu(mcs_map.rx_mcs_160));
952 fallthrough;
953 default:
developer7800b8d2022-06-23 22:15:56 +0800954 besra_mcu_set_sta_he_mcs(sta,
developerb11a5392022-03-31 00:34:47 +0800955 &he->max_nss_mcs[CMD_HE_MCS_BW80],
956 le16_to_cpu(mcs_map.rx_mcs_80));
957 break;
958 }
959
960 he->pkt_ext = 2;
961}
962
963static void
developer7800b8d2022-06-23 22:15:56 +0800964besra_mcu_sta_he_6g_tlv(struct sk_buff *skb, struct ieee80211_sta *sta,
developerb11a5392022-03-31 00:34:47 +0800965 struct ieee80211_vif *vif)
966{
967 struct sta_rec_he_6g_capa *he_6g;
968 struct tlv *tlv;
969
970 if (!sta->he_6ghz_capa.capa)
971 return;
972
973 tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_HE_6G, sizeof(*he_6g));
974
975 he_6g = (struct sta_rec_he_6g_capa *)tlv;
976 he_6g->capa = cpu_to_le16(sta->he_6ghz_capa.capa);
977
978}
979
980static void
developer7800b8d2022-06-23 22:15:56 +0800981besra_mcu_sta_muru_tlv(struct sk_buff *skb, struct ieee80211_sta *sta,
developerb11a5392022-03-31 00:34:47 +0800982 struct ieee80211_vif *vif)
983{
developer7800b8d2022-06-23 22:15:56 +0800984 struct besra_vif *mvif = (struct besra_vif *)vif->drv_priv;
developerb11a5392022-03-31 00:34:47 +0800985 struct ieee80211_he_cap_elem *elem = &sta->he_cap.he_cap_elem;
986 struct sta_rec_muru *muru;
987 struct tlv *tlv;
988
989 if (vif->type != NL80211_IFTYPE_STATION &&
990 vif->type != NL80211_IFTYPE_AP)
991 return;
992
993 tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_MURU, sizeof(*muru));
994
995 muru = (struct sta_rec_muru *)tlv;
996
997 muru->cfg.mimo_dl_en = mvif->cap.he_mu_ebfer ||
998 mvif->cap.vht_mu_ebfer ||
999 mvif->cap.vht_mu_ebfee;
1000 muru->cfg.mimo_ul_en = true;
1001 muru->cfg.ofdma_dl_en = true;
1002
1003 muru->mimo_dl.vht_mu_bfee =
1004 !!(sta->vht_cap.cap & IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE);
1005
1006 if (sta->vht_cap.vht_supported)
1007 muru->mimo_dl.vht_mu_bfee =
1008 !!(sta->vht_cap.cap & IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE);
1009
1010 if (!sta->he_cap.has_he)
1011 return;
1012
1013 muru->mimo_dl.partial_bw_dl_mimo =
1014 HE_PHY(CAP6_PARTIAL_BANDWIDTH_DL_MUMIMO, elem->phy_cap_info[6]);
1015
1016 muru->cfg.mimo_ul_en = true;
1017 muru->mimo_ul.full_ul_mimo =
1018 HE_PHY(CAP2_UL_MU_FULL_MU_MIMO, elem->phy_cap_info[2]);
1019 muru->mimo_ul.partial_ul_mimo =
1020 HE_PHY(CAP2_UL_MU_PARTIAL_MU_MIMO, elem->phy_cap_info[2]);
1021
1022 muru->cfg.ofdma_dl_en = true;
1023 muru->ofdma_dl.punc_pream_rx =
1024 HE_PHY(CAP1_PREAMBLE_PUNC_RX_MASK, elem->phy_cap_info[1]);
1025 muru->ofdma_dl.he_20m_in_40m_2g =
1026 HE_PHY(CAP8_20MHZ_IN_40MHZ_HE_PPDU_IN_2G, elem->phy_cap_info[8]);
1027 muru->ofdma_dl.he_20m_in_160m =
1028 HE_PHY(CAP8_20MHZ_IN_160MHZ_HE_PPDU, elem->phy_cap_info[8]);
1029 muru->ofdma_dl.he_80m_in_160m =
1030 HE_PHY(CAP8_80MHZ_IN_160MHZ_HE_PPDU, elem->phy_cap_info[8]);
1031
1032 muru->ofdma_ul.t_frame_dur =
1033 HE_MAC(CAP1_TF_MAC_PAD_DUR_MASK, elem->mac_cap_info[1]);
1034 muru->ofdma_ul.mu_cascading =
1035 HE_MAC(CAP2_MU_CASCADING, elem->mac_cap_info[2]);
1036 muru->ofdma_ul.uo_ra =
1037 HE_MAC(CAP3_OFDMA_RA, elem->mac_cap_info[3]);
1038}
1039
1040static void
developer7800b8d2022-06-23 22:15:56 +08001041besra_mcu_sta_ht_tlv(struct sk_buff *skb, struct ieee80211_sta *sta)
developerb11a5392022-03-31 00:34:47 +08001042{
1043 struct sta_rec_ht *ht;
1044 struct tlv *tlv;
1045
1046 if (!sta->ht_cap.ht_supported)
1047 return;
1048
1049 tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_HT, sizeof(*ht));
1050
1051 ht = (struct sta_rec_ht *)tlv;
1052 ht->ht_cap = cpu_to_le16(sta->ht_cap.cap);
1053}
1054
1055static void
developer7800b8d2022-06-23 22:15:56 +08001056besra_mcu_sta_vht_tlv(struct sk_buff *skb, struct ieee80211_sta *sta)
developerb11a5392022-03-31 00:34:47 +08001057{
1058 struct sta_rec_vht *vht;
1059 struct tlv *tlv;
1060
1061 if (!sta->vht_cap.vht_supported)
1062 return;
1063
1064 tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_VHT, sizeof(*vht));
1065
1066 vht = (struct sta_rec_vht *)tlv;
1067 vht->vht_cap = cpu_to_le32(sta->vht_cap.cap);
1068 vht->vht_rx_mcs_map = sta->vht_cap.vht_mcs.rx_mcs_map;
1069 vht->vht_tx_mcs_map = sta->vht_cap.vht_mcs.tx_mcs_map;
1070}
1071
1072static void
developer7800b8d2022-06-23 22:15:56 +08001073besra_mcu_sta_amsdu_tlv(struct besra_dev *dev, struct sk_buff *skb,
developerb11a5392022-03-31 00:34:47 +08001074 struct ieee80211_vif *vif, struct ieee80211_sta *sta)
1075{
developer7800b8d2022-06-23 22:15:56 +08001076 struct besra_sta *msta = (struct besra_sta *)sta->drv_priv;
developerb11a5392022-03-31 00:34:47 +08001077 struct sta_rec_amsdu *amsdu;
1078 struct tlv *tlv;
1079
1080 if (vif->type != NL80211_IFTYPE_STATION &&
1081 vif->type != NL80211_IFTYPE_AP)
1082 return;
1083
1084 if (!sta->max_amsdu_len)
1085 return;
1086
1087 tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_HW_AMSDU, sizeof(*amsdu));
1088 amsdu = (struct sta_rec_amsdu *)tlv;
1089 amsdu->max_amsdu_num = 8;
1090 amsdu->amsdu_en = true;
1091 msta->wcid.amsdu = true;
1092
1093 switch (sta->max_amsdu_len) {
1094 case IEEE80211_MAX_MPDU_LEN_VHT_11454:
1095 amsdu->max_mpdu_size =
1096 IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454;
1097 return;
1098 case IEEE80211_MAX_MPDU_LEN_HT_7935:
1099 case IEEE80211_MAX_MPDU_LEN_VHT_7991:
1100 amsdu->max_mpdu_size = IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_7991;
1101 return;
1102 default:
1103 amsdu->max_mpdu_size = IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_3895;
1104 return;
1105 }
1106}
1107
1108#if 0
1109static int
developer7800b8d2022-06-23 22:15:56 +08001110besra_mcu_sta_wtbl_tlv(struct besra_dev *dev, struct sk_buff *skb,
developerb11a5392022-03-31 00:34:47 +08001111 struct ieee80211_vif *vif, struct ieee80211_sta *sta)
1112{
developer7800b8d2022-06-23 22:15:56 +08001113 struct besra_vif *mvif = (struct besra_vif *)vif->drv_priv;
1114 struct besra_sta *msta;
developerb11a5392022-03-31 00:34:47 +08001115 struct wtbl_req_hdr *wtbl_hdr;
1116 struct mt76_wcid *wcid;
1117 struct tlv *tlv;
1118
developer7800b8d2022-06-23 22:15:56 +08001119 msta = sta ? (struct besra_sta *)sta->drv_priv : &mvif->sta;
developerb11a5392022-03-31 00:34:47 +08001120 wcid = sta ? &msta->wcid : NULL;
1121
1122 tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_WTBL, sizeof(struct tlv));
1123 wtbl_hdr = mt76_connac_mcu_alloc_wtbl_req(&dev->mt76, &msta->wcid,
1124 WTBL_RESET_AND_SET, tlv,
1125 &skb);
1126 if (IS_ERR(wtbl_hdr))
1127 return PTR_ERR(wtbl_hdr);
1128
1129 mt76_connac_mcu_wtbl_generic_tlv(&dev->mt76, skb, vif, sta, tlv,
1130 wtbl_hdr);
1131 mt76_connac_mcu_wtbl_hdr_trans_tlv(skb, vif, wcid, tlv, wtbl_hdr);
1132 if (sta)
1133 mt76_connac_mcu_wtbl_ht_tlv(&dev->mt76, skb, sta, tlv,
1134 wtbl_hdr, mvif->cap.ldpc);
1135
1136 return 0;
1137}
1138#endif
1139
1140static inline bool
developer7800b8d2022-06-23 22:15:56 +08001141besra_is_ebf_supported(struct besra_phy *phy, struct ieee80211_vif *vif,
developerb11a5392022-03-31 00:34:47 +08001142 struct ieee80211_sta *sta, bool bfee)
1143{
developer7800b8d2022-06-23 22:15:56 +08001144 struct besra_vif *mvif = (struct besra_vif *)vif->drv_priv;
developerb11a5392022-03-31 00:34:47 +08001145 int tx_ant = hweight8(phy->mt76->chainmask) - 1;
1146
1147 if (vif->type != NL80211_IFTYPE_STATION &&
1148 vif->type != NL80211_IFTYPE_AP)
1149 return false;
1150
1151 if (!bfee && tx_ant < 2)
1152 return false;
1153
1154 if (sta->he_cap.has_he) {
1155 struct ieee80211_he_cap_elem *pe = &sta->he_cap.he_cap_elem;
1156
1157 if (bfee)
1158 return mvif->cap.he_su_ebfee &&
1159 HE_PHY(CAP3_SU_BEAMFORMER, pe->phy_cap_info[3]);
1160 else
1161 return mvif->cap.he_su_ebfer &&
1162 HE_PHY(CAP4_SU_BEAMFORMEE, pe->phy_cap_info[4]);
1163 }
1164
1165 if (sta->vht_cap.vht_supported) {
1166 u32 cap = sta->vht_cap.cap;
1167
1168 if (bfee)
1169 return mvif->cap.vht_su_ebfee &&
1170 (cap & IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE);
1171 else
1172 return mvif->cap.vht_su_ebfer &&
1173 (cap & IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE);
1174 }
1175
1176 return false;
1177}
1178
1179static void
developer7800b8d2022-06-23 22:15:56 +08001180besra_mcu_sta_sounding_rate(struct sta_rec_bf *bf)
developerb11a5392022-03-31 00:34:47 +08001181{
1182 bf->sounding_phy = MT_PHY_TYPE_OFDM;
1183 bf->ndp_rate = 0; /* mcs0 */
developer7800b8d2022-06-23 22:15:56 +08001184 bf->ndpa_rate = BESRA_CFEND_RATE_DEFAULT; /* ofdm 24m */
1185 bf->rept_poll_rate = BESRA_CFEND_RATE_DEFAULT; /* ofdm 24m */
developerb11a5392022-03-31 00:34:47 +08001186}
1187
1188static void
developer7800b8d2022-06-23 22:15:56 +08001189besra_mcu_sta_bfer_ht(struct ieee80211_sta *sta, struct besra_phy *phy,
developerb11a5392022-03-31 00:34:47 +08001190 struct sta_rec_bf *bf)
1191{
1192 struct ieee80211_mcs_info *mcs = &sta->ht_cap.mcs;
1193 u8 n = 0;
1194
1195 bf->tx_mode = MT_PHY_TYPE_HT;
1196
1197 if ((mcs->tx_params & IEEE80211_HT_MCS_TX_RX_DIFF) &&
1198 (mcs->tx_params & IEEE80211_HT_MCS_TX_DEFINED))
1199 n = FIELD_GET(IEEE80211_HT_MCS_TX_MAX_STREAMS_MASK,
1200 mcs->tx_params);
1201 else if (mcs->rx_mask[3])
1202 n = 3;
1203 else if (mcs->rx_mask[2])
1204 n = 2;
1205 else if (mcs->rx_mask[1])
1206 n = 1;
1207
1208 bf->nrow = hweight8(phy->mt76->chainmask) - 1;
1209 bf->ncol = min_t(u8, bf->nrow, n);
1210 bf->ibf_ncol = n;
1211}
1212
1213static void
developer7800b8d2022-06-23 22:15:56 +08001214besra_mcu_sta_bfer_vht(struct ieee80211_sta *sta, struct besra_phy *phy,
developerb11a5392022-03-31 00:34:47 +08001215 struct sta_rec_bf *bf, bool explicit)
1216{
1217 struct ieee80211_sta_vht_cap *pc = &sta->vht_cap;
1218 struct ieee80211_sta_vht_cap *vc = &phy->mt76->sband_5g.sband.vht_cap;
1219 u16 mcs_map = le16_to_cpu(pc->vht_mcs.rx_mcs_map);
developer7800b8d2022-06-23 22:15:56 +08001220 u8 nss_mcs = besra_mcu_get_sta_nss(mcs_map);
developerb11a5392022-03-31 00:34:47 +08001221 u8 tx_ant = hweight8(phy->mt76->chainmask) - 1;
1222
1223 bf->tx_mode = MT_PHY_TYPE_VHT;
1224
1225 if (explicit) {
1226 u8 sts, snd_dim;
1227
developer7800b8d2022-06-23 22:15:56 +08001228 besra_mcu_sta_sounding_rate(bf);
developerb11a5392022-03-31 00:34:47 +08001229
1230 sts = FIELD_GET(IEEE80211_VHT_CAP_BEAMFORMEE_STS_MASK,
1231 pc->cap);
1232 snd_dim = FIELD_GET(IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_MASK,
1233 vc->cap);
1234 bf->nrow = min_t(u8, min_t(u8, snd_dim, sts), tx_ant);
1235 bf->ncol = min_t(u8, nss_mcs, bf->nrow);
1236 bf->ibf_ncol = bf->ncol;
1237
1238 if (sta->bandwidth == IEEE80211_STA_RX_BW_160)
1239 bf->nrow = 1;
1240 } else {
1241 bf->nrow = tx_ant;
1242 bf->ncol = min_t(u8, nss_mcs, bf->nrow);
1243 bf->ibf_ncol = nss_mcs;
1244
1245 if (sta->bandwidth == IEEE80211_STA_RX_BW_160)
1246 bf->ibf_nrow = 1;
1247 }
1248}
1249
1250static void
developer7800b8d2022-06-23 22:15:56 +08001251besra_mcu_sta_bfer_he(struct ieee80211_sta *sta, struct ieee80211_vif *vif,
1252 struct besra_phy *phy, struct sta_rec_bf *bf)
developerb11a5392022-03-31 00:34:47 +08001253{
1254 struct ieee80211_sta_he_cap *pc = &sta->he_cap;
1255 struct ieee80211_he_cap_elem *pe = &pc->he_cap_elem;
1256 const struct ieee80211_sta_he_cap *vc =
1257 mt76_connac_get_he_phy_cap(phy->mt76, vif);
1258 const struct ieee80211_he_cap_elem *ve = &vc->he_cap_elem;
1259 u16 mcs_map = le16_to_cpu(pc->he_mcs_nss_supp.rx_mcs_80);
developer7800b8d2022-06-23 22:15:56 +08001260 u8 nss_mcs = besra_mcu_get_sta_nss(mcs_map);
developerb11a5392022-03-31 00:34:47 +08001261 u8 snd_dim, sts;
1262
1263 bf->tx_mode = MT_PHY_TYPE_HE_SU;
1264
developer7800b8d2022-06-23 22:15:56 +08001265 besra_mcu_sta_sounding_rate(bf);
developerb11a5392022-03-31 00:34:47 +08001266
1267 bf->trigger_su = HE_PHY(CAP6_TRIG_SU_BEAMFORMING_FB,
1268 pe->phy_cap_info[6]);
1269 bf->trigger_mu = HE_PHY(CAP6_TRIG_MU_BEAMFORMING_PARTIAL_BW_FB,
1270 pe->phy_cap_info[6]);
1271 snd_dim = HE_PHY(CAP5_BEAMFORMEE_NUM_SND_DIM_UNDER_80MHZ_MASK,
1272 ve->phy_cap_info[5]);
1273 sts = HE_PHY(CAP4_BEAMFORMEE_MAX_STS_UNDER_80MHZ_MASK,
1274 pe->phy_cap_info[4]);
1275 bf->nrow = min_t(u8, snd_dim, sts);
1276 bf->ncol = min_t(u8, nss_mcs, bf->nrow);
1277 bf->ibf_ncol = bf->ncol;
1278
1279 if (sta->bandwidth != IEEE80211_STA_RX_BW_160)
1280 return;
1281
1282 /* go over for 160MHz and 80p80 */
1283 if (pe->phy_cap_info[0] &
1284 IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_160MHZ_IN_5G) {
1285 mcs_map = le16_to_cpu(pc->he_mcs_nss_supp.rx_mcs_160);
developer7800b8d2022-06-23 22:15:56 +08001286 nss_mcs = besra_mcu_get_sta_nss(mcs_map);
developerb11a5392022-03-31 00:34:47 +08001287
1288 bf->ncol_bw160 = nss_mcs;
1289 }
1290
1291 if (pe->phy_cap_info[0] &
1292 IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_80PLUS80_MHZ_IN_5G) {
1293 mcs_map = le16_to_cpu(pc->he_mcs_nss_supp.rx_mcs_80p80);
developer7800b8d2022-06-23 22:15:56 +08001294 nss_mcs = besra_mcu_get_sta_nss(mcs_map);
developerb11a5392022-03-31 00:34:47 +08001295
1296 if (bf->ncol_bw160)
1297 bf->ncol_bw160 = min_t(u8, bf->ncol_bw160, nss_mcs);
1298 else
1299 bf->ncol_bw160 = nss_mcs;
1300 }
1301
1302 snd_dim = HE_PHY(CAP5_BEAMFORMEE_NUM_SND_DIM_ABOVE_80MHZ_MASK,
1303 ve->phy_cap_info[5]);
1304 sts = HE_PHY(CAP4_BEAMFORMEE_MAX_STS_ABOVE_80MHZ_MASK,
1305 pe->phy_cap_info[4]);
1306
1307 bf->nrow_bw160 = min_t(int, snd_dim, sts);
1308}
1309
1310static void
developer7800b8d2022-06-23 22:15:56 +08001311besra_mcu_sta_bfer_tlv(struct besra_dev *dev, struct sk_buff *skb,
developerb11a5392022-03-31 00:34:47 +08001312 struct ieee80211_vif *vif, struct ieee80211_sta *sta)
1313{
developer7800b8d2022-06-23 22:15:56 +08001314 struct besra_vif *mvif = (struct besra_vif *)vif->drv_priv;
1315 struct besra_phy *phy = mvif->phy;
developerb11a5392022-03-31 00:34:47 +08001316 int tx_ant = hweight8(phy->mt76->chainmask) - 1;
1317 struct sta_rec_bf *bf;
1318 struct tlv *tlv;
1319 const u8 matrix[4][4] = {
1320 {0, 0, 0, 0},
1321 {1, 1, 0, 0}, /* 2x1, 2x2, 2x3, 2x4 */
1322 {2, 4, 4, 0}, /* 3x1, 3x2, 3x3, 3x4 */
1323 {3, 5, 6, 0} /* 4x1, 4x2, 4x3, 4x4 */
1324 };
1325 bool ebf;
1326
1327 if (!(sta->ht_cap.ht_supported || sta->he_cap.has_he))
1328 return;
1329
developer7800b8d2022-06-23 22:15:56 +08001330 ebf = besra_is_ebf_supported(phy, vif, sta, false);
developerb11a5392022-03-31 00:34:47 +08001331 if (!ebf && !dev->ibf)
1332 return;
1333
1334 tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_BF, sizeof(*bf));
1335 bf = (struct sta_rec_bf *)tlv;
1336
1337 /* he: eBF only, in accordance with spec
1338 * vht: support eBF and iBF
1339 * ht: iBF only, since mac80211 lacks of eBF support
1340 */
1341 if (sta->he_cap.has_he && ebf)
developer7800b8d2022-06-23 22:15:56 +08001342 besra_mcu_sta_bfer_he(sta, vif, phy, bf);
developerb11a5392022-03-31 00:34:47 +08001343 else if (sta->vht_cap.vht_supported)
developer7800b8d2022-06-23 22:15:56 +08001344 besra_mcu_sta_bfer_vht(sta, phy, bf, ebf);
developerb11a5392022-03-31 00:34:47 +08001345 else if (sta->ht_cap.ht_supported)
developer7800b8d2022-06-23 22:15:56 +08001346 besra_mcu_sta_bfer_ht(sta, phy, bf);
developerb11a5392022-03-31 00:34:47 +08001347 else
1348 return;
1349
1350 bf->bf_cap = ebf ? ebf : dev->ibf << 1;
1351 bf->bw = sta->bandwidth;
1352 bf->ibf_dbw = sta->bandwidth;
1353 bf->ibf_nrow = tx_ant;
1354
1355 if (!ebf && sta->bandwidth <= IEEE80211_STA_RX_BW_40 && !bf->ncol)
1356 bf->ibf_timeout = 0x48;
1357 else
1358 bf->ibf_timeout = 0x18;
1359
1360 if (ebf && bf->nrow != tx_ant)
1361 bf->mem_20m = matrix[tx_ant][bf->ncol];
1362 else
1363 bf->mem_20m = matrix[bf->nrow][bf->ncol];
1364
1365 switch (sta->bandwidth) {
1366 case IEEE80211_STA_RX_BW_160:
1367 case IEEE80211_STA_RX_BW_80:
1368 bf->mem_total = bf->mem_20m * 2;
1369 break;
1370 case IEEE80211_STA_RX_BW_40:
1371 bf->mem_total = bf->mem_20m;
1372 break;
1373 case IEEE80211_STA_RX_BW_20:
1374 default:
1375 break;
1376 }
1377}
1378
1379static void
developer7800b8d2022-06-23 22:15:56 +08001380besra_mcu_sta_bfee_tlv(struct besra_dev *dev, struct sk_buff *skb,
developerb11a5392022-03-31 00:34:47 +08001381 struct ieee80211_vif *vif, struct ieee80211_sta *sta)
1382{
developer7800b8d2022-06-23 22:15:56 +08001383 struct besra_vif *mvif = (struct besra_vif *)vif->drv_priv;
1384 struct besra_phy *phy = mvif->phy;
developerb11a5392022-03-31 00:34:47 +08001385 int tx_ant = hweight8(phy->mt76->chainmask) - 1;
1386 struct sta_rec_bfee *bfee;
1387 struct tlv *tlv;
1388 u8 nrow = 0;
1389
1390 if (!(sta->vht_cap.vht_supported || sta->he_cap.has_he))
1391 return;
1392
developer7800b8d2022-06-23 22:15:56 +08001393 if (!besra_is_ebf_supported(phy, vif, sta, true))
developerb11a5392022-03-31 00:34:47 +08001394 return;
1395
1396 tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_BFEE, sizeof(*bfee));
1397 bfee = (struct sta_rec_bfee *)tlv;
1398
1399 if (sta->he_cap.has_he) {
1400 struct ieee80211_he_cap_elem *pe = &sta->he_cap.he_cap_elem;
1401
1402 nrow = HE_PHY(CAP5_BEAMFORMEE_NUM_SND_DIM_UNDER_80MHZ_MASK,
1403 pe->phy_cap_info[5]);
1404 } else if (sta->vht_cap.vht_supported) {
1405 struct ieee80211_sta_vht_cap *pc = &sta->vht_cap;
1406
1407 nrow = FIELD_GET(IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_MASK,
1408 pc->cap);
1409 }
1410
1411 /* reply with identity matrix to avoid 2x2 BF negative gain */
1412 bfee->fb_identity_matrix = (nrow == 1 && tx_ant == 2);
1413}
1414
1415static void
developer7800b8d2022-06-23 22:15:56 +08001416besra_mcu_sta_phy_tlv(struct besra_dev *dev, struct sk_buff *skb,
developerb11a5392022-03-31 00:34:47 +08001417 struct ieee80211_vif *vif, struct ieee80211_sta *sta)
1418{
developer7800b8d2022-06-23 22:15:56 +08001419 struct besra_vif *mvif = (struct besra_vif *)vif->drv_priv;
developerb11a5392022-03-31 00:34:47 +08001420 struct cfg80211_chan_def *chandef = &mvif->phy->mt76->chandef;
1421 enum nl80211_band band = chandef->chan->band;
1422 struct mt76_phy *mphy = &dev->mphy;
1423 struct sta_rec_phy *phy;
1424 struct tlv *tlv;
1425 u8 af, mm;
1426
1427 if (!sta->ht_cap.ht_supported && !sta->he_6ghz_capa.capa)
1428 return;
1429
1430 tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_PHY, sizeof(*phy));
1431
1432 phy = (struct sta_rec_phy *)tlv;
1433 phy->phy_type = mt76_connac_get_phy_mode_v2(mphy, vif, band, sta);
1434 phy->basic_rate = cpu_to_le16((u16)vif->bss_conf.basic_rates);
1435 if (sta->ht_cap.ht_supported) {
1436 af = sta->ht_cap.ampdu_factor;
1437 mm = sta->ht_cap.ampdu_density;
1438 } else {
1439 af = le16_get_bits(sta->he_6ghz_capa.capa,
1440 IEEE80211_HE_6GHZ_CAP_MAX_AMPDU_LEN_EXP);
1441 mm = le16_get_bits(sta->he_6ghz_capa.capa,
1442 IEEE80211_HE_6GHZ_CAP_MIN_MPDU_START);
1443 }
1444
1445 phy->ampdu = FIELD_PREP(IEEE80211_HT_AMPDU_PARM_FACTOR, af) |
1446 FIELD_PREP(IEEE80211_HT_AMPDU_PARM_DENSITY, mm);
1447}
1448
developer66cd2092022-05-10 15:43:01 +08001449static void
developer7800b8d2022-06-23 22:15:56 +08001450besra_mcu_sta_hdr_trans_tlv(struct besra_dev *dev, struct sk_buff *skb,
developer66cd2092022-05-10 15:43:01 +08001451 struct ieee80211_vif *vif, struct ieee80211_sta *sta)
1452{
1453 struct sta_rec_hdr_trans *hdr_trans;
1454 struct tlv *tlv;
1455
1456 tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_HDR_TRANS, sizeof(*hdr_trans));
1457 hdr_trans = (struct sta_rec_hdr_trans*) tlv;
1458 hdr_trans->dis_rx_hdr_tran = 0;
1459 if (vif->type == NL80211_IFTYPE_STATION)
1460 hdr_trans->to_ds = true;
1461 else
1462 hdr_trans->from_ds = true;
1463
1464 struct mt76_wcid *wcid;
1465 wcid = (struct mt76_wcid *)sta->drv_priv;
1466 if (!wcid)
1467 return;
1468
1469 if (test_bit(MT_WCID_FLAG_4ADDR, &wcid->flags)) {
1470 hdr_trans->to_ds = true;
1471 hdr_trans->from_ds = true;
1472 }
1473}
1474
developerb11a5392022-03-31 00:34:47 +08001475static enum mcu_mmps_mode
developer7800b8d2022-06-23 22:15:56 +08001476besra_mcu_get_mmps_mode(enum ieee80211_smps_mode smps)
developerb11a5392022-03-31 00:34:47 +08001477{
1478 switch (smps) {
1479 case IEEE80211_SMPS_OFF:
1480 return MCU_MMPS_DISABLE;
1481 case IEEE80211_SMPS_STATIC:
1482 return MCU_MMPS_STATIC;
1483 case IEEE80211_SMPS_DYNAMIC:
1484 return MCU_MMPS_DYNAMIC;
1485 default:
1486 return MCU_MMPS_DISABLE;
1487 }
1488}
1489
developer7800b8d2022-06-23 22:15:56 +08001490int besra_mcu_set_fixed_rate_ctrl(struct besra_dev *dev,
developerb11a5392022-03-31 00:34:47 +08001491 struct ieee80211_vif *vif,
1492 struct ieee80211_sta *sta,
1493 void *data, u32 field)
1494{
developer7800b8d2022-06-23 22:15:56 +08001495 struct besra_vif *mvif = (struct besra_vif *)vif->drv_priv;
1496 struct besra_sta *msta = (struct besra_sta *)sta->drv_priv;
developerb11a5392022-03-31 00:34:47 +08001497 struct sta_phy *phy = data;
1498 struct sta_rec_ra_fixed *ra;
1499 struct sk_buff *skb;
1500 struct tlv *tlv;
1501
1502 skb = mt76_connac_mcu_alloc_sta_req(&dev->mt76, &mvif->mt76,
1503 &msta->wcid);
1504 if (IS_ERR(skb))
1505 return PTR_ERR(skb);
1506
1507 tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_RA_UPDATE, sizeof(*ra));
1508 ra = (struct sta_rec_ra_fixed *)tlv;
1509
1510 switch (field) {
1511 case RATE_PARAM_AUTO:
1512 break;
1513 case RATE_PARAM_FIXED:
1514 case RATE_PARAM_FIXED_MCS:
1515 case RATE_PARAM_FIXED_GI:
1516 case RATE_PARAM_FIXED_HE_LTF:
1517 if (phy)
1518 ra->phy = *phy;
1519 break;
1520 case RATE_PARAM_MMPS_UPDATE:
developer7800b8d2022-06-23 22:15:56 +08001521 ra->mmps_mode = besra_mcu_get_mmps_mode(sta->smps_mode);
developerb11a5392022-03-31 00:34:47 +08001522 break;
1523 default:
1524 break;
1525 }
1526 ra->field = cpu_to_le32(field);
1527
1528 return mt76_mcu_skb_send_msg(&dev->mt76, skb,
1529 MCU_WMWA_UNI_CMD(STA_REC_UPDATE), true);
1530}
1531
developer7800b8d2022-06-23 22:15:56 +08001532int besra_mcu_add_smps(struct besra_dev *dev, struct ieee80211_vif *vif,
developerb11a5392022-03-31 00:34:47 +08001533 struct ieee80211_sta *sta)
1534{
1535#if 0
developer7800b8d2022-06-23 22:15:56 +08001536 struct besra_vif *mvif = (struct besra_vif *)vif->drv_priv;
1537 struct besra_sta *msta = (struct besra_sta *)sta->drv_priv;
developerb11a5392022-03-31 00:34:47 +08001538 struct wtbl_req_hdr *wtbl_hdr;
1539 struct tlv *sta_wtbl;
1540 struct sk_buff *skb;
1541 int ret;
1542
1543 skb = mt76_connac_mcu_alloc_sta_req(&dev->mt76, &mvif->mt76,
1544 &msta->wcid);
1545 if (IS_ERR(skb))
1546 return PTR_ERR(skb);
1547
1548 sta_wtbl = mt76_connac_mcu_add_tlv(skb, STA_REC_WTBL,
1549 sizeof(struct tlv));
1550 wtbl_hdr = mt76_connac_mcu_alloc_wtbl_req(&dev->mt76, &msta->wcid,
1551 WTBL_SET, sta_wtbl, &skb);
1552 if (IS_ERR(wtbl_hdr))
1553 return PTR_ERR(wtbl_hdr);
1554
1555 mt76_connac_mcu_wtbl_smps_tlv(skb, sta, sta_wtbl, wtbl_hdr);
1556
1557 ret = mt76_mcu_skb_send_msg(&dev->mt76, skb,
1558 MCU_EXT_CMD(STA_REC_UPDATE), true);
1559 if (ret)
1560 return ret;
1561#endif
1562 printk("Remove smps tag in wtbl. Todo: check it is corrected or not");
1563
developer7800b8d2022-06-23 22:15:56 +08001564 return besra_mcu_set_fixed_rate_ctrl(dev, vif, sta, NULL,
developerb11a5392022-03-31 00:34:47 +08001565 RATE_PARAM_MMPS_UPDATE);
1566}
1567
1568static int
developer7800b8d2022-06-23 22:15:56 +08001569besra_mcu_add_rate_ctrl_fixed(struct besra_dev *dev,
developerb11a5392022-03-31 00:34:47 +08001570 struct ieee80211_vif *vif,
1571 struct ieee80211_sta *sta)
1572{
developer7800b8d2022-06-23 22:15:56 +08001573 struct besra_vif *mvif = (struct besra_vif *)vif->drv_priv;
developerb11a5392022-03-31 00:34:47 +08001574 struct cfg80211_chan_def *chandef = &mvif->phy->mt76->chandef;
1575 struct cfg80211_bitrate_mask *mask = &mvif->bitrate_mask;
1576 enum nl80211_band band = chandef->chan->band;
1577 struct sta_phy phy = {};
1578 int ret, nrates = 0;
1579
1580#define __sta_phy_bitrate_mask_check(_mcs, _gi, _he) \
1581 do { \
1582 u8 i, gi = mask->control[band]._gi; \
1583 gi = (_he) ? gi : gi == NL80211_TXRATE_FORCE_SGI; \
1584 for (i = 0; i <= sta->bandwidth; i++) { \
1585 phy.sgi |= gi << (i << (_he)); \
1586 phy.he_ltf |= mask->control[band].he_ltf << (i << (_he));\
1587 } \
1588 for (i = 0; i < ARRAY_SIZE(mask->control[band]._mcs); i++) { \
1589 if (!mask->control[band]._mcs[i]) \
1590 continue; \
1591 nrates += hweight16(mask->control[band]._mcs[i]); \
1592 phy.mcs = ffs(mask->control[band]._mcs[i]) - 1; \
1593 } \
1594 } while (0)
1595
1596 if (sta->he_cap.has_he) {
1597 __sta_phy_bitrate_mask_check(he_mcs, he_gi, 1);
1598 } else if (sta->vht_cap.vht_supported) {
1599 __sta_phy_bitrate_mask_check(vht_mcs, gi, 0);
1600 } else if (sta->ht_cap.ht_supported) {
1601 __sta_phy_bitrate_mask_check(ht_mcs, gi, 0);
1602 } else {
1603 nrates = hweight32(mask->control[band].legacy);
1604 phy.mcs = ffs(mask->control[band].legacy) - 1;
1605 }
1606#undef __sta_phy_bitrate_mask_check
1607
1608 /* fall back to auto rate control */
1609 if (mask->control[band].gi == NL80211_TXRATE_DEFAULT_GI &&
1610 mask->control[band].he_gi == GENMASK(7, 0) &&
1611 mask->control[band].he_ltf == GENMASK(7, 0) &&
1612 nrates != 1)
1613 return 0;
1614
1615 /* fixed single rate */
1616 if (nrates == 1) {
developer7800b8d2022-06-23 22:15:56 +08001617 ret = besra_mcu_set_fixed_rate_ctrl(dev, vif, sta, &phy,
developerb11a5392022-03-31 00:34:47 +08001618 RATE_PARAM_FIXED_MCS);
1619 if (ret)
1620 return ret;
1621 }
1622
1623 /* fixed GI */
1624 if (mask->control[band].gi != NL80211_TXRATE_DEFAULT_GI ||
1625 mask->control[band].he_gi != GENMASK(7, 0)) {
developer7800b8d2022-06-23 22:15:56 +08001626 struct besra_sta *msta = (struct besra_sta *)sta->drv_priv;
developerb11a5392022-03-31 00:34:47 +08001627 u32 addr;
1628
1629 /* firmware updates only TXCMD but doesn't take WTBL into
1630 * account, so driver should update here to reflect the
1631 * actual txrate hardware sends out.
1632 */
developer7800b8d2022-06-23 22:15:56 +08001633 addr = besra_mac_wtbl_lmac_addr(dev, msta->wcid.idx, 7);
developerb11a5392022-03-31 00:34:47 +08001634 if (sta->he_cap.has_he)
1635 mt76_rmw_field(dev, addr, GENMASK(31, 24), phy.sgi);
1636 else
1637 mt76_rmw_field(dev, addr, GENMASK(15, 12), phy.sgi);
1638
developer7800b8d2022-06-23 22:15:56 +08001639 ret = besra_mcu_set_fixed_rate_ctrl(dev, vif, sta, &phy,
developerb11a5392022-03-31 00:34:47 +08001640 RATE_PARAM_FIXED_GI);
1641 if (ret)
1642 return ret;
1643 }
1644
1645 /* fixed HE_LTF */
1646 if (mask->control[band].he_ltf != GENMASK(7, 0)) {
developer7800b8d2022-06-23 22:15:56 +08001647 ret = besra_mcu_set_fixed_rate_ctrl(dev, vif, sta, &phy,
developerb11a5392022-03-31 00:34:47 +08001648 RATE_PARAM_FIXED_HE_LTF);
1649 if (ret)
1650 return ret;
1651 }
1652
1653 return 0;
1654}
1655
1656static void
developer7800b8d2022-06-23 22:15:56 +08001657besra_mcu_sta_rate_ctrl_tlv(struct sk_buff *skb, struct besra_dev *dev,
developerb11a5392022-03-31 00:34:47 +08001658 struct ieee80211_vif *vif, struct ieee80211_sta *sta)
1659{
developer7800b8d2022-06-23 22:15:56 +08001660 struct besra_vif *mvif = (struct besra_vif *)vif->drv_priv;
developerb11a5392022-03-31 00:34:47 +08001661 struct mt76_phy *mphy = mvif->phy->mt76;
1662 struct cfg80211_chan_def *chandef = &mphy->chandef;
1663 struct cfg80211_bitrate_mask *mask = &mvif->bitrate_mask;
1664 enum nl80211_band band = chandef->chan->band;
1665 struct sta_rec_ra *ra;
1666 struct tlv *tlv;
1667 u32 supp_rate = sta->supp_rates[band];
1668 u32 cap = sta->wme ? STA_CAP_WMM : 0;
1669
1670 tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_RA, sizeof(*ra));
1671 ra = (struct sta_rec_ra *)tlv;
1672
1673 ra->valid = true;
1674 ra->auto_rate = true;
1675 ra->phy_mode = mt76_connac_get_phy_mode(mphy, vif, band, sta);
1676 ra->channel = chandef->chan->hw_value;
1677 ra->bw = sta->bandwidth;
1678 ra->phy.bw = sta->bandwidth;
developer7800b8d2022-06-23 22:15:56 +08001679 ra->mmps_mode = besra_mcu_get_mmps_mode(sta->smps_mode);
developerb11a5392022-03-31 00:34:47 +08001680
1681 if (supp_rate) {
1682 supp_rate &= mask->control[band].legacy;
1683 ra->rate_len = hweight32(supp_rate);
1684
1685 if (band == NL80211_BAND_2GHZ) {
1686 ra->supp_mode = MODE_CCK;
1687 ra->supp_cck_rate = supp_rate & GENMASK(3, 0);
1688
1689 if (ra->rate_len > 4) {
1690 ra->supp_mode |= MODE_OFDM;
1691 ra->supp_ofdm_rate = supp_rate >> 4;
1692 }
1693 } else {
1694 ra->supp_mode = MODE_OFDM;
1695 ra->supp_ofdm_rate = supp_rate;
1696 }
1697 }
1698
1699 if (sta->ht_cap.ht_supported) {
1700 ra->supp_mode |= MODE_HT;
1701 ra->af = sta->ht_cap.ampdu_factor;
1702 ra->ht_gf = !!(sta->ht_cap.cap & IEEE80211_HT_CAP_GRN_FLD);
1703
1704 cap |= STA_CAP_HT;
1705 if (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20)
1706 cap |= STA_CAP_SGI_20;
1707 if (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40)
1708 cap |= STA_CAP_SGI_40;
1709 if (sta->ht_cap.cap & IEEE80211_HT_CAP_TX_STBC)
1710 cap |= STA_CAP_TX_STBC;
1711 if (sta->ht_cap.cap & IEEE80211_HT_CAP_RX_STBC)
1712 cap |= STA_CAP_RX_STBC;
developer66cd2092022-05-10 15:43:01 +08001713 if (mvif->cap.ht_ldpc &&
developerb11a5392022-03-31 00:34:47 +08001714 (sta->ht_cap.cap & IEEE80211_HT_CAP_LDPC_CODING))
1715 cap |= STA_CAP_LDPC;
1716
developer7800b8d2022-06-23 22:15:56 +08001717 besra_mcu_set_sta_ht_mcs(sta, ra->ht_mcs,
developerb11a5392022-03-31 00:34:47 +08001718 mask->control[band].ht_mcs);
1719 ra->supp_ht_mcs = *(__le32 *)ra->ht_mcs;
1720 }
1721
1722 if (sta->vht_cap.vht_supported) {
1723 u8 af;
1724
1725 ra->supp_mode |= MODE_VHT;
1726 af = FIELD_GET(IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK,
1727 sta->vht_cap.cap);
1728 ra->af = max_t(u8, ra->af, af);
1729
1730 cap |= STA_CAP_VHT;
1731 if (sta->vht_cap.cap & IEEE80211_VHT_CAP_SHORT_GI_80)
1732 cap |= STA_CAP_VHT_SGI_80;
1733 if (sta->vht_cap.cap & IEEE80211_VHT_CAP_SHORT_GI_160)
1734 cap |= STA_CAP_VHT_SGI_160;
1735 if (sta->vht_cap.cap & IEEE80211_VHT_CAP_TXSTBC)
1736 cap |= STA_CAP_VHT_TX_STBC;
1737 if (sta->vht_cap.cap & IEEE80211_VHT_CAP_RXSTBC_1)
1738 cap |= STA_CAP_VHT_RX_STBC;
developer66cd2092022-05-10 15:43:01 +08001739 if (mvif->cap.vht_ldpc &&
developerb11a5392022-03-31 00:34:47 +08001740 (sta->vht_cap.cap & IEEE80211_VHT_CAP_RXLDPC))
1741 cap |= STA_CAP_VHT_LDPC;
1742
developer7800b8d2022-06-23 22:15:56 +08001743 besra_mcu_set_sta_vht_mcs(sta, ra->supp_vht_mcs,
developerb11a5392022-03-31 00:34:47 +08001744 mask->control[band].vht_mcs);
1745 }
1746
1747 if (sta->he_cap.has_he) {
1748 ra->supp_mode |= MODE_HE;
1749 cap |= STA_CAP_HE;
1750
1751 if (sta->he_6ghz_capa.capa)
1752 ra->af = le16_get_bits(sta->he_6ghz_capa.capa,
1753 IEEE80211_HE_6GHZ_CAP_MAX_AMPDU_LEN_EXP);
1754 }
1755
1756 ra->sta_cap = cpu_to_le32(cap);
1757}
1758
developer7800b8d2022-06-23 22:15:56 +08001759int besra_mcu_add_rate_ctrl(struct besra_dev *dev, struct ieee80211_vif *vif,
developerb11a5392022-03-31 00:34:47 +08001760 struct ieee80211_sta *sta, bool changed)
1761{
developer7800b8d2022-06-23 22:15:56 +08001762 struct besra_vif *mvif = (struct besra_vif *)vif->drv_priv;
1763 struct besra_sta *msta = (struct besra_sta *)sta->drv_priv;
developerb11a5392022-03-31 00:34:47 +08001764 struct sk_buff *skb;
1765 int ret;
1766
1767 skb = mt76_connac_mcu_alloc_sta_req(&dev->mt76, &mvif->mt76,
1768 &msta->wcid);
1769 if (IS_ERR(skb))
1770 return PTR_ERR(skb);
1771
1772 /* firmware rc algorithm refers to sta_rec_he for HE control.
1773 * once dev->rc_work changes the settings driver should also
1774 * update sta_rec_he here.
1775 */
developer66cd2092022-05-10 15:43:01 +08001776 if (changed)
developer7800b8d2022-06-23 22:15:56 +08001777 besra_mcu_sta_he_tlv(skb, sta, vif);
developerb11a5392022-03-31 00:34:47 +08001778
1779 /* sta_rec_ra accommodates BW, NSS and only MCS range format
1780 * i.e 0-{7,8,9} for VHT.
1781 */
developer7800b8d2022-06-23 22:15:56 +08001782 besra_mcu_sta_rate_ctrl_tlv(skb, dev, vif, sta);
developerb11a5392022-03-31 00:34:47 +08001783
1784 ret = mt76_mcu_skb_send_msg(&dev->mt76, skb,
1785 MCU_WMWA_UNI_CMD(STA_REC_UPDATE), true);
1786 if (ret)
1787 return ret;
1788
1789 /* sta_rec_ra_fixed accommodates single rate, (HE)GI and HE_LTE,
1790 * and updates as peer fixed rate parameters, which overrides
1791 * sta_rec_ra and firmware rate control algorithm.
1792 */
developer7800b8d2022-06-23 22:15:56 +08001793 return besra_mcu_add_rate_ctrl_fixed(dev, vif, sta);
developerb11a5392022-03-31 00:34:47 +08001794}
1795
1796static int
developer7800b8d2022-06-23 22:15:56 +08001797besra_mcu_add_group(struct besra_dev *dev, struct ieee80211_vif *vif,
developerb11a5392022-03-31 00:34:47 +08001798 struct ieee80211_sta *sta)
1799{
1800#define MT_STA_BSS_GROUP 1
developer7800b8d2022-06-23 22:15:56 +08001801 struct besra_vif *mvif = (struct besra_vif *)vif->drv_priv;
1802 struct besra_sta *msta;
developerb11a5392022-03-31 00:34:47 +08001803 struct {
1804 /* fixed field */
1805 u8 __rsv1[4];
1806 /* TLV */
1807 __le16 tag;
1808 __le16 len;
1809 __le16 wlan_idx;
1810 u8 __rsv2[2];
1811 __le32 action;
1812 __le32 val;
1813 u8 __rsv3[8];
1814 } __packed req = {
1815 .tag = cpu_to_le16(UNI_VOW_DRR_CTRL),
1816 .len = cpu_to_le16(sizeof(req) - 4),
1817 .action = cpu_to_le32(MT_STA_BSS_GROUP),
1818 .val = cpu_to_le32(mvif->mt76.idx % 16),
1819 };
1820
developer7800b8d2022-06-23 22:15:56 +08001821 msta = sta ? (struct besra_sta *)sta->drv_priv : &mvif->sta;
developerb11a5392022-03-31 00:34:47 +08001822 req.wlan_idx = cpu_to_le16(msta->wcid.idx);
1823
1824 return mt76_mcu_send_msg(&dev->mt76, MCU_WM_UNI_CMD(VOW), &req,
1825 sizeof(req), true);
1826}
1827
developer7800b8d2022-06-23 22:15:56 +08001828int besra_mcu_add_sta(struct besra_dev *dev, struct ieee80211_vif *vif,
developerb11a5392022-03-31 00:34:47 +08001829 struct ieee80211_sta *sta, bool enable)
1830{
developer7800b8d2022-06-23 22:15:56 +08001831 struct besra_vif *mvif = (struct besra_vif *)vif->drv_priv;
1832 struct besra_sta *msta;
developerb11a5392022-03-31 00:34:47 +08001833 struct sk_buff *skb;
1834 int ret;
1835
developer7800b8d2022-06-23 22:15:56 +08001836 msta = sta ? (struct besra_sta *)sta->drv_priv : &mvif->sta;
developerb11a5392022-03-31 00:34:47 +08001837
1838 skb = mt76_connac_mcu_alloc_sta_req(&dev->mt76, &mvif->mt76,
1839 &msta->wcid);
1840 if (IS_ERR(skb))
1841 return PTR_ERR(skb);
1842
1843 /* starec basic */
1844 mt76_connac_mcu_sta_basic_tlv(skb, vif, sta, enable, true);
1845 if (!enable)
1846 goto out;
1847
1848 /* tag order is in accordance with firmware dependency. */
1849 if (sta) {
1850 /* starec phy */
1851 if (mt76_chip(&dev->mt76) != 0x7902)
developer7800b8d2022-06-23 22:15:56 +08001852 besra_mcu_sta_phy_tlv(dev, skb, vif, sta);
developerb11a5392022-03-31 00:34:47 +08001853 /* starec bfer */
developer7800b8d2022-06-23 22:15:56 +08001854 besra_mcu_sta_bfer_tlv(dev, skb, vif, sta);
developerb11a5392022-03-31 00:34:47 +08001855 /* starec ht */
developer7800b8d2022-06-23 22:15:56 +08001856 besra_mcu_sta_ht_tlv(skb, sta);
developerb11a5392022-03-31 00:34:47 +08001857 /* starec vht */
developer7800b8d2022-06-23 22:15:56 +08001858 besra_mcu_sta_vht_tlv(skb, sta);
developerb11a5392022-03-31 00:34:47 +08001859 /* starec uapsd */
1860 mt76_connac_mcu_sta_uapsd(skb, vif, sta);
1861 /* starec amsdu */
developer7800b8d2022-06-23 22:15:56 +08001862 besra_mcu_sta_amsdu_tlv(dev, skb, vif, sta);
developerb11a5392022-03-31 00:34:47 +08001863 /* starec he */
developer7800b8d2022-06-23 22:15:56 +08001864 besra_mcu_sta_he_tlv(skb, sta, vif);
developerb11a5392022-03-31 00:34:47 +08001865 /* starec he 6g*/
developer7800b8d2022-06-23 22:15:56 +08001866 besra_mcu_sta_he_6g_tlv(skb, sta, vif);
developerb11a5392022-03-31 00:34:47 +08001867 /* starec muru */
developer7800b8d2022-06-23 22:15:56 +08001868 besra_mcu_sta_muru_tlv(skb, sta, vif);
developerb11a5392022-03-31 00:34:47 +08001869 /* starec bfee */
developer7800b8d2022-06-23 22:15:56 +08001870 besra_mcu_sta_bfee_tlv(dev, skb, vif, sta);
developer66cd2092022-05-10 15:43:01 +08001871 /* starec hdr trans */
developer7800b8d2022-06-23 22:15:56 +08001872 besra_mcu_sta_hdr_trans_tlv(dev, skb, vif, sta);
developerb11a5392022-03-31 00:34:47 +08001873 }
1874
developer7800b8d2022-06-23 22:15:56 +08001875 ret = besra_mcu_add_group(dev, vif, sta);
developerb11a5392022-03-31 00:34:47 +08001876 if (ret) {
1877 dev_kfree_skb(skb);
1878 return ret;
1879 }
1880out:
1881 return mt76_mcu_skb_send_msg(&dev->mt76, skb,
1882 MCU_WMWA_UNI_CMD(STA_REC_UPDATE), true);
1883}
1884
1885static int
developer7800b8d2022-06-23 22:15:56 +08001886besra_mcu_sta_key_tlv(struct mt76_wcid *wcid,
developerb11a5392022-03-31 00:34:47 +08001887 struct mt76_connac_sta_key_conf *sta_key_conf,
1888 struct sk_buff *skb,
1889 struct ieee80211_key_conf *key,
1890 enum set_key_cmd cmd)
1891{
1892 struct uni_sta_rec_sec *sec;
1893 struct tlv *tlv;
1894
1895 tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_KEY_V2, sizeof(*sec));
1896 sec = (struct uni_sta_rec_sec *)tlv;
1897 sec->add = cmd;
1898
1899 if (cmd == SET_KEY) {
1900 struct uni_sec_key *sec_key;
1901 u8 cipher;
1902
1903 cipher = mt76_connac_mcu_get_cipher(key->cipher);
1904 if (cipher == MCU_CIPHER_NONE)
1905 return -EOPNOTSUPP;
1906
1907 sec_key = &sec->key[0];
1908 sec_key->cipher_len = sizeof(*sec_key);
1909
1910 if (cipher == MCU_CIPHER_BIP_CMAC_128) {
1911 sec_key->wlan_idx = cpu_to_le16(wcid->idx);
1912 sec_key->cipher_id = MCU_CIPHER_AES_CCMP;
1913 sec_key->key_id = sta_key_conf->keyidx;
1914 sec_key->key_len = 16;
1915 memcpy(sec_key->key, sta_key_conf->key, 16);
1916
1917 sec_key = &sec->key[1];
1918 sec_key->wlan_idx = cpu_to_le16(wcid->idx);
1919 sec_key->cipher_id = MCU_CIPHER_BIP_CMAC_128;
1920 sec_key->cipher_len = sizeof(*sec_key);
1921 sec_key->key_len = 16;
1922 memcpy(sec_key->key, key->key, 16);
1923 sec->n_cipher = 2;
1924 } else {
1925 sec_key->wlan_idx = cpu_to_le16(wcid->idx);
1926 sec_key->cipher_id = cipher;
1927 sec_key->key_id = key->keyidx;
1928 sec_key->key_len = key->keylen;
1929 memcpy(sec_key->key, key->key, key->keylen);
1930
1931 if (cipher == MCU_CIPHER_TKIP) {
1932 /* Rx/Tx MIC keys are swapped */
1933 memcpy(sec_key->key + 16, key->key + 24, 8);
1934 memcpy(sec_key->key + 24, key->key + 16, 8);
1935 }
1936
1937 /* store key_conf for BIP batch update */
1938 if (cipher == MCU_CIPHER_AES_CCMP) {
1939 memcpy(sta_key_conf->key, key->key, key->keylen);
1940 sta_key_conf->keyidx = key->keyidx;
1941 }
1942
1943 sec->n_cipher = 1;
1944 }
1945 } else {
1946 sec->n_cipher = 0;
1947 }
1948
1949 return 0;
1950}
1951
developer7800b8d2022-06-23 22:15:56 +08001952int besra_mcu_add_key(struct mt76_dev *dev, struct ieee80211_vif *vif,
developerb11a5392022-03-31 00:34:47 +08001953 struct mt76_connac_sta_key_conf *sta_key_conf,
1954 struct ieee80211_key_conf *key, int mcu_cmd,
1955 struct mt76_wcid *wcid, enum set_key_cmd cmd)
1956{
1957 struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv;
1958 struct sk_buff *skb;
1959 int ret;
1960
1961 skb = mt76_connac_mcu_alloc_sta_req(dev, mvif, wcid);
1962 if (IS_ERR(skb))
1963 return PTR_ERR(skb);
1964
developer7800b8d2022-06-23 22:15:56 +08001965 ret = besra_mcu_sta_key_tlv(wcid, sta_key_conf, skb, key, cmd);
developerb11a5392022-03-31 00:34:47 +08001966 if (ret)
1967 return ret;
1968
1969 return mt76_mcu_skb_send_msg(dev, skb, mcu_cmd, true);
1970}
1971
developer7800b8d2022-06-23 22:15:56 +08001972int besra_mcu_add_dev_info(struct besra_phy *phy,
developerb11a5392022-03-31 00:34:47 +08001973 struct ieee80211_vif *vif, bool enable)
1974{
developer7800b8d2022-06-23 22:15:56 +08001975 struct besra_dev *dev = phy->dev;
1976 struct besra_vif *mvif = (struct besra_vif *)vif->drv_priv;
developerb11a5392022-03-31 00:34:47 +08001977 struct {
1978 struct req_hdr {
1979 u8 omac_idx;
1980 u8 dbdc_idx;
1981 u8 __rsv[2];
1982 } __packed hdr;
1983 struct req_tlv {
1984 __le16 tag;
1985 __le16 len;
1986 u8 active;
1987 u8 __rsv;
1988 u8 omac_addr[ETH_ALEN];
1989 } __packed tlv;
1990 } data = {
1991 .hdr = {
1992 .omac_idx = mvif->mt76.omac_idx,
1993 .dbdc_idx = mvif->mt76.band_idx,
1994 },
1995 .tlv = {
1996 .tag = cpu_to_le16(DEV_INFO_ACTIVE),
1997 .len = cpu_to_le16(sizeof(struct req_tlv)),
1998 .active = enable,
1999 },
2000 };
2001
2002 if (mvif->mt76.omac_idx >= REPEATER_BSSID_START)
developer7800b8d2022-06-23 22:15:56 +08002003 return besra_mcu_muar_config(phy, vif, false, enable);
developerb11a5392022-03-31 00:34:47 +08002004
2005 memcpy(data.tlv.omac_addr, vif->addr, ETH_ALEN);
2006 return mt76_mcu_send_msg(&dev->mt76, MCU_WMWA_UNI_CMD(DEV_INFO_UPDATE),
2007 &data, sizeof(data), true);
2008}
2009
2010static void
developer7800b8d2022-06-23 22:15:56 +08002011besra_mcu_beacon_cntdwn(struct ieee80211_vif *vif, struct sk_buff *rskb,
developerb11a5392022-03-31 00:34:47 +08002012 struct sk_buff *skb,
2013 struct ieee80211_mutable_offsets *offs)
2014{
2015 struct bss_bcn_cntdwn_tlv *info;
2016 struct tlv *tlv;
2017 u16 tag;
2018
2019 if (!offs->cntdwn_counter_offs[0])
2020 return;
2021
2022 tag = vif->csa_active ? UNI_BSS_INFO_BCN_CSA : UNI_BSS_INFO_BCN_BCC;
2023
developer7800b8d2022-06-23 22:15:56 +08002024 tlv = besra_mcu_add_uni_tlv(rskb, tag, sizeof(*info));
developerb11a5392022-03-31 00:34:47 +08002025
2026 info = (struct bss_bcn_cntdwn_tlv *)tlv;
2027 info->cnt = skb->data[offs->cntdwn_counter_offs[0]];
2028}
2029
2030static void
developer7800b8d2022-06-23 22:15:56 +08002031besra_mcu_beacon_cont(struct besra_dev *dev, struct ieee80211_vif *vif,
developerb11a5392022-03-31 00:34:47 +08002032 struct sk_buff *rskb, struct sk_buff *skb,
2033 struct bss_bcn_content_tlv *bcn,
2034 struct ieee80211_mutable_offsets *offs)
2035{
2036 struct mt76_wcid *wcid = &dev->mt76.global_wcid;
2037 u8 *buf;
2038
2039 bcn->pkt_len = cpu_to_le16(MT_TXD_SIZE + skb->len);
2040 bcn->tim_ie_pos = cpu_to_le16(offs->tim_offset);
2041
2042 if (offs->cntdwn_counter_offs[0]) {
2043 u16 offset = offs->cntdwn_counter_offs[0];
2044
2045 if (vif->csa_active)
2046 bcn->csa_ie_pos = cpu_to_le16(offset - 4);
2047 if (vif->color_change_active)
2048 bcn->bcc_ie_pos = cpu_to_le16(offset - 3);
2049 }
2050
2051 buf = (u8 *)bcn + sizeof(*bcn) - MAX_BEACON_SIZE;
developer7800b8d2022-06-23 22:15:56 +08002052 besra_mac_write_txwi(dev, (__le32 *)buf, skb, wcid, 0, NULL,
developerb11a5392022-03-31 00:34:47 +08002053 true);
2054 memcpy(buf + MT_TXD_SIZE, skb->data, skb->len);
2055}
2056
2057static void
developer7800b8d2022-06-23 22:15:56 +08002058besra_mcu_beacon_check_caps(struct besra_phy *phy, struct ieee80211_vif *vif,
developerb11a5392022-03-31 00:34:47 +08002059 struct sk_buff *skb)
2060{
developer7800b8d2022-06-23 22:15:56 +08002061 struct besra_vif *mvif = (struct besra_vif *)vif->drv_priv;
2062 struct besra_vif_cap *vc = &mvif->cap;
developerb11a5392022-03-31 00:34:47 +08002063 const struct ieee80211_he_cap_elem *he;
2064 const struct ieee80211_vht_cap *vht;
2065 const struct ieee80211_ht_cap *ht;
2066 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data;
2067 const u8 *ie;
2068 u32 len, bc;
2069
2070 /* Check missing configuration options to allow AP mode in mac80211
2071 * to remain in sync with hostapd settings, and get a subset of
2072 * beacon and hardware capabilities.
2073 */
2074 if (WARN_ON_ONCE(skb->len <= (mgmt->u.beacon.variable - skb->data)))
2075 return;
2076
2077 memset(vc, 0, sizeof(*vc));
2078
2079 len = skb->len - (mgmt->u.beacon.variable - skb->data);
2080
2081 ie = cfg80211_find_ie(WLAN_EID_HT_CAPABILITY, mgmt->u.beacon.variable,
2082 len);
2083 if (ie && ie[1] >= sizeof(*ht)) {
2084 ht = (void *)(ie + 2);
developer66cd2092022-05-10 15:43:01 +08002085 vc->ht_ldpc |= !!(le16_to_cpu(ht->cap_info) &
2086 IEEE80211_HT_CAP_LDPC_CODING);
developerb11a5392022-03-31 00:34:47 +08002087 }
2088
2089 ie = cfg80211_find_ie(WLAN_EID_VHT_CAPABILITY, mgmt->u.beacon.variable,
2090 len);
2091 if (ie && ie[1] >= sizeof(*vht)) {
2092 u32 pc = phy->mt76->sband_5g.sband.vht_cap.cap;
2093
2094 vht = (void *)(ie + 2);
2095 bc = le32_to_cpu(vht->vht_cap_info);
2096
developer66cd2092022-05-10 15:43:01 +08002097 vc->vht_ldpc |= !!(bc & IEEE80211_VHT_CAP_RXLDPC);
developerb11a5392022-03-31 00:34:47 +08002098 vc->vht_su_ebfer =
2099 (bc & IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE) &&
2100 (pc & IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE);
2101 vc->vht_su_ebfee =
2102 (bc & IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE) &&
2103 (pc & IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE);
2104 vc->vht_mu_ebfer =
2105 (bc & IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE) &&
2106 (pc & IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE);
2107 vc->vht_mu_ebfee =
2108 (bc & IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE) &&
2109 (pc & IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE);
2110 }
2111
2112 ie = cfg80211_find_ext_ie(WLAN_EID_EXT_HE_CAPABILITY,
2113 mgmt->u.beacon.variable, len);
2114 if (ie && ie[1] >= sizeof(*he) + 1) {
2115 const struct ieee80211_sta_he_cap *pc =
2116 mt76_connac_get_he_phy_cap(phy->mt76, vif);
2117 const struct ieee80211_he_cap_elem *pe = &pc->he_cap_elem;
2118
2119 he = (void *)(ie + 3);
2120
developer66cd2092022-05-10 15:43:01 +08002121 vc->he_ldpc =
2122 HE_PHY(CAP1_LDPC_CODING_IN_PAYLOAD, pe->phy_cap_info[1]);
developerb11a5392022-03-31 00:34:47 +08002123 vc->he_su_ebfer =
2124 HE_PHY(CAP3_SU_BEAMFORMER, he->phy_cap_info[3]) &&
2125 HE_PHY(CAP3_SU_BEAMFORMER, pe->phy_cap_info[3]);
2126 vc->he_su_ebfee =
2127 HE_PHY(CAP4_SU_BEAMFORMEE, he->phy_cap_info[4]) &&
2128 HE_PHY(CAP4_SU_BEAMFORMEE, pe->phy_cap_info[4]);
2129 vc->he_mu_ebfer =
2130 HE_PHY(CAP4_MU_BEAMFORMER, he->phy_cap_info[4]) &&
2131 HE_PHY(CAP4_MU_BEAMFORMER, pe->phy_cap_info[4]);
2132 }
2133}
2134
developer7800b8d2022-06-23 22:15:56 +08002135int besra_mcu_add_beacon(struct ieee80211_hw *hw,
developerb11a5392022-03-31 00:34:47 +08002136 struct ieee80211_vif *vif, int en)
2137{
developer7800b8d2022-06-23 22:15:56 +08002138 struct besra_dev *dev = besra_hw_dev(hw);
2139 struct besra_phy *phy = besra_hw_phy(hw);
2140 struct besra_vif *mvif = (struct besra_vif *)vif->drv_priv;
developerb11a5392022-03-31 00:34:47 +08002141 struct ieee80211_mutable_offsets offs;
2142 struct ieee80211_tx_info *info;
2143 struct sk_buff *skb, *rskb;
2144 struct tlv *tlv;
2145 struct bss_bcn_content_tlv *bcn;
developer7800b8d2022-06-23 22:15:56 +08002146 u8 phy_idx = besra_get_phy_id(phy);
developerb11a5392022-03-31 00:34:47 +08002147
developer7800b8d2022-06-23 22:15:56 +08002148 rskb = __besra_mcu_alloc_bss_req(&dev->mt76, &mvif->mt76,
2149 BESRA_BEACON_UPDATE_SIZE);
developerb11a5392022-03-31 00:34:47 +08002150 if (IS_ERR(rskb))
2151 return PTR_ERR(rskb);
2152
developer7800b8d2022-06-23 22:15:56 +08002153 tlv = besra_mcu_add_uni_tlv(rskb,
developerb11a5392022-03-31 00:34:47 +08002154 UNI_BSS_INFO_BCN_CONTENT, sizeof(*bcn));
2155 bcn = (struct bss_bcn_content_tlv *)tlv;
2156 bcn->enable = en;
2157
2158 if (!en)
2159 goto out;
2160
2161 skb = ieee80211_beacon_get_template(hw, vif, &offs);
2162 if (!skb)
2163 return -EINVAL;
2164
2165 if (skb->len > MAX_BEACON_SIZE - MT_TXD_SIZE) {
2166 dev_err(dev->mt76.dev, "Bcn size limit exceed\n");
2167 dev_kfree_skb(skb);
2168 return -EINVAL;
2169 }
2170
2171 info = IEEE80211_SKB_CB(skb);
2172 info->hw_queue |= FIELD_PREP(MT_TX_HW_QUEUE_PHY, phy_idx);
2173
developer7800b8d2022-06-23 22:15:56 +08002174 besra_mcu_beacon_check_caps(phy, vif, skb);
developerb11a5392022-03-31 00:34:47 +08002175
developer7800b8d2022-06-23 22:15:56 +08002176 besra_mcu_beacon_cont(dev, vif, rskb, skb, bcn, &offs);
developerb11a5392022-03-31 00:34:47 +08002177 /* TODO: subtag - 11v MBSSID */
developer7800b8d2022-06-23 22:15:56 +08002178 besra_mcu_beacon_cntdwn(vif, rskb, skb, &offs);
developerb11a5392022-03-31 00:34:47 +08002179 dev_kfree_skb(skb);
2180out:
2181 return mt76_mcu_skb_send_msg(&phy->dev->mt76, rskb,
2182 MCU_WMWA_UNI_CMD(BSS_INFO_UPDATE), true);
2183}
2184
developer7800b8d2022-06-23 22:15:56 +08002185static int besra_driver_own(struct besra_dev *dev, u8 band)
developerb11a5392022-03-31 00:34:47 +08002186{
2187 mt76_wr(dev, MT_TOP_LPCR_HOST_BAND(band), MT_TOP_LPCR_HOST_DRV_OWN);
2188 if (!mt76_poll_msec(dev, MT_TOP_LPCR_HOST_BAND(band),
2189 MT_TOP_LPCR_HOST_FW_OWN_STAT, 0, 500)) {
2190 dev_err(dev->mt76.dev, "Timeout for driver own\n");
2191 return -EIO;
2192 }
2193
2194 /* clear irq when the driver own success */
2195 mt76_wr(dev, MT_TOP_LPCR_HOST_BAND_IRQ_STAT(band),
2196 MT_TOP_LPCR_HOST_BAND_STAT);
2197
2198 return 0;
2199}
2200
developer7800b8d2022-06-23 22:15:56 +08002201static int besra_load_patch(struct besra_dev *dev)
developerb11a5392022-03-31 00:34:47 +08002202{
developer7800b8d2022-06-23 22:15:56 +08002203 const struct besra_patch_hdr *hdr;
developerb11a5392022-03-31 00:34:47 +08002204 const struct firmware *fw = NULL;
2205 int i, ret, sem;
2206
2207 sem = mt76_connac_mcu_patch_sem_ctrl(&dev->mt76, 1);
2208 switch (sem) {
2209 case PATCH_IS_DL:
2210 return 0;
2211 case PATCH_NOT_DL_SEM_SUCCESS:
2212 break;
2213 default:
2214 dev_err(dev->mt76.dev, "Failed to get patch semaphore\n");
2215 return -EAGAIN;
2216 }
2217
2218 ret = request_firmware(&fw, MT7902_ROM_PATCH,
2219 dev->mt76.dev);
2220 if (ret)
2221 goto out;
2222
2223 if (!fw || !fw->data || fw->size < sizeof(*hdr)) {
2224 dev_err(dev->mt76.dev, "Invalid firmware\n");
2225 ret = -EINVAL;
2226 goto out;
2227 }
2228
developer7800b8d2022-06-23 22:15:56 +08002229 hdr = (const struct besra_patch_hdr *)(fw->data);
developerb11a5392022-03-31 00:34:47 +08002230
2231 dev_info(dev->mt76.dev, "HW/SW Version: 0x%x, Build Time: %.16s\n",
2232 be32_to_cpu(hdr->hw_sw_ver), hdr->build_date);
2233
2234 for (i = 0; i < be32_to_cpu(hdr->desc.n_region); i++) {
developer7800b8d2022-06-23 22:15:56 +08002235 struct besra_patch_sec *sec;
developerb11a5392022-03-31 00:34:47 +08002236 const u8 *dl;
2237 u32 len, addr;
2238
developer7800b8d2022-06-23 22:15:56 +08002239 sec = (struct besra_patch_sec *)(fw->data + sizeof(*hdr) +
developerb11a5392022-03-31 00:34:47 +08002240 i * sizeof(*sec));
2241 if ((be32_to_cpu(sec->type) & PATCH_SEC_TYPE_MASK) !=
2242 PATCH_SEC_TYPE_INFO) {
2243 ret = -EINVAL;
2244 goto out;
2245 }
2246
2247 addr = be32_to_cpu(sec->info.addr);
2248 len = be32_to_cpu(sec->info.len);
2249 dl = fw->data + be32_to_cpu(sec->offs);
2250
2251 ret = mt76_connac_mcu_init_download(&dev->mt76, addr, len,
2252 DL_MODE_NEED_RSP);
2253 if (ret) {
2254 dev_err(dev->mt76.dev, "Download request failed\n");
2255 goto out;
2256 }
2257
2258 ret = __mt76_mcu_send_firmware(&dev->mt76, MCU_CMD(FW_SCATTER),
2259 dl, len, 4096);
2260 if (ret) {
2261 dev_err(dev->mt76.dev, "Failed to send patch\n");
2262 goto out;
2263 }
2264 }
2265
2266 ret = mt76_connac_mcu_start_patch(&dev->mt76);
2267 if (ret)
2268 dev_err(dev->mt76.dev, "Failed to start patch\n");
2269
2270out:
2271 sem = mt76_connac_mcu_patch_sem_ctrl(&dev->mt76, 0);
2272 switch (sem) {
2273 case PATCH_REL_SEM_SUCCESS:
2274 break;
2275 default:
2276 ret = -EAGAIN;
2277 dev_err(dev->mt76.dev, "Failed to release patch semaphore\n");
2278 break;
2279 }
2280 release_firmware(fw);
2281
2282 return ret;
2283}
2284
2285static int
developer7800b8d2022-06-23 22:15:56 +08002286besra_mcu_send_ram_firmware(struct besra_dev *dev,
2287 const struct besra_fw_trailer *hdr,
developerb11a5392022-03-31 00:34:47 +08002288 const u8 *data, bool is_wa)
2289{
2290 int i, offset = 0;
2291 u32 override = 0, option = 0;
2292
2293 for (i = 0; i < hdr->n_region; i++) {
developer7800b8d2022-06-23 22:15:56 +08002294 const struct besra_fw_region *region;
developerb11a5392022-03-31 00:34:47 +08002295 int err;
2296 u32 len, addr, mode;
2297
developer7800b8d2022-06-23 22:15:56 +08002298 region = (const struct besra_fw_region *)((const u8 *)hdr -
developerb11a5392022-03-31 00:34:47 +08002299 (hdr->n_region - i) * sizeof(*region));
2300 mode = mt76_connac_mcu_gen_dl_mode(&dev->mt76,
2301 region->feature_set, is_wa);
2302 len = le32_to_cpu(region->len);
2303 addr = le32_to_cpu(region->addr);
2304
2305 if (region->feature_set & FW_FEATURE_OVERRIDE_ADDR)
2306 override = addr;
2307
2308 err = mt76_connac_mcu_init_download(&dev->mt76, addr, len,
2309 mode);
2310 if (err) {
2311 dev_err(dev->mt76.dev, "Download request failed\n");
2312 return err;
2313 }
2314
2315 err = __mt76_mcu_send_firmware(&dev->mt76, MCU_CMD(FW_SCATTER),
2316 data + offset, len, 4096);
2317 if (err) {
2318 dev_err(dev->mt76.dev, "Failed to send firmware.\n");
2319 return err;
2320 }
2321
2322 offset += len;
2323 }
2324
2325 if (override)
2326 option |= FW_START_OVERRIDE;
2327
2328 if (is_wa)
2329 option |= FW_START_WORKING_PDA_CR4;
2330
2331 return mt76_connac_mcu_start_firmware(&dev->mt76, override, option);
2332}
2333
developer7800b8d2022-06-23 22:15:56 +08002334static int besra_load_ram(struct besra_dev *dev)
developerb11a5392022-03-31 00:34:47 +08002335{
developer7800b8d2022-06-23 22:15:56 +08002336 const struct besra_fw_trailer *hdr;
developerb11a5392022-03-31 00:34:47 +08002337 const struct firmware *fw;
2338 int ret;
2339
2340 ret = request_firmware(&fw, MT7902_FIRMWARE_WM,
2341 dev->mt76.dev);
2342 if (ret)
2343 return ret;
2344
2345 if (!fw || !fw->data || fw->size < sizeof(*hdr)) {
2346 dev_err(dev->mt76.dev, "Invalid firmware\n");
2347 ret = -EINVAL;
2348 goto out;
2349 }
2350
developer7800b8d2022-06-23 22:15:56 +08002351 hdr = (const struct besra_fw_trailer *)(fw->data + fw->size -
developerb11a5392022-03-31 00:34:47 +08002352 sizeof(*hdr));
2353
2354 dev_info(dev->mt76.dev, "WM Firmware Version: %.10s, Build Time: %.15s\n",
2355 hdr->fw_ver, hdr->build_date);
2356
developer7800b8d2022-06-23 22:15:56 +08002357 ret = besra_mcu_send_ram_firmware(dev, hdr, fw->data, false);
developerb11a5392022-03-31 00:34:47 +08002358 if (ret) {
2359 dev_err(dev->mt76.dev, "Failed to start WM firmware\n");
2360 goto out;
2361 }
2362
2363 release_firmware(fw);
2364
2365 ret = request_firmware(&fw, MT7902_FIRMWARE_WA,
2366 dev->mt76.dev);
2367 if (ret)
2368 return ret;
2369
2370 if (!fw || !fw->data || fw->size < sizeof(*hdr)) {
2371 dev_err(dev->mt76.dev, "Invalid firmware\n");
2372 ret = -EINVAL;
2373 goto out;
2374 }
2375
developer7800b8d2022-06-23 22:15:56 +08002376 hdr = (const struct besra_fw_trailer *)(fw->data + fw->size -
developerb11a5392022-03-31 00:34:47 +08002377 sizeof(*hdr));
2378
2379 dev_info(dev->mt76.dev, "WA Firmware Version: %.10s, Build Time: %.15s\n",
2380 hdr->fw_ver, hdr->build_date);
2381
developer7800b8d2022-06-23 22:15:56 +08002382 ret = besra_mcu_send_ram_firmware(dev, hdr, fw->data, true);
developerb11a5392022-03-31 00:34:47 +08002383 if (ret) {
2384 dev_err(dev->mt76.dev, "Failed to start WA firmware\n");
2385 goto out;
2386 }
2387
2388 snprintf(dev->mt76.hw->wiphy->fw_version,
2389 sizeof(dev->mt76.hw->wiphy->fw_version),
2390 "%.10s-%.15s", hdr->fw_ver, hdr->build_date);
2391
2392out:
2393 release_firmware(fw);
2394
2395 return ret;
2396}
2397
2398static int
developer7800b8d2022-06-23 22:15:56 +08002399besra_firmware_state(struct besra_dev *dev, bool wa)
developerb11a5392022-03-31 00:34:47 +08002400{
2401 u32 state = FIELD_PREP(MT_TOP_MISC_FW_STATE,
2402 wa ? FW_STATE_RDY : FW_STATE_FW_DOWNLOAD);
2403
2404 if (!mt76_poll_msec(dev, MT_TOP_MISC, MT_TOP_MISC_FW_STATE,
2405 state, 1000)) {
2406 dev_err(dev->mt76.dev, "Timeout for initializing firmware\n");
2407 return -EIO;
2408 }
2409 return 0;
2410}
2411
developer7800b8d2022-06-23 22:15:56 +08002412static int besra_load_firmware(struct besra_dev *dev)
developerb11a5392022-03-31 00:34:47 +08002413{
2414 int ret;
2415
2416 /* make sure fw is download state */
developer7800b8d2022-06-23 22:15:56 +08002417 if (besra_firmware_state(dev, false)) {
developerb11a5392022-03-31 00:34:47 +08002418 /* restart firmware once */
2419 __mt76_mcu_restart(&dev->mt76);
developer7800b8d2022-06-23 22:15:56 +08002420 ret = besra_firmware_state(dev, false);
developerb11a5392022-03-31 00:34:47 +08002421 if (ret) {
2422 dev_err(dev->mt76.dev,
2423 "Firmware is not ready for download\n");
2424 return ret;
2425 }
2426 }
2427
developer7800b8d2022-06-23 22:15:56 +08002428 ret = besra_load_patch(dev);
developerb11a5392022-03-31 00:34:47 +08002429 if (ret)
2430 return ret;
2431
developer7800b8d2022-06-23 22:15:56 +08002432 ret = besra_load_ram(dev);
developerb11a5392022-03-31 00:34:47 +08002433 if (ret)
2434 return ret;
2435
developer7800b8d2022-06-23 22:15:56 +08002436 ret = besra_firmware_state(dev, true);
developerb11a5392022-03-31 00:34:47 +08002437 if (ret)
2438 return ret;
2439
2440 mt76_queue_tx_cleanup(dev, dev->mt76.q_mcu[MT_MCUQ_FWDL], false);
2441
2442 dev_dbg(dev->mt76.dev, "Firmware init done\n");
2443
2444 return 0;
2445}
2446
developer7800b8d2022-06-23 22:15:56 +08002447int besra_mcu_fw_log_2_host(struct besra_dev *dev, u8 type, u8 ctrl)
developerb11a5392022-03-31 00:34:47 +08002448{
2449 struct {
2450 u8 _rsv[4];
2451
2452 __le16 tag;
2453 __le16 len;
2454 u8 ctrl;
2455 u8 interval;
2456 u8 _rsv2[2];
2457 } __packed data = {
2458 .tag = cpu_to_le16(UNI_WSYS_CONFIG_FW_LOG_CTRL),
2459 .len = cpu_to_le16(sizeof(data) - 4),
2460 .ctrl = ctrl,
2461 };
2462
2463 if (type == MCU_FW_LOG_WA)
2464 return mt76_mcu_send_msg(&dev->mt76, MCU_WA_UNI_CMD(WSYS_CONFIG),
2465 &data, sizeof(data), true);
2466
2467 return mt76_mcu_send_msg(&dev->mt76, MCU_WM_UNI_CMD(WSYS_CONFIG), &data,
2468 sizeof(data), true);
2469}
2470
developer7800b8d2022-06-23 22:15:56 +08002471int besra_mcu_fw_dbg_ctrl(struct besra_dev *dev, u32 module, u8 level)
developerb11a5392022-03-31 00:34:47 +08002472{
2473 struct {
2474 u8 _rsv[4];
2475
2476 __le16 tag;
2477 __le16 len;
2478 __le32 module_idx;
2479 u8 level;
2480 u8 _rsv2[3];
2481 } data = {
2482 .tag = cpu_to_le16(UNI_WSYS_CONFIG_FW_DBG_CTRL),
2483 .len = cpu_to_le16(sizeof(data) - 4),
2484 .module_idx = cpu_to_le32(module),
2485 .level = level,
2486 };
2487
2488 return mt76_mcu_send_msg(&dev->mt76, MCU_WM_UNI_CMD(WSYS_CONFIG), &data,
2489 sizeof(data), false);
2490}
2491
developer7800b8d2022-06-23 22:15:56 +08002492int besra_mcu_muru_debug_set(struct besra_dev *dev, bool enabled)
developerb11a5392022-03-31 00:34:47 +08002493{
2494 struct {
2495 __le32 cmd;
2496 u8 enable;
2497 } data = {
2498 .cmd = cpu_to_le32(MURU_SET_TXC_TX_STATS_EN),
2499 .enable = enabled,
2500 };
2501
2502 return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(MURU_CTRL), &data,
2503 sizeof(data), false);
2504}
2505
developer7800b8d2022-06-23 22:15:56 +08002506int besra_mcu_muru_debug_get(struct besra_phy *phy, void *ms)
developerb11a5392022-03-31 00:34:47 +08002507{
developer7800b8d2022-06-23 22:15:56 +08002508 struct besra_dev *dev = phy->dev;
developerb11a5392022-03-31 00:34:47 +08002509 struct sk_buff *skb;
developer7800b8d2022-06-23 22:15:56 +08002510 struct besra_mcu_muru_stats *mu_stats =
2511 (struct besra_mcu_muru_stats *)ms;
developerb11a5392022-03-31 00:34:47 +08002512 int ret;
2513
2514 struct {
2515 __le32 cmd;
2516 u8 band_idx;
2517 } req = {
2518 .cmd = cpu_to_le32(MURU_GET_TXC_TX_STATS),
2519 .band_idx = phy->band_idx,
2520 };
2521
2522 ret = mt76_mcu_send_and_get_msg(&dev->mt76, MCU_EXT_CMD(MURU_CTRL),
2523 &req, sizeof(req), true, &skb);
2524 if (ret)
2525 return ret;
2526
developer7800b8d2022-06-23 22:15:56 +08002527 memcpy(mu_stats, skb->data, sizeof(struct besra_mcu_muru_stats));
developerb11a5392022-03-31 00:34:47 +08002528 dev_kfree_skb(skb);
2529
2530 return 0;
2531}
2532
developer7800b8d2022-06-23 22:15:56 +08002533static int besra_mcu_set_mwds(struct besra_dev *dev, bool enabled)
developerb11a5392022-03-31 00:34:47 +08002534{
2535 struct {
2536 u8 enable;
2537 u8 _rsv[3];
2538 } __packed req = {
2539 .enable = enabled
2540 };
2541
2542 return mt76_mcu_send_msg(&dev->mt76, MCU_WA_EXT_CMD(MWDS_SUPPORT), &req,
2543 sizeof(req), false);
2544}
2545
developer7800b8d2022-06-23 22:15:56 +08002546int besra_mcu_set_muru_ctrl(struct besra_dev *dev, u32 cmd, u32 val)
developerb11a5392022-03-31 00:34:47 +08002547{
2548 struct {
2549 __le32 cmd;
2550 u8 val[4];
2551 } __packed req = {
2552 .cmd = cpu_to_le32(cmd),
2553 };
2554
2555 put_unaligned_le32(val, req.val);
2556
2557 return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(MURU_CTRL), &req,
2558 sizeof(req), false);
2559}
2560
2561static int
developer7800b8d2022-06-23 22:15:56 +08002562besra_mcu_init_rx_airtime(struct besra_dev *dev)
developerb11a5392022-03-31 00:34:47 +08002563{
2564#define RX_AIRTIME_FEATURE_CTRL 1
2565#define RX_AIRTIME_BITWISE_CTRL 2
2566#define RX_AIRTIME_CLEAR_EN 1
2567 struct {
2568 __le16 field;
2569 __le16 sub_field;
2570 __le32 set_status;
2571 __le32 get_status;
2572 u8 _rsv[12];
2573
2574 bool airtime_en;
2575 bool mibtime_en;
2576 bool earlyend_en;
2577 u8 _rsv1[9];
2578
2579 bool airtime_clear;
2580 bool mibtime_clear;
2581 u8 _rsv2[98];
2582 } __packed req = {
2583 .field = cpu_to_le16(RX_AIRTIME_BITWISE_CTRL),
2584 .sub_field = cpu_to_le16(RX_AIRTIME_CLEAR_EN),
2585 .airtime_clear = true,
2586 };
2587 int ret;
2588
2589 ret = mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(RX_AIRTIME_CTRL), &req,
2590 sizeof(req), true);
2591 if (ret)
2592 return ret;
2593
2594 req.field = cpu_to_le16(RX_AIRTIME_FEATURE_CTRL);
2595 req.sub_field = cpu_to_le16(RX_AIRTIME_CLEAR_EN);
2596 req.airtime_en = true;
2597
2598 return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(RX_AIRTIME_CTRL), &req,
2599 sizeof(req), true);
2600}
2601
2602static int
developer7800b8d2022-06-23 22:15:56 +08002603besra_load_rom(struct besra_dev *dev, bool is_sram)
developerb11a5392022-03-31 00:34:47 +08002604{
2605#define MCU_FIRMWARE_ROM_ADDR 0x00800000
2606#define MCU_FIRMWARE_ROM_SRAM_ADDR 0xE0048000
2607
2608 const struct firmware *fw;
2609 int ret;
2610 u32 val, ofs = 0;
2611
2612 ret = request_firmware(&fw, (is_sram ? MT7902_FIRMWARE_ROM_SRAM :
2613 MT7902_FIRMWARE_ROM),
2614 dev->mt76.dev);
2615 if (ret) {
2616 dev_err(dev->mt76.dev, "request rom binary failed\n");
2617 return ret;
2618 }
2619
2620 if (!fw || !fw->data ) {
2621 dev_err(dev->mt76.dev, "Invalid firmware\n");
2622 ret = -EINVAL;
2623 goto out;
2624 }
2625
2626 val = mt76_rr(dev, MT_INFRA_BUS_ON_REMAP_WF_5_4);
2627
2628 mt76_wr(dev, MT_INFRA_BUS_ON_REMAP_WF_5_4,
2629 FIELD_GET(MT_INFRA_BUS_ON_REMAP_WF_4_MASK, val) |
2630 FIELD_PREP(MT_INFRA_BUS_ON_REMAP_WF_5_MASK, 0x1850));
2631
2632 while (true) {
2633 u32 size;
2634
2635 if (ofs >= fw->size)
2636 break;
2637
2638 if ((ofs + 0x10000) <= fw->size)
2639 size = 0x10000;
2640 else
2641 size = fw->size - ofs;
2642
2643 mt76_wr(dev, MT_MCU_BUS_REMAP,
2644 ((is_sram ? MCU_FIRMWARE_ROM_SRAM_ADDR : MCU_FIRMWARE_ROM_ADDR) + ofs));
2645 mt76_wr_copy(dev, 0x50000, (void *) (fw->data + ofs), size);
2646
2647 ofs += 0x10000;
2648 }
2649
2650 mt76_wr(dev, MT_INFRA_BUS_ON_REMAP_WF_5_4, val);
2651
2652out:
2653 release_firmware(fw);
2654
2655 return ret;
2656
2657}
2658
developer7800b8d2022-06-23 22:15:56 +08002659int besra_rom_start(struct besra_dev *dev)
developerb11a5392022-03-31 00:34:47 +08002660{
2661#define WF_IDLE 0xBE11
2662#define WF_STATE_MASK GENMASK(15, 0)
2663
2664 int ret;
2665 u32 val;
2666
2667 ret = !mt76_poll_msec(dev, MT_TOP_CFG_ON_ROM_IDX,
2668 MT_TOP_CFG_ON_ROM_STATE_MASK,
2669 FIELD_PREP(MT_TOP_CFG_ON_ROM_STATE_MASK,
2670 MT_TOP_CFG_ON_ROM_IDLE), 200);
2671 if (!ret)
2672 return ret;
2673
2674 mt76_rmw(dev, MT_INFRA_RGU_RGU_ON_SW_RST_B,
2675 MT_INFRA_RGU_RGU_ON_SW_RST_B_MASK, 0);
2676
developer7800b8d2022-06-23 22:15:56 +08002677 ret = besra_load_rom(dev, false);
developerb11a5392022-03-31 00:34:47 +08002678 if (ret)
2679 return ret;
2680
developer7800b8d2022-06-23 22:15:56 +08002681 ret = besra_load_rom(dev, true);
developerb11a5392022-03-31 00:34:47 +08002682 if (ret)
2683 return ret;
2684
2685 mt76_rmw(dev, MT_INFRA_RGU_RGU_ON_SW_RST_B,
2686 MT_INFRA_RGU_RGU_ON_SW_RST_B_MASK, 1);
2687
2688 ret = !mt76_poll_msec(dev, MT_TOP_CFG_ON_ROM_IDX,
2689 MT_TOP_CFG_ON_ROM_STATE_MASK,
2690 FIELD_PREP(MT_TOP_CFG_ON_ROM_STATE_MASK,
2691 MT_TOP_CFG_ON_ROM_IDLE), 200);
2692 if (ret)
2693 return ret;
2694
2695 val = mt76_rr(dev, MT_HIF_REMAP_L1);
2696
2697 mt76_wr(dev, MT_HIF_REMAP_L1,
2698 FIELD_GET(MT_HIF_REMAP_L1_OFFSET, val) | FIELD_PREP(MT_HIF_REMAP_L1_BASE, 0x1805));
2699 if (!mt76_poll_msec(dev, 0x54A68, WF_STATE_MASK,
2700 FIELD_PREP(WF_STATE_MASK, WF_IDLE), 1000)) {
2701 dev_err(dev->mt76.dev, "timeout for wf idle\n");
2702 ret = -EIO;
2703 }
2704
2705 mt76_wr(dev, MT_HIF_REMAP_L1, val);
2706
2707 return ret;
2708}
2709
developer7800b8d2022-06-23 22:15:56 +08002710int besra_mcu_init(struct besra_dev *dev)
developerb11a5392022-03-31 00:34:47 +08002711{
developer7800b8d2022-06-23 22:15:56 +08002712 static const struct mt76_mcu_ops besra_mcu_ops = {
2713 .headroom = sizeof(struct besra_mcu_txd),
2714 .mcu_skb_send_msg = besra_mcu_send_message,
2715 .mcu_parse_response = besra_mcu_parse_response,
developerb11a5392022-03-31 00:34:47 +08002716 .mcu_restart = mt76_connac_mcu_restart,
2717 };
2718 int ret;
2719
developer7800b8d2022-06-23 22:15:56 +08002720 dev->mt76.mcu_ops = &besra_mcu_ops;
developerb11a5392022-03-31 00:34:47 +08002721
2722 /* force firmware operation mode into normal state,
2723 * which should be set before firmware download stage.
2724 */
2725 mt76_wr(dev, MT_SWDEF_MODE, MT_SWDEF_NORMAL_MODE);
2726
developer7800b8d2022-06-23 22:15:56 +08002727 ret = besra_driver_own(dev, 0);
developerb11a5392022-03-31 00:34:47 +08002728 if (ret)
2729 return ret;
2730 /* set driver own for band1 when two hif exist */
2731 if (dev->hif2) {
developer7800b8d2022-06-23 22:15:56 +08002732 ret = besra_driver_own(dev, 1);
developerb11a5392022-03-31 00:34:47 +08002733 if (ret)
2734 return ret;
2735 }
2736
developer7800b8d2022-06-23 22:15:56 +08002737 ret = besra_load_firmware(dev);
developerb11a5392022-03-31 00:34:47 +08002738 if (ret)
2739 return ret;
2740
2741 set_bit(MT76_STATE_MCU_RUNNING, &dev->mphy.state);
developer7800b8d2022-06-23 22:15:56 +08002742 ret = besra_mcu_fw_log_2_host(dev, MCU_FW_LOG_WM, 0);
developerb11a5392022-03-31 00:34:47 +08002743 if (ret)
2744 return ret;
2745
developer7800b8d2022-06-23 22:15:56 +08002746 ret = besra_mcu_fw_log_2_host(dev, MCU_FW_LOG_WA, 0);
developerb11a5392022-03-31 00:34:47 +08002747 if (ret)
2748 return ret;
2749
developer7800b8d2022-06-23 22:15:56 +08002750 ret = besra_mcu_set_mwds(dev, 1);
developerb11a5392022-03-31 00:34:47 +08002751 if (ret)
2752 return ret;
2753
developer7800b8d2022-06-23 22:15:56 +08002754 ret = besra_mcu_set_muru_ctrl(dev, MURU_SET_PLATFORM_TYPE,
developerb11a5392022-03-31 00:34:47 +08002755 MURU_PLATFORM_TYPE_PERF_LEVEL_2);
2756 if (ret)
2757 return ret;
2758
developer7800b8d2022-06-23 22:15:56 +08002759 ret = besra_mcu_init_rx_airtime(dev);
developerb11a5392022-03-31 00:34:47 +08002760 if (ret)
2761 return ret;
2762
developer7800b8d2022-06-23 22:15:56 +08002763 return besra_mcu_wa_cmd(dev, MCU_WA_PARAM_CMD(SET),
developerb11a5392022-03-31 00:34:47 +08002764 MCU_WA_PARAM_RED, 0, 0);
2765}
2766
developer7800b8d2022-06-23 22:15:56 +08002767void besra_mcu_exit(struct besra_dev *dev)
developerb11a5392022-03-31 00:34:47 +08002768{
2769 __mt76_mcu_restart(&dev->mt76);
developer7800b8d2022-06-23 22:15:56 +08002770 if (besra_firmware_state(dev, false)) {
developerb11a5392022-03-31 00:34:47 +08002771 dev_err(dev->mt76.dev, "Failed to exit mcu\n");
2772 return;
2773 }
2774
2775 mt76_wr(dev, MT_TOP_LPCR_HOST_BAND(0), MT_TOP_LPCR_HOST_FW_OWN);
2776 if (dev->hif2)
2777 mt76_wr(dev, MT_TOP_LPCR_HOST_BAND(1),
2778 MT_TOP_LPCR_HOST_FW_OWN);
2779 skb_queue_purge(&dev->mt76.mcu.res_q);
2780}
2781
developer7800b8d2022-06-23 22:15:56 +08002782int besra_mcu_set_hdr_trans(struct besra_dev *dev, bool hdr_trans)
developerb11a5392022-03-31 00:34:47 +08002783{
2784 struct {
2785 u8 __rsv[4];
2786 } __packed hdr;
2787 struct hdr_trans_blacklist *req_blacklist;
2788 struct hdr_trans_en *req_en;
2789 struct sk_buff *skb;
2790 struct tlv *tlv;
developer7800b8d2022-06-23 22:15:56 +08002791 int len = BESRA_HDR_TRANS_MAX_SIZE + sizeof(hdr);
developerb11a5392022-03-31 00:34:47 +08002792 int ret;
2793
2794 skb = mt76_mcu_msg_alloc(&dev->mt76, NULL, len);
2795 if (!skb)
2796 return ERR_PTR(-ENOMEM);
2797
2798 skb_put_data(skb, &hdr, sizeof(hdr));
2799
developer7800b8d2022-06-23 22:15:56 +08002800 tlv = besra_mcu_add_uni_tlv(skb, UNI_HDR_TRANS_EN, sizeof(*req_en));
developerb11a5392022-03-31 00:34:47 +08002801 req_en = (struct hdr_trans_en *)tlv;
2802 req_en->enable = hdr_trans;
2803
developer7800b8d2022-06-23 22:15:56 +08002804 tlv = besra_mcu_add_uni_tlv(skb, UNI_HDR_TRANS_VLAN,
developerb11a5392022-03-31 00:34:47 +08002805 sizeof(struct hdr_trans_vlan));
2806
2807 if (hdr_trans) {
developer7800b8d2022-06-23 22:15:56 +08002808 tlv = besra_mcu_add_uni_tlv(skb, UNI_HDR_TRANS_BLACKLIST,
developerb11a5392022-03-31 00:34:47 +08002809 sizeof(*req_blacklist));
2810 req_blacklist = (struct hdr_trans_blacklist *)tlv;
2811 req_blacklist->enable = 1;
2812 req_blacklist->type = cpu_to_le16(ETH_P_PAE);
2813 }
2814
2815 return mt76_mcu_skb_send_msg(&dev->mt76, skb,
2816 MCU_WM_UNI_CMD(RX_HDR_TRANS), true);
2817}
2818
developer7800b8d2022-06-23 22:15:56 +08002819int besra_mcu_set_tx(struct besra_dev *dev, struct ieee80211_vif *vif)
developerb11a5392022-03-31 00:34:47 +08002820{
developer7800b8d2022-06-23 22:15:56 +08002821 struct besra_vif *mvif = (struct besra_vif *)vif->drv_priv;
developerb11a5392022-03-31 00:34:47 +08002822 struct {
2823 u8 bss_idx;
2824 u8 __rsv[3];
2825 } __packed hdr = {
2826 .bss_idx = mvif->mt76.idx,
2827 };
2828 struct sk_buff *skb;
2829 int len = sizeof(hdr) + IEEE80211_NUM_ACS * sizeof(struct edca);
2830 int ac;
2831
2832 skb = mt76_mcu_msg_alloc(&dev->mt76, NULL, len);
2833 if (!skb)
2834 return ERR_PTR(-ENOMEM);
2835
2836 skb_put_data(skb, &hdr, sizeof(hdr));
2837
2838 for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
2839 struct ieee80211_tx_queue_params *q = &mvif->queue_params[ac];
2840 struct edca *e;
2841 struct tlv *tlv;
2842
developer7800b8d2022-06-23 22:15:56 +08002843 tlv = besra_mcu_add_uni_tlv(skb, MCU_EDCA_AC_PARAM, sizeof(*e));
developerb11a5392022-03-31 00:34:47 +08002844
2845 e = (struct edca *)tlv;
2846 e->set = WMM_PARAM_SET;
developer7800b8d2022-06-23 22:15:56 +08002847 e->queue = ac + mvif->mt76.wmm_idx * BESRA_MAX_WMM_SETS;
developerb11a5392022-03-31 00:34:47 +08002848 e->aifs = q->aifs;
2849 e->txop = cpu_to_le16(q->txop);
2850
2851 if (q->cw_min)
2852 e->cw_min = fls(q->cw_min);
2853 else
2854 e->cw_min = 5;
2855
2856 if (q->cw_max)
2857 e->cw_max = cpu_to_le16(fls(q->cw_max));
2858 else
2859 e->cw_max = cpu_to_le16(10);
2860 }
2861 return mt76_mcu_skb_send_msg(&dev->mt76, skb,
2862 MCU_WM_UNI_CMD(EDCA), true);
2863}
2864
developer7800b8d2022-06-23 22:15:56 +08002865int besra_mcu_set_fcc5_lpn(struct besra_dev *dev, int val)
developerb11a5392022-03-31 00:34:47 +08002866{
2867 struct {
2868 __le32 tag;
2869 __le16 min_lpn;
2870 u8 rsv[2];
2871 } __packed req = {
2872 .tag = cpu_to_le32(0x1),
2873 .min_lpn = cpu_to_le16(val),
2874 };
2875
2876 return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(SET_RDD_TH), &req,
2877 sizeof(req), true);
2878}
2879
developer7800b8d2022-06-23 22:15:56 +08002880int besra_mcu_set_pulse_th(struct besra_dev *dev,
2881 const struct besra_dfs_pulse *pulse)
developerb11a5392022-03-31 00:34:47 +08002882{
2883 struct {
2884 __le32 tag;
2885
2886 __le32 max_width; /* us */
2887 __le32 max_pwr; /* dbm */
2888 __le32 min_pwr; /* dbm */
2889 __le32 min_stgr_pri; /* us */
2890 __le32 max_stgr_pri; /* us */
2891 __le32 min_cr_pri; /* us */
2892 __le32 max_cr_pri; /* us */
2893 } __packed req = {
2894 .tag = cpu_to_le32(0x3),
2895
2896#define __req_field(field) .field = cpu_to_le32(pulse->field)
2897 __req_field(max_width),
2898 __req_field(max_pwr),
2899 __req_field(min_pwr),
2900 __req_field(min_stgr_pri),
2901 __req_field(max_stgr_pri),
2902 __req_field(min_cr_pri),
2903 __req_field(max_cr_pri),
2904#undef __req_field
2905 };
2906
2907 return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(SET_RDD_TH), &req,
2908 sizeof(req), true);
2909}
2910
developer7800b8d2022-06-23 22:15:56 +08002911int besra_mcu_set_radar_th(struct besra_dev *dev, int index,
2912 const struct besra_dfs_pattern *pattern)
developerb11a5392022-03-31 00:34:47 +08002913{
2914 struct {
2915 __le32 tag;
2916 __le16 radar_type;
2917
2918 u8 enb;
2919 u8 stgr;
2920 u8 min_crpn;
2921 u8 max_crpn;
2922 u8 min_crpr;
2923 u8 min_pw;
2924 __le32 min_pri;
2925 __le32 max_pri;
2926 u8 max_pw;
2927 u8 min_crbn;
2928 u8 max_crbn;
2929 u8 min_stgpn;
2930 u8 max_stgpn;
2931 u8 min_stgpr;
2932 u8 rsv[2];
2933 __le32 min_stgpr_diff;
2934 } __packed req = {
2935 .tag = cpu_to_le32(0x2),
2936 .radar_type = cpu_to_le16(index),
2937
2938#define __req_field_u8(field) .field = pattern->field
2939#define __req_field_u32(field) .field = cpu_to_le32(pattern->field)
2940 __req_field_u8(enb),
2941 __req_field_u8(stgr),
2942 __req_field_u8(min_crpn),
2943 __req_field_u8(max_crpn),
2944 __req_field_u8(min_crpr),
2945 __req_field_u8(min_pw),
2946 __req_field_u32(min_pri),
2947 __req_field_u32(max_pri),
2948 __req_field_u8(max_pw),
2949 __req_field_u8(min_crbn),
2950 __req_field_u8(max_crbn),
2951 __req_field_u8(min_stgpn),
2952 __req_field_u8(max_stgpn),
2953 __req_field_u8(min_stgpr),
2954 __req_field_u32(min_stgpr_diff),
2955#undef __req_field_u8
2956#undef __req_field_u32
2957 };
2958
2959 return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(SET_RDD_TH), &req,
2960 sizeof(req), true);
2961}
2962
2963static int
developer7800b8d2022-06-23 22:15:56 +08002964besra_mcu_background_chain_ctrl(struct besra_phy *phy,
developerb11a5392022-03-31 00:34:47 +08002965 struct cfg80211_chan_def *chandef,
2966 int cmd)
2967{
developer7800b8d2022-06-23 22:15:56 +08002968 struct besra_dev *dev = phy->dev;
developerb11a5392022-03-31 00:34:47 +08002969 struct mt76_phy *mphy = phy->mt76;
2970 struct ieee80211_channel *chan = mphy->chandef.chan;
2971 int freq = mphy->chandef.center_freq1;
developer7800b8d2022-06-23 22:15:56 +08002972 struct besra_mcu_background_chain_ctrl req = {
developerb11a5392022-03-31 00:34:47 +08002973 .monitor_scan_type = 2, /* simple rx */
2974 };
2975
2976 if (!chandef && cmd != CH_SWITCH_BACKGROUND_SCAN_STOP)
2977 return -EINVAL;
2978
2979 if (!cfg80211_chandef_valid(&mphy->chandef))
2980 return -EINVAL;
2981
2982 switch (cmd) {
2983 case CH_SWITCH_BACKGROUND_SCAN_START: {
2984 req.chan = chan->hw_value;
2985 req.central_chan = ieee80211_frequency_to_channel(freq);
2986 req.bw = mt76_connac_chan_bw(&mphy->chandef);
2987 req.monitor_chan = chandef->chan->hw_value;
2988 req.monitor_central_chan =
2989 ieee80211_frequency_to_channel(chandef->center_freq1);
2990 req.monitor_bw = mt76_connac_chan_bw(chandef);
2991 req.band_idx = phy->band_idx;
2992 req.scan_mode = 1;
2993 break;
2994 }
2995 case CH_SWITCH_BACKGROUND_SCAN_RUNNING:
2996 req.monitor_chan = chandef->chan->hw_value;
2997 req.monitor_central_chan =
2998 ieee80211_frequency_to_channel(chandef->center_freq1);
2999 req.band_idx = phy->band_idx;
3000 req.scan_mode = 2;
3001 break;
3002 case CH_SWITCH_BACKGROUND_SCAN_STOP:
3003 req.chan = chan->hw_value;
3004 req.central_chan = ieee80211_frequency_to_channel(freq);
3005 req.bw = mt76_connac_chan_bw(&mphy->chandef);
3006 req.tx_stream = hweight8(mphy->antenna_mask);
3007 req.rx_stream = mphy->antenna_mask;
3008 break;
3009 default:
3010 return -EINVAL;
3011 }
3012 req.band = chandef ? chandef->chan->band == NL80211_BAND_5GHZ : 1;
3013
3014 return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(OFFCH_SCAN_CTRL),
3015 &req, sizeof(req), false);
3016}
3017
developer7800b8d2022-06-23 22:15:56 +08003018int besra_mcu_rdd_background_enable(struct besra_phy *phy,
developerb11a5392022-03-31 00:34:47 +08003019 struct cfg80211_chan_def *chandef)
3020{
developer7800b8d2022-06-23 22:15:56 +08003021 struct besra_dev *dev = phy->dev;
developerb11a5392022-03-31 00:34:47 +08003022 int err, region;
3023
3024 if (!chandef) { /* disable offchain */
developer7800b8d2022-06-23 22:15:56 +08003025 err = besra_mcu_rdd_cmd(dev, RDD_STOP, MT_RX_SEL2,
developerb11a5392022-03-31 00:34:47 +08003026 0, 0);
3027 if (err)
3028 return err;
3029
developer7800b8d2022-06-23 22:15:56 +08003030 return besra_mcu_background_chain_ctrl(phy, NULL,
developerb11a5392022-03-31 00:34:47 +08003031 CH_SWITCH_BACKGROUND_SCAN_STOP);
3032 }
3033
developer7800b8d2022-06-23 22:15:56 +08003034 err = besra_mcu_background_chain_ctrl(phy, chandef,
developerb11a5392022-03-31 00:34:47 +08003035 CH_SWITCH_BACKGROUND_SCAN_START);
3036 if (err)
3037 return err;
3038
3039 switch (dev->mt76.region) {
3040 case NL80211_DFS_ETSI:
3041 region = 0;
3042 break;
3043 case NL80211_DFS_JP:
3044 region = 2;
3045 break;
3046 case NL80211_DFS_FCC:
3047 default:
3048 region = 1;
3049 break;
3050 }
3051
developer7800b8d2022-06-23 22:15:56 +08003052 return besra_mcu_rdd_cmd(dev, RDD_START, MT_RX_SEL2,
developerb11a5392022-03-31 00:34:47 +08003053 0, region);
3054}
3055
developer7800b8d2022-06-23 22:15:56 +08003056int besra_mcu_set_chan_info(struct besra_phy *phy, int tag)
developerb11a5392022-03-31 00:34:47 +08003057{
developer66cd2092022-05-10 15:43:01 +08003058 static const u8 ch_band[] = {
3059 [NL80211_BAND_2GHZ] = 0,
3060 [NL80211_BAND_5GHZ] = 1,
3061 [NL80211_BAND_6GHZ] = 2,
3062 };
developer7800b8d2022-06-23 22:15:56 +08003063 struct besra_dev *dev = phy->dev;
developerb11a5392022-03-31 00:34:47 +08003064 struct cfg80211_chan_def *chandef = &phy->mt76->chandef;
3065 int freq1 = chandef->center_freq1;
developer7800b8d2022-06-23 22:15:56 +08003066 u8 phy_idx = besra_get_phy_id(phy);
developerb11a5392022-03-31 00:34:47 +08003067 u16 chainshift;
3068 struct {
3069 /* fixed field */
3070 u8 __rsv[4];
3071
3072 /* TLV*/
3073 __u16 tag;
3074 __u16 len;
3075 u8 control_ch;
3076 u8 center_ch;
3077 u8 bw;
3078 u8 tx_streams_num;
3079 u8 rx_streams; /* mask or num */
3080 u8 switch_reason;
3081 u8 band_idx;
3082 u8 center_ch2; /* for 80+80 only */
3083 __le16 cac_case;
3084 u8 channel_band;
3085 u8 rsv0;
3086 __le32 outband_freq;
3087 u8 txpower_drop;
3088 u8 ap_bw;
3089 u8 ap_center_ch;
3090 u8 rsv1[53];
3091 } __packed req = {
3092 .tag = cpu_to_le16(tag),
3093 .len = cpu_to_le16(sizeof(req) - 4),
3094 .control_ch = chandef->chan->hw_value,
3095 .center_ch = ieee80211_frequency_to_channel(freq1),
3096 .bw = mt76_connac_chan_bw(chandef),
3097 .tx_streams_num = hweight8(phy->mt76->antenna_mask),
3098 .rx_streams = phy->mt76->antenna_mask,
3099 .band_idx = phy->band_idx,
developer66cd2092022-05-10 15:43:01 +08003100 .channel_band = ch_band[chandef->chan->band],
developerb11a5392022-03-31 00:34:47 +08003101 };
3102
3103#ifdef CONFIG_NL80211_TESTMODE
3104 if (phy->mt76->test.tx_antenna_mask &&
3105 (phy->mt76->test.state == MT76_TM_STATE_TX_FRAMES ||
3106 phy->mt76->test.state == MT76_TM_STATE_RX_FRAMES ||
3107 phy->mt76->test.state == MT76_TM_STATE_TX_CONT)) {
3108 req.tx_streams_num = fls(phy->mt76->test.tx_antenna_mask);
3109 req.rx_streams = phy->mt76->test.tx_antenna_mask;
3110
3111 if (phy_idx == MT_MAIN_PHY)
3112 chainshift = 0;
3113 else if (phy_idx == MT_EXT_PHY)
3114 chainshift = dev->chain_shift_ext;
3115 else
3116 chainshift = dev->chain_shift_tri;
3117
3118 req.rx_streams >>= chainshift;
3119 }
3120#endif
3121
developer66cd2092022-05-10 15:43:01 +08003122 if (tag == UNI_CHANNEL_RX_PATH ||
3123 dev->mt76.hw->conf.flags & IEEE80211_CONF_MONITOR)
3124 req.switch_reason = CH_SWITCH_NORMAL;
3125 else if (phy->mt76->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL)
developerb11a5392022-03-31 00:34:47 +08003126 req.switch_reason = CH_SWITCH_SCAN_BYPASS_DPD;
developer66cd2092022-05-10 15:43:01 +08003127 else if (!cfg80211_reg_can_beacon(phy->mt76->hw->wiphy, chandef,
3128 NL80211_IFTYPE_AP))
developerb11a5392022-03-31 00:34:47 +08003129 req.switch_reason = CH_SWITCH_DFS;
3130 else
3131 req.switch_reason = CH_SWITCH_NORMAL;
3132
3133 if (tag == UNI_CHANNEL_SWITCH)
3134 req.rx_streams = hweight8(req.rx_streams);
3135
3136 if (chandef->width == NL80211_CHAN_WIDTH_80P80) {
3137 int freq2 = chandef->center_freq2;
3138
3139 req.center_ch2 = ieee80211_frequency_to_channel(freq2);
3140 }
3141
3142 return mt76_mcu_send_msg(&dev->mt76, MCU_WMWA_UNI_CMD(CHANNEL_SWITCH),
3143 &req, sizeof(req), true);
3144}
3145
developer7800b8d2022-06-23 22:15:56 +08003146static int besra_mcu_set_eeprom_flash(struct besra_dev *dev)
developerb11a5392022-03-31 00:34:47 +08003147{
3148#define MAX_PAGE_IDX_MASK GENMASK(7, 5)
3149#define PAGE_IDX_MASK GENMASK(4, 2)
3150#define PER_PAGE_SIZE 0x400
developer7800b8d2022-06-23 22:15:56 +08003151 struct besra_mcu_eeprom req = {
developerb11a5392022-03-31 00:34:47 +08003152 .tag = cpu_to_le16(UNI_EFUSE_BUFFER_MODE),
3153 .buffer_mode = EE_MODE_BUFFER
3154 };
developer7800b8d2022-06-23 22:15:56 +08003155 u16 eeprom_size = BESRA_EEPROM_SIZE;
developerb11a5392022-03-31 00:34:47 +08003156 u8 total = DIV_ROUND_UP(eeprom_size, PER_PAGE_SIZE);
3157 u8 *eep = (u8 *)dev->mt76.eeprom.data;
3158 int eep_len, i;
3159
3160 for (i = 0; i < total; i++, eep += eep_len) {
3161 struct sk_buff *skb;
3162 int ret, msg_len;
3163
3164 if (i == total - 1 && !!(eeprom_size % PER_PAGE_SIZE))
3165 eep_len = eeprom_size % PER_PAGE_SIZE;
3166 else
3167 eep_len = PER_PAGE_SIZE;
3168
3169 msg_len = sizeof(req) + eep_len;
3170 skb = mt76_mcu_msg_alloc(&dev->mt76, NULL, msg_len);
3171 if (!skb)
3172 return -ENOMEM;
3173
3174 req.len = cpu_to_le16(msg_len - 4);
3175 req.format = FIELD_PREP(MAX_PAGE_IDX_MASK, total - 1) |
3176 FIELD_PREP(PAGE_IDX_MASK, i) | EE_FORMAT_WHOLE;
3177 req.buf_len = cpu_to_le16(eep_len);
3178
3179 skb_put_data(skb, &req, sizeof(req));
3180 skb_put_data(skb, eep, eep_len);
3181
3182 ret = mt76_mcu_skb_send_msg(&dev->mt76, skb,
3183 MCU_WM_UNI_CMD(EFUSE_CTRL), true);
3184 if (ret)
3185 return ret;
3186 }
3187
3188 return 0;
3189}
3190
developer7800b8d2022-06-23 22:15:56 +08003191int besra_mcu_set_eeprom(struct besra_dev *dev)
developerb11a5392022-03-31 00:34:47 +08003192{
developer7800b8d2022-06-23 22:15:56 +08003193 struct besra_mcu_eeprom req = {
developerb11a5392022-03-31 00:34:47 +08003194 .tag = cpu_to_le16(UNI_EFUSE_BUFFER_MODE),
3195 .len = cpu_to_le16(sizeof(req) - 4),
3196 .buffer_mode = EE_MODE_EFUSE,
3197 .format = EE_FORMAT_WHOLE
3198 };
3199
3200 if (dev->flash_mode)
developer7800b8d2022-06-23 22:15:56 +08003201 return besra_mcu_set_eeprom_flash(dev);
developerb11a5392022-03-31 00:34:47 +08003202
3203 return mt76_mcu_send_msg(&dev->mt76, MCU_WM_UNI_CMD(EFUSE_CTRL),
3204 &req, sizeof(req), true);
3205}
3206
developer7800b8d2022-06-23 22:15:56 +08003207int besra_mcu_get_eeprom(struct besra_dev *dev, u32 offset)
developerb11a5392022-03-31 00:34:47 +08003208{
developer7800b8d2022-06-23 22:15:56 +08003209 struct besra_mcu_eeprom_info req = {
developerb11a5392022-03-31 00:34:47 +08003210 .addr = cpu_to_le32(round_down(offset,
developer7800b8d2022-06-23 22:15:56 +08003211 BESRA_EEPROM_BLOCK_SIZE)),
developerb11a5392022-03-31 00:34:47 +08003212 };
developer7800b8d2022-06-23 22:15:56 +08003213 struct besra_mcu_eeprom_info *res;
developerb11a5392022-03-31 00:34:47 +08003214 struct sk_buff *skb;
3215 int ret;
3216 u8 *buf;
3217
3218 ret = mt76_mcu_send_and_get_msg(&dev->mt76, MCU_EXT_QUERY(EFUSE_ACCESS), &req,
3219 sizeof(req), true, &skb);
3220 if (ret)
3221 return ret;
3222
developer7800b8d2022-06-23 22:15:56 +08003223 res = (struct besra_mcu_eeprom_info *)skb->data;
developerb11a5392022-03-31 00:34:47 +08003224 buf = dev->mt76.eeprom.data + le32_to_cpu(res->addr);
developer7800b8d2022-06-23 22:15:56 +08003225 memcpy(buf, res->data, BESRA_EEPROM_BLOCK_SIZE);
developerb11a5392022-03-31 00:34:47 +08003226 dev_kfree_skb(skb);
3227
3228 return 0;
3229}
3230
developer7800b8d2022-06-23 22:15:56 +08003231int besra_mcu_get_eeprom_free_block(struct besra_dev *dev, u8 *block_num)
developerb11a5392022-03-31 00:34:47 +08003232{
3233 struct {
3234 u8 _rsv;
3235 u8 version;
3236 u8 die_idx;
3237 u8 _rsv2;
3238 } __packed req = {
3239 .version = 1,
3240 };
3241 struct sk_buff *skb;
3242 int ret;
3243
3244 ret = mt76_mcu_send_and_get_msg(&dev->mt76, MCU_EXT_QUERY(EFUSE_FREE_BLOCK), &req,
3245 sizeof(req), true, &skb);
3246 if (ret)
3247 return ret;
3248
3249 *block_num = *(u8 *)skb->data;
3250 dev_kfree_skb(skb);
3251
3252 return 0;
3253}
3254
developer7800b8d2022-06-23 22:15:56 +08003255static int besra_mcu_set_pre_cal(struct besra_dev *dev, u8 idx,
developerb11a5392022-03-31 00:34:47 +08003256 u8 *data, u32 len, int cmd)
3257{
3258 struct {
3259 u8 dir;
3260 u8 valid;
3261 __le16 bitmap;
3262 s8 precal;
3263 u8 action;
3264 u8 band;
3265 u8 idx;
3266 u8 rsv[4];
3267 __le32 len;
3268 } req = {};
3269 struct sk_buff *skb;
3270
3271 skb = mt76_mcu_msg_alloc(&dev->mt76, NULL, sizeof(req) + len);
3272 if (!skb)
3273 return -ENOMEM;
3274
3275 req.idx = idx;
3276 req.len = cpu_to_le32(len);
3277 skb_put_data(skb, &req, sizeof(req));
3278 skb_put_data(skb, data, len);
3279
3280 return mt76_mcu_skb_send_msg(&dev->mt76, skb, cmd, false);
3281}
3282
developer7800b8d2022-06-23 22:15:56 +08003283int besra_mcu_apply_group_cal(struct besra_dev *dev)
developerb11a5392022-03-31 00:34:47 +08003284{
3285 u8 idx = 0, *cal = dev->cal, *eep = dev->mt76.eeprom.data;
3286 u32 total = MT_EE_CAL_GROUP_SIZE;
3287
3288 if (1 || !(eep[MT_EE_DO_PRE_CAL] & MT_EE_WIFI_CAL_GROUP))
3289 return 0;
3290
3291 /*
3292 * Items: Rx DCOC, RSSI DCOC, Tx TSSI DCOC, Tx LPFG
3293 * Tx FDIQ, Tx DCIQ, Rx FDIQ, Rx FIIQ, ADCDCOC
3294 */
3295 while (total > 0) {
3296 int ret, len;
3297
3298 len = min_t(u32, total, MT_EE_CAL_UNIT);
3299
developer7800b8d2022-06-23 22:15:56 +08003300 ret = besra_mcu_set_pre_cal(dev, idx, cal, len,
developerb11a5392022-03-31 00:34:47 +08003301 MCU_EXT_CMD(GROUP_PRE_CAL_INFO));
3302 if (ret)
3303 return ret;
3304
3305 total -= len;
3306 cal += len;
3307 idx++;
3308 }
3309
3310 return 0;
3311}
3312
developer7800b8d2022-06-23 22:15:56 +08003313static int besra_find_freq_idx(const u16 *freqs, int n_freqs, u16 cur)
developerb11a5392022-03-31 00:34:47 +08003314{
3315 int i;
3316
3317 for (i = 0; i < n_freqs; i++)
3318 if (cur == freqs[i])
3319 return i;
3320
3321 return -1;
3322}
3323
developer7800b8d2022-06-23 22:15:56 +08003324static int besra_dpd_freq_idx(u16 freq, u8 bw)
developerb11a5392022-03-31 00:34:47 +08003325{
3326 static const u16 freq_list[] = {
3327 5180, 5200, 5220, 5240,
3328 5260, 5280, 5300, 5320,
3329 5500, 5520, 5540, 5560,
3330 5580, 5600, 5620, 5640,
3331 5660, 5680, 5700, 5745,
3332 5765, 5785, 5805, 5825
3333 };
3334 int offset_2g = ARRAY_SIZE(freq_list);
3335 int idx;
3336
3337 if (freq < 4000) {
3338 if (freq < 2432)
3339 return offset_2g;
3340 if (freq < 2457)
3341 return offset_2g + 1;
3342
3343 return offset_2g + 2;
3344 }
3345
3346 if (bw == NL80211_CHAN_WIDTH_80P80 || bw == NL80211_CHAN_WIDTH_160)
3347 return -1;
3348
3349 if (bw != NL80211_CHAN_WIDTH_20) {
developer7800b8d2022-06-23 22:15:56 +08003350 idx = besra_find_freq_idx(freq_list, ARRAY_SIZE(freq_list),
developerb11a5392022-03-31 00:34:47 +08003351 freq + 10);
3352 if (idx >= 0)
3353 return idx;
3354
developer7800b8d2022-06-23 22:15:56 +08003355 idx = besra_find_freq_idx(freq_list, ARRAY_SIZE(freq_list),
developerb11a5392022-03-31 00:34:47 +08003356 freq - 10);
3357 if (idx >= 0)
3358 return idx;
3359 }
3360
developer7800b8d2022-06-23 22:15:56 +08003361 return besra_find_freq_idx(freq_list, ARRAY_SIZE(freq_list), freq);
developerb11a5392022-03-31 00:34:47 +08003362}
3363
developer7800b8d2022-06-23 22:15:56 +08003364int besra_mcu_apply_tx_dpd(struct besra_phy *phy)
developerb11a5392022-03-31 00:34:47 +08003365{
developer7800b8d2022-06-23 22:15:56 +08003366 struct besra_dev *dev = phy->dev;
developerb11a5392022-03-31 00:34:47 +08003367 struct cfg80211_chan_def *chandef = &phy->mt76->chandef;
3368 u16 total = 2, center_freq = chandef->center_freq1;
3369 u8 *cal = dev->cal, *eep = dev->mt76.eeprom.data;
3370 int idx;
3371
3372 if (1 || !(eep[MT_EE_DO_PRE_CAL] & MT_EE_WIFI_CAL_DPD))
3373 return 0;
3374
developer7800b8d2022-06-23 22:15:56 +08003375 idx = besra_dpd_freq_idx(center_freq, chandef->width);
developerb11a5392022-03-31 00:34:47 +08003376 if (idx < 0)
3377 return -EINVAL;
3378
3379 /* Items: Tx DPD, Tx Flatness */
3380 idx = idx * 2;
3381 cal += MT_EE_CAL_GROUP_SIZE;
3382
3383 while (total--) {
3384 int ret;
3385
3386 cal += (idx * MT_EE_CAL_UNIT);
developer7800b8d2022-06-23 22:15:56 +08003387 ret = besra_mcu_set_pre_cal(dev, idx, cal, MT_EE_CAL_UNIT,
developerb11a5392022-03-31 00:34:47 +08003388 MCU_EXT_CMD(DPD_PRE_CAL_INFO));
3389 if (ret)
3390 return ret;
3391
3392 idx++;
3393 }
3394
3395 return 0;
3396}
3397
developer7800b8d2022-06-23 22:15:56 +08003398int besra_mcu_get_chan_mib_info(struct besra_phy *phy, bool chan_switch)
developerb11a5392022-03-31 00:34:47 +08003399{
3400 struct {
3401 struct {
3402 u8 band;
3403 u8 __rsv[3];
3404 } hdr;
3405 struct {
3406 __le16 tag;
3407 __le16 len;
3408 __le32 offs;
3409 } data[4];
3410 } __packed req = {
3411 .hdr.band = phy->band_idx,
3412 };
3413 /* strict order */
3414 static const u32 offs[] = {
3415 MIB_BUSY_TIME, MIB_TX_TIME, MIB_RX_TIME,
3416 MIB_OBSS_AIRTIME
3417 };
3418 struct mt76_channel_state *state = phy->mt76->chan_state;
3419 struct mt76_channel_state *state_ts = &phy->state_ts;
developer7800b8d2022-06-23 22:15:56 +08003420 struct besra_dev *dev = phy->dev;
3421 struct besra_mcu_mib *res;
developerb11a5392022-03-31 00:34:47 +08003422 struct sk_buff *skb;
3423 int i, ret;
3424
3425 for (i = 0; i < 4; i++) {
3426 req.data[i].tag = cpu_to_le16(UNI_CMD_MIB_DATA);
3427 req.data[i].len = cpu_to_le16(sizeof(req.data[i]));
3428 req.data[i].offs = cpu_to_le32(offs[i]);
3429 }
3430
3431 ret = mt76_mcu_send_and_get_msg(&dev->mt76, MCU_WM_UNI_CMD(GET_MIB_INFO),
3432 &req, sizeof(req), true, &skb);
3433 if (ret)
3434 return ret;
3435
3436 skb_pull(skb, sizeof(req.hdr));
3437
developer7800b8d2022-06-23 22:15:56 +08003438 res = (struct besra_mcu_mib *)(skb->data);
developerb11a5392022-03-31 00:34:47 +08003439
3440 if (chan_switch)
3441 goto out;
3442
3443#define __res_u64(s) le64_to_cpu(res[s].data)
3444 state->cc_busy += __res_u64(0) - state_ts->cc_busy;
3445 state->cc_tx += __res_u64(1) - state_ts->cc_tx;
3446 state->cc_bss_rx += __res_u64(2) - state_ts->cc_bss_rx;
3447 state->cc_rx += __res_u64(2) + __res_u64(3) - state_ts->cc_rx;
3448
3449out:
3450 state_ts->cc_busy = __res_u64(0);
3451 state_ts->cc_tx = __res_u64(1);
3452 state_ts->cc_bss_rx = __res_u64(2);
3453 state_ts->cc_rx = __res_u64(2) + __res_u64(3);
3454#undef __res_u64
3455
3456 dev_kfree_skb(skb);
3457
3458 return 0;
3459}
3460
developer7800b8d2022-06-23 22:15:56 +08003461int besra_mcu_get_temperature(struct besra_phy *phy)
developerb11a5392022-03-31 00:34:47 +08003462{
developer7800b8d2022-06-23 22:15:56 +08003463 struct besra_dev *dev = phy->dev;
developerb11a5392022-03-31 00:34:47 +08003464 struct {
3465 u8 ctrl_id;
3466 u8 action;
3467 u8 band;
3468 u8 rsv[5];
3469 } req = {
3470 .ctrl_id = THERMAL_SENSOR_TEMP_QUERY,
3471 .band = phy->band_idx,
3472 };
3473
3474 return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(THERMAL_CTRL), &req,
3475 sizeof(req), true);
3476}
3477
developer7800b8d2022-06-23 22:15:56 +08003478int besra_mcu_set_thermal_throttling(struct besra_phy *phy, u8 state)
developerb11a5392022-03-31 00:34:47 +08003479{
developer7800b8d2022-06-23 22:15:56 +08003480 struct besra_dev *dev = phy->dev;
developerb11a5392022-03-31 00:34:47 +08003481 struct {
developer7800b8d2022-06-23 22:15:56 +08003482 struct besra_mcu_thermal_ctrl ctrl;
developerb11a5392022-03-31 00:34:47 +08003483
3484 __le32 trigger_temp;
3485 __le32 restore_temp;
3486 __le16 sustain_time;
3487 u8 rsv[2];
3488 } __packed req = {
3489 .ctrl = {
3490 .band_idx = phy->band_idx,
3491 },
3492 };
3493 int level;
3494
3495 if (!state) {
3496 req.ctrl.ctrl_id = THERMAL_PROTECT_DISABLE;
3497 goto out;
3498 }
3499
3500 /* set duty cycle and level */
3501 for (level = 0; level < 4; level++) {
3502 int ret;
3503
3504 req.ctrl.ctrl_id = THERMAL_PROTECT_DUTY_CONFIG;
3505 req.ctrl.duty.duty_level = level;
3506 req.ctrl.duty.duty_cycle = state;
3507 state /= 2;
3508
3509 ret = mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(THERMAL_PROT),
3510 &req, sizeof(req.ctrl), false);
3511 if (ret)
3512 return ret;
3513 }
3514
3515 /* set high-temperature trigger threshold */
3516 req.ctrl.ctrl_id = THERMAL_PROTECT_ENABLE;
3517 /* add a safety margin ~10 */
3518 req.restore_temp = cpu_to_le32(phy->throttle_temp[0] - 10);
3519 req.trigger_temp = cpu_to_le32(phy->throttle_temp[1]);
3520 req.sustain_time = cpu_to_le16(10);
3521
3522out:
3523 req.ctrl.type.protect_type = 1;
3524 req.ctrl.type.trigger_type = 1;
3525
3526 return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(THERMAL_PROT),
3527 &req, sizeof(req), false);
3528}
3529
3530#if 0
developer7800b8d2022-06-23 22:15:56 +08003531int besra_mcu_set_txpower_sku(struct besra_phy *phy)
developerb11a5392022-03-31 00:34:47 +08003532{
developer7800b8d2022-06-23 22:15:56 +08003533 struct besra_dev *dev = phy->dev;
developerb11a5392022-03-31 00:34:47 +08003534 struct mt76_phy *mphy = phy->mt76;
3535 struct ieee80211_hw *hw = mphy->hw;
developer7800b8d2022-06-23 22:15:56 +08003536 struct besra_sku_val {
developerb11a5392022-03-31 00:34:47 +08003537 u8 format_id;
3538 u8 limit_type;
3539 u8 band;
developer7800b8d2022-06-23 22:15:56 +08003540 s8 val[BESRA_SKU_RATE_NUM];
developerb11a5392022-03-31 00:34:47 +08003541 } __packed req = {
3542 .format_id = 4,
3543 .band = phy->band_idx,
3544 };
3545 struct mt76_power_limits limits_array;
3546 s8 *la = (s8 *)&limits_array;
3547 int i, idx, n_chains = hweight8(mphy->antenna_mask);
3548 int tx_power = hw->conf.power_level * 2;
3549
3550 tx_power = mt76_get_sar_power(mphy, mphy->chandef.chan,
3551 tx_power);
3552 tx_power -= mt76_tx_power_nss_delta(n_chains);
3553 tx_power = mt76_get_rate_power_limits(mphy, mphy->chandef.chan,
3554 &limits_array, tx_power);
3555 mphy->txpower_cur = tx_power;
3556
developer7800b8d2022-06-23 22:15:56 +08003557 for (i = 0, idx = 0; i < ARRAY_SIZE(besra_sku_group_len); i++) {
3558 u8 mcs_num, len = besra_sku_group_len[i];
developerb11a5392022-03-31 00:34:47 +08003559 int j;
3560
3561 if (i >= SKU_HT_BW20 && i <= SKU_VHT_BW160) {
3562 mcs_num = 10;
3563
3564 if (i == SKU_HT_BW20 || i == SKU_VHT_BW20)
3565 la = (s8 *)&limits_array + 12;
3566 } else {
3567 mcs_num = len;
3568 }
3569
3570 for (j = 0; j < min_t(u8, mcs_num, len); j++)
3571 req.val[idx + j] = la[j];
3572
3573 la += mcs_num;
3574 idx += len;
3575 }
3576
3577 return mt76_mcu_send_msg(&dev->mt76,
3578 MCU_EXT_CMD(TX_POWER_FEATURE_CTRL), &req,
3579 sizeof(req), true);
3580}
3581#endif
3582
developer7800b8d2022-06-23 22:15:56 +08003583int besra_mcu_get_txpower_sku(struct besra_phy *phy, s8 *txpower, int len)
developerb11a5392022-03-31 00:34:47 +08003584{
3585#define RATE_POWER_INFO 2
developer7800b8d2022-06-23 22:15:56 +08003586 struct besra_dev *dev = phy->dev;
developerb11a5392022-03-31 00:34:47 +08003587 struct {
3588 u8 _rsv[4];
3589
3590 __le16 tag;
3591 __le16 len;
3592
3593 u8 format_id;
3594 u8 category;
3595 u8 band;
3596 u8 _rsv2;
3597 } __packed req = {
3598 .tag = cpu_to_le16(UNI_TXPOWER_SHOW_INFO),
3599 .len = cpu_to_le16(sizeof(req) - 4),
3600 .format_id = 7,
3601 .category = RATE_POWER_INFO,
3602 .band = phy->band_idx,
3603 };
developer7800b8d2022-06-23 22:15:56 +08003604 s8 res[BESRA_SKU_RATE_NUM][3];
developerb11a5392022-03-31 00:34:47 +08003605 struct sk_buff *skb;
3606 int ret, i;
3607
3608 ret = mt76_mcu_send_and_get_msg(&dev->mt76, MCU_WM_UNI_CMD(TXPOWER),
3609 &req, sizeof(req), true, &skb);
3610 if (ret)
3611 return ret;
3612
3613 /* TODO: support EHT rates */
3614 skb_pull(skb, 4 + sizeof(struct tlv));
3615 memcpy(res, skb->data, sizeof(res));
3616 for (i = 0; i < len; i++)
3617 txpower[i] = res[i][req.band];
3618
3619 dev_kfree_skb(skb);
3620
3621 return 0;
3622}
3623
developer7800b8d2022-06-23 22:15:56 +08003624int besra_mcu_set_test_param(struct besra_dev *dev, u8 param, bool test_mode,
developerb11a5392022-03-31 00:34:47 +08003625 u8 en)
3626{
3627 struct {
3628 u8 test_mode_en;
3629 u8 param_idx;
3630 u8 _rsv[2];
3631
3632 u8 enable;
3633 u8 _rsv2[3];
3634
3635 u8 pad[8];
3636 } __packed req = {
3637 .test_mode_en = test_mode,
3638 .param_idx = param,
3639 .enable = en,
3640 };
3641
3642 return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(ATE_CTRL), &req,
3643 sizeof(req), false);
3644}
3645
developer7800b8d2022-06-23 22:15:56 +08003646int besra_mcu_set_sku_en(struct besra_phy *phy, bool enable)
developerb11a5392022-03-31 00:34:47 +08003647{
developer7800b8d2022-06-23 22:15:56 +08003648 struct besra_dev *dev = phy->dev;
3649 struct besra_sku {
developerb11a5392022-03-31 00:34:47 +08003650 u8 format_id;
3651 u8 sku_enable;
3652 u8 band;
3653 u8 rsv;
3654 } __packed req = {
3655 .format_id = 0,
3656 .band = phy->band_idx,
3657 .sku_enable = enable,
3658 };
3659
3660 return mt76_mcu_send_msg(&dev->mt76,
3661 MCU_EXT_CMD(TX_POWER_FEATURE_CTRL), &req,
3662 sizeof(req), true);
3663}
3664
developer7800b8d2022-06-23 22:15:56 +08003665int besra_mcu_set_ser(struct besra_dev *dev, u8 action, u8 set, u8 band)
developerb11a5392022-03-31 00:34:47 +08003666{
3667 struct {
3668 u8 action;
3669 u8 set;
3670 u8 band;
3671 u8 rsv;
3672 } req = {
3673 .action = action,
3674 .set = set,
3675 .band = band,
3676 };
3677
3678 return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(SET_SER_TRIGGER),
3679 &req, sizeof(req), false);
3680}
3681
developer7800b8d2022-06-23 22:15:56 +08003682int besra_mcu_set_txbf(struct besra_dev *dev, u8 action)
developerb11a5392022-03-31 00:34:47 +08003683{
3684 struct {
3685 u8 action;
3686 union {
3687 struct {
3688 u8 snd_mode;
3689 u8 sta_num;
3690 u8 rsv;
3691 u8 wlan_idx[4];
3692 __le32 snd_period; /* ms */
3693 } __packed snd;
3694 struct {
3695 bool ebf;
3696 bool ibf;
3697 u8 rsv;
3698 } __packed type;
3699 struct {
3700 u8 bf_num;
3701 u8 bf_bitmap;
3702 u8 bf_sel[8];
3703 u8 rsv[5];
3704 } __packed mod;
3705 };
3706 } __packed req = {
3707 .action = action,
3708 };
3709
3710#define MT_BF_PROCESSING 4
3711 switch (action) {
3712 case MT_BF_SOUNDING_ON:
3713 req.snd.snd_mode = MT_BF_PROCESSING;
3714 break;
3715 case MT_BF_TYPE_UPDATE:
3716 req.type.ebf = true;
3717 req.type.ibf = dev->ibf;
3718 break;
3719 case MT_BF_MODULE_UPDATE:
3720 req.mod.bf_num = 2;
3721 req.mod.bf_bitmap = GENMASK(1, 0);
3722 break;
3723 default:
3724 return -EINVAL;
3725 }
3726
3727 return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(TXBF_ACTION), &req,
3728 sizeof(req), true);
3729}
3730
developer7800b8d2022-06-23 22:15:56 +08003731int besra_mcu_add_obss_spr(struct besra_dev *dev, struct ieee80211_vif *vif,
developerb11a5392022-03-31 00:34:47 +08003732 bool enable)
3733{
3734#define MT_SPR_ENABLE 1
developer7800b8d2022-06-23 22:15:56 +08003735 struct besra_vif *mvif = (struct besra_vif *)vif->drv_priv;
developerb11a5392022-03-31 00:34:47 +08003736 struct {
3737 u8 action;
3738 u8 arg_num;
3739 u8 band_idx;
3740 u8 status;
3741 u8 drop_tx_idx;
3742 u8 sta_idx; /* 256 sta */
3743 u8 rsv[2];
3744 __le32 val;
3745 } __packed req = {
3746 .action = MT_SPR_ENABLE,
3747 .arg_num = 1,
3748 .band_idx = mvif->mt76.band_idx,
3749 .val = cpu_to_le32(enable),
3750 };
3751
3752 return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(SET_SPR), &req,
3753 sizeof(req), true);
3754}
3755
developer7800b8d2022-06-23 22:15:56 +08003756int besra_mcu_get_rx_rate(struct besra_phy *phy, struct ieee80211_vif *vif,
developerb11a5392022-03-31 00:34:47 +08003757 struct ieee80211_sta *sta, struct rate_info *rate)
3758{
developer7800b8d2022-06-23 22:15:56 +08003759 struct besra_vif *mvif = (struct besra_vif *)vif->drv_priv;
3760 struct besra_sta *msta = (struct besra_sta *)sta->drv_priv;
3761 struct besra_dev *dev = phy->dev;
developerb11a5392022-03-31 00:34:47 +08003762 struct mt76_phy *mphy = phy->mt76;
3763 struct {
3764 u8 category;
3765 u8 band;
3766 __le16 wcid;
3767 } __packed req = {
3768 .category = MCU_PHY_STATE_CONTENTION_RX_RATE,
3769 .band = mvif->mt76.band_idx,
3770 .wcid = cpu_to_le16(msta->wcid.idx),
3771 };
3772 struct ieee80211_supported_band *sband;
developer7800b8d2022-06-23 22:15:56 +08003773 struct besra_mcu_phy_rx_info *res;
developerb11a5392022-03-31 00:34:47 +08003774 struct sk_buff *skb;
3775 int ret;
3776 bool cck = false;
3777
3778 ret = mt76_mcu_send_and_get_msg(&dev->mt76, MCU_EXT_CMD(PHY_STAT_INFO),
3779 &req, sizeof(req), true, &skb);
3780 if (ret)
3781 return ret;
3782
developer7800b8d2022-06-23 22:15:56 +08003783 res = (struct besra_mcu_phy_rx_info *)skb->data;
developerb11a5392022-03-31 00:34:47 +08003784
3785 rate->mcs = res->rate;
3786 rate->nss = res->nsts + 1;
3787
3788 switch (res->mode) {
3789 case MT_PHY_TYPE_CCK:
3790 cck = true;
3791 fallthrough;
3792 case MT_PHY_TYPE_OFDM:
3793 if (mphy->chandef.chan->band == NL80211_BAND_5GHZ)
3794 sband = &mphy->sband_5g.sband;
developer66cd2092022-05-10 15:43:01 +08003795 else if (mphy->chandef.chan->band == NL80211_BAND_6GHZ)
3796 sband = &mphy->sband_6g.sband;
developerb11a5392022-03-31 00:34:47 +08003797 else
3798 sband = &mphy->sband_2g.sband;
3799
3800 rate->mcs = mt76_get_rate(&dev->mt76, sband, rate->mcs, cck);
3801 rate->legacy = sband->bitrates[rate->mcs].bitrate;
3802 break;
3803 case MT_PHY_TYPE_HT:
3804 case MT_PHY_TYPE_HT_GF:
3805 if (rate->mcs > 31) {
3806 ret = -EINVAL;
3807 goto out;
3808 }
3809
3810 rate->flags = RATE_INFO_FLAGS_MCS;
3811 if (res->gi)
3812 rate->flags |= RATE_INFO_FLAGS_SHORT_GI;
3813 break;
3814 case MT_PHY_TYPE_VHT:
3815 if (rate->mcs > 9) {
3816 ret = -EINVAL;
3817 goto out;
3818 }
3819
3820 rate->flags = RATE_INFO_FLAGS_VHT_MCS;
3821 if (res->gi)
3822 rate->flags |= RATE_INFO_FLAGS_SHORT_GI;
3823 break;
3824 case MT_PHY_TYPE_HE_SU:
3825 case MT_PHY_TYPE_HE_EXT_SU:
3826 case MT_PHY_TYPE_HE_TB:
3827 case MT_PHY_TYPE_HE_MU:
3828 if (res->gi > NL80211_RATE_INFO_HE_GI_3_2 || rate->mcs > 11) {
3829 ret = -EINVAL;
3830 goto out;
3831 }
3832 rate->he_gi = res->gi;
3833 rate->flags = RATE_INFO_FLAGS_HE_MCS;
3834 break;
3835 default:
3836 ret = -EINVAL;
3837 goto out;
3838 }
3839
3840 switch (res->bw) {
3841 case IEEE80211_STA_RX_BW_160:
3842 rate->bw = RATE_INFO_BW_160;
3843 break;
3844 case IEEE80211_STA_RX_BW_80:
3845 rate->bw = RATE_INFO_BW_80;
3846 break;
3847 case IEEE80211_STA_RX_BW_40:
3848 rate->bw = RATE_INFO_BW_40;
3849 break;
3850 default:
3851 rate->bw = RATE_INFO_BW_20;
3852 break;
3853 }
3854
3855out:
3856 dev_kfree_skb(skb);
3857
3858 return ret;
3859}
3860
developer7800b8d2022-06-23 22:15:56 +08003861int besra_mcu_update_bss_color(struct besra_dev *dev, struct ieee80211_vif *vif,
developerb11a5392022-03-31 00:34:47 +08003862 struct cfg80211_he_bss_color *he_bss_color)
3863{
3864 int len = sizeof(struct bss_req_hdr) + sizeof(struct bss_color_tlv);
developer7800b8d2022-06-23 22:15:56 +08003865 struct besra_vif *mvif = (struct besra_vif *)vif->drv_priv;
developerb11a5392022-03-31 00:34:47 +08003866 struct bss_color_tlv *bss_color;
3867 struct sk_buff *skb;
3868 struct tlv *tlv;
3869
developer7800b8d2022-06-23 22:15:56 +08003870 skb = __besra_mcu_alloc_bss_req(&dev->mt76, &mvif->mt76, len);
developerb11a5392022-03-31 00:34:47 +08003871 if (IS_ERR(skb))
3872 return PTR_ERR(skb);
3873
3874 tlv = mt76_connac_mcu_add_tlv(skb, UNI_BSS_INFO_BSS_COLOR,
3875 sizeof(*bss_color));
3876 bss_color = (struct bss_color_tlv *)tlv;
3877 bss_color->enable = he_bss_color->enabled;
3878 bss_color->color = he_bss_color->color;
3879
3880 return mt76_mcu_skb_send_msg(&dev->mt76, skb,
3881 MCU_WMWA_UNI_CMD(BSS_INFO_UPDATE), true);
3882}
3883
3884#define TWT_AGRT_TRIGGER BIT(0)
3885#define TWT_AGRT_ANNOUNCE BIT(1)
3886#define TWT_AGRT_PROTECT BIT(2)
3887
developer7800b8d2022-06-23 22:15:56 +08003888int besra_mcu_twt_agrt_update(struct besra_dev *dev,
3889 struct besra_vif *mvif,
3890 struct besra_twt_flow *flow,
developerb11a5392022-03-31 00:34:47 +08003891 int cmd)
3892{
3893 struct {
3894 u8 tbl_idx;
3895 u8 cmd;
3896 u8 own_mac_idx;
3897 u8 flowid; /* 0xff for group id */
3898 __le16 peer_id; /* specify the peer_id (msb=0)
3899 * or group_id (msb=1)
3900 */
3901 u8 duration; /* 256 us */
3902 u8 bss_idx;
3903 __le64 start_tsf;
3904 __le16 mantissa;
3905 u8 exponent;
3906 u8 is_ap;
3907 u8 agrt_params;
3908 u8 rsv[23];
3909 } __packed req = {
3910 .tbl_idx = flow->table_id,
3911 .cmd = cmd,
3912 .own_mac_idx = mvif->mt76.omac_idx,
3913 .flowid = flow->id,
3914 .peer_id = cpu_to_le16(flow->wcid),
3915 .duration = flow->duration,
3916 .bss_idx = mvif->mt76.idx,
3917 .start_tsf = cpu_to_le64(flow->tsf),
3918 .mantissa = flow->mantissa,
3919 .exponent = flow->exp,
3920 .is_ap = true,
3921 };
3922
3923 if (flow->protection)
3924 req.agrt_params |= TWT_AGRT_PROTECT;
3925 if (!flow->flowtype)
3926 req.agrt_params |= TWT_AGRT_ANNOUNCE;
3927 if (flow->trigger)
3928 req.agrt_params |= TWT_AGRT_TRIGGER;
3929
3930 return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(TWT_AGRT_UPDATE),
3931 &req, sizeof(req), true);
3932}
3933
3934
developer7800b8d2022-06-23 22:15:56 +08003935void besra_mcu_set_pm(void *priv, u8 *mac, struct ieee80211_vif *vif)
developerb11a5392022-03-31 00:34:47 +08003936{
3937#define EXIT_PM_STATE 0
3938#define ENTER_PM_STATE 1
3939 struct ieee80211_hw *hw = priv;
developer7800b8d2022-06-23 22:15:56 +08003940 struct besra_dev *dev = besra_hw_dev(hw);
3941 struct besra_phy *phy = besra_hw_phy(hw);
3942 struct besra_vif *mvif = (struct besra_vif *)vif->drv_priv;
developerb11a5392022-03-31 00:34:47 +08003943 struct bss_power_save *ps;
3944 struct sk_buff *skb;
3945 struct tlv *tlv;
3946 bool running = test_bit(MT76_STATE_RUNNING, &phy->mt76->state);
3947
developer7800b8d2022-06-23 22:15:56 +08003948 skb = __besra_mcu_alloc_bss_req(&dev->mt76, &mvif->mt76,
3949 BESRA_BSS_UPDATE_MAX_SIZE);
developerb11a5392022-03-31 00:34:47 +08003950 if (IS_ERR(skb))
3951 return;
3952
developer7800b8d2022-06-23 22:15:56 +08003953 tlv = besra_mcu_add_uni_tlv(skb, UNI_BSS_INFO_PS, sizeof(*ps));
developerb11a5392022-03-31 00:34:47 +08003954 ps = (struct bss_power_save *)tlv;
3955 ps->profile = running ? EXIT_PM_STATE : ENTER_PM_STATE;
3956
3957 mt76_mcu_skb_send_msg(&dev->mt76, skb,
3958 MCU_WMWA_UNI_CMD(BSS_INFO_UPDATE), true);
3959}
3960
developer7800b8d2022-06-23 22:15:56 +08003961int besra_mcu_set_rts_thresh(struct besra_phy *phy, u32 val)
developerb11a5392022-03-31 00:34:47 +08003962{
3963 struct {
3964 u8 band_idx;
3965 u8 _rsv[3];
3966
3967 __le16 tag;
3968 __le16 len;
3969 __le32 len_thresh;
3970 __le32 pkt_thresh;
3971 } __packed req = {
3972 .band_idx = phy->band_idx,
3973 .tag = cpu_to_le16(UNI_BAND_CONFIG_RTS_THRESHOLD),
3974 .len = cpu_to_le16(sizeof(req) - 4),
3975 .len_thresh = cpu_to_le32(val),
3976 .pkt_thresh = cpu_to_le32(0x2),
3977 };
3978
3979 return mt76_mcu_send_msg(&phy->dev->mt76, MCU_WM_UNI_CMD(BAND_CONFIG),
3980 &req, sizeof(req), true);
3981}
3982
developer7800b8d2022-06-23 22:15:56 +08003983int besra_mcu_set_radio_en(struct besra_phy *phy, bool enable)
developerb11a5392022-03-31 00:34:47 +08003984{
3985 struct {
3986 u8 band_idx;
3987 u8 _rsv[3];
3988
3989 __le16 tag;
3990 __le16 len;
3991 u8 enable;
3992 u8 _rsv2[3];
3993 } __packed req = {
3994 .band_idx = phy->band_idx,
3995 .tag = cpu_to_le16(UNI_BAND_CONFIG_RADIO_ENABLE),
3996 .len = cpu_to_le16(sizeof(req) - 4),
3997 .enable = enable,
3998 };
3999
4000 return mt76_mcu_send_msg(&phy->dev->mt76, MCU_WM_UNI_CMD(BAND_CONFIG),
4001 &req, sizeof(req), true);
4002}
4003
developer7800b8d2022-06-23 22:15:56 +08004004int besra_mcu_set_edcca_thresh(struct besra_phy *phy)
developerb11a5392022-03-31 00:34:47 +08004005{
4006 struct {
4007 u8 band_idx;
4008 u8 _rsv[3];
4009
4010 __le16 tag;
4011 __le16 len;
4012 u8 thresh[3];
4013 u8 fginit;
4014 } __packed req = {
4015 .band_idx = phy->band_idx,
4016 .tag = cpu_to_le16(UNI_BAND_CONFIG_EDCCA_THRESHOLD),
4017 .len = cpu_to_le16(sizeof(req) - 4),
4018 .thresh = {0x7f, 0x7f, 0x7f},
4019 .fginit = 1,
4020 };
4021
4022 return mt76_mcu_send_msg(&phy->dev->mt76, MCU_WM_UNI_CMD(BAND_CONFIG),
4023 &req, sizeof(req), true);
4024}
4025
developer7800b8d2022-06-23 22:15:56 +08004026int besra_mcu_set_edcca_en(struct besra_phy *phy, bool enable)
developerb11a5392022-03-31 00:34:47 +08004027{
4028 struct {
4029 u8 band_idx;
4030 u8 _rsv[3];
4031
4032 __le16 tag;
4033 __le16 len;
4034 u8 enable;
4035 u8 _rsv2[3];
4036 } __packed req = {
4037 .band_idx = phy->band_idx,
4038 .tag = cpu_to_le16(UNI_BAND_CONFIG_EDCCA_ENABLE),
4039 .len = cpu_to_le16(sizeof(req) - 4),
4040 .enable = enable,
4041 };
4042
4043 return mt76_mcu_send_msg(&phy->dev->mt76, MCU_WM_UNI_CMD(BAND_CONFIG),
4044 &req, sizeof(req), true);
4045}
4046
developer7800b8d2022-06-23 22:15:56 +08004047int besra_mcu_rdd_cmd(struct besra_dev *dev, int cmd, u8 index,
developerb11a5392022-03-31 00:34:47 +08004048 u8 rx_sel, u8 val)
4049{
4050 struct {
4051 u8 _rsv[4];
4052
4053 __le16 tag;
4054 __le16 len;
4055
4056 u8 ctrl;
4057 u8 rdd_idx;
4058 u8 rdd_rx_sel;
4059 u8 val;
4060 u8 rsv[4];
4061 } __packed req = {
4062 .tag = cpu_to_le16(UNI_RDD_CTRL_PARM),
4063 .len = cpu_to_le16(sizeof(req) - 4),
4064 .ctrl = cmd,
4065 .rdd_idx = index,
4066 .rdd_rx_sel = rx_sel,
4067 .val = val,
4068 };
4069
4070 /* Todo: check return value. return 0 is bellwether workaround.
4071 Bellwether does not enable RDD.
4072 */
4073 mt76_mcu_send_msg(&dev->mt76, MCU_WM_UNI_CMD(RDD_CTRL),
4074 &req, sizeof(req), true);
4075 return 0;
4076}
developer66cd2092022-05-10 15:43:01 +08004077
4078
developer7800b8d2022-06-23 22:15:56 +08004079int besra_mcu_wtbl_update_hdr_trans(struct besra_dev *dev,
developer66cd2092022-05-10 15:43:01 +08004080 struct ieee80211_vif *vif, struct ieee80211_sta *sta)
4081{
developer7800b8d2022-06-23 22:15:56 +08004082 struct besra_vif *mvif = (struct besra_vif *)vif->drv_priv;
4083 struct besra_sta *msta;
developer66cd2092022-05-10 15:43:01 +08004084 struct sk_buff *skb;
4085
developer7800b8d2022-06-23 22:15:56 +08004086 msta = sta ? (struct besra_sta *)sta->drv_priv : &mvif->sta;
developer66cd2092022-05-10 15:43:01 +08004087
4088 skb = mt76_connac_mcu_alloc_sta_req(&dev->mt76, &mvif->mt76,
4089 &msta->wcid);
4090 if (IS_ERR(skb))
4091 return PTR_ERR(skb);
4092
4093 /* starec hdr trans */
developer7800b8d2022-06-23 22:15:56 +08004094 besra_mcu_sta_hdr_trans_tlv(dev, skb, vif, sta);
developer66cd2092022-05-10 15:43:01 +08004095 return mt76_mcu_skb_send_msg(&dev->mt76, skb,
4096 MCU_WMWA_UNI_CMD(STA_REC_UPDATE), true);
4097}
4098
developer7800b8d2022-06-23 22:15:56 +08004099int besra_mcu_rf_regval(struct besra_dev *dev, u32 regidx, u32 *val, bool set)
developer66cd2092022-05-10 15:43:01 +08004100{
4101 struct {
4102 __le32 idx;
4103 __le32 ofs;
4104 __le32 data;
4105 } __packed req = {
4106 .idx = cpu_to_le32(u32_get_bits(regidx, GENMASK(31, 28))),
4107 .ofs = cpu_to_le32(u32_get_bits(regidx, GENMASK(27, 0))),
4108 .data = set ? cpu_to_le32(*val) : 0,
4109 };
4110 struct sk_buff *skb;
4111 int ret;
4112
4113 if (set)
4114 return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(RF_REG_ACCESS),
4115 &req, sizeof(req), false);
4116
4117 ret = mt76_mcu_send_and_get_msg(&dev->mt76, MCU_EXT_QUERY(RF_REG_ACCESS),
4118 &req, sizeof(req), true, &skb);
4119 if (ret)
4120 return ret;
4121
4122 *val = le32_to_cpu(*(__le32 *)(skb->data + 8));
4123 dev_kfree_skb(skb);
4124
4125 return 0;
4126}