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(phy: mphy, pm: &dev->pm)) {
79 mt76_tx(dev: mphy, sta: control->sta, wcid, skb);
80 mt76_connac_pm_unref(phy: mphy, pm: &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, queue_mapping: qid);
88 }
89
90 mt76_connac_pm_queue_skb(hw, pm: &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(dwork: &phy->mt76->mac_work);
100
101 cancel_delayed_work_sync(dwork: &dev->pm.ps_work);
102 cancel_work_sync(work: &dev->pm.wake_work);
103 cancel_work_sync(work: &dev->reset_work);
104 mt76_connac_free_pending_tx_skbs(pm: &dev->pm, NULL);
105
106 if (is_mt7921(dev: &dev->mt76)) {
107 mt792x_mutex_acquire(dev);
108 mt76_connac_mcu_set_mac_enable(dev: &dev->mt76, band: 0, enable: false, hdr_trans: false);
109 mt792x_mutex_release(dev);
110 }
111
112 clear_bit(nr: MT76_STATE_RUNNING, addr: &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(pm: &dev->pm, wcid: &msta->wcid);
127 mt76_connac_mcu_uni_add_dev(phy: &dev->mphy, vif, wcid: &mvif->sta.wcid, enable: 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(lock: &dev->mt76.sta_poll_lock);
136 if (!list_empty(head: &msta->wcid.poll_list))
137 list_del_init(entry: &msta->wcid.poll_list);
138 spin_unlock_bh(lock: &dev->mt76.sta_poll_lock);
139
140 mt76_wcid_cleanup(dev: &dev->mt76, wcid: &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(ac: 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(phy: &dev->mphy, pm: &dev->pm)) {
232 queue_work(wq: dev->mt76.wq, work: &dev->pm.wake_work);
233 return;
234 }
235
236 mt76_txq_schedule_all(phy: &dev->mphy);
237 mt76_connac_pm_unref(phy: &dev->mphy, pm: &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(hw: phy->mt76->hw, work: &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(lock: &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(lock: &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(dev: mdev->dev, enable: 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_bw_320",
358 "v_tx_mcs_0",
359 "v_tx_mcs_1",
360 "v_tx_mcs_2",
361 "v_tx_mcs_3",
362 "v_tx_mcs_4",
363 "v_tx_mcs_5",
364 "v_tx_mcs_6",
365 "v_tx_mcs_7",
366 "v_tx_mcs_8",
367 "v_tx_mcs_9",
368 "v_tx_mcs_10",
369 "v_tx_mcs_11",
370 "v_tx_mcs_12",
371 "v_tx_mcs_13",
372 "v_tx_nss_1",
373 "v_tx_nss_2",
374 "v_tx_nss_3",
375 "v_tx_nss_4",
376};
377
378void mt792x_get_et_strings(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
379 u32 sset, u8 *data)
380{
381 if (sset != ETH_SS_STATS)
382 return;
383
384 memcpy(data, mt792x_gstrings_stats, sizeof(mt792x_gstrings_stats));
385
386 data += sizeof(mt792x_gstrings_stats);
387 page_pool_ethtool_stats_get_strings(data);
388}
389EXPORT_SYMBOL_GPL(mt792x_get_et_strings);
390
391int mt792x_get_et_sset_count(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
392 int sset)
393{
394 if (sset != ETH_SS_STATS)
395 return 0;
396
397 return ARRAY_SIZE(mt792x_gstrings_stats) +
398 page_pool_ethtool_stats_get_count();
399}
400EXPORT_SYMBOL_GPL(mt792x_get_et_sset_count);
401
402static void
403mt792x_ethtool_worker(void *wi_data, struct ieee80211_sta *sta)
404{
405 struct mt792x_sta *msta = (struct mt792x_sta *)sta->drv_priv;
406 struct mt76_ethtool_worker_info *wi = wi_data;
407
408 if (msta->vif->mt76.idx != wi->idx)
409 return;
410
411 mt76_ethtool_worker(wi, stats: &msta->wcid.stats, eht: true);
412}
413
414void mt792x_get_et_stats(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
415 struct ethtool_stats *stats, u64 *data)
416{
417 struct mt792x_vif *mvif = (struct mt792x_vif *)vif->drv_priv;
418 int stats_size = ARRAY_SIZE(mt792x_gstrings_stats);
419 struct mt792x_phy *phy = mt792x_hw_phy(hw);
420 struct mt792x_dev *dev = phy->dev;
421 struct mt76_mib_stats *mib = &phy->mib;
422 struct mt76_ethtool_worker_info wi = {
423 .data = data,
424 .idx = mvif->mt76.idx,
425 };
426 int i, ei = 0;
427
428 mt792x_mutex_acquire(dev);
429
430 mt792x_mac_update_mib_stats(phy);
431
432 data[ei++] = mib->tx_ampdu_cnt;
433 data[ei++] = mib->tx_mpdu_attempts_cnt;
434 data[ei++] = mib->tx_mpdu_success_cnt;
435 data[ei++] = mib->tx_pkt_ebf_cnt;
436 data[ei++] = mib->tx_pkt_ibf_cnt;
437
438 /* Tx ampdu stat */
439 for (i = 0; i < 15; i++)
440 data[ei++] = phy->mt76->aggr_stats[i];
441
442 data[ei++] = phy->mib.ba_miss_cnt;
443
444 /* Tx Beamformer monitor */
445 data[ei++] = mib->tx_bf_ibf_ppdu_cnt;
446 data[ei++] = mib->tx_bf_ebf_ppdu_cnt;
447
448 /* Tx Beamformer Rx feedback monitor */
449 data[ei++] = mib->tx_bf_rx_fb_all_cnt;
450 data[ei++] = mib->tx_bf_rx_fb_he_cnt;
451 data[ei++] = mib->tx_bf_rx_fb_vht_cnt;
452 data[ei++] = mib->tx_bf_rx_fb_ht_cnt;
453
454 /* Tx amsdu info (pack-count histogram) */
455 for (i = 0; i < ARRAY_SIZE(mib->tx_amsdu); i++)
456 data[ei++] = mib->tx_amsdu[i];
457
458 /* rx counters */
459 data[ei++] = mib->rx_mpdu_cnt;
460 data[ei++] = mib->rx_ampdu_cnt;
461 data[ei++] = mib->rx_ampdu_bytes_cnt;
462 data[ei++] = mib->rx_ba_cnt;
463
464 /* Add values for all stations owned by this vif */
465 wi.initial_stat_idx = ei;
466 ieee80211_iterate_stations_atomic(hw, iterator: mt792x_ethtool_worker, data: &wi);
467
468 mt792x_mutex_release(dev);
469
470 if (!wi.sta_count)
471 return;
472
473 ei += wi.worker_stat_count;
474
475 mt76_ethtool_page_pool_stats(dev: &dev->mt76, data: &data[ei], index: &ei);
476 stats_size += page_pool_ethtool_stats_get_count();
477
478 if (ei != stats_size)
479 dev_err(dev->mt76.dev, "ei: %d SSTATS_LEN: %d", ei,
480 stats_size);
481}
482EXPORT_SYMBOL_GPL(mt792x_get_et_stats);
483
484void mt792x_sta_statistics(struct ieee80211_hw *hw,
485 struct ieee80211_vif *vif,
486 struct ieee80211_sta *sta,
487 struct station_info *sinfo)
488{
489 struct mt792x_sta *msta = (struct mt792x_sta *)sta->drv_priv;
490 struct rate_info *txrate = &msta->wcid.rate;
491
492 if (!txrate->legacy && !txrate->flags)
493 return;
494
495 if (txrate->legacy) {
496 sinfo->txrate.legacy = txrate->legacy;
497 } else {
498 sinfo->txrate.mcs = txrate->mcs;
499 sinfo->txrate.nss = txrate->nss;
500 sinfo->txrate.bw = txrate->bw;
501 sinfo->txrate.he_gi = txrate->he_gi;
502 sinfo->txrate.he_dcm = txrate->he_dcm;
503 sinfo->txrate.he_ru_alloc = txrate->he_ru_alloc;
504 }
505 sinfo->tx_failed = msta->wcid.stats.tx_failed;
506 sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_FAILED);
507
508 sinfo->tx_retries = msta->wcid.stats.tx_retries;
509 sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_RETRIES);
510
511 sinfo->txrate.flags = txrate->flags;
512 sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BITRATE);
513
514 sinfo->ack_signal = (s8)msta->ack_signal;
515 sinfo->filled |= BIT_ULL(NL80211_STA_INFO_ACK_SIGNAL);
516
517 sinfo->avg_ack_signal = -(s8)ewma_avg_signal_read(e: &msta->avg_ack_signal);
518 sinfo->filled |= BIT_ULL(NL80211_STA_INFO_ACK_SIGNAL_AVG);
519}
520EXPORT_SYMBOL_GPL(mt792x_sta_statistics);
521
522void mt792x_set_coverage_class(struct ieee80211_hw *hw, s16 coverage_class)
523{
524 struct mt792x_phy *phy = mt792x_hw_phy(hw);
525 struct mt792x_dev *dev = phy->dev;
526
527 mt792x_mutex_acquire(dev);
528
529 phy->coverage_class = max_t(s16, coverage_class, 0);
530 mt792x_mac_set_timeing(phy);
531
532 mt792x_mutex_release(dev);
533}
534EXPORT_SYMBOL_GPL(mt792x_set_coverage_class);
535
536int mt792x_init_wiphy(struct ieee80211_hw *hw)
537{
538 struct mt792x_phy *phy = mt792x_hw_phy(hw);
539 struct mt792x_dev *dev = phy->dev;
540 struct wiphy *wiphy = hw->wiphy;
541
542 hw->queues = 4;
543 if (dev->has_eht) {
544 hw->max_rx_aggregation_subframes = IEEE80211_MAX_AMPDU_BUF_EHT;
545 hw->max_tx_aggregation_subframes = IEEE80211_MAX_AMPDU_BUF_EHT;
546 } else {
547 hw->max_rx_aggregation_subframes = IEEE80211_MAX_AMPDU_BUF_HE;
548 hw->max_tx_aggregation_subframes = IEEE80211_MAX_AMPDU_BUF_HE;
549 }
550 hw->netdev_features = NETIF_F_RXCSUM;
551
552 hw->radiotap_timestamp.units_pos =
553 IEEE80211_RADIOTAP_TIMESTAMP_UNIT_US;
554
555 phy->slottime = 9;
556
557 hw->sta_data_size = sizeof(struct mt792x_sta);
558 hw->vif_data_size = sizeof(struct mt792x_vif);
559
560 if (dev->fw_features & MT792x_FW_CAP_CNM) {
561 wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
562 wiphy->iface_combinations = if_comb_chanctx;
563 wiphy->n_iface_combinations = ARRAY_SIZE(if_comb_chanctx);
564 } else {
565 wiphy->flags &= ~WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
566 wiphy->iface_combinations = if_comb;
567 wiphy->n_iface_combinations = ARRAY_SIZE(if_comb);
568 }
569 wiphy->flags &= ~(WIPHY_FLAG_IBSS_RSN | WIPHY_FLAG_4ADDR_AP |
570 WIPHY_FLAG_4ADDR_STATION);
571 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
572 BIT(NL80211_IFTYPE_AP) |
573 BIT(NL80211_IFTYPE_P2P_CLIENT) |
574 BIT(NL80211_IFTYPE_P2P_GO);
575 wiphy->max_remain_on_channel_duration = 5000;
576 wiphy->max_scan_ie_len = MT76_CONNAC_SCAN_IE_LEN;
577 wiphy->max_scan_ssids = 4;
578 wiphy->max_sched_scan_plan_interval =
579 MT76_CONNAC_MAX_TIME_SCHED_SCAN_INTERVAL;
580 wiphy->max_sched_scan_ie_len = IEEE80211_MAX_DATA_LEN;
581 wiphy->max_sched_scan_ssids = MT76_CONNAC_MAX_SCHED_SCAN_SSID;
582 wiphy->max_match_sets = MT76_CONNAC_MAX_SCAN_MATCH;
583 wiphy->max_sched_scan_reqs = 1;
584 wiphy->flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH |
585 WIPHY_FLAG_SPLIT_SCAN_6GHZ;
586
587 wiphy->features |= NL80211_FEATURE_SCHED_SCAN_RANDOM_MAC_ADDR |
588 NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR;
589 wiphy_ext_feature_set(wiphy, ftidx: NL80211_EXT_FEATURE_SET_SCAN_DWELL);
590 wiphy_ext_feature_set(wiphy, ftidx: NL80211_EXT_FEATURE_BEACON_RATE_LEGACY);
591 wiphy_ext_feature_set(wiphy, ftidx: NL80211_EXT_FEATURE_BEACON_RATE_HT);
592 wiphy_ext_feature_set(wiphy, ftidx: NL80211_EXT_FEATURE_BEACON_RATE_VHT);
593 wiphy_ext_feature_set(wiphy, ftidx: NL80211_EXT_FEATURE_BEACON_RATE_HE);
594 wiphy_ext_feature_set(wiphy, ftidx: NL80211_EXT_FEATURE_ACK_SIGNAL_SUPPORT);
595 wiphy_ext_feature_set(wiphy, ftidx: NL80211_EXT_FEATURE_CAN_REPLACE_PTK0);
596
597 ieee80211_hw_set(hw, SINGLE_SCAN_ON_ALL_BANDS);
598 ieee80211_hw_set(hw, HAS_RATE_CONTROL);
599 ieee80211_hw_set(hw, SUPPORTS_TX_ENCAP_OFFLOAD);
600 ieee80211_hw_set(hw, SUPPORTS_RX_DECAP_OFFLOAD);
601 ieee80211_hw_set(hw, WANT_MONITOR_VIF);
602 ieee80211_hw_set(hw, SUPPORTS_PS);
603 ieee80211_hw_set(hw, SUPPORTS_DYNAMIC_PS);
604 ieee80211_hw_set(hw, SUPPORTS_VHT_EXT_NSS_BW);
605 ieee80211_hw_set(hw, CONNECTION_MONITOR);
606
607 if (dev->pm.enable)
608 ieee80211_hw_set(hw, CONNECTION_MONITOR);
609
610 hw->max_tx_fragments = 4;
611
612 return 0;
613}
614EXPORT_SYMBOL_GPL(mt792x_init_wiphy);
615
616static u8
617mt792x_get_offload_capability(struct device *dev, const char *fw_wm)
618{
619 const struct mt76_connac2_fw_trailer *hdr;
620 struct mt792x_realease_info *rel_info;
621 const struct firmware *fw;
622 int ret, i, offset = 0;
623 const u8 *data, *end;
624 u8 offload_caps = 0;
625
626 ret = request_firmware(fw: &fw, name: fw_wm, device: dev);
627 if (ret)
628 return ret;
629
630 if (!fw || !fw->data || fw->size < sizeof(*hdr)) {
631 dev_err(dev, "Invalid firmware\n");
632 goto out;
633 }
634
635 data = fw->data;
636 hdr = (const void *)(fw->data + fw->size - sizeof(*hdr));
637
638 for (i = 0; i < hdr->n_region; i++) {
639 const struct mt76_connac2_fw_region *region;
640
641 region = (const void *)((const u8 *)hdr -
642 (hdr->n_region - i) * sizeof(*region));
643 offset += le32_to_cpu(region->len);
644 }
645
646 data += offset + 16;
647 rel_info = (struct mt792x_realease_info *)data;
648 data += sizeof(*rel_info);
649 end = data + le16_to_cpu(rel_info->len);
650
651 while (data < end) {
652 rel_info = (struct mt792x_realease_info *)data;
653 data += sizeof(*rel_info);
654
655 if (rel_info->tag == MT792x_FW_TAG_FEATURE) {
656 struct mt792x_fw_features *features;
657
658 features = (struct mt792x_fw_features *)data;
659 offload_caps = features->data;
660 break;
661 }
662
663 data += le16_to_cpu(rel_info->len) + rel_info->pad_len;
664 }
665
666out:
667 release_firmware(fw);
668
669 return offload_caps;
670}
671
672struct ieee80211_ops *
673mt792x_get_mac80211_ops(struct device *dev,
674 const struct ieee80211_ops *mac80211_ops,
675 void *drv_data, u8 *fw_features)
676{
677 struct ieee80211_ops *ops;
678
679 ops = devm_kmemdup(dev, src: mac80211_ops, len: sizeof(struct ieee80211_ops),
680 GFP_KERNEL);
681 if (!ops)
682 return NULL;
683
684 *fw_features = mt792x_get_offload_capability(dev, fw_wm: drv_data);
685 if (!(*fw_features & MT792x_FW_CAP_CNM)) {
686 ops->remain_on_channel = NULL;
687 ops->cancel_remain_on_channel = NULL;
688 ops->add_chanctx = ieee80211_emulate_add_chanctx;
689 ops->remove_chanctx = ieee80211_emulate_remove_chanctx;
690 ops->change_chanctx = ieee80211_emulate_change_chanctx;
691 ops->switch_vif_chanctx = ieee80211_emulate_switch_vif_chanctx;
692 ops->assign_vif_chanctx = NULL;
693 ops->unassign_vif_chanctx = NULL;
694 ops->mgd_prepare_tx = NULL;
695 ops->mgd_complete_tx = NULL;
696 }
697 return ops;
698}
699EXPORT_SYMBOL_GPL(mt792x_get_mac80211_ops);
700
701int mt792x_init_wcid(struct mt792x_dev *dev)
702{
703 int idx;
704
705 /* Beacon and mgmt frames should occupy wcid 0 */
706 idx = mt76_wcid_alloc(mask: dev->mt76.wcid_mask, MT792x_WTBL_STA - 1);
707 if (idx)
708 return -ENOSPC;
709
710 dev->mt76.global_wcid.idx = idx;
711 dev->mt76.global_wcid.hw_key_idx = -1;
712 dev->mt76.global_wcid.tx_info |= MT_WCID_TX_INFO_SET;
713 rcu_assign_pointer(dev->mt76.wcid[idx], &dev->mt76.global_wcid);
714
715 return 0;
716}
717EXPORT_SYMBOL_GPL(mt792x_init_wcid);
718
719int mt792x_mcu_drv_pmctrl(struct mt792x_dev *dev)
720{
721 struct mt76_phy *mphy = &dev->mt76.phy;
722 struct mt76_connac_pm *pm = &dev->pm;
723 int err = 0;
724
725 mutex_lock(&pm->mutex);
726
727 if (!test_bit(MT76_STATE_PM, &mphy->state))
728 goto out;
729
730 err = __mt792x_mcu_drv_pmctrl(dev);
731out:
732 mutex_unlock(lock: &pm->mutex);
733
734 if (err)
735 mt792x_reset(mdev: &dev->mt76);
736
737 return err;
738}
739EXPORT_SYMBOL_GPL(mt792x_mcu_drv_pmctrl);
740
741int mt792x_mcu_fw_pmctrl(struct mt792x_dev *dev)
742{
743 struct mt76_phy *mphy = &dev->mt76.phy;
744 struct mt76_connac_pm *pm = &dev->pm;
745 int err = 0;
746
747 mutex_lock(&pm->mutex);
748
749 if (mt76_connac_skip_fw_pmctrl(phy: mphy, pm))
750 goto out;
751
752 err = __mt792x_mcu_fw_pmctrl(dev);
753out:
754 mutex_unlock(lock: &pm->mutex);
755
756 if (err)
757 mt792x_reset(mdev: &dev->mt76);
758
759 return err;
760}
761EXPORT_SYMBOL_GPL(mt792x_mcu_fw_pmctrl);
762
763int __mt792xe_mcu_drv_pmctrl(struct mt792x_dev *dev)
764{
765 int i, err = 0;
766
767 for (i = 0; i < MT792x_DRV_OWN_RETRY_COUNT; i++) {
768 mt76_wr(dev, MT_CONN_ON_LPCTL, PCIE_LPCR_HOST_CLR_OWN);
769 if (mt76_poll_msec_tick(dev, MT_CONN_ON_LPCTL,
770 PCIE_LPCR_HOST_OWN_SYNC, 0, 50, 1))
771 break;
772 }
773
774 if (i == MT792x_DRV_OWN_RETRY_COUNT) {
775 dev_err(dev->mt76.dev, "driver own failed\n");
776 err = -EIO;
777 }
778
779 return err;
780}
781EXPORT_SYMBOL_GPL(__mt792xe_mcu_drv_pmctrl);
782
783int mt792xe_mcu_drv_pmctrl(struct mt792x_dev *dev)
784{
785 struct mt76_phy *mphy = &dev->mt76.phy;
786 struct mt76_connac_pm *pm = &dev->pm;
787 int err;
788
789 err = __mt792xe_mcu_drv_pmctrl(dev);
790 if (err < 0)
791 goto out;
792
793 mt792x_wpdma_reinit_cond(dev);
794 clear_bit(nr: MT76_STATE_PM, addr: &mphy->state);
795
796 pm->stats.last_wake_event = jiffies;
797 pm->stats.doze_time += pm->stats.last_wake_event -
798 pm->stats.last_doze_event;
799out:
800 return err;
801}
802EXPORT_SYMBOL_GPL(mt792xe_mcu_drv_pmctrl);
803
804int mt792xe_mcu_fw_pmctrl(struct mt792x_dev *dev)
805{
806 struct mt76_phy *mphy = &dev->mt76.phy;
807 struct mt76_connac_pm *pm = &dev->pm;
808 int i;
809
810 for (i = 0; i < MT792x_DRV_OWN_RETRY_COUNT; i++) {
811 mt76_wr(dev, MT_CONN_ON_LPCTL, PCIE_LPCR_HOST_SET_OWN);
812 if (mt76_poll_msec_tick(dev, MT_CONN_ON_LPCTL,
813 PCIE_LPCR_HOST_OWN_SYNC, 4, 50, 1))
814 break;
815 }
816
817 if (i == MT792x_DRV_OWN_RETRY_COUNT) {
818 dev_err(dev->mt76.dev, "firmware own failed\n");
819 clear_bit(nr: MT76_STATE_PM, addr: &mphy->state);
820 return -EIO;
821 }
822
823 pm->stats.last_doze_event = jiffies;
824 pm->stats.awake_time += pm->stats.last_doze_event -
825 pm->stats.last_wake_event;
826
827 return 0;
828}
829EXPORT_SYMBOL_GPL(mt792xe_mcu_fw_pmctrl);
830
831int mt792x_load_firmware(struct mt792x_dev *dev)
832{
833 int ret;
834
835 ret = mt76_connac2_load_patch(dev: &dev->mt76, fw_name: mt792x_patch_name(dev));
836 if (ret)
837 return ret;
838
839 if (mt76_is_sdio(&dev->mt76)) {
840 /* activate again */
841 ret = __mt792x_mcu_fw_pmctrl(dev);
842 if (!ret)
843 ret = __mt792x_mcu_drv_pmctrl(dev);
844 }
845
846 ret = mt76_connac2_load_ram(dev: &dev->mt76, fw_wm: mt792x_ram_name(dev), NULL);
847 if (ret)
848 return ret;
849
850 if (!mt76_poll_msec(dev, MT_CONN_ON_MISC, MT_TOP_MISC2_FW_N9_RDY,
851 MT_TOP_MISC2_FW_N9_RDY, 1500)) {
852 dev_err(dev->mt76.dev, "Timeout for initializing firmware\n");
853
854 return -EIO;
855 }
856
857#ifdef CONFIG_PM
858 dev->mt76.hw->wiphy->wowlan = &mt76_connac_wowlan_support;
859#endif /* CONFIG_PM */
860
861 dev_dbg(dev->mt76.dev, "Firmware init done\n");
862
863 return 0;
864}
865EXPORT_SYMBOL_GPL(mt792x_load_firmware);
866
867MODULE_DESCRIPTION("MediaTek MT792x core driver");
868MODULE_LICENSE("Dual BSD/GPL");
869MODULE_AUTHOR("Lorenzo Bianconi <lorenzo@kernel.org>");
870

source code of linux/drivers/net/wireless/mediatek/mt76/mt792x_core.c