1511 lines · c
1// SPDX-License-Identifier: ISC2/*3 * Copyright (C) 2022 MediaTek Inc.4 */5 6#include "mt7996.h"7#include "mcu.h"8#include "mac.h"9 10static bool mt7996_dev_running(struct mt7996_dev *dev)11{12 struct mt7996_phy *phy;13 14 if (test_bit(MT76_STATE_RUNNING, &dev->mphy.state))15 return true;16 17 phy = mt7996_phy2(dev);18 if (phy && test_bit(MT76_STATE_RUNNING, &phy->mt76->state))19 return true;20 21 phy = mt7996_phy3(dev);22 23 return phy && test_bit(MT76_STATE_RUNNING, &phy->mt76->state);24}25 26int mt7996_run(struct ieee80211_hw *hw)27{28 struct mt7996_dev *dev = mt7996_hw_dev(hw);29 struct mt7996_phy *phy = mt7996_hw_phy(hw);30 bool running;31 int ret;32 33 running = mt7996_dev_running(dev);34 if (!running) {35 ret = mt7996_mcu_set_hdr_trans(dev, true);36 if (ret)37 goto out;38 39 if (is_mt7992(&dev->mt76)) {40 u8 queue = mt76_connac_lmac_mapping(IEEE80211_AC_VI);41 42 ret = mt7996_mcu_cp_support(dev, queue);43 if (ret)44 goto out;45 }46 }47 48 mt7996_mac_enable_nf(dev, phy->mt76->band_idx);49 50 ret = mt7996_mcu_set_rts_thresh(phy, 0x92b);51 if (ret)52 goto out;53 54 ret = mt7996_mcu_set_radio_en(phy, true);55 if (ret)56 goto out;57 58 ret = mt7996_mcu_set_chan_info(phy, UNI_CHANNEL_RX_PATH);59 if (ret)60 goto out;61 62 ret = mt7996_mcu_set_thermal_throttling(phy, MT7996_THERMAL_THROTTLE_MAX);63 if (ret)64 goto out;65 66 ret = mt7996_mcu_set_thermal_protect(phy, true);67 if (ret)68 goto out;69 70 set_bit(MT76_STATE_RUNNING, &phy->mt76->state);71 72 ieee80211_queue_delayed_work(hw, &phy->mt76->mac_work,73 MT7996_WATCHDOG_TIME);74 75 if (!running)76 mt7996_mac_reset_counters(phy);77 78out:79 return ret;80}81 82static int mt7996_start(struct ieee80211_hw *hw)83{84 struct mt7996_dev *dev = mt7996_hw_dev(hw);85 int ret;86 87 flush_work(&dev->init_work);88 89 mutex_lock(&dev->mt76.mutex);90 ret = mt7996_run(hw);91 mutex_unlock(&dev->mt76.mutex);92 93 return ret;94}95 96static void mt7996_stop(struct ieee80211_hw *hw, bool suspend)97{98 struct mt7996_dev *dev = mt7996_hw_dev(hw);99 struct mt7996_phy *phy = mt7996_hw_phy(hw);100 101 cancel_delayed_work_sync(&phy->mt76->mac_work);102 103 mutex_lock(&dev->mt76.mutex);104 105 mt7996_mcu_set_radio_en(phy, false);106 107 clear_bit(MT76_STATE_RUNNING, &phy->mt76->state);108 109 mutex_unlock(&dev->mt76.mutex);110}111 112static inline int get_free_idx(u32 mask, u8 start, u8 end)113{114 return ffs(~mask & GENMASK(end, start));115}116 117static int get_omac_idx(enum nl80211_iftype type, u64 mask)118{119 int i;120 121 switch (type) {122 case NL80211_IFTYPE_MESH_POINT:123 case NL80211_IFTYPE_ADHOC:124 case NL80211_IFTYPE_STATION:125 /* prefer hw bssid slot 1-3 */126 i = get_free_idx(mask, HW_BSSID_1, HW_BSSID_3);127 if (i)128 return i - 1;129 130 if (type != NL80211_IFTYPE_STATION)131 break;132 133 i = get_free_idx(mask, EXT_BSSID_1, EXT_BSSID_MAX);134 if (i)135 return i - 1;136 137 if (~mask & BIT(HW_BSSID_0))138 return HW_BSSID_0;139 140 break;141 case NL80211_IFTYPE_MONITOR:142 case NL80211_IFTYPE_AP:143 /* ap uses hw bssid 0 and ext bssid */144 if (~mask & BIT(HW_BSSID_0))145 return HW_BSSID_0;146 147 i = get_free_idx(mask, EXT_BSSID_1, EXT_BSSID_MAX);148 if (i)149 return i - 1;150 151 break;152 default:153 WARN_ON(1);154 break;155 }156 157 return -1;158}159 160static void mt7996_init_bitrate_mask(struct ieee80211_vif *vif)161{162 struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv;163 int i;164 165 for (i = 0; i < ARRAY_SIZE(mvif->bitrate_mask.control); i++) {166 mvif->bitrate_mask.control[i].gi = NL80211_TXRATE_DEFAULT_GI;167 mvif->bitrate_mask.control[i].he_gi = 0xff;168 mvif->bitrate_mask.control[i].he_ltf = 0xff;169 mvif->bitrate_mask.control[i].legacy = GENMASK(31, 0);170 memset(mvif->bitrate_mask.control[i].ht_mcs, 0xff,171 sizeof(mvif->bitrate_mask.control[i].ht_mcs));172 memset(mvif->bitrate_mask.control[i].vht_mcs, 0xff,173 sizeof(mvif->bitrate_mask.control[i].vht_mcs));174 memset(mvif->bitrate_mask.control[i].he_mcs, 0xff,175 sizeof(mvif->bitrate_mask.control[i].he_mcs));176 }177}178 179static int mt7996_add_interface(struct ieee80211_hw *hw,180 struct ieee80211_vif *vif)181{182 struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv;183 struct mt7996_dev *dev = mt7996_hw_dev(hw);184 struct mt7996_phy *phy = mt7996_hw_phy(hw);185 struct mt76_txq *mtxq;186 u8 band_idx = phy->mt76->band_idx;187 int idx, ret = 0;188 189 mutex_lock(&dev->mt76.mutex);190 191 if (vif->type == NL80211_IFTYPE_MONITOR &&192 is_zero_ether_addr(vif->addr))193 phy->monitor_vif = vif;194 195 mvif->mt76.idx = __ffs64(~dev->mt76.vif_mask);196 if (mvif->mt76.idx >= mt7996_max_interface_num(dev)) {197 ret = -ENOSPC;198 goto out;199 }200 201 idx = get_omac_idx(vif->type, phy->omac_mask);202 if (idx < 0) {203 ret = -ENOSPC;204 goto out;205 }206 mvif->mt76.omac_idx = idx;207 mvif->phy = phy;208 mvif->mt76.band_idx = band_idx;209 mvif->mt76.wmm_idx = vif->type == NL80211_IFTYPE_AP ? 0 : 3;210 211 ret = mt7996_mcu_add_dev_info(phy, vif, true);212 if (ret)213 goto out;214 215 dev->mt76.vif_mask |= BIT_ULL(mvif->mt76.idx);216 phy->omac_mask |= BIT_ULL(mvif->mt76.omac_idx);217 218 idx = MT7996_WTBL_RESERVED - mvif->mt76.idx;219 220 INIT_LIST_HEAD(&mvif->sta.rc_list);221 INIT_LIST_HEAD(&mvif->sta.wcid.poll_list);222 mvif->sta.wcid.idx = idx;223 mvif->sta.wcid.phy_idx = band_idx;224 mvif->sta.wcid.hw_key_idx = -1;225 mvif->sta.wcid.tx_info |= MT_WCID_TX_INFO_SET;226 mt76_wcid_init(&mvif->sta.wcid);227 228 mt7996_mac_wtbl_update(dev, idx,229 MT_WTBL_UPDATE_ADM_COUNT_CLEAR);230 231 if (vif->txq) {232 mtxq = (struct mt76_txq *)vif->txq->drv_priv;233 mtxq->wcid = idx;234 }235 236 if (vif->type != NL80211_IFTYPE_AP &&237 (!mvif->mt76.omac_idx || mvif->mt76.omac_idx > 3))238 vif->offload_flags = 0;239 vif->offload_flags |= IEEE80211_OFFLOAD_ENCAP_4ADDR;240 241 if (phy->mt76->chandef.chan->band != NL80211_BAND_2GHZ)242 mvif->mt76.basic_rates_idx = MT7996_BASIC_RATES_TBL + 4;243 else244 mvif->mt76.basic_rates_idx = MT7996_BASIC_RATES_TBL;245 246 mt7996_init_bitrate_mask(vif);247 248 mt7996_mcu_add_bss_info(phy, vif, true);249 /* defer the first STA_REC of BMC entry to BSS_CHANGED_BSSID for STA250 * interface, since firmware only records BSSID when the entry is new251 */252 if (vif->type != NL80211_IFTYPE_STATION)253 mt7996_mcu_add_sta(dev, vif, NULL, true, true);254 rcu_assign_pointer(dev->mt76.wcid[idx], &mvif->sta.wcid);255 256out:257 mutex_unlock(&dev->mt76.mutex);258 259 return ret;260}261 262static void mt7996_remove_interface(struct ieee80211_hw *hw,263 struct ieee80211_vif *vif)264{265 struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv;266 struct mt7996_sta *msta = &mvif->sta;267 struct mt7996_dev *dev = mt7996_hw_dev(hw);268 struct mt7996_phy *phy = mt7996_hw_phy(hw);269 int idx = msta->wcid.idx;270 271 mt7996_mcu_add_sta(dev, vif, NULL, false, false);272 mt7996_mcu_add_bss_info(phy, vif, false);273 274 if (vif == phy->monitor_vif)275 phy->monitor_vif = NULL;276 277 mt7996_mcu_add_dev_info(phy, vif, false);278 279 rcu_assign_pointer(dev->mt76.wcid[idx], NULL);280 281 mutex_lock(&dev->mt76.mutex);282 dev->mt76.vif_mask &= ~BIT_ULL(mvif->mt76.idx);283 phy->omac_mask &= ~BIT_ULL(mvif->mt76.omac_idx);284 mutex_unlock(&dev->mt76.mutex);285 286 spin_lock_bh(&dev->mt76.sta_poll_lock);287 if (!list_empty(&msta->wcid.poll_list))288 list_del_init(&msta->wcid.poll_list);289 spin_unlock_bh(&dev->mt76.sta_poll_lock);290 291 mt76_wcid_cleanup(&dev->mt76, &msta->wcid);292}293 294int mt7996_set_channel(struct mt76_phy *mphy)295{296 struct mt7996_phy *phy = mphy->priv;297 int ret;298 299 ret = mt7996_mcu_set_chan_info(phy, UNI_CHANNEL_SWITCH);300 if (ret)301 goto out;302 303 ret = mt7996_mcu_set_chan_info(phy, UNI_CHANNEL_RX_PATH);304 if (ret)305 goto out;306 307 ret = mt7996_dfs_init_radar_detector(phy);308 mt7996_mac_cca_stats_reset(phy);309 310 mt7996_mac_reset_counters(phy);311 phy->noise = 0;312 313out:314 ieee80211_queue_delayed_work(mphy->hw, &mphy->mac_work,315 MT7996_WATCHDOG_TIME);316 317 return ret;318}319 320static int mt7996_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,321 struct ieee80211_vif *vif, struct ieee80211_sta *sta,322 struct ieee80211_key_conf *key)323{324 struct mt7996_dev *dev = mt7996_hw_dev(hw);325 struct mt7996_phy *phy = mt7996_hw_phy(hw);326 struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv;327 struct mt7996_sta *msta = sta ? (struct mt7996_sta *)sta->drv_priv :328 &mvif->sta;329 struct mt76_wcid *wcid = &msta->wcid;330 u8 *wcid_keyidx = &wcid->hw_key_idx;331 int idx = key->keyidx;332 int err = 0;333 334 /* The hardware does not support per-STA RX GTK, fallback335 * to software mode for these.336 */337 if ((vif->type == NL80211_IFTYPE_ADHOC ||338 vif->type == NL80211_IFTYPE_MESH_POINT) &&339 (key->cipher == WLAN_CIPHER_SUITE_TKIP ||340 key->cipher == WLAN_CIPHER_SUITE_CCMP) &&341 !(key->flags & IEEE80211_KEY_FLAG_PAIRWISE))342 return -EOPNOTSUPP;343 344 /* fall back to sw encryption for unsupported ciphers */345 switch (key->cipher) {346 case WLAN_CIPHER_SUITE_TKIP:347 case WLAN_CIPHER_SUITE_CCMP:348 case WLAN_CIPHER_SUITE_CCMP_256:349 case WLAN_CIPHER_SUITE_GCMP:350 case WLAN_CIPHER_SUITE_GCMP_256:351 case WLAN_CIPHER_SUITE_SMS4:352 break;353 case WLAN_CIPHER_SUITE_AES_CMAC:354 case WLAN_CIPHER_SUITE_BIP_CMAC_256:355 case WLAN_CIPHER_SUITE_BIP_GMAC_128:356 case WLAN_CIPHER_SUITE_BIP_GMAC_256:357 if (key->keyidx == 6 || key->keyidx == 7) {358 wcid_keyidx = &wcid->hw_key_idx2;359 key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIE;360 break;361 }362 fallthrough;363 case WLAN_CIPHER_SUITE_WEP40:364 case WLAN_CIPHER_SUITE_WEP104:365 default:366 return -EOPNOTSUPP;367 }368 369 mutex_lock(&dev->mt76.mutex);370 371 if (cmd == SET_KEY && !sta && !mvif->mt76.cipher) {372 mvif->mt76.cipher = mt76_connac_mcu_get_cipher(key->cipher);373 mt7996_mcu_add_bss_info(phy, vif, true);374 }375 376 if (cmd == SET_KEY) {377 *wcid_keyidx = idx;378 } else {379 if (idx == *wcid_keyidx)380 *wcid_keyidx = -1;381 goto out;382 }383 384 mt76_wcid_key_setup(&dev->mt76, wcid, key);385 386 if (key->keyidx == 6 || key->keyidx == 7)387 err = mt7996_mcu_bcn_prot_enable(dev, vif, key);388 else389 err = mt7996_mcu_add_key(&dev->mt76, vif, key,390 MCU_WMWA_UNI_CMD(STA_REC_UPDATE),391 &msta->wcid, cmd);392out:393 mutex_unlock(&dev->mt76.mutex);394 395 return err;396}397 398static int mt7996_config(struct ieee80211_hw *hw, u32 changed)399{400 struct mt7996_dev *dev = mt7996_hw_dev(hw);401 struct mt7996_phy *phy = mt7996_hw_phy(hw);402 int ret;403 404 if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {405 ret = mt76_update_channel(phy->mt76);406 if (ret)407 return ret;408 }409 410 if (changed & (IEEE80211_CONF_CHANGE_POWER |411 IEEE80211_CONF_CHANGE_CHANNEL)) {412 ret = mt7996_mcu_set_txpower_sku(phy);413 if (ret)414 return ret;415 }416 417 mutex_lock(&dev->mt76.mutex);418 419 if (changed & IEEE80211_CONF_CHANGE_MONITOR) {420 bool enabled = !!(hw->conf.flags & IEEE80211_CONF_MONITOR);421 422 if (!enabled)423 phy->rxfilter |= MT_WF_RFCR_DROP_OTHER_UC;424 else425 phy->rxfilter &= ~MT_WF_RFCR_DROP_OTHER_UC;426 427 mt76_rmw_field(dev, MT_DMA_DCR0(phy->mt76->band_idx),428 MT_DMA_DCR0_RXD_G5_EN, enabled);429 mt76_wr(dev, MT_WF_RFCR(phy->mt76->band_idx), phy->rxfilter);430 }431 432 mutex_unlock(&dev->mt76.mutex);433 434 return 0;435}436 437static int438mt7996_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif,439 unsigned int link_id, u16 queue,440 const struct ieee80211_tx_queue_params *params)441{442 struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv;443 static const u8 mq_to_aci[] = {444 [IEEE80211_AC_VO] = 3,445 [IEEE80211_AC_VI] = 2,446 [IEEE80211_AC_BE] = 0,447 [IEEE80211_AC_BK] = 1,448 };449 450 /* firmware uses access class index */451 mvif->queue_params[mq_to_aci[queue]] = *params;452 /* no need to update right away, we'll get BSS_CHANGED_QOS */453 454 return 0;455}456 457static void mt7996_configure_filter(struct ieee80211_hw *hw,458 unsigned int changed_flags,459 unsigned int *total_flags,460 u64 multicast)461{462 struct mt7996_dev *dev = mt7996_hw_dev(hw);463 struct mt7996_phy *phy = mt7996_hw_phy(hw);464 u32 ctl_flags = MT_WF_RFCR1_DROP_ACK |465 MT_WF_RFCR1_DROP_BF_POLL |466 MT_WF_RFCR1_DROP_BA |467 MT_WF_RFCR1_DROP_CFEND |468 MT_WF_RFCR1_DROP_CFACK;469 u32 flags = 0;470 471#define MT76_FILTER(_flag, _hw) do { \472 flags |= *total_flags & FIF_##_flag; \473 phy->rxfilter &= ~(_hw); \474 phy->rxfilter |= !(flags & FIF_##_flag) * (_hw); \475 } while (0)476 477 mutex_lock(&dev->mt76.mutex);478 479 phy->rxfilter &= ~(MT_WF_RFCR_DROP_OTHER_BSS |480 MT_WF_RFCR_DROP_OTHER_BEACON |481 MT_WF_RFCR_DROP_FRAME_REPORT |482 MT_WF_RFCR_DROP_PROBEREQ |483 MT_WF_RFCR_DROP_MCAST_FILTERED |484 MT_WF_RFCR_DROP_MCAST |485 MT_WF_RFCR_DROP_BCAST |486 MT_WF_RFCR_DROP_DUPLICATE |487 MT_WF_RFCR_DROP_A2_BSSID |488 MT_WF_RFCR_DROP_UNWANTED_CTL |489 MT_WF_RFCR_DROP_STBC_MULTI);490 491 MT76_FILTER(OTHER_BSS, MT_WF_RFCR_DROP_OTHER_TIM |492 MT_WF_RFCR_DROP_A3_MAC |493 MT_WF_RFCR_DROP_A3_BSSID);494 495 MT76_FILTER(FCSFAIL, MT_WF_RFCR_DROP_FCSFAIL);496 497 MT76_FILTER(CONTROL, MT_WF_RFCR_DROP_CTS |498 MT_WF_RFCR_DROP_RTS |499 MT_WF_RFCR_DROP_CTL_RSV |500 MT_WF_RFCR_DROP_NDPA);501 502 *total_flags = flags;503 mt76_wr(dev, MT_WF_RFCR(phy->mt76->band_idx), phy->rxfilter);504 505 if (*total_flags & FIF_CONTROL)506 mt76_clear(dev, MT_WF_RFCR1(phy->mt76->band_idx), ctl_flags);507 else508 mt76_set(dev, MT_WF_RFCR1(phy->mt76->band_idx), ctl_flags);509 510 mutex_unlock(&dev->mt76.mutex);511}512 513static void514mt7996_update_bss_color(struct ieee80211_hw *hw,515 struct ieee80211_vif *vif,516 struct cfg80211_he_bss_color *bss_color)517{518 struct mt7996_dev *dev = mt7996_hw_dev(hw);519 520 switch (vif->type) {521 case NL80211_IFTYPE_AP: {522 struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv;523 524 if (mvif->mt76.omac_idx > HW_BSSID_MAX)525 return;526 fallthrough;527 }528 case NL80211_IFTYPE_STATION:529 mt7996_mcu_update_bss_color(dev, vif, bss_color);530 break;531 default:532 break;533 }534}535 536static u8537mt7996_get_rates_table(struct ieee80211_hw *hw, struct ieee80211_vif *vif,538 bool beacon, bool mcast)539{540 struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv;541 struct mt76_phy *mphy = hw->priv;542 u16 rate;543 u8 i, idx;544 545 rate = mt76_connac2_mac_tx_rate_val(mphy, vif, beacon, mcast);546 547 if (beacon) {548 struct mt7996_phy *phy = mphy->priv;549 550 /* odd index for driver, even index for firmware */551 idx = MT7996_BEACON_RATES_TBL + 2 * phy->mt76->band_idx;552 if (phy->beacon_rate != rate)553 mt7996_mcu_set_fixed_rate_table(phy, idx, rate, beacon);554 555 return idx;556 }557 558 idx = FIELD_GET(MT_TX_RATE_IDX, rate);559 for (i = 0; i < ARRAY_SIZE(mt76_rates); i++)560 if ((mt76_rates[i].hw_value & GENMASK(7, 0)) == idx)561 return MT7996_BASIC_RATES_TBL + 2 * i;562 563 return mvif->basic_rates_idx;564}565 566static void567mt7996_update_mu_group(struct ieee80211_hw *hw, struct ieee80211_vif *vif,568 struct ieee80211_bss_conf *info)569{570 struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv;571 struct mt7996_dev *dev = mt7996_hw_dev(hw);572 u8 band = mvif->mt76.band_idx;573 u32 *mu;574 575 mu = (u32 *)info->mu_group.membership;576 mt76_wr(dev, MT_WF_PHYRX_BAND_GID_TAB_VLD0(band), mu[0]);577 mt76_wr(dev, MT_WF_PHYRX_BAND_GID_TAB_VLD1(band), mu[1]);578 579 mu = (u32 *)info->mu_group.position;580 mt76_wr(dev, MT_WF_PHYRX_BAND_GID_TAB_POS0(band), mu[0]);581 mt76_wr(dev, MT_WF_PHYRX_BAND_GID_TAB_POS1(band), mu[1]);582 mt76_wr(dev, MT_WF_PHYRX_BAND_GID_TAB_POS2(band), mu[2]);583 mt76_wr(dev, MT_WF_PHYRX_BAND_GID_TAB_POS3(band), mu[3]);584}585 586static void mt7996_bss_info_changed(struct ieee80211_hw *hw,587 struct ieee80211_vif *vif,588 struct ieee80211_bss_conf *info,589 u64 changed)590{591 struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv;592 struct mt7996_phy *phy = mt7996_hw_phy(hw);593 struct mt7996_dev *dev = mt7996_hw_dev(hw);594 595 mutex_lock(&dev->mt76.mutex);596 597 /* station mode uses BSSID to map the wlan entry to a peer,598 * and then peer references bss_info_rfch to set bandwidth cap.599 */600 if ((changed & BSS_CHANGED_BSSID && !is_zero_ether_addr(info->bssid)) ||601 (changed & BSS_CHANGED_ASSOC && vif->cfg.assoc) ||602 (changed & BSS_CHANGED_BEACON_ENABLED && info->enable_beacon)) {603 mt7996_mcu_add_bss_info(phy, vif, true);604 mt7996_mcu_add_sta(dev, vif, NULL, true,605 !!(changed & BSS_CHANGED_BSSID));606 }607 608 if (changed & BSS_CHANGED_ERP_CTS_PROT)609 mt7996_mac_enable_rtscts(dev, vif, info->use_cts_prot);610 611 if (changed & BSS_CHANGED_ERP_SLOT) {612 int slottime = info->use_short_slot ? 9 : 20;613 614 if (slottime != phy->slottime) {615 phy->slottime = slottime;616 mt7996_mcu_set_timing(phy, vif);617 }618 }619 620 if (changed & BSS_CHANGED_MCAST_RATE)621 mvif->mcast_rates_idx =622 mt7996_get_rates_table(hw, vif, false, true);623 624 if (changed & BSS_CHANGED_BASIC_RATES)625 mvif->basic_rates_idx =626 mt7996_get_rates_table(hw, vif, false, false);627 628 /* ensure that enable txcmd_mode after bss_info */629 if (changed & (BSS_CHANGED_QOS | BSS_CHANGED_BEACON_ENABLED))630 mt7996_mcu_set_tx(dev, vif);631 632 if (changed & BSS_CHANGED_HE_OBSS_PD)633 mt7996_mcu_add_obss_spr(phy, vif, &info->he_obss_pd);634 635 if (changed & BSS_CHANGED_HE_BSS_COLOR)636 mt7996_update_bss_color(hw, vif, &info->he_bss_color);637 638 if (changed & (BSS_CHANGED_BEACON |639 BSS_CHANGED_BEACON_ENABLED)) {640 mvif->beacon_rates_idx =641 mt7996_get_rates_table(hw, vif, true, false);642 643 mt7996_mcu_add_beacon(hw, vif, info->enable_beacon);644 }645 646 if (changed & (BSS_CHANGED_UNSOL_BCAST_PROBE_RESP |647 BSS_CHANGED_FILS_DISCOVERY))648 mt7996_mcu_beacon_inband_discov(dev, vif, changed);649 650 if (changed & BSS_CHANGED_MU_GROUPS)651 mt7996_update_mu_group(hw, vif, info);652 653 mutex_unlock(&dev->mt76.mutex);654}655 656static void657mt7996_channel_switch_beacon(struct ieee80211_hw *hw,658 struct ieee80211_vif *vif,659 struct cfg80211_chan_def *chandef)660{661 struct mt7996_dev *dev = mt7996_hw_dev(hw);662 663 mutex_lock(&dev->mt76.mutex);664 mt7996_mcu_add_beacon(hw, vif, true);665 mutex_unlock(&dev->mt76.mutex);666}667 668int mt7996_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,669 struct ieee80211_sta *sta)670{671 struct mt7996_dev *dev = container_of(mdev, struct mt7996_dev, mt76);672 struct mt7996_sta *msta = (struct mt7996_sta *)sta->drv_priv;673 struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv;674 u8 band_idx = mvif->phy->mt76->band_idx;675 int ret, idx;676 677 idx = mt76_wcid_alloc(dev->mt76.wcid_mask, MT7996_WTBL_STA);678 if (idx < 0)679 return -ENOSPC;680 681 INIT_LIST_HEAD(&msta->rc_list);682 INIT_LIST_HEAD(&msta->wcid.poll_list);683 msta->vif = mvif;684 msta->wcid.sta = 1;685 msta->wcid.idx = idx;686 msta->wcid.phy_idx = band_idx;687 msta->wcid.tx_info |= MT_WCID_TX_INFO_SET;688 689 ewma_avg_signal_init(&msta->avg_ack_signal);690 691 mt7996_mac_wtbl_update(dev, idx,692 MT_WTBL_UPDATE_ADM_COUNT_CLEAR);693 694 ret = mt7996_mcu_add_sta(dev, vif, sta, true, true);695 if (ret)696 return ret;697 698 return mt7996_mcu_add_rate_ctrl(dev, vif, sta, false);699}700 701void mt7996_mac_sta_remove(struct mt76_dev *mdev, struct ieee80211_vif *vif,702 struct ieee80211_sta *sta)703{704 struct mt7996_dev *dev = container_of(mdev, struct mt7996_dev, mt76);705 struct mt7996_sta *msta = (struct mt7996_sta *)sta->drv_priv;706 int i;707 708 mt7996_mcu_add_sta(dev, vif, sta, false, false);709 710 mt7996_mac_wtbl_update(dev, msta->wcid.idx,711 MT_WTBL_UPDATE_ADM_COUNT_CLEAR);712 713 for (i = 0; i < ARRAY_SIZE(msta->twt.flow); i++)714 mt7996_mac_twt_teardown_flow(dev, msta, i);715 716 spin_lock_bh(&mdev->sta_poll_lock);717 if (!list_empty(&msta->wcid.poll_list))718 list_del_init(&msta->wcid.poll_list);719 if (!list_empty(&msta->rc_list))720 list_del_init(&msta->rc_list);721 spin_unlock_bh(&mdev->sta_poll_lock);722}723 724static void mt7996_tx(struct ieee80211_hw *hw,725 struct ieee80211_tx_control *control,726 struct sk_buff *skb)727{728 struct mt7996_dev *dev = mt7996_hw_dev(hw);729 struct mt76_phy *mphy = hw->priv;730 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);731 struct ieee80211_vif *vif = info->control.vif;732 struct mt76_wcid *wcid = &dev->mt76.global_wcid;733 734 if (control->sta) {735 struct mt7996_sta *sta;736 737 sta = (struct mt7996_sta *)control->sta->drv_priv;738 wcid = &sta->wcid;739 }740 741 if (vif && !control->sta) {742 struct mt7996_vif *mvif;743 744 mvif = (struct mt7996_vif *)vif->drv_priv;745 wcid = &mvif->sta.wcid;746 }747 748 mt76_tx(mphy, control->sta, wcid, skb);749}750 751static int mt7996_set_rts_threshold(struct ieee80211_hw *hw, u32 val)752{753 struct mt7996_phy *phy = mt7996_hw_phy(hw);754 int ret;755 756 mutex_lock(&phy->dev->mt76.mutex);757 ret = mt7996_mcu_set_rts_thresh(phy, val);758 mutex_unlock(&phy->dev->mt76.mutex);759 760 return ret;761}762 763static int764mt7996_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,765 struct ieee80211_ampdu_params *params)766{767 enum ieee80211_ampdu_mlme_action action = params->action;768 struct mt7996_dev *dev = mt7996_hw_dev(hw);769 struct ieee80211_sta *sta = params->sta;770 struct ieee80211_txq *txq = sta->txq[params->tid];771 struct mt7996_sta *msta = (struct mt7996_sta *)sta->drv_priv;772 u16 tid = params->tid;773 u16 ssn = params->ssn;774 struct mt76_txq *mtxq;775 int ret = 0;776 777 if (!txq)778 return -EINVAL;779 780 mtxq = (struct mt76_txq *)txq->drv_priv;781 782 mutex_lock(&dev->mt76.mutex);783 switch (action) {784 case IEEE80211_AMPDU_RX_START:785 mt76_rx_aggr_start(&dev->mt76, &msta->wcid, tid, ssn,786 params->buf_size);787 ret = mt7996_mcu_add_rx_ba(dev, params, true);788 break;789 case IEEE80211_AMPDU_RX_STOP:790 mt76_rx_aggr_stop(&dev->mt76, &msta->wcid, tid);791 ret = mt7996_mcu_add_rx_ba(dev, params, false);792 break;793 case IEEE80211_AMPDU_TX_OPERATIONAL:794 mtxq->aggr = true;795 mtxq->send_bar = false;796 ret = mt7996_mcu_add_tx_ba(dev, params, true);797 break;798 case IEEE80211_AMPDU_TX_STOP_FLUSH:799 case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT:800 mtxq->aggr = false;801 clear_bit(tid, &msta->wcid.ampdu_state);802 ret = mt7996_mcu_add_tx_ba(dev, params, false);803 break;804 case IEEE80211_AMPDU_TX_START:805 set_bit(tid, &msta->wcid.ampdu_state);806 ret = IEEE80211_AMPDU_TX_START_IMMEDIATE;807 break;808 case IEEE80211_AMPDU_TX_STOP_CONT:809 mtxq->aggr = false;810 clear_bit(tid, &msta->wcid.ampdu_state);811 ret = mt7996_mcu_add_tx_ba(dev, params, false);812 ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid);813 break;814 }815 mutex_unlock(&dev->mt76.mutex);816 817 return ret;818}819 820static int821mt7996_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif,822 struct ieee80211_sta *sta)823{824 return mt76_sta_state(hw, vif, sta, IEEE80211_STA_NOTEXIST,825 IEEE80211_STA_NONE);826}827 828static int829mt7996_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif,830 struct ieee80211_sta *sta)831{832 return mt76_sta_state(hw, vif, sta, IEEE80211_STA_NONE,833 IEEE80211_STA_NOTEXIST);834}835 836static int837mt7996_get_stats(struct ieee80211_hw *hw,838 struct ieee80211_low_level_stats *stats)839{840 struct mt7996_phy *phy = mt7996_hw_phy(hw);841 struct mt7996_dev *dev = mt7996_hw_dev(hw);842 struct mt76_mib_stats *mib = &phy->mib;843 844 mutex_lock(&dev->mt76.mutex);845 846 stats->dot11RTSSuccessCount = mib->rts_cnt;847 stats->dot11RTSFailureCount = mib->rts_retries_cnt;848 stats->dot11FCSErrorCount = mib->fcs_err_cnt;849 stats->dot11ACKFailureCount = mib->ack_fail_cnt;850 851 mutex_unlock(&dev->mt76.mutex);852 853 return 0;854}855 856u64 __mt7996_get_tsf(struct ieee80211_hw *hw, struct mt7996_vif *mvif)857{858 struct mt7996_dev *dev = mt7996_hw_dev(hw);859 struct mt7996_phy *phy = mt7996_hw_phy(hw);860 union {861 u64 t64;862 u32 t32[2];863 } tsf;864 u16 n;865 866 lockdep_assert_held(&dev->mt76.mutex);867 868 n = mvif->mt76.omac_idx > HW_BSSID_MAX ? HW_BSSID_0869 : mvif->mt76.omac_idx;870 /* TSF software read */871 mt76_rmw(dev, MT_LPON_TCR(phy->mt76->band_idx, n), MT_LPON_TCR_SW_MODE,872 MT_LPON_TCR_SW_READ);873 tsf.t32[0] = mt76_rr(dev, MT_LPON_UTTR0(phy->mt76->band_idx));874 tsf.t32[1] = mt76_rr(dev, MT_LPON_UTTR1(phy->mt76->band_idx));875 876 return tsf.t64;877}878 879static u64880mt7996_get_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif)881{882 struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv;883 struct mt7996_dev *dev = mt7996_hw_dev(hw);884 u64 ret;885 886 mutex_lock(&dev->mt76.mutex);887 ret = __mt7996_get_tsf(hw, mvif);888 mutex_unlock(&dev->mt76.mutex);889 890 return ret;891}892 893static void894mt7996_set_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif,895 u64 timestamp)896{897 struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv;898 struct mt7996_dev *dev = mt7996_hw_dev(hw);899 struct mt7996_phy *phy = mt7996_hw_phy(hw);900 union {901 u64 t64;902 u32 t32[2];903 } tsf = { .t64 = timestamp, };904 u16 n;905 906 mutex_lock(&dev->mt76.mutex);907 908 n = mvif->mt76.omac_idx > HW_BSSID_MAX ? HW_BSSID_0909 : mvif->mt76.omac_idx;910 mt76_wr(dev, MT_LPON_UTTR0(phy->mt76->band_idx), tsf.t32[0]);911 mt76_wr(dev, MT_LPON_UTTR1(phy->mt76->band_idx), tsf.t32[1]);912 /* TSF software overwrite */913 mt76_rmw(dev, MT_LPON_TCR(phy->mt76->band_idx, n), MT_LPON_TCR_SW_MODE,914 MT_LPON_TCR_SW_WRITE);915 916 mutex_unlock(&dev->mt76.mutex);917}918 919static void920mt7996_offset_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif,921 s64 timestamp)922{923 struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv;924 struct mt7996_dev *dev = mt7996_hw_dev(hw);925 struct mt7996_phy *phy = mt7996_hw_phy(hw);926 union {927 u64 t64;928 u32 t32[2];929 } tsf = { .t64 = timestamp, };930 u16 n;931 932 mutex_lock(&dev->mt76.mutex);933 934 n = mvif->mt76.omac_idx > HW_BSSID_MAX ? HW_BSSID_0935 : mvif->mt76.omac_idx;936 mt76_wr(dev, MT_LPON_UTTR0(phy->mt76->band_idx), tsf.t32[0]);937 mt76_wr(dev, MT_LPON_UTTR1(phy->mt76->band_idx), tsf.t32[1]);938 /* TSF software adjust*/939 mt76_rmw(dev, MT_LPON_TCR(phy->mt76->band_idx, n), MT_LPON_TCR_SW_MODE,940 MT_LPON_TCR_SW_ADJUST);941 942 mutex_unlock(&dev->mt76.mutex);943}944 945static void946mt7996_set_coverage_class(struct ieee80211_hw *hw, s16 coverage_class)947{948 struct mt7996_phy *phy = mt7996_hw_phy(hw);949 struct mt7996_dev *dev = phy->dev;950 951 mutex_lock(&dev->mt76.mutex);952 phy->coverage_class = max_t(s16, coverage_class, 0);953 mt7996_mac_set_coverage_class(phy);954 mutex_unlock(&dev->mt76.mutex);955}956 957static int958mt7996_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant)959{960 struct mt7996_dev *dev = mt7996_hw_dev(hw);961 struct mt7996_phy *phy = mt7996_hw_phy(hw);962 int max_nss = hweight8(hw->wiphy->available_antennas_tx);963 u8 band_idx = phy->mt76->band_idx, shift = dev->chainshift[band_idx];964 965 if (!tx_ant || tx_ant != rx_ant || ffs(tx_ant) > max_nss)966 return -EINVAL;967 968 if ((BIT(hweight8(tx_ant)) - 1) != tx_ant)969 tx_ant = BIT(ffs(tx_ant) - 1) - 1;970 971 mutex_lock(&dev->mt76.mutex);972 973 phy->mt76->antenna_mask = tx_ant;974 975 /* restore to the origin chainmask which might have auxiliary path */976 if (hweight8(tx_ant) == max_nss && band_idx < MT_BAND2)977 phy->mt76->chainmask = ((dev->chainmask >> shift) &978 (BIT(dev->chainshift[band_idx + 1] - shift) - 1)) << shift;979 else if (hweight8(tx_ant) == max_nss)980 phy->mt76->chainmask = (dev->chainmask >> shift) << shift;981 else982 phy->mt76->chainmask = tx_ant << shift;983 984 mt76_set_stream_caps(phy->mt76, true);985 mt7996_set_stream_vht_txbf_caps(phy);986 mt7996_set_stream_he_eht_caps(phy);987 mt7996_mcu_set_txpower_sku(phy);988 989 mutex_unlock(&dev->mt76.mutex);990 991 return 0;992}993 994static void mt7996_sta_statistics(struct ieee80211_hw *hw,995 struct ieee80211_vif *vif,996 struct ieee80211_sta *sta,997 struct station_info *sinfo)998{999 struct mt7996_phy *phy = mt7996_hw_phy(hw);1000 struct mt7996_sta *msta = (struct mt7996_sta *)sta->drv_priv;1001 struct rate_info *txrate = &msta->wcid.rate;1002 1003 if (txrate->legacy || txrate->flags) {1004 if (txrate->legacy) {1005 sinfo->txrate.legacy = txrate->legacy;1006 } else {1007 sinfo->txrate.mcs = txrate->mcs;1008 sinfo->txrate.nss = txrate->nss;1009 sinfo->txrate.bw = txrate->bw;1010 sinfo->txrate.he_gi = txrate->he_gi;1011 sinfo->txrate.he_dcm = txrate->he_dcm;1012 sinfo->txrate.he_ru_alloc = txrate->he_ru_alloc;1013 sinfo->txrate.eht_gi = txrate->eht_gi;1014 }1015 sinfo->txrate.flags = txrate->flags;1016 sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BITRATE);1017 }1018 sinfo->txrate.flags = txrate->flags;1019 sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BITRATE);1020 1021 sinfo->tx_failed = msta->wcid.stats.tx_failed;1022 sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_FAILED);1023 1024 sinfo->tx_retries = msta->wcid.stats.tx_retries;1025 sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_RETRIES);1026 1027 sinfo->ack_signal = (s8)msta->ack_signal;1028 sinfo->filled |= BIT_ULL(NL80211_STA_INFO_ACK_SIGNAL);1029 1030 sinfo->avg_ack_signal = -(s8)ewma_avg_signal_read(&msta->avg_ack_signal);1031 sinfo->filled |= BIT_ULL(NL80211_STA_INFO_ACK_SIGNAL_AVG);1032 1033 if (mtk_wed_device_active(&phy->dev->mt76.mmio.wed)) {1034 sinfo->tx_bytes = msta->wcid.stats.tx_bytes;1035 sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BYTES64);1036 1037 sinfo->rx_bytes = msta->wcid.stats.rx_bytes;1038 sinfo->filled |= BIT_ULL(NL80211_STA_INFO_RX_BYTES64);1039 1040 sinfo->tx_packets = msta->wcid.stats.tx_packets;1041 sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_PACKETS);1042 1043 sinfo->rx_packets = msta->wcid.stats.rx_packets;1044 sinfo->filled |= BIT_ULL(NL80211_STA_INFO_RX_PACKETS);1045 }1046}1047 1048static void mt7996_sta_rc_work(void *data, struct ieee80211_sta *sta)1049{1050 struct mt7996_sta *msta = (struct mt7996_sta *)sta->drv_priv;1051 struct mt7996_dev *dev = msta->vif->phy->dev;1052 u32 *changed = data;1053 1054 spin_lock_bh(&dev->mt76.sta_poll_lock);1055 msta->changed |= *changed;1056 if (list_empty(&msta->rc_list))1057 list_add_tail(&msta->rc_list, &dev->sta_rc_list);1058 spin_unlock_bh(&dev->mt76.sta_poll_lock);1059}1060 1061static void mt7996_sta_rc_update(struct ieee80211_hw *hw,1062 struct ieee80211_vif *vif,1063 struct ieee80211_sta *sta,1064 u32 changed)1065{1066 struct mt7996_phy *phy = mt7996_hw_phy(hw);1067 struct mt7996_dev *dev = phy->dev;1068 1069 mt7996_sta_rc_work(&changed, sta);1070 ieee80211_queue_work(hw, &dev->rc_work);1071}1072 1073static int1074mt7996_set_bitrate_mask(struct ieee80211_hw *hw, struct ieee80211_vif *vif,1075 const struct cfg80211_bitrate_mask *mask)1076{1077 struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv;1078 struct mt7996_phy *phy = mt7996_hw_phy(hw);1079 struct mt7996_dev *dev = phy->dev;1080 u32 changed = IEEE80211_RC_SUPP_RATES_CHANGED;1081 1082 mvif->bitrate_mask = *mask;1083 1084 /* if multiple rates across different preambles are given we can1085 * reconfigure this info with all peers using sta_rec command with1086 * the below exception cases.1087 * - single rate : if a rate is passed along with different preambles,1088 * we select the highest one as fixed rate. i.e VHT MCS for VHT peers.1089 * - multiple rates: if it's not in range format i.e 0-{7,8,9} for VHT1090 * then multiple MCS setting (MCS 4,5,6) is not supported.1091 */1092 ieee80211_iterate_stations_atomic(hw, mt7996_sta_rc_work, &changed);1093 ieee80211_queue_work(hw, &dev->rc_work);1094 1095 return 0;1096}1097 1098static void mt7996_sta_set_4addr(struct ieee80211_hw *hw,1099 struct ieee80211_vif *vif,1100 struct ieee80211_sta *sta,1101 bool enabled)1102{1103 struct mt7996_dev *dev = mt7996_hw_dev(hw);1104 struct mt7996_sta *msta = (struct mt7996_sta *)sta->drv_priv;1105 1106 if (enabled)1107 set_bit(MT_WCID_FLAG_4ADDR, &msta->wcid.flags);1108 else1109 clear_bit(MT_WCID_FLAG_4ADDR, &msta->wcid.flags);1110 1111 mt7996_mcu_wtbl_update_hdr_trans(dev, vif, sta);1112}1113 1114static void mt7996_sta_set_decap_offload(struct ieee80211_hw *hw,1115 struct ieee80211_vif *vif,1116 struct ieee80211_sta *sta,1117 bool enabled)1118{1119 struct mt7996_dev *dev = mt7996_hw_dev(hw);1120 struct mt7996_sta *msta = (struct mt7996_sta *)sta->drv_priv;1121 1122 if (enabled)1123 set_bit(MT_WCID_FLAG_HDR_TRANS, &msta->wcid.flags);1124 else1125 clear_bit(MT_WCID_FLAG_HDR_TRANS, &msta->wcid.flags);1126 1127 mt7996_mcu_wtbl_update_hdr_trans(dev, vif, sta);1128}1129 1130static const char mt7996_gstrings_stats[][ETH_GSTRING_LEN] = {1131 "tx_ampdu_cnt",1132 "tx_stop_q_empty_cnt",1133 "tx_mpdu_attempts",1134 "tx_mpdu_success",1135 "tx_rwp_fail_cnt",1136 "tx_rwp_need_cnt",1137 "tx_pkt_ebf_cnt",1138 "tx_pkt_ibf_cnt",1139 "tx_ampdu_len:0-1",1140 "tx_ampdu_len:2-10",1141 "tx_ampdu_len:11-19",1142 "tx_ampdu_len:20-28",1143 "tx_ampdu_len:29-37",1144 "tx_ampdu_len:38-46",1145 "tx_ampdu_len:47-55",1146 "tx_ampdu_len:56-79",1147 "tx_ampdu_len:80-103",1148 "tx_ampdu_len:104-127",1149 "tx_ampdu_len:128-151",1150 "tx_ampdu_len:152-175",1151 "tx_ampdu_len:176-199",1152 "tx_ampdu_len:200-223",1153 "tx_ampdu_len:224-247",1154 "ba_miss_count",1155 "tx_beamformer_ppdu_iBF",1156 "tx_beamformer_ppdu_eBF",1157 "tx_beamformer_rx_feedback_all",1158 "tx_beamformer_rx_feedback_he",1159 "tx_beamformer_rx_feedback_vht",1160 "tx_beamformer_rx_feedback_ht",1161 "tx_beamformer_rx_feedback_bw", /* zero based idx: 20, 40, 80, 160 */1162 "tx_beamformer_rx_feedback_nc",1163 "tx_beamformer_rx_feedback_nr",1164 "tx_beamformee_ok_feedback_pkts",1165 "tx_beamformee_feedback_trig",1166 "tx_mu_beamforming",1167 "tx_mu_mpdu",1168 "tx_mu_successful_mpdu",1169 "tx_su_successful_mpdu",1170 "tx_msdu_pack_1",1171 "tx_msdu_pack_2",1172 "tx_msdu_pack_3",1173 "tx_msdu_pack_4",1174 "tx_msdu_pack_5",1175 "tx_msdu_pack_6",1176 "tx_msdu_pack_7",1177 "tx_msdu_pack_8",1178 1179 /* rx counters */1180 "rx_fifo_full_cnt",1181 "rx_mpdu_cnt",1182 "channel_idle_cnt",1183 "rx_vector_mismatch_cnt",1184 "rx_delimiter_fail_cnt",1185 "rx_len_mismatch_cnt",1186 "rx_ampdu_cnt",1187 "rx_ampdu_bytes_cnt",1188 "rx_ampdu_valid_subframe_cnt",1189 "rx_ampdu_valid_subframe_b_cnt",1190 "rx_pfdrop_cnt",1191 "rx_vec_queue_overflow_drop_cnt",1192 "rx_ba_cnt",1193 1194 /* per vif counters */1195 "v_tx_mode_cck",1196 "v_tx_mode_ofdm",1197 "v_tx_mode_ht",1198 "v_tx_mode_ht_gf",1199 "v_tx_mode_vht",1200 "v_tx_mode_he_su",1201 "v_tx_mode_he_ext_su",1202 "v_tx_mode_he_tb",1203 "v_tx_mode_he_mu",1204 "v_tx_mode_eht_su",1205 "v_tx_mode_eht_trig",1206 "v_tx_mode_eht_mu",1207 "v_tx_bw_20",1208 "v_tx_bw_40",1209 "v_tx_bw_80",1210 "v_tx_bw_160",1211 "v_tx_bw_320",1212 "v_tx_mcs_0",1213 "v_tx_mcs_1",1214 "v_tx_mcs_2",1215 "v_tx_mcs_3",1216 "v_tx_mcs_4",1217 "v_tx_mcs_5",1218 "v_tx_mcs_6",1219 "v_tx_mcs_7",1220 "v_tx_mcs_8",1221 "v_tx_mcs_9",1222 "v_tx_mcs_10",1223 "v_tx_mcs_11",1224 "v_tx_mcs_12",1225 "v_tx_mcs_13",1226 "v_tx_nss_1",1227 "v_tx_nss_2",1228 "v_tx_nss_3",1229 "v_tx_nss_4",1230};1231 1232#define MT7996_SSTATS_LEN ARRAY_SIZE(mt7996_gstrings_stats)1233 1234/* Ethtool related API */1235static1236void mt7996_get_et_strings(struct ieee80211_hw *hw,1237 struct ieee80211_vif *vif,1238 u32 sset, u8 *data)1239{1240 if (sset == ETH_SS_STATS)1241 memcpy(data, mt7996_gstrings_stats,1242 sizeof(mt7996_gstrings_stats));1243}1244 1245static1246int mt7996_get_et_sset_count(struct ieee80211_hw *hw,1247 struct ieee80211_vif *vif, int sset)1248{1249 if (sset == ETH_SS_STATS)1250 return MT7996_SSTATS_LEN;1251 1252 return 0;1253}1254 1255static void mt7996_ethtool_worker(void *wi_data, struct ieee80211_sta *sta)1256{1257 struct mt76_ethtool_worker_info *wi = wi_data;1258 struct mt7996_sta *msta = (struct mt7996_sta *)sta->drv_priv;1259 1260 if (msta->vif->mt76.idx != wi->idx)1261 return;1262 1263 mt76_ethtool_worker(wi, &msta->wcid.stats, true);1264}1265 1266static1267void mt7996_get_et_stats(struct ieee80211_hw *hw,1268 struct ieee80211_vif *vif,1269 struct ethtool_stats *stats, u64 *data)1270{1271 struct mt7996_dev *dev = mt7996_hw_dev(hw);1272 struct mt7996_phy *phy = mt7996_hw_phy(hw);1273 struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv;1274 struct mt76_mib_stats *mib = &phy->mib;1275 struct mt76_ethtool_worker_info wi = {1276 .data = data,1277 .idx = mvif->mt76.idx,1278 };1279 /* See mt7996_ampdu_stat_read_phy, etc */1280 int i, ei = 0;1281 1282 mutex_lock(&dev->mt76.mutex);1283 1284 mt7996_mac_update_stats(phy);1285 1286 data[ei++] = mib->tx_ampdu_cnt;1287 data[ei++] = mib->tx_stop_q_empty_cnt;1288 data[ei++] = mib->tx_mpdu_attempts_cnt;1289 data[ei++] = mib->tx_mpdu_success_cnt;1290 data[ei++] = mib->tx_rwp_fail_cnt;1291 data[ei++] = mib->tx_rwp_need_cnt;1292 data[ei++] = mib->tx_bf_ebf_ppdu_cnt;1293 data[ei++] = mib->tx_bf_ibf_ppdu_cnt;1294 1295 /* Tx ampdu stat */1296 for (i = 0; i < 15 /*ARRAY_SIZE(bound)*/; i++)1297 data[ei++] = phy->mt76->aggr_stats[i];1298 data[ei++] = phy->mib.ba_miss_cnt;1299 1300 /* Tx Beamformer monitor */1301 data[ei++] = mib->tx_bf_ibf_ppdu_cnt;1302 data[ei++] = mib->tx_bf_ebf_ppdu_cnt;1303 1304 /* Tx Beamformer Rx feedback monitor */1305 data[ei++] = mib->tx_bf_rx_fb_all_cnt;1306 data[ei++] = mib->tx_bf_rx_fb_he_cnt;1307 data[ei++] = mib->tx_bf_rx_fb_vht_cnt;1308 data[ei++] = mib->tx_bf_rx_fb_ht_cnt;1309 1310 data[ei++] = mib->tx_bf_rx_fb_bw;1311 data[ei++] = mib->tx_bf_rx_fb_nc_cnt;1312 data[ei++] = mib->tx_bf_rx_fb_nr_cnt;1313 1314 /* Tx Beamformee Rx NDPA & Tx feedback report */1315 data[ei++] = mib->tx_bf_fb_cpl_cnt;1316 data[ei++] = mib->tx_bf_fb_trig_cnt;1317 1318 /* Tx SU & MU counters */1319 data[ei++] = mib->tx_mu_bf_cnt;1320 data[ei++] = mib->tx_mu_mpdu_cnt;1321 data[ei++] = mib->tx_mu_acked_mpdu_cnt;1322 data[ei++] = mib->tx_su_acked_mpdu_cnt;1323 1324 /* Tx amsdu info (pack-count histogram) */1325 for (i = 0; i < ARRAY_SIZE(mib->tx_amsdu); i++)1326 data[ei++] = mib->tx_amsdu[i];1327 1328 /* rx counters */1329 data[ei++] = mib->rx_fifo_full_cnt;1330 data[ei++] = mib->rx_mpdu_cnt;1331 data[ei++] = mib->channel_idle_cnt;1332 data[ei++] = mib->rx_vector_mismatch_cnt;1333 data[ei++] = mib->rx_delimiter_fail_cnt;1334 data[ei++] = mib->rx_len_mismatch_cnt;1335 data[ei++] = mib->rx_ampdu_cnt;1336 data[ei++] = mib->rx_ampdu_bytes_cnt;1337 data[ei++] = mib->rx_ampdu_valid_subframe_cnt;1338 data[ei++] = mib->rx_ampdu_valid_subframe_bytes_cnt;1339 data[ei++] = mib->rx_pfdrop_cnt;1340 data[ei++] = mib->rx_vec_queue_overflow_drop_cnt;1341 data[ei++] = mib->rx_ba_cnt;1342 1343 /* Add values for all stations owned by this vif */1344 wi.initial_stat_idx = ei;1345 ieee80211_iterate_stations_atomic(hw, mt7996_ethtool_worker, &wi);1346 1347 mutex_unlock(&dev->mt76.mutex);1348 1349 if (wi.sta_count == 0)1350 return;1351 1352 ei += wi.worker_stat_count;1353 if (ei != MT7996_SSTATS_LEN)1354 dev_err(dev->mt76.dev, "ei: %d MT7996_SSTATS_LEN: %d",1355 ei, (int)MT7996_SSTATS_LEN);1356}1357 1358static void1359mt7996_twt_teardown_request(struct ieee80211_hw *hw,1360 struct ieee80211_sta *sta,1361 u8 flowid)1362{1363 struct mt7996_sta *msta = (struct mt7996_sta *)sta->drv_priv;1364 struct mt7996_dev *dev = mt7996_hw_dev(hw);1365 1366 mutex_lock(&dev->mt76.mutex);1367 mt7996_mac_twt_teardown_flow(dev, msta, flowid);1368 mutex_unlock(&dev->mt76.mutex);1369}1370 1371static int1372mt7996_set_radar_background(struct ieee80211_hw *hw,1373 struct cfg80211_chan_def *chandef)1374{1375 struct mt7996_phy *phy = mt7996_hw_phy(hw);1376 struct mt7996_dev *dev = phy->dev;1377 int ret = -EINVAL;1378 bool running;1379 1380 mutex_lock(&dev->mt76.mutex);1381 1382 if (dev->mt76.region == NL80211_DFS_UNSET)1383 goto out;1384 1385 if (dev->rdd2_phy && dev->rdd2_phy != phy) {1386 /* rdd2 is already locked */1387 ret = -EBUSY;1388 goto out;1389 }1390 1391 /* rdd2 already configured on a radar channel */1392 running = dev->rdd2_phy &&1393 cfg80211_chandef_valid(&dev->rdd2_chandef) &&1394 !!(dev->rdd2_chandef.chan->flags & IEEE80211_CHAN_RADAR);1395 1396 if (!chandef || running ||1397 !(chandef->chan->flags & IEEE80211_CHAN_RADAR)) {1398 ret = mt7996_mcu_rdd_background_enable(phy, NULL);1399 if (ret)1400 goto out;1401 1402 if (!running)1403 goto update_phy;1404 }1405 1406 ret = mt7996_mcu_rdd_background_enable(phy, chandef);1407 if (ret)1408 goto out;1409 1410update_phy:1411 dev->rdd2_phy = chandef ? phy : NULL;1412 if (chandef)1413 dev->rdd2_chandef = *chandef;1414out:1415 mutex_unlock(&dev->mt76.mutex);1416 1417 return ret;1418}1419 1420#ifdef CONFIG_NET_MEDIATEK_SOC_WED1421static int1422mt7996_net_fill_forward_path(struct ieee80211_hw *hw,1423 struct ieee80211_vif *vif,1424 struct ieee80211_sta *sta,1425 struct net_device_path_ctx *ctx,1426 struct net_device_path *path)1427{1428 struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv;1429 struct mt7996_sta *msta = (struct mt7996_sta *)sta->drv_priv;1430 struct mt7996_dev *dev = mt7996_hw_dev(hw);1431 struct mt7996_phy *phy = mt7996_hw_phy(hw);1432 struct mtk_wed_device *wed = &dev->mt76.mmio.wed;1433 1434 if (phy != &dev->phy && phy->mt76->band_idx == MT_BAND2)1435 wed = &dev->mt76.mmio.wed_hif2;1436 1437 if (!mtk_wed_device_active(wed))1438 return -ENODEV;1439 1440 if (msta->wcid.idx > MT7996_WTBL_STA)1441 return -EIO;1442 1443 path->type = DEV_PATH_MTK_WDMA;1444 path->dev = ctx->dev;1445 path->mtk_wdma.wdma_idx = wed->wdma_idx;1446 path->mtk_wdma.bss = mvif->mt76.idx;1447 path->mtk_wdma.queue = 0;1448 path->mtk_wdma.wcid = msta->wcid.idx;1449 1450 path->mtk_wdma.amsdu = mtk_wed_is_amsdu_supported(wed);1451 ctx->dev = NULL;1452 1453 return 0;1454}1455 1456#endif1457 1458const struct ieee80211_ops mt7996_ops = {1459 .add_chanctx = ieee80211_emulate_add_chanctx,1460 .remove_chanctx = ieee80211_emulate_remove_chanctx,1461 .change_chanctx = ieee80211_emulate_change_chanctx,1462 .switch_vif_chanctx = ieee80211_emulate_switch_vif_chanctx,1463 .tx = mt7996_tx,1464 .start = mt7996_start,1465 .stop = mt7996_stop,1466 .add_interface = mt7996_add_interface,1467 .remove_interface = mt7996_remove_interface,1468 .config = mt7996_config,1469 .conf_tx = mt7996_conf_tx,1470 .configure_filter = mt7996_configure_filter,1471 .bss_info_changed = mt7996_bss_info_changed,1472 .sta_add = mt7996_sta_add,1473 .sta_remove = mt7996_sta_remove,1474 .sta_pre_rcu_remove = mt76_sta_pre_rcu_remove,1475 .sta_rc_update = mt7996_sta_rc_update,1476 .set_key = mt7996_set_key,1477 .ampdu_action = mt7996_ampdu_action,1478 .set_rts_threshold = mt7996_set_rts_threshold,1479 .wake_tx_queue = mt76_wake_tx_queue,1480 .sw_scan_start = mt76_sw_scan,1481 .sw_scan_complete = mt76_sw_scan_complete,1482 .release_buffered_frames = mt76_release_buffered_frames,1483 .get_txpower = mt76_get_txpower,1484 .channel_switch_beacon = mt7996_channel_switch_beacon,1485 .get_stats = mt7996_get_stats,1486 .get_et_sset_count = mt7996_get_et_sset_count,1487 .get_et_stats = mt7996_get_et_stats,1488 .get_et_strings = mt7996_get_et_strings,1489 .get_tsf = mt7996_get_tsf,1490 .set_tsf = mt7996_set_tsf,1491 .offset_tsf = mt7996_offset_tsf,1492 .get_survey = mt76_get_survey,1493 .get_antenna = mt76_get_antenna,1494 .set_antenna = mt7996_set_antenna,1495 .set_bitrate_mask = mt7996_set_bitrate_mask,1496 .set_coverage_class = mt7996_set_coverage_class,1497 .sta_statistics = mt7996_sta_statistics,1498 .sta_set_4addr = mt7996_sta_set_4addr,1499 .sta_set_decap_offload = mt7996_sta_set_decap_offload,1500 .add_twt_setup = mt7996_mac_add_twt_setup,1501 .twt_teardown_request = mt7996_twt_teardown_request,1502#ifdef CONFIG_MAC80211_DEBUGFS1503 .sta_add_debugfs = mt7996_sta_add_debugfs,1504#endif1505 .set_radar_background = mt7996_set_radar_background,1506#ifdef CONFIG_NET_MEDIATEK_SOC_WED1507 .net_fill_forward_path = mt7996_net_fill_forward_path,1508 .net_setup_tc = mt76_wed_net_setup_tc,1509#endif1510};1511