brintos

brintos / linux-shallow public Read only

0
0
Text · 34.2 KiB · 6bef96e Raw
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