1754 lines · c
1// SPDX-License-Identifier: ISC2/* Copyright (C) 2020 MediaTek Inc. */3 4#include <linux/etherdevice.h>5#include <linux/platform_device.h>6#include <linux/pci.h>7#include <linux/module.h>8#include "mt7915.h"9#include "mcu.h"10 11static bool mt7915_dev_running(struct mt7915_dev *dev)12{13 struct mt7915_phy *phy;14 15 if (test_bit(MT76_STATE_RUNNING, &dev->mphy.state))16 return true;17 18 phy = mt7915_ext_phy(dev);19 20 return phy && test_bit(MT76_STATE_RUNNING, &phy->mt76->state);21}22 23int mt7915_run(struct ieee80211_hw *hw)24{25 struct mt7915_dev *dev = mt7915_hw_dev(hw);26 struct mt7915_phy *phy = mt7915_hw_phy(hw);27 bool running;28 int ret;29 30 running = mt7915_dev_running(dev);31 32 if (!running) {33 ret = mt76_connac_mcu_set_pm(&dev->mt76,34 dev->phy.mt76->band_idx, 0);35 if (ret)36 goto out;37 38 ret = mt7915_mcu_set_mac(dev, dev->phy.mt76->band_idx,39 true, true);40 if (ret)41 goto out;42 43 mt7915_mac_enable_nf(dev, dev->phy.mt76->band_idx);44 }45 46 if (phy != &dev->phy) {47 ret = mt76_connac_mcu_set_pm(&dev->mt76,48 phy->mt76->band_idx, 0);49 if (ret)50 goto out;51 52 ret = mt7915_mcu_set_mac(dev, phy->mt76->band_idx,53 true, true);54 if (ret)55 goto out;56 57 mt7915_mac_enable_nf(dev, phy->mt76->band_idx);58 }59 60 ret = mt7915_mcu_set_thermal_throttling(phy,61 MT7915_THERMAL_THROTTLE_MAX);62 63 if (ret)64 goto out;65 66 ret = mt7915_mcu_set_thermal_protect(phy);67 68 if (ret)69 goto out;70 71 ret = mt76_connac_mcu_set_rts_thresh(&dev->mt76, 0x92b,72 phy->mt76->band_idx);73 if (ret)74 goto out;75 76 ret = mt7915_mcu_set_sku_en(phy, true);77 if (ret)78 goto out;79 80 ret = mt7915_mcu_set_chan_info(phy, MCU_EXT_CMD(SET_RX_PATH));81 if (ret)82 goto out;83 84 set_bit(MT76_STATE_RUNNING, &phy->mt76->state);85 86 if (!mt76_testmode_enabled(phy->mt76))87 ieee80211_queue_delayed_work(hw, &phy->mt76->mac_work,88 MT7915_WATCHDOG_TIME);89 90 if (!running)91 mt7915_mac_reset_counters(phy);92 93out:94 return ret;95}96 97static int mt7915_start(struct ieee80211_hw *hw)98{99 struct mt7915_dev *dev = mt7915_hw_dev(hw);100 int ret;101 102 flush_work(&dev->init_work);103 104 mutex_lock(&dev->mt76.mutex);105 ret = mt7915_run(hw);106 mutex_unlock(&dev->mt76.mutex);107 108 return ret;109}110 111static void mt7915_stop(struct ieee80211_hw *hw, bool suspend)112{113 struct mt7915_dev *dev = mt7915_hw_dev(hw);114 struct mt7915_phy *phy = mt7915_hw_phy(hw);115 116 cancel_delayed_work_sync(&phy->mt76->mac_work);117 118 mutex_lock(&dev->mt76.mutex);119 120 mt76_testmode_reset(phy->mt76, true);121 122 clear_bit(MT76_STATE_RUNNING, &phy->mt76->state);123 124 if (phy != &dev->phy) {125 mt76_connac_mcu_set_pm(&dev->mt76, phy->mt76->band_idx, 1);126 mt7915_mcu_set_mac(dev, phy->mt76->band_idx, false, false);127 }128 129 if (!mt7915_dev_running(dev)) {130 mt76_connac_mcu_set_pm(&dev->mt76, dev->phy.mt76->band_idx, 1);131 mt7915_mcu_set_mac(dev, dev->phy.mt76->band_idx, false, false);132 }133 134 mutex_unlock(&dev->mt76.mutex);135}136 137static inline int get_free_idx(u32 mask, u8 start, u8 end)138{139 return ffs(~mask & GENMASK(end, start));140}141 142static int get_omac_idx(enum nl80211_iftype type, u64 mask)143{144 int i;145 146 switch (type) {147 case NL80211_IFTYPE_MESH_POINT:148 case NL80211_IFTYPE_ADHOC:149 case NL80211_IFTYPE_STATION:150 /* prefer hw bssid slot 1-3 */151 i = get_free_idx(mask, HW_BSSID_1, HW_BSSID_3);152 if (i)153 return i - 1;154 155 if (type != NL80211_IFTYPE_STATION)156 break;157 158 i = get_free_idx(mask, EXT_BSSID_1, EXT_BSSID_MAX);159 if (i)160 return i - 1;161 162 if (~mask & BIT(HW_BSSID_0))163 return HW_BSSID_0;164 165 break;166 case NL80211_IFTYPE_MONITOR:167 case NL80211_IFTYPE_AP:168 /* ap uses hw bssid 0 and ext bssid */169 if (~mask & BIT(HW_BSSID_0))170 return HW_BSSID_0;171 172 i = get_free_idx(mask, EXT_BSSID_1, EXT_BSSID_MAX);173 if (i)174 return i - 1;175 176 break;177 default:178 WARN_ON(1);179 break;180 }181 182 return -1;183}184 185static void mt7915_init_bitrate_mask(struct ieee80211_vif *vif)186{187 struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv;188 int i;189 190 for (i = 0; i < ARRAY_SIZE(mvif->bitrate_mask.control); i++) {191 mvif->bitrate_mask.control[i].gi = NL80211_TXRATE_DEFAULT_GI;192 mvif->bitrate_mask.control[i].he_gi = 0xff;193 mvif->bitrate_mask.control[i].he_ltf = 0xff;194 mvif->bitrate_mask.control[i].legacy = GENMASK(31, 0);195 memset(mvif->bitrate_mask.control[i].ht_mcs, 0xff,196 sizeof(mvif->bitrate_mask.control[i].ht_mcs));197 memset(mvif->bitrate_mask.control[i].vht_mcs, 0xff,198 sizeof(mvif->bitrate_mask.control[i].vht_mcs));199 memset(mvif->bitrate_mask.control[i].he_mcs, 0xff,200 sizeof(mvif->bitrate_mask.control[i].he_mcs));201 }202}203 204static int mt7915_add_interface(struct ieee80211_hw *hw,205 struct ieee80211_vif *vif)206{207 struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv;208 struct mt7915_dev *dev = mt7915_hw_dev(hw);209 struct mt7915_phy *phy = mt7915_hw_phy(hw);210 struct mt76_txq *mtxq;211 bool ext_phy = phy != &dev->phy;212 int idx, ret = 0;213 214 mutex_lock(&dev->mt76.mutex);215 216 mt76_testmode_reset(phy->mt76, true);217 218 if (vif->type == NL80211_IFTYPE_MONITOR &&219 is_zero_ether_addr(vif->addr))220 phy->monitor_vif = vif;221 222 mvif->mt76.idx = __ffs64(~dev->mt76.vif_mask);223 if (mvif->mt76.idx >= (MT7915_MAX_INTERFACES << dev->dbdc_support)) {224 ret = -ENOSPC;225 goto out;226 }227 228 idx = get_omac_idx(vif->type, phy->omac_mask);229 if (idx < 0) {230 ret = -ENOSPC;231 goto out;232 }233 mvif->mt76.omac_idx = idx;234 mvif->phy = phy;235 mvif->mt76.band_idx = phy->mt76->band_idx;236 237 mvif->mt76.wmm_idx = vif->type != NL80211_IFTYPE_AP;238 if (ext_phy)239 mvif->mt76.wmm_idx += 2;240 241 ret = mt7915_mcu_add_dev_info(phy, vif, true);242 if (ret)243 goto out;244 245 dev->mt76.vif_mask |= BIT_ULL(mvif->mt76.idx);246 phy->omac_mask |= BIT_ULL(mvif->mt76.omac_idx);247 248 idx = mt76_wcid_alloc(dev->mt76.wcid_mask, mt7915_wtbl_size(dev));249 if (idx < 0)250 return -ENOSPC;251 252 INIT_LIST_HEAD(&mvif->sta.rc_list);253 INIT_LIST_HEAD(&mvif->sta.wcid.poll_list);254 mvif->sta.wcid.idx = idx;255 mvif->sta.wcid.phy_idx = ext_phy;256 mvif->sta.wcid.hw_key_idx = -1;257 mvif->sta.wcid.tx_info |= MT_WCID_TX_INFO_SET;258 mt76_wcid_init(&mvif->sta.wcid);259 260 mt7915_mac_wtbl_update(dev, idx,261 MT_WTBL_UPDATE_ADM_COUNT_CLEAR);262 263 if (vif->txq) {264 mtxq = (struct mt76_txq *)vif->txq->drv_priv;265 mtxq->wcid = idx;266 }267 268 if (vif->type != NL80211_IFTYPE_AP &&269 (!mvif->mt76.omac_idx || mvif->mt76.omac_idx > 3))270 vif->offload_flags = 0;271 vif->offload_flags |= IEEE80211_OFFLOAD_ENCAP_4ADDR;272 273 mt7915_init_bitrate_mask(vif);274 memset(&mvif->cap, -1, sizeof(mvif->cap));275 276 mt7915_mcu_add_bss_info(phy, vif, true);277 mt7915_mcu_add_sta(dev, vif, NULL, CONN_STATE_PORT_SECURE, true);278 rcu_assign_pointer(dev->mt76.wcid[idx], &mvif->sta.wcid);279 280out:281 mutex_unlock(&dev->mt76.mutex);282 283 return ret;284}285 286static void mt7915_remove_interface(struct ieee80211_hw *hw,287 struct ieee80211_vif *vif)288{289 struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv;290 struct mt7915_sta *msta = &mvif->sta;291 struct mt7915_dev *dev = mt7915_hw_dev(hw);292 struct mt7915_phy *phy = mt7915_hw_phy(hw);293 int idx = msta->wcid.idx;294 295 mt7915_mcu_add_bss_info(phy, vif, false);296 mt7915_mcu_add_sta(dev, vif, NULL, CONN_STATE_DISCONNECT, false);297 mt76_wcid_mask_clear(dev->mt76.wcid_mask, mvif->sta.wcid.idx);298 299 mutex_lock(&dev->mt76.mutex);300 mt76_testmode_reset(phy->mt76, true);301 mutex_unlock(&dev->mt76.mutex);302 303 if (vif == phy->monitor_vif)304 phy->monitor_vif = NULL;305 306 mt7915_mcu_add_dev_info(phy, vif, false);307 308 rcu_assign_pointer(dev->mt76.wcid[idx], NULL);309 310 mutex_lock(&dev->mt76.mutex);311 dev->mt76.vif_mask &= ~BIT_ULL(mvif->mt76.idx);312 phy->omac_mask &= ~BIT_ULL(mvif->mt76.omac_idx);313 mutex_unlock(&dev->mt76.mutex);314 315 spin_lock_bh(&dev->mt76.sta_poll_lock);316 if (!list_empty(&msta->wcid.poll_list))317 list_del_init(&msta->wcid.poll_list);318 spin_unlock_bh(&dev->mt76.sta_poll_lock);319 320 mt76_wcid_cleanup(&dev->mt76, &msta->wcid);321}322 323int mt7915_set_channel(struct mt76_phy *mphy)324{325 struct mt7915_phy *phy = mphy->priv;326 struct mt7915_dev *dev = phy->dev;327 int ret;328 329 if (dev->cal) {330 ret = mt7915_mcu_apply_tx_dpd(phy);331 if (ret)332 goto out;333 }334 335 ret = mt7915_mcu_set_chan_info(phy, MCU_EXT_CMD(CHANNEL_SWITCH));336 if (ret)337 goto out;338 339 mt7915_mac_set_timing(phy);340 ret = mt7915_dfs_init_radar_detector(phy);341 mt7915_mac_cca_stats_reset(phy);342 343 mt7915_mac_reset_counters(phy);344 phy->noise = 0;345 346out:347 if (!mt76_testmode_enabled(phy->mt76))348 ieee80211_queue_delayed_work(phy->mt76->hw,349 &phy->mt76->mac_work,350 MT7915_WATCHDOG_TIME);351 352 return ret;353}354 355static int mt7915_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,356 struct ieee80211_vif *vif, struct ieee80211_sta *sta,357 struct ieee80211_key_conf *key)358{359 struct mt7915_dev *dev = mt7915_hw_dev(hw);360 struct mt7915_phy *phy = mt7915_hw_phy(hw);361 struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv;362 struct mt7915_sta *msta = sta ? (struct mt7915_sta *)sta->drv_priv :363 &mvif->sta;364 struct mt76_wcid *wcid = &msta->wcid;365 u8 *wcid_keyidx = &wcid->hw_key_idx;366 int idx = key->keyidx;367 int err = 0;368 369 if (sta && !wcid->sta)370 return -EOPNOTSUPP;371 372 /* The hardware does not support per-STA RX GTK, fallback373 * to software mode for these.374 */375 if ((vif->type == NL80211_IFTYPE_ADHOC ||376 vif->type == NL80211_IFTYPE_MESH_POINT) &&377 (key->cipher == WLAN_CIPHER_SUITE_TKIP ||378 key->cipher == WLAN_CIPHER_SUITE_CCMP) &&379 !(key->flags & IEEE80211_KEY_FLAG_PAIRWISE))380 return -EOPNOTSUPP;381 382 /* fall back to sw encryption for unsupported ciphers */383 switch (key->cipher) {384 case WLAN_CIPHER_SUITE_AES_CMAC:385 wcid_keyidx = &wcid->hw_key_idx2;386 key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIE;387 break;388 case WLAN_CIPHER_SUITE_TKIP:389 case WLAN_CIPHER_SUITE_CCMP:390 case WLAN_CIPHER_SUITE_CCMP_256:391 case WLAN_CIPHER_SUITE_GCMP:392 case WLAN_CIPHER_SUITE_GCMP_256:393 case WLAN_CIPHER_SUITE_SMS4:394 break;395 case WLAN_CIPHER_SUITE_WEP40:396 case WLAN_CIPHER_SUITE_WEP104:397 default:398 return -EOPNOTSUPP;399 }400 401 mutex_lock(&dev->mt76.mutex);402 403 if (cmd == SET_KEY && !sta && !mvif->mt76.cipher) {404 mvif->mt76.cipher = mt76_connac_mcu_get_cipher(key->cipher);405 mt7915_mcu_add_bss_info(phy, vif, true);406 }407 408 if (cmd == SET_KEY) {409 *wcid_keyidx = idx;410 } else {411 if (idx == *wcid_keyidx)412 *wcid_keyidx = -1;413 goto out;414 }415 416 mt76_wcid_key_setup(&dev->mt76, wcid, key);417 err = mt76_connac_mcu_add_key(&dev->mt76, vif, &msta->bip,418 key, MCU_EXT_CMD(STA_REC_UPDATE),419 &msta->wcid, cmd);420out:421 mutex_unlock(&dev->mt76.mutex);422 423 return err;424}425 426static int mt7915_set_sar_specs(struct ieee80211_hw *hw,427 const struct cfg80211_sar_specs *sar)428{429 struct mt7915_phy *phy = mt7915_hw_phy(hw);430 struct mt7915_dev *dev = mt7915_hw_dev(hw);431 int err = -EINVAL;432 433 mutex_lock(&dev->mt76.mutex);434 if (!cfg80211_chandef_valid(&phy->mt76->chandef))435 goto out;436 437 err = mt76_init_sar_power(hw, sar);438 if (err)439 goto out;440 441 err = mt7915_mcu_set_txpower_sku(phy);442out:443 mutex_unlock(&dev->mt76.mutex);444 445 return err;446}447 448static int mt7915_config(struct ieee80211_hw *hw, u32 changed)449{450 struct mt7915_dev *dev = mt7915_hw_dev(hw);451 struct mt7915_phy *phy = mt7915_hw_phy(hw);452 int ret;453 454 if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {455#ifdef CONFIG_NL80211_TESTMODE456 if (phy->mt76->test.state != MT76_TM_STATE_OFF) {457 mutex_lock(&dev->mt76.mutex);458 mt76_testmode_reset(phy->mt76, false);459 mutex_unlock(&dev->mt76.mutex);460 }461#endif462 ret = mt76_update_channel(phy->mt76);463 if (ret)464 return ret;465 }466 467 if (changed & (IEEE80211_CONF_CHANGE_POWER |468 IEEE80211_CONF_CHANGE_CHANNEL)) {469 ret = mt7915_mcu_set_txpower_sku(phy);470 if (ret)471 return ret;472 }473 474 mutex_lock(&dev->mt76.mutex);475 476 if (changed & IEEE80211_CONF_CHANGE_MONITOR) {477 bool enabled = !!(hw->conf.flags & IEEE80211_CONF_MONITOR);478 bool band = phy->mt76->band_idx;479 u32 rxfilter = phy->rxfilter;480 481 if (!enabled) {482 rxfilter |= MT_WF_RFCR_DROP_OTHER_UC;483 dev->monitor_mask &= ~BIT(band);484 } else {485 rxfilter &= ~MT_WF_RFCR_DROP_OTHER_UC;486 dev->monitor_mask |= BIT(band);487 }488 489 mt76_rmw_field(dev, MT_DMA_DCR0(band), MT_DMA_DCR0_RXD_G5_EN,490 enabled);491 mt76_rmw_field(dev, MT_DMA_DCR0(band), MT_MDP_DCR0_RX_HDR_TRANS_EN,492 !dev->monitor_mask);493 mt76_testmode_reset(phy->mt76, true);494 mt76_wr(dev, MT_WF_RFCR(band), rxfilter);495 }496 497 mutex_unlock(&dev->mt76.mutex);498 499 return 0;500}501 502static int503mt7915_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif,504 unsigned int link_id, u16 queue,505 const struct ieee80211_tx_queue_params *params)506{507 struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv;508 509 /* no need to update right away, we'll get BSS_CHANGED_QOS */510 queue = mt76_connac_lmac_mapping(queue);511 mvif->queue_params[queue] = *params;512 513 return 0;514}515 516static void mt7915_configure_filter(struct ieee80211_hw *hw,517 unsigned int changed_flags,518 unsigned int *total_flags,519 u64 multicast)520{521 struct mt7915_dev *dev = mt7915_hw_dev(hw);522 struct mt7915_phy *phy = mt7915_hw_phy(hw);523 bool band = phy->mt76->band_idx;524 u32 ctl_flags = MT_WF_RFCR1_DROP_ACK |525 MT_WF_RFCR1_DROP_BF_POLL |526 MT_WF_RFCR1_DROP_BA |527 MT_WF_RFCR1_DROP_CFEND |528 MT_WF_RFCR1_DROP_CFACK;529 u32 rxfilter;530 u32 flags = 0;531 532#define MT76_FILTER(_flag, _hw) do { \533 flags |= *total_flags & FIF_##_flag; \534 phy->rxfilter &= ~(_hw); \535 phy->rxfilter |= !(flags & FIF_##_flag) * (_hw); \536 } while (0)537 538 mutex_lock(&dev->mt76.mutex);539 540 phy->rxfilter &= ~(MT_WF_RFCR_DROP_OTHER_BSS |541 MT_WF_RFCR_DROP_OTHER_BEACON |542 MT_WF_RFCR_DROP_FRAME_REPORT |543 MT_WF_RFCR_DROP_PROBEREQ |544 MT_WF_RFCR_DROP_MCAST_FILTERED |545 MT_WF_RFCR_DROP_MCAST |546 MT_WF_RFCR_DROP_BCAST |547 MT_WF_RFCR_DROP_DUPLICATE |548 MT_WF_RFCR_DROP_A2_BSSID |549 MT_WF_RFCR_DROP_UNWANTED_CTL |550 MT_WF_RFCR_DROP_STBC_MULTI);551 552 MT76_FILTER(OTHER_BSS, MT_WF_RFCR_DROP_OTHER_TIM |553 MT_WF_RFCR_DROP_A3_MAC |554 MT_WF_RFCR_DROP_A3_BSSID);555 556 MT76_FILTER(FCSFAIL, MT_WF_RFCR_DROP_FCSFAIL);557 558 MT76_FILTER(CONTROL, MT_WF_RFCR_DROP_CTS |559 MT_WF_RFCR_DROP_RTS |560 MT_WF_RFCR_DROP_CTL_RSV);561 562 *total_flags = flags;563 rxfilter = phy->rxfilter;564 if (hw->conf.flags & IEEE80211_CONF_MONITOR)565 rxfilter &= ~MT_WF_RFCR_DROP_OTHER_UC;566 else567 rxfilter |= MT_WF_RFCR_DROP_OTHER_UC;568 mt76_wr(dev, MT_WF_RFCR(band), rxfilter);569 570 if (*total_flags & FIF_CONTROL)571 mt76_clear(dev, MT_WF_RFCR1(band), ctl_flags);572 else573 mt76_set(dev, MT_WF_RFCR1(band), ctl_flags);574 575 mutex_unlock(&dev->mt76.mutex);576}577 578static void579mt7915_update_bss_color(struct ieee80211_hw *hw,580 struct ieee80211_vif *vif,581 struct cfg80211_he_bss_color *bss_color)582{583 struct mt7915_dev *dev = mt7915_hw_dev(hw);584 585 switch (vif->type) {586 case NL80211_IFTYPE_AP: {587 struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv;588 589 if (mvif->mt76.omac_idx > HW_BSSID_MAX)590 return;591 fallthrough;592 }593 case NL80211_IFTYPE_STATION:594 mt7915_mcu_update_bss_color(dev, vif, bss_color);595 break;596 default:597 break;598 }599}600 601static void mt7915_bss_info_changed(struct ieee80211_hw *hw,602 struct ieee80211_vif *vif,603 struct ieee80211_bss_conf *info,604 u64 changed)605{606 struct mt7915_phy *phy = mt7915_hw_phy(hw);607 struct mt7915_dev *dev = mt7915_hw_dev(hw);608 int set_bss_info = -1, set_sta = -1;609 610 mutex_lock(&dev->mt76.mutex);611 612 /*613 * station mode uses BSSID to map the wlan entry to a peer,614 * and then peer references bss_info_rfch to set bandwidth cap.615 */616 if (changed & BSS_CHANGED_BSSID &&617 vif->type == NL80211_IFTYPE_STATION)618 set_bss_info = set_sta = !is_zero_ether_addr(info->bssid);619 if (changed & BSS_CHANGED_ASSOC)620 set_bss_info = vif->cfg.assoc;621 if (changed & BSS_CHANGED_BEACON_ENABLED &&622 vif->type != NL80211_IFTYPE_AP)623 set_bss_info = set_sta = info->enable_beacon;624 625 if (set_bss_info == 1)626 mt7915_mcu_add_bss_info(phy, vif, true);627 if (set_sta == 1)628 mt7915_mcu_add_sta(dev, vif, NULL, CONN_STATE_PORT_SECURE, false);629 630 if (changed & BSS_CHANGED_ERP_CTS_PROT)631 mt7915_mac_enable_rtscts(dev, vif, info->use_cts_prot);632 633 if (changed & BSS_CHANGED_ERP_SLOT) {634 int slottime = info->use_short_slot ? 9 : 20;635 636 if (slottime != phy->slottime) {637 phy->slottime = slottime;638 mt7915_mac_set_timing(phy);639 }640 }641 642 /* ensure that enable txcmd_mode after bss_info */643 if (changed & (BSS_CHANGED_QOS | BSS_CHANGED_BEACON_ENABLED))644 mt7915_mcu_set_tx(dev, vif);645 646 if (changed & BSS_CHANGED_HE_OBSS_PD)647 mt7915_mcu_add_obss_spr(phy, vif, &info->he_obss_pd);648 649 if (changed & BSS_CHANGED_HE_BSS_COLOR)650 mt7915_update_bss_color(hw, vif, &info->he_bss_color);651 652 if (changed & (BSS_CHANGED_BEACON |653 BSS_CHANGED_BEACON_ENABLED))654 mt7915_mcu_add_beacon(hw, vif, info->enable_beacon, changed);655 656 if (changed & (BSS_CHANGED_UNSOL_BCAST_PROBE_RESP |657 BSS_CHANGED_FILS_DISCOVERY))658 mt7915_mcu_add_inband_discov(dev, vif, changed);659 660 if (set_bss_info == 0)661 mt7915_mcu_add_bss_info(phy, vif, false);662 if (set_sta == 0)663 mt7915_mcu_add_sta(dev, vif, NULL, CONN_STATE_DISCONNECT, false);664 665 mutex_unlock(&dev->mt76.mutex);666}667 668static void669mt7915_vif_check_caps(struct mt7915_phy *phy, struct ieee80211_vif *vif)670{671 struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv;672 struct mt7915_vif_cap *vc = &mvif->cap;673 674 vc->ht_ldpc = vif->bss_conf.ht_ldpc;675 vc->vht_ldpc = vif->bss_conf.vht_ldpc;676 vc->vht_su_ebfer = vif->bss_conf.vht_su_beamformer;677 vc->vht_su_ebfee = vif->bss_conf.vht_su_beamformee;678 vc->vht_mu_ebfer = vif->bss_conf.vht_mu_beamformer;679 vc->vht_mu_ebfee = vif->bss_conf.vht_mu_beamformee;680 vc->he_ldpc = vif->bss_conf.he_ldpc;681 vc->he_su_ebfer = vif->bss_conf.he_su_beamformer;682 vc->he_su_ebfee = vif->bss_conf.he_su_beamformee;683 vc->he_mu_ebfer = vif->bss_conf.he_mu_beamformer;684}685 686static int687mt7915_start_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif,688 struct ieee80211_bss_conf *link_conf)689{690 struct mt7915_phy *phy = mt7915_hw_phy(hw);691 struct mt7915_dev *dev = mt7915_hw_dev(hw);692 int err;693 694 mutex_lock(&dev->mt76.mutex);695 696 mt7915_vif_check_caps(phy, vif);697 698 err = mt7915_mcu_add_bss_info(phy, vif, true);699 if (err)700 goto out;701 err = mt7915_mcu_add_sta(dev, vif, NULL, CONN_STATE_PORT_SECURE, false);702out:703 mutex_unlock(&dev->mt76.mutex);704 705 return err;706}707 708static void709mt7915_stop_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif,710 struct ieee80211_bss_conf *link_conf)711{712 struct mt7915_dev *dev = mt7915_hw_dev(hw);713 714 mutex_lock(&dev->mt76.mutex);715 mt7915_mcu_add_sta(dev, vif, NULL, CONN_STATE_DISCONNECT, false);716 mutex_unlock(&dev->mt76.mutex);717}718 719static void720mt7915_channel_switch_beacon(struct ieee80211_hw *hw,721 struct ieee80211_vif *vif,722 struct cfg80211_chan_def *chandef)723{724 struct mt7915_dev *dev = mt7915_hw_dev(hw);725 726 mutex_lock(&dev->mt76.mutex);727 mt7915_mcu_add_beacon(hw, vif, true, BSS_CHANGED_BEACON);728 mutex_unlock(&dev->mt76.mutex);729}730 731int mt7915_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,732 struct ieee80211_sta *sta)733{734 struct mt7915_dev *dev = container_of(mdev, struct mt7915_dev, mt76);735 struct mt7915_sta *msta = (struct mt7915_sta *)sta->drv_priv;736 struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv;737 bool ext_phy = mvif->phy != &dev->phy;738 int idx;739 740 idx = mt76_wcid_alloc(dev->mt76.wcid_mask, MT7915_WTBL_STA);741 if (idx < 0)742 return -ENOSPC;743 744 INIT_LIST_HEAD(&msta->rc_list);745 INIT_LIST_HEAD(&msta->wcid.poll_list);746 msta->vif = mvif;747 msta->wcid.sta_disabled = 1;748 msta->wcid.idx = idx;749 msta->wcid.phy_idx = ext_phy;750 msta->jiffies = jiffies;751 752 ewma_avg_signal_init(&msta->avg_ack_signal);753 754 mt7915_mac_wtbl_update(dev, idx,755 MT_WTBL_UPDATE_ADM_COUNT_CLEAR);756 mt7915_mcu_add_sta(dev, vif, sta, CONN_STATE_DISCONNECT, true);757 758 return 0;759}760 761int mt7915_mac_sta_event(struct mt76_dev *mdev, struct ieee80211_vif *vif,762 struct ieee80211_sta *sta, enum mt76_sta_event ev)763{764 struct mt7915_dev *dev = container_of(mdev, struct mt7915_dev, mt76);765 struct mt7915_sta *msta = (struct mt7915_sta *)sta->drv_priv;766 int i, ret;767 u32 addr;768 769 switch (ev) {770 case MT76_STA_EVENT_ASSOC:771 ret = mt7915_mcu_add_sta(dev, vif, sta, CONN_STATE_CONNECT, true);772 if (ret)773 return ret;774 775 addr = mt7915_mac_wtbl_lmac_addr(dev, msta->wcid.idx, 30);776 mt76_rmw_field(dev, addr, GENMASK(7, 0), 0xa0);777 778 ret = mt7915_mcu_add_rate_ctrl(dev, vif, sta, false);779 if (ret)780 return ret;781 782 msta->wcid.tx_info |= MT_WCID_TX_INFO_SET;783 msta->wcid.sta = 1;784 msta->wcid.sta_disabled = 0;785 786 return 0;787 788 case MT76_STA_EVENT_AUTHORIZE:789 return mt7915_mcu_add_sta(dev, vif, sta, CONN_STATE_PORT_SECURE, false);790 791 case MT76_STA_EVENT_DISASSOC:792 for (i = 0; i < ARRAY_SIZE(msta->twt.flow); i++)793 mt7915_mac_twt_teardown_flow(dev, msta, i);794 795 mt7915_mcu_add_sta(dev, vif, sta, CONN_STATE_DISCONNECT, false);796 msta->wcid.sta_disabled = 1;797 msta->wcid.sta = 0;798 return 0;799 }800 801 return 0;802}803 804void mt7915_mac_sta_remove(struct mt76_dev *mdev, struct ieee80211_vif *vif,805 struct ieee80211_sta *sta)806{807 struct mt7915_dev *dev = container_of(mdev, struct mt7915_dev, mt76);808 struct mt7915_sta *msta = (struct mt7915_sta *)sta->drv_priv;809 810 mt7915_mac_wtbl_update(dev, msta->wcid.idx,811 MT_WTBL_UPDATE_ADM_COUNT_CLEAR);812 813 spin_lock_bh(&mdev->sta_poll_lock);814 if (!list_empty(&msta->wcid.poll_list))815 list_del_init(&msta->wcid.poll_list);816 if (!list_empty(&msta->rc_list))817 list_del_init(&msta->rc_list);818 spin_unlock_bh(&mdev->sta_poll_lock);819}820 821static void mt7915_tx(struct ieee80211_hw *hw,822 struct ieee80211_tx_control *control,823 struct sk_buff *skb)824{825 struct mt7915_dev *dev = mt7915_hw_dev(hw);826 struct mt76_phy *mphy = hw->priv;827 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);828 struct ieee80211_vif *vif = info->control.vif;829 struct mt76_wcid *wcid = &dev->mt76.global_wcid;830 831 if (control->sta) {832 struct mt7915_sta *sta;833 834 sta = (struct mt7915_sta *)control->sta->drv_priv;835 wcid = &sta->wcid;836 }837 838 if (vif && !control->sta) {839 struct mt7915_vif *mvif;840 841 mvif = (struct mt7915_vif *)vif->drv_priv;842 wcid = &mvif->sta.wcid;843 }844 845 mt76_tx(mphy, control->sta, wcid, skb);846}847 848static int mt7915_set_rts_threshold(struct ieee80211_hw *hw, u32 val)849{850 struct mt7915_dev *dev = mt7915_hw_dev(hw);851 struct mt7915_phy *phy = mt7915_hw_phy(hw);852 int ret;853 854 mutex_lock(&dev->mt76.mutex);855 ret = mt76_connac_mcu_set_rts_thresh(&dev->mt76, val,856 phy->mt76->band_idx);857 mutex_unlock(&dev->mt76.mutex);858 859 return ret;860}861 862static int863mt7915_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,864 struct ieee80211_ampdu_params *params)865{866 enum ieee80211_ampdu_mlme_action action = params->action;867 struct mt7915_dev *dev = mt7915_hw_dev(hw);868 struct ieee80211_sta *sta = params->sta;869 struct ieee80211_txq *txq = sta->txq[params->tid];870 struct mt7915_sta *msta = (struct mt7915_sta *)sta->drv_priv;871 u16 tid = params->tid;872 u16 ssn = params->ssn;873 struct mt76_txq *mtxq;874 int ret = 0;875 876 if (!txq)877 return -EINVAL;878 879 mtxq = (struct mt76_txq *)txq->drv_priv;880 881 mutex_lock(&dev->mt76.mutex);882 switch (action) {883 case IEEE80211_AMPDU_RX_START:884 mt76_rx_aggr_start(&dev->mt76, &msta->wcid, tid, ssn,885 params->buf_size);886 ret = mt7915_mcu_add_rx_ba(dev, params, true);887 break;888 case IEEE80211_AMPDU_RX_STOP:889 mt76_rx_aggr_stop(&dev->mt76, &msta->wcid, tid);890 ret = mt7915_mcu_add_rx_ba(dev, params, false);891 break;892 case IEEE80211_AMPDU_TX_OPERATIONAL:893 mtxq->aggr = true;894 mtxq->send_bar = false;895 ret = mt7915_mcu_add_tx_ba(dev, params, true);896 break;897 case IEEE80211_AMPDU_TX_STOP_FLUSH:898 case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT:899 mtxq->aggr = false;900 clear_bit(tid, &msta->wcid.ampdu_state);901 ret = mt7915_mcu_add_tx_ba(dev, params, false);902 break;903 case IEEE80211_AMPDU_TX_START:904 set_bit(tid, &msta->wcid.ampdu_state);905 ret = IEEE80211_AMPDU_TX_START_IMMEDIATE;906 break;907 case IEEE80211_AMPDU_TX_STOP_CONT:908 mtxq->aggr = false;909 clear_bit(tid, &msta->wcid.ampdu_state);910 ret = mt7915_mcu_add_tx_ba(dev, params, false);911 ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid);912 break;913 }914 mutex_unlock(&dev->mt76.mutex);915 916 return ret;917}918 919static int920mt7915_get_stats(struct ieee80211_hw *hw,921 struct ieee80211_low_level_stats *stats)922{923 struct mt7915_phy *phy = mt7915_hw_phy(hw);924 struct mt7915_dev *dev = mt7915_hw_dev(hw);925 struct mt76_mib_stats *mib = &phy->mib;926 927 mutex_lock(&dev->mt76.mutex);928 929 stats->dot11RTSSuccessCount = mib->rts_cnt;930 stats->dot11RTSFailureCount = mib->rts_retries_cnt;931 stats->dot11FCSErrorCount = mib->fcs_err_cnt;932 stats->dot11ACKFailureCount = mib->ack_fail_cnt;933 934 mutex_unlock(&dev->mt76.mutex);935 936 return 0;937}938 939u64 __mt7915_get_tsf(struct ieee80211_hw *hw, struct mt7915_vif *mvif)940{941 struct mt7915_dev *dev = mt7915_hw_dev(hw);942 struct mt7915_phy *phy = mt7915_hw_phy(hw);943 bool band = phy->mt76->band_idx;944 union {945 u64 t64;946 u32 t32[2];947 } tsf;948 u16 n;949 950 lockdep_assert_held(&dev->mt76.mutex);951 952 n = mvif->mt76.omac_idx > HW_BSSID_MAX ? HW_BSSID_0953 : mvif->mt76.omac_idx;954 /* TSF software read */955 if (is_mt7915(&dev->mt76))956 mt76_rmw(dev, MT_LPON_TCR(band, n), MT_LPON_TCR_SW_MODE,957 MT_LPON_TCR_SW_READ);958 else959 mt76_rmw(dev, MT_LPON_TCR_MT7916(band, n), MT_LPON_TCR_SW_MODE,960 MT_LPON_TCR_SW_READ);961 tsf.t32[0] = mt76_rr(dev, MT_LPON_UTTR0(band));962 tsf.t32[1] = mt76_rr(dev, MT_LPON_UTTR1(band));963 964 return tsf.t64;965}966 967static u64968mt7915_get_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif)969{970 struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv;971 struct mt7915_dev *dev = mt7915_hw_dev(hw);972 u64 ret;973 974 mutex_lock(&dev->mt76.mutex);975 ret = __mt7915_get_tsf(hw, mvif);976 mutex_unlock(&dev->mt76.mutex);977 978 return ret;979}980 981static void982mt7915_set_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif,983 u64 timestamp)984{985 struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv;986 struct mt7915_dev *dev = mt7915_hw_dev(hw);987 struct mt7915_phy *phy = mt7915_hw_phy(hw);988 bool band = phy->mt76->band_idx;989 union {990 u64 t64;991 u32 t32[2];992 } tsf = { .t64 = timestamp, };993 u16 n;994 995 mutex_lock(&dev->mt76.mutex);996 997 n = mvif->mt76.omac_idx > HW_BSSID_MAX ? HW_BSSID_0998 : mvif->mt76.omac_idx;999 mt76_wr(dev, MT_LPON_UTTR0(band), tsf.t32[0]);1000 mt76_wr(dev, MT_LPON_UTTR1(band), tsf.t32[1]);1001 /* TSF software overwrite */1002 if (is_mt7915(&dev->mt76))1003 mt76_rmw(dev, MT_LPON_TCR(band, n), MT_LPON_TCR_SW_MODE,1004 MT_LPON_TCR_SW_WRITE);1005 else1006 mt76_rmw(dev, MT_LPON_TCR_MT7916(band, n), MT_LPON_TCR_SW_MODE,1007 MT_LPON_TCR_SW_WRITE);1008 1009 mutex_unlock(&dev->mt76.mutex);1010}1011 1012static void1013mt7915_offset_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif,1014 s64 timestamp)1015{1016 struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv;1017 struct mt7915_dev *dev = mt7915_hw_dev(hw);1018 struct mt7915_phy *phy = mt7915_hw_phy(hw);1019 bool band = phy->mt76->band_idx;1020 union {1021 u64 t64;1022 u32 t32[2];1023 } tsf = { .t64 = timestamp, };1024 u16 n;1025 1026 mutex_lock(&dev->mt76.mutex);1027 1028 n = mvif->mt76.omac_idx > HW_BSSID_MAX ? HW_BSSID_01029 : mvif->mt76.omac_idx;1030 mt76_wr(dev, MT_LPON_UTTR0(band), tsf.t32[0]);1031 mt76_wr(dev, MT_LPON_UTTR1(band), tsf.t32[1]);1032 /* TSF software adjust*/1033 if (is_mt7915(&dev->mt76))1034 mt76_rmw(dev, MT_LPON_TCR(band, n), MT_LPON_TCR_SW_MODE,1035 MT_LPON_TCR_SW_ADJUST);1036 else1037 mt76_rmw(dev, MT_LPON_TCR_MT7916(band, n), MT_LPON_TCR_SW_MODE,1038 MT_LPON_TCR_SW_ADJUST);1039 1040 mutex_unlock(&dev->mt76.mutex);1041}1042 1043static void1044mt7915_set_coverage_class(struct ieee80211_hw *hw, s16 coverage_class)1045{1046 struct mt7915_phy *phy = mt7915_hw_phy(hw);1047 struct mt7915_dev *dev = phy->dev;1048 1049 mutex_lock(&dev->mt76.mutex);1050 phy->coverage_class = max_t(s16, coverage_class, 0);1051 mt7915_mac_set_timing(phy);1052 mutex_unlock(&dev->mt76.mutex);1053}1054 1055static int1056mt7915_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant)1057{1058 struct mt7915_dev *dev = mt7915_hw_dev(hw);1059 struct mt7915_phy *phy = mt7915_hw_phy(hw);1060 int max_nss = hweight8(hw->wiphy->available_antennas_tx);1061 u8 chainshift = dev->chainshift;1062 u8 band = phy->mt76->band_idx;1063 1064 if (!tx_ant || tx_ant != rx_ant || ffs(tx_ant) > max_nss)1065 return -EINVAL;1066 1067 mutex_lock(&dev->mt76.mutex);1068 1069 phy->mt76->antenna_mask = tx_ant;1070 1071 /* handle a variant of mt7916/mt7981 which has 3T3R but nss2 on 5 GHz band */1072 if ((is_mt7916(&dev->mt76) || is_mt7981(&dev->mt76)) &&1073 band && hweight8(tx_ant) == max_nss)1074 phy->mt76->chainmask = (dev->chainmask >> chainshift) << chainshift;1075 else1076 phy->mt76->chainmask = tx_ant << (chainshift * band);1077 1078 mt76_set_stream_caps(phy->mt76, true);1079 mt7915_set_stream_vht_txbf_caps(phy);1080 mt7915_set_stream_he_caps(phy);1081 1082 mutex_unlock(&dev->mt76.mutex);1083 1084 return 0;1085}1086 1087static void mt7915_sta_statistics(struct ieee80211_hw *hw,1088 struct ieee80211_vif *vif,1089 struct ieee80211_sta *sta,1090 struct station_info *sinfo)1091{1092 struct mt7915_phy *phy = mt7915_hw_phy(hw);1093 struct mt7915_sta *msta = (struct mt7915_sta *)sta->drv_priv;1094 struct rate_info *txrate = &msta->wcid.rate;1095 struct rate_info rxrate = {};1096 1097 if (!mt7915_mcu_get_rx_rate(phy, vif, sta, &rxrate)) {1098 sinfo->rxrate = rxrate;1099 sinfo->filled |= BIT_ULL(NL80211_STA_INFO_RX_BITRATE);1100 }1101 1102 if (txrate->legacy || txrate->flags) {1103 if (txrate->legacy) {1104 sinfo->txrate.legacy = txrate->legacy;1105 } else {1106 sinfo->txrate.mcs = txrate->mcs;1107 sinfo->txrate.nss = txrate->nss;1108 sinfo->txrate.bw = txrate->bw;1109 sinfo->txrate.he_gi = txrate->he_gi;1110 sinfo->txrate.he_dcm = txrate->he_dcm;1111 sinfo->txrate.he_ru_alloc = txrate->he_ru_alloc;1112 }1113 sinfo->txrate.flags = txrate->flags;1114 sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BITRATE);1115 }1116 1117 /* offloading flows bypass networking stack, so driver counts and1118 * reports sta statistics via NL80211_STA_INFO when WED is active.1119 */1120 if (mtk_wed_device_active(&phy->dev->mt76.mmio.wed)) {1121 sinfo->tx_bytes = msta->wcid.stats.tx_bytes;1122 sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BYTES64);1123 1124 if (!mt7915_mcu_wed_wa_tx_stats(phy->dev, msta->wcid.idx)) {1125 sinfo->tx_packets = msta->wcid.stats.tx_packets;1126 sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_PACKETS);1127 }1128 1129 if (mtk_wed_get_rx_capa(&phy->dev->mt76.mmio.wed)) {1130 sinfo->rx_bytes = msta->wcid.stats.rx_bytes;1131 sinfo->filled |= BIT_ULL(NL80211_STA_INFO_RX_BYTES64);1132 1133 sinfo->rx_packets = msta->wcid.stats.rx_packets;1134 sinfo->filled |= BIT_ULL(NL80211_STA_INFO_RX_PACKETS);1135 }1136 }1137 1138 sinfo->tx_failed = msta->wcid.stats.tx_failed;1139 sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_FAILED);1140 1141 sinfo->tx_retries = msta->wcid.stats.tx_retries;1142 sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_RETRIES);1143 1144 sinfo->ack_signal = (s8)msta->ack_signal;1145 sinfo->filled |= BIT_ULL(NL80211_STA_INFO_ACK_SIGNAL);1146 1147 sinfo->avg_ack_signal = -(s8)ewma_avg_signal_read(&msta->avg_ack_signal);1148 sinfo->filled |= BIT_ULL(NL80211_STA_INFO_ACK_SIGNAL_AVG);1149}1150 1151static void mt7915_sta_rc_work(void *data, struct ieee80211_sta *sta)1152{1153 struct mt7915_sta *msta = (struct mt7915_sta *)sta->drv_priv;1154 struct mt7915_dev *dev = msta->vif->phy->dev;1155 u32 *changed = data;1156 1157 spin_lock_bh(&dev->mt76.sta_poll_lock);1158 msta->changed |= *changed;1159 if (list_empty(&msta->rc_list))1160 list_add_tail(&msta->rc_list, &dev->sta_rc_list);1161 spin_unlock_bh(&dev->mt76.sta_poll_lock);1162}1163 1164static void mt7915_sta_rc_update(struct ieee80211_hw *hw,1165 struct ieee80211_vif *vif,1166 struct ieee80211_sta *sta,1167 u32 changed)1168{1169 struct mt7915_phy *phy = mt7915_hw_phy(hw);1170 struct mt7915_dev *dev = phy->dev;1171 struct mt7915_sta *msta = (struct mt7915_sta *)sta->drv_priv;1172 1173 if (!msta->wcid.sta)1174 return;1175 1176 mt7915_sta_rc_work(&changed, sta);1177 ieee80211_queue_work(hw, &dev->rc_work);1178}1179 1180static int1181mt7915_set_bitrate_mask(struct ieee80211_hw *hw, struct ieee80211_vif *vif,1182 const struct cfg80211_bitrate_mask *mask)1183{1184 struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv;1185 struct mt7915_phy *phy = mt7915_hw_phy(hw);1186 struct mt7915_dev *dev = phy->dev;1187 u32 changed = IEEE80211_RC_SUPP_RATES_CHANGED;1188 1189 mvif->bitrate_mask = *mask;1190 1191 /* if multiple rates across different preambles are given we can1192 * reconfigure this info with all peers using sta_rec command with1193 * the below exception cases.1194 * - single rate : if a rate is passed along with different preambles,1195 * we select the highest one as fixed rate. i.e VHT MCS for VHT peers.1196 * - multiple rates: if it's not in range format i.e 0-{7,8,9} for VHT1197 * then multiple MCS setting (MCS 4,5,6) is not supported.1198 */1199 ieee80211_iterate_stations_atomic(hw, mt7915_sta_rc_work, &changed);1200 ieee80211_queue_work(hw, &dev->rc_work);1201 1202 return 0;1203}1204 1205static void mt7915_sta_set_4addr(struct ieee80211_hw *hw,1206 struct ieee80211_vif *vif,1207 struct ieee80211_sta *sta,1208 bool enabled)1209{1210 struct mt7915_dev *dev = mt7915_hw_dev(hw);1211 struct mt7915_sta *msta = (struct mt7915_sta *)sta->drv_priv;1212 1213 if (enabled)1214 set_bit(MT_WCID_FLAG_4ADDR, &msta->wcid.flags);1215 else1216 clear_bit(MT_WCID_FLAG_4ADDR, &msta->wcid.flags);1217 1218 if (!msta->wcid.sta)1219 return;1220 1221 mt76_connac_mcu_wtbl_update_hdr_trans(&dev->mt76, vif, sta);1222}1223 1224static void mt7915_sta_set_decap_offload(struct ieee80211_hw *hw,1225 struct ieee80211_vif *vif,1226 struct ieee80211_sta *sta,1227 bool enabled)1228{1229 struct mt7915_dev *dev = mt7915_hw_dev(hw);1230 struct mt7915_sta *msta = (struct mt7915_sta *)sta->drv_priv;1231 1232 if (enabled)1233 set_bit(MT_WCID_FLAG_HDR_TRANS, &msta->wcid.flags);1234 else1235 clear_bit(MT_WCID_FLAG_HDR_TRANS, &msta->wcid.flags);1236 1237 if (!msta->wcid.sta)1238 return;1239 1240 mt76_connac_mcu_wtbl_update_hdr_trans(&dev->mt76, vif, sta);1241}1242 1243static int mt7915_sta_set_txpwr(struct ieee80211_hw *hw,1244 struct ieee80211_vif *vif,1245 struct ieee80211_sta *sta)1246{1247 struct mt7915_phy *phy = mt7915_hw_phy(hw);1248 struct mt7915_dev *dev = mt7915_hw_dev(hw);1249 s16 txpower = sta->deflink.txpwr.power;1250 int ret;1251 1252 if (sta->deflink.txpwr.type == NL80211_TX_POWER_AUTOMATIC)1253 txpower = 0;1254 1255 mutex_lock(&dev->mt76.mutex);1256 1257 /* NOTE: temporarily use 0 as minimum limit, which is a1258 * global setting and will be applied to all stations.1259 */1260 ret = mt7915_mcu_set_txpower_frame_min(phy, 0);1261 if (ret)1262 goto out;1263 1264 /* This only applies to data frames while pushing traffic,1265 * whereas the management frames or other packets that are1266 * using fixed rate can be configured via TxD.1267 */1268 ret = mt7915_mcu_set_txpower_frame(phy, vif, sta, txpower);1269 1270out:1271 mutex_unlock(&dev->mt76.mutex);1272 1273 return ret;1274}1275 1276static const char mt7915_gstrings_stats[][ETH_GSTRING_LEN] = {1277 "tx_ampdu_cnt",1278 "tx_stop_q_empty_cnt",1279 "tx_mpdu_attempts",1280 "tx_mpdu_success",1281 "tx_rwp_fail_cnt",1282 "tx_rwp_need_cnt",1283 "tx_pkt_ebf_cnt",1284 "tx_pkt_ibf_cnt",1285 "tx_ampdu_len:0-1",1286 "tx_ampdu_len:2-10",1287 "tx_ampdu_len:11-19",1288 "tx_ampdu_len:20-28",1289 "tx_ampdu_len:29-37",1290 "tx_ampdu_len:38-46",1291 "tx_ampdu_len:47-55",1292 "tx_ampdu_len:56-79",1293 "tx_ampdu_len:80-103",1294 "tx_ampdu_len:104-127",1295 "tx_ampdu_len:128-151",1296 "tx_ampdu_len:152-175",1297 "tx_ampdu_len:176-199",1298 "tx_ampdu_len:200-223",1299 "tx_ampdu_len:224-247",1300 "ba_miss_count",1301 "tx_beamformer_ppdu_iBF",1302 "tx_beamformer_ppdu_eBF",1303 "tx_beamformer_rx_feedback_all",1304 "tx_beamformer_rx_feedback_he",1305 "tx_beamformer_rx_feedback_vht",1306 "tx_beamformer_rx_feedback_ht",1307 "tx_beamformer_rx_feedback_bw", /* zero based idx: 20, 40, 80, 160 */1308 "tx_beamformer_rx_feedback_nc",1309 "tx_beamformer_rx_feedback_nr",1310 "tx_beamformee_ok_feedback_pkts",1311 "tx_beamformee_feedback_trig",1312 "tx_mu_beamforming",1313 "tx_mu_mpdu",1314 "tx_mu_successful_mpdu",1315 "tx_su_successful_mpdu",1316 "tx_msdu_pack_1",1317 "tx_msdu_pack_2",1318 "tx_msdu_pack_3",1319 "tx_msdu_pack_4",1320 "tx_msdu_pack_5",1321 "tx_msdu_pack_6",1322 "tx_msdu_pack_7",1323 "tx_msdu_pack_8",1324 1325 /* rx counters */1326 "rx_fifo_full_cnt",1327 "rx_mpdu_cnt",1328 "channel_idle_cnt",1329 "primary_cca_busy_time",1330 "secondary_cca_busy_time",1331 "primary_energy_detect_time",1332 "cck_mdrdy_time",1333 "ofdm_mdrdy_time",1334 "green_mdrdy_time",1335 "rx_vector_mismatch_cnt",1336 "rx_delimiter_fail_cnt",1337 "rx_mrdy_cnt",1338 "rx_len_mismatch_cnt",1339 "rx_ampdu_cnt",1340 "rx_ampdu_bytes_cnt",1341 "rx_ampdu_valid_subframe_cnt",1342 "rx_ampdu_valid_subframe_b_cnt",1343 "rx_pfdrop_cnt",1344 "rx_vec_queue_overflow_drop_cnt",1345 "rx_ba_cnt",1346 1347 /* muru mu-mimo and ofdma related stats */1348 "dl_cck_cnt",1349 "dl_ofdm_cnt",1350 "dl_htmix_cnt",1351 "dl_htgf_cnt",1352 "dl_vht_su_cnt",1353 "dl_vht_2mu_cnt",1354 "dl_vht_3mu_cnt",1355 "dl_vht_4mu_cnt",1356 "dl_he_su_cnt",1357 "dl_he_ext_su_cnt",1358 "dl_he_2ru_cnt",1359 "dl_he_2mu_cnt",1360 "dl_he_3ru_cnt",1361 "dl_he_3mu_cnt",1362 "dl_he_4ru_cnt",1363 "dl_he_4mu_cnt",1364 "dl_he_5to8ru_cnt",1365 "dl_he_9to16ru_cnt",1366 "dl_he_gtr16ru_cnt",1367 1368 "ul_hetrig_su_cnt",1369 "ul_hetrig_2ru_cnt",1370 "ul_hetrig_3ru_cnt",1371 "ul_hetrig_4ru_cnt",1372 "ul_hetrig_5to8ru_cnt",1373 "ul_hetrig_9to16ru_cnt",1374 "ul_hetrig_gtr16ru_cnt",1375 "ul_hetrig_2mu_cnt",1376 "ul_hetrig_3mu_cnt",1377 "ul_hetrig_4mu_cnt",1378 1379 /* per vif counters */1380 "v_tx_mode_cck",1381 "v_tx_mode_ofdm",1382 "v_tx_mode_ht",1383 "v_tx_mode_ht_gf",1384 "v_tx_mode_vht",1385 "v_tx_mode_he_su",1386 "v_tx_mode_he_ext_su",1387 "v_tx_mode_he_tb",1388 "v_tx_mode_he_mu",1389 "v_tx_bw_20",1390 "v_tx_bw_40",1391 "v_tx_bw_80",1392 "v_tx_bw_160",1393 "v_tx_mcs_0",1394 "v_tx_mcs_1",1395 "v_tx_mcs_2",1396 "v_tx_mcs_3",1397 "v_tx_mcs_4",1398 "v_tx_mcs_5",1399 "v_tx_mcs_6",1400 "v_tx_mcs_7",1401 "v_tx_mcs_8",1402 "v_tx_mcs_9",1403 "v_tx_mcs_10",1404 "v_tx_mcs_11",1405 "v_tx_nss_1",1406 "v_tx_nss_2",1407 "v_tx_nss_3",1408 "v_tx_nss_4",1409};1410 1411#define MT7915_SSTATS_LEN ARRAY_SIZE(mt7915_gstrings_stats)1412 1413/* Ethtool related API */1414static1415void mt7915_get_et_strings(struct ieee80211_hw *hw,1416 struct ieee80211_vif *vif,1417 u32 sset, u8 *data)1418{1419 if (sset != ETH_SS_STATS)1420 return;1421 1422 memcpy(data, mt7915_gstrings_stats, sizeof(mt7915_gstrings_stats));1423 data += sizeof(mt7915_gstrings_stats);1424 page_pool_ethtool_stats_get_strings(data);1425}1426 1427static1428int mt7915_get_et_sset_count(struct ieee80211_hw *hw,1429 struct ieee80211_vif *vif, int sset)1430{1431 if (sset != ETH_SS_STATS)1432 return 0;1433 1434 return MT7915_SSTATS_LEN + page_pool_ethtool_stats_get_count();1435}1436 1437static void mt7915_ethtool_worker(void *wi_data, struct ieee80211_sta *sta)1438{1439 struct mt76_ethtool_worker_info *wi = wi_data;1440 struct mt7915_sta *msta = (struct mt7915_sta *)sta->drv_priv;1441 1442 if (msta->vif->mt76.idx != wi->idx)1443 return;1444 1445 mt76_ethtool_worker(wi, &msta->wcid.stats, false);1446}1447 1448static1449void mt7915_get_et_stats(struct ieee80211_hw *hw,1450 struct ieee80211_vif *vif,1451 struct ethtool_stats *stats, u64 *data)1452{1453 struct mt7915_dev *dev = mt7915_hw_dev(hw);1454 struct mt7915_phy *phy = mt7915_hw_phy(hw);1455 struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv;1456 struct mt76_mib_stats *mib = &phy->mib;1457 struct mt76_ethtool_worker_info wi = {1458 .data = data,1459 .idx = mvif->mt76.idx,1460 };1461 /* See mt7915_ampdu_stat_read_phy, etc */1462 int i, ei = 0, stats_size;1463 1464 mutex_lock(&dev->mt76.mutex);1465 1466 mt7915_mac_update_stats(phy);1467 1468 data[ei++] = mib->tx_ampdu_cnt;1469 data[ei++] = mib->tx_stop_q_empty_cnt;1470 data[ei++] = mib->tx_mpdu_attempts_cnt;1471 data[ei++] = mib->tx_mpdu_success_cnt;1472 data[ei++] = mib->tx_rwp_fail_cnt;1473 data[ei++] = mib->tx_rwp_need_cnt;1474 data[ei++] = mib->tx_pkt_ebf_cnt;1475 data[ei++] = mib->tx_pkt_ibf_cnt;1476 1477 /* Tx ampdu stat */1478 for (i = 0; i < 15 /*ARRAY_SIZE(bound)*/; i++)1479 data[ei++] = phy->mt76->aggr_stats[i];1480 1481 data[ei++] = phy->mib.ba_miss_cnt;1482 1483 /* Tx Beamformer monitor */1484 data[ei++] = mib->tx_bf_ibf_ppdu_cnt;1485 data[ei++] = mib->tx_bf_ebf_ppdu_cnt;1486 1487 /* Tx Beamformer Rx feedback monitor */1488 data[ei++] = mib->tx_bf_rx_fb_all_cnt;1489 data[ei++] = mib->tx_bf_rx_fb_he_cnt;1490 data[ei++] = mib->tx_bf_rx_fb_vht_cnt;1491 data[ei++] = mib->tx_bf_rx_fb_ht_cnt;1492 1493 data[ei++] = mib->tx_bf_rx_fb_bw;1494 data[ei++] = mib->tx_bf_rx_fb_nc_cnt;1495 data[ei++] = mib->tx_bf_rx_fb_nr_cnt;1496 1497 /* Tx Beamformee Rx NDPA & Tx feedback report */1498 data[ei++] = mib->tx_bf_fb_cpl_cnt;1499 data[ei++] = mib->tx_bf_fb_trig_cnt;1500 1501 /* Tx SU & MU counters */1502 data[ei++] = mib->tx_bf_cnt;1503 data[ei++] = mib->tx_mu_mpdu_cnt;1504 data[ei++] = mib->tx_mu_acked_mpdu_cnt;1505 data[ei++] = mib->tx_su_acked_mpdu_cnt;1506 1507 /* Tx amsdu info (pack-count histogram) */1508 for (i = 0; i < ARRAY_SIZE(mib->tx_amsdu); i++)1509 data[ei++] = mib->tx_amsdu[i];1510 1511 /* rx counters */1512 data[ei++] = mib->rx_fifo_full_cnt;1513 data[ei++] = mib->rx_mpdu_cnt;1514 data[ei++] = mib->channel_idle_cnt;1515 data[ei++] = mib->primary_cca_busy_time;1516 data[ei++] = mib->secondary_cca_busy_time;1517 data[ei++] = mib->primary_energy_detect_time;1518 data[ei++] = mib->cck_mdrdy_time;1519 data[ei++] = mib->ofdm_mdrdy_time;1520 data[ei++] = mib->green_mdrdy_time;1521 data[ei++] = mib->rx_vector_mismatch_cnt;1522 data[ei++] = mib->rx_delimiter_fail_cnt;1523 data[ei++] = mib->rx_mrdy_cnt;1524 data[ei++] = mib->rx_len_mismatch_cnt;1525 data[ei++] = mib->rx_ampdu_cnt;1526 data[ei++] = mib->rx_ampdu_bytes_cnt;1527 data[ei++] = mib->rx_ampdu_valid_subframe_cnt;1528 data[ei++] = mib->rx_ampdu_valid_subframe_bytes_cnt;1529 data[ei++] = mib->rx_pfdrop_cnt;1530 data[ei++] = mib->rx_vec_queue_overflow_drop_cnt;1531 data[ei++] = mib->rx_ba_cnt;1532 1533 data[ei++] = mib->dl_cck_cnt;1534 data[ei++] = mib->dl_ofdm_cnt;1535 data[ei++] = mib->dl_htmix_cnt;1536 data[ei++] = mib->dl_htgf_cnt;1537 data[ei++] = mib->dl_vht_su_cnt;1538 data[ei++] = mib->dl_vht_2mu_cnt;1539 data[ei++] = mib->dl_vht_3mu_cnt;1540 data[ei++] = mib->dl_vht_4mu_cnt;1541 data[ei++] = mib->dl_he_su_cnt;1542 data[ei++] = mib->dl_he_ext_su_cnt;1543 data[ei++] = mib->dl_he_2ru_cnt;1544 data[ei++] = mib->dl_he_2mu_cnt;1545 data[ei++] = mib->dl_he_3ru_cnt;1546 data[ei++] = mib->dl_he_3mu_cnt;1547 data[ei++] = mib->dl_he_4ru_cnt;1548 data[ei++] = mib->dl_he_4mu_cnt;1549 data[ei++] = mib->dl_he_5to8ru_cnt;1550 data[ei++] = mib->dl_he_9to16ru_cnt;1551 data[ei++] = mib->dl_he_gtr16ru_cnt;1552 1553 data[ei++] = mib->ul_hetrig_su_cnt;1554 data[ei++] = mib->ul_hetrig_2ru_cnt;1555 data[ei++] = mib->ul_hetrig_3ru_cnt;1556 data[ei++] = mib->ul_hetrig_4ru_cnt;1557 data[ei++] = mib->ul_hetrig_5to8ru_cnt;1558 data[ei++] = mib->ul_hetrig_9to16ru_cnt;1559 data[ei++] = mib->ul_hetrig_gtr16ru_cnt;1560 data[ei++] = mib->ul_hetrig_2mu_cnt;1561 data[ei++] = mib->ul_hetrig_3mu_cnt;1562 data[ei++] = mib->ul_hetrig_4mu_cnt;1563 1564 /* Add values for all stations owned by this vif */1565 wi.initial_stat_idx = ei;1566 ieee80211_iterate_stations_atomic(hw, mt7915_ethtool_worker, &wi);1567 1568 mutex_unlock(&dev->mt76.mutex);1569 1570 if (wi.sta_count == 0)1571 return;1572 1573 ei += wi.worker_stat_count;1574 1575 mt76_ethtool_page_pool_stats(&dev->mt76, &data[ei], &ei);1576 1577 stats_size = MT7915_SSTATS_LEN + page_pool_ethtool_stats_get_count();1578 if (ei != stats_size)1579 dev_err(dev->mt76.dev, "ei: %d size: %d", ei, stats_size);1580}1581 1582static void1583mt7915_twt_teardown_request(struct ieee80211_hw *hw,1584 struct ieee80211_sta *sta,1585 u8 flowid)1586{1587 struct mt7915_sta *msta = (struct mt7915_sta *)sta->drv_priv;1588 struct mt7915_dev *dev = mt7915_hw_dev(hw);1589 1590 mutex_lock(&dev->mt76.mutex);1591 mt7915_mac_twt_teardown_flow(dev, msta, flowid);1592 mutex_unlock(&dev->mt76.mutex);1593}1594 1595static int1596mt7915_set_frag_threshold(struct ieee80211_hw *hw, u32 val)1597{1598 return 0;1599}1600 1601static int1602mt7915_set_radar_background(struct ieee80211_hw *hw,1603 struct cfg80211_chan_def *chandef)1604{1605 struct mt7915_phy *phy = mt7915_hw_phy(hw);1606 struct mt7915_dev *dev = phy->dev;1607 int ret = -EINVAL;1608 bool running;1609 1610 mutex_lock(&dev->mt76.mutex);1611 1612 if (dev->mt76.region == NL80211_DFS_UNSET)1613 goto out;1614 1615 if (dev->rdd2_phy && dev->rdd2_phy != phy) {1616 /* rdd2 is already locked */1617 ret = -EBUSY;1618 goto out;1619 }1620 1621 /* rdd2 already configured on a radar channel */1622 running = dev->rdd2_phy &&1623 cfg80211_chandef_valid(&dev->rdd2_chandef) &&1624 !!(dev->rdd2_chandef.chan->flags & IEEE80211_CHAN_RADAR);1625 1626 if (!chandef || running ||1627 !(chandef->chan->flags & IEEE80211_CHAN_RADAR)) {1628 ret = mt7915_mcu_rdd_background_enable(phy, NULL);1629 if (ret)1630 goto out;1631 1632 if (!running)1633 goto update_phy;1634 }1635 1636 ret = mt7915_mcu_rdd_background_enable(phy, chandef);1637 if (ret)1638 goto out;1639 1640update_phy:1641 dev->rdd2_phy = chandef ? phy : NULL;1642 if (chandef)1643 dev->rdd2_chandef = *chandef;1644out:1645 mutex_unlock(&dev->mt76.mutex);1646 1647 return ret;1648}1649 1650#ifdef CONFIG_NET_MEDIATEK_SOC_WED1651static int1652mt7915_net_fill_forward_path(struct ieee80211_hw *hw,1653 struct ieee80211_vif *vif,1654 struct ieee80211_sta *sta,1655 struct net_device_path_ctx *ctx,1656 struct net_device_path *path)1657{1658 struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv;1659 struct mt7915_sta *msta = (struct mt7915_sta *)sta->drv_priv;1660 struct mt7915_dev *dev = mt7915_hw_dev(hw);1661 struct mt7915_phy *phy = mt7915_hw_phy(hw);1662 struct mtk_wed_device *wed = &dev->mt76.mmio.wed;1663 1664 if (!mtk_wed_device_active(wed))1665 return -ENODEV;1666 1667 if (msta->wcid.idx > 0xff)1668 return -EIO;1669 1670 path->type = DEV_PATH_MTK_WDMA;1671 path->dev = ctx->dev;1672 path->mtk_wdma.wdma_idx = wed->wdma_idx;1673 path->mtk_wdma.bss = mvif->mt76.idx;1674 path->mtk_wdma.wcid = is_mt7915(&dev->mt76) ? msta->wcid.idx : 0x3ff;1675 path->mtk_wdma.queue = phy != &dev->phy;1676 1677 ctx->dev = NULL;1678 1679 return 0;1680}1681#endif1682 1683static void1684mt7915_reconfig_complete(struct ieee80211_hw *hw,1685 enum ieee80211_reconfig_type reconfig_type)1686{1687 struct mt7915_phy *phy = mt7915_hw_phy(hw);1688 1689 ieee80211_wake_queues(hw);1690 ieee80211_queue_delayed_work(hw, &phy->mt76->mac_work,1691 MT7915_WATCHDOG_TIME);1692}1693 1694const struct ieee80211_ops mt7915_ops = {1695 .add_chanctx = ieee80211_emulate_add_chanctx,1696 .remove_chanctx = ieee80211_emulate_remove_chanctx,1697 .change_chanctx = ieee80211_emulate_change_chanctx,1698 .switch_vif_chanctx = ieee80211_emulate_switch_vif_chanctx,1699 .tx = mt7915_tx,1700 .start = mt7915_start,1701 .stop = mt7915_stop,1702 .add_interface = mt7915_add_interface,1703 .remove_interface = mt7915_remove_interface,1704 .config = mt7915_config,1705 .conf_tx = mt7915_conf_tx,1706 .configure_filter = mt7915_configure_filter,1707 .bss_info_changed = mt7915_bss_info_changed,1708 .start_ap = mt7915_start_ap,1709 .stop_ap = mt7915_stop_ap,1710 .sta_state = mt76_sta_state,1711 .sta_pre_rcu_remove = mt76_sta_pre_rcu_remove,1712 .sta_rc_update = mt7915_sta_rc_update,1713 .set_key = mt7915_set_key,1714 .ampdu_action = mt7915_ampdu_action,1715 .set_rts_threshold = mt7915_set_rts_threshold,1716 .wake_tx_queue = mt76_wake_tx_queue,1717 .sw_scan_start = mt76_sw_scan,1718 .sw_scan_complete = mt76_sw_scan_complete,1719 .release_buffered_frames = mt76_release_buffered_frames,1720 .get_txpower = mt76_get_txpower,1721 .set_sar_specs = mt7915_set_sar_specs,1722 .channel_switch_beacon = mt7915_channel_switch_beacon,1723 .get_stats = mt7915_get_stats,1724 .get_et_sset_count = mt7915_get_et_sset_count,1725 .get_et_stats = mt7915_get_et_stats,1726 .get_et_strings = mt7915_get_et_strings,1727 .get_tsf = mt7915_get_tsf,1728 .set_tsf = mt7915_set_tsf,1729 .offset_tsf = mt7915_offset_tsf,1730 .get_survey = mt76_get_survey,1731 .get_antenna = mt76_get_antenna,1732 .set_antenna = mt7915_set_antenna,1733 .set_bitrate_mask = mt7915_set_bitrate_mask,1734 .set_coverage_class = mt7915_set_coverage_class,1735 .sta_statistics = mt7915_sta_statistics,1736 .sta_set_txpwr = mt7915_sta_set_txpwr,1737 .sta_set_4addr = mt7915_sta_set_4addr,1738 .sta_set_decap_offload = mt7915_sta_set_decap_offload,1739 .add_twt_setup = mt7915_mac_add_twt_setup,1740 .twt_teardown_request = mt7915_twt_teardown_request,1741 .set_frag_threshold = mt7915_set_frag_threshold,1742 CFG80211_TESTMODE_CMD(mt76_testmode_cmd)1743 CFG80211_TESTMODE_DUMP(mt76_testmode_dump)1744#ifdef CONFIG_MAC80211_DEBUGFS1745 .sta_add_debugfs = mt7915_sta_add_debugfs,1746#endif1747 .set_radar_background = mt7915_set_radar_background,1748#ifdef CONFIG_NET_MEDIATEK_SOC_WED1749 .net_fill_forward_path = mt7915_net_fill_forward_path,1750 .net_setup_tc = mt76_wed_net_setup_tc,1751#endif1752 .reconfig_complete = mt7915_reconfig_complete,1753};1754