File Index
Files and directories
Sign in
FILE

main.c

File preview with syntax highlighting.

linux-6.19.14/drivers/net/wireless/mediatek/mt76/mt7603/main.c C
  1// SPDX-License-Identifier: BSD-3-Clause-Clear
  2
  3#include <linux/etherdevice.h>
  4#include <linux/platform_device.h>
  5#include <linux/pci.h>
  6#include <linux/module.h>
  7#include "mt7603.h"
  8#include "mac.h"
  9#include "eeprom.h"
 10
 11static int
 12mt7603_start(struct ieee80211_hw *hw)
 13{
 14	struct mt7603_dev *dev = hw->priv;
 15
 16	mt7603_mac_reset_counters(dev);
 17	mt7603_mac_start(dev);
 18	dev->mphy.survey_time = ktime_get_boottime();
 19	set_bit(MT76_STATE_RUNNING, &dev->mphy.state);
 20	mt7603_mac_work(&dev->mphy.mac_work.work);
 21
 22	return 0;
 23}
 24
 25static void
 26mt7603_stop(struct ieee80211_hw *hw, bool suspend)
 27{
 28	struct mt7603_dev *dev = hw->priv;
 29
 30	clear_bit(MT76_STATE_RUNNING, &dev->mphy.state);
 31	cancel_delayed_work_sync(&dev->mphy.mac_work);
 32	mt7603_mac_stop(dev);
 33}
 34
 35static int
 36mt7603_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
 37{
 38	struct mt7603_vif *mvif = (struct mt7603_vif *)vif->drv_priv;
 39	struct mt7603_dev *dev = hw->priv;
 40	struct mt76_txq *mtxq;
 41	u8 bc_addr[ETH_ALEN];
 42	int idx;
 43	int ret = 0;
 44
 45	mutex_lock(&dev->mt76.mutex);
 46
 47	mvif->idx = __ffs64(~dev->mt76.vif_mask);
 48	if (mvif->idx >= MT7603_MAX_INTERFACES) {
 49		ret = -ENOSPC;
 50		goto out;
 51	}
 52
 53	mt76_wr(dev, MT_MAC_ADDR0(mvif->idx),
 54		get_unaligned_le32(vif->addr));
 55	mt76_wr(dev, MT_MAC_ADDR1(mvif->idx),
 56		(get_unaligned_le16(vif->addr + 4) |
 57		 MT_MAC_ADDR1_VALID));
 58
 59	if (vif->type == NL80211_IFTYPE_AP) {
 60		mt76_wr(dev, MT_BSSID0(mvif->idx),
 61			get_unaligned_le32(vif->addr));
 62		mt76_wr(dev, MT_BSSID1(mvif->idx),
 63			(get_unaligned_le16(vif->addr + 4) |
 64			 MT_BSSID1_VALID));
 65	}
 66
 67	idx = MT7603_WTBL_RESERVED - 1 - mvif->idx;
 68	dev->mt76.vif_mask |= BIT_ULL(mvif->idx);
 69	mvif->sta.wcid.idx = idx;
 70	mvif->sta.vif = mvif;
 71	mt76_wcid_init(&mvif->sta.wcid, 0);
 72
 73	eth_broadcast_addr(bc_addr);
 74	mt7603_wtbl_init(dev, idx, mvif->idx, bc_addr);
 75
 76	mtxq = (struct mt76_txq *)vif->txq->drv_priv;
 77	mtxq->wcid = idx;
 78	rcu_assign_pointer(dev->mt76.wcid[idx], &mvif->sta.wcid);
 79
 80out:
 81	mutex_unlock(&dev->mt76.mutex);
 82
 83	return ret;
 84}
 85
 86static void
 87mt7603_remove_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
 88{
 89	struct mt7603_vif *mvif = (struct mt7603_vif *)vif->drv_priv;
 90	struct mt7603_sta *msta = &mvif->sta;
 91	struct mt7603_dev *dev = hw->priv;
 92	int idx = msta->wcid.idx;
 93
 94	mt76_wr(dev, MT_MAC_ADDR0(mvif->idx), 0);
 95	mt76_wr(dev, MT_MAC_ADDR1(mvif->idx), 0);
 96	mt76_wr(dev, MT_BSSID0(mvif->idx), 0);
 97	mt76_wr(dev, MT_BSSID1(mvif->idx), 0);
 98	mt7603_beacon_set_timer(dev, mvif->idx, 0);
 99
100	rcu_assign_pointer(dev->mt76.wcid[idx], NULL);
101
102	spin_lock_bh(&dev->mt76.sta_poll_lock);
103	if (!list_empty(&msta->wcid.poll_list))
104		list_del_init(&msta->wcid.poll_list);
105	spin_unlock_bh(&dev->mt76.sta_poll_lock);
106
107	mutex_lock(&dev->mt76.mutex);
108	dev->mt76.vif_mask &= ~BIT_ULL(mvif->idx);
109	mutex_unlock(&dev->mt76.mutex);
110
111	mt76_wcid_cleanup(&dev->mt76, &mvif->sta.wcid);
112}
113
114void mt7603_init_edcca(struct mt7603_dev *dev)
115{
116	/* Set lower signal level to -65dBm */
117	mt76_rmw_field(dev, MT_RXTD(8), MT_RXTD_8_LOWER_SIGNAL, 0x23);
118
119	/* clear previous energy detect monitor results */
120	mt76_rr(dev, MT_MIB_STAT_ED);
121
122	if (dev->ed_monitor)
123		mt76_set(dev, MT_MIB_CTL, MT_MIB_CTL_ED_TIME);
124	else
125		mt76_clear(dev, MT_MIB_CTL, MT_MIB_CTL_ED_TIME);
126
127	dev->ed_strict_mode = 0xff;
128	dev->ed_strong_signal = 0;
129	dev->ed_time = ktime_get_boottime();
130
131	mt7603_edcca_set_strict(dev, false);
132}
133
134int mt7603_set_channel(struct mt76_phy *mphy)
135{
136	struct mt7603_dev *dev = container_of(mphy->dev, struct mt7603_dev, mt76);
137	struct cfg80211_chan_def *def = &mphy->chandef;
138
139	u8 *rssi_data = (u8 *)dev->mt76.eeprom.data;
140	int idx, ret;
141	u8 bw = MT_BW_20;
142	bool failed = false;
143
144	tasklet_disable(&dev->mt76.pre_tbtt_tasklet);
145
146	mt7603_beacon_set_timer(dev, -1, 0);
147	mt7603_mac_stop(dev);
148
149	if (def->width == NL80211_CHAN_WIDTH_40)
150		bw = MT_BW_40;
151
152	mt76_rmw_field(dev, MT_AGG_BWCR, MT_AGG_BWCR_BW, bw);
153	ret = mt7603_mcu_set_channel(dev);
154	if (ret) {
155		failed = true;
156		goto out;
157	}
158
159	if (def->chan->band == NL80211_BAND_5GHZ) {
160		idx = 1;
161		rssi_data += MT_EE_RSSI_OFFSET_5G;
162	} else {
163		idx = 0;
164		rssi_data += MT_EE_RSSI_OFFSET_2G;
165	}
166
167	memcpy(dev->rssi_offset, rssi_data, sizeof(dev->rssi_offset));
168
169	idx |= (def->chan -
170		mt76_hw(dev)->wiphy->bands[def->chan->band]->channels) << 1;
171	mt76_wr(dev, MT_WF_RMAC_CH_FREQ, idx);
172	mt7603_mac_set_timing(dev);
173	mt7603_mac_start(dev);
174
175	ieee80211_queue_delayed_work(mt76_hw(dev), &dev->mphy.mac_work,
176				     msecs_to_jiffies(MT7603_WATCHDOG_TIME));
177
178	/* reset channel stats */
179	mt76_clear(dev, MT_MIB_CTL, MT_MIB_CTL_READ_CLR_DIS);
180	mt76_set(dev, MT_MIB_CTL,
181		 MT_MIB_CTL_CCA_NAV_TX | MT_MIB_CTL_PSCCA_TIME);
182	mt76_rr(dev, MT_MIB_STAT_CCA);
183	mt7603_cca_stats_reset(dev);
184
185	dev->mphy.survey_time = ktime_get_boottime();
186
187	mt7603_init_edcca(dev);
188
189out:
190	if (!mphy->offchannel)
191		mt7603_beacon_set_timer(dev, -1, dev->mt76.beacon_int);
192
193	tasklet_enable(&dev->mt76.pre_tbtt_tasklet);
194
195	if (failed)
196		mt7603_mac_work(&dev->mphy.mac_work.work);
197
198	return ret;
199}
200
201static int mt7603_set_sar_specs(struct ieee80211_hw *hw,
202				const struct cfg80211_sar_specs *sar)
203{
204	struct mt7603_dev *dev = hw->priv;
205	struct mt76_phy *mphy = &dev->mphy;
206	int err;
207
208	if (!cfg80211_chandef_valid(&mphy->chandef))
209		return -EINVAL;
210
211	err = mt76_init_sar_power(hw, sar);
212	if (err)
213		return err;
214
215	return mt76_update_channel(mphy);
216}
217
218static int
219mt7603_config(struct ieee80211_hw *hw, int radio_idx, u32 changed)
220{
221	struct mt7603_dev *dev = hw->priv;
222	int ret = 0;
223
224	if (changed & (IEEE80211_CONF_CHANGE_CHANNEL |
225		       IEEE80211_CONF_CHANGE_POWER))
226		ret = mt76_update_channel(&dev->mphy);
227
228	if (changed & IEEE80211_CONF_CHANGE_MONITOR) {
229		mutex_lock(&dev->mt76.mutex);
230
231		if (!(hw->conf.flags & IEEE80211_CONF_MONITOR))
232			dev->rxfilter |= MT_WF_RFCR_DROP_OTHER_UC;
233		else
234			dev->rxfilter &= ~MT_WF_RFCR_DROP_OTHER_UC;
235
236		mt76_wr(dev, MT_WF_RFCR, dev->rxfilter);
237
238		mutex_unlock(&dev->mt76.mutex);
239	}
240
241	return ret;
242}
243
244static void
245mt7603_configure_filter(struct ieee80211_hw *hw, unsigned int changed_flags,
246			unsigned int *total_flags, u64 multicast)
247{
248	struct mt7603_dev *dev = hw->priv;
249	u32 flags = 0;
250
251#define MT76_FILTER(_flag, _hw) do { \
252		flags |= *total_flags & FIF_##_flag;			\
253		dev->rxfilter &= ~(_hw);				\
254		dev->rxfilter |= !(flags & FIF_##_flag) * (_hw);	\
255	} while (0)
256
257	dev->rxfilter &= ~(MT_WF_RFCR_DROP_OTHER_BSS |
258			   MT_WF_RFCR_DROP_OTHER_BEACON |
259			   MT_WF_RFCR_DROP_FRAME_REPORT |
260			   MT_WF_RFCR_DROP_PROBEREQ |
261			   MT_WF_RFCR_DROP_MCAST_FILTERED |
262			   MT_WF_RFCR_DROP_MCAST |
263			   MT_WF_RFCR_DROP_BCAST |
264			   MT_WF_RFCR_DROP_DUPLICATE |
265			   MT_WF_RFCR_DROP_A2_BSSID |
266			   MT_WF_RFCR_DROP_UNWANTED_CTL |
267			   MT_WF_RFCR_DROP_STBC_MULTI);
268
269	MT76_FILTER(OTHER_BSS, MT_WF_RFCR_DROP_OTHER_TIM |
270			       MT_WF_RFCR_DROP_A3_MAC |
271			       MT_WF_RFCR_DROP_A3_BSSID);
272
273	MT76_FILTER(FCSFAIL, MT_WF_RFCR_DROP_FCSFAIL);
274
275	MT76_FILTER(CONTROL, MT_WF_RFCR_DROP_CTS |
276			     MT_WF_RFCR_DROP_RTS |
277			     MT_WF_RFCR_DROP_CTL_RSV |
278			     MT_WF_RFCR_DROP_NDPA);
279
280	*total_flags = flags;
281	mt76_wr(dev, MT_WF_RFCR, dev->rxfilter);
282}
283
284static void
285mt7603_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
286			struct ieee80211_bss_conf *info, u64 changed)
287{
288	struct mt7603_dev *dev = hw->priv;
289	struct mt7603_vif *mvif = (struct mt7603_vif *)vif->drv_priv;
290
291	mutex_lock(&dev->mt76.mutex);
292
293	if (changed & (BSS_CHANGED_ASSOC | BSS_CHANGED_BSSID)) {
294		if (vif->cfg.assoc || vif->cfg.ibss_joined) {
295			mt76_wr(dev, MT_BSSID0(mvif->idx),
296				get_unaligned_le32(info->bssid));
297			mt76_wr(dev, MT_BSSID1(mvif->idx),
298				(get_unaligned_le16(info->bssid + 4) |
299				 MT_BSSID1_VALID));
300		} else {
301			mt76_wr(dev, MT_BSSID0(mvif->idx), 0);
302			mt76_wr(dev, MT_BSSID1(mvif->idx), 0);
303		}
304	}
305
306	if (changed & BSS_CHANGED_ERP_SLOT) {
307		int slottime = info->use_short_slot ? 9 : 20;
308
309		if (slottime != dev->slottime) {
310			dev->slottime = slottime;
311			mt7603_mac_set_timing(dev);
312		}
313	}
314
315	if (changed & (BSS_CHANGED_BEACON_ENABLED | BSS_CHANGED_BEACON_INT)) {
316		int beacon_int = !!info->enable_beacon * info->beacon_int;
317
318		tasklet_disable(&dev->mt76.pre_tbtt_tasklet);
319		mt7603_beacon_set_timer(dev, mvif->idx, beacon_int);
320		tasklet_enable(&dev->mt76.pre_tbtt_tasklet);
321	}
322
323	mutex_unlock(&dev->mt76.mutex);
324}
325
326int
327mt7603_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,
328	       struct ieee80211_sta *sta)
329{
330	struct mt7603_dev *dev = container_of(mdev, struct mt7603_dev, mt76);
331	struct mt7603_sta *msta = (struct mt7603_sta *)sta->drv_priv;
332	struct mt7603_vif *mvif = (struct mt7603_vif *)vif->drv_priv;
333	int idx;
334	int ret = 0;
335
336	idx = mt76_wcid_alloc(dev->mt76.wcid_mask, MT7603_WTBL_STA - 1);
337	if (idx < 0)
338		return -ENOSPC;
339
340	INIT_LIST_HEAD(&msta->wcid.poll_list);
341	__skb_queue_head_init(&msta->psq);
342	msta->ps = ~0;
343	msta->smps = ~0;
344	msta->wcid.sta = 1;
345	msta->wcid.idx = idx;
346	msta->vif = mvif;
347	mt7603_wtbl_init(dev, idx, mvif->idx, sta->addr);
348	mt7603_wtbl_set_ps(dev, msta, false);
349
350	if (vif->type == NL80211_IFTYPE_AP)
351		set_bit(MT_WCID_FLAG_CHECK_PS, &msta->wcid.flags);
352
353	return ret;
354}
355
356int
357mt7603_sta_event(struct mt76_dev *mdev, struct ieee80211_vif *vif,
358		 struct ieee80211_sta *sta, enum mt76_sta_event ev)
359{
360	struct mt7603_dev *dev = container_of(mdev, struct mt7603_dev, mt76);
361
362	if (ev == MT76_STA_EVENT_ASSOC) {
363		mutex_lock(&dev->mt76.mutex);
364		mt7603_wtbl_update_cap(dev, sta);
365		mutex_unlock(&dev->mt76.mutex);
366	}
367
368	return 0;
369}
370
371void
372mt7603_sta_remove(struct mt76_dev *mdev, struct ieee80211_vif *vif,
373		  struct ieee80211_sta *sta)
374{
375	struct mt7603_dev *dev = container_of(mdev, struct mt7603_dev, mt76);
376	struct mt7603_vif *mvif = (struct mt7603_vif *)vif->drv_priv;
377	struct mt7603_sta *msta = (struct mt7603_sta *)sta->drv_priv;
378	struct mt76_wcid *wcid = (struct mt76_wcid *)sta->drv_priv;
379
380	spin_lock_bh(&dev->ps_lock);
381	__skb_queue_purge(&msta->psq);
382	mt7603_filter_tx(dev, mvif->idx, wcid->idx, true);
383	spin_unlock_bh(&dev->ps_lock);
384
385	spin_lock_bh(&mdev->sta_poll_lock);
386	if (!list_empty(&msta->wcid.poll_list))
387		list_del_init(&msta->wcid.poll_list);
388	spin_unlock_bh(&mdev->sta_poll_lock);
389
390	mt7603_wtbl_clear(dev, wcid->idx);
391}
392
393static void
394mt7603_ps_tx_list(struct mt7603_dev *dev, struct sk_buff_head *list)
395{
396	struct sk_buff *skb;
397
398	while ((skb = __skb_dequeue(list)) != NULL) {
399		int qid = skb_get_queue_mapping(skb);
400
401		mt76_tx_queue_skb_raw(dev, dev->mphy.q_tx[qid], skb, 0);
402	}
403}
404
405void
406mt7603_sta_ps(struct mt76_dev *mdev, struct ieee80211_sta *sta, bool ps)
407{
408	struct mt7603_dev *dev = container_of(mdev, struct mt7603_dev, mt76);
409	struct mt7603_sta *msta = (struct mt7603_sta *)sta->drv_priv;
410	struct sk_buff_head list;
411
412	mt76_stop_tx_queues(&dev->mphy, sta, true);
413	mt7603_wtbl_set_ps(dev, msta, ps);
414	if (ps)
415		return;
416
417	__skb_queue_head_init(&list);
418
419	spin_lock_bh(&dev->ps_lock);
420	skb_queue_splice_tail_init(&msta->psq, &list);
421	spin_unlock_bh(&dev->ps_lock);
422
423	mt7603_ps_tx_list(dev, &list);
424}
425
426static void
427mt7603_ps_set_more_data(struct sk_buff *skb)
428{
429	struct ieee80211_hdr *hdr;
430
431	hdr = (struct ieee80211_hdr *)&skb->data[MT_TXD_SIZE];
432	hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_MOREDATA);
433}
434
435static void
436mt7603_release_buffered_frames(struct ieee80211_hw *hw,
437			       struct ieee80211_sta *sta,
438			       u16 tids, int nframes,
439			       enum ieee80211_frame_release_type reason,
440			       bool more_data)
441{
442	struct mt7603_dev *dev = hw->priv;
443	struct mt7603_sta *msta = (struct mt7603_sta *)sta->drv_priv;
444	struct sk_buff_head list;
445	struct sk_buff *skb, *tmp;
446
447	__skb_queue_head_init(&list);
448
449	mt7603_wtbl_set_ps(dev, msta, false);
450
451	spin_lock_bh(&dev->ps_lock);
452	skb_queue_walk_safe(&msta->psq, skb, tmp) {
453		if (!nframes)
454			break;
455
456		if (!(tids & BIT(skb->priority)))
457			continue;
458
459		skb_set_queue_mapping(skb, MT_TXQ_PSD);
460		__skb_unlink(skb, &msta->psq);
461		mt7603_ps_set_more_data(skb);
462		__skb_queue_tail(&list, skb);
463		nframes--;
464	}
465	spin_unlock_bh(&dev->ps_lock);
466
467	if (!skb_queue_empty(&list))
468		ieee80211_sta_eosp(sta);
469
470	mt7603_ps_tx_list(dev, &list);
471
472	if (nframes)
473		mt76_release_buffered_frames(hw, sta, tids, nframes, reason,
474					     more_data);
475}
476
477static int
478mt7603_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
479	       struct ieee80211_vif *vif, struct ieee80211_sta *sta,
480	       struct ieee80211_key_conf *key)
481{
482	struct mt7603_dev *dev = hw->priv;
483	struct mt7603_vif *mvif = (struct mt7603_vif *)vif->drv_priv;
484	struct mt7603_sta *msta = sta ? (struct mt7603_sta *)sta->drv_priv :
485				  &mvif->sta;
486	struct mt76_wcid *wcid = &msta->wcid;
487	int idx = key->keyidx;
488
489	/* fall back to sw encryption for unsupported ciphers */
490	switch (key->cipher) {
491	case WLAN_CIPHER_SUITE_TKIP:
492	case WLAN_CIPHER_SUITE_CCMP:
493		break;
494	default:
495		return -EOPNOTSUPP;
496	}
497
498	/*
499	 * The hardware does not support per-STA RX GTK, fall back
500	 * to software mode for these.
501	 */
502	if ((vif->type == NL80211_IFTYPE_ADHOC ||
503	     vif->type == NL80211_IFTYPE_MESH_POINT) &&
504	    (key->cipher == WLAN_CIPHER_SUITE_TKIP ||
505	     key->cipher == WLAN_CIPHER_SUITE_CCMP) &&
506	    !(key->flags & IEEE80211_KEY_FLAG_PAIRWISE))
507		return -EOPNOTSUPP;
508
509	if (cmd != SET_KEY) {
510		if (idx == wcid->hw_key_idx)
511			wcid->hw_key_idx = -1;
512
513		return 0;
514	}
515
516	key->hw_key_idx = wcid->idx;
517	wcid->hw_key_idx = idx;
518	mt76_wcid_key_setup(&dev->mt76, wcid, key);
519
520	return mt7603_wtbl_set_key(dev, wcid->idx, key);
521}
522
523static int
524mt7603_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
525	       unsigned int link_id, u16 queue,
526	       const struct ieee80211_tx_queue_params *params)
527{
528	struct mt7603_dev *dev = hw->priv;
529	u16 cw_min = (1 << 5) - 1;
530	u16 cw_max = (1 << 10) - 1;
531	u32 val;
532
533	queue = dev->mphy.q_tx[queue]->hw_idx;
534
535	if (params->cw_min)
536		cw_min = params->cw_min;
537	if (params->cw_max)
538		cw_max = params->cw_max;
539
540	mutex_lock(&dev->mt76.mutex);
541	mt7603_mac_stop(dev);
542
543	val = mt76_rr(dev, MT_WMM_TXOP(queue));
544	val &= ~(MT_WMM_TXOP_MASK << MT_WMM_TXOP_SHIFT(queue));
545	val |= params->txop << MT_WMM_TXOP_SHIFT(queue);
546	mt76_wr(dev, MT_WMM_TXOP(queue), val);
547
548	val = mt76_rr(dev, MT_WMM_AIFSN);
549	val &= ~(MT_WMM_AIFSN_MASK << MT_WMM_AIFSN_SHIFT(queue));
550	val |= params->aifs << MT_WMM_AIFSN_SHIFT(queue);
551	mt76_wr(dev, MT_WMM_AIFSN, val);
552
553	val = mt76_rr(dev, MT_WMM_CWMIN);
554	val &= ~(MT_WMM_CWMIN_MASK << MT_WMM_CWMIN_SHIFT(queue));
555	val |= cw_min << MT_WMM_CWMIN_SHIFT(queue);
556	mt76_wr(dev, MT_WMM_CWMIN, val);
557
558	val = mt76_rr(dev, MT_WMM_CWMAX(queue));
559	val &= ~(MT_WMM_CWMAX_MASK << MT_WMM_CWMAX_SHIFT(queue));
560	val |= cw_max << MT_WMM_CWMAX_SHIFT(queue);
561	mt76_wr(dev, MT_WMM_CWMAX(queue), val);
562
563	mt7603_mac_start(dev);
564	mutex_unlock(&dev->mt76.mutex);
565
566	return 0;
567}
568
569static void
570mt7603_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
571	     u32 queues, bool drop)
572{
573}
574
575static int
576mt7603_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
577		    struct ieee80211_ampdu_params *params)
578{
579	enum ieee80211_ampdu_mlme_action action = params->action;
580	struct mt7603_dev *dev = hw->priv;
581	struct ieee80211_sta *sta = params->sta;
582	struct ieee80211_txq *txq = sta->txq[params->tid];
583	struct mt7603_sta *msta = (struct mt7603_sta *)sta->drv_priv;
584	u16 tid = params->tid;
585	u16 ssn = params->ssn;
586	u8 ba_size = params->buf_size;
587	struct mt76_txq *mtxq;
588	int ret = 0;
589
590	if (!txq)
591		return -EINVAL;
592
593	mtxq = (struct mt76_txq *)txq->drv_priv;
594
595	mutex_lock(&dev->mt76.mutex);
596	switch (action) {
597	case IEEE80211_AMPDU_RX_START:
598		mt76_rx_aggr_start(&dev->mt76, &msta->wcid, tid, ssn,
599				   params->buf_size);
600		mt7603_mac_rx_ba_reset(dev, sta->addr, tid);
601		break;
602	case IEEE80211_AMPDU_RX_STOP:
603		mt76_rx_aggr_stop(&dev->mt76, &msta->wcid, tid);
604		break;
605	case IEEE80211_AMPDU_TX_OPERATIONAL:
606		mtxq->aggr = true;
607		mtxq->send_bar = false;
608		mt7603_mac_tx_ba_reset(dev, msta->wcid.idx, tid, ba_size);
609		break;
610	case IEEE80211_AMPDU_TX_STOP_FLUSH:
611	case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT:
612		mtxq->aggr = false;
613		mt7603_mac_tx_ba_reset(dev, msta->wcid.idx, tid, -1);
614		break;
615	case IEEE80211_AMPDU_TX_START:
616		mtxq->agg_ssn = IEEE80211_SN_TO_SEQ(ssn);
617		ret = IEEE80211_AMPDU_TX_START_IMMEDIATE;
618		break;
619	case IEEE80211_AMPDU_TX_STOP_CONT:
620		mtxq->aggr = false;
621		mt7603_mac_tx_ba_reset(dev, msta->wcid.idx, tid, -1);
622		ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid);
623		break;
624	}
625	mutex_unlock(&dev->mt76.mutex);
626
627	return ret;
628}
629
630static void
631mt7603_sta_rate_tbl_update(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
632			   struct ieee80211_sta *sta)
633{
634	struct mt7603_dev *dev = hw->priv;
635	struct mt7603_sta *msta = (struct mt7603_sta *)sta->drv_priv;
636	struct ieee80211_sta_rates *sta_rates = rcu_dereference(sta->rates);
637	int i;
638
639	if (!sta_rates)
640		return;
641
642	spin_lock_bh(&dev->mt76.lock);
643	for (i = 0; i < ARRAY_SIZE(msta->rates); i++) {
644		msta->rates[i].idx = sta_rates->rate[i].idx;
645		msta->rates[i].count = sta_rates->rate[i].count;
646		msta->rates[i].flags = sta_rates->rate[i].flags;
647
648		if (msta->rates[i].idx < 0 || !msta->rates[i].count)
649			break;
650	}
651	msta->n_rates = i;
652	mt7603_wtbl_set_rates(dev, msta, NULL, msta->rates);
653	msta->rate_probe = false;
654	mt7603_wtbl_set_smps(dev, msta,
655			     sta->deflink.smps_mode == IEEE80211_SMPS_DYNAMIC);
656	spin_unlock_bh(&dev->mt76.lock);
657}
658
659static void
660mt7603_set_coverage_class(struct ieee80211_hw *hw, int radio_idx,
661			  s16 coverage_class)
662{
663	struct mt7603_dev *dev = hw->priv;
664
665	mutex_lock(&dev->mt76.mutex);
666	dev->coverage_class = max_t(s16, coverage_class, 0);
667	mt7603_mac_set_timing(dev);
668	mutex_unlock(&dev->mt76.mutex);
669}
670
671static void mt7603_tx(struct ieee80211_hw *hw,
672		      struct ieee80211_tx_control *control,
673		      struct sk_buff *skb)
674{
675	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
676	struct ieee80211_vif *vif = info->control.vif;
677	struct mt7603_dev *dev = hw->priv;
678	struct mt76_wcid *wcid = &dev->global_sta.wcid;
679
680	if (control->sta) {
681		struct mt7603_sta *msta;
682
683		msta = (struct mt7603_sta *)control->sta->drv_priv;
684		wcid = &msta->wcid;
685	} else if (vif) {
686		struct mt7603_vif *mvif;
687
688		mvif = (struct mt7603_vif *)vif->drv_priv;
689		wcid = &mvif->sta.wcid;
690	}
691
692	mt76_tx(&dev->mphy, control->sta, wcid, skb);
693}
694
695const struct ieee80211_ops mt7603_ops = {
696	.add_chanctx = ieee80211_emulate_add_chanctx,
697	.remove_chanctx = ieee80211_emulate_remove_chanctx,
698	.change_chanctx = ieee80211_emulate_change_chanctx,
699	.switch_vif_chanctx = ieee80211_emulate_switch_vif_chanctx,
700	.tx = mt7603_tx,
701	.start = mt7603_start,
702	.stop = mt7603_stop,
703	.add_interface = mt7603_add_interface,
704	.remove_interface = mt7603_remove_interface,
705	.config = mt7603_config,
706	.configure_filter = mt7603_configure_filter,
707	.bss_info_changed = mt7603_bss_info_changed,
708	.sta_state = mt76_sta_state,
709	.sta_pre_rcu_remove = mt76_sta_pre_rcu_remove,
710	.set_key = mt7603_set_key,
711	.conf_tx = mt7603_conf_tx,
712	.sw_scan_start = mt76_sw_scan,
713	.sw_scan_complete = mt76_sw_scan_complete,
714	.flush = mt7603_flush,
715	.ampdu_action = mt7603_ampdu_action,
716	.get_txpower = mt76_get_txpower,
717	.wake_tx_queue = mt76_wake_tx_queue,
718	.sta_rate_tbl_update = mt7603_sta_rate_tbl_update,
719	.release_buffered_frames = mt7603_release_buffered_frames,
720	.set_coverage_class = mt7603_set_coverage_class,
721	.set_tim = mt76_set_tim,
722	.get_survey = mt76_get_survey,
723	.get_antenna = mt76_get_antenna,
724	.set_sar_specs = mt7603_set_sar_specs,
725};
726
727MODULE_DESCRIPTION("MediaTek MT7603E and MT76x8 wireless driver");
728MODULE_LICENSE("Dual BSD/GPL");
729
730static int __init mt7603_init(void)
731{
732	int ret;
733
734	ret = platform_driver_register(&mt76_wmac_driver);
735	if (ret)
736		return ret;
737
738#ifdef CONFIG_PCI
739	ret = pci_register_driver(&mt7603_pci_driver);
740	if (ret)
741		platform_driver_unregister(&mt76_wmac_driver);
742#endif
743	return ret;
744}
745
746static void __exit mt7603_exit(void)
747{
748#ifdef CONFIG_PCI
749	pci_unregister_driver(&mt7603_pci_driver);
750#endif
751	platform_driver_unregister(&mt76_wmac_driver);
752}
753
754module_init(mt7603_init);
755module_exit(mt7603_exit);
~/ Read-only file preview.