cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

main.c (19489B)


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