File Index
Files and directories
Sign in
FILE

mt792x_core.c

File preview with syntax highlighting.

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