1284 lines · c
1// SPDX-License-Identifier: ISC2/* Copyright (C) 2020 MediaTek Inc. */3 4#include <linux/etherdevice.h>5#include <linux/hwmon.h>6#include <linux/hwmon-sysfs.h>7#include <linux/of.h>8#include <linux/thermal.h>9#include "mt7915.h"10#include "mac.h"11#include "mcu.h"12#include "coredump.h"13#include "eeprom.h"14 15static const struct ieee80211_iface_limit if_limits[] = {16 {17 .max = 1,18 .types = BIT(NL80211_IFTYPE_ADHOC)19 }, {20 .max = 16,21 .types = BIT(NL80211_IFTYPE_AP)22#ifdef CONFIG_MAC80211_MESH23 | BIT(NL80211_IFTYPE_MESH_POINT)24#endif25 }, {26 .max = MT7915_MAX_INTERFACES,27 .types = BIT(NL80211_IFTYPE_STATION)28 }29};30 31static const struct ieee80211_iface_combination if_comb[] = {32 {33 .limits = if_limits,34 .n_limits = ARRAY_SIZE(if_limits),35 .max_interfaces = MT7915_MAX_INTERFACES,36 .num_different_channels = 1,37 .beacon_int_infra_match = true,38 .radar_detect_widths = BIT(NL80211_CHAN_WIDTH_20_NOHT) |39 BIT(NL80211_CHAN_WIDTH_20) |40 BIT(NL80211_CHAN_WIDTH_40) |41 BIT(NL80211_CHAN_WIDTH_80) |42 BIT(NL80211_CHAN_WIDTH_160),43 }44};45 46static ssize_t mt7915_thermal_temp_show(struct device *dev,47 struct device_attribute *attr,48 char *buf)49{50 struct mt7915_phy *phy = dev_get_drvdata(dev);51 int i = to_sensor_dev_attr(attr)->index;52 int temperature;53 54 switch (i) {55 case 0:56 temperature = mt7915_mcu_get_temperature(phy);57 if (temperature < 0)58 return temperature;59 /* display in millidegree celcius */60 return sprintf(buf, "%u\n", temperature * 1000);61 case 1:62 case 2:63 return sprintf(buf, "%u\n",64 phy->throttle_temp[i - 1] * 1000);65 case 3:66 return sprintf(buf, "%hhu\n", phy->throttle_state);67 default:68 return -EINVAL;69 }70}71 72static ssize_t mt7915_thermal_temp_store(struct device *dev,73 struct device_attribute *attr,74 const char *buf, size_t count)75{76 struct mt7915_phy *phy = dev_get_drvdata(dev);77 int ret, i = to_sensor_dev_attr(attr)->index;78 long val;79 80 ret = kstrtol(buf, 10, &val);81 if (ret < 0)82 return ret;83 84 mutex_lock(&phy->dev->mt76.mutex);85 val = clamp_val(DIV_ROUND_CLOSEST(val, 1000), 60, 130);86 87 if ((i - 1 == MT7915_CRIT_TEMP_IDX &&88 val > phy->throttle_temp[MT7915_MAX_TEMP_IDX]) ||89 (i - 1 == MT7915_MAX_TEMP_IDX &&90 val < phy->throttle_temp[MT7915_CRIT_TEMP_IDX])) {91 dev_err(phy->dev->mt76.dev,92 "temp1_max shall be greater than temp1_crit.");93 mutex_unlock(&phy->dev->mt76.mutex);94 return -EINVAL;95 }96 97 phy->throttle_temp[i - 1] = val;98 mutex_unlock(&phy->dev->mt76.mutex);99 100 ret = mt7915_mcu_set_thermal_protect(phy);101 if (ret)102 return ret;103 104 return count;105}106 107static SENSOR_DEVICE_ATTR_RO(temp1_input, mt7915_thermal_temp, 0);108static SENSOR_DEVICE_ATTR_RW(temp1_crit, mt7915_thermal_temp, 1);109static SENSOR_DEVICE_ATTR_RW(temp1_max, mt7915_thermal_temp, 2);110static SENSOR_DEVICE_ATTR_RO(throttle1, mt7915_thermal_temp, 3);111 112static struct attribute *mt7915_hwmon_attrs[] = {113 &sensor_dev_attr_temp1_input.dev_attr.attr,114 &sensor_dev_attr_temp1_crit.dev_attr.attr,115 &sensor_dev_attr_temp1_max.dev_attr.attr,116 &sensor_dev_attr_throttle1.dev_attr.attr,117 NULL,118};119ATTRIBUTE_GROUPS(mt7915_hwmon);120 121static int122mt7915_thermal_get_max_throttle_state(struct thermal_cooling_device *cdev,123 unsigned long *state)124{125 *state = MT7915_CDEV_THROTTLE_MAX;126 127 return 0;128}129 130static int131mt7915_thermal_get_cur_throttle_state(struct thermal_cooling_device *cdev,132 unsigned long *state)133{134 struct mt7915_phy *phy = cdev->devdata;135 136 *state = phy->cdev_state;137 138 return 0;139}140 141static int142mt7915_thermal_set_cur_throttle_state(struct thermal_cooling_device *cdev,143 unsigned long state)144{145 struct mt7915_phy *phy = cdev->devdata;146 u8 throttling = MT7915_THERMAL_THROTTLE_MAX - state;147 int ret;148 149 if (state > MT7915_CDEV_THROTTLE_MAX) {150 dev_err(phy->dev->mt76.dev,151 "please specify a valid throttling state\n");152 return -EINVAL;153 }154 155 if (state == phy->cdev_state)156 return 0;157 158 /*159 * cooling_device convention: 0 = no cooling, more = more cooling160 * mcu convention: 1 = max cooling, more = less cooling161 */162 ret = mt7915_mcu_set_thermal_throttling(phy, throttling);163 if (ret)164 return ret;165 166 phy->cdev_state = state;167 168 return 0;169}170 171static const struct thermal_cooling_device_ops mt7915_thermal_ops = {172 .get_max_state = mt7915_thermal_get_max_throttle_state,173 .get_cur_state = mt7915_thermal_get_cur_throttle_state,174 .set_cur_state = mt7915_thermal_set_cur_throttle_state,175};176 177static void mt7915_unregister_thermal(struct mt7915_phy *phy)178{179 struct wiphy *wiphy = phy->mt76->hw->wiphy;180 181 if (!phy->cdev)182 return;183 184 sysfs_remove_link(&wiphy->dev.kobj, "cooling_device");185 thermal_cooling_device_unregister(phy->cdev);186}187 188static int mt7915_thermal_init(struct mt7915_phy *phy)189{190 struct wiphy *wiphy = phy->mt76->hw->wiphy;191 struct thermal_cooling_device *cdev;192 struct device *hwmon;193 const char *name;194 195 name = devm_kasprintf(&wiphy->dev, GFP_KERNEL, "mt7915_%s",196 wiphy_name(wiphy));197 if (!name)198 return -ENOMEM;199 200 cdev = thermal_cooling_device_register(name, phy, &mt7915_thermal_ops);201 if (!IS_ERR(cdev)) {202 if (sysfs_create_link(&wiphy->dev.kobj, &cdev->device.kobj,203 "cooling_device") < 0)204 thermal_cooling_device_unregister(cdev);205 else206 phy->cdev = cdev;207 }208 209 /* initialize critical/maximum high temperature */210 phy->throttle_temp[MT7915_CRIT_TEMP_IDX] = MT7915_CRIT_TEMP;211 phy->throttle_temp[MT7915_MAX_TEMP_IDX] = MT7915_MAX_TEMP;212 213 if (!IS_REACHABLE(CONFIG_HWMON))214 return 0;215 216 hwmon = devm_hwmon_device_register_with_groups(&wiphy->dev, name, phy,217 mt7915_hwmon_groups);218 return PTR_ERR_OR_ZERO(hwmon);219}220 221static void mt7915_led_set_config(struct led_classdev *led_cdev,222 u8 delay_on, u8 delay_off)223{224 struct mt7915_dev *dev;225 struct mt76_phy *mphy;226 u32 val;227 228 mphy = container_of(led_cdev, struct mt76_phy, leds.cdev);229 dev = container_of(mphy->dev, struct mt7915_dev, mt76);230 231 /* set PWM mode */232 val = FIELD_PREP(MT_LED_STATUS_DURATION, 0xffff) |233 FIELD_PREP(MT_LED_STATUS_OFF, delay_off) |234 FIELD_PREP(MT_LED_STATUS_ON, delay_on);235 mt76_wr(dev, MT_LED_STATUS_0(mphy->band_idx), val);236 mt76_wr(dev, MT_LED_STATUS_1(mphy->band_idx), val);237 238 /* enable LED */239 mt76_wr(dev, MT_LED_EN(mphy->band_idx), 1);240 241 /* control LED */242 val = MT_LED_CTRL_KICK;243 if (dev->mphy.leds.al)244 val |= MT_LED_CTRL_POLARITY;245 if (mphy->band_idx)246 val |= MT_LED_CTRL_BAND;247 248 mt76_wr(dev, MT_LED_CTRL(mphy->band_idx), val);249 mt76_clear(dev, MT_LED_CTRL(mphy->band_idx), MT_LED_CTRL_KICK);250}251 252static int mt7915_led_set_blink(struct led_classdev *led_cdev,253 unsigned long *delay_on,254 unsigned long *delay_off)255{256 u16 delta_on = 0, delta_off = 0;257 258#define HW_TICK 10259#define TO_HW_TICK(_t) (((_t) > HW_TICK) ? ((_t) / HW_TICK) : HW_TICK)260 261 if (*delay_on)262 delta_on = TO_HW_TICK(*delay_on);263 if (*delay_off)264 delta_off = TO_HW_TICK(*delay_off);265 266 mt7915_led_set_config(led_cdev, delta_on, delta_off);267 268 return 0;269}270 271static void mt7915_led_set_brightness(struct led_classdev *led_cdev,272 enum led_brightness brightness)273{274 if (!brightness)275 mt7915_led_set_config(led_cdev, 0, 0xff);276 else277 mt7915_led_set_config(led_cdev, 0xff, 0);278}279 280static void __mt7915_init_txpower(struct mt7915_phy *phy,281 struct ieee80211_supported_band *sband)282{283 struct mt7915_dev *dev = phy->dev;284 int i, n_chains = hweight16(phy->mt76->chainmask);285 int nss_delta = mt76_tx_power_nss_delta(n_chains);286 int pwr_delta = mt7915_eeprom_get_power_delta(dev, sband->band);287 struct mt76_power_limits limits;288 289 for (i = 0; i < sband->n_channels; i++) {290 struct ieee80211_channel *chan = &sband->channels[i];291 u32 target_power = 0;292 int j;293 294 for (j = 0; j < n_chains; j++) {295 u32 val;296 297 val = mt7915_eeprom_get_target_power(dev, chan, j);298 target_power = max(target_power, val);299 }300 301 target_power += pwr_delta;302 target_power = mt76_get_rate_power_limits(phy->mt76, chan,303 &limits,304 target_power);305 target_power += nss_delta;306 target_power = DIV_ROUND_UP(target_power, 2);307 chan->max_power = min_t(int, chan->max_reg_power,308 target_power);309 chan->orig_mpwr = target_power;310 }311}312 313void mt7915_init_txpower(struct mt7915_phy *phy)314{315 if (!phy)316 return;317 318 if (phy->mt76->cap.has_2ghz)319 __mt7915_init_txpower(phy, &phy->mt76->sband_2g.sband);320 if (phy->mt76->cap.has_5ghz)321 __mt7915_init_txpower(phy, &phy->mt76->sband_5g.sband);322 if (phy->mt76->cap.has_6ghz)323 __mt7915_init_txpower(phy, &phy->mt76->sband_6g.sband);324}325 326static void327mt7915_regd_notifier(struct wiphy *wiphy,328 struct regulatory_request *request)329{330 struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);331 struct mt7915_dev *dev = mt7915_hw_dev(hw);332 struct mt76_phy *mphy = hw->priv;333 struct mt7915_phy *phy = mphy->priv;334 335 memcpy(dev->mt76.alpha2, request->alpha2, sizeof(dev->mt76.alpha2));336 dev->mt76.region = request->dfs_region;337 338 if (dev->mt76.region == NL80211_DFS_UNSET)339 mt7915_mcu_rdd_background_enable(phy, NULL);340 341 mt7915_init_txpower(phy);342 343 mphy->dfs_state = MT_DFS_STATE_UNKNOWN;344 mt7915_dfs_init_radar_detector(phy);345}346 347static void348mt7915_init_wiphy(struct mt7915_phy *phy)349{350 struct mt76_phy *mphy = phy->mt76;351 struct ieee80211_hw *hw = mphy->hw;352 struct mt76_dev *mdev = &phy->dev->mt76;353 struct wiphy *wiphy = hw->wiphy;354 struct mt7915_dev *dev = phy->dev;355 356 hw->queues = 4;357 hw->max_rx_aggregation_subframes = IEEE80211_MAX_AMPDU_BUF_HE;358 hw->max_tx_aggregation_subframes = IEEE80211_MAX_AMPDU_BUF_HE;359 hw->netdev_features = NETIF_F_RXCSUM;360 361 if (mtk_wed_device_active(&mdev->mmio.wed))362 hw->netdev_features |= NETIF_F_HW_TC;363 364 hw->radiotap_timestamp.units_pos =365 IEEE80211_RADIOTAP_TIMESTAMP_UNIT_US;366 367 phy->slottime = 9;368 369 hw->sta_data_size = sizeof(struct mt7915_sta);370 hw->vif_data_size = sizeof(struct mt7915_vif);371 372 wiphy->iface_combinations = if_comb;373 wiphy->n_iface_combinations = ARRAY_SIZE(if_comb);374 wiphy->reg_notifier = mt7915_regd_notifier;375 wiphy->flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH;376 wiphy->mbssid_max_interfaces = 16;377 378 wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_BSS_COLOR);379 wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_VHT_IBSS);380 wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_BEACON_RATE_LEGACY);381 wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_BEACON_RATE_HT);382 wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_BEACON_RATE_VHT);383 wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_BEACON_RATE_HE);384 wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_UNSOL_BCAST_PROBE_RESP);385 wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_FILS_DISCOVERY);386 wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_ACK_SIGNAL_SUPPORT);387 wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_CAN_REPLACE_PTK0);388 389 if (!is_mt7915(&dev->mt76))390 wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_STA_TX_PWR);391 392 if (!mdev->dev->of_node ||393 !of_property_read_bool(mdev->dev->of_node,394 "mediatek,disable-radar-background"))395 wiphy_ext_feature_set(wiphy,396 NL80211_EXT_FEATURE_RADAR_BACKGROUND);397 398 ieee80211_hw_set(hw, HAS_RATE_CONTROL);399 ieee80211_hw_set(hw, SUPPORTS_TX_ENCAP_OFFLOAD);400 ieee80211_hw_set(hw, SUPPORTS_RX_DECAP_OFFLOAD);401 ieee80211_hw_set(hw, SUPPORTS_MULTI_BSSID);402 ieee80211_hw_set(hw, WANT_MONITOR_VIF);403 ieee80211_hw_set(hw, SUPPORTS_TX_FRAG);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 if (is_mt7915(&dev->mt76))412 phy->mt76->sband_2g.sband.ht_cap.ampdu_density =413 IEEE80211_HT_MPDU_DENSITY_4;414 else415 phy->mt76->sband_2g.sband.ht_cap.ampdu_density =416 IEEE80211_HT_MPDU_DENSITY_2;417 }418 419 if (phy->mt76->cap.has_5ghz) {420 struct ieee80211_sta_vht_cap *vht_cap;421 422 vht_cap = &phy->mt76->sband_5g.sband.vht_cap;423 phy->mt76->sband_5g.sband.ht_cap.cap |=424 IEEE80211_HT_CAP_LDPC_CODING |425 IEEE80211_HT_CAP_MAX_AMSDU;426 427 if (is_mt7915(&dev->mt76)) {428 phy->mt76->sband_5g.sband.ht_cap.ampdu_density =429 IEEE80211_HT_MPDU_DENSITY_4;430 431 vht_cap->cap |=432 IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_7991 |433 IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK;434 435 if (!dev->dbdc_support)436 vht_cap->cap |=437 IEEE80211_VHT_CAP_SHORT_GI_160 |438 FIELD_PREP(IEEE80211_VHT_CAP_EXT_NSS_BW_MASK, 1);439 } else {440 phy->mt76->sband_5g.sband.ht_cap.ampdu_density =441 IEEE80211_HT_MPDU_DENSITY_2;442 443 vht_cap->cap |=444 IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454 |445 IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK;446 447 /* mt7916 dbdc with 2g 2x2 bw40 and 5g 2x2 bw160c */448 vht_cap->cap |=449 IEEE80211_VHT_CAP_SHORT_GI_160 |450 IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ;451 }452 453 if (!is_mt7915(&dev->mt76) || !dev->dbdc_support)454 ieee80211_hw_set(hw, SUPPORTS_VHT_EXT_NSS_BW);455 }456 457 mt76_set_stream_caps(phy->mt76, true);458 mt7915_set_stream_vht_txbf_caps(phy);459 mt7915_set_stream_he_caps(phy);460 mt7915_init_txpower(phy);461 462 wiphy->available_antennas_rx = phy->mt76->antenna_mask;463 wiphy->available_antennas_tx = phy->mt76->antenna_mask;464 465 /* init led callbacks */466 if (IS_ENABLED(CONFIG_MT76_LEDS)) {467 mphy->leds.cdev.brightness_set = mt7915_led_set_brightness;468 mphy->leds.cdev.blink_set = mt7915_led_set_blink;469 }470}471 472static void473mt7915_mac_init_band(struct mt7915_dev *dev, u8 band)474{475 u32 mask, set;476 477 mt76_rmw_field(dev, MT_TMAC_CTCR0(band),478 MT_TMAC_CTCR0_INS_DDLMT_REFTIME, 0x3f);479 mt76_set(dev, MT_TMAC_CTCR0(band),480 MT_TMAC_CTCR0_INS_DDLMT_VHT_SMPDU_EN |481 MT_TMAC_CTCR0_INS_DDLMT_EN);482 483 mask = MT_MDP_RCFR0_MCU_RX_MGMT |484 MT_MDP_RCFR0_MCU_RX_CTL_NON_BAR |485 MT_MDP_RCFR0_MCU_RX_CTL_BAR;486 set = FIELD_PREP(MT_MDP_RCFR0_MCU_RX_MGMT, MT_MDP_TO_HIF) |487 FIELD_PREP(MT_MDP_RCFR0_MCU_RX_CTL_NON_BAR, MT_MDP_TO_HIF) |488 FIELD_PREP(MT_MDP_RCFR0_MCU_RX_CTL_BAR, MT_MDP_TO_HIF);489 mt76_rmw(dev, MT_MDP_BNRCFR0(band), mask, set);490 491 mask = MT_MDP_RCFR1_MCU_RX_BYPASS |492 MT_MDP_RCFR1_RX_DROPPED_UCAST |493 MT_MDP_RCFR1_RX_DROPPED_MCAST;494 set = FIELD_PREP(MT_MDP_RCFR1_MCU_RX_BYPASS, MT_MDP_TO_HIF) |495 FIELD_PREP(MT_MDP_RCFR1_RX_DROPPED_UCAST, MT_MDP_TO_HIF) |496 FIELD_PREP(MT_MDP_RCFR1_RX_DROPPED_MCAST, MT_MDP_TO_HIF);497 mt76_rmw(dev, MT_MDP_BNRCFR1(band), mask, set);498 499 mt76_rmw_field(dev, MT_DMA_DCR0(band), MT_DMA_DCR0_MAX_RX_LEN, 0x680);500 501 /* mt7915: disable rx rate report by default due to hw issues */502 mt76_clear(dev, MT_DMA_DCR0(band), MT_DMA_DCR0_RXD_G5_EN);503 504 /* clear estimated value of EIFS for Rx duration & OBSS time */505 mt76_wr(dev, MT_WF_RMAC_RSVD0(band), MT_WF_RMAC_RSVD0_EIFS_CLR);506 507 /* clear backoff time for Rx duration */508 mt76_clear(dev, MT_WF_RMAC_MIB_AIRTIME1(band),509 MT_WF_RMAC_MIB_NONQOSD_BACKOFF);510 mt76_clear(dev, MT_WF_RMAC_MIB_AIRTIME3(band),511 MT_WF_RMAC_MIB_QOS01_BACKOFF);512 mt76_clear(dev, MT_WF_RMAC_MIB_AIRTIME4(band),513 MT_WF_RMAC_MIB_QOS23_BACKOFF);514 515 /* clear backoff time and set software compensation for OBSS time */516 mask = MT_WF_RMAC_MIB_OBSS_BACKOFF | MT_WF_RMAC_MIB_ED_OFFSET;517 set = FIELD_PREP(MT_WF_RMAC_MIB_OBSS_BACKOFF, 0) |518 FIELD_PREP(MT_WF_RMAC_MIB_ED_OFFSET, 4);519 mt76_rmw(dev, MT_WF_RMAC_MIB_AIRTIME0(band), mask, set);520 521 /* filter out non-resp frames and get instanstaeous signal reporting */522 mask = MT_WTBLOFF_TOP_RSCR_RCPI_MODE | MT_WTBLOFF_TOP_RSCR_RCPI_PARAM;523 set = FIELD_PREP(MT_WTBLOFF_TOP_RSCR_RCPI_MODE, 0) |524 FIELD_PREP(MT_WTBLOFF_TOP_RSCR_RCPI_PARAM, 0x3);525 mt76_rmw(dev, MT_WTBLOFF_TOP_RSCR(band), mask, set);526 527 /* MT_TXD5_TX_STATUS_HOST (MPDU format) has higher priority than528 * MT_AGG_ACR_PPDU_TXS2H (PPDU format) even though ACR bit is set.529 */530 if (mtk_wed_device_active(&dev->mt76.mmio.wed))531 mt76_set(dev, MT_AGG_ACR4(band), MT_AGG_ACR_PPDU_TXS2H);532}533 534static void535mt7915_init_led_mux(struct mt7915_dev *dev)536{537 if (!IS_ENABLED(CONFIG_MT76_LEDS))538 return;539 540 if (dev->dbdc_support) {541 switch (mt76_chip(&dev->mt76)) {542 case 0x7915:543 mt76_rmw_field(dev, MT_LED_GPIO_MUX2,544 GENMASK(11, 8), 4);545 mt76_rmw_field(dev, MT_LED_GPIO_MUX3,546 GENMASK(11, 8), 4);547 break;548 case 0x7986:549 mt76_rmw_field(dev, MT_LED_GPIO_MUX0,550 GENMASK(7, 4), 1);551 mt76_rmw_field(dev, MT_LED_GPIO_MUX0,552 GENMASK(11, 8), 1);553 break;554 case 0x7916:555 mt76_rmw_field(dev, MT_LED_GPIO_MUX1,556 GENMASK(27, 24), 3);557 mt76_rmw_field(dev, MT_LED_GPIO_MUX1,558 GENMASK(31, 28), 3);559 break;560 default:561 break;562 }563 } else if (dev->mphy.leds.pin) {564 switch (mt76_chip(&dev->mt76)) {565 case 0x7915:566 mt76_rmw_field(dev, MT_LED_GPIO_MUX3,567 GENMASK(11, 8), 4);568 break;569 case 0x7986:570 mt76_rmw_field(dev, MT_LED_GPIO_MUX0,571 GENMASK(11, 8), 1);572 break;573 case 0x7916:574 mt76_rmw_field(dev, MT_LED_GPIO_MUX1,575 GENMASK(31, 28), 3);576 break;577 default:578 break;579 }580 } else {581 switch (mt76_chip(&dev->mt76)) {582 case 0x7915:583 mt76_rmw_field(dev, MT_LED_GPIO_MUX2,584 GENMASK(11, 8), 4);585 break;586 case 0x7986:587 mt76_rmw_field(dev, MT_LED_GPIO_MUX0,588 GENMASK(7, 4), 1);589 break;590 case 0x7916:591 mt76_rmw_field(dev, MT_LED_GPIO_MUX1,592 GENMASK(27, 24), 3);593 break;594 default:595 break;596 }597 }598}599 600void mt7915_mac_init(struct mt7915_dev *dev)601{602 int i;603 u32 rx_len = is_mt7915(&dev->mt76) ? 0x400 : 0x680;604 605 /* config pse qid6 wfdma port selection */606 if (!is_mt7915(&dev->mt76) && dev->hif2)607 mt76_rmw(dev, MT_WF_PP_TOP_RXQ_WFDMA_CF_5, 0,608 MT_WF_PP_TOP_RXQ_QID6_WFDMA_HIF_SEL_MASK);609 610 mt76_rmw_field(dev, MT_MDP_DCR1, MT_MDP_DCR1_MAX_RX_LEN, rx_len);611 612 if (!is_mt7915(&dev->mt76))613 mt76_clear(dev, MT_MDP_DCR2, MT_MDP_DCR2_RX_TRANS_SHORT);614 else615 mt76_clear(dev, MT_PLE_HOST_RPT0, MT_PLE_HOST_RPT0_TX_LATENCY);616 617 /* enable hardware de-agg */618 mt76_set(dev, MT_MDP_DCR0, MT_MDP_DCR0_DAMSDU_EN);619 620 for (i = 0; i < mt7915_wtbl_size(dev); i++)621 mt7915_mac_wtbl_update(dev, i,622 MT_WTBL_UPDATE_ADM_COUNT_CLEAR);623 for (i = 0; i < 2; i++)624 mt7915_mac_init_band(dev, i);625 626 mt7915_init_led_mux(dev);627}628 629int mt7915_txbf_init(struct mt7915_dev *dev)630{631 int ret;632 633 if (dev->dbdc_support) {634 ret = mt7915_mcu_set_txbf(dev, MT_BF_MODULE_UPDATE);635 if (ret)636 return ret;637 }638 639 /* trigger sounding packets */640 ret = mt7915_mcu_set_txbf(dev, MT_BF_SOUNDING_ON);641 if (ret)642 return ret;643 644 /* enable eBF */645 return mt7915_mcu_set_txbf(dev, MT_BF_TYPE_UPDATE);646}647 648static struct mt7915_phy *649mt7915_alloc_ext_phy(struct mt7915_dev *dev)650{651 struct mt7915_phy *phy;652 struct mt76_phy *mphy;653 654 if (!dev->dbdc_support)655 return NULL;656 657 mphy = mt76_alloc_phy(&dev->mt76, sizeof(*phy), &mt7915_ops, MT_BAND1);658 if (!mphy)659 return ERR_PTR(-ENOMEM);660 661 phy = mphy->priv;662 phy->dev = dev;663 phy->mt76 = mphy;664 665 /* Bind main phy to band0 and ext_phy to band1 for dbdc case */666 phy->mt76->band_idx = 1;667 668 return phy;669}670 671static int672mt7915_register_ext_phy(struct mt7915_dev *dev, struct mt7915_phy *phy)673{674 struct mt76_phy *mphy = phy->mt76;675 int ret;676 677 INIT_DELAYED_WORK(&mphy->mac_work, mt7915_mac_work);678 679 mt7915_eeprom_parse_hw_cap(dev, phy);680 681 memcpy(mphy->macaddr, dev->mt76.eeprom.data + MT_EE_MAC_ADDR2,682 ETH_ALEN);683 /* Make the secondary PHY MAC address local without overlapping with684 * the usual MAC address allocation scheme on multiple virtual interfaces685 */686 if (!is_valid_ether_addr(mphy->macaddr)) {687 memcpy(mphy->macaddr, dev->mt76.eeprom.data + MT_EE_MAC_ADDR,688 ETH_ALEN);689 mphy->macaddr[0] |= 2;690 mphy->macaddr[0] ^= BIT(7);691 }692 mt76_eeprom_override(mphy);693 694 /* init wiphy according to mphy and phy */695 mt7915_init_wiphy(phy);696 697 ret = mt76_register_phy(mphy, true, mt76_rates,698 ARRAY_SIZE(mt76_rates));699 if (ret)700 return ret;701 702 ret = mt7915_thermal_init(phy);703 if (ret)704 goto unreg;705 706 mt7915_init_debugfs(phy);707 708 return 0;709 710unreg:711 mt76_unregister_phy(mphy);712 return ret;713}714 715static void mt7915_init_work(struct work_struct *work)716{717 struct mt7915_dev *dev = container_of(work, struct mt7915_dev,718 init_work);719 720 mt7915_mcu_set_eeprom(dev);721 mt7915_mac_init(dev);722 mt7915_txbf_init(dev);723}724 725void mt7915_wfsys_reset(struct mt7915_dev *dev)726{727#define MT_MCU_DUMMY_RANDOM GENMASK(15, 0)728#define MT_MCU_DUMMY_DEFAULT GENMASK(31, 16)729 730 if (is_mt7915(&dev->mt76)) {731 u32 val = MT_TOP_PWR_KEY | MT_TOP_PWR_SW_PWR_ON | MT_TOP_PWR_PWR_ON;732 733 mt76_wr(dev, MT_MCU_WFDMA0_DUMMY_CR, MT_MCU_DUMMY_RANDOM);734 735 /* change to software control */736 val |= MT_TOP_PWR_SW_RST;737 mt76_wr(dev, MT_TOP_PWR_CTRL, val);738 739 /* reset wfsys */740 val &= ~MT_TOP_PWR_SW_RST;741 mt76_wr(dev, MT_TOP_PWR_CTRL, val);742 743 /* release wfsys then mcu re-executes romcode */744 val |= MT_TOP_PWR_SW_RST;745 mt76_wr(dev, MT_TOP_PWR_CTRL, val);746 747 /* switch to hw control */748 val &= ~MT_TOP_PWR_SW_RST;749 val |= MT_TOP_PWR_HW_CTRL;750 mt76_wr(dev, MT_TOP_PWR_CTRL, val);751 752 /* check whether mcu resets to default */753 if (!mt76_poll_msec(dev, MT_MCU_WFDMA0_DUMMY_CR,754 MT_MCU_DUMMY_DEFAULT, MT_MCU_DUMMY_DEFAULT,755 1000)) {756 dev_err(dev->mt76.dev, "wifi subsystem reset failure\n");757 return;758 }759 760 /* wfsys reset won't clear host registers */761 mt76_clear(dev, MT_TOP_MISC, MT_TOP_MISC_FW_STATE);762 763 msleep(100);764 } else if (is_mt798x(&dev->mt76)) {765 mt7986_wmac_disable(dev);766 msleep(20);767 768 mt7986_wmac_enable(dev);769 msleep(20);770 } else {771 mt76_set(dev, MT_WF_SUBSYS_RST, 0x1);772 msleep(20);773 774 mt76_clear(dev, MT_WF_SUBSYS_RST, 0x1);775 msleep(20);776 }777}778 779static bool mt7915_band_config(struct mt7915_dev *dev)780{781 bool ret = true;782 783 dev->phy.mt76->band_idx = 0;784 785 if (is_mt798x(&dev->mt76)) {786 u32 sku = mt7915_check_adie(dev, true);787 788 /*789 * for mt7986, dbdc support is determined by the number790 * of adie chips and the main phy is bound to band1 when791 * dbdc is disabled.792 */793 if (sku == MT7975_ONE_ADIE || sku == MT7976_ONE_ADIE) {794 dev->phy.mt76->band_idx = 1;795 ret = false;796 }797 } else {798 ret = is_mt7915(&dev->mt76) ?799 !!(mt76_rr(dev, MT_HW_BOUND) & BIT(5)) : true;800 }801 802 return ret;803}804 805static int806mt7915_init_hardware(struct mt7915_dev *dev, struct mt7915_phy *phy2)807{808 int ret, idx;809 810 mt76_wr(dev, MT_INT_MASK_CSR, 0);811 mt76_wr(dev, MT_INT_SOURCE_CSR, ~0);812 813 INIT_WORK(&dev->init_work, mt7915_init_work);814 815 ret = mt7915_dma_init(dev, phy2);816 if (ret)817 return ret;818 819 set_bit(MT76_STATE_INITIALIZED, &dev->mphy.state);820 821 ret = mt7915_mcu_init(dev);822 if (ret)823 return ret;824 825 ret = mt7915_eeprom_init(dev);826 if (ret < 0)827 return ret;828 829 if (dev->cal) {830 ret = mt7915_mcu_apply_group_cal(dev);831 if (ret)832 return ret;833 }834 835 /* Beacon and mgmt frames should occupy wcid 0 */836 idx = mt76_wcid_alloc(dev->mt76.wcid_mask, MT7915_WTBL_STA);837 if (idx)838 return -ENOSPC;839 840 dev->mt76.global_wcid.idx = idx;841 dev->mt76.global_wcid.hw_key_idx = -1;842 dev->mt76.global_wcid.tx_info |= MT_WCID_TX_INFO_SET;843 rcu_assign_pointer(dev->mt76.wcid[idx], &dev->mt76.global_wcid);844 845 return 0;846}847 848void mt7915_set_stream_vht_txbf_caps(struct mt7915_phy *phy)849{850 int sts;851 u32 *cap;852 853 if (!phy->mt76->cap.has_5ghz)854 return;855 856 sts = hweight8(phy->mt76->chainmask);857 cap = &phy->mt76->sband_5g.sband.vht_cap.cap;858 859 *cap |= IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE |860 IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE |861 FIELD_PREP(IEEE80211_VHT_CAP_BEAMFORMEE_STS_MASK,862 sts - 1);863 864 *cap &= ~(IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_MASK |865 IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE |866 IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE);867 868 if (sts < 2)869 return;870 871 *cap |= IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE |872 IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE |873 FIELD_PREP(IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_MASK,874 sts - 1);875}876 877static void878mt7915_set_stream_he_txbf_caps(struct mt7915_phy *phy,879 struct ieee80211_sta_he_cap *he_cap, int vif)880{881 struct mt7915_dev *dev = phy->dev;882 struct ieee80211_he_cap_elem *elem = &he_cap->he_cap_elem;883 int sts = hweight8(phy->mt76->chainmask);884 u8 c, sts_160 = sts;885 886 /* Can do 1/2 of STS in 160Mhz mode for mt7915 */887 if (is_mt7915(&dev->mt76)) {888 if (!dev->dbdc_support)889 sts_160 /= 2;890 else891 sts_160 = 0;892 }893 894#ifdef CONFIG_MAC80211_MESH895 if (vif == NL80211_IFTYPE_MESH_POINT)896 return;897#endif898 899 elem->phy_cap_info[3] &= ~IEEE80211_HE_PHY_CAP3_SU_BEAMFORMER;900 elem->phy_cap_info[4] &= ~IEEE80211_HE_PHY_CAP4_MU_BEAMFORMER;901 902 c = IEEE80211_HE_PHY_CAP5_BEAMFORMEE_NUM_SND_DIM_UNDER_80MHZ_MASK;903 if (sts_160)904 c |= IEEE80211_HE_PHY_CAP5_BEAMFORMEE_NUM_SND_DIM_ABOVE_80MHZ_MASK;905 elem->phy_cap_info[5] &= ~c;906 907 c = IEEE80211_HE_PHY_CAP6_TRIG_SU_BEAMFORMING_FB |908 IEEE80211_HE_PHY_CAP6_TRIG_MU_BEAMFORMING_PARTIAL_BW_FB;909 elem->phy_cap_info[6] &= ~c;910 911 elem->phy_cap_info[7] &= ~IEEE80211_HE_PHY_CAP7_MAX_NC_MASK;912 913 c = IEEE80211_HE_PHY_CAP2_NDP_4x_LTF_AND_3_2US;914 if (!is_mt7915(&dev->mt76))915 c |= IEEE80211_HE_PHY_CAP2_UL_MU_FULL_MU_MIMO |916 IEEE80211_HE_PHY_CAP2_UL_MU_PARTIAL_MU_MIMO;917 elem->phy_cap_info[2] |= c;918 919 c = IEEE80211_HE_PHY_CAP4_SU_BEAMFORMEE |920 IEEE80211_HE_PHY_CAP4_BEAMFORMEE_MAX_STS_UNDER_80MHZ_4;921 if (sts_160)922 c |= IEEE80211_HE_PHY_CAP4_BEAMFORMEE_MAX_STS_ABOVE_80MHZ_4;923 elem->phy_cap_info[4] |= c;924 925 /* do not support NG16 due to spec D4.0 changes subcarrier idx */926 c = IEEE80211_HE_PHY_CAP6_CODEBOOK_SIZE_42_SU |927 IEEE80211_HE_PHY_CAP6_CODEBOOK_SIZE_75_MU;928 929 if (vif == NL80211_IFTYPE_STATION)930 c |= IEEE80211_HE_PHY_CAP6_PARTIAL_BANDWIDTH_DL_MUMIMO;931 932 elem->phy_cap_info[6] |= c;933 934 if (sts < 2)935 return;936 937 /* the maximum cap is 4 x 3, (Nr, Nc) = (3, 2) */938 elem->phy_cap_info[7] |= min_t(int, sts - 1, 2) << 3;939 940 if (vif != NL80211_IFTYPE_AP && vif != NL80211_IFTYPE_STATION)941 return;942 943 elem->phy_cap_info[3] |= IEEE80211_HE_PHY_CAP3_SU_BEAMFORMER;944 945 c = FIELD_PREP(IEEE80211_HE_PHY_CAP5_BEAMFORMEE_NUM_SND_DIM_UNDER_80MHZ_MASK,946 sts - 1);947 if (sts_160)948 c |= FIELD_PREP(IEEE80211_HE_PHY_CAP5_BEAMFORMEE_NUM_SND_DIM_ABOVE_80MHZ_MASK,949 sts_160 - 1);950 elem->phy_cap_info[5] |= c;951 952 if (vif != NL80211_IFTYPE_AP)953 return;954 955 elem->phy_cap_info[4] |= IEEE80211_HE_PHY_CAP4_MU_BEAMFORMER;956 957 c = IEEE80211_HE_PHY_CAP6_TRIG_SU_BEAMFORMING_FB |958 IEEE80211_HE_PHY_CAP6_TRIG_MU_BEAMFORMING_PARTIAL_BW_FB;959 elem->phy_cap_info[6] |= c;960 961 if (!is_mt7915(&dev->mt76)) {962 c = IEEE80211_HE_PHY_CAP7_STBC_TX_ABOVE_80MHZ |963 IEEE80211_HE_PHY_CAP7_STBC_RX_ABOVE_80MHZ;964 elem->phy_cap_info[7] |= c;965 }966}967 968static int969mt7915_init_he_caps(struct mt7915_phy *phy, enum nl80211_band band,970 struct ieee80211_sband_iftype_data *data)971{972 struct mt7915_dev *dev = phy->dev;973 int i, idx = 0, nss = hweight8(phy->mt76->antenna_mask);974 u16 mcs_map = 0;975 u16 mcs_map_160 = 0;976 u8 nss_160;977 978 if (!is_mt7915(&dev->mt76))979 nss_160 = nss;980 else if (!dev->dbdc_support)981 /* Can do 1/2 of NSS streams in 160Mhz mode for mt7915 */982 nss_160 = nss / 2;983 else984 /* Can't do 160MHz with mt7915 dbdc */985 nss_160 = 0;986 987 for (i = 0; i < 8; i++) {988 if (i < nss)989 mcs_map |= (IEEE80211_HE_MCS_SUPPORT_0_11 << (i * 2));990 else991 mcs_map |= (IEEE80211_HE_MCS_NOT_SUPPORTED << (i * 2));992 993 if (i < nss_160)994 mcs_map_160 |= (IEEE80211_HE_MCS_SUPPORT_0_11 << (i * 2));995 else996 mcs_map_160 |= (IEEE80211_HE_MCS_NOT_SUPPORTED << (i * 2));997 }998 999 for (i = 0; i < NUM_NL80211_IFTYPES; i++) {1000 struct ieee80211_sta_he_cap *he_cap = &data[idx].he_cap;1001 struct ieee80211_he_cap_elem *he_cap_elem =1002 &he_cap->he_cap_elem;1003 struct ieee80211_he_mcs_nss_supp *he_mcs =1004 &he_cap->he_mcs_nss_supp;1005 1006 switch (i) {1007 case NL80211_IFTYPE_STATION:1008 case NL80211_IFTYPE_AP:1009#ifdef CONFIG_MAC80211_MESH1010 case NL80211_IFTYPE_MESH_POINT:1011#endif1012 break;1013 default:1014 continue;1015 }1016 1017 data[idx].types_mask = BIT(i);1018 he_cap->has_he = true;1019 1020 he_cap_elem->mac_cap_info[0] =1021 IEEE80211_HE_MAC_CAP0_HTC_HE;1022 he_cap_elem->mac_cap_info[3] =1023 IEEE80211_HE_MAC_CAP3_OMI_CONTROL |1024 IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_EXT_3;1025 he_cap_elem->mac_cap_info[4] =1026 IEEE80211_HE_MAC_CAP4_AMSDU_IN_AMPDU;1027 1028 if (band == NL80211_BAND_2GHZ)1029 he_cap_elem->phy_cap_info[0] =1030 IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_IN_2G;1031 else if (nss_160)1032 he_cap_elem->phy_cap_info[0] =1033 IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_80MHZ_IN_5G |1034 IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_160MHZ_IN_5G;1035 else1036 he_cap_elem->phy_cap_info[0] =1037 IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_80MHZ_IN_5G;1038 1039 he_cap_elem->phy_cap_info[1] =1040 IEEE80211_HE_PHY_CAP1_LDPC_CODING_IN_PAYLOAD;1041 he_cap_elem->phy_cap_info[2] =1042 IEEE80211_HE_PHY_CAP2_STBC_TX_UNDER_80MHZ |1043 IEEE80211_HE_PHY_CAP2_STBC_RX_UNDER_80MHZ;1044 1045 switch (i) {1046 case NL80211_IFTYPE_AP:1047 he_cap_elem->mac_cap_info[0] |=1048 IEEE80211_HE_MAC_CAP0_TWT_RES;1049 he_cap_elem->mac_cap_info[2] |=1050 IEEE80211_HE_MAC_CAP2_BSR;1051 he_cap_elem->mac_cap_info[4] |=1052 IEEE80211_HE_MAC_CAP4_BQR;1053 he_cap_elem->mac_cap_info[5] |=1054 IEEE80211_HE_MAC_CAP5_OM_CTRL_UL_MU_DATA_DIS_RX;1055 he_cap_elem->phy_cap_info[3] |=1056 IEEE80211_HE_PHY_CAP3_DCM_MAX_CONST_TX_QPSK |1057 IEEE80211_HE_PHY_CAP3_DCM_MAX_CONST_RX_QPSK;1058 he_cap_elem->phy_cap_info[6] |=1059 IEEE80211_HE_PHY_CAP6_PARTIAL_BW_EXT_RANGE |1060 IEEE80211_HE_PHY_CAP6_PPE_THRESHOLD_PRESENT;1061 he_cap_elem->phy_cap_info[9] |=1062 IEEE80211_HE_PHY_CAP9_TX_1024_QAM_LESS_THAN_242_TONE_RU |1063 IEEE80211_HE_PHY_CAP9_RX_1024_QAM_LESS_THAN_242_TONE_RU;1064 break;1065 case NL80211_IFTYPE_STATION:1066 he_cap_elem->mac_cap_info[1] |=1067 IEEE80211_HE_MAC_CAP1_TF_MAC_PAD_DUR_16US;1068 1069 if (band == NL80211_BAND_2GHZ)1070 he_cap_elem->phy_cap_info[0] |=1071 IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_RU_MAPPING_IN_2G;1072 else1073 he_cap_elem->phy_cap_info[0] |=1074 IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_RU_MAPPING_IN_5G;1075 1076 he_cap_elem->phy_cap_info[1] |=1077 IEEE80211_HE_PHY_CAP1_DEVICE_CLASS_A |1078 IEEE80211_HE_PHY_CAP1_HE_LTF_AND_GI_FOR_HE_PPDUS_0_8US;1079 he_cap_elem->phy_cap_info[3] |=1080 IEEE80211_HE_PHY_CAP3_DCM_MAX_CONST_TX_QPSK |1081 IEEE80211_HE_PHY_CAP3_DCM_MAX_CONST_RX_QPSK;1082 he_cap_elem->phy_cap_info[6] |=1083 IEEE80211_HE_PHY_CAP6_TRIG_CQI_FB |1084 IEEE80211_HE_PHY_CAP6_PARTIAL_BW_EXT_RANGE |1085 IEEE80211_HE_PHY_CAP6_PPE_THRESHOLD_PRESENT;1086 he_cap_elem->phy_cap_info[7] |=1087 IEEE80211_HE_PHY_CAP7_POWER_BOOST_FACTOR_SUPP |1088 IEEE80211_HE_PHY_CAP7_HE_SU_MU_PPDU_4XLTF_AND_08_US_GI;1089 he_cap_elem->phy_cap_info[8] |=1090 IEEE80211_HE_PHY_CAP8_20MHZ_IN_40MHZ_HE_PPDU_IN_2G |1091 IEEE80211_HE_PHY_CAP8_DCM_MAX_RU_484;1092 if (nss_160)1093 he_cap_elem->phy_cap_info[8] |=1094 IEEE80211_HE_PHY_CAP8_20MHZ_IN_160MHZ_HE_PPDU |1095 IEEE80211_HE_PHY_CAP8_80MHZ_IN_160MHZ_HE_PPDU;1096 he_cap_elem->phy_cap_info[9] |=1097 IEEE80211_HE_PHY_CAP9_LONGER_THAN_16_SIGB_OFDM_SYM |1098 IEEE80211_HE_PHY_CAP9_NON_TRIGGERED_CQI_FEEDBACK |1099 IEEE80211_HE_PHY_CAP9_TX_1024_QAM_LESS_THAN_242_TONE_RU |1100 IEEE80211_HE_PHY_CAP9_RX_1024_QAM_LESS_THAN_242_TONE_RU |1101 IEEE80211_HE_PHY_CAP9_RX_FULL_BW_SU_USING_MU_WITH_COMP_SIGB |1102 IEEE80211_HE_PHY_CAP9_RX_FULL_BW_SU_USING_MU_WITH_NON_COMP_SIGB;1103 break;1104 }1105 1106 memset(he_mcs, 0, sizeof(*he_mcs));1107 he_mcs->rx_mcs_80 = cpu_to_le16(mcs_map);1108 he_mcs->tx_mcs_80 = cpu_to_le16(mcs_map);1109 he_mcs->rx_mcs_160 = cpu_to_le16(mcs_map_160);1110 he_mcs->tx_mcs_160 = cpu_to_le16(mcs_map_160);1111 1112 mt7915_set_stream_he_txbf_caps(phy, he_cap, i);1113 1114 memset(he_cap->ppe_thres, 0, sizeof(he_cap->ppe_thres));1115 if (he_cap_elem->phy_cap_info[6] &1116 IEEE80211_HE_PHY_CAP6_PPE_THRESHOLD_PRESENT) {1117 mt76_connac_gen_ppe_thresh(he_cap->ppe_thres, nss);1118 } else {1119 he_cap_elem->phy_cap_info[9] |=1120 u8_encode_bits(IEEE80211_HE_PHY_CAP9_NOMINAL_PKT_PADDING_16US,1121 IEEE80211_HE_PHY_CAP9_NOMINAL_PKT_PADDING_MASK);1122 }1123 1124 if (band == NL80211_BAND_6GHZ) {1125 u16 cap = IEEE80211_HE_6GHZ_CAP_TX_ANTPAT_CONS |1126 IEEE80211_HE_6GHZ_CAP_RX_ANTPAT_CONS;1127 1128 cap |= u16_encode_bits(IEEE80211_HT_MPDU_DENSITY_2,1129 IEEE80211_HE_6GHZ_CAP_MIN_MPDU_START) |1130 u16_encode_bits(IEEE80211_VHT_MAX_AMPDU_1024K,1131 IEEE80211_HE_6GHZ_CAP_MAX_AMPDU_LEN_EXP) |1132 u16_encode_bits(IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454,1133 IEEE80211_HE_6GHZ_CAP_MAX_MPDU_LEN);1134 1135 data[idx].he_6ghz_capa.capa = cpu_to_le16(cap);1136 }1137 1138 idx++;1139 }1140 1141 return idx;1142}1143 1144void mt7915_set_stream_he_caps(struct mt7915_phy *phy)1145{1146 struct ieee80211_sband_iftype_data *data;1147 struct ieee80211_supported_band *band;1148 int n;1149 1150 if (phy->mt76->cap.has_2ghz) {1151 data = phy->iftype[NL80211_BAND_2GHZ];1152 n = mt7915_init_he_caps(phy, NL80211_BAND_2GHZ, data);1153 1154 band = &phy->mt76->sband_2g.sband;1155 _ieee80211_set_sband_iftype_data(band, data, n);1156 }1157 1158 if (phy->mt76->cap.has_5ghz) {1159 data = phy->iftype[NL80211_BAND_5GHZ];1160 n = mt7915_init_he_caps(phy, NL80211_BAND_5GHZ, data);1161 1162 band = &phy->mt76->sband_5g.sband;1163 _ieee80211_set_sband_iftype_data(band, data, n);1164 }1165 1166 if (phy->mt76->cap.has_6ghz) {1167 data = phy->iftype[NL80211_BAND_6GHZ];1168 n = mt7915_init_he_caps(phy, NL80211_BAND_6GHZ, data);1169 1170 band = &phy->mt76->sband_6g.sband;1171 _ieee80211_set_sband_iftype_data(band, data, n);1172 }1173}1174 1175static void mt7915_unregister_ext_phy(struct mt7915_dev *dev)1176{1177 struct mt7915_phy *phy = mt7915_ext_phy(dev);1178 struct mt76_phy *mphy = dev->mt76.phys[MT_BAND1];1179 1180 if (!phy)1181 return;1182 1183 mt7915_unregister_thermal(phy);1184 mt76_unregister_phy(mphy);1185 ieee80211_free_hw(mphy->hw);1186}1187 1188static void mt7915_stop_hardware(struct mt7915_dev *dev)1189{1190 mt7915_mcu_exit(dev);1191 mt76_connac2_tx_token_put(&dev->mt76);1192 mt7915_dma_cleanup(dev);1193 tasklet_disable(&dev->mt76.irq_tasklet);1194 1195 if (is_mt798x(&dev->mt76))1196 mt7986_wmac_disable(dev);1197}1198 1199int mt7915_register_device(struct mt7915_dev *dev)1200{1201 struct mt7915_phy *phy2;1202 int ret;1203 1204 dev->phy.dev = dev;1205 dev->phy.mt76 = &dev->mt76.phy;1206 dev->mt76.phy.priv = &dev->phy;1207 INIT_WORK(&dev->rc_work, mt7915_mac_sta_rc_work);1208 INIT_DELAYED_WORK(&dev->mphy.mac_work, mt7915_mac_work);1209 INIT_LIST_HEAD(&dev->sta_rc_list);1210 INIT_LIST_HEAD(&dev->twt_list);1211 1212 init_waitqueue_head(&dev->reset_wait);1213 INIT_WORK(&dev->reset_work, mt7915_mac_reset_work);1214 INIT_WORK(&dev->dump_work, mt7915_mac_dump_work);1215 mutex_init(&dev->dump_mutex);1216 1217 dev->dbdc_support = mt7915_band_config(dev);1218 1219 phy2 = mt7915_alloc_ext_phy(dev);1220 if (IS_ERR(phy2))1221 return PTR_ERR(phy2);1222 1223 ret = mt7915_init_hardware(dev, phy2);1224 if (ret)1225 goto free_phy2;1226 1227 mt7915_init_wiphy(&dev->phy);1228 1229#ifdef CONFIG_NL80211_TESTMODE1230 dev->mt76.test_ops = &mt7915_testmode_ops;1231#endif1232 1233 ret = mt76_register_device(&dev->mt76, true, mt76_rates,1234 ARRAY_SIZE(mt76_rates));1235 if (ret)1236 goto stop_hw;1237 1238 ret = mt7915_thermal_init(&dev->phy);1239 if (ret)1240 goto unreg_dev;1241 1242 ieee80211_queue_work(mt76_hw(dev), &dev->init_work);1243 1244 if (phy2) {1245 ret = mt7915_register_ext_phy(dev, phy2);1246 if (ret)1247 goto unreg_thermal;1248 }1249 1250 dev->recovery.hw_init_done = true;1251 1252 ret = mt7915_init_debugfs(&dev->phy);1253 if (ret)1254 goto unreg_thermal;1255 1256 ret = mt7915_coredump_register(dev);1257 if (ret)1258 goto unreg_thermal;1259 1260 return 0;1261 1262unreg_thermal:1263 mt7915_unregister_thermal(&dev->phy);1264unreg_dev:1265 mt76_unregister_device(&dev->mt76);1266stop_hw:1267 mt7915_stop_hardware(dev);1268free_phy2:1269 if (phy2)1270 ieee80211_free_hw(phy2->mt76->hw);1271 return ret;1272}1273 1274void mt7915_unregister_device(struct mt7915_dev *dev)1275{1276 mt7915_unregister_ext_phy(dev);1277 mt7915_coredump_unregister(dev);1278 mt7915_unregister_thermal(&dev->phy);1279 mt76_unregister_device(&dev->mt76);1280 mt7915_stop_hardware(dev);1281 1282 mt76_free_device(&dev->mt76);1283}1284