1410 lines · c
1// SPDX-License-Identifier: ISC2/*3 * Copyright (C) 2022 MediaTek Inc.4 */5 6#include <linux/etherdevice.h>7#include <linux/of.h>8#include <linux/hwmon.h>9#include <linux/hwmon-sysfs.h>10#include <linux/thermal.h>11#include "mt7996.h"12#include "mac.h"13#include "mcu.h"14#include "coredump.h"15#include "eeprom.h"16 17static const struct ieee80211_iface_limit if_limits[] = {18 {19 .max = 1,20 .types = BIT(NL80211_IFTYPE_ADHOC)21 }, {22 .max = 16,23 .types = BIT(NL80211_IFTYPE_AP)24#ifdef CONFIG_MAC80211_MESH25 | BIT(NL80211_IFTYPE_MESH_POINT)26#endif27 }, {28 .max = MT7996_MAX_INTERFACES,29 .types = BIT(NL80211_IFTYPE_STATION)30 }31};32 33static const struct ieee80211_iface_combination if_comb[] = {34 {35 .limits = if_limits,36 .n_limits = ARRAY_SIZE(if_limits),37 .max_interfaces = MT7996_MAX_INTERFACES,38 .num_different_channels = 1,39 .beacon_int_infra_match = true,40 .radar_detect_widths = BIT(NL80211_CHAN_WIDTH_20_NOHT) |41 BIT(NL80211_CHAN_WIDTH_20) |42 BIT(NL80211_CHAN_WIDTH_40) |43 BIT(NL80211_CHAN_WIDTH_80) |44 BIT(NL80211_CHAN_WIDTH_160),45 .beacon_int_min_gcd = 100,46 }47};48 49static ssize_t mt7996_thermal_temp_show(struct device *dev,50 struct device_attribute *attr,51 char *buf)52{53 struct mt7996_phy *phy = dev_get_drvdata(dev);54 int i = to_sensor_dev_attr(attr)->index;55 int temperature;56 57 switch (i) {58 case 0:59 temperature = mt7996_mcu_get_temperature(phy);60 if (temperature < 0)61 return temperature;62 /* display in millidegree celcius */63 return sprintf(buf, "%u\n", temperature * 1000);64 case 1:65 case 2:66 return sprintf(buf, "%u\n",67 phy->throttle_temp[i - 1] * 1000);68 case 3:69 return sprintf(buf, "%hhu\n", phy->throttle_state);70 default:71 return -EINVAL;72 }73}74 75static ssize_t mt7996_thermal_temp_store(struct device *dev,76 struct device_attribute *attr,77 const char *buf, size_t count)78{79 struct mt7996_phy *phy = dev_get_drvdata(dev);80 int ret, i = to_sensor_dev_attr(attr)->index;81 long val;82 83 ret = kstrtol(buf, 10, &val);84 if (ret < 0)85 return ret;86 87 mutex_lock(&phy->dev->mt76.mutex);88 val = clamp_val(DIV_ROUND_CLOSEST(val, 1000), 40, 130);89 90 /* add a safety margin ~10 */91 if ((i - 1 == MT7996_CRIT_TEMP_IDX &&92 val > phy->throttle_temp[MT7996_MAX_TEMP_IDX] - 10) ||93 (i - 1 == MT7996_MAX_TEMP_IDX &&94 val - 10 < phy->throttle_temp[MT7996_CRIT_TEMP_IDX])) {95 dev_err(phy->dev->mt76.dev,96 "temp1_max shall be 10 degrees higher than temp1_crit.");97 mutex_unlock(&phy->dev->mt76.mutex);98 return -EINVAL;99 }100 101 phy->throttle_temp[i - 1] = val;102 mutex_unlock(&phy->dev->mt76.mutex);103 104 ret = mt7996_mcu_set_thermal_protect(phy, true);105 if (ret)106 return ret;107 108 return count;109}110 111static SENSOR_DEVICE_ATTR_RO(temp1_input, mt7996_thermal_temp, 0);112static SENSOR_DEVICE_ATTR_RW(temp1_crit, mt7996_thermal_temp, 1);113static SENSOR_DEVICE_ATTR_RW(temp1_max, mt7996_thermal_temp, 2);114static SENSOR_DEVICE_ATTR_RO(throttle1, mt7996_thermal_temp, 3);115 116static struct attribute *mt7996_hwmon_attrs[] = {117 &sensor_dev_attr_temp1_input.dev_attr.attr,118 &sensor_dev_attr_temp1_crit.dev_attr.attr,119 &sensor_dev_attr_temp1_max.dev_attr.attr,120 &sensor_dev_attr_throttle1.dev_attr.attr,121 NULL,122};123ATTRIBUTE_GROUPS(mt7996_hwmon);124 125static int126mt7996_thermal_get_max_throttle_state(struct thermal_cooling_device *cdev,127 unsigned long *state)128{129 *state = MT7996_CDEV_THROTTLE_MAX;130 131 return 0;132}133 134static int135mt7996_thermal_get_cur_throttle_state(struct thermal_cooling_device *cdev,136 unsigned long *state)137{138 struct mt7996_phy *phy = cdev->devdata;139 140 *state = phy->cdev_state;141 142 return 0;143}144 145static int146mt7996_thermal_set_cur_throttle_state(struct thermal_cooling_device *cdev,147 unsigned long state)148{149 struct mt7996_phy *phy = cdev->devdata;150 u8 throttling = MT7996_THERMAL_THROTTLE_MAX - state;151 int ret;152 153 if (state > MT7996_CDEV_THROTTLE_MAX) {154 dev_err(phy->dev->mt76.dev,155 "please specify a valid throttling state\n");156 return -EINVAL;157 }158 159 if (state == phy->cdev_state)160 return 0;161 162 /* cooling_device convention: 0 = no cooling, more = more cooling163 * mcu convention: 1 = max cooling, more = less cooling164 */165 ret = mt7996_mcu_set_thermal_throttling(phy, throttling);166 if (ret)167 return ret;168 169 phy->cdev_state = state;170 171 return 0;172}173 174static const struct thermal_cooling_device_ops mt7996_thermal_ops = {175 .get_max_state = mt7996_thermal_get_max_throttle_state,176 .get_cur_state = mt7996_thermal_get_cur_throttle_state,177 .set_cur_state = mt7996_thermal_set_cur_throttle_state,178};179 180static void mt7996_unregister_thermal(struct mt7996_phy *phy)181{182 struct wiphy *wiphy = phy->mt76->hw->wiphy;183 184 if (!phy->cdev)185 return;186 187 sysfs_remove_link(&wiphy->dev.kobj, "cooling_device");188 thermal_cooling_device_unregister(phy->cdev);189}190 191static int mt7996_thermal_init(struct mt7996_phy *phy)192{193 struct wiphy *wiphy = phy->mt76->hw->wiphy;194 struct thermal_cooling_device *cdev;195 struct device *hwmon;196 const char *name;197 198 name = devm_kasprintf(&wiphy->dev, GFP_KERNEL, "mt7996_%s",199 wiphy_name(wiphy));200 201 cdev = thermal_cooling_device_register(name, phy, &mt7996_thermal_ops);202 if (!IS_ERR(cdev)) {203 if (sysfs_create_link(&wiphy->dev.kobj, &cdev->device.kobj,204 "cooling_device") < 0)205 thermal_cooling_device_unregister(cdev);206 else207 phy->cdev = cdev;208 }209 210 /* initialize critical/maximum high temperature */211 phy->throttle_temp[MT7996_CRIT_TEMP_IDX] = MT7996_CRIT_TEMP;212 phy->throttle_temp[MT7996_MAX_TEMP_IDX] = MT7996_MAX_TEMP;213 214 if (!IS_REACHABLE(CONFIG_HWMON))215 return 0;216 217 hwmon = devm_hwmon_device_register_with_groups(&wiphy->dev, name, phy,218 mt7996_hwmon_groups);219 220 if (IS_ERR(hwmon))221 return PTR_ERR(hwmon);222 223 return 0;224}225 226static void mt7996_led_set_config(struct led_classdev *led_cdev,227 u8 delay_on, u8 delay_off)228{229 struct mt7996_dev *dev;230 struct mt76_phy *mphy;231 u32 val;232 233 mphy = container_of(led_cdev, struct mt76_phy, leds.cdev);234 dev = container_of(mphy->dev, struct mt7996_dev, mt76);235 236 /* select TX blink mode, 2: only data frames */237 mt76_rmw_field(dev, MT_TMAC_TCR0(mphy->band_idx), MT_TMAC_TCR0_TX_BLINK, 2);238 239 /* enable LED */240 mt76_wr(dev, MT_LED_EN(mphy->band_idx), 1);241 242 /* set LED Tx blink on/off time */243 val = FIELD_PREP(MT_LED_TX_BLINK_ON_MASK, delay_on) |244 FIELD_PREP(MT_LED_TX_BLINK_OFF_MASK, delay_off);245 mt76_wr(dev, MT_LED_TX_BLINK(mphy->band_idx), val);246 247 /* turn LED off */248 if (delay_off == 0xff && delay_on == 0x0) {249 val = MT_LED_CTRL_POLARITY | MT_LED_CTRL_KICK;250 } else {251 /* control LED */252 val = MT_LED_CTRL_BLINK_MODE | MT_LED_CTRL_KICK;253 if (mphy->band_idx == MT_BAND1)254 val |= MT_LED_CTRL_BLINK_BAND_SEL;255 }256 257 if (mphy->leds.al)258 val |= MT_LED_CTRL_POLARITY;259 260 mt76_wr(dev, MT_LED_CTRL(mphy->band_idx), val);261 mt76_clear(dev, MT_LED_CTRL(mphy->band_idx), MT_LED_CTRL_KICK);262}263 264static int mt7996_led_set_blink(struct led_classdev *led_cdev,265 unsigned long *delay_on,266 unsigned long *delay_off)267{268 u16 delta_on = 0, delta_off = 0;269 270#define HW_TICK 10271#define TO_HW_TICK(_t) (((_t) > HW_TICK) ? ((_t) / HW_TICK) : HW_TICK)272 273 if (*delay_on)274 delta_on = TO_HW_TICK(*delay_on);275 if (*delay_off)276 delta_off = TO_HW_TICK(*delay_off);277 278 mt7996_led_set_config(led_cdev, delta_on, delta_off);279 280 return 0;281}282 283static void mt7996_led_set_brightness(struct led_classdev *led_cdev,284 enum led_brightness brightness)285{286 if (!brightness)287 mt7996_led_set_config(led_cdev, 0, 0xff);288 else289 mt7996_led_set_config(led_cdev, 0xff, 0);290}291 292static void __mt7996_init_txpower(struct mt7996_phy *phy,293 struct ieee80211_supported_band *sband)294{295 struct mt7996_dev *dev = phy->dev;296 int i, nss = hweight16(phy->mt76->chainmask);297 int nss_delta = mt76_tx_power_nss_delta(nss);298 int pwr_delta = mt7996_eeprom_get_power_delta(dev, sband->band);299 struct mt76_power_limits limits;300 301 for (i = 0; i < sband->n_channels; i++) {302 struct ieee80211_channel *chan = &sband->channels[i];303 int target_power = mt7996_eeprom_get_target_power(dev, chan);304 305 target_power += pwr_delta;306 target_power = mt76_get_rate_power_limits(phy->mt76, chan,307 &limits,308 target_power);309 target_power += nss_delta;310 target_power = DIV_ROUND_UP(target_power, 2);311 chan->max_power = min_t(int, chan->max_reg_power,312 target_power);313 chan->orig_mpwr = target_power;314 }315}316 317void mt7996_init_txpower(struct mt7996_phy *phy)318{319 if (!phy)320 return;321 322 if (phy->mt76->cap.has_2ghz)323 __mt7996_init_txpower(phy, &phy->mt76->sband_2g.sband);324 if (phy->mt76->cap.has_5ghz)325 __mt7996_init_txpower(phy, &phy->mt76->sband_5g.sband);326 if (phy->mt76->cap.has_6ghz)327 __mt7996_init_txpower(phy, &phy->mt76->sband_6g.sband);328}329 330static void331mt7996_regd_notifier(struct wiphy *wiphy,332 struct regulatory_request *request)333{334 struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);335 struct mt7996_dev *dev = mt7996_hw_dev(hw);336 struct mt7996_phy *phy = mt7996_hw_phy(hw);337 338 memcpy(dev->mt76.alpha2, request->alpha2, sizeof(dev->mt76.alpha2));339 dev->mt76.region = request->dfs_region;340 341 if (dev->mt76.region == NL80211_DFS_UNSET)342 mt7996_mcu_rdd_background_enable(phy, NULL);343 344 mt7996_init_txpower(phy);345 346 phy->mt76->dfs_state = MT_DFS_STATE_UNKNOWN;347 mt7996_dfs_init_radar_detector(phy);348}349 350static void351mt7996_init_wiphy(struct ieee80211_hw *hw, struct mtk_wed_device *wed)352{353 struct mt7996_phy *phy = mt7996_hw_phy(hw);354 struct mt76_dev *mdev = &phy->dev->mt76;355 struct wiphy *wiphy = hw->wiphy;356 u16 max_subframes = phy->dev->has_eht ? IEEE80211_MAX_AMPDU_BUF_EHT :357 IEEE80211_MAX_AMPDU_BUF_HE;358 359 hw->queues = 4;360 hw->max_rx_aggregation_subframes = max_subframes;361 hw->max_tx_aggregation_subframes = max_subframes;362 hw->netdev_features = NETIF_F_RXCSUM;363 if (mtk_wed_device_active(wed))364 hw->netdev_features |= NETIF_F_HW_TC;365 366 hw->radiotap_timestamp.units_pos =367 IEEE80211_RADIOTAP_TIMESTAMP_UNIT_US;368 369 phy->slottime = 9;370 phy->beacon_rate = -1;371 372 hw->sta_data_size = sizeof(struct mt7996_sta);373 hw->vif_data_size = sizeof(struct mt7996_vif);374 375 wiphy->iface_combinations = if_comb;376 wiphy->n_iface_combinations = ARRAY_SIZE(if_comb);377 wiphy->reg_notifier = mt7996_regd_notifier;378 wiphy->flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH;379 wiphy->mbssid_max_interfaces = 16;380 381 wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_BSS_COLOR);382 wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_VHT_IBSS);383 wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_BEACON_RATE_LEGACY);384 wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_BEACON_RATE_HT);385 wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_BEACON_RATE_VHT);386 wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_BEACON_RATE_HE);387 wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_UNSOL_BCAST_PROBE_RESP);388 wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_FILS_DISCOVERY);389 wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_ACK_SIGNAL_SUPPORT);390 wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_CAN_REPLACE_PTK0);391 wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_MU_MIMO_AIR_SNIFFER);392 393 if (!mdev->dev->of_node ||394 !of_property_read_bool(mdev->dev->of_node,395 "mediatek,disable-radar-background"))396 wiphy_ext_feature_set(wiphy,397 NL80211_EXT_FEATURE_RADAR_BACKGROUND);398 399 ieee80211_hw_set(hw, HAS_RATE_CONTROL);400 ieee80211_hw_set(hw, SUPPORTS_TX_ENCAP_OFFLOAD);401 ieee80211_hw_set(hw, SUPPORTS_RX_DECAP_OFFLOAD);402 ieee80211_hw_set(hw, WANT_MONITOR_VIF);403 ieee80211_hw_set(hw, SUPPORTS_MULTI_BSSID);404 405 hw->max_tx_fragments = 4;406 407 if (phy->mt76->cap.has_2ghz) {408 phy->mt76->sband_2g.sband.ht_cap.cap |=409 IEEE80211_HT_CAP_LDPC_CODING |410 IEEE80211_HT_CAP_MAX_AMSDU;411 phy->mt76->sband_2g.sband.ht_cap.ampdu_density =412 IEEE80211_HT_MPDU_DENSITY_2;413 }414 415 if (phy->mt76->cap.has_5ghz) {416 phy->mt76->sband_5g.sband.ht_cap.cap |=417 IEEE80211_HT_CAP_LDPC_CODING |418 IEEE80211_HT_CAP_MAX_AMSDU;419 420 phy->mt76->sband_5g.sband.vht_cap.cap |=421 IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454 |422 IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK |423 IEEE80211_VHT_CAP_SHORT_GI_160 |424 IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ;425 phy->mt76->sband_5g.sband.ht_cap.ampdu_density =426 IEEE80211_HT_MPDU_DENSITY_1;427 428 ieee80211_hw_set(hw, SUPPORTS_VHT_EXT_NSS_BW);429 }430 431 /* init led callbacks */432 if (IS_ENABLED(CONFIG_MT76_LEDS)) {433 phy->mt76->leds.cdev.brightness_set = mt7996_led_set_brightness;434 phy->mt76->leds.cdev.blink_set = mt7996_led_set_blink;435 }436 437 mt76_set_stream_caps(phy->mt76, true);438 mt7996_set_stream_vht_txbf_caps(phy);439 mt7996_set_stream_he_eht_caps(phy);440 mt7996_init_txpower(phy);441 442 wiphy->available_antennas_rx = phy->mt76->antenna_mask;443 wiphy->available_antennas_tx = phy->mt76->antenna_mask;444}445 446static void447mt7996_mac_init_band(struct mt7996_dev *dev, u8 band)448{449 u32 mask, set;450 451 /* clear estimated value of EIFS for Rx duration & OBSS time */452 mt76_wr(dev, MT_WF_RMAC_RSVD0(band), MT_WF_RMAC_RSVD0_EIFS_CLR);453 454 /* clear backoff time for Rx duration */455 mt76_clear(dev, MT_WF_RMAC_MIB_AIRTIME1(band),456 MT_WF_RMAC_MIB_NONQOSD_BACKOFF);457 mt76_clear(dev, MT_WF_RMAC_MIB_AIRTIME3(band),458 MT_WF_RMAC_MIB_QOS01_BACKOFF);459 mt76_clear(dev, MT_WF_RMAC_MIB_AIRTIME4(band),460 MT_WF_RMAC_MIB_QOS23_BACKOFF);461 462 /* clear backoff time and set software compensation for OBSS time */463 mask = MT_WF_RMAC_MIB_OBSS_BACKOFF | MT_WF_RMAC_MIB_ED_OFFSET;464 set = FIELD_PREP(MT_WF_RMAC_MIB_OBSS_BACKOFF, 0) |465 FIELD_PREP(MT_WF_RMAC_MIB_ED_OFFSET, 4);466 mt76_rmw(dev, MT_WF_RMAC_MIB_AIRTIME0(band), mask, set);467 468 /* filter out non-resp frames and get instanstaeous signal reporting */469 mask = MT_WTBLOFF_RSCR_RCPI_MODE | MT_WTBLOFF_RSCR_RCPI_PARAM;470 set = FIELD_PREP(MT_WTBLOFF_RSCR_RCPI_MODE, 0) |471 FIELD_PREP(MT_WTBLOFF_RSCR_RCPI_PARAM, 0x3);472 mt76_rmw(dev, MT_WTBLOFF_RSCR(band), mask, set);473 474 /* MT_TXD5_TX_STATUS_HOST (MPDU format) has higher priority than475 * MT_AGG_ACR_PPDU_TXS2H (PPDU format) even though ACR bit is set.476 */477 mt76_set(dev, MT_AGG_ACR4(band), MT_AGG_ACR_PPDU_TXS2H);478}479 480static void mt7996_mac_init_basic_rates(struct mt7996_dev *dev)481{482 int i;483 484 for (i = 0; i < ARRAY_SIZE(mt76_rates); i++) {485 u16 rate = mt76_rates[i].hw_value;486 /* odd index for driver, even index for firmware */487 u16 idx = MT7996_BASIC_RATES_TBL + 2 * i;488 489 rate = FIELD_PREP(MT_TX_RATE_MODE, rate >> 8) |490 FIELD_PREP(MT_TX_RATE_IDX, rate & GENMASK(7, 0));491 mt7996_mcu_set_fixed_rate_table(&dev->phy, idx, rate, false);492 }493}494 495void mt7996_mac_init(struct mt7996_dev *dev)496{497#define HIF_TXD_V2_1 0x21498 int i;499 500 mt76_clear(dev, MT_MDP_DCR2, MT_MDP_DCR2_RX_TRANS_SHORT);501 502 for (i = 0; i < mt7996_wtbl_size(dev); i++)503 mt7996_mac_wtbl_update(dev, i,504 MT_WTBL_UPDATE_ADM_COUNT_CLEAR);505 506 if (IS_ENABLED(CONFIG_MT76_LEDS)) {507 i = dev->mphy.leds.pin ? MT_LED_GPIO_MUX3 : MT_LED_GPIO_MUX2;508 mt76_rmw_field(dev, i, MT_LED_GPIO_SEL_MASK, 4);509 }510 511 /* rro module init */512 if (is_mt7996(&dev->mt76))513 mt7996_mcu_set_rro(dev, UNI_RRO_SET_PLATFORM_TYPE, 2);514 else515 mt7996_mcu_set_rro(dev, UNI_RRO_SET_PLATFORM_TYPE,516 dev->hif2 ? 7 : 0);517 518 if (dev->has_rro) {519 u16 timeout;520 521 timeout = mt76_rr(dev, MT_HW_REV) == MT_HW_REV1 ? 512 : 128;522 mt7996_mcu_set_rro(dev, UNI_RRO_SET_FLUSH_TIMEOUT, timeout);523 mt7996_mcu_set_rro(dev, UNI_RRO_SET_BYPASS_MODE, 1);524 mt7996_mcu_set_rro(dev, UNI_RRO_SET_TXFREE_PATH, 0);525 } else {526 mt7996_mcu_set_rro(dev, UNI_RRO_SET_BYPASS_MODE, 3);527 mt7996_mcu_set_rro(dev, UNI_RRO_SET_TXFREE_PATH, 1);528 }529 530 mt7996_mcu_wa_cmd(dev, MCU_WA_PARAM_CMD(SET),531 MCU_WA_PARAM_HW_PATH_HIF_VER,532 HIF_TXD_V2_1, 0);533 534 for (i = MT_BAND0; i <= MT_BAND2; i++)535 mt7996_mac_init_band(dev, i);536 537 mt7996_mac_init_basic_rates(dev);538}539 540int mt7996_txbf_init(struct mt7996_dev *dev)541{542 int ret;543 544 if (mt7996_band_valid(dev, MT_BAND1) ||545 mt7996_band_valid(dev, MT_BAND2)) {546 ret = mt7996_mcu_set_txbf(dev, BF_MOD_EN_CTRL);547 if (ret)548 return ret;549 }550 551 /* trigger sounding packets */552 ret = mt7996_mcu_set_txbf(dev, BF_SOUNDING_ON);553 if (ret)554 return ret;555 556 /* enable eBF */557 return mt7996_mcu_set_txbf(dev, BF_HW_EN_UPDATE);558}559 560static int mt7996_register_phy(struct mt7996_dev *dev, struct mt7996_phy *phy,561 enum mt76_band_id band)562{563 struct mt76_phy *mphy;564 u32 mac_ofs, hif1_ofs = 0;565 int ret;566 struct mtk_wed_device *wed = &dev->mt76.mmio.wed;567 568 if (!mt7996_band_valid(dev, band) || band == MT_BAND0)569 return 0;570 571 if (phy)572 return 0;573 574 if (is_mt7996(&dev->mt76) && band == MT_BAND2 && dev->hif2) {575 hif1_ofs = MT_WFDMA0_PCIE1(0) - MT_WFDMA0(0);576 wed = &dev->mt76.mmio.wed_hif2;577 }578 579 mphy = mt76_alloc_phy(&dev->mt76, sizeof(*phy), &mt7996_ops, band);580 if (!mphy)581 return -ENOMEM;582 583 phy = mphy->priv;584 phy->dev = dev;585 phy->mt76 = mphy;586 mphy->dev->phys[band] = mphy;587 588 INIT_DELAYED_WORK(&mphy->mac_work, mt7996_mac_work);589 590 ret = mt7996_eeprom_parse_hw_cap(dev, phy);591 if (ret)592 goto error;593 594 mac_ofs = band == MT_BAND2 ? MT_EE_MAC_ADDR3 : MT_EE_MAC_ADDR2;595 memcpy(mphy->macaddr, dev->mt76.eeprom.data + mac_ofs, ETH_ALEN);596 /* Make the extra PHY MAC address local without overlapping with597 * the usual MAC address allocation scheme on multiple virtual interfaces598 */599 if (!is_valid_ether_addr(mphy->macaddr)) {600 memcpy(mphy->macaddr, dev->mt76.eeprom.data + MT_EE_MAC_ADDR,601 ETH_ALEN);602 mphy->macaddr[0] |= 2;603 mphy->macaddr[0] ^= BIT(7);604 if (band == MT_BAND2)605 mphy->macaddr[0] ^= BIT(6);606 }607 mt76_eeprom_override(mphy);608 609 /* init wiphy according to mphy and phy */610 mt7996_init_wiphy(mphy->hw, wed);611 ret = mt7996_init_tx_queues(mphy->priv,612 MT_TXQ_ID(band),613 MT7996_TX_RING_SIZE,614 MT_TXQ_RING_BASE(band) + hif1_ofs,615 wed);616 if (ret)617 goto error;618 619 ret = mt76_register_phy(mphy, true, mt76_rates,620 ARRAY_SIZE(mt76_rates));621 if (ret)622 goto error;623 624 ret = mt7996_thermal_init(phy);625 if (ret)626 goto error;627 628 ret = mt7996_init_debugfs(phy);629 if (ret)630 goto error;631 632 if (wed == &dev->mt76.mmio.wed_hif2 && mtk_wed_device_active(wed)) {633 u32 irq_mask = dev->mt76.mmio.irqmask | MT_INT_TX_DONE_BAND2;634 635 mt76_wr(dev, MT_INT1_MASK_CSR, irq_mask);636 mtk_wed_device_start(&dev->mt76.mmio.wed_hif2, irq_mask);637 }638 639 return 0;640 641error:642 mphy->dev->phys[band] = NULL;643 ieee80211_free_hw(mphy->hw);644 return ret;645}646 647static void648mt7996_unregister_phy(struct mt7996_phy *phy, enum mt76_band_id band)649{650 struct mt76_phy *mphy;651 652 if (!phy)653 return;654 655 mt7996_unregister_thermal(phy);656 657 mphy = phy->dev->mt76.phys[band];658 mt76_unregister_phy(mphy);659 ieee80211_free_hw(mphy->hw);660 phy->dev->mt76.phys[band] = NULL;661}662 663static void mt7996_init_work(struct work_struct *work)664{665 struct mt7996_dev *dev = container_of(work, struct mt7996_dev,666 init_work);667 668 mt7996_mcu_set_eeprom(dev);669 mt7996_mac_init(dev);670 mt7996_txbf_init(dev);671}672 673void mt7996_wfsys_reset(struct mt7996_dev *dev)674{675 mt76_set(dev, MT_WF_SUBSYS_RST, 0x1);676 msleep(20);677 678 mt76_clear(dev, MT_WF_SUBSYS_RST, 0x1);679 msleep(20);680}681 682static int mt7996_wed_rro_init(struct mt7996_dev *dev)683{684#ifdef CONFIG_NET_MEDIATEK_SOC_WED685 struct mtk_wed_device *wed = &dev->mt76.mmio.wed;686 u32 reg = MT_RRO_ADDR_ELEM_SEG_ADDR0;687 struct mt7996_wed_rro_addr *addr;688 void *ptr;689 int i;690 691 if (!dev->has_rro)692 return 0;693 694 if (!mtk_wed_device_active(wed))695 return 0;696 697 for (i = 0; i < ARRAY_SIZE(dev->wed_rro.ba_bitmap); i++) {698 ptr = dmam_alloc_coherent(dev->mt76.dma_dev,699 MT7996_RRO_BA_BITMAP_CR_SIZE,700 &dev->wed_rro.ba_bitmap[i].phy_addr,701 GFP_KERNEL);702 if (!ptr)703 return -ENOMEM;704 705 dev->wed_rro.ba_bitmap[i].ptr = ptr;706 }707 708 for (i = 0; i < ARRAY_SIZE(dev->wed_rro.addr_elem); i++) {709 int j;710 711 ptr = dmam_alloc_coherent(dev->mt76.dma_dev,712 MT7996_RRO_WINDOW_MAX_SIZE * sizeof(*addr),713 &dev->wed_rro.addr_elem[i].phy_addr,714 GFP_KERNEL);715 if (!ptr)716 return -ENOMEM;717 718 dev->wed_rro.addr_elem[i].ptr = ptr;719 memset(dev->wed_rro.addr_elem[i].ptr, 0,720 MT7996_RRO_WINDOW_MAX_SIZE * sizeof(*addr));721 722 addr = dev->wed_rro.addr_elem[i].ptr;723 for (j = 0; j < MT7996_RRO_WINDOW_MAX_SIZE; j++) {724 addr->signature = 0xff;725 addr++;726 }727 728 wed->wlan.ind_cmd.addr_elem_phys[i] =729 dev->wed_rro.addr_elem[i].phy_addr;730 }731 732 ptr = dmam_alloc_coherent(dev->mt76.dma_dev,733 MT7996_RRO_WINDOW_MAX_LEN * sizeof(*addr),734 &dev->wed_rro.session.phy_addr,735 GFP_KERNEL);736 if (!ptr)737 return -ENOMEM;738 739 dev->wed_rro.session.ptr = ptr;740 addr = dev->wed_rro.session.ptr;741 for (i = 0; i < MT7996_RRO_WINDOW_MAX_LEN; i++) {742 addr->signature = 0xff;743 addr++;744 }745 746 /* rro hw init */747 /* TODO: remove line after WM has set */748 mt76_clear(dev, WF_RRO_AXI_MST_CFG, WF_RRO_AXI_MST_CFG_DIDX_OK);749 750 /* setup BA bitmap cache address */751 mt76_wr(dev, MT_RRO_BA_BITMAP_BASE0,752 dev->wed_rro.ba_bitmap[0].phy_addr);753 mt76_wr(dev, MT_RRO_BA_BITMAP_BASE1, 0);754 mt76_wr(dev, MT_RRO_BA_BITMAP_BASE_EXT0,755 dev->wed_rro.ba_bitmap[1].phy_addr);756 mt76_wr(dev, MT_RRO_BA_BITMAP_BASE_EXT1, 0);757 758 /* setup Address element address */759 for (i = 0; i < ARRAY_SIZE(dev->wed_rro.addr_elem); i++) {760 mt76_wr(dev, reg, dev->wed_rro.addr_elem[i].phy_addr >> 4);761 reg += 4;762 }763 764 /* setup Address element address - separate address segment mode */765 mt76_wr(dev, MT_RRO_ADDR_ARRAY_BASE1,766 MT_RRO_ADDR_ARRAY_ELEM_ADDR_SEG_MODE);767 768 wed->wlan.ind_cmd.win_size = ffs(MT7996_RRO_WINDOW_MAX_LEN) - 6;769 wed->wlan.ind_cmd.particular_sid = MT7996_RRO_MAX_SESSION;770 wed->wlan.ind_cmd.particular_se_phys = dev->wed_rro.session.phy_addr;771 wed->wlan.ind_cmd.se_group_nums = MT7996_RRO_ADDR_ELEM_LEN;772 wed->wlan.ind_cmd.ack_sn_addr = MT_RRO_ACK_SN_CTRL;773 774 mt76_wr(dev, MT_RRO_IND_CMD_SIGNATURE_BASE0, 0x15010e00);775 mt76_set(dev, MT_RRO_IND_CMD_SIGNATURE_BASE1,776 MT_RRO_IND_CMD_SIGNATURE_BASE1_EN);777 778 /* particular session configure */779 /* use max session idx + 1 as particular session id */780 mt76_wr(dev, MT_RRO_PARTICULAR_CFG0, dev->wed_rro.session.phy_addr);781 mt76_wr(dev, MT_RRO_PARTICULAR_CFG1,782 MT_RRO_PARTICULAR_CONFG_EN |783 FIELD_PREP(MT_RRO_PARTICULAR_SID, MT7996_RRO_MAX_SESSION));784 785 /* interrupt enable */786 mt76_wr(dev, MT_RRO_HOST_INT_ENA,787 MT_RRO_HOST_INT_ENA_HOST_RRO_DONE_ENA);788 789 /* rro ind cmd queue init */790 return mt7996_dma_rro_init(dev);791#else792 return 0;793#endif794}795 796static void mt7996_wed_rro_free(struct mt7996_dev *dev)797{798#ifdef CONFIG_NET_MEDIATEK_SOC_WED799 int i;800 801 if (!dev->has_rro)802 return;803 804 if (!mtk_wed_device_active(&dev->mt76.mmio.wed))805 return;806 807 for (i = 0; i < ARRAY_SIZE(dev->wed_rro.ba_bitmap); i++) {808 if (!dev->wed_rro.ba_bitmap[i].ptr)809 continue;810 811 dmam_free_coherent(dev->mt76.dma_dev,812 MT7996_RRO_BA_BITMAP_CR_SIZE,813 dev->wed_rro.ba_bitmap[i].ptr,814 dev->wed_rro.ba_bitmap[i].phy_addr);815 }816 817 for (i = 0; i < ARRAY_SIZE(dev->wed_rro.addr_elem); i++) {818 if (!dev->wed_rro.addr_elem[i].ptr)819 continue;820 821 dmam_free_coherent(dev->mt76.dma_dev,822 MT7996_RRO_WINDOW_MAX_SIZE *823 sizeof(struct mt7996_wed_rro_addr),824 dev->wed_rro.addr_elem[i].ptr,825 dev->wed_rro.addr_elem[i].phy_addr);826 }827 828 if (!dev->wed_rro.session.ptr)829 return;830 831 dmam_free_coherent(dev->mt76.dma_dev,832 MT7996_RRO_WINDOW_MAX_LEN *833 sizeof(struct mt7996_wed_rro_addr),834 dev->wed_rro.session.ptr,835 dev->wed_rro.session.phy_addr);836#endif837}838 839static void mt7996_wed_rro_work(struct work_struct *work)840{841#ifdef CONFIG_NET_MEDIATEK_SOC_WED842 struct mt7996_dev *dev;843 LIST_HEAD(list);844 845 dev = (struct mt7996_dev *)container_of(work, struct mt7996_dev,846 wed_rro.work);847 848 spin_lock_bh(&dev->wed_rro.lock);849 list_splice_init(&dev->wed_rro.poll_list, &list);850 spin_unlock_bh(&dev->wed_rro.lock);851 852 while (!list_empty(&list)) {853 struct mt7996_wed_rro_session_id *e;854 int i;855 856 e = list_first_entry(&list, struct mt7996_wed_rro_session_id,857 list);858 list_del_init(&e->list);859 860 for (i = 0; i < MT7996_RRO_WINDOW_MAX_LEN; i++) {861 void *ptr = dev->wed_rro.session.ptr;862 struct mt7996_wed_rro_addr *elem;863 u32 idx, elem_id = i;864 865 if (e->id == MT7996_RRO_MAX_SESSION)866 goto reset;867 868 idx = e->id / MT7996_RRO_BA_BITMAP_SESSION_SIZE;869 if (idx >= ARRAY_SIZE(dev->wed_rro.addr_elem))870 goto out;871 872 ptr = dev->wed_rro.addr_elem[idx].ptr;873 elem_id +=874 (e->id % MT7996_RRO_BA_BITMAP_SESSION_SIZE) *875 MT7996_RRO_WINDOW_MAX_LEN;876reset:877 elem = ptr + elem_id * sizeof(*elem);878 elem->signature = 0xff;879 }880 mt7996_mcu_wed_rro_reset_sessions(dev, e->id);881out:882 kfree(e);883 }884#endif885}886 887static int mt7996_init_hardware(struct mt7996_dev *dev)888{889 int ret, idx;890 891 mt76_wr(dev, MT_INT_SOURCE_CSR, ~0);892 if (is_mt7992(&dev->mt76)) {893 mt76_rmw(dev, MT_AFE_CTL_BAND_PLL_03(MT_BAND0), MT_AFE_CTL_BAND_PLL_03_MSB_EN, 0);894 mt76_rmw(dev, MT_AFE_CTL_BAND_PLL_03(MT_BAND1), MT_AFE_CTL_BAND_PLL_03_MSB_EN, 0);895 }896 897 INIT_WORK(&dev->init_work, mt7996_init_work);898 INIT_WORK(&dev->wed_rro.work, mt7996_wed_rro_work);899 INIT_LIST_HEAD(&dev->wed_rro.poll_list);900 spin_lock_init(&dev->wed_rro.lock);901 902 ret = mt7996_dma_init(dev);903 if (ret)904 return ret;905 906 set_bit(MT76_STATE_INITIALIZED, &dev->mphy.state);907 908 ret = mt7996_mcu_init(dev);909 if (ret)910 return ret;911 912 ret = mt7996_wed_rro_init(dev);913 if (ret)914 return ret;915 916 ret = mt7996_eeprom_init(dev);917 if (ret < 0)918 return ret;919 920 /* Beacon and mgmt frames should occupy wcid 0 */921 idx = mt76_wcid_alloc(dev->mt76.wcid_mask, MT7996_WTBL_STA);922 if (idx)923 return -ENOSPC;924 925 dev->mt76.global_wcid.idx = idx;926 dev->mt76.global_wcid.hw_key_idx = -1;927 dev->mt76.global_wcid.tx_info |= MT_WCID_TX_INFO_SET;928 rcu_assign_pointer(dev->mt76.wcid[idx], &dev->mt76.global_wcid);929 930 return 0;931}932 933void mt7996_set_stream_vht_txbf_caps(struct mt7996_phy *phy)934{935 int sts;936 u32 *cap;937 938 if (!phy->mt76->cap.has_5ghz)939 return;940 941 sts = hweight16(phy->mt76->chainmask);942 cap = &phy->mt76->sband_5g.sband.vht_cap.cap;943 944 *cap |= IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE |945 IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE;946 947 if (is_mt7996(phy->mt76->dev))948 *cap |= FIELD_PREP(IEEE80211_VHT_CAP_BEAMFORMEE_STS_MASK, 3);949 else950 *cap |= FIELD_PREP(IEEE80211_VHT_CAP_BEAMFORMEE_STS_MASK, 4);951 952 *cap &= ~(IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_MASK |953 IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE |954 IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE);955 956 if (sts < 2)957 return;958 959 *cap |= IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE |960 IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE |961 FIELD_PREP(IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_MASK, sts - 1);962}963 964static void965mt7996_set_stream_he_txbf_caps(struct mt7996_phy *phy,966 struct ieee80211_sta_he_cap *he_cap, int vif)967{968 struct ieee80211_he_cap_elem *elem = &he_cap->he_cap_elem;969 int sts = hweight16(phy->mt76->chainmask);970 u8 c;971 972#ifdef CONFIG_MAC80211_MESH973 if (vif == NL80211_IFTYPE_MESH_POINT)974 return;975#endif976 977 elem->phy_cap_info[3] &= ~IEEE80211_HE_PHY_CAP3_SU_BEAMFORMER;978 elem->phy_cap_info[4] &= ~IEEE80211_HE_PHY_CAP4_MU_BEAMFORMER;979 980 c = IEEE80211_HE_PHY_CAP5_BEAMFORMEE_NUM_SND_DIM_UNDER_80MHZ_MASK |981 IEEE80211_HE_PHY_CAP5_BEAMFORMEE_NUM_SND_DIM_ABOVE_80MHZ_MASK;982 elem->phy_cap_info[5] &= ~c;983 984 c = IEEE80211_HE_PHY_CAP6_TRIG_SU_BEAMFORMING_FB |985 IEEE80211_HE_PHY_CAP6_TRIG_MU_BEAMFORMING_PARTIAL_BW_FB;986 elem->phy_cap_info[6] &= ~c;987 988 elem->phy_cap_info[7] &= ~IEEE80211_HE_PHY_CAP7_MAX_NC_MASK;989 990 c = IEEE80211_HE_PHY_CAP2_NDP_4x_LTF_AND_3_2US |991 IEEE80211_HE_PHY_CAP2_UL_MU_FULL_MU_MIMO |992 IEEE80211_HE_PHY_CAP2_UL_MU_PARTIAL_MU_MIMO;993 elem->phy_cap_info[2] |= c;994 995 c = IEEE80211_HE_PHY_CAP4_SU_BEAMFORMEE;996 997 if (is_mt7996(phy->mt76->dev))998 c |= IEEE80211_HE_PHY_CAP4_BEAMFORMEE_MAX_STS_UNDER_80MHZ_4 |999 IEEE80211_HE_PHY_CAP4_BEAMFORMEE_MAX_STS_ABOVE_80MHZ_4;1000 else1001 c |= IEEE80211_HE_PHY_CAP4_BEAMFORMEE_MAX_STS_UNDER_80MHZ_5 |1002 IEEE80211_HE_PHY_CAP4_BEAMFORMEE_MAX_STS_ABOVE_80MHZ_5;1003 1004 elem->phy_cap_info[4] |= c;1005 1006 /* do not support NG16 due to spec D4.0 changes subcarrier idx */1007 c = IEEE80211_HE_PHY_CAP6_CODEBOOK_SIZE_42_SU |1008 IEEE80211_HE_PHY_CAP6_CODEBOOK_SIZE_75_MU;1009 1010 if (vif == NL80211_IFTYPE_STATION)1011 c |= IEEE80211_HE_PHY_CAP6_PARTIAL_BANDWIDTH_DL_MUMIMO;1012 1013 elem->phy_cap_info[6] |= c;1014 1015 if (sts < 2)1016 return;1017 1018 /* the maximum cap is 4 x 3, (Nr, Nc) = (3, 2) */1019 elem->phy_cap_info[7] |= min_t(int, sts - 1, 2) << 3;1020 1021 if (!(vif == NL80211_IFTYPE_AP || vif == NL80211_IFTYPE_STATION))1022 return;1023 1024 elem->phy_cap_info[3] |= IEEE80211_HE_PHY_CAP3_SU_BEAMFORMER;1025 1026 c = FIELD_PREP(IEEE80211_HE_PHY_CAP5_BEAMFORMEE_NUM_SND_DIM_UNDER_80MHZ_MASK,1027 sts - 1) |1028 FIELD_PREP(IEEE80211_HE_PHY_CAP5_BEAMFORMEE_NUM_SND_DIM_ABOVE_80MHZ_MASK,1029 sts - 1);1030 elem->phy_cap_info[5] |= c;1031 1032 if (vif != NL80211_IFTYPE_AP)1033 return;1034 1035 elem->phy_cap_info[4] |= IEEE80211_HE_PHY_CAP4_MU_BEAMFORMER;1036 1037 c = IEEE80211_HE_PHY_CAP6_TRIG_SU_BEAMFORMING_FB |1038 IEEE80211_HE_PHY_CAP6_TRIG_MU_BEAMFORMING_PARTIAL_BW_FB;1039 elem->phy_cap_info[6] |= c;1040 1041 c = IEEE80211_HE_PHY_CAP7_STBC_TX_ABOVE_80MHZ |1042 IEEE80211_HE_PHY_CAP7_STBC_RX_ABOVE_80MHZ;1043 elem->phy_cap_info[7] |= c;1044}1045 1046static void1047mt7996_init_he_caps(struct mt7996_phy *phy, enum nl80211_band band,1048 struct ieee80211_sband_iftype_data *data,1049 enum nl80211_iftype iftype)1050{1051 struct ieee80211_sta_he_cap *he_cap = &data->he_cap;1052 struct ieee80211_he_cap_elem *he_cap_elem = &he_cap->he_cap_elem;1053 struct ieee80211_he_mcs_nss_supp *he_mcs = &he_cap->he_mcs_nss_supp;1054 int i, nss = hweight8(phy->mt76->antenna_mask);1055 u16 mcs_map = 0;1056 1057 for (i = 0; i < 8; i++) {1058 if (i < nss)1059 mcs_map |= (IEEE80211_HE_MCS_SUPPORT_0_11 << (i * 2));1060 else1061 mcs_map |= (IEEE80211_HE_MCS_NOT_SUPPORTED << (i * 2));1062 }1063 1064 he_cap->has_he = true;1065 1066 he_cap_elem->mac_cap_info[0] = IEEE80211_HE_MAC_CAP0_HTC_HE;1067 he_cap_elem->mac_cap_info[3] = IEEE80211_HE_MAC_CAP3_OMI_CONTROL |1068 IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_EXT_3;1069 he_cap_elem->mac_cap_info[4] = IEEE80211_HE_MAC_CAP4_AMSDU_IN_AMPDU;1070 1071 if (band == NL80211_BAND_2GHZ)1072 he_cap_elem->phy_cap_info[0] =1073 IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_IN_2G;1074 else1075 he_cap_elem->phy_cap_info[0] =1076 IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_80MHZ_IN_5G |1077 IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_160MHZ_IN_5G;1078 1079 he_cap_elem->phy_cap_info[1] = IEEE80211_HE_PHY_CAP1_LDPC_CODING_IN_PAYLOAD;1080 he_cap_elem->phy_cap_info[2] = IEEE80211_HE_PHY_CAP2_STBC_TX_UNDER_80MHZ |1081 IEEE80211_HE_PHY_CAP2_STBC_RX_UNDER_80MHZ;1082 1083 switch (iftype) {1084 case NL80211_IFTYPE_AP:1085 he_cap_elem->mac_cap_info[0] |= IEEE80211_HE_MAC_CAP0_TWT_RES;1086 he_cap_elem->mac_cap_info[2] |= IEEE80211_HE_MAC_CAP2_BSR;1087 he_cap_elem->mac_cap_info[4] |= IEEE80211_HE_MAC_CAP4_BQR;1088 he_cap_elem->mac_cap_info[5] |=1089 IEEE80211_HE_MAC_CAP5_OM_CTRL_UL_MU_DATA_DIS_RX;1090 he_cap_elem->phy_cap_info[3] |=1091 IEEE80211_HE_PHY_CAP3_DCM_MAX_CONST_TX_QPSK |1092 IEEE80211_HE_PHY_CAP3_DCM_MAX_CONST_RX_QPSK;1093 he_cap_elem->phy_cap_info[6] |=1094 IEEE80211_HE_PHY_CAP6_PARTIAL_BW_EXT_RANGE |1095 IEEE80211_HE_PHY_CAP6_PPE_THRESHOLD_PRESENT;1096 he_cap_elem->phy_cap_info[9] |=1097 IEEE80211_HE_PHY_CAP9_TX_1024_QAM_LESS_THAN_242_TONE_RU |1098 IEEE80211_HE_PHY_CAP9_RX_1024_QAM_LESS_THAN_242_TONE_RU;1099 break;1100 case NL80211_IFTYPE_STATION:1101 he_cap_elem->mac_cap_info[1] |=1102 IEEE80211_HE_MAC_CAP1_TF_MAC_PAD_DUR_16US;1103 1104 if (band == NL80211_BAND_2GHZ)1105 he_cap_elem->phy_cap_info[0] |=1106 IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_RU_MAPPING_IN_2G;1107 else1108 he_cap_elem->phy_cap_info[0] |=1109 IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_RU_MAPPING_IN_5G;1110 1111 he_cap_elem->phy_cap_info[1] |=1112 IEEE80211_HE_PHY_CAP1_DEVICE_CLASS_A |1113 IEEE80211_HE_PHY_CAP1_HE_LTF_AND_GI_FOR_HE_PPDUS_0_8US;1114 he_cap_elem->phy_cap_info[3] |=1115 IEEE80211_HE_PHY_CAP3_DCM_MAX_CONST_TX_QPSK |1116 IEEE80211_HE_PHY_CAP3_DCM_MAX_CONST_RX_QPSK;1117 he_cap_elem->phy_cap_info[6] |=1118 IEEE80211_HE_PHY_CAP6_TRIG_CQI_FB |1119 IEEE80211_HE_PHY_CAP6_PARTIAL_BW_EXT_RANGE |1120 IEEE80211_HE_PHY_CAP6_PPE_THRESHOLD_PRESENT;1121 he_cap_elem->phy_cap_info[7] |=1122 IEEE80211_HE_PHY_CAP7_POWER_BOOST_FACTOR_SUPP |1123 IEEE80211_HE_PHY_CAP7_HE_SU_MU_PPDU_4XLTF_AND_08_US_GI;1124 he_cap_elem->phy_cap_info[8] |=1125 IEEE80211_HE_PHY_CAP8_20MHZ_IN_40MHZ_HE_PPDU_IN_2G |1126 IEEE80211_HE_PHY_CAP8_20MHZ_IN_160MHZ_HE_PPDU |1127 IEEE80211_HE_PHY_CAP8_80MHZ_IN_160MHZ_HE_PPDU |1128 IEEE80211_HE_PHY_CAP8_DCM_MAX_RU_484;1129 he_cap_elem->phy_cap_info[9] |=1130 IEEE80211_HE_PHY_CAP9_LONGER_THAN_16_SIGB_OFDM_SYM |1131 IEEE80211_HE_PHY_CAP9_NON_TRIGGERED_CQI_FEEDBACK |1132 IEEE80211_HE_PHY_CAP9_TX_1024_QAM_LESS_THAN_242_TONE_RU |1133 IEEE80211_HE_PHY_CAP9_RX_1024_QAM_LESS_THAN_242_TONE_RU |1134 IEEE80211_HE_PHY_CAP9_RX_FULL_BW_SU_USING_MU_WITH_COMP_SIGB |1135 IEEE80211_HE_PHY_CAP9_RX_FULL_BW_SU_USING_MU_WITH_NON_COMP_SIGB;1136 break;1137 default:1138 break;1139 }1140 1141 he_mcs->rx_mcs_80 = cpu_to_le16(mcs_map);1142 he_mcs->tx_mcs_80 = cpu_to_le16(mcs_map);1143 he_mcs->rx_mcs_160 = cpu_to_le16(mcs_map);1144 he_mcs->tx_mcs_160 = cpu_to_le16(mcs_map);1145 1146 mt7996_set_stream_he_txbf_caps(phy, he_cap, iftype);1147 1148 memset(he_cap->ppe_thres, 0, sizeof(he_cap->ppe_thres));1149 if (he_cap_elem->phy_cap_info[6] &1150 IEEE80211_HE_PHY_CAP6_PPE_THRESHOLD_PRESENT) {1151 mt76_connac_gen_ppe_thresh(he_cap->ppe_thres, nss);1152 } else {1153 he_cap_elem->phy_cap_info[9] |=1154 u8_encode_bits(IEEE80211_HE_PHY_CAP9_NOMINAL_PKT_PADDING_16US,1155 IEEE80211_HE_PHY_CAP9_NOMINAL_PKT_PADDING_MASK);1156 }1157 1158 if (band == NL80211_BAND_6GHZ) {1159 u16 cap = IEEE80211_HE_6GHZ_CAP_TX_ANTPAT_CONS |1160 IEEE80211_HE_6GHZ_CAP_RX_ANTPAT_CONS;1161 1162 cap |= u16_encode_bits(IEEE80211_HT_MPDU_DENSITY_0_5,1163 IEEE80211_HE_6GHZ_CAP_MIN_MPDU_START) |1164 u16_encode_bits(IEEE80211_VHT_MAX_AMPDU_1024K,1165 IEEE80211_HE_6GHZ_CAP_MAX_AMPDU_LEN_EXP) |1166 u16_encode_bits(IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454,1167 IEEE80211_HE_6GHZ_CAP_MAX_MPDU_LEN);1168 1169 data->he_6ghz_capa.capa = cpu_to_le16(cap);1170 }1171}1172 1173static void1174mt7996_init_eht_caps(struct mt7996_phy *phy, enum nl80211_band band,1175 struct ieee80211_sband_iftype_data *data,1176 enum nl80211_iftype iftype)1177{1178 struct ieee80211_sta_eht_cap *eht_cap = &data->eht_cap;1179 struct ieee80211_eht_cap_elem_fixed *eht_cap_elem = &eht_cap->eht_cap_elem;1180 struct ieee80211_eht_mcs_nss_supp *eht_nss = &eht_cap->eht_mcs_nss_supp;1181 enum nl80211_chan_width width = phy->mt76->chandef.width;1182 int nss = hweight8(phy->mt76->antenna_mask);1183 int sts = hweight16(phy->mt76->chainmask);1184 u8 val;1185 1186 if (!phy->dev->has_eht)1187 return;1188 1189 eht_cap->has_eht = true;1190 1191 eht_cap_elem->mac_cap_info[0] =1192 IEEE80211_EHT_MAC_CAP0_EPCS_PRIO_ACCESS |1193 IEEE80211_EHT_MAC_CAP0_OM_CONTROL;1194 1195 eht_cap_elem->phy_cap_info[0] =1196 IEEE80211_EHT_PHY_CAP0_NDP_4_EHT_LFT_32_GI |1197 IEEE80211_EHT_PHY_CAP0_SU_BEAMFORMER |1198 IEEE80211_EHT_PHY_CAP0_SU_BEAMFORMEE;1199 1200 /* Set the maximum capability regardless of the antenna configuration. */1201 val = is_mt7992(phy->mt76->dev) ? 4 : 3;1202 eht_cap_elem->phy_cap_info[0] |=1203 u8_encode_bits(u8_get_bits(val, BIT(0)),1204 IEEE80211_EHT_PHY_CAP0_BEAMFORMEE_SS_80MHZ_MASK);1205 1206 eht_cap_elem->phy_cap_info[1] =1207 u8_encode_bits(u8_get_bits(val, GENMASK(2, 1)),1208 IEEE80211_EHT_PHY_CAP1_BEAMFORMEE_SS_80MHZ_MASK) |1209 u8_encode_bits(val,1210 IEEE80211_EHT_PHY_CAP1_BEAMFORMEE_SS_160MHZ_MASK);1211 1212 eht_cap_elem->phy_cap_info[2] =1213 u8_encode_bits(sts - 1, IEEE80211_EHT_PHY_CAP2_SOUNDING_DIM_80MHZ_MASK) |1214 u8_encode_bits(sts - 1, IEEE80211_EHT_PHY_CAP2_SOUNDING_DIM_160MHZ_MASK);1215 1216 if (band == NL80211_BAND_6GHZ) {1217 eht_cap_elem->phy_cap_info[0] |=1218 IEEE80211_EHT_PHY_CAP0_320MHZ_IN_6GHZ;1219 1220 eht_cap_elem->phy_cap_info[1] |=1221 u8_encode_bits(val,1222 IEEE80211_EHT_PHY_CAP1_BEAMFORMEE_SS_320MHZ_MASK);1223 1224 eht_cap_elem->phy_cap_info[2] |=1225 u8_encode_bits(sts - 1,1226 IEEE80211_EHT_PHY_CAP2_SOUNDING_DIM_320MHZ_MASK);1227 }1228 1229 eht_cap_elem->phy_cap_info[3] =1230 IEEE80211_EHT_PHY_CAP3_NG_16_SU_FEEDBACK |1231 IEEE80211_EHT_PHY_CAP3_NG_16_MU_FEEDBACK |1232 IEEE80211_EHT_PHY_CAP3_CODEBOOK_4_2_SU_FDBK |1233 IEEE80211_EHT_PHY_CAP3_CODEBOOK_7_5_MU_FDBK;1234 1235 eht_cap_elem->phy_cap_info[4] =1236 u8_encode_bits(min_t(int, sts - 1, 2),1237 IEEE80211_EHT_PHY_CAP4_MAX_NC_MASK);1238 1239 eht_cap_elem->phy_cap_info[5] =1240 u8_encode_bits(IEEE80211_EHT_PHY_CAP5_COMMON_NOMINAL_PKT_PAD_16US,1241 IEEE80211_EHT_PHY_CAP5_COMMON_NOMINAL_PKT_PAD_MASK) |1242 u8_encode_bits(u8_get_bits(0x11, GENMASK(1, 0)),1243 IEEE80211_EHT_PHY_CAP5_MAX_NUM_SUPP_EHT_LTF_MASK);1244 1245 val = width == NL80211_CHAN_WIDTH_320 ? 0xf :1246 width == NL80211_CHAN_WIDTH_160 ? 0x7 :1247 width == NL80211_CHAN_WIDTH_80 ? 0x3 : 0x1;1248 eht_cap_elem->phy_cap_info[6] =1249 u8_encode_bits(u8_get_bits(0x11, GENMASK(4, 2)),1250 IEEE80211_EHT_PHY_CAP6_MAX_NUM_SUPP_EHT_LTF_MASK) |1251 u8_encode_bits(val, IEEE80211_EHT_PHY_CAP6_MCS15_SUPP_MASK);1252 1253 val = u8_encode_bits(nss, IEEE80211_EHT_MCS_NSS_RX) |1254 u8_encode_bits(nss, IEEE80211_EHT_MCS_NSS_TX);1255#define SET_EHT_MAX_NSS(_bw, _val) do { \1256 eht_nss->bw._##_bw.rx_tx_mcs9_max_nss = _val; \1257 eht_nss->bw._##_bw.rx_tx_mcs11_max_nss = _val; \1258 eht_nss->bw._##_bw.rx_tx_mcs13_max_nss = _val; \1259 } while (0)1260 1261 SET_EHT_MAX_NSS(80, val);1262 SET_EHT_MAX_NSS(160, val);1263 if (band == NL80211_BAND_6GHZ)1264 SET_EHT_MAX_NSS(320, val);1265#undef SET_EHT_MAX_NSS1266 1267 if (iftype != NL80211_IFTYPE_AP)1268 return;1269 1270 eht_cap_elem->phy_cap_info[3] |=1271 IEEE80211_EHT_PHY_CAP3_TRIG_SU_BF_FDBK |1272 IEEE80211_EHT_PHY_CAP3_TRIG_MU_BF_PART_BW_FDBK;1273 1274 eht_cap_elem->phy_cap_info[7] =1275 IEEE80211_EHT_PHY_CAP7_NON_OFDMA_UL_MU_MIMO_80MHZ |1276 IEEE80211_EHT_PHY_CAP7_NON_OFDMA_UL_MU_MIMO_160MHZ |1277 IEEE80211_EHT_PHY_CAP7_MU_BEAMFORMER_80MHZ |1278 IEEE80211_EHT_PHY_CAP7_MU_BEAMFORMER_160MHZ;1279 1280 if (band != NL80211_BAND_6GHZ)1281 return;1282 1283 eht_cap_elem->phy_cap_info[7] |=1284 IEEE80211_EHT_PHY_CAP7_NON_OFDMA_UL_MU_MIMO_320MHZ |1285 IEEE80211_EHT_PHY_CAP7_MU_BEAMFORMER_320MHZ;1286}1287 1288static void1289__mt7996_set_stream_he_eht_caps(struct mt7996_phy *phy,1290 struct ieee80211_supported_band *sband,1291 enum nl80211_band band)1292{1293 struct ieee80211_sband_iftype_data *data = phy->iftype[band];1294 int i, n = 0;1295 1296 for (i = 0; i < NUM_NL80211_IFTYPES; i++) {1297 switch (i) {1298 case NL80211_IFTYPE_STATION:1299 case NL80211_IFTYPE_AP:1300#ifdef CONFIG_MAC80211_MESH1301 case NL80211_IFTYPE_MESH_POINT:1302#endif1303 break;1304 default:1305 continue;1306 }1307 1308 data[n].types_mask = BIT(i);1309 mt7996_init_he_caps(phy, band, &data[n], i);1310 mt7996_init_eht_caps(phy, band, &data[n], i);1311 1312 n++;1313 }1314 1315 _ieee80211_set_sband_iftype_data(sband, data, n);1316}1317 1318void mt7996_set_stream_he_eht_caps(struct mt7996_phy *phy)1319{1320 if (phy->mt76->cap.has_2ghz)1321 __mt7996_set_stream_he_eht_caps(phy, &phy->mt76->sband_2g.sband,1322 NL80211_BAND_2GHZ);1323 1324 if (phy->mt76->cap.has_5ghz)1325 __mt7996_set_stream_he_eht_caps(phy, &phy->mt76->sband_5g.sband,1326 NL80211_BAND_5GHZ);1327 1328 if (phy->mt76->cap.has_6ghz)1329 __mt7996_set_stream_he_eht_caps(phy, &phy->mt76->sband_6g.sband,1330 NL80211_BAND_6GHZ);1331}1332 1333int mt7996_register_device(struct mt7996_dev *dev)1334{1335 struct ieee80211_hw *hw = mt76_hw(dev);1336 int ret;1337 1338 dev->phy.dev = dev;1339 dev->phy.mt76 = &dev->mt76.phy;1340 dev->mt76.phy.priv = &dev->phy;1341 INIT_WORK(&dev->rc_work, mt7996_mac_sta_rc_work);1342 INIT_DELAYED_WORK(&dev->mphy.mac_work, mt7996_mac_work);1343 INIT_LIST_HEAD(&dev->sta_rc_list);1344 INIT_LIST_HEAD(&dev->twt_list);1345 1346 init_waitqueue_head(&dev->reset_wait);1347 INIT_WORK(&dev->reset_work, mt7996_mac_reset_work);1348 INIT_WORK(&dev->dump_work, mt7996_mac_dump_work);1349 mutex_init(&dev->dump_mutex);1350 1351 ret = mt7996_init_hardware(dev);1352 if (ret)1353 return ret;1354 1355 mt7996_init_wiphy(hw, &dev->mt76.mmio.wed);1356 1357 ret = mt76_register_device(&dev->mt76, true, mt76_rates,1358 ARRAY_SIZE(mt76_rates));1359 if (ret)1360 return ret;1361 1362 ret = mt7996_thermal_init(&dev->phy);1363 if (ret)1364 return ret;1365 1366 ret = mt7996_register_phy(dev, mt7996_phy2(dev), MT_BAND1);1367 if (ret)1368 return ret;1369 1370 ret = mt7996_register_phy(dev, mt7996_phy3(dev), MT_BAND2);1371 if (ret)1372 return ret;1373 1374 ieee80211_queue_work(mt76_hw(dev), &dev->init_work);1375 1376 dev->recovery.hw_init_done = true;1377 1378 ret = mt7996_init_debugfs(&dev->phy);1379 if (ret)1380 goto error;1381 1382 ret = mt7996_coredump_register(dev);1383 if (ret)1384 goto error;1385 1386 return 0;1387 1388error:1389 cancel_work_sync(&dev->init_work);1390 1391 return ret;1392}1393 1394void mt7996_unregister_device(struct mt7996_dev *dev)1395{1396 cancel_work_sync(&dev->wed_rro.work);1397 mt7996_unregister_phy(mt7996_phy3(dev), MT_BAND2);1398 mt7996_unregister_phy(mt7996_phy2(dev), MT_BAND1);1399 mt7996_unregister_thermal(&dev->phy);1400 mt7996_coredump_unregister(dev);1401 mt76_unregister_device(&dev->mt76);1402 mt7996_wed_rro_free(dev);1403 mt7996_mcu_exit(dev);1404 mt7996_tx_token_put(dev);1405 mt7996_dma_cleanup(dev);1406 tasklet_disable(&dev->mt76.irq_tasklet);1407 1408 mt76_free_device(&dev->mt76);1409}1410