brintos

brintos / linux-shallow public Read only

0
0
Text · 39.3 KiB · 5e96973 Raw
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