Loading...
1// SPDX-License-Identifier: ISC
2/* Copyright (C) 2023 MediaTek Inc. */
3
4#include <linux/module.h>
5#include <linux/firmware.h>
6
7#include "mt792x.h"
8#include "dma.h"
9
10static const struct ieee80211_iface_limit if_limits[] = {
11 {
12 .max = MT792x_MAX_INTERFACES,
13 .types = BIT(NL80211_IFTYPE_STATION)
14 },
15 {
16 .max = 1,
17 .types = BIT(NL80211_IFTYPE_AP)
18 }
19};
20
21static const struct ieee80211_iface_combination if_comb[] = {
22 {
23 .limits = if_limits,
24 .n_limits = ARRAY_SIZE(if_limits),
25 .max_interfaces = MT792x_MAX_INTERFACES,
26 .num_different_channels = 1,
27 .beacon_int_infra_match = true,
28 },
29};
30
31static const struct ieee80211_iface_limit if_limits_chanctx[] = {
32 {
33 .max = 2,
34 .types = BIT(NL80211_IFTYPE_STATION) |
35 BIT(NL80211_IFTYPE_P2P_CLIENT)
36 },
37 {
38 .max = 1,
39 .types = BIT(NL80211_IFTYPE_AP) |
40 BIT(NL80211_IFTYPE_P2P_GO)
41 }
42};
43
44static const struct ieee80211_iface_combination if_comb_chanctx[] = {
45 {
46 .limits = if_limits_chanctx,
47 .n_limits = ARRAY_SIZE(if_limits_chanctx),
48 .max_interfaces = 2,
49 .num_different_channels = 2,
50 .beacon_int_infra_match = false,
51 }
52};
53
54void mt792x_tx(struct ieee80211_hw *hw, struct ieee80211_tx_control *control,
55 struct sk_buff *skb)
56{
57 struct mt792x_dev *dev = mt792x_hw_dev(hw);
58 struct mt76_phy *mphy = hw->priv;
59 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
60 struct ieee80211_vif *vif = info->control.vif;
61 struct mt76_wcid *wcid = &dev->mt76.global_wcid;
62 int qid;
63
64 if (control->sta) {
65 struct mt792x_sta *sta;
66
67 sta = (struct mt792x_sta *)control->sta->drv_priv;
68 wcid = &sta->wcid;
69 }
70
71 if (vif && !control->sta) {
72 struct mt792x_vif *mvif;
73
74 mvif = (struct mt792x_vif *)vif->drv_priv;
75 wcid = &mvif->sta.wcid;
76 }
77
78 if (mt76_connac_pm_ref(mphy, &dev->pm)) {
79 mt76_tx(mphy, control->sta, wcid, skb);
80 mt76_connac_pm_unref(mphy, &dev->pm);
81 return;
82 }
83
84 qid = skb_get_queue_mapping(skb);
85 if (qid >= MT_TXQ_PSD) {
86 qid = IEEE80211_AC_BE;
87 skb_set_queue_mapping(skb, qid);
88 }
89
90 mt76_connac_pm_queue_skb(hw, &dev->pm, wcid, skb);
91}
92EXPORT_SYMBOL_GPL(mt792x_tx);
93
94void mt792x_stop(struct ieee80211_hw *hw)
95{
96 struct mt792x_dev *dev = mt792x_hw_dev(hw);
97 struct mt792x_phy *phy = mt792x_hw_phy(hw);
98
99 cancel_delayed_work_sync(&phy->mt76->mac_work);
100
101 cancel_delayed_work_sync(&dev->pm.ps_work);
102 cancel_work_sync(&dev->pm.wake_work);
103 cancel_work_sync(&dev->reset_work);
104 mt76_connac_free_pending_tx_skbs(&dev->pm, NULL);
105
106 if (is_mt7921(&dev->mt76)) {
107 mt792x_mutex_acquire(dev);
108 mt76_connac_mcu_set_mac_enable(&dev->mt76, 0, false, false);
109 mt792x_mutex_release(dev);
110 }
111
112 clear_bit(MT76_STATE_RUNNING, &phy->mt76->state);
113}
114EXPORT_SYMBOL_GPL(mt792x_stop);
115
116void mt792x_remove_interface(struct ieee80211_hw *hw,
117 struct ieee80211_vif *vif)
118{
119 struct mt792x_vif *mvif = (struct mt792x_vif *)vif->drv_priv;
120 struct mt792x_sta *msta = &mvif->sta;
121 struct mt792x_dev *dev = mt792x_hw_dev(hw);
122 struct mt792x_phy *phy = mt792x_hw_phy(hw);
123 int idx = msta->wcid.idx;
124
125 mt792x_mutex_acquire(dev);
126 mt76_connac_free_pending_tx_skbs(&dev->pm, &msta->wcid);
127 mt76_connac_mcu_uni_add_dev(&dev->mphy, vif, &mvif->sta.wcid, false);
128
129 rcu_assign_pointer(dev->mt76.wcid[idx], NULL);
130
131 dev->mt76.vif_mask &= ~BIT_ULL(mvif->mt76.idx);
132 phy->omac_mask &= ~BIT_ULL(mvif->mt76.omac_idx);
133 mt792x_mutex_release(dev);
134
135 spin_lock_bh(&dev->mt76.sta_poll_lock);
136 if (!list_empty(&msta->wcid.poll_list))
137 list_del_init(&msta->wcid.poll_list);
138 spin_unlock_bh(&dev->mt76.sta_poll_lock);
139
140 mt76_wcid_cleanup(&dev->mt76, &msta->wcid);
141}
142EXPORT_SYMBOL_GPL(mt792x_remove_interface);
143
144int mt792x_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
145 unsigned int link_id, u16 queue,
146 const struct ieee80211_tx_queue_params *params)
147{
148 struct mt792x_vif *mvif = (struct mt792x_vif *)vif->drv_priv;
149
150 /* no need to update right away, we'll get BSS_CHANGED_QOS */
151 queue = mt76_connac_lmac_mapping(queue);
152 mvif->queue_params[queue] = *params;
153
154 return 0;
155}
156EXPORT_SYMBOL_GPL(mt792x_conf_tx);
157
158int mt792x_get_stats(struct ieee80211_hw *hw,
159 struct ieee80211_low_level_stats *stats)
160{
161 struct mt792x_phy *phy = mt792x_hw_phy(hw);
162 struct mt76_mib_stats *mib = &phy->mib;
163
164 mt792x_mutex_acquire(phy->dev);
165
166 stats->dot11RTSSuccessCount = mib->rts_cnt;
167 stats->dot11RTSFailureCount = mib->rts_retries_cnt;
168 stats->dot11FCSErrorCount = mib->fcs_err_cnt;
169 stats->dot11ACKFailureCount = mib->ack_fail_cnt;
170
171 mt792x_mutex_release(phy->dev);
172
173 return 0;
174}
175EXPORT_SYMBOL_GPL(mt792x_get_stats);
176
177u64 mt792x_get_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
178{
179 struct mt792x_vif *mvif = (struct mt792x_vif *)vif->drv_priv;
180 struct mt792x_dev *dev = mt792x_hw_dev(hw);
181 u8 omac_idx = mvif->mt76.omac_idx;
182 union {
183 u64 t64;
184 u32 t32[2];
185 } tsf;
186 u16 n;
187
188 mt792x_mutex_acquire(dev);
189
190 n = omac_idx > HW_BSSID_MAX ? HW_BSSID_0 : omac_idx;
191 /* TSF software read */
192 mt76_set(dev, MT_LPON_TCR(0, n), MT_LPON_TCR_SW_MODE);
193 tsf.t32[0] = mt76_rr(dev, MT_LPON_UTTR0(0));
194 tsf.t32[1] = mt76_rr(dev, MT_LPON_UTTR1(0));
195
196 mt792x_mutex_release(dev);
197
198 return tsf.t64;
199}
200EXPORT_SYMBOL_GPL(mt792x_get_tsf);
201
202void mt792x_set_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
203 u64 timestamp)
204{
205 struct mt792x_vif *mvif = (struct mt792x_vif *)vif->drv_priv;
206 struct mt792x_dev *dev = mt792x_hw_dev(hw);
207 u8 omac_idx = mvif->mt76.omac_idx;
208 union {
209 u64 t64;
210 u32 t32[2];
211 } tsf = { .t64 = timestamp, };
212 u16 n;
213
214 mt792x_mutex_acquire(dev);
215
216 n = omac_idx > HW_BSSID_MAX ? HW_BSSID_0 : omac_idx;
217 mt76_wr(dev, MT_LPON_UTTR0(0), tsf.t32[0]);
218 mt76_wr(dev, MT_LPON_UTTR1(0), tsf.t32[1]);
219 /* TSF software overwrite */
220 mt76_set(dev, MT_LPON_TCR(0, n), MT_LPON_TCR_SW_WRITE);
221
222 mt792x_mutex_release(dev);
223}
224EXPORT_SYMBOL_GPL(mt792x_set_tsf);
225
226void mt792x_tx_worker(struct mt76_worker *w)
227{
228 struct mt792x_dev *dev = container_of(w, struct mt792x_dev,
229 mt76.tx_worker);
230
231 if (!mt76_connac_pm_ref(&dev->mphy, &dev->pm)) {
232 queue_work(dev->mt76.wq, &dev->pm.wake_work);
233 return;
234 }
235
236 mt76_txq_schedule_all(&dev->mphy);
237 mt76_connac_pm_unref(&dev->mphy, &dev->pm);
238}
239EXPORT_SYMBOL_GPL(mt792x_tx_worker);
240
241void mt792x_roc_timer(struct timer_list *timer)
242{
243 struct mt792x_phy *phy = from_timer(phy, timer, roc_timer);
244
245 ieee80211_queue_work(phy->mt76->hw, &phy->roc_work);
246}
247EXPORT_SYMBOL_GPL(mt792x_roc_timer);
248
249void mt792x_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
250 u32 queues, bool drop)
251{
252 struct mt792x_dev *dev = mt792x_hw_dev(hw);
253
254 wait_event_timeout(dev->mt76.tx_wait,
255 !mt76_has_tx_pending(&dev->mphy), HZ / 2);
256}
257EXPORT_SYMBOL_GPL(mt792x_flush);
258
259int mt792x_assign_vif_chanctx(struct ieee80211_hw *hw,
260 struct ieee80211_vif *vif,
261 struct ieee80211_bss_conf *link_conf,
262 struct ieee80211_chanctx_conf *ctx)
263{
264 struct mt792x_vif *mvif = (struct mt792x_vif *)vif->drv_priv;
265 struct mt792x_dev *dev = mt792x_hw_dev(hw);
266
267 mutex_lock(&dev->mt76.mutex);
268 mvif->mt76.ctx = ctx;
269 mutex_unlock(&dev->mt76.mutex);
270
271 return 0;
272}
273EXPORT_SYMBOL_GPL(mt792x_assign_vif_chanctx);
274
275void mt792x_unassign_vif_chanctx(struct ieee80211_hw *hw,
276 struct ieee80211_vif *vif,
277 struct ieee80211_bss_conf *link_conf,
278 struct ieee80211_chanctx_conf *ctx)
279{
280 struct mt792x_vif *mvif = (struct mt792x_vif *)vif->drv_priv;
281 struct mt792x_dev *dev = mt792x_hw_dev(hw);
282
283 mutex_lock(&dev->mt76.mutex);
284 mvif->mt76.ctx = NULL;
285 mutex_unlock(&dev->mt76.mutex);
286}
287EXPORT_SYMBOL_GPL(mt792x_unassign_vif_chanctx);
288
289void mt792x_set_wakeup(struct ieee80211_hw *hw, bool enabled)
290{
291 struct mt792x_dev *dev = mt792x_hw_dev(hw);
292 struct mt76_dev *mdev = &dev->mt76;
293
294 device_set_wakeup_enable(mdev->dev, enabled);
295}
296EXPORT_SYMBOL_GPL(mt792x_set_wakeup);
297
298static const char mt792x_gstrings_stats[][ETH_GSTRING_LEN] = {
299 /* tx counters */
300 "tx_ampdu_cnt",
301 "tx_mpdu_attempts",
302 "tx_mpdu_success",
303 "tx_pkt_ebf_cnt",
304 "tx_pkt_ibf_cnt",
305 "tx_ampdu_len:0-1",
306 "tx_ampdu_len:2-10",
307 "tx_ampdu_len:11-19",
308 "tx_ampdu_len:20-28",
309 "tx_ampdu_len:29-37",
310 "tx_ampdu_len:38-46",
311 "tx_ampdu_len:47-55",
312 "tx_ampdu_len:56-79",
313 "tx_ampdu_len:80-103",
314 "tx_ampdu_len:104-127",
315 "tx_ampdu_len:128-151",
316 "tx_ampdu_len:152-175",
317 "tx_ampdu_len:176-199",
318 "tx_ampdu_len:200-223",
319 "tx_ampdu_len:224-247",
320 "ba_miss_count",
321 "tx_beamformer_ppdu_iBF",
322 "tx_beamformer_ppdu_eBF",
323 "tx_beamformer_rx_feedback_all",
324 "tx_beamformer_rx_feedback_he",
325 "tx_beamformer_rx_feedback_vht",
326 "tx_beamformer_rx_feedback_ht",
327 "tx_msdu_pack_1",
328 "tx_msdu_pack_2",
329 "tx_msdu_pack_3",
330 "tx_msdu_pack_4",
331 "tx_msdu_pack_5",
332 "tx_msdu_pack_6",
333 "tx_msdu_pack_7",
334 "tx_msdu_pack_8",
335 /* rx counters */
336 "rx_mpdu_cnt",
337 "rx_ampdu_cnt",
338 "rx_ampdu_bytes_cnt",
339 "rx_ba_cnt",
340 /* per vif counters */
341 "v_tx_mode_cck",
342 "v_tx_mode_ofdm",
343 "v_tx_mode_ht",
344 "v_tx_mode_ht_gf",
345 "v_tx_mode_vht",
346 "v_tx_mode_he_su",
347 "v_tx_mode_he_ext_su",
348 "v_tx_mode_he_tb",
349 "v_tx_mode_he_mu",
350 "v_tx_mode_eht_su",
351 "v_tx_mode_eht_trig",
352 "v_tx_mode_eht_mu",
353 "v_tx_bw_20",
354 "v_tx_bw_40",
355 "v_tx_bw_80",
356 "v_tx_bw_160",
357 "v_tx_mcs_0",
358 "v_tx_mcs_1",
359 "v_tx_mcs_2",
360 "v_tx_mcs_3",
361 "v_tx_mcs_4",
362 "v_tx_mcs_5",
363 "v_tx_mcs_6",
364 "v_tx_mcs_7",
365 "v_tx_mcs_8",
366 "v_tx_mcs_9",
367 "v_tx_mcs_10",
368 "v_tx_mcs_11",
369 "v_tx_mcs_12",
370 "v_tx_mcs_13",
371 "v_tx_nss_1",
372 "v_tx_nss_2",
373 "v_tx_nss_3",
374 "v_tx_nss_4",
375};
376
377void mt792x_get_et_strings(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
378 u32 sset, u8 *data)
379{
380 if (sset != ETH_SS_STATS)
381 return;
382
383 memcpy(data, mt792x_gstrings_stats, sizeof(mt792x_gstrings_stats));
384
385 data += sizeof(mt792x_gstrings_stats);
386 page_pool_ethtool_stats_get_strings(data);
387}
388EXPORT_SYMBOL_GPL(mt792x_get_et_strings);
389
390int mt792x_get_et_sset_count(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
391 int sset)
392{
393 if (sset != ETH_SS_STATS)
394 return 0;
395
396 return ARRAY_SIZE(mt792x_gstrings_stats) +
397 page_pool_ethtool_stats_get_count();
398}
399EXPORT_SYMBOL_GPL(mt792x_get_et_sset_count);
400
401static void
402mt792x_ethtool_worker(void *wi_data, struct ieee80211_sta *sta)
403{
404 struct mt792x_sta *msta = (struct mt792x_sta *)sta->drv_priv;
405 struct mt76_ethtool_worker_info *wi = wi_data;
406
407 if (msta->vif->mt76.idx != wi->idx)
408 return;
409
410 mt76_ethtool_worker(wi, &msta->wcid.stats, true);
411}
412
413void mt792x_get_et_stats(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
414 struct ethtool_stats *stats, u64 *data)
415{
416 struct mt792x_vif *mvif = (struct mt792x_vif *)vif->drv_priv;
417 int stats_size = ARRAY_SIZE(mt792x_gstrings_stats);
418 struct mt792x_phy *phy = mt792x_hw_phy(hw);
419 struct mt792x_dev *dev = phy->dev;
420 struct mt76_mib_stats *mib = &phy->mib;
421 struct mt76_ethtool_worker_info wi = {
422 .data = data,
423 .idx = mvif->mt76.idx,
424 };
425 int i, ei = 0;
426
427 mt792x_mutex_acquire(dev);
428
429 mt792x_mac_update_mib_stats(phy);
430
431 data[ei++] = mib->tx_ampdu_cnt;
432 data[ei++] = mib->tx_mpdu_attempts_cnt;
433 data[ei++] = mib->tx_mpdu_success_cnt;
434 data[ei++] = mib->tx_pkt_ebf_cnt;
435 data[ei++] = mib->tx_pkt_ibf_cnt;
436
437 /* Tx ampdu stat */
438 for (i = 0; i < 15; i++)
439 data[ei++] = phy->mt76->aggr_stats[i];
440
441 data[ei++] = phy->mib.ba_miss_cnt;
442
443 /* Tx Beamformer monitor */
444 data[ei++] = mib->tx_bf_ibf_ppdu_cnt;
445 data[ei++] = mib->tx_bf_ebf_ppdu_cnt;
446
447 /* Tx Beamformer Rx feedback monitor */
448 data[ei++] = mib->tx_bf_rx_fb_all_cnt;
449 data[ei++] = mib->tx_bf_rx_fb_he_cnt;
450 data[ei++] = mib->tx_bf_rx_fb_vht_cnt;
451 data[ei++] = mib->tx_bf_rx_fb_ht_cnt;
452
453 /* Tx amsdu info (pack-count histogram) */
454 for (i = 0; i < ARRAY_SIZE(mib->tx_amsdu); i++)
455 data[ei++] = mib->tx_amsdu[i];
456
457 /* rx counters */
458 data[ei++] = mib->rx_mpdu_cnt;
459 data[ei++] = mib->rx_ampdu_cnt;
460 data[ei++] = mib->rx_ampdu_bytes_cnt;
461 data[ei++] = mib->rx_ba_cnt;
462
463 /* Add values for all stations owned by this vif */
464 wi.initial_stat_idx = ei;
465 ieee80211_iterate_stations_atomic(hw, mt792x_ethtool_worker, &wi);
466
467 mt792x_mutex_release(dev);
468
469 if (!wi.sta_count)
470 return;
471
472 ei += wi.worker_stat_count;
473
474 mt76_ethtool_page_pool_stats(&dev->mt76, &data[ei], &ei);
475 stats_size += page_pool_ethtool_stats_get_count();
476
477 if (ei != stats_size)
478 dev_err(dev->mt76.dev, "ei: %d SSTATS_LEN: %d", ei,
479 stats_size);
480}
481EXPORT_SYMBOL_GPL(mt792x_get_et_stats);
482
483void mt792x_sta_statistics(struct ieee80211_hw *hw,
484 struct ieee80211_vif *vif,
485 struct ieee80211_sta *sta,
486 struct station_info *sinfo)
487{
488 struct mt792x_sta *msta = (struct mt792x_sta *)sta->drv_priv;
489 struct rate_info *txrate = &msta->wcid.rate;
490
491 if (!txrate->legacy && !txrate->flags)
492 return;
493
494 if (txrate->legacy) {
495 sinfo->txrate.legacy = txrate->legacy;
496 } else {
497 sinfo->txrate.mcs = txrate->mcs;
498 sinfo->txrate.nss = txrate->nss;
499 sinfo->txrate.bw = txrate->bw;
500 sinfo->txrate.he_gi = txrate->he_gi;
501 sinfo->txrate.he_dcm = txrate->he_dcm;
502 sinfo->txrate.he_ru_alloc = txrate->he_ru_alloc;
503 }
504 sinfo->tx_failed = msta->wcid.stats.tx_failed;
505 sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_FAILED);
506
507 sinfo->tx_retries = msta->wcid.stats.tx_retries;
508 sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_RETRIES);
509
510 sinfo->txrate.flags = txrate->flags;
511 sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BITRATE);
512
513 sinfo->ack_signal = (s8)msta->ack_signal;
514 sinfo->filled |= BIT_ULL(NL80211_STA_INFO_ACK_SIGNAL);
515
516 sinfo->avg_ack_signal = -(s8)ewma_avg_signal_read(&msta->avg_ack_signal);
517 sinfo->filled |= BIT_ULL(NL80211_STA_INFO_ACK_SIGNAL_AVG);
518}
519EXPORT_SYMBOL_GPL(mt792x_sta_statistics);
520
521void mt792x_set_coverage_class(struct ieee80211_hw *hw, s16 coverage_class)
522{
523 struct mt792x_phy *phy = mt792x_hw_phy(hw);
524 struct mt792x_dev *dev = phy->dev;
525
526 mt792x_mutex_acquire(dev);
527
528 phy->coverage_class = max_t(s16, coverage_class, 0);
529 mt792x_mac_set_timeing(phy);
530
531 mt792x_mutex_release(dev);
532}
533EXPORT_SYMBOL_GPL(mt792x_set_coverage_class);
534
535int mt792x_init_wiphy(struct ieee80211_hw *hw)
536{
537 struct mt792x_phy *phy = mt792x_hw_phy(hw);
538 struct mt792x_dev *dev = phy->dev;
539 struct wiphy *wiphy = hw->wiphy;
540
541 hw->queues = 4;
542 if (dev->has_eht) {
543 hw->max_rx_aggregation_subframes = IEEE80211_MAX_AMPDU_BUF_EHT;
544 hw->max_tx_aggregation_subframes = IEEE80211_MAX_AMPDU_BUF_EHT;
545 } else {
546 hw->max_rx_aggregation_subframes = IEEE80211_MAX_AMPDU_BUF_HE;
547 hw->max_tx_aggregation_subframes = IEEE80211_MAX_AMPDU_BUF_HE;
548 }
549 hw->netdev_features = NETIF_F_RXCSUM;
550
551 hw->radiotap_timestamp.units_pos =
552 IEEE80211_RADIOTAP_TIMESTAMP_UNIT_US;
553
554 phy->slottime = 9;
555
556 hw->sta_data_size = sizeof(struct mt792x_sta);
557 hw->vif_data_size = sizeof(struct mt792x_vif);
558
559 if (dev->fw_features & MT792x_FW_CAP_CNM) {
560 wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
561 wiphy->iface_combinations = if_comb_chanctx;
562 wiphy->n_iface_combinations = ARRAY_SIZE(if_comb_chanctx);
563 } else {
564 wiphy->flags &= ~WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
565 wiphy->iface_combinations = if_comb;
566 wiphy->n_iface_combinations = ARRAY_SIZE(if_comb);
567 }
568 wiphy->flags &= ~(WIPHY_FLAG_IBSS_RSN | WIPHY_FLAG_4ADDR_AP |
569 WIPHY_FLAG_4ADDR_STATION);
570 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
571 BIT(NL80211_IFTYPE_AP) |
572 BIT(NL80211_IFTYPE_P2P_CLIENT) |
573 BIT(NL80211_IFTYPE_P2P_GO);
574 wiphy->max_remain_on_channel_duration = 5000;
575 wiphy->max_scan_ie_len = MT76_CONNAC_SCAN_IE_LEN;
576 wiphy->max_scan_ssids = 4;
577 wiphy->max_sched_scan_plan_interval =
578 MT76_CONNAC_MAX_TIME_SCHED_SCAN_INTERVAL;
579 wiphy->max_sched_scan_ie_len = IEEE80211_MAX_DATA_LEN;
580 wiphy->max_sched_scan_ssids = MT76_CONNAC_MAX_SCHED_SCAN_SSID;
581 wiphy->max_match_sets = MT76_CONNAC_MAX_SCAN_MATCH;
582 wiphy->max_sched_scan_reqs = 1;
583 wiphy->flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH |
584 WIPHY_FLAG_SPLIT_SCAN_6GHZ;
585
586 wiphy->features |= NL80211_FEATURE_SCHED_SCAN_RANDOM_MAC_ADDR |
587 NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR;
588 wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_SET_SCAN_DWELL);
589 wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_BEACON_RATE_LEGACY);
590 wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_BEACON_RATE_HT);
591 wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_BEACON_RATE_VHT);
592 wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_BEACON_RATE_HE);
593 wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_ACK_SIGNAL_SUPPORT);
594 wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_CAN_REPLACE_PTK0);
595
596 ieee80211_hw_set(hw, SINGLE_SCAN_ON_ALL_BANDS);
597 ieee80211_hw_set(hw, HAS_RATE_CONTROL);
598 ieee80211_hw_set(hw, SUPPORTS_TX_ENCAP_OFFLOAD);
599 ieee80211_hw_set(hw, SUPPORTS_RX_DECAP_OFFLOAD);
600 ieee80211_hw_set(hw, WANT_MONITOR_VIF);
601 ieee80211_hw_set(hw, SUPPORTS_PS);
602 ieee80211_hw_set(hw, SUPPORTS_DYNAMIC_PS);
603 ieee80211_hw_set(hw, SUPPORTS_VHT_EXT_NSS_BW);
604 ieee80211_hw_set(hw, CONNECTION_MONITOR);
605
606 if (dev->pm.enable)
607 ieee80211_hw_set(hw, CONNECTION_MONITOR);
608
609 hw->max_tx_fragments = 4;
610
611 return 0;
612}
613EXPORT_SYMBOL_GPL(mt792x_init_wiphy);
614
615static u8
616mt792x_get_offload_capability(struct device *dev, const char *fw_wm)
617{
618 const struct mt76_connac2_fw_trailer *hdr;
619 struct mt792x_realease_info *rel_info;
620 const struct firmware *fw;
621 int ret, i, offset = 0;
622 const u8 *data, *end;
623 u8 offload_caps = 0;
624
625 ret = request_firmware(&fw, fw_wm, dev);
626 if (ret)
627 return ret;
628
629 if (!fw || !fw->data || fw->size < sizeof(*hdr)) {
630 dev_err(dev, "Invalid firmware\n");
631 goto out;
632 }
633
634 data = fw->data;
635 hdr = (const void *)(fw->data + fw->size - sizeof(*hdr));
636
637 for (i = 0; i < hdr->n_region; i++) {
638 const struct mt76_connac2_fw_region *region;
639
640 region = (const void *)((const u8 *)hdr -
641 (hdr->n_region - i) * sizeof(*region));
642 offset += le32_to_cpu(region->len);
643 }
644
645 data += offset + 16;
646 rel_info = (struct mt792x_realease_info *)data;
647 data += sizeof(*rel_info);
648 end = data + le16_to_cpu(rel_info->len);
649
650 while (data < end) {
651 rel_info = (struct mt792x_realease_info *)data;
652 data += sizeof(*rel_info);
653
654 if (rel_info->tag == MT792x_FW_TAG_FEATURE) {
655 struct mt792x_fw_features *features;
656
657 features = (struct mt792x_fw_features *)data;
658 offload_caps = features->data;
659 break;
660 }
661
662 data += le16_to_cpu(rel_info->len) + rel_info->pad_len;
663 }
664
665out:
666 release_firmware(fw);
667
668 return offload_caps;
669}
670
671struct ieee80211_ops *
672mt792x_get_mac80211_ops(struct device *dev,
673 const struct ieee80211_ops *mac80211_ops,
674 void *drv_data, u8 *fw_features)
675{
676 struct ieee80211_ops *ops;
677
678 ops = devm_kmemdup(dev, mac80211_ops, sizeof(struct ieee80211_ops),
679 GFP_KERNEL);
680 if (!ops)
681 return NULL;
682
683 *fw_features = mt792x_get_offload_capability(dev, drv_data);
684 if (!(*fw_features & MT792x_FW_CAP_CNM)) {
685 ops->remain_on_channel = NULL;
686 ops->cancel_remain_on_channel = NULL;
687 ops->add_chanctx = NULL;
688 ops->remove_chanctx = NULL;
689 ops->change_chanctx = NULL;
690 ops->assign_vif_chanctx = NULL;
691 ops->unassign_vif_chanctx = NULL;
692 ops->mgd_prepare_tx = NULL;
693 ops->mgd_complete_tx = NULL;
694 }
695 return ops;
696}
697EXPORT_SYMBOL_GPL(mt792x_get_mac80211_ops);
698
699int mt792x_init_wcid(struct mt792x_dev *dev)
700{
701 int idx;
702
703 /* Beacon and mgmt frames should occupy wcid 0 */
704 idx = mt76_wcid_alloc(dev->mt76.wcid_mask, MT792x_WTBL_STA - 1);
705 if (idx)
706 return -ENOSPC;
707
708 dev->mt76.global_wcid.idx = idx;
709 dev->mt76.global_wcid.hw_key_idx = -1;
710 dev->mt76.global_wcid.tx_info |= MT_WCID_TX_INFO_SET;
711 rcu_assign_pointer(dev->mt76.wcid[idx], &dev->mt76.global_wcid);
712
713 return 0;
714}
715EXPORT_SYMBOL_GPL(mt792x_init_wcid);
716
717int mt792x_mcu_drv_pmctrl(struct mt792x_dev *dev)
718{
719 struct mt76_phy *mphy = &dev->mt76.phy;
720 struct mt76_connac_pm *pm = &dev->pm;
721 int err = 0;
722
723 mutex_lock(&pm->mutex);
724
725 if (!test_bit(MT76_STATE_PM, &mphy->state))
726 goto out;
727
728 err = __mt792x_mcu_drv_pmctrl(dev);
729out:
730 mutex_unlock(&pm->mutex);
731
732 if (err)
733 mt792x_reset(&dev->mt76);
734
735 return err;
736}
737EXPORT_SYMBOL_GPL(mt792x_mcu_drv_pmctrl);
738
739int mt792x_mcu_fw_pmctrl(struct mt792x_dev *dev)
740{
741 struct mt76_phy *mphy = &dev->mt76.phy;
742 struct mt76_connac_pm *pm = &dev->pm;
743 int err = 0;
744
745 mutex_lock(&pm->mutex);
746
747 if (mt76_connac_skip_fw_pmctrl(mphy, pm))
748 goto out;
749
750 err = __mt792x_mcu_fw_pmctrl(dev);
751out:
752 mutex_unlock(&pm->mutex);
753
754 if (err)
755 mt792x_reset(&dev->mt76);
756
757 return err;
758}
759EXPORT_SYMBOL_GPL(mt792x_mcu_fw_pmctrl);
760
761int __mt792xe_mcu_drv_pmctrl(struct mt792x_dev *dev)
762{
763 int i, err = 0;
764
765 for (i = 0; i < MT792x_DRV_OWN_RETRY_COUNT; i++) {
766 mt76_wr(dev, MT_CONN_ON_LPCTL, PCIE_LPCR_HOST_CLR_OWN);
767 if (mt76_poll_msec_tick(dev, MT_CONN_ON_LPCTL,
768 PCIE_LPCR_HOST_OWN_SYNC, 0, 50, 1))
769 break;
770 }
771
772 if (i == MT792x_DRV_OWN_RETRY_COUNT) {
773 dev_err(dev->mt76.dev, "driver own failed\n");
774 err = -EIO;
775 }
776
777 return err;
778}
779EXPORT_SYMBOL_GPL(__mt792xe_mcu_drv_pmctrl);
780
781int mt792xe_mcu_drv_pmctrl(struct mt792x_dev *dev)
782{
783 struct mt76_phy *mphy = &dev->mt76.phy;
784 struct mt76_connac_pm *pm = &dev->pm;
785 int err;
786
787 err = __mt792xe_mcu_drv_pmctrl(dev);
788 if (err < 0)
789 goto out;
790
791 mt792x_wpdma_reinit_cond(dev);
792 clear_bit(MT76_STATE_PM, &mphy->state);
793
794 pm->stats.last_wake_event = jiffies;
795 pm->stats.doze_time += pm->stats.last_wake_event -
796 pm->stats.last_doze_event;
797out:
798 return err;
799}
800EXPORT_SYMBOL_GPL(mt792xe_mcu_drv_pmctrl);
801
802int mt792xe_mcu_fw_pmctrl(struct mt792x_dev *dev)
803{
804 struct mt76_phy *mphy = &dev->mt76.phy;
805 struct mt76_connac_pm *pm = &dev->pm;
806 int i;
807
808 for (i = 0; i < MT792x_DRV_OWN_RETRY_COUNT; i++) {
809 mt76_wr(dev, MT_CONN_ON_LPCTL, PCIE_LPCR_HOST_SET_OWN);
810 if (mt76_poll_msec_tick(dev, MT_CONN_ON_LPCTL,
811 PCIE_LPCR_HOST_OWN_SYNC, 4, 50, 1))
812 break;
813 }
814
815 if (i == MT792x_DRV_OWN_RETRY_COUNT) {
816 dev_err(dev->mt76.dev, "firmware own failed\n");
817 clear_bit(MT76_STATE_PM, &mphy->state);
818 return -EIO;
819 }
820
821 pm->stats.last_doze_event = jiffies;
822 pm->stats.awake_time += pm->stats.last_doze_event -
823 pm->stats.last_wake_event;
824
825 return 0;
826}
827EXPORT_SYMBOL_GPL(mt792xe_mcu_fw_pmctrl);
828
829int mt792x_load_firmware(struct mt792x_dev *dev)
830{
831 int ret;
832
833 ret = mt76_connac2_load_patch(&dev->mt76, mt792x_patch_name(dev));
834 if (ret)
835 return ret;
836
837 if (mt76_is_sdio(&dev->mt76)) {
838 /* activate again */
839 ret = __mt792x_mcu_fw_pmctrl(dev);
840 if (!ret)
841 ret = __mt792x_mcu_drv_pmctrl(dev);
842 }
843
844 ret = mt76_connac2_load_ram(&dev->mt76, mt792x_ram_name(dev), NULL);
845 if (ret)
846 return ret;
847
848 if (!mt76_poll_msec(dev, MT_CONN_ON_MISC, MT_TOP_MISC2_FW_N9_RDY,
849 MT_TOP_MISC2_FW_N9_RDY, 1500)) {
850 dev_err(dev->mt76.dev, "Timeout for initializing firmware\n");
851
852 return -EIO;
853 }
854
855#ifdef CONFIG_PM
856 dev->mt76.hw->wiphy->wowlan = &mt76_connac_wowlan_support;
857#endif /* CONFIG_PM */
858
859 dev_dbg(dev->mt76.dev, "Firmware init done\n");
860
861 return 0;
862}
863EXPORT_SYMBOL_GPL(mt792x_load_firmware);
864
865MODULE_DESCRIPTION("MediaTek MT792x core driver");
866MODULE_LICENSE("Dual BSD/GPL");
867MODULE_AUTHOR("Lorenzo Bianconi <lorenzo@kernel.org>");
1// SPDX-License-Identifier: ISC
2/* Copyright (C) 2023 MediaTek Inc. */
3
4#include <linux/module.h>
5#include <linux/firmware.h>
6
7#include "mt792x.h"
8#include "dma.h"
9
10static const struct ieee80211_iface_limit if_limits[] = {
11 {
12 .max = MT792x_MAX_INTERFACES,
13 .types = BIT(NL80211_IFTYPE_STATION)
14 },
15 {
16 .max = 1,
17 .types = BIT(NL80211_IFTYPE_AP)
18 }
19};
20
21static const struct ieee80211_iface_combination if_comb[] = {
22 {
23 .limits = if_limits,
24 .n_limits = ARRAY_SIZE(if_limits),
25 .max_interfaces = MT792x_MAX_INTERFACES,
26 .num_different_channels = 1,
27 .beacon_int_infra_match = true,
28 },
29};
30
31static const struct ieee80211_iface_limit if_limits_chanctx[] = {
32 {
33 .max = 2,
34 .types = BIT(NL80211_IFTYPE_STATION) |
35 BIT(NL80211_IFTYPE_P2P_CLIENT)
36 },
37 {
38 .max = 1,
39 .types = BIT(NL80211_IFTYPE_AP) |
40 BIT(NL80211_IFTYPE_P2P_GO)
41 }
42};
43
44static const struct ieee80211_iface_combination if_comb_chanctx[] = {
45 {
46 .limits = if_limits_chanctx,
47 .n_limits = ARRAY_SIZE(if_limits_chanctx),
48 .max_interfaces = 2,
49 .num_different_channels = 2,
50 .beacon_int_infra_match = false,
51 }
52};
53
54void mt792x_tx(struct ieee80211_hw *hw, struct ieee80211_tx_control *control,
55 struct sk_buff *skb)
56{
57 struct mt792x_dev *dev = mt792x_hw_dev(hw);
58 struct mt76_phy *mphy = hw->priv;
59 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
60 struct ieee80211_vif *vif = info->control.vif;
61 struct mt76_wcid *wcid = &dev->mt76.global_wcid;
62 u8 link_id;
63 int qid;
64
65 if (control->sta) {
66 struct mt792x_link_sta *mlink;
67 struct mt792x_sta *sta;
68 link_id = u32_get_bits(info->control.flags,
69 IEEE80211_TX_CTRL_MLO_LINK);
70 sta = (struct mt792x_sta *)control->sta->drv_priv;
71 mlink = mt792x_sta_to_link(sta, link_id);
72 wcid = &mlink->wcid;
73 }
74
75 if (vif && !control->sta) {
76 struct mt792x_vif *mvif;
77
78 mvif = (struct mt792x_vif *)vif->drv_priv;
79 wcid = &mvif->sta.deflink.wcid;
80 }
81
82 if (vif && control->sta && ieee80211_vif_is_mld(vif)) {
83 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
84 struct ieee80211_link_sta *link_sta;
85 struct ieee80211_bss_conf *conf;
86
87 link_id = wcid->link_id;
88 rcu_read_lock();
89 conf = rcu_dereference(vif->link_conf[link_id]);
90 memcpy(hdr->addr2, conf->addr, ETH_ALEN);
91
92 link_sta = rcu_dereference(control->sta->link[link_id]);
93 memcpy(hdr->addr1, link_sta->addr, ETH_ALEN);
94
95 if (vif->type == NL80211_IFTYPE_STATION)
96 memcpy(hdr->addr3, conf->bssid, ETH_ALEN);
97 rcu_read_unlock();
98 }
99
100 if (mt76_connac_pm_ref(mphy, &dev->pm)) {
101 mt76_tx(mphy, control->sta, wcid, skb);
102 mt76_connac_pm_unref(mphy, &dev->pm);
103 return;
104 }
105
106 qid = skb_get_queue_mapping(skb);
107 if (qid >= MT_TXQ_PSD) {
108 qid = IEEE80211_AC_BE;
109 skb_set_queue_mapping(skb, qid);
110 }
111
112 mt76_connac_pm_queue_skb(hw, &dev->pm, wcid, skb);
113}
114EXPORT_SYMBOL_GPL(mt792x_tx);
115
116void mt792x_stop(struct ieee80211_hw *hw, bool suspend)
117{
118 struct mt792x_dev *dev = mt792x_hw_dev(hw);
119 struct mt792x_phy *phy = mt792x_hw_phy(hw);
120
121 cancel_delayed_work_sync(&phy->mt76->mac_work);
122
123 cancel_delayed_work_sync(&dev->pm.ps_work);
124 cancel_work_sync(&dev->pm.wake_work);
125 cancel_work_sync(&dev->reset_work);
126 mt76_connac_free_pending_tx_skbs(&dev->pm, NULL);
127
128 if (is_mt7921(&dev->mt76)) {
129 mt792x_mutex_acquire(dev);
130 mt76_connac_mcu_set_mac_enable(&dev->mt76, 0, false, false);
131 mt792x_mutex_release(dev);
132 }
133
134 clear_bit(MT76_STATE_RUNNING, &phy->mt76->state);
135}
136EXPORT_SYMBOL_GPL(mt792x_stop);
137
138void mt792x_mac_link_bss_remove(struct mt792x_dev *dev,
139 struct mt792x_bss_conf *mconf,
140 struct mt792x_link_sta *mlink)
141{
142 struct ieee80211_vif *vif = container_of((void *)mconf->vif,
143 struct ieee80211_vif, drv_priv);
144 struct ieee80211_bss_conf *link_conf;
145 int idx = mlink->wcid.idx;
146
147 link_conf = mt792x_vif_to_bss_conf(vif, mconf->link_id);
148
149 mt76_connac_free_pending_tx_skbs(&dev->pm, &mlink->wcid);
150 mt76_connac_mcu_uni_add_dev(&dev->mphy, link_conf, &mconf->mt76,
151 &mlink->wcid, false);
152
153 rcu_assign_pointer(dev->mt76.wcid[idx], NULL);
154
155 dev->mt76.vif_mask &= ~BIT_ULL(mconf->mt76.idx);
156 mconf->vif->phy->omac_mask &= ~BIT_ULL(mconf->mt76.omac_idx);
157
158 spin_lock_bh(&dev->mt76.sta_poll_lock);
159 if (!list_empty(&mlink->wcid.poll_list))
160 list_del_init(&mlink->wcid.poll_list);
161 spin_unlock_bh(&dev->mt76.sta_poll_lock);
162
163 mt76_wcid_cleanup(&dev->mt76, &mlink->wcid);
164}
165EXPORT_SYMBOL_GPL(mt792x_mac_link_bss_remove);
166
167void mt792x_remove_interface(struct ieee80211_hw *hw,
168 struct ieee80211_vif *vif)
169{
170 struct mt792x_vif *mvif = (struct mt792x_vif *)vif->drv_priv;
171 struct mt792x_dev *dev = mt792x_hw_dev(hw);
172 struct mt792x_bss_conf *mconf;
173
174 mt792x_mutex_acquire(dev);
175
176 mconf = mt792x_link_conf_to_mconf(&vif->bss_conf);
177 mt792x_mac_link_bss_remove(dev, mconf, &mvif->sta.deflink);
178
179 mt792x_mutex_release(dev);
180}
181EXPORT_SYMBOL_GPL(mt792x_remove_interface);
182
183int mt792x_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
184 unsigned int link_id, u16 queue,
185 const struct ieee80211_tx_queue_params *params)
186{
187 struct mt792x_vif *mvif = (struct mt792x_vif *)vif->drv_priv;
188
189 /* no need to update right away, we'll get BSS_CHANGED_QOS */
190 queue = mt76_connac_lmac_mapping(queue);
191 mvif->bss_conf.queue_params[queue] = *params;
192
193 return 0;
194}
195EXPORT_SYMBOL_GPL(mt792x_conf_tx);
196
197int mt792x_get_stats(struct ieee80211_hw *hw,
198 struct ieee80211_low_level_stats *stats)
199{
200 struct mt792x_phy *phy = mt792x_hw_phy(hw);
201 struct mt76_mib_stats *mib = &phy->mib;
202
203 mt792x_mutex_acquire(phy->dev);
204
205 stats->dot11RTSSuccessCount = mib->rts_cnt;
206 stats->dot11RTSFailureCount = mib->rts_retries_cnt;
207 stats->dot11FCSErrorCount = mib->fcs_err_cnt;
208 stats->dot11ACKFailureCount = mib->ack_fail_cnt;
209
210 mt792x_mutex_release(phy->dev);
211
212 return 0;
213}
214EXPORT_SYMBOL_GPL(mt792x_get_stats);
215
216u64 mt792x_get_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
217{
218 struct mt792x_vif *mvif = (struct mt792x_vif *)vif->drv_priv;
219 struct mt792x_dev *dev = mt792x_hw_dev(hw);
220 u8 omac_idx = mvif->bss_conf.mt76.omac_idx;
221 union {
222 u64 t64;
223 u32 t32[2];
224 } tsf;
225 u16 n;
226
227 mt792x_mutex_acquire(dev);
228
229 n = omac_idx > HW_BSSID_MAX ? HW_BSSID_0 : omac_idx;
230 /* TSF software read */
231 mt76_set(dev, MT_LPON_TCR(0, n), MT_LPON_TCR_SW_MODE);
232 tsf.t32[0] = mt76_rr(dev, MT_LPON_UTTR0(0));
233 tsf.t32[1] = mt76_rr(dev, MT_LPON_UTTR1(0));
234
235 mt792x_mutex_release(dev);
236
237 return tsf.t64;
238}
239EXPORT_SYMBOL_GPL(mt792x_get_tsf);
240
241void mt792x_set_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
242 u64 timestamp)
243{
244 struct mt792x_vif *mvif = (struct mt792x_vif *)vif->drv_priv;
245 struct mt792x_dev *dev = mt792x_hw_dev(hw);
246 u8 omac_idx = mvif->bss_conf.mt76.omac_idx;
247 union {
248 u64 t64;
249 u32 t32[2];
250 } tsf = { .t64 = timestamp, };
251 u16 n;
252
253 mt792x_mutex_acquire(dev);
254
255 n = omac_idx > HW_BSSID_MAX ? HW_BSSID_0 : omac_idx;
256 mt76_wr(dev, MT_LPON_UTTR0(0), tsf.t32[0]);
257 mt76_wr(dev, MT_LPON_UTTR1(0), tsf.t32[1]);
258 /* TSF software overwrite */
259 mt76_set(dev, MT_LPON_TCR(0, n), MT_LPON_TCR_SW_WRITE);
260
261 mt792x_mutex_release(dev);
262}
263EXPORT_SYMBOL_GPL(mt792x_set_tsf);
264
265void mt792x_tx_worker(struct mt76_worker *w)
266{
267 struct mt792x_dev *dev = container_of(w, struct mt792x_dev,
268 mt76.tx_worker);
269
270 if (!mt76_connac_pm_ref(&dev->mphy, &dev->pm)) {
271 queue_work(dev->mt76.wq, &dev->pm.wake_work);
272 return;
273 }
274
275 mt76_txq_schedule_all(&dev->mphy);
276 mt76_connac_pm_unref(&dev->mphy, &dev->pm);
277}
278EXPORT_SYMBOL_GPL(mt792x_tx_worker);
279
280void mt792x_roc_timer(struct timer_list *timer)
281{
282 struct mt792x_phy *phy = from_timer(phy, timer, roc_timer);
283
284 ieee80211_queue_work(phy->mt76->hw, &phy->roc_work);
285}
286EXPORT_SYMBOL_GPL(mt792x_roc_timer);
287
288void mt792x_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
289 u32 queues, bool drop)
290{
291 struct mt792x_dev *dev = mt792x_hw_dev(hw);
292
293 wait_event_timeout(dev->mt76.tx_wait,
294 !mt76_has_tx_pending(&dev->mphy), HZ / 2);
295}
296EXPORT_SYMBOL_GPL(mt792x_flush);
297
298int mt792x_assign_vif_chanctx(struct ieee80211_hw *hw,
299 struct ieee80211_vif *vif,
300 struct ieee80211_bss_conf *link_conf,
301 struct ieee80211_chanctx_conf *ctx)
302{
303 struct mt792x_chanctx *mctx = (struct mt792x_chanctx *)ctx->drv_priv;
304 struct mt792x_vif *mvif = (struct mt792x_vif *)vif->drv_priv;
305 struct mt792x_dev *dev = mt792x_hw_dev(hw);
306
307 mutex_lock(&dev->mt76.mutex);
308 mvif->bss_conf.mt76.ctx = ctx;
309 mctx->bss_conf = &mvif->bss_conf;
310 mutex_unlock(&dev->mt76.mutex);
311
312 return 0;
313}
314EXPORT_SYMBOL_GPL(mt792x_assign_vif_chanctx);
315
316void mt792x_unassign_vif_chanctx(struct ieee80211_hw *hw,
317 struct ieee80211_vif *vif,
318 struct ieee80211_bss_conf *link_conf,
319 struct ieee80211_chanctx_conf *ctx)
320{
321 struct mt792x_chanctx *mctx = (struct mt792x_chanctx *)ctx->drv_priv;
322 struct mt792x_vif *mvif = (struct mt792x_vif *)vif->drv_priv;
323 struct mt792x_dev *dev = mt792x_hw_dev(hw);
324
325 mutex_lock(&dev->mt76.mutex);
326 mctx->bss_conf = NULL;
327 mvif->bss_conf.mt76.ctx = NULL;
328 mutex_unlock(&dev->mt76.mutex);
329}
330EXPORT_SYMBOL_GPL(mt792x_unassign_vif_chanctx);
331
332void mt792x_set_wakeup(struct ieee80211_hw *hw, bool enabled)
333{
334 struct mt792x_dev *dev = mt792x_hw_dev(hw);
335 struct mt76_dev *mdev = &dev->mt76;
336
337 device_set_wakeup_enable(mdev->dev, enabled);
338}
339EXPORT_SYMBOL_GPL(mt792x_set_wakeup);
340
341static const char mt792x_gstrings_stats[][ETH_GSTRING_LEN] = {
342 /* tx counters */
343 "tx_ampdu_cnt",
344 "tx_mpdu_attempts",
345 "tx_mpdu_success",
346 "tx_pkt_ebf_cnt",
347 "tx_pkt_ibf_cnt",
348 "tx_ampdu_len:0-1",
349 "tx_ampdu_len:2-10",
350 "tx_ampdu_len:11-19",
351 "tx_ampdu_len:20-28",
352 "tx_ampdu_len:29-37",
353 "tx_ampdu_len:38-46",
354 "tx_ampdu_len:47-55",
355 "tx_ampdu_len:56-79",
356 "tx_ampdu_len:80-103",
357 "tx_ampdu_len:104-127",
358 "tx_ampdu_len:128-151",
359 "tx_ampdu_len:152-175",
360 "tx_ampdu_len:176-199",
361 "tx_ampdu_len:200-223",
362 "tx_ampdu_len:224-247",
363 "ba_miss_count",
364 "tx_beamformer_ppdu_iBF",
365 "tx_beamformer_ppdu_eBF",
366 "tx_beamformer_rx_feedback_all",
367 "tx_beamformer_rx_feedback_he",
368 "tx_beamformer_rx_feedback_vht",
369 "tx_beamformer_rx_feedback_ht",
370 "tx_msdu_pack_1",
371 "tx_msdu_pack_2",
372 "tx_msdu_pack_3",
373 "tx_msdu_pack_4",
374 "tx_msdu_pack_5",
375 "tx_msdu_pack_6",
376 "tx_msdu_pack_7",
377 "tx_msdu_pack_8",
378 /* rx counters */
379 "rx_mpdu_cnt",
380 "rx_ampdu_cnt",
381 "rx_ampdu_bytes_cnt",
382 "rx_ba_cnt",
383 /* per vif counters */
384 "v_tx_mode_cck",
385 "v_tx_mode_ofdm",
386 "v_tx_mode_ht",
387 "v_tx_mode_ht_gf",
388 "v_tx_mode_vht",
389 "v_tx_mode_he_su",
390 "v_tx_mode_he_ext_su",
391 "v_tx_mode_he_tb",
392 "v_tx_mode_he_mu",
393 "v_tx_mode_eht_su",
394 "v_tx_mode_eht_trig",
395 "v_tx_mode_eht_mu",
396 "v_tx_bw_20",
397 "v_tx_bw_40",
398 "v_tx_bw_80",
399 "v_tx_bw_160",
400 "v_tx_bw_320",
401 "v_tx_mcs_0",
402 "v_tx_mcs_1",
403 "v_tx_mcs_2",
404 "v_tx_mcs_3",
405 "v_tx_mcs_4",
406 "v_tx_mcs_5",
407 "v_tx_mcs_6",
408 "v_tx_mcs_7",
409 "v_tx_mcs_8",
410 "v_tx_mcs_9",
411 "v_tx_mcs_10",
412 "v_tx_mcs_11",
413 "v_tx_mcs_12",
414 "v_tx_mcs_13",
415 "v_tx_nss_1",
416 "v_tx_nss_2",
417 "v_tx_nss_3",
418 "v_tx_nss_4",
419};
420
421void mt792x_get_et_strings(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
422 u32 sset, u8 *data)
423{
424 if (sset != ETH_SS_STATS)
425 return;
426
427 memcpy(data, mt792x_gstrings_stats, sizeof(mt792x_gstrings_stats));
428
429 data += sizeof(mt792x_gstrings_stats);
430 page_pool_ethtool_stats_get_strings(data);
431}
432EXPORT_SYMBOL_GPL(mt792x_get_et_strings);
433
434int mt792x_get_et_sset_count(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
435 int sset)
436{
437 if (sset != ETH_SS_STATS)
438 return 0;
439
440 return ARRAY_SIZE(mt792x_gstrings_stats) +
441 page_pool_ethtool_stats_get_count();
442}
443EXPORT_SYMBOL_GPL(mt792x_get_et_sset_count);
444
445static void
446mt792x_ethtool_worker(void *wi_data, struct ieee80211_sta *sta)
447{
448 struct mt792x_sta *msta = (struct mt792x_sta *)sta->drv_priv;
449 struct mt76_ethtool_worker_info *wi = wi_data;
450
451 if (msta->vif->bss_conf.mt76.idx != wi->idx)
452 return;
453
454 mt76_ethtool_worker(wi, &msta->deflink.wcid.stats, true);
455}
456
457void mt792x_get_et_stats(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
458 struct ethtool_stats *stats, u64 *data)
459{
460 struct mt792x_vif *mvif = (struct mt792x_vif *)vif->drv_priv;
461 int stats_size = ARRAY_SIZE(mt792x_gstrings_stats);
462 struct mt792x_phy *phy = mt792x_hw_phy(hw);
463 struct mt792x_dev *dev = phy->dev;
464 struct mt76_mib_stats *mib = &phy->mib;
465 struct mt76_ethtool_worker_info wi = {
466 .data = data,
467 .idx = mvif->bss_conf.mt76.idx,
468 };
469 int i, ei = 0;
470
471 mt792x_mutex_acquire(dev);
472
473 mt792x_mac_update_mib_stats(phy);
474
475 data[ei++] = mib->tx_ampdu_cnt;
476 data[ei++] = mib->tx_mpdu_attempts_cnt;
477 data[ei++] = mib->tx_mpdu_success_cnt;
478 data[ei++] = mib->tx_pkt_ebf_cnt;
479 data[ei++] = mib->tx_pkt_ibf_cnt;
480
481 /* Tx ampdu stat */
482 for (i = 0; i < 15; i++)
483 data[ei++] = phy->mt76->aggr_stats[i];
484
485 data[ei++] = phy->mib.ba_miss_cnt;
486
487 /* Tx Beamformer monitor */
488 data[ei++] = mib->tx_bf_ibf_ppdu_cnt;
489 data[ei++] = mib->tx_bf_ebf_ppdu_cnt;
490
491 /* Tx Beamformer Rx feedback monitor */
492 data[ei++] = mib->tx_bf_rx_fb_all_cnt;
493 data[ei++] = mib->tx_bf_rx_fb_he_cnt;
494 data[ei++] = mib->tx_bf_rx_fb_vht_cnt;
495 data[ei++] = mib->tx_bf_rx_fb_ht_cnt;
496
497 /* Tx amsdu info (pack-count histogram) */
498 for (i = 0; i < ARRAY_SIZE(mib->tx_amsdu); i++)
499 data[ei++] = mib->tx_amsdu[i];
500
501 /* rx counters */
502 data[ei++] = mib->rx_mpdu_cnt;
503 data[ei++] = mib->rx_ampdu_cnt;
504 data[ei++] = mib->rx_ampdu_bytes_cnt;
505 data[ei++] = mib->rx_ba_cnt;
506
507 /* Add values for all stations owned by this vif */
508 wi.initial_stat_idx = ei;
509 ieee80211_iterate_stations_atomic(hw, mt792x_ethtool_worker, &wi);
510
511 mt792x_mutex_release(dev);
512
513 if (!wi.sta_count)
514 return;
515
516 ei += wi.worker_stat_count;
517
518 mt76_ethtool_page_pool_stats(&dev->mt76, &data[ei], &ei);
519 stats_size += page_pool_ethtool_stats_get_count();
520
521 if (ei != stats_size)
522 dev_err(dev->mt76.dev, "ei: %d SSTATS_LEN: %d", ei,
523 stats_size);
524}
525EXPORT_SYMBOL_GPL(mt792x_get_et_stats);
526
527void mt792x_sta_statistics(struct ieee80211_hw *hw,
528 struct ieee80211_vif *vif,
529 struct ieee80211_sta *sta,
530 struct station_info *sinfo)
531{
532 struct mt792x_sta *msta = (struct mt792x_sta *)sta->drv_priv;
533 struct rate_info *txrate = &msta->deflink.wcid.rate;
534
535 if (!txrate->legacy && !txrate->flags)
536 return;
537
538 if (txrate->legacy) {
539 sinfo->txrate.legacy = txrate->legacy;
540 } else {
541 sinfo->txrate.mcs = txrate->mcs;
542 sinfo->txrate.nss = txrate->nss;
543 sinfo->txrate.bw = txrate->bw;
544 sinfo->txrate.he_gi = txrate->he_gi;
545 sinfo->txrate.he_dcm = txrate->he_dcm;
546 sinfo->txrate.he_ru_alloc = txrate->he_ru_alloc;
547 }
548 sinfo->tx_failed = msta->deflink.wcid.stats.tx_failed;
549 sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_FAILED);
550
551 sinfo->tx_retries = msta->deflink.wcid.stats.tx_retries;
552 sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_RETRIES);
553
554 sinfo->txrate.flags = txrate->flags;
555 sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BITRATE);
556
557 sinfo->ack_signal = (s8)msta->deflink.ack_signal;
558 sinfo->filled |= BIT_ULL(NL80211_STA_INFO_ACK_SIGNAL);
559
560 sinfo->avg_ack_signal = -(s8)ewma_avg_signal_read(&msta->deflink.avg_ack_signal);
561 sinfo->filled |= BIT_ULL(NL80211_STA_INFO_ACK_SIGNAL_AVG);
562}
563EXPORT_SYMBOL_GPL(mt792x_sta_statistics);
564
565void mt792x_set_coverage_class(struct ieee80211_hw *hw, s16 coverage_class)
566{
567 struct mt792x_phy *phy = mt792x_hw_phy(hw);
568 struct mt792x_dev *dev = phy->dev;
569
570 mt792x_mutex_acquire(dev);
571
572 phy->coverage_class = max_t(s16, coverage_class, 0);
573 mt792x_mac_set_timeing(phy);
574
575 mt792x_mutex_release(dev);
576}
577EXPORT_SYMBOL_GPL(mt792x_set_coverage_class);
578
579int mt792x_init_wiphy(struct ieee80211_hw *hw)
580{
581 struct mt792x_phy *phy = mt792x_hw_phy(hw);
582 struct mt792x_dev *dev = phy->dev;
583 struct wiphy *wiphy = hw->wiphy;
584
585 hw->queues = 4;
586 if (dev->has_eht) {
587 hw->max_rx_aggregation_subframes = IEEE80211_MAX_AMPDU_BUF_EHT;
588 hw->max_tx_aggregation_subframes = IEEE80211_MAX_AMPDU_BUF_EHT;
589 } else {
590 hw->max_rx_aggregation_subframes = IEEE80211_MAX_AMPDU_BUF_HE;
591 hw->max_tx_aggregation_subframes = IEEE80211_MAX_AMPDU_BUF_HE;
592 }
593 hw->netdev_features = NETIF_F_RXCSUM;
594
595 hw->radiotap_timestamp.units_pos =
596 IEEE80211_RADIOTAP_TIMESTAMP_UNIT_US;
597
598 phy->slottime = 9;
599
600 hw->sta_data_size = sizeof(struct mt792x_sta);
601 hw->vif_data_size = sizeof(struct mt792x_vif);
602 hw->chanctx_data_size = sizeof(struct mt792x_chanctx);
603
604 if (dev->fw_features & MT792x_FW_CAP_CNM) {
605 wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
606 wiphy->iface_combinations = if_comb_chanctx;
607 wiphy->n_iface_combinations = ARRAY_SIZE(if_comb_chanctx);
608 } else {
609 wiphy->flags &= ~WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
610 wiphy->iface_combinations = if_comb;
611 wiphy->n_iface_combinations = ARRAY_SIZE(if_comb);
612 }
613 wiphy->flags &= ~(WIPHY_FLAG_IBSS_RSN | WIPHY_FLAG_4ADDR_AP |
614 WIPHY_FLAG_4ADDR_STATION);
615 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
616 BIT(NL80211_IFTYPE_AP) |
617 BIT(NL80211_IFTYPE_P2P_CLIENT) |
618 BIT(NL80211_IFTYPE_P2P_GO);
619 wiphy->max_remain_on_channel_duration = 5000;
620 wiphy->max_scan_ie_len = MT76_CONNAC_SCAN_IE_LEN;
621 wiphy->max_scan_ssids = 4;
622 wiphy->max_sched_scan_plan_interval =
623 MT76_CONNAC_MAX_TIME_SCHED_SCAN_INTERVAL;
624 wiphy->max_sched_scan_ie_len = IEEE80211_MAX_DATA_LEN;
625 wiphy->max_sched_scan_ssids = MT76_CONNAC_MAX_SCHED_SCAN_SSID;
626 wiphy->max_match_sets = MT76_CONNAC_MAX_SCAN_MATCH;
627 wiphy->max_sched_scan_reqs = 1;
628 wiphy->flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH |
629 WIPHY_FLAG_SPLIT_SCAN_6GHZ;
630
631 wiphy->features |= NL80211_FEATURE_SCHED_SCAN_RANDOM_MAC_ADDR |
632 NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR;
633 wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_SET_SCAN_DWELL);
634 wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_BEACON_RATE_LEGACY);
635 wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_BEACON_RATE_HT);
636 wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_BEACON_RATE_VHT);
637 wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_BEACON_RATE_HE);
638 wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_ACK_SIGNAL_SUPPORT);
639 wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_CAN_REPLACE_PTK0);
640
641 ieee80211_hw_set(hw, SINGLE_SCAN_ON_ALL_BANDS);
642 ieee80211_hw_set(hw, HAS_RATE_CONTROL);
643 ieee80211_hw_set(hw, SUPPORTS_TX_ENCAP_OFFLOAD);
644 ieee80211_hw_set(hw, SUPPORTS_RX_DECAP_OFFLOAD);
645 ieee80211_hw_set(hw, WANT_MONITOR_VIF);
646 ieee80211_hw_set(hw, SUPPORTS_PS);
647 ieee80211_hw_set(hw, SUPPORTS_DYNAMIC_PS);
648 ieee80211_hw_set(hw, SUPPORTS_VHT_EXT_NSS_BW);
649 ieee80211_hw_set(hw, CONNECTION_MONITOR);
650
651 if (dev->pm.enable)
652 ieee80211_hw_set(hw, CONNECTION_MONITOR);
653
654 hw->max_tx_fragments = 4;
655
656 return 0;
657}
658EXPORT_SYMBOL_GPL(mt792x_init_wiphy);
659
660static u8
661mt792x_get_offload_capability(struct device *dev, const char *fw_wm)
662{
663 const struct mt76_connac2_fw_trailer *hdr;
664 struct mt792x_realease_info *rel_info;
665 const struct firmware *fw;
666 int ret, i, offset = 0;
667 const u8 *data, *end;
668 u8 offload_caps = 0;
669
670 ret = request_firmware(&fw, fw_wm, dev);
671 if (ret)
672 return ret;
673
674 if (!fw || !fw->data || fw->size < sizeof(*hdr)) {
675 dev_err(dev, "Invalid firmware\n");
676 goto out;
677 }
678
679 data = fw->data;
680 hdr = (const void *)(fw->data + fw->size - sizeof(*hdr));
681
682 for (i = 0; i < hdr->n_region; i++) {
683 const struct mt76_connac2_fw_region *region;
684
685 region = (const void *)((const u8 *)hdr -
686 (hdr->n_region - i) * sizeof(*region));
687 offset += le32_to_cpu(region->len);
688 }
689
690 data += offset + 16;
691 rel_info = (struct mt792x_realease_info *)data;
692 data += sizeof(*rel_info);
693 end = data + le16_to_cpu(rel_info->len);
694
695 while (data < end) {
696 rel_info = (struct mt792x_realease_info *)data;
697 data += sizeof(*rel_info);
698
699 if (rel_info->tag == MT792x_FW_TAG_FEATURE) {
700 struct mt792x_fw_features *features;
701
702 features = (struct mt792x_fw_features *)data;
703 offload_caps = features->data;
704 break;
705 }
706
707 data += le16_to_cpu(rel_info->len) + rel_info->pad_len;
708 }
709
710out:
711 release_firmware(fw);
712
713 return offload_caps;
714}
715
716struct ieee80211_ops *
717mt792x_get_mac80211_ops(struct device *dev,
718 const struct ieee80211_ops *mac80211_ops,
719 void *drv_data, u8 *fw_features)
720{
721 struct ieee80211_ops *ops;
722
723 ops = devm_kmemdup(dev, mac80211_ops, sizeof(struct ieee80211_ops),
724 GFP_KERNEL);
725 if (!ops)
726 return NULL;
727
728 *fw_features = mt792x_get_offload_capability(dev, drv_data);
729 if (!(*fw_features & MT792x_FW_CAP_CNM)) {
730 ops->remain_on_channel = NULL;
731 ops->cancel_remain_on_channel = NULL;
732 ops->add_chanctx = ieee80211_emulate_add_chanctx;
733 ops->remove_chanctx = ieee80211_emulate_remove_chanctx;
734 ops->change_chanctx = ieee80211_emulate_change_chanctx;
735 ops->switch_vif_chanctx = ieee80211_emulate_switch_vif_chanctx;
736 ops->assign_vif_chanctx = NULL;
737 ops->unassign_vif_chanctx = NULL;
738 ops->mgd_prepare_tx = NULL;
739 ops->mgd_complete_tx = NULL;
740 }
741 return ops;
742}
743EXPORT_SYMBOL_GPL(mt792x_get_mac80211_ops);
744
745int mt792x_init_wcid(struct mt792x_dev *dev)
746{
747 int idx;
748
749 /* Beacon and mgmt frames should occupy wcid 0 */
750 idx = mt76_wcid_alloc(dev->mt76.wcid_mask, MT792x_WTBL_STA - 1);
751 if (idx)
752 return -ENOSPC;
753
754 dev->mt76.global_wcid.idx = idx;
755 dev->mt76.global_wcid.hw_key_idx = -1;
756 dev->mt76.global_wcid.tx_info |= MT_WCID_TX_INFO_SET;
757 rcu_assign_pointer(dev->mt76.wcid[idx], &dev->mt76.global_wcid);
758
759 return 0;
760}
761EXPORT_SYMBOL_GPL(mt792x_init_wcid);
762
763int mt792x_mcu_drv_pmctrl(struct mt792x_dev *dev)
764{
765 struct mt76_phy *mphy = &dev->mt76.phy;
766 struct mt76_connac_pm *pm = &dev->pm;
767 int err = 0;
768
769 mutex_lock(&pm->mutex);
770
771 if (!test_bit(MT76_STATE_PM, &mphy->state))
772 goto out;
773
774 err = __mt792x_mcu_drv_pmctrl(dev);
775out:
776 mutex_unlock(&pm->mutex);
777
778 if (err)
779 mt792x_reset(&dev->mt76);
780
781 return err;
782}
783EXPORT_SYMBOL_GPL(mt792x_mcu_drv_pmctrl);
784
785int mt792x_mcu_fw_pmctrl(struct mt792x_dev *dev)
786{
787 struct mt76_phy *mphy = &dev->mt76.phy;
788 struct mt76_connac_pm *pm = &dev->pm;
789 int err = 0;
790
791 mutex_lock(&pm->mutex);
792
793 if (mt76_connac_skip_fw_pmctrl(mphy, pm))
794 goto out;
795
796 err = __mt792x_mcu_fw_pmctrl(dev);
797out:
798 mutex_unlock(&pm->mutex);
799
800 if (err)
801 mt792x_reset(&dev->mt76);
802
803 return err;
804}
805EXPORT_SYMBOL_GPL(mt792x_mcu_fw_pmctrl);
806
807int __mt792xe_mcu_drv_pmctrl(struct mt792x_dev *dev)
808{
809 int i, err = 0;
810
811 for (i = 0; i < MT792x_DRV_OWN_RETRY_COUNT; i++) {
812 mt76_wr(dev, MT_CONN_ON_LPCTL, PCIE_LPCR_HOST_CLR_OWN);
813
814 if (dev->aspm_supported)
815 usleep_range(2000, 3000);
816
817 if (mt76_poll_msec_tick(dev, MT_CONN_ON_LPCTL,
818 PCIE_LPCR_HOST_OWN_SYNC, 0, 50, 1))
819 break;
820 }
821
822 if (i == MT792x_DRV_OWN_RETRY_COUNT) {
823 dev_err(dev->mt76.dev, "driver own failed\n");
824 err = -EIO;
825 }
826
827 return err;
828}
829EXPORT_SYMBOL_GPL(__mt792xe_mcu_drv_pmctrl);
830
831int mt792xe_mcu_drv_pmctrl(struct mt792x_dev *dev)
832{
833 struct mt76_phy *mphy = &dev->mt76.phy;
834 struct mt76_connac_pm *pm = &dev->pm;
835 int err;
836
837 err = __mt792xe_mcu_drv_pmctrl(dev);
838 if (err < 0)
839 goto out;
840
841 mt792x_wpdma_reinit_cond(dev);
842 clear_bit(MT76_STATE_PM, &mphy->state);
843
844 pm->stats.last_wake_event = jiffies;
845 pm->stats.doze_time += pm->stats.last_wake_event -
846 pm->stats.last_doze_event;
847out:
848 return err;
849}
850EXPORT_SYMBOL_GPL(mt792xe_mcu_drv_pmctrl);
851
852int mt792xe_mcu_fw_pmctrl(struct mt792x_dev *dev)
853{
854 struct mt76_phy *mphy = &dev->mt76.phy;
855 struct mt76_connac_pm *pm = &dev->pm;
856 int i;
857
858 for (i = 0; i < MT792x_DRV_OWN_RETRY_COUNT; i++) {
859 mt76_wr(dev, MT_CONN_ON_LPCTL, PCIE_LPCR_HOST_SET_OWN);
860 if (mt76_poll_msec_tick(dev, MT_CONN_ON_LPCTL,
861 PCIE_LPCR_HOST_OWN_SYNC, 4, 50, 1))
862 break;
863 }
864
865 if (i == MT792x_DRV_OWN_RETRY_COUNT) {
866 dev_err(dev->mt76.dev, "firmware own failed\n");
867 clear_bit(MT76_STATE_PM, &mphy->state);
868 return -EIO;
869 }
870
871 pm->stats.last_doze_event = jiffies;
872 pm->stats.awake_time += pm->stats.last_doze_event -
873 pm->stats.last_wake_event;
874
875 return 0;
876}
877EXPORT_SYMBOL_GPL(mt792xe_mcu_fw_pmctrl);
878
879int mt792x_load_firmware(struct mt792x_dev *dev)
880{
881 int ret;
882
883 ret = mt76_connac2_load_patch(&dev->mt76, mt792x_patch_name(dev));
884 if (ret)
885 return ret;
886
887 if (mt76_is_sdio(&dev->mt76)) {
888 /* activate again */
889 ret = __mt792x_mcu_fw_pmctrl(dev);
890 if (!ret)
891 ret = __mt792x_mcu_drv_pmctrl(dev);
892 }
893
894 ret = mt76_connac2_load_ram(&dev->mt76, mt792x_ram_name(dev), NULL);
895 if (ret)
896 return ret;
897
898 if (!mt76_poll_msec(dev, MT_CONN_ON_MISC, MT_TOP_MISC2_FW_N9_RDY,
899 MT_TOP_MISC2_FW_N9_RDY, 1500)) {
900 dev_err(dev->mt76.dev, "Timeout for initializing firmware\n");
901
902 return -EIO;
903 }
904
905#ifdef CONFIG_PM
906 dev->mt76.hw->wiphy->wowlan = &mt76_connac_wowlan_support;
907#endif /* CONFIG_PM */
908
909 dev_dbg(dev->mt76.dev, "Firmware init done\n");
910
911 return 0;
912}
913EXPORT_SYMBOL_GPL(mt792x_load_firmware);
914
915MODULE_DESCRIPTION("MediaTek MT792x core driver");
916MODULE_LICENSE("Dual BSD/GPL");
917MODULE_AUTHOR("Lorenzo Bianconi <lorenzo@kernel.org>");