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