cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

init.c (16437B)


      1// SPDX-License-Identifier: ISC
      2/* Copyright (C) 2019 MediaTek Inc.
      3 *
      4 * Author: Roy Luo <royluo@google.com>
      5 *         Ryder Lee <ryder.lee@mediatek.com>
      6 *         Felix Fietkau <nbd@nbd.name>
      7 *         Lorenzo Bianconi <lorenzo@kernel.org>
      8 */
      9
     10#include <linux/etherdevice.h>
     11#include <linux/hwmon.h>
     12#include <linux/hwmon-sysfs.h>
     13#include "mt7615.h"
     14#include "mac.h"
     15#include "mcu.h"
     16#include "eeprom.h"
     17
     18static ssize_t mt7615_thermal_show_temp(struct device *dev,
     19					struct device_attribute *attr,
     20					char *buf)
     21{
     22	struct mt7615_dev *mdev = dev_get_drvdata(dev);
     23	int temperature;
     24
     25	if (!mt7615_wait_for_mcu_init(mdev))
     26		return 0;
     27
     28	mt7615_mutex_acquire(mdev);
     29	temperature = mt7615_mcu_get_temperature(mdev);
     30	mt7615_mutex_release(mdev);
     31
     32	if (temperature < 0)
     33		return temperature;
     34
     35	/* display in millidegree celcius */
     36	return sprintf(buf, "%u\n", temperature * 1000);
     37}
     38
     39static SENSOR_DEVICE_ATTR(temp1_input, 0444, mt7615_thermal_show_temp,
     40			  NULL, 0);
     41
     42static struct attribute *mt7615_hwmon_attrs[] = {
     43	&sensor_dev_attr_temp1_input.dev_attr.attr,
     44	NULL,
     45};
     46ATTRIBUTE_GROUPS(mt7615_hwmon);
     47
     48int mt7615_thermal_init(struct mt7615_dev *dev)
     49{
     50	struct wiphy *wiphy = mt76_hw(dev)->wiphy;
     51	struct device *hwmon;
     52	const char *name;
     53
     54	if (!IS_REACHABLE(CONFIG_HWMON))
     55		return 0;
     56
     57	name = devm_kasprintf(&wiphy->dev, GFP_KERNEL, "mt7615_%s",
     58			      wiphy_name(wiphy));
     59	hwmon = devm_hwmon_device_register_with_groups(&wiphy->dev, name, dev,
     60						       mt7615_hwmon_groups);
     61	if (IS_ERR(hwmon))
     62		return PTR_ERR(hwmon);
     63
     64	return 0;
     65}
     66EXPORT_SYMBOL_GPL(mt7615_thermal_init);
     67
     68static void
     69mt7615_phy_init(struct mt7615_dev *dev)
     70{
     71	/* disable rf low power beacon mode */
     72	mt76_set(dev, MT_WF_PHY_WF2_RFCTRL0(0), MT_WF_PHY_WF2_RFCTRL0_LPBCN_EN);
     73	mt76_set(dev, MT_WF_PHY_WF2_RFCTRL0(1), MT_WF_PHY_WF2_RFCTRL0_LPBCN_EN);
     74}
     75
     76static void
     77mt7615_init_mac_chain(struct mt7615_dev *dev, int chain)
     78{
     79	u32 val;
     80
     81	if (!chain)
     82		val = MT_CFG_CCR_MAC_D0_1X_GC_EN | MT_CFG_CCR_MAC_D0_2X_GC_EN;
     83	else
     84		val = MT_CFG_CCR_MAC_D1_1X_GC_EN | MT_CFG_CCR_MAC_D1_2X_GC_EN;
     85
     86	/* enable band 0/1 clk */
     87	mt76_set(dev, MT_CFG_CCR, val);
     88
     89	mt76_rmw(dev, MT_TMAC_TRCR(chain),
     90		 MT_TMAC_TRCR_CCA_SEL | MT_TMAC_TRCR_SEC_CCA_SEL,
     91		 FIELD_PREP(MT_TMAC_TRCR_CCA_SEL, 2) |
     92		 FIELD_PREP(MT_TMAC_TRCR_SEC_CCA_SEL, 0));
     93
     94	mt76_wr(dev, MT_AGG_ACR(chain),
     95		MT_AGG_ACR_PKT_TIME_EN | MT_AGG_ACR_NO_BA_AR_RULE |
     96		FIELD_PREP(MT_AGG_ACR_CFEND_RATE, MT7615_CFEND_RATE_DEFAULT) |
     97		FIELD_PREP(MT_AGG_ACR_BAR_RATE, MT7615_BAR_RATE_DEFAULT));
     98
     99	mt76_wr(dev, MT_AGG_ARUCR(chain),
    100		FIELD_PREP(MT_AGG_ARxCR_LIMIT(0), 7) |
    101		FIELD_PREP(MT_AGG_ARxCR_LIMIT(1), 2) |
    102		FIELD_PREP(MT_AGG_ARxCR_LIMIT(2), 2) |
    103		FIELD_PREP(MT_AGG_ARxCR_LIMIT(3), 2) |
    104		FIELD_PREP(MT_AGG_ARxCR_LIMIT(4), 1) |
    105		FIELD_PREP(MT_AGG_ARxCR_LIMIT(5), 1) |
    106		FIELD_PREP(MT_AGG_ARxCR_LIMIT(6), 1) |
    107		FIELD_PREP(MT_AGG_ARxCR_LIMIT(7), 1));
    108
    109	mt76_wr(dev, MT_AGG_ARDCR(chain),
    110		FIELD_PREP(MT_AGG_ARxCR_LIMIT(0), MT7615_RATE_RETRY - 1) |
    111		FIELD_PREP(MT_AGG_ARxCR_LIMIT(1), MT7615_RATE_RETRY - 1) |
    112		FIELD_PREP(MT_AGG_ARxCR_LIMIT(2), MT7615_RATE_RETRY - 1) |
    113		FIELD_PREP(MT_AGG_ARxCR_LIMIT(3), MT7615_RATE_RETRY - 1) |
    114		FIELD_PREP(MT_AGG_ARxCR_LIMIT(4), MT7615_RATE_RETRY - 1) |
    115		FIELD_PREP(MT_AGG_ARxCR_LIMIT(5), MT7615_RATE_RETRY - 1) |
    116		FIELD_PREP(MT_AGG_ARxCR_LIMIT(6), MT7615_RATE_RETRY - 1) |
    117		FIELD_PREP(MT_AGG_ARxCR_LIMIT(7), MT7615_RATE_RETRY - 1));
    118
    119	mt76_clear(dev, MT_DMA_RCFR0(chain), MT_DMA_RCFR0_MCU_RX_TDLS);
    120	if (!mt7615_firmware_offload(dev)) {
    121		u32 mask, set;
    122
    123		mask = MT_DMA_RCFR0_MCU_RX_MGMT |
    124		       MT_DMA_RCFR0_MCU_RX_CTL_NON_BAR |
    125		       MT_DMA_RCFR0_MCU_RX_CTL_BAR |
    126		       MT_DMA_RCFR0_MCU_RX_BYPASS |
    127		       MT_DMA_RCFR0_RX_DROPPED_UCAST |
    128		       MT_DMA_RCFR0_RX_DROPPED_MCAST;
    129		set = FIELD_PREP(MT_DMA_RCFR0_RX_DROPPED_UCAST, 2) |
    130		      FIELD_PREP(MT_DMA_RCFR0_RX_DROPPED_MCAST, 2);
    131		mt76_rmw(dev, MT_DMA_RCFR0(chain), mask, set);
    132	}
    133}
    134
    135static void
    136mt7615_mac_init(struct mt7615_dev *dev)
    137{
    138	int i;
    139
    140	mt7615_init_mac_chain(dev, 0);
    141
    142	mt76_rmw_field(dev, MT_TMAC_CTCR0,
    143		       MT_TMAC_CTCR0_INS_DDLMT_REFTIME, 0x3f);
    144	mt76_rmw_field(dev, MT_TMAC_CTCR0,
    145		       MT_TMAC_CTCR0_INS_DDLMT_DENSITY, 0x3);
    146	mt76_rmw(dev, MT_TMAC_CTCR0,
    147		 MT_TMAC_CTCR0_INS_DDLMT_VHT_SMPDU_EN |
    148		 MT_TMAC_CTCR0_INS_DDLMT_EN,
    149		 MT_TMAC_CTCR0_INS_DDLMT_VHT_SMPDU_EN |
    150		 MT_TMAC_CTCR0_INS_DDLMT_EN);
    151
    152	mt76_connac_mcu_set_rts_thresh(&dev->mt76, 0x92b, 0);
    153	mt7615_mac_set_scs(&dev->phy, true);
    154
    155	mt76_rmw(dev, MT_AGG_SCR, MT_AGG_SCR_NLNAV_MID_PTEC_DIS,
    156		 MT_AGG_SCR_NLNAV_MID_PTEC_DIS);
    157
    158	mt76_wr(dev, MT_AGG_ARCR,
    159		FIELD_PREP(MT_AGG_ARCR_RTS_RATE_THR, 2) |
    160		MT_AGG_ARCR_RATE_DOWN_RATIO_EN |
    161		FIELD_PREP(MT_AGG_ARCR_RATE_DOWN_RATIO, 1) |
    162		FIELD_PREP(MT_AGG_ARCR_RATE_UP_EXTRA_TH, 4));
    163
    164	for (i = 0; i < MT7615_WTBL_SIZE; i++)
    165		mt7615_mac_wtbl_update(dev, i,
    166				       MT_WTBL_UPDATE_ADM_COUNT_CLEAR);
    167
    168	mt76_set(dev, MT_WF_RMAC_MIB_TIME0, MT_WF_RMAC_MIB_RXTIME_EN);
    169	mt76_set(dev, MT_WF_RMAC_MIB_AIRTIME0, MT_WF_RMAC_MIB_RXTIME_EN);
    170
    171	mt76_wr(dev, MT_DMA_DCR0,
    172		FIELD_PREP(MT_DMA_DCR0_MAX_RX_LEN, 3072) |
    173		MT_DMA_DCR0_RX_VEC_DROP | MT_DMA_DCR0_DAMSDU_EN |
    174		MT_DMA_DCR0_RX_HDR_TRANS_EN);
    175	/* disable TDLS filtering */
    176	mt76_clear(dev, MT_WF_PFCR, MT_WF_PFCR_TDLS_EN);
    177	mt76_set(dev, MT_WF_MIB_SCR0, MT_MIB_SCR0_AGG_CNT_RANGE_EN);
    178	if (is_mt7663(&dev->mt76)) {
    179		mt76_wr(dev, MT_WF_AGG(0x160), 0x5c341c02);
    180		mt76_wr(dev, MT_WF_AGG(0x164), 0x70708040);
    181	} else {
    182		mt7615_init_mac_chain(dev, 1);
    183	}
    184	mt7615_mcu_set_rx_hdr_trans_blacklist(dev);
    185}
    186
    187static void
    188mt7615_check_offload_capability(struct mt7615_dev *dev)
    189{
    190	struct ieee80211_hw *hw = mt76_hw(dev);
    191	struct wiphy *wiphy = hw->wiphy;
    192
    193	if (mt7615_firmware_offload(dev)) {
    194		ieee80211_hw_set(hw, SUPPORTS_PS);
    195		ieee80211_hw_set(hw, SUPPORTS_DYNAMIC_PS);
    196
    197		wiphy->flags &= ~WIPHY_FLAG_4ADDR_STATION;
    198		wiphy->max_remain_on_channel_duration = 5000;
    199		wiphy->features |= NL80211_FEATURE_SCHED_SCAN_RANDOM_MAC_ADDR |
    200				   NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR |
    201				   WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL |
    202				   NL80211_FEATURE_P2P_GO_CTWIN |
    203				   NL80211_FEATURE_P2P_GO_OPPPS;
    204	} else {
    205		dev->ops->hw_scan = NULL;
    206		dev->ops->cancel_hw_scan = NULL;
    207		dev->ops->sched_scan_start = NULL;
    208		dev->ops->sched_scan_stop = NULL;
    209		dev->ops->set_rekey_data = NULL;
    210		dev->ops->remain_on_channel = NULL;
    211		dev->ops->cancel_remain_on_channel = NULL;
    212
    213		wiphy->max_sched_scan_plan_interval = 0;
    214		wiphy->max_sched_scan_ie_len = 0;
    215		wiphy->max_scan_ie_len = IEEE80211_MAX_DATA_LEN;
    216		wiphy->max_sched_scan_ssids = 0;
    217		wiphy->max_match_sets = 0;
    218		wiphy->max_sched_scan_reqs = 0;
    219	}
    220}
    221
    222bool mt7615_wait_for_mcu_init(struct mt7615_dev *dev)
    223{
    224	flush_work(&dev->mcu_work);
    225
    226	return test_bit(MT76_STATE_MCU_RUNNING, &dev->mphy.state);
    227}
    228EXPORT_SYMBOL_GPL(mt7615_wait_for_mcu_init);
    229
    230static const struct ieee80211_iface_limit if_limits[] = {
    231	{
    232		.max = 1,
    233		.types = BIT(NL80211_IFTYPE_ADHOC)
    234	}, {
    235		.max = MT7615_MAX_INTERFACES,
    236		.types = BIT(NL80211_IFTYPE_AP) |
    237#ifdef CONFIG_MAC80211_MESH
    238			 BIT(NL80211_IFTYPE_MESH_POINT) |
    239#endif
    240			 BIT(NL80211_IFTYPE_P2P_CLIENT) |
    241			 BIT(NL80211_IFTYPE_P2P_GO) |
    242			 BIT(NL80211_IFTYPE_STATION)
    243	}
    244};
    245
    246static const struct ieee80211_iface_combination if_comb_radar[] = {
    247	{
    248		.limits = if_limits,
    249		.n_limits = ARRAY_SIZE(if_limits),
    250		.max_interfaces = MT7615_MAX_INTERFACES,
    251		.num_different_channels = 1,
    252		.beacon_int_infra_match = true,
    253		.radar_detect_widths = BIT(NL80211_CHAN_WIDTH_20_NOHT) |
    254				       BIT(NL80211_CHAN_WIDTH_20) |
    255				       BIT(NL80211_CHAN_WIDTH_40) |
    256				       BIT(NL80211_CHAN_WIDTH_80) |
    257				       BIT(NL80211_CHAN_WIDTH_160) |
    258				       BIT(NL80211_CHAN_WIDTH_80P80),
    259	}
    260};
    261
    262static const struct ieee80211_iface_combination if_comb[] = {
    263	{
    264		.limits = if_limits,
    265		.n_limits = ARRAY_SIZE(if_limits),
    266		.max_interfaces = MT7615_MAX_INTERFACES,
    267		.num_different_channels = 1,
    268		.beacon_int_infra_match = true,
    269	}
    270};
    271
    272void mt7615_init_txpower(struct mt7615_dev *dev,
    273			 struct ieee80211_supported_band *sband)
    274{
    275	int i, n_chains = hweight8(dev->mphy.antenna_mask), target_chains;
    276	int delta_idx, delta = mt76_tx_power_nss_delta(n_chains);
    277	u8 *eep = (u8 *)dev->mt76.eeprom.data;
    278	enum nl80211_band band = sband->band;
    279	struct mt76_power_limits limits;
    280	u8 rate_val;
    281
    282	delta_idx = mt7615_eeprom_get_power_delta_index(dev, band);
    283	rate_val = eep[delta_idx];
    284	if ((rate_val & ~MT_EE_RATE_POWER_MASK) ==
    285	    (MT_EE_RATE_POWER_EN | MT_EE_RATE_POWER_SIGN))
    286		delta += rate_val & MT_EE_RATE_POWER_MASK;
    287
    288	if (!is_mt7663(&dev->mt76) && mt7615_ext_pa_enabled(dev, band))
    289		target_chains = 1;
    290	else
    291		target_chains = n_chains;
    292
    293	for (i = 0; i < sband->n_channels; i++) {
    294		struct ieee80211_channel *chan = &sband->channels[i];
    295		u8 target_power = 0;
    296		int j;
    297
    298		for (j = 0; j < target_chains; j++) {
    299			int index;
    300
    301			index = mt7615_eeprom_get_target_power_index(dev, chan, j);
    302			if (index < 0)
    303				continue;
    304
    305			target_power = max(target_power, eep[index]);
    306		}
    307
    308		target_power = mt76_get_rate_power_limits(&dev->mphy, chan,
    309							  &limits,
    310							  target_power);
    311		target_power += delta;
    312		target_power = DIV_ROUND_UP(target_power, 2);
    313		chan->max_power = min_t(int, chan->max_reg_power,
    314					target_power);
    315		chan->orig_mpwr = target_power;
    316	}
    317}
    318EXPORT_SYMBOL_GPL(mt7615_init_txpower);
    319
    320void mt7615_init_work(struct mt7615_dev *dev)
    321{
    322	mt7615_mcu_set_eeprom(dev);
    323	mt7615_mac_init(dev);
    324	mt7615_phy_init(dev);
    325	mt7615_mcu_del_wtbl_all(dev);
    326	mt7615_check_offload_capability(dev);
    327}
    328EXPORT_SYMBOL_GPL(mt7615_init_work);
    329
    330static void
    331mt7615_regd_notifier(struct wiphy *wiphy,
    332		     struct regulatory_request *request)
    333{
    334	struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
    335	struct mt7615_dev *dev = mt7615_hw_dev(hw);
    336	struct mt76_phy *mphy = hw->priv;
    337	struct mt7615_phy *phy = mphy->priv;
    338	struct cfg80211_chan_def *chandef = &mphy->chandef;
    339
    340	memcpy(dev->mt76.alpha2, request->alpha2, sizeof(dev->mt76.alpha2));
    341	dev->mt76.region = request->dfs_region;
    342
    343	mt7615_init_txpower(dev, &mphy->sband_2g.sband);
    344	mt7615_init_txpower(dev, &mphy->sband_5g.sband);
    345
    346	mt7615_mutex_acquire(dev);
    347
    348	if (chandef->chan->flags & IEEE80211_CHAN_RADAR)
    349		mt7615_dfs_init_radar_detector(phy);
    350
    351	if (mt7615_firmware_offload(phy->dev)) {
    352		mt76_connac_mcu_set_channel_domain(mphy);
    353		mt76_connac_mcu_set_rate_txpower(mphy);
    354	}
    355
    356	mt7615_mutex_release(dev);
    357}
    358
    359static void
    360mt7615_init_wiphy(struct ieee80211_hw *hw)
    361{
    362	struct mt7615_phy *phy = mt7615_hw_phy(hw);
    363	struct wiphy *wiphy = hw->wiphy;
    364
    365	hw->queues = 4;
    366	hw->max_rates = 3;
    367	hw->max_report_rates = 7;
    368	hw->max_rate_tries = 11;
    369	hw->netdev_features = NETIF_F_RXCSUM;
    370
    371	hw->radiotap_timestamp.units_pos =
    372		IEEE80211_RADIOTAP_TIMESTAMP_UNIT_US;
    373
    374	phy->slottime = 9;
    375
    376	hw->sta_data_size = sizeof(struct mt7615_sta);
    377	hw->vif_data_size = sizeof(struct mt7615_vif);
    378
    379	if (is_mt7663(&phy->dev->mt76)) {
    380		wiphy->iface_combinations = if_comb;
    381		wiphy->n_iface_combinations = ARRAY_SIZE(if_comb);
    382	} else {
    383		wiphy->iface_combinations = if_comb_radar;
    384		wiphy->n_iface_combinations = ARRAY_SIZE(if_comb_radar);
    385	}
    386	wiphy->reg_notifier = mt7615_regd_notifier;
    387
    388	wiphy->max_sched_scan_plan_interval =
    389		MT76_CONNAC_MAX_TIME_SCHED_SCAN_INTERVAL;
    390	wiphy->max_sched_scan_ie_len = IEEE80211_MAX_DATA_LEN;
    391	wiphy->max_scan_ie_len = MT76_CONNAC_SCAN_IE_LEN;
    392	wiphy->max_sched_scan_ssids = MT76_CONNAC_MAX_SCHED_SCAN_SSID;
    393	wiphy->max_match_sets = MT76_CONNAC_MAX_SCAN_MATCH;
    394	wiphy->max_sched_scan_reqs = 1;
    395	wiphy->max_scan_ssids = 4;
    396
    397	wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_SET_SCAN_DWELL);
    398	wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_VHT_IBSS);
    399
    400	ieee80211_hw_set(hw, SINGLE_SCAN_ON_ALL_BANDS);
    401	ieee80211_hw_set(hw, TX_STATUS_NO_AMPDU_LEN);
    402	ieee80211_hw_set(hw, WANT_MONITOR_VIF);
    403	ieee80211_hw_set(hw, SUPPORTS_RX_DECAP_OFFLOAD);
    404
    405	if (is_mt7615(&phy->dev->mt76))
    406		hw->max_tx_fragments = MT_TXP_MAX_BUF_NUM;
    407	else
    408		hw->max_tx_fragments = MT_HW_TXP_MAX_BUF_NUM;
    409
    410	phy->mt76->sband_2g.sband.ht_cap.cap |= IEEE80211_HT_CAP_LDPC_CODING;
    411	phy->mt76->sband_5g.sband.ht_cap.cap |= IEEE80211_HT_CAP_LDPC_CODING;
    412	phy->mt76->sband_5g.sband.vht_cap.cap |=
    413			IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK;
    414}
    415
    416static void
    417mt7615_cap_dbdc_enable(struct mt7615_dev *dev)
    418{
    419	dev->mphy.sband_5g.sband.vht_cap.cap &=
    420			~(IEEE80211_VHT_CAP_SHORT_GI_160 |
    421			  IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ);
    422	if (dev->chainmask == 0xf)
    423		dev->mphy.antenna_mask = dev->chainmask >> 2;
    424	else
    425		dev->mphy.antenna_mask = dev->chainmask >> 1;
    426	dev->mphy.chainmask = dev->mphy.antenna_mask;
    427	dev->mphy.hw->wiphy->available_antennas_rx = dev->mphy.chainmask;
    428	dev->mphy.hw->wiphy->available_antennas_tx = dev->mphy.chainmask;
    429	mt76_set_stream_caps(&dev->mphy, true);
    430}
    431
    432static void
    433mt7615_cap_dbdc_disable(struct mt7615_dev *dev)
    434{
    435	dev->mphy.sband_5g.sband.vht_cap.cap |=
    436			IEEE80211_VHT_CAP_SHORT_GI_160 |
    437			IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ;
    438	dev->mphy.antenna_mask = dev->chainmask;
    439	dev->mphy.chainmask = dev->chainmask;
    440	dev->mphy.hw->wiphy->available_antennas_rx = dev->chainmask;
    441	dev->mphy.hw->wiphy->available_antennas_tx = dev->chainmask;
    442	mt76_set_stream_caps(&dev->mphy, true);
    443}
    444
    445int mt7615_register_ext_phy(struct mt7615_dev *dev)
    446{
    447	struct mt7615_phy *phy = mt7615_ext_phy(dev);
    448	struct mt76_phy *mphy;
    449	int i, ret;
    450
    451	if (!is_mt7615(&dev->mt76))
    452		return -EOPNOTSUPP;
    453
    454	if (test_bit(MT76_STATE_RUNNING, &dev->mphy.state))
    455		return -EINVAL;
    456
    457	if (phy)
    458		return 0;
    459
    460	mt7615_cap_dbdc_enable(dev);
    461	mphy = mt76_alloc_phy(&dev->mt76, sizeof(*phy), &mt7615_ops);
    462	if (!mphy)
    463		return -ENOMEM;
    464
    465	phy = mphy->priv;
    466	phy->dev = dev;
    467	phy->mt76 = mphy;
    468	mphy->chainmask = dev->chainmask & ~dev->mphy.chainmask;
    469	mphy->antenna_mask = BIT(hweight8(mphy->chainmask)) - 1;
    470	mt7615_init_wiphy(mphy->hw);
    471
    472	INIT_DELAYED_WORK(&mphy->mac_work, mt7615_mac_work);
    473	INIT_DELAYED_WORK(&phy->scan_work, mt7615_scan_work);
    474	skb_queue_head_init(&phy->scan_event_list);
    475
    476	INIT_WORK(&phy->roc_work, mt7615_roc_work);
    477	timer_setup(&phy->roc_timer, mt7615_roc_timer, 0);
    478	init_waitqueue_head(&phy->roc_wait);
    479
    480	mt7615_mac_set_scs(phy, true);
    481
    482	/*
    483	 * Make the secondary PHY MAC address local without overlapping with
    484	 * the usual MAC address allocation scheme on multiple virtual interfaces
    485	 */
    486	memcpy(mphy->macaddr, dev->mt76.eeprom.data + MT_EE_MAC_ADDR,
    487	       ETH_ALEN);
    488	mphy->macaddr[0] |= 2;
    489	mphy->macaddr[0] ^= BIT(7);
    490	mt76_eeprom_override(mphy);
    491
    492	/* second phy can only handle 5 GHz */
    493	mphy->cap.has_5ghz = true;
    494
    495	/* mt7615 second phy shares the same hw queues with the primary one */
    496	for (i = 0; i <= MT_TXQ_PSD ; i++)
    497		mphy->q_tx[i] = dev->mphy.q_tx[i];
    498
    499	ret = mt76_register_phy(mphy, true, mt76_rates,
    500				ARRAY_SIZE(mt76_rates));
    501	if (ret)
    502		ieee80211_free_hw(mphy->hw);
    503
    504	return ret;
    505}
    506EXPORT_SYMBOL_GPL(mt7615_register_ext_phy);
    507
    508void mt7615_unregister_ext_phy(struct mt7615_dev *dev)
    509{
    510	struct mt7615_phy *phy = mt7615_ext_phy(dev);
    511	struct mt76_phy *mphy = dev->mt76.phy2;
    512
    513	if (!phy)
    514		return;
    515
    516	mt7615_cap_dbdc_disable(dev);
    517	mt76_unregister_phy(mphy);
    518	ieee80211_free_hw(mphy->hw);
    519}
    520EXPORT_SYMBOL_GPL(mt7615_unregister_ext_phy);
    521
    522void mt7615_init_device(struct mt7615_dev *dev)
    523{
    524	struct ieee80211_hw *hw = mt76_hw(dev);
    525
    526	dev->phy.dev = dev;
    527	dev->phy.mt76 = &dev->mt76.phy;
    528	dev->mt76.phy.priv = &dev->phy;
    529	dev->mt76.tx_worker.fn = mt7615_tx_worker;
    530
    531	INIT_DELAYED_WORK(&dev->pm.ps_work, mt7615_pm_power_save_work);
    532	INIT_WORK(&dev->pm.wake_work, mt7615_pm_wake_work);
    533	spin_lock_init(&dev->pm.wake.lock);
    534	mutex_init(&dev->pm.mutex);
    535	init_waitqueue_head(&dev->pm.wait);
    536	spin_lock_init(&dev->pm.txq_lock);
    537	INIT_DELAYED_WORK(&dev->mphy.mac_work, mt7615_mac_work);
    538	INIT_DELAYED_WORK(&dev->phy.scan_work, mt7615_scan_work);
    539	INIT_DELAYED_WORK(&dev->coredump.work, mt7615_coredump_work);
    540	skb_queue_head_init(&dev->phy.scan_event_list);
    541	skb_queue_head_init(&dev->coredump.msg_list);
    542	INIT_LIST_HEAD(&dev->sta_poll_list);
    543	spin_lock_init(&dev->sta_poll_lock);
    544	init_waitqueue_head(&dev->reset_wait);
    545	init_waitqueue_head(&dev->phy.roc_wait);
    546
    547	INIT_WORK(&dev->phy.roc_work, mt7615_roc_work);
    548	timer_setup(&dev->phy.roc_timer, mt7615_roc_timer, 0);
    549
    550	mt7615_init_wiphy(hw);
    551	dev->pm.idle_timeout = MT7615_PM_TIMEOUT;
    552	dev->pm.stats.last_wake_event = jiffies;
    553	dev->pm.stats.last_doze_event = jiffies;
    554	mt7615_cap_dbdc_disable(dev);
    555
    556#ifdef CONFIG_NL80211_TESTMODE
    557	dev->mt76.test_ops = &mt7615_testmode_ops;
    558#endif
    559}
    560EXPORT_SYMBOL_GPL(mt7615_init_device);