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

mt76x02_util.c (19431B)


      1// SPDX-License-Identifier: ISC
      2/*
      3 * Copyright (C) 2018 Stanislaw Gruszka <stf_xl@wp.pl>
      4 * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
      5 */
      6
      7#include <linux/module.h>
      8#include "mt76x02.h"
      9
     10#define MT76x02_CCK_RATE(_idx, _rate) {					\
     11	.bitrate = _rate,					\
     12	.flags = IEEE80211_RATE_SHORT_PREAMBLE,			\
     13	.hw_value = (MT_PHY_TYPE_CCK << 8) | (_idx),		\
     14	.hw_value_short = (MT_PHY_TYPE_CCK << 8) | (8 + (_idx)),	\
     15}
     16
     17struct ieee80211_rate mt76x02_rates[] = {
     18	MT76x02_CCK_RATE(0, 10),
     19	MT76x02_CCK_RATE(1, 20),
     20	MT76x02_CCK_RATE(2, 55),
     21	MT76x02_CCK_RATE(3, 110),
     22	OFDM_RATE(0, 60),
     23	OFDM_RATE(1, 90),
     24	OFDM_RATE(2, 120),
     25	OFDM_RATE(3, 180),
     26	OFDM_RATE(4, 240),
     27	OFDM_RATE(5, 360),
     28	OFDM_RATE(6, 480),
     29	OFDM_RATE(7, 540),
     30};
     31EXPORT_SYMBOL_GPL(mt76x02_rates);
     32
     33static const struct ieee80211_iface_limit mt76x02_if_limits[] = {
     34	{
     35		.max = 1,
     36		.types = BIT(NL80211_IFTYPE_ADHOC)
     37	}, {
     38		.max = 8,
     39		.types = BIT(NL80211_IFTYPE_STATION) |
     40#ifdef CONFIG_MAC80211_MESH
     41			 BIT(NL80211_IFTYPE_MESH_POINT) |
     42#endif
     43			 BIT(NL80211_IFTYPE_P2P_CLIENT) |
     44			 BIT(NL80211_IFTYPE_P2P_GO) |
     45			 BIT(NL80211_IFTYPE_AP)
     46	 },
     47};
     48
     49static const struct ieee80211_iface_limit mt76x02u_if_limits[] = {
     50	{
     51		.max = 1,
     52		.types = BIT(NL80211_IFTYPE_ADHOC)
     53	}, {
     54		.max = 2,
     55		.types = BIT(NL80211_IFTYPE_STATION) |
     56#ifdef CONFIG_MAC80211_MESH
     57			 BIT(NL80211_IFTYPE_MESH_POINT) |
     58#endif
     59			 BIT(NL80211_IFTYPE_P2P_CLIENT) |
     60			 BIT(NL80211_IFTYPE_P2P_GO) |
     61			 BIT(NL80211_IFTYPE_AP)
     62	},
     63};
     64
     65static const struct ieee80211_iface_combination mt76x02_if_comb[] = {
     66	{
     67		.limits = mt76x02_if_limits,
     68		.n_limits = ARRAY_SIZE(mt76x02_if_limits),
     69		.max_interfaces = 8,
     70		.num_different_channels = 1,
     71		.beacon_int_infra_match = true,
     72		.radar_detect_widths = BIT(NL80211_CHAN_WIDTH_20_NOHT) |
     73				       BIT(NL80211_CHAN_WIDTH_20) |
     74				       BIT(NL80211_CHAN_WIDTH_40) |
     75				       BIT(NL80211_CHAN_WIDTH_80),
     76	}
     77};
     78
     79static const struct ieee80211_iface_combination mt76x02u_if_comb[] = {
     80	{
     81		.limits = mt76x02u_if_limits,
     82		.n_limits = ARRAY_SIZE(mt76x02u_if_limits),
     83		.max_interfaces = 2,
     84		.num_different_channels = 1,
     85		.beacon_int_infra_match = true,
     86	}
     87};
     88
     89static void
     90mt76x02_led_set_config(struct mt76_dev *mdev, u8 delay_on,
     91		       u8 delay_off)
     92{
     93	struct mt76x02_dev *dev = container_of(mdev, struct mt76x02_dev,
     94					       mt76);
     95	u32 val;
     96
     97	val = FIELD_PREP(MT_LED_STATUS_DURATION, 0xff) |
     98	      FIELD_PREP(MT_LED_STATUS_OFF, delay_off) |
     99	      FIELD_PREP(MT_LED_STATUS_ON, delay_on);
    100
    101	mt76_wr(dev, MT_LED_S0(mdev->led_pin), val);
    102	mt76_wr(dev, MT_LED_S1(mdev->led_pin), val);
    103
    104	val = MT_LED_CTRL_REPLAY(mdev->led_pin) |
    105	      MT_LED_CTRL_KICK(mdev->led_pin);
    106	if (mdev->led_al)
    107		val |= MT_LED_CTRL_POLARITY(mdev->led_pin);
    108	mt76_wr(dev, MT_LED_CTRL, val);
    109}
    110
    111static int
    112mt76x02_led_set_blink(struct led_classdev *led_cdev,
    113		      unsigned long *delay_on,
    114		      unsigned long *delay_off)
    115{
    116	struct mt76_dev *mdev = container_of(led_cdev, struct mt76_dev,
    117					     led_cdev);
    118	u8 delta_on, delta_off;
    119
    120	delta_off = max_t(u8, *delay_off / 10, 1);
    121	delta_on = max_t(u8, *delay_on / 10, 1);
    122
    123	mt76x02_led_set_config(mdev, delta_on, delta_off);
    124
    125	return 0;
    126}
    127
    128static void
    129mt76x02_led_set_brightness(struct led_classdev *led_cdev,
    130			   enum led_brightness brightness)
    131{
    132	struct mt76_dev *mdev = container_of(led_cdev, struct mt76_dev,
    133					     led_cdev);
    134
    135	if (!brightness)
    136		mt76x02_led_set_config(mdev, 0, 0xff);
    137	else
    138		mt76x02_led_set_config(mdev, 0xff, 0);
    139}
    140
    141int mt76x02_init_device(struct mt76x02_dev *dev)
    142{
    143	struct ieee80211_hw *hw = mt76_hw(dev);
    144	struct wiphy *wiphy = hw->wiphy;
    145
    146	INIT_DELAYED_WORK(&dev->mphy.mac_work, mt76x02_mac_work);
    147
    148	hw->queues = 4;
    149	hw->max_rates = 1;
    150	hw->max_report_rates = 7;
    151	hw->max_rate_tries = 1;
    152	hw->extra_tx_headroom = 2;
    153
    154	if (mt76_is_usb(&dev->mt76)) {
    155		hw->extra_tx_headroom += sizeof(struct mt76x02_txwi) +
    156					 MT_DMA_HDR_LEN;
    157		wiphy->iface_combinations = mt76x02u_if_comb;
    158		wiphy->n_iface_combinations = ARRAY_SIZE(mt76x02u_if_comb);
    159	} else {
    160		INIT_DELAYED_WORK(&dev->wdt_work, mt76x02_wdt_work);
    161
    162		mt76x02_dfs_init_detector(dev);
    163
    164		wiphy->reg_notifier = mt76x02_regd_notifier;
    165		wiphy->iface_combinations = mt76x02_if_comb;
    166		wiphy->n_iface_combinations = ARRAY_SIZE(mt76x02_if_comb);
    167
    168		/* init led callbacks */
    169		if (IS_ENABLED(CONFIG_MT76_LEDS)) {
    170			dev->mt76.led_cdev.brightness_set =
    171					mt76x02_led_set_brightness;
    172			dev->mt76.led_cdev.blink_set = mt76x02_led_set_blink;
    173		}
    174	}
    175
    176	wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_VHT_IBSS);
    177
    178	hw->sta_data_size = sizeof(struct mt76x02_sta);
    179	hw->vif_data_size = sizeof(struct mt76x02_vif);
    180
    181	ieee80211_hw_set(hw, SUPPORTS_HT_CCK_RATES);
    182	ieee80211_hw_set(hw, HOST_BROADCAST_PS_BUFFERING);
    183	ieee80211_hw_set(hw, NEEDS_UNIQUE_STA_ADDR);
    184
    185	dev->mt76.global_wcid.idx = 255;
    186	dev->mt76.global_wcid.hw_key_idx = -1;
    187	dev->slottime = 9;
    188
    189	if (is_mt76x2(dev)) {
    190		dev->mphy.sband_2g.sband.ht_cap.cap |=
    191				IEEE80211_HT_CAP_LDPC_CODING;
    192		dev->mphy.sband_5g.sband.ht_cap.cap |=
    193				IEEE80211_HT_CAP_LDPC_CODING;
    194		dev->mphy.chainmask = 0x202;
    195		dev->mphy.antenna_mask = 3;
    196	} else {
    197		dev->mphy.chainmask = 0x101;
    198		dev->mphy.antenna_mask = 1;
    199	}
    200
    201	return 0;
    202}
    203EXPORT_SYMBOL_GPL(mt76x02_init_device);
    204
    205void mt76x02_configure_filter(struct ieee80211_hw *hw,
    206			      unsigned int changed_flags,
    207			      unsigned int *total_flags, u64 multicast)
    208{
    209	struct mt76x02_dev *dev = hw->priv;
    210	u32 flags = 0;
    211
    212#define MT76_FILTER(_flag, _hw) do { \
    213		flags |= *total_flags & FIF_##_flag;			\
    214		dev->mt76.rxfilter &= ~(_hw);				\
    215		dev->mt76.rxfilter |= !(flags & FIF_##_flag) * (_hw);	\
    216	} while (0)
    217
    218	mutex_lock(&dev->mt76.mutex);
    219
    220	dev->mt76.rxfilter &= ~MT_RX_FILTR_CFG_OTHER_BSS;
    221
    222	MT76_FILTER(FCSFAIL, MT_RX_FILTR_CFG_CRC_ERR);
    223	MT76_FILTER(PLCPFAIL, MT_RX_FILTR_CFG_PHY_ERR);
    224	MT76_FILTER(CONTROL, MT_RX_FILTR_CFG_ACK |
    225			     MT_RX_FILTR_CFG_CTS |
    226			     MT_RX_FILTR_CFG_CFEND |
    227			     MT_RX_FILTR_CFG_CFACK |
    228			     MT_RX_FILTR_CFG_BA |
    229			     MT_RX_FILTR_CFG_CTRL_RSV);
    230	MT76_FILTER(PSPOLL, MT_RX_FILTR_CFG_PSPOLL);
    231
    232	*total_flags = flags;
    233	mt76_wr(dev, MT_RX_FILTR_CFG, dev->mt76.rxfilter);
    234
    235	mutex_unlock(&dev->mt76.mutex);
    236}
    237EXPORT_SYMBOL_GPL(mt76x02_configure_filter);
    238
    239int mt76x02_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,
    240		    struct ieee80211_sta *sta)
    241{
    242	struct mt76x02_dev *dev = container_of(mdev, struct mt76x02_dev, mt76);
    243	struct mt76x02_sta *msta = (struct mt76x02_sta *)sta->drv_priv;
    244	struct mt76x02_vif *mvif = (struct mt76x02_vif *)vif->drv_priv;
    245	int idx = 0;
    246
    247	memset(msta, 0, sizeof(*msta));
    248
    249	idx = mt76_wcid_alloc(dev->mt76.wcid_mask, MT76x02_N_WCIDS);
    250	if (idx < 0)
    251		return -ENOSPC;
    252
    253	msta->vif = mvif;
    254	msta->wcid.sta = 1;
    255	msta->wcid.idx = idx;
    256	msta->wcid.hw_key_idx = -1;
    257	mt76x02_mac_wcid_setup(dev, idx, mvif->idx, sta->addr);
    258	mt76x02_mac_wcid_set_drop(dev, idx, false);
    259	ewma_pktlen_init(&msta->pktlen);
    260
    261	if (vif->type == NL80211_IFTYPE_AP)
    262		set_bit(MT_WCID_FLAG_CHECK_PS, &msta->wcid.flags);
    263
    264	return 0;
    265}
    266EXPORT_SYMBOL_GPL(mt76x02_sta_add);
    267
    268void mt76x02_sta_remove(struct mt76_dev *mdev, struct ieee80211_vif *vif,
    269			struct ieee80211_sta *sta)
    270{
    271	struct mt76x02_dev *dev = container_of(mdev, struct mt76x02_dev, mt76);
    272	struct mt76_wcid *wcid = (struct mt76_wcid *)sta->drv_priv;
    273	int idx = wcid->idx;
    274
    275	mt76x02_mac_wcid_set_drop(dev, idx, true);
    276	mt76x02_mac_wcid_setup(dev, idx, 0, NULL);
    277}
    278EXPORT_SYMBOL_GPL(mt76x02_sta_remove);
    279
    280static void
    281mt76x02_vif_init(struct mt76x02_dev *dev, struct ieee80211_vif *vif,
    282		 unsigned int idx)
    283{
    284	struct mt76x02_vif *mvif = (struct mt76x02_vif *)vif->drv_priv;
    285	struct mt76_txq *mtxq;
    286
    287	memset(mvif, 0, sizeof(*mvif));
    288
    289	mvif->idx = idx;
    290	mvif->group_wcid.idx = MT_VIF_WCID(idx);
    291	mvif->group_wcid.hw_key_idx = -1;
    292	mt76_packet_id_init(&mvif->group_wcid);
    293
    294	mtxq = (struct mt76_txq *)vif->txq->drv_priv;
    295	rcu_assign_pointer(dev->mt76.wcid[MT_VIF_WCID(idx)], &mvif->group_wcid);
    296	mtxq->wcid = MT_VIF_WCID(idx);
    297}
    298
    299int
    300mt76x02_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
    301{
    302	struct mt76x02_dev *dev = hw->priv;
    303	unsigned int idx = 0;
    304
    305	/* Allow to change address in HW if we create first interface. */
    306	if (!dev->mt76.vif_mask &&
    307	    (((vif->addr[0] ^ dev->mphy.macaddr[0]) & ~GENMASK(4, 1)) ||
    308	     memcmp(vif->addr + 1, dev->mphy.macaddr + 1, ETH_ALEN - 1)))
    309		mt76x02_mac_setaddr(dev, vif->addr);
    310
    311	if (vif->addr[0] & BIT(1))
    312		idx = 1 + (((dev->mphy.macaddr[0] ^ vif->addr[0]) >> 2) & 7);
    313
    314	/*
    315	 * Client mode typically only has one configurable BSSID register,
    316	 * which is used for bssidx=0. This is linked to the MAC address.
    317	 * Since mac80211 allows changing interface types, and we cannot
    318	 * force the use of the primary MAC address for a station mode
    319	 * interface, we need some other way of configuring a per-interface
    320	 * remote BSSID.
    321	 * The hardware provides an AP-Client feature, where bssidx 0-7 are
    322	 * used for AP mode and bssidx 8-15 for client mode.
    323	 * We shift the station interface bss index by 8 to force the
    324	 * hardware to recognize the BSSID.
    325	 * The resulting bssidx mismatch for unicast frames is ignored by hw.
    326	 */
    327	if (vif->type == NL80211_IFTYPE_STATION)
    328		idx += 8;
    329
    330	/* vif is already set or idx is 8 for AP/Mesh/... */
    331	if (dev->mt76.vif_mask & BIT_ULL(idx) ||
    332	    (vif->type != NL80211_IFTYPE_STATION && idx > 7))
    333		return -EBUSY;
    334
    335	dev->mt76.vif_mask |= BIT_ULL(idx);
    336
    337	mt76x02_vif_init(dev, vif, idx);
    338	return 0;
    339}
    340EXPORT_SYMBOL_GPL(mt76x02_add_interface);
    341
    342void mt76x02_remove_interface(struct ieee80211_hw *hw,
    343			      struct ieee80211_vif *vif)
    344{
    345	struct mt76x02_dev *dev = hw->priv;
    346	struct mt76x02_vif *mvif = (struct mt76x02_vif *)vif->drv_priv;
    347
    348	dev->mt76.vif_mask &= ~BIT_ULL(mvif->idx);
    349	rcu_assign_pointer(dev->mt76.wcid[mvif->group_wcid.idx], NULL);
    350	mt76_packet_id_flush(&dev->mt76, &mvif->group_wcid);
    351}
    352EXPORT_SYMBOL_GPL(mt76x02_remove_interface);
    353
    354int mt76x02_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
    355			 struct ieee80211_ampdu_params *params)
    356{
    357	enum ieee80211_ampdu_mlme_action action = params->action;
    358	struct ieee80211_sta *sta = params->sta;
    359	struct mt76x02_dev *dev = hw->priv;
    360	struct mt76x02_sta *msta = (struct mt76x02_sta *)sta->drv_priv;
    361	struct ieee80211_txq *txq = sta->txq[params->tid];
    362	u16 tid = params->tid;
    363	u16 ssn = params->ssn;
    364	struct mt76_txq *mtxq;
    365	int ret = 0;
    366
    367	if (!txq)
    368		return -EINVAL;
    369
    370	mtxq = (struct mt76_txq *)txq->drv_priv;
    371
    372	mutex_lock(&dev->mt76.mutex);
    373	switch (action) {
    374	case IEEE80211_AMPDU_RX_START:
    375		mt76_rx_aggr_start(&dev->mt76, &msta->wcid, tid,
    376				   ssn, params->buf_size);
    377		mt76_set(dev, MT_WCID_ADDR(msta->wcid.idx) + 4, BIT(16 + tid));
    378		break;
    379	case IEEE80211_AMPDU_RX_STOP:
    380		mt76_rx_aggr_stop(&dev->mt76, &msta->wcid, tid);
    381		mt76_clear(dev, MT_WCID_ADDR(msta->wcid.idx) + 4,
    382			   BIT(16 + tid));
    383		break;
    384	case IEEE80211_AMPDU_TX_OPERATIONAL:
    385		mtxq->aggr = true;
    386		mtxq->send_bar = false;
    387		ieee80211_send_bar(vif, sta->addr, tid, mtxq->agg_ssn);
    388		break;
    389	case IEEE80211_AMPDU_TX_STOP_FLUSH:
    390	case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT:
    391		mtxq->aggr = false;
    392		break;
    393	case IEEE80211_AMPDU_TX_START:
    394		mtxq->agg_ssn = IEEE80211_SN_TO_SEQ(ssn);
    395		ret = IEEE80211_AMPDU_TX_START_IMMEDIATE;
    396		break;
    397	case IEEE80211_AMPDU_TX_STOP_CONT:
    398		mtxq->aggr = false;
    399		ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid);
    400		break;
    401	}
    402	mutex_unlock(&dev->mt76.mutex);
    403
    404	return ret;
    405}
    406EXPORT_SYMBOL_GPL(mt76x02_ampdu_action);
    407
    408int mt76x02_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
    409		    struct ieee80211_vif *vif, struct ieee80211_sta *sta,
    410		    struct ieee80211_key_conf *key)
    411{
    412	struct mt76x02_dev *dev = hw->priv;
    413	struct mt76x02_vif *mvif = (struct mt76x02_vif *)vif->drv_priv;
    414	struct mt76x02_sta *msta;
    415	struct mt76_wcid *wcid;
    416	int idx = key->keyidx;
    417	int ret;
    418
    419	/* fall back to sw encryption for unsupported ciphers */
    420	switch (key->cipher) {
    421	case WLAN_CIPHER_SUITE_WEP40:
    422	case WLAN_CIPHER_SUITE_WEP104:
    423	case WLAN_CIPHER_SUITE_TKIP:
    424	case WLAN_CIPHER_SUITE_CCMP:
    425		break;
    426	default:
    427		return -EOPNOTSUPP;
    428	}
    429
    430	/*
    431	 * The hardware does not support per-STA RX GTK, fall back
    432	 * to software mode for these.
    433	 */
    434	if ((vif->type == NL80211_IFTYPE_ADHOC ||
    435	     vif->type == NL80211_IFTYPE_MESH_POINT) &&
    436	    (key->cipher == WLAN_CIPHER_SUITE_TKIP ||
    437	     key->cipher == WLAN_CIPHER_SUITE_CCMP) &&
    438	    !(key->flags & IEEE80211_KEY_FLAG_PAIRWISE))
    439		return -EOPNOTSUPP;
    440
    441	/*
    442	 * In USB AP mode, broadcast/multicast frames are setup in beacon
    443	 * data registers and sent via HW beacons engine, they require to
    444	 * be already encrypted.
    445	 */
    446	if (mt76_is_usb(&dev->mt76) &&
    447	    vif->type == NL80211_IFTYPE_AP &&
    448	    !(key->flags & IEEE80211_KEY_FLAG_PAIRWISE))
    449		return -EOPNOTSUPP;
    450
    451	/* MT76x0 GTK offloading does not work with more than one VIF */
    452	if (is_mt76x0(dev) && !(key->flags & IEEE80211_KEY_FLAG_PAIRWISE))
    453		return -EOPNOTSUPP;
    454
    455	msta = sta ? (struct mt76x02_sta *)sta->drv_priv : NULL;
    456	wcid = msta ? &msta->wcid : &mvif->group_wcid;
    457
    458	if (cmd == SET_KEY) {
    459		key->hw_key_idx = wcid->idx;
    460		wcid->hw_key_idx = idx;
    461		if (key->flags & IEEE80211_KEY_FLAG_RX_MGMT) {
    462			key->flags |= IEEE80211_KEY_FLAG_SW_MGMT_TX;
    463			wcid->sw_iv = true;
    464		}
    465	} else {
    466		if (idx == wcid->hw_key_idx) {
    467			wcid->hw_key_idx = -1;
    468			wcid->sw_iv = false;
    469		}
    470
    471		key = NULL;
    472	}
    473	mt76_wcid_key_setup(&dev->mt76, wcid, key);
    474
    475	if (!msta) {
    476		if (key || wcid->hw_key_idx == idx) {
    477			ret = mt76x02_mac_wcid_set_key(dev, wcid->idx, key);
    478			if (ret)
    479				return ret;
    480		}
    481
    482		return mt76x02_mac_shared_key_setup(dev, mvif->idx, idx, key);
    483	}
    484
    485	return mt76x02_mac_wcid_set_key(dev, msta->wcid.idx, key);
    486}
    487EXPORT_SYMBOL_GPL(mt76x02_set_key);
    488
    489int mt76x02_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
    490		    u16 queue, const struct ieee80211_tx_queue_params *params)
    491{
    492	struct mt76x02_dev *dev = hw->priv;
    493	u8 cw_min = 5, cw_max = 10, qid;
    494	u32 val;
    495
    496	qid = dev->mphy.q_tx[queue]->hw_idx;
    497
    498	if (params->cw_min)
    499		cw_min = fls(params->cw_min);
    500	if (params->cw_max)
    501		cw_max = fls(params->cw_max);
    502
    503	val = FIELD_PREP(MT_EDCA_CFG_TXOP, params->txop) |
    504	      FIELD_PREP(MT_EDCA_CFG_AIFSN, params->aifs) |
    505	      FIELD_PREP(MT_EDCA_CFG_CWMIN, cw_min) |
    506	      FIELD_PREP(MT_EDCA_CFG_CWMAX, cw_max);
    507	mt76_wr(dev, MT_EDCA_CFG_AC(qid), val);
    508
    509	val = mt76_rr(dev, MT_WMM_TXOP(qid));
    510	val &= ~(MT_WMM_TXOP_MASK << MT_WMM_TXOP_SHIFT(qid));
    511	val |= params->txop << MT_WMM_TXOP_SHIFT(qid);
    512	mt76_wr(dev, MT_WMM_TXOP(qid), val);
    513
    514	val = mt76_rr(dev, MT_WMM_AIFSN);
    515	val &= ~(MT_WMM_AIFSN_MASK << MT_WMM_AIFSN_SHIFT(qid));
    516	val |= params->aifs << MT_WMM_AIFSN_SHIFT(qid);
    517	mt76_wr(dev, MT_WMM_AIFSN, val);
    518
    519	val = mt76_rr(dev, MT_WMM_CWMIN);
    520	val &= ~(MT_WMM_CWMIN_MASK << MT_WMM_CWMIN_SHIFT(qid));
    521	val |= cw_min << MT_WMM_CWMIN_SHIFT(qid);
    522	mt76_wr(dev, MT_WMM_CWMIN, val);
    523
    524	val = mt76_rr(dev, MT_WMM_CWMAX);
    525	val &= ~(MT_WMM_CWMAX_MASK << MT_WMM_CWMAX_SHIFT(qid));
    526	val |= cw_max << MT_WMM_CWMAX_SHIFT(qid);
    527	mt76_wr(dev, MT_WMM_CWMAX, val);
    528
    529	return 0;
    530}
    531EXPORT_SYMBOL_GPL(mt76x02_conf_tx);
    532
    533void mt76x02_set_tx_ackto(struct mt76x02_dev *dev)
    534{
    535	u8 ackto, sifs, slottime = dev->slottime;
    536
    537	/* As defined by IEEE 802.11-2007 17.3.8.6 */
    538	slottime += 3 * dev->coverage_class;
    539	mt76_rmw_field(dev, MT_BKOFF_SLOT_CFG,
    540		       MT_BKOFF_SLOT_CFG_SLOTTIME, slottime);
    541
    542	sifs = mt76_get_field(dev, MT_XIFS_TIME_CFG,
    543			      MT_XIFS_TIME_CFG_OFDM_SIFS);
    544
    545	ackto = slottime + sifs;
    546	mt76_rmw_field(dev, MT_TX_TIMEOUT_CFG,
    547		       MT_TX_TIMEOUT_CFG_ACKTO, ackto);
    548}
    549EXPORT_SYMBOL_GPL(mt76x02_set_tx_ackto);
    550
    551void mt76x02_set_coverage_class(struct ieee80211_hw *hw,
    552				s16 coverage_class)
    553{
    554	struct mt76x02_dev *dev = hw->priv;
    555
    556	mutex_lock(&dev->mt76.mutex);
    557	dev->coverage_class = max_t(s16, coverage_class, 0);
    558	mt76x02_set_tx_ackto(dev);
    559	mutex_unlock(&dev->mt76.mutex);
    560}
    561EXPORT_SYMBOL_GPL(mt76x02_set_coverage_class);
    562
    563int mt76x02_set_rts_threshold(struct ieee80211_hw *hw, u32 val)
    564{
    565	struct mt76x02_dev *dev = hw->priv;
    566
    567	if (val != ~0 && val > 0xffff)
    568		return -EINVAL;
    569
    570	mutex_lock(&dev->mt76.mutex);
    571	mt76x02_mac_set_rts_thresh(dev, val);
    572	mutex_unlock(&dev->mt76.mutex);
    573
    574	return 0;
    575}
    576EXPORT_SYMBOL_GPL(mt76x02_set_rts_threshold);
    577
    578void mt76x02_sta_rate_tbl_update(struct ieee80211_hw *hw,
    579				 struct ieee80211_vif *vif,
    580				 struct ieee80211_sta *sta)
    581{
    582	struct mt76x02_dev *dev = hw->priv;
    583	struct mt76x02_sta *msta = (struct mt76x02_sta *)sta->drv_priv;
    584	struct ieee80211_sta_rates *rates = rcu_dereference(sta->rates);
    585	struct ieee80211_tx_rate rate = {};
    586
    587	if (!rates)
    588		return;
    589
    590	rate.idx = rates->rate[0].idx;
    591	rate.flags = rates->rate[0].flags;
    592	mt76x02_mac_wcid_set_rate(dev, &msta->wcid, &rate);
    593}
    594EXPORT_SYMBOL_GPL(mt76x02_sta_rate_tbl_update);
    595
    596void mt76x02_remove_hdr_pad(struct sk_buff *skb, int len)
    597{
    598	int hdrlen;
    599
    600	if (!len)
    601		return;
    602
    603	hdrlen = ieee80211_get_hdrlen_from_skb(skb);
    604	memmove(skb->data + len, skb->data, hdrlen);
    605	skb_pull(skb, len);
    606}
    607EXPORT_SYMBOL_GPL(mt76x02_remove_hdr_pad);
    608
    609void mt76x02_sw_scan_complete(struct ieee80211_hw *hw,
    610			      struct ieee80211_vif *vif)
    611{
    612	struct mt76x02_dev *dev = hw->priv;
    613
    614	clear_bit(MT76_SCANNING, &dev->mphy.state);
    615	if (dev->cal.gain_init_done) {
    616		/* Restore AGC gain and resume calibration after scanning. */
    617		dev->cal.low_gain = -1;
    618		ieee80211_queue_delayed_work(hw, &dev->cal_work, 0);
    619	}
    620}
    621EXPORT_SYMBOL_GPL(mt76x02_sw_scan_complete);
    622
    623void mt76x02_sta_ps(struct mt76_dev *mdev, struct ieee80211_sta *sta,
    624		    bool ps)
    625{
    626	struct mt76x02_dev *dev = container_of(mdev, struct mt76x02_dev, mt76);
    627	struct mt76x02_sta *msta = (struct mt76x02_sta *)sta->drv_priv;
    628	int idx = msta->wcid.idx;
    629
    630	mt76_stop_tx_queues(&dev->mphy, sta, true);
    631	if (mt76_is_mmio(mdev))
    632		mt76x02_mac_wcid_set_drop(dev, idx, ps);
    633}
    634EXPORT_SYMBOL_GPL(mt76x02_sta_ps);
    635
    636void mt76x02_bss_info_changed(struct ieee80211_hw *hw,
    637			      struct ieee80211_vif *vif,
    638			      struct ieee80211_bss_conf *info,
    639			      u32 changed)
    640{
    641	struct mt76x02_vif *mvif = (struct mt76x02_vif *)vif->drv_priv;
    642	struct mt76x02_dev *dev = hw->priv;
    643
    644	mutex_lock(&dev->mt76.mutex);
    645
    646	if (changed & BSS_CHANGED_BSSID)
    647		mt76x02_mac_set_bssid(dev, mvif->idx, info->bssid);
    648
    649	if (changed & BSS_CHANGED_HT || changed & BSS_CHANGED_ERP_CTS_PROT)
    650		mt76x02_mac_set_tx_protection(dev, info->use_cts_prot,
    651					      info->ht_operation_mode);
    652
    653	if (changed & BSS_CHANGED_BEACON_INT) {
    654		mt76_rmw_field(dev, MT_BEACON_TIME_CFG,
    655			       MT_BEACON_TIME_CFG_INTVAL,
    656			       info->beacon_int << 4);
    657		dev->mt76.beacon_int = info->beacon_int;
    658	}
    659
    660	if (changed & BSS_CHANGED_BEACON_ENABLED)
    661		mt76x02_mac_set_beacon_enable(dev, vif, info->enable_beacon);
    662
    663	if (changed & BSS_CHANGED_ERP_PREAMBLE)
    664		mt76x02_mac_set_short_preamble(dev, info->use_short_preamble);
    665
    666	if (changed & BSS_CHANGED_ERP_SLOT) {
    667		int slottime = info->use_short_slot ? 9 : 20;
    668
    669		dev->slottime = slottime;
    670		mt76x02_set_tx_ackto(dev);
    671	}
    672
    673	mutex_unlock(&dev->mt76.mutex);
    674}
    675EXPORT_SYMBOL_GPL(mt76x02_bss_info_changed);
    676
    677void mt76x02_config_mac_addr_list(struct mt76x02_dev *dev)
    678{
    679	struct ieee80211_hw *hw = mt76_hw(dev);
    680	struct wiphy *wiphy = hw->wiphy;
    681	int i;
    682
    683	for (i = 0; i < ARRAY_SIZE(dev->macaddr_list); i++) {
    684		u8 *addr = dev->macaddr_list[i].addr;
    685
    686		memcpy(addr, dev->mphy.macaddr, ETH_ALEN);
    687
    688		if (!i)
    689			continue;
    690
    691		addr[0] |= BIT(1);
    692		addr[0] ^= ((i - 1) << 2);
    693	}
    694	wiphy->addresses = dev->macaddr_list;
    695	wiphy->n_addresses = ARRAY_SIZE(dev->macaddr_list);
    696}
    697EXPORT_SYMBOL_GPL(mt76x02_config_mac_addr_list);
    698
    699MODULE_LICENSE("Dual BSD/GPL");