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 
10 static 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 
21 static 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 
31 static 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 
44 static 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 
54 void 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 }
92 EXPORT_SYMBOL_GPL(mt792x_tx);
93 
94 void mt792x_remove_interface(struct ieee80211_hw *hw,
95 			     struct ieee80211_vif *vif)
96 {
97 	struct mt792x_vif *mvif = (struct mt792x_vif *)vif->drv_priv;
98 	struct mt792x_sta *msta = &mvif->sta;
99 	struct mt792x_dev *dev = mt792x_hw_dev(hw);
100 	struct mt792x_phy *phy = mt792x_hw_phy(hw);
101 	int idx = msta->wcid.idx;
102 
103 	mt792x_mutex_acquire(dev);
104 	mt76_connac_free_pending_tx_skbs(&dev->pm, &msta->wcid);
105 	mt76_connac_mcu_uni_add_dev(&dev->mphy, vif, &mvif->sta.wcid, false);
106 
107 	rcu_assign_pointer(dev->mt76.wcid[idx], NULL);
108 
109 	dev->mt76.vif_mask &= ~BIT_ULL(mvif->mt76.idx);
110 	phy->omac_mask &= ~BIT_ULL(mvif->mt76.omac_idx);
111 	mt792x_mutex_release(dev);
112 
113 	spin_lock_bh(&dev->mt76.sta_poll_lock);
114 	if (!list_empty(&msta->wcid.poll_list))
115 		list_del_init(&msta->wcid.poll_list);
116 	spin_unlock_bh(&dev->mt76.sta_poll_lock);
117 
118 	mt76_packet_id_flush(&dev->mt76, &msta->wcid);
119 }
120 EXPORT_SYMBOL_GPL(mt792x_remove_interface);
121 
122 int mt792x_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
123 		   unsigned int link_id, u16 queue,
124 		   const struct ieee80211_tx_queue_params *params)
125 {
126 	struct mt792x_vif *mvif = (struct mt792x_vif *)vif->drv_priv;
127 
128 	/* no need to update right away, we'll get BSS_CHANGED_QOS */
129 	queue = mt76_connac_lmac_mapping(queue);
130 	mvif->queue_params[queue] = *params;
131 
132 	return 0;
133 }
134 EXPORT_SYMBOL_GPL(mt792x_conf_tx);
135 
136 int mt792x_get_stats(struct ieee80211_hw *hw,
137 		     struct ieee80211_low_level_stats *stats)
138 {
139 	struct mt792x_phy *phy = mt792x_hw_phy(hw);
140 	struct mt76_mib_stats *mib = &phy->mib;
141 
142 	mt792x_mutex_acquire(phy->dev);
143 
144 	stats->dot11RTSSuccessCount = mib->rts_cnt;
145 	stats->dot11RTSFailureCount = mib->rts_retries_cnt;
146 	stats->dot11FCSErrorCount = mib->fcs_err_cnt;
147 	stats->dot11ACKFailureCount = mib->ack_fail_cnt;
148 
149 	mt792x_mutex_release(phy->dev);
150 
151 	return 0;
152 }
153 EXPORT_SYMBOL_GPL(mt792x_get_stats);
154 
155 u64 mt792x_get_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
156 {
157 	struct mt792x_vif *mvif = (struct mt792x_vif *)vif->drv_priv;
158 	struct mt792x_dev *dev = mt792x_hw_dev(hw);
159 	u8 omac_idx = mvif->mt76.omac_idx;
160 	union {
161 		u64 t64;
162 		u32 t32[2];
163 	} tsf;
164 	u16 n;
165 
166 	mt792x_mutex_acquire(dev);
167 
168 	n = omac_idx > HW_BSSID_MAX ? HW_BSSID_0 : omac_idx;
169 	/* TSF software read */
170 	mt76_set(dev, MT_LPON_TCR(0, n), MT_LPON_TCR_SW_MODE);
171 	tsf.t32[0] = mt76_rr(dev, MT_LPON_UTTR0(0));
172 	tsf.t32[1] = mt76_rr(dev, MT_LPON_UTTR1(0));
173 
174 	mt792x_mutex_release(dev);
175 
176 	return tsf.t64;
177 }
178 EXPORT_SYMBOL_GPL(mt792x_get_tsf);
179 
180 void mt792x_set_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
181 		    u64 timestamp)
182 {
183 	struct mt792x_vif *mvif = (struct mt792x_vif *)vif->drv_priv;
184 	struct mt792x_dev *dev = mt792x_hw_dev(hw);
185 	u8 omac_idx = mvif->mt76.omac_idx;
186 	union {
187 		u64 t64;
188 		u32 t32[2];
189 	} tsf = { .t64 = timestamp, };
190 	u16 n;
191 
192 	mt792x_mutex_acquire(dev);
193 
194 	n = omac_idx > HW_BSSID_MAX ? HW_BSSID_0 : omac_idx;
195 	mt76_wr(dev, MT_LPON_UTTR0(0), tsf.t32[0]);
196 	mt76_wr(dev, MT_LPON_UTTR1(0), tsf.t32[1]);
197 	/* TSF software overwrite */
198 	mt76_set(dev, MT_LPON_TCR(0, n), MT_LPON_TCR_SW_WRITE);
199 
200 	mt792x_mutex_release(dev);
201 }
202 EXPORT_SYMBOL_GPL(mt792x_set_tsf);
203 
204 void mt792x_tx_worker(struct mt76_worker *w)
205 {
206 	struct mt792x_dev *dev = container_of(w, struct mt792x_dev,
207 					      mt76.tx_worker);
208 
209 	if (!mt76_connac_pm_ref(&dev->mphy, &dev->pm)) {
210 		queue_work(dev->mt76.wq, &dev->pm.wake_work);
211 		return;
212 	}
213 
214 	mt76_txq_schedule_all(&dev->mphy);
215 	mt76_connac_pm_unref(&dev->mphy, &dev->pm);
216 }
217 EXPORT_SYMBOL_GPL(mt792x_tx_worker);
218 
219 void mt792x_roc_timer(struct timer_list *timer)
220 {
221 	struct mt792x_phy *phy = from_timer(phy, timer, roc_timer);
222 
223 	ieee80211_queue_work(phy->mt76->hw, &phy->roc_work);
224 }
225 EXPORT_SYMBOL_GPL(mt792x_roc_timer);
226 
227 void mt792x_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
228 		  u32 queues, bool drop)
229 {
230 	struct mt792x_dev *dev = mt792x_hw_dev(hw);
231 
232 	wait_event_timeout(dev->mt76.tx_wait,
233 			   !mt76_has_tx_pending(&dev->mphy), HZ / 2);
234 }
235 EXPORT_SYMBOL_GPL(mt792x_flush);
236 
237 int mt792x_assign_vif_chanctx(struct ieee80211_hw *hw,
238 			      struct ieee80211_vif *vif,
239 			      struct ieee80211_bss_conf *link_conf,
240 			      struct ieee80211_chanctx_conf *ctx)
241 {
242 	struct mt792x_vif *mvif = (struct mt792x_vif *)vif->drv_priv;
243 	struct mt792x_dev *dev = mt792x_hw_dev(hw);
244 
245 	mutex_lock(&dev->mt76.mutex);
246 	mvif->ctx = ctx;
247 	mutex_unlock(&dev->mt76.mutex);
248 
249 	return 0;
250 }
251 EXPORT_SYMBOL_GPL(mt792x_assign_vif_chanctx);
252 
253 void mt792x_unassign_vif_chanctx(struct ieee80211_hw *hw,
254 				 struct ieee80211_vif *vif,
255 				 struct ieee80211_bss_conf *link_conf,
256 				 struct ieee80211_chanctx_conf *ctx)
257 {
258 	struct mt792x_vif *mvif = (struct mt792x_vif *)vif->drv_priv;
259 	struct mt792x_dev *dev = mt792x_hw_dev(hw);
260 
261 	mutex_lock(&dev->mt76.mutex);
262 	mvif->ctx = NULL;
263 	mutex_unlock(&dev->mt76.mutex);
264 }
265 EXPORT_SYMBOL_GPL(mt792x_unassign_vif_chanctx);
266 
267 void mt792x_set_wakeup(struct ieee80211_hw *hw, bool enabled)
268 {
269 	struct mt792x_dev *dev = mt792x_hw_dev(hw);
270 	struct mt76_dev *mdev = &dev->mt76;
271 
272 	device_set_wakeup_enable(mdev->dev, enabled);
273 }
274 EXPORT_SYMBOL_GPL(mt792x_set_wakeup);
275 
276 static const char mt792x_gstrings_stats[][ETH_GSTRING_LEN] = {
277 	/* tx counters */
278 	"tx_ampdu_cnt",
279 	"tx_mpdu_attempts",
280 	"tx_mpdu_success",
281 	"tx_pkt_ebf_cnt",
282 	"tx_pkt_ibf_cnt",
283 	"tx_ampdu_len:0-1",
284 	"tx_ampdu_len:2-10",
285 	"tx_ampdu_len:11-19",
286 	"tx_ampdu_len:20-28",
287 	"tx_ampdu_len:29-37",
288 	"tx_ampdu_len:38-46",
289 	"tx_ampdu_len:47-55",
290 	"tx_ampdu_len:56-79",
291 	"tx_ampdu_len:80-103",
292 	"tx_ampdu_len:104-127",
293 	"tx_ampdu_len:128-151",
294 	"tx_ampdu_len:152-175",
295 	"tx_ampdu_len:176-199",
296 	"tx_ampdu_len:200-223",
297 	"tx_ampdu_len:224-247",
298 	"ba_miss_count",
299 	"tx_beamformer_ppdu_iBF",
300 	"tx_beamformer_ppdu_eBF",
301 	"tx_beamformer_rx_feedback_all",
302 	"tx_beamformer_rx_feedback_he",
303 	"tx_beamformer_rx_feedback_vht",
304 	"tx_beamformer_rx_feedback_ht",
305 	"tx_msdu_pack_1",
306 	"tx_msdu_pack_2",
307 	"tx_msdu_pack_3",
308 	"tx_msdu_pack_4",
309 	"tx_msdu_pack_5",
310 	"tx_msdu_pack_6",
311 	"tx_msdu_pack_7",
312 	"tx_msdu_pack_8",
313 	/* rx counters */
314 	"rx_mpdu_cnt",
315 	"rx_ampdu_cnt",
316 	"rx_ampdu_bytes_cnt",
317 	"rx_ba_cnt",
318 	/* per vif counters */
319 	"v_tx_mode_cck",
320 	"v_tx_mode_ofdm",
321 	"v_tx_mode_ht",
322 	"v_tx_mode_ht_gf",
323 	"v_tx_mode_vht",
324 	"v_tx_mode_he_su",
325 	"v_tx_mode_he_ext_su",
326 	"v_tx_mode_he_tb",
327 	"v_tx_mode_he_mu",
328 	"v_tx_mode_eht_su",
329 	"v_tx_mode_eht_trig",
330 	"v_tx_mode_eht_mu",
331 	"v_tx_bw_20",
332 	"v_tx_bw_40",
333 	"v_tx_bw_80",
334 	"v_tx_bw_160",
335 	"v_tx_mcs_0",
336 	"v_tx_mcs_1",
337 	"v_tx_mcs_2",
338 	"v_tx_mcs_3",
339 	"v_tx_mcs_4",
340 	"v_tx_mcs_5",
341 	"v_tx_mcs_6",
342 	"v_tx_mcs_7",
343 	"v_tx_mcs_8",
344 	"v_tx_mcs_9",
345 	"v_tx_mcs_10",
346 	"v_tx_mcs_11",
347 	"v_tx_mcs_12",
348 	"v_tx_mcs_13",
349 	"v_tx_nss_1",
350 	"v_tx_nss_2",
351 	"v_tx_nss_3",
352 	"v_tx_nss_4",
353 };
354 
355 void mt792x_get_et_strings(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
356 			   u32 sset, u8 *data)
357 {
358 	if (sset != ETH_SS_STATS)
359 		return;
360 
361 	memcpy(data, *mt792x_gstrings_stats, sizeof(mt792x_gstrings_stats));
362 
363 	data += sizeof(mt792x_gstrings_stats);
364 	page_pool_ethtool_stats_get_strings(data);
365 }
366 EXPORT_SYMBOL_GPL(mt792x_get_et_strings);
367 
368 int mt792x_get_et_sset_count(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
369 			     int sset)
370 {
371 	if (sset != ETH_SS_STATS)
372 		return 0;
373 
374 	return ARRAY_SIZE(mt792x_gstrings_stats) +
375 	       page_pool_ethtool_stats_get_count();
376 }
377 EXPORT_SYMBOL_GPL(mt792x_get_et_sset_count);
378 
379 static void
380 mt792x_ethtool_worker(void *wi_data, struct ieee80211_sta *sta)
381 {
382 	struct mt792x_sta *msta = (struct mt792x_sta *)sta->drv_priv;
383 	struct mt76_ethtool_worker_info *wi = wi_data;
384 
385 	if (msta->vif->mt76.idx != wi->idx)
386 		return;
387 
388 	mt76_ethtool_worker(wi, &msta->wcid.stats, true);
389 }
390 
391 void mt792x_get_et_stats(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
392 			 struct ethtool_stats *stats, u64 *data)
393 {
394 	struct mt792x_vif *mvif = (struct mt792x_vif *)vif->drv_priv;
395 	int stats_size = ARRAY_SIZE(mt792x_gstrings_stats);
396 	struct mt792x_phy *phy = mt792x_hw_phy(hw);
397 	struct mt792x_dev *dev = phy->dev;
398 	struct mt76_mib_stats *mib = &phy->mib;
399 	struct mt76_ethtool_worker_info wi = {
400 		.data = data,
401 		.idx = mvif->mt76.idx,
402 	};
403 	int i, ei = 0;
404 
405 	mt792x_mutex_acquire(dev);
406 
407 	mt792x_mac_update_mib_stats(phy);
408 
409 	data[ei++] = mib->tx_ampdu_cnt;
410 	data[ei++] = mib->tx_mpdu_attempts_cnt;
411 	data[ei++] = mib->tx_mpdu_success_cnt;
412 	data[ei++] = mib->tx_pkt_ebf_cnt;
413 	data[ei++] = mib->tx_pkt_ibf_cnt;
414 
415 	/* Tx ampdu stat */
416 	for (i = 0; i < 15; i++)
417 		data[ei++] = phy->mt76->aggr_stats[i];
418 
419 	data[ei++] = phy->mib.ba_miss_cnt;
420 
421 	/* Tx Beamformer monitor */
422 	data[ei++] = mib->tx_bf_ibf_ppdu_cnt;
423 	data[ei++] = mib->tx_bf_ebf_ppdu_cnt;
424 
425 	/* Tx Beamformer Rx feedback monitor */
426 	data[ei++] = mib->tx_bf_rx_fb_all_cnt;
427 	data[ei++] = mib->tx_bf_rx_fb_he_cnt;
428 	data[ei++] = mib->tx_bf_rx_fb_vht_cnt;
429 	data[ei++] = mib->tx_bf_rx_fb_ht_cnt;
430 
431 	/* Tx amsdu info (pack-count histogram) */
432 	for (i = 0; i < ARRAY_SIZE(mib->tx_amsdu); i++)
433 		data[ei++] = mib->tx_amsdu[i];
434 
435 	/* rx counters */
436 	data[ei++] = mib->rx_mpdu_cnt;
437 	data[ei++] = mib->rx_ampdu_cnt;
438 	data[ei++] = mib->rx_ampdu_bytes_cnt;
439 	data[ei++] = mib->rx_ba_cnt;
440 
441 	/* Add values for all stations owned by this vif */
442 	wi.initial_stat_idx = ei;
443 	ieee80211_iterate_stations_atomic(hw, mt792x_ethtool_worker, &wi);
444 
445 	mt792x_mutex_release(dev);
446 
447 	if (!wi.sta_count)
448 		return;
449 
450 	ei += wi.worker_stat_count;
451 
452 	mt76_ethtool_page_pool_stats(&dev->mt76, &data[ei], &ei);
453 	stats_size += page_pool_ethtool_stats_get_count();
454 
455 	if (ei != stats_size)
456 		dev_err(dev->mt76.dev, "ei: %d  SSTATS_LEN: %d", ei,
457 			stats_size);
458 }
459 EXPORT_SYMBOL_GPL(mt792x_get_et_stats);
460 
461 void mt792x_sta_statistics(struct ieee80211_hw *hw,
462 			   struct ieee80211_vif *vif,
463 			   struct ieee80211_sta *sta,
464 			   struct station_info *sinfo)
465 {
466 	struct mt792x_sta *msta = (struct mt792x_sta *)sta->drv_priv;
467 	struct rate_info *txrate = &msta->wcid.rate;
468 
469 	if (!txrate->legacy && !txrate->flags)
470 		return;
471 
472 	if (txrate->legacy) {
473 		sinfo->txrate.legacy = txrate->legacy;
474 	} else {
475 		sinfo->txrate.mcs = txrate->mcs;
476 		sinfo->txrate.nss = txrate->nss;
477 		sinfo->txrate.bw = txrate->bw;
478 		sinfo->txrate.he_gi = txrate->he_gi;
479 		sinfo->txrate.he_dcm = txrate->he_dcm;
480 		sinfo->txrate.he_ru_alloc = txrate->he_ru_alloc;
481 	}
482 	sinfo->tx_failed = msta->wcid.stats.tx_failed;
483 	sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_FAILED);
484 
485 	sinfo->tx_retries = msta->wcid.stats.tx_retries;
486 	sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_RETRIES);
487 
488 	sinfo->txrate.flags = txrate->flags;
489 	sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BITRATE);
490 
491 	sinfo->ack_signal = (s8)msta->ack_signal;
492 	sinfo->filled |= BIT_ULL(NL80211_STA_INFO_ACK_SIGNAL);
493 
494 	sinfo->avg_ack_signal = -(s8)ewma_avg_signal_read(&msta->avg_ack_signal);
495 	sinfo->filled |= BIT_ULL(NL80211_STA_INFO_ACK_SIGNAL_AVG);
496 }
497 EXPORT_SYMBOL_GPL(mt792x_sta_statistics);
498 
499 void mt792x_set_coverage_class(struct ieee80211_hw *hw, s16 coverage_class)
500 {
501 	struct mt792x_phy *phy = mt792x_hw_phy(hw);
502 	struct mt792x_dev *dev = phy->dev;
503 
504 	mt792x_mutex_acquire(dev);
505 
506 	phy->coverage_class = max_t(s16, coverage_class, 0);
507 	mt792x_mac_set_timeing(phy);
508 
509 	mt792x_mutex_release(dev);
510 }
511 EXPORT_SYMBOL_GPL(mt792x_set_coverage_class);
512 
513 int mt792x_init_wiphy(struct ieee80211_hw *hw)
514 {
515 	struct mt792x_phy *phy = mt792x_hw_phy(hw);
516 	struct mt792x_dev *dev = phy->dev;
517 	struct wiphy *wiphy = hw->wiphy;
518 
519 	hw->queues = 4;
520 	if (dev->has_eht) {
521 		hw->max_rx_aggregation_subframes = IEEE80211_MAX_AMPDU_BUF_EHT;
522 		hw->max_tx_aggregation_subframes = IEEE80211_MAX_AMPDU_BUF_EHT;
523 	} else {
524 		hw->max_rx_aggregation_subframes = IEEE80211_MAX_AMPDU_BUF_HE;
525 		hw->max_tx_aggregation_subframes = IEEE80211_MAX_AMPDU_BUF_HE;
526 	}
527 	hw->netdev_features = NETIF_F_RXCSUM;
528 
529 	hw->radiotap_timestamp.units_pos =
530 		IEEE80211_RADIOTAP_TIMESTAMP_UNIT_US;
531 
532 	phy->slottime = 9;
533 
534 	hw->sta_data_size = sizeof(struct mt792x_sta);
535 	hw->vif_data_size = sizeof(struct mt792x_vif);
536 
537 	if (dev->fw_features & MT792x_FW_CAP_CNM) {
538 		wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
539 		wiphy->iface_combinations = if_comb_chanctx;
540 		wiphy->n_iface_combinations = ARRAY_SIZE(if_comb_chanctx);
541 	} else {
542 		wiphy->flags &= ~WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
543 		wiphy->iface_combinations = if_comb;
544 		wiphy->n_iface_combinations = ARRAY_SIZE(if_comb);
545 	}
546 	wiphy->flags &= ~(WIPHY_FLAG_IBSS_RSN | WIPHY_FLAG_4ADDR_AP |
547 			  WIPHY_FLAG_4ADDR_STATION);
548 	wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
549 				 BIT(NL80211_IFTYPE_AP) |
550 				 BIT(NL80211_IFTYPE_P2P_CLIENT) |
551 				 BIT(NL80211_IFTYPE_P2P_GO);
552 	wiphy->max_remain_on_channel_duration = 5000;
553 	wiphy->max_scan_ie_len = MT76_CONNAC_SCAN_IE_LEN;
554 	wiphy->max_scan_ssids = 4;
555 	wiphy->max_sched_scan_plan_interval =
556 		MT76_CONNAC_MAX_TIME_SCHED_SCAN_INTERVAL;
557 	wiphy->max_sched_scan_ie_len = IEEE80211_MAX_DATA_LEN;
558 	wiphy->max_sched_scan_ssids = MT76_CONNAC_MAX_SCHED_SCAN_SSID;
559 	wiphy->max_match_sets = MT76_CONNAC_MAX_SCAN_MATCH;
560 	wiphy->max_sched_scan_reqs = 1;
561 	wiphy->flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH |
562 			WIPHY_FLAG_SPLIT_SCAN_6GHZ;
563 
564 	wiphy->features |= NL80211_FEATURE_SCHED_SCAN_RANDOM_MAC_ADDR |
565 			   NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR;
566 	wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_SET_SCAN_DWELL);
567 	wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_BEACON_RATE_LEGACY);
568 	wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_BEACON_RATE_HT);
569 	wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_BEACON_RATE_VHT);
570 	wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_BEACON_RATE_HE);
571 	wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_ACK_SIGNAL_SUPPORT);
572 	wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_CAN_REPLACE_PTK0);
573 
574 	ieee80211_hw_set(hw, SINGLE_SCAN_ON_ALL_BANDS);
575 	ieee80211_hw_set(hw, HAS_RATE_CONTROL);
576 	ieee80211_hw_set(hw, SUPPORTS_TX_ENCAP_OFFLOAD);
577 	ieee80211_hw_set(hw, SUPPORTS_RX_DECAP_OFFLOAD);
578 	ieee80211_hw_set(hw, WANT_MONITOR_VIF);
579 	ieee80211_hw_set(hw, SUPPORTS_PS);
580 	ieee80211_hw_set(hw, SUPPORTS_DYNAMIC_PS);
581 	ieee80211_hw_set(hw, SUPPORTS_VHT_EXT_NSS_BW);
582 	ieee80211_hw_set(hw, CONNECTION_MONITOR);
583 
584 	if (dev->pm.enable)
585 		ieee80211_hw_set(hw, CONNECTION_MONITOR);
586 
587 	hw->max_tx_fragments = 4;
588 
589 	return 0;
590 }
591 EXPORT_SYMBOL_GPL(mt792x_init_wiphy);
592 
593 static u8
594 mt792x_get_offload_capability(struct device *dev, const char *fw_wm)
595 {
596 	const struct mt76_connac2_fw_trailer *hdr;
597 	struct mt792x_realease_info *rel_info;
598 	const struct firmware *fw;
599 	int ret, i, offset = 0;
600 	const u8 *data, *end;
601 	u8 offload_caps = 0;
602 
603 	ret = request_firmware(&fw, fw_wm, dev);
604 	if (ret)
605 		return ret;
606 
607 	if (!fw || !fw->data || fw->size < sizeof(*hdr)) {
608 		dev_err(dev, "Invalid firmware\n");
609 		goto out;
610 	}
611 
612 	data = fw->data;
613 	hdr = (const void *)(fw->data + fw->size - sizeof(*hdr));
614 
615 	for (i = 0; i < hdr->n_region; i++) {
616 		const struct mt76_connac2_fw_region *region;
617 
618 		region = (const void *)((const u8 *)hdr -
619 					(hdr->n_region - i) * sizeof(*region));
620 		offset += le32_to_cpu(region->len);
621 	}
622 
623 	data += offset + 16;
624 	rel_info = (struct mt792x_realease_info *)data;
625 	data += sizeof(*rel_info);
626 	end = data + le16_to_cpu(rel_info->len);
627 
628 	while (data < end) {
629 		rel_info = (struct mt792x_realease_info *)data;
630 		data += sizeof(*rel_info);
631 
632 		if (rel_info->tag == MT792x_FW_TAG_FEATURE) {
633 			struct mt792x_fw_features *features;
634 
635 			features = (struct mt792x_fw_features *)data;
636 			offload_caps = features->data;
637 			break;
638 		}
639 
640 		data += le16_to_cpu(rel_info->len) + rel_info->pad_len;
641 	}
642 
643 out:
644 	release_firmware(fw);
645 
646 	return offload_caps;
647 }
648 
649 struct ieee80211_ops *
650 mt792x_get_mac80211_ops(struct device *dev,
651 			const struct ieee80211_ops *mac80211_ops,
652 			void *drv_data, u8 *fw_features)
653 {
654 	struct ieee80211_ops *ops;
655 
656 	ops = devm_kmemdup(dev, mac80211_ops, sizeof(struct ieee80211_ops),
657 			   GFP_KERNEL);
658 	if (!ops)
659 		return NULL;
660 
661 	*fw_features = mt792x_get_offload_capability(dev, drv_data);
662 	if (!(*fw_features & MT792x_FW_CAP_CNM)) {
663 		ops->remain_on_channel = NULL;
664 		ops->cancel_remain_on_channel = NULL;
665 		ops->add_chanctx = NULL;
666 		ops->remove_chanctx = NULL;
667 		ops->change_chanctx = NULL;
668 		ops->assign_vif_chanctx = NULL;
669 		ops->unassign_vif_chanctx = NULL;
670 		ops->mgd_prepare_tx = NULL;
671 		ops->mgd_complete_tx = NULL;
672 	}
673 	return ops;
674 }
675 EXPORT_SYMBOL_GPL(mt792x_get_mac80211_ops);
676 
677 int mt792x_init_wcid(struct mt792x_dev *dev)
678 {
679 	int idx;
680 
681 	/* Beacon and mgmt frames should occupy wcid 0 */
682 	idx = mt76_wcid_alloc(dev->mt76.wcid_mask, MT792x_WTBL_STA - 1);
683 	if (idx)
684 		return -ENOSPC;
685 
686 	dev->mt76.global_wcid.idx = idx;
687 	dev->mt76.global_wcid.hw_key_idx = -1;
688 	dev->mt76.global_wcid.tx_info |= MT_WCID_TX_INFO_SET;
689 	rcu_assign_pointer(dev->mt76.wcid[idx], &dev->mt76.global_wcid);
690 
691 	return 0;
692 }
693 EXPORT_SYMBOL_GPL(mt792x_init_wcid);
694 
695 MODULE_LICENSE("Dual BSD/GPL");
696 MODULE_AUTHOR("Lorenzo Bianconi <lorenzo@kernel.org>");
697