Path: blob/main/sys/contrib/dev/mediatek/mt76/mt7925/init.c
48525 views
// SPDX-License-Identifier: ISC1/* Copyright (C) 2023 MediaTek Inc. */23#include <linux/etherdevice.h>4#include <linux/hwmon.h>5#include <linux/hwmon-sysfs.h>6#include <linux/thermal.h>7#include <linux/firmware.h>8#include "mt7925.h"9#include "mac.h"10#include "mcu.h"1112#if defined(CONFIG_HWMON)13static ssize_t mt7925_thermal_temp_show(struct device *dev,14struct device_attribute *attr,15char *buf)16{17switch (to_sensor_dev_attr(attr)->index) {18case 0: {19struct mt792x_phy *phy = dev_get_drvdata(dev);20struct mt792x_dev *mdev = phy->dev;21int temperature;2223mt792x_mutex_acquire(mdev);24temperature = mt7925_mcu_get_temperature(phy);25mt792x_mutex_release(mdev);2627if (temperature < 0)28return temperature;29/* display in millidegree Celsius */30return sprintf(buf, "%u\n", temperature * 1000);31}32default:33return -EINVAL;34}35}36static SENSOR_DEVICE_ATTR_RO(temp1_input, mt7925_thermal_temp, 0);3738static struct attribute *mt7925_hwmon_attrs[] = {39&sensor_dev_attr_temp1_input.dev_attr.attr,40NULL,41};42ATTRIBUTE_GROUPS(mt7925_hwmon);4344static int mt7925_thermal_init(struct mt792x_phy *phy)45{46struct wiphy *wiphy = phy->mt76->hw->wiphy;47struct device *hwmon;48const char *name;4950if (!IS_REACHABLE(CONFIG_HWMON))51return 0;5253name = devm_kasprintf(&wiphy->dev, GFP_KERNEL, "mt7925_%s",54wiphy_name(wiphy));55if (!name)56return -ENOMEM;5758hwmon = devm_hwmon_device_register_with_groups(&wiphy->dev, name, phy,59mt7925_hwmon_groups);60return PTR_ERR_OR_ZERO(hwmon);61}62#endif6364void mt7925_regd_be_ctrl(struct mt792x_dev *dev, u8 *alpha2)65{66struct mt792x_phy *phy = &dev->phy;67struct mt7925_clc_rule_v2 *rule;68struct mt7925_clc *clc;69bool old = dev->has_eht, new = true;70u32 mtcl_conf = mt792x_acpi_get_mtcl_conf(&dev->phy, alpha2);71u8 *pos;7273if (mtcl_conf != MT792X_ACPI_MTCL_INVALID &&74(((mtcl_conf >> 4) & 0x3) == 0)) {75new = false;76goto out;77}7879if (!phy->clc[MT792x_CLC_BE_CTRL])80goto out;8182clc = (struct mt7925_clc *)phy->clc[MT792x_CLC_BE_CTRL];83pos = clc->data;8485while (1) {86rule = (struct mt7925_clc_rule_v2 *)pos;8788if (rule->alpha2[0] == alpha2[0] &&89rule->alpha2[1] == alpha2[1]) {90new = false;91break;92}9394/* Check the last one */95if (rule->flag & BIT(0))96break;9798pos += sizeof(*rule);99}100101out:102if (old == new)103return;104105dev->has_eht = new;106mt7925_set_stream_he_eht_caps(phy);107}108109static void110mt7925_regd_channel_update(struct wiphy *wiphy, struct mt792x_dev *dev)111{112#define IS_UNII_INVALID(idx, sfreq, efreq, cfreq) \113(!(dev->phy.clc_chan_conf & BIT(idx)) && (cfreq) >= (sfreq) && (cfreq) <= (efreq))114#define MT7925_UNII_59G_IS_VALID 0x1115#define MT7925_UNII_6G_IS_VALID 0x1e116struct ieee80211_supported_band *sband;117struct mt76_dev *mdev = &dev->mt76;118struct ieee80211_channel *ch;119u32 mtcl_conf = mt792x_acpi_get_mtcl_conf(&dev->phy, mdev->alpha2);120int i;121122if (mtcl_conf != MT792X_ACPI_MTCL_INVALID) {123if ((mtcl_conf & 0x3) == 0)124dev->phy.clc_chan_conf &= ~MT7925_UNII_59G_IS_VALID;125if (((mtcl_conf >> 2) & 0x3) == 0)126dev->phy.clc_chan_conf &= ~MT7925_UNII_6G_IS_VALID;127}128129sband = wiphy->bands[NL80211_BAND_5GHZ];130if (!sband)131return;132133for (i = 0; i < sband->n_channels; i++) {134ch = &sband->channels[i];135136/* UNII-4 */137if (IS_UNII_INVALID(0, 5845, 5925, ch->center_freq))138ch->flags |= IEEE80211_CHAN_DISABLED;139}140141sband = wiphy->bands[NL80211_BAND_6GHZ];142if (!sband)143return;144145for (i = 0; i < sband->n_channels; i++) {146ch = &sband->channels[i];147148/* UNII-5/6/7/8 */149if (IS_UNII_INVALID(1, 5925, 6425, ch->center_freq) ||150IS_UNII_INVALID(2, 6425, 6525, ch->center_freq) ||151IS_UNII_INVALID(3, 6525, 6875, ch->center_freq) ||152IS_UNII_INVALID(4, 6875, 7125, ch->center_freq))153ch->flags |= IEEE80211_CHAN_DISABLED;154}155}156157void mt7925_regd_update(struct mt792x_dev *dev)158{159struct mt76_dev *mdev = &dev->mt76;160struct ieee80211_hw *hw = mdev->hw;161struct wiphy *wiphy = hw->wiphy;162163if (!dev->regd_change)164return;165166mt7925_mcu_set_clc(dev, mdev->alpha2, dev->country_ie_env);167mt7925_regd_channel_update(wiphy, dev);168mt7925_mcu_set_channel_domain(hw->priv);169mt7925_set_tx_sar_pwr(hw, NULL);170dev->regd_change = false;171}172EXPORT_SYMBOL_GPL(mt7925_regd_update);173174static void175mt7925_regd_notifier(struct wiphy *wiphy,176struct regulatory_request *req)177{178struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);179struct mt792x_dev *dev = mt792x_hw_dev(hw);180struct mt76_dev *mdev = &dev->mt76;181struct mt76_connac_pm *pm = &dev->pm;182183/* allow world regdom at the first boot only */184if (!memcmp(req->alpha2, "00", 2) &&185mdev->alpha2[0] && mdev->alpha2[1])186return;187188/* do not need to update the same country twice */189if (!memcmp(req->alpha2, mdev->alpha2, 2) &&190dev->country_ie_env == req->country_ie_env)191return;192193memcpy(mdev->alpha2, req->alpha2, 2);194mdev->region = req->dfs_region;195dev->country_ie_env = req->country_ie_env;196dev->regd_change = true;197198if (pm->suspended)199return;200201dev->regd_in_progress = true;202mt792x_mutex_acquire(dev);203mt7925_regd_update(dev);204mt792x_mutex_release(dev);205dev->regd_in_progress = false;206wake_up(&dev->wait);207}208209static void mt7925_mac_init_basic_rates(struct mt792x_dev *dev)210{211int i;212213for (i = 0; i < ARRAY_SIZE(mt76_rates); i++) {214u16 rate = mt76_rates[i].hw_value;215u16 idx = MT792x_BASIC_RATES_TBL + i;216217rate = FIELD_PREP(MT_TX_RATE_MODE, rate >> 8) |218FIELD_PREP(MT_TX_RATE_IDX, rate & GENMASK(7, 0));219mt7925_mac_set_fixed_rate_table(dev, idx, rate);220}221}222223int mt7925_mac_init(struct mt792x_dev *dev)224{225int i;226227mt76_rmw_field(dev, MT_MDP_DCR1, MT_MDP_DCR1_MAX_RX_LEN, 1536);228/* enable hardware de-agg */229mt76_set(dev, MT_MDP_DCR0, MT_MDP_DCR0_DAMSDU_EN);230231for (i = 0; i < MT792x_WTBL_SIZE; i++)232mt7925_mac_wtbl_update(dev, i,233MT_WTBL_UPDATE_ADM_COUNT_CLEAR);234for (i = 0; i < 2; i++)235mt792x_mac_init_band(dev, i);236237mt7925_mac_init_basic_rates(dev);238239memzero_explicit(&dev->mt76.alpha2, sizeof(dev->mt76.alpha2));240241return 0;242}243EXPORT_SYMBOL_GPL(mt7925_mac_init);244245static int __mt7925_init_hardware(struct mt792x_dev *dev)246{247int ret;248249ret = mt792x_mcu_init(dev);250if (ret)251goto out;252253mt76_eeprom_override(&dev->mphy);254255ret = mt7925_mcu_set_eeprom(dev);256if (ret)257goto out;258259ret = mt7925_mac_init(dev);260if (ret)261goto out;262263out:264return ret;265}266267static int mt7925_init_hardware(struct mt792x_dev *dev)268{269int ret, i;270271set_bit(MT76_STATE_INITIALIZED, &dev->mphy.state);272273for (i = 0; i < MT792x_MCU_INIT_RETRY_COUNT; i++) {274ret = __mt7925_init_hardware(dev);275if (!ret)276break;277278mt792x_init_reset(dev);279}280281if (i == MT792x_MCU_INIT_RETRY_COUNT) {282dev_err(dev->mt76.dev, "hardware init failed\n");283return ret;284}285286return 0;287}288289static void mt7925_init_work(struct work_struct *work)290{291struct mt792x_dev *dev = container_of(work, struct mt792x_dev,292init_work);293int ret;294295ret = mt7925_init_hardware(dev);296if (ret)297return;298299mt76_set_stream_caps(&dev->mphy, true);300mt7925_set_stream_he_eht_caps(&dev->phy);301mt792x_config_mac_addr_list(dev);302303ret = mt7925_init_mlo_caps(&dev->phy);304if (ret) {305dev_err(dev->mt76.dev, "MLO init failed\n");306return;307}308309ret = mt76_register_device(&dev->mt76, true, mt76_rates,310ARRAY_SIZE(mt76_rates));311if (ret) {312dev_err(dev->mt76.dev, "register device failed\n");313return;314}315316#if !defined(__FreeBSD__) || defined(CONFIG_MT7925_DEBUGFS)317ret = mt7925_init_debugfs(dev);318if (ret) {319dev_err(dev->mt76.dev, "register debugfs failed\n");320return;321}322#endif323324#if defined(CONFIG_HWMON)325ret = mt7925_thermal_init(&dev->phy);326if (ret) {327dev_err(dev->mt76.dev, "thermal init failed\n");328return;329}330#endif331332ret = mt7925_mcu_set_thermal_protect(dev);333if (ret) {334dev_err(dev->mt76.dev, "thermal protection enable failed\n");335return;336}337338/* we support chip reset now */339dev->hw_init_done = true;340341mt7925_mcu_set_deep_sleep(dev, dev->pm.ds_enable);342}343344int mt7925_register_device(struct mt792x_dev *dev)345{346struct ieee80211_hw *hw = mt76_hw(dev);347int ret;348349dev->phy.dev = dev;350dev->phy.mt76 = &dev->mt76.phy;351dev->mt76.phy.priv = &dev->phy;352dev->mt76.tx_worker.fn = mt792x_tx_worker;353354INIT_DELAYED_WORK(&dev->pm.ps_work, mt792x_pm_power_save_work);355INIT_DELAYED_WORK(&dev->mlo_pm_work, mt7925_mlo_pm_work);356INIT_WORK(&dev->pm.wake_work, mt792x_pm_wake_work);357spin_lock_init(&dev->pm.wake.lock);358mutex_init(&dev->pm.mutex);359init_waitqueue_head(&dev->pm.wait);360init_waitqueue_head(&dev->wait);361spin_lock_init(&dev->pm.txq_lock);362INIT_DELAYED_WORK(&dev->mphy.mac_work, mt792x_mac_work);363INIT_DELAYED_WORK(&dev->phy.scan_work, mt7925_scan_work);364INIT_DELAYED_WORK(&dev->coredump.work, mt7925_coredump_work);365#if IS_ENABLED(CONFIG_IPV6)366INIT_WORK(&dev->ipv6_ns_work, mt7925_set_ipv6_ns_work);367skb_queue_head_init(&dev->ipv6_ns_list);368#endif369skb_queue_head_init(&dev->phy.scan_event_list);370skb_queue_head_init(&dev->coredump.msg_list);371372INIT_WORK(&dev->reset_work, mt7925_mac_reset_work);373INIT_WORK(&dev->init_work, mt7925_init_work);374375INIT_WORK(&dev->phy.roc_work, mt7925_roc_work);376timer_setup(&dev->phy.roc_timer, mt792x_roc_timer, 0);377init_waitqueue_head(&dev->phy.roc_wait);378379dev->pm.idle_timeout = MT792x_PM_TIMEOUT;380dev->pm.stats.last_wake_event = jiffies;381dev->pm.stats.last_doze_event = jiffies;382if (!mt76_is_usb(&dev->mt76)) {383dev->pm.enable_user = true;384dev->pm.enable = true;385dev->pm.ds_enable_user = true;386dev->pm.ds_enable = true;387}388389if (!mt76_is_mmio(&dev->mt76))390hw->extra_tx_headroom += MT_SDIO_TXD_SIZE + MT_SDIO_HDR_SIZE;391392mt792x_init_acpi_sar(dev);393394ret = mt792x_init_wcid(dev);395if (ret)396return ret;397398ret = mt792x_init_wiphy(hw);399if (ret)400return ret;401402hw->wiphy->reg_notifier = mt7925_regd_notifier;403dev->mphy.sband_2g.sband.ht_cap.cap |=404IEEE80211_HT_CAP_LDPC_CODING |405IEEE80211_HT_CAP_MAX_AMSDU;406dev->mphy.sband_2g.sband.ht_cap.ampdu_density =407IEEE80211_HT_MPDU_DENSITY_2;408dev->mphy.sband_5g.sband.ht_cap.cap |=409IEEE80211_HT_CAP_LDPC_CODING |410IEEE80211_HT_CAP_MAX_AMSDU;411dev->mphy.sband_2g.sband.ht_cap.ampdu_density =412IEEE80211_HT_MPDU_DENSITY_1;413dev->mphy.sband_5g.sband.vht_cap.cap |=414IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454 |415IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK |416IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE |417IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE |418(3 << IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT);419dev->mphy.sband_5g.sband.vht_cap.cap |=420IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ |421IEEE80211_VHT_CAP_SHORT_GI_160;422423dev->mphy.hw->wiphy->available_antennas_rx = dev->mphy.chainmask;424dev->mphy.hw->wiphy->available_antennas_tx = dev->mphy.chainmask;425426queue_work(system_wq, &dev->init_work);427428return 0;429}430EXPORT_SYMBOL_GPL(mt7925_register_device);431432433