Path: blob/main/sys/contrib/dev/mediatek/mt76/mt7925/init.c
106175 views
// SPDX-License-Identifier: BSD-3-Clause-Clear1/* 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 "regd.h"10#include "mac.h"11#include "mcu.h"1213#if defined(CONFIG_HWMON)14static ssize_t mt7925_thermal_temp_show(struct device *dev,15struct device_attribute *attr,16char *buf)17{18switch (to_sensor_dev_attr(attr)->index) {19case 0: {20struct mt792x_phy *phy = dev_get_drvdata(dev);21struct mt792x_dev *mdev = phy->dev;22int temperature;2324mt792x_mutex_acquire(mdev);25temperature = mt7925_mcu_get_temperature(phy);26mt792x_mutex_release(mdev);2728if (temperature < 0)29return temperature;30/* display in millidegree Celsius */31return sprintf(buf, "%u\n", temperature * 1000);32}33default:34return -EINVAL;35}36}37static SENSOR_DEVICE_ATTR_RO(temp1_input, mt7925_thermal_temp, 0);3839static struct attribute *mt7925_hwmon_attrs[] = {40&sensor_dev_attr_temp1_input.dev_attr.attr,41NULL,42};43ATTRIBUTE_GROUPS(mt7925_hwmon);4445static int mt7925_thermal_init(struct mt792x_phy *phy)46{47struct wiphy *wiphy = phy->mt76->hw->wiphy;48struct device *hwmon;49const char *name;5051if (!IS_REACHABLE(CONFIG_HWMON))52return 0;5354name = devm_kasprintf(&wiphy->dev, GFP_KERNEL, "mt7925_%s",55wiphy_name(wiphy));56if (!name)57return -ENOMEM;5859hwmon = devm_hwmon_device_register_with_groups(&wiphy->dev, name, phy,60mt7925_hwmon_groups);61return PTR_ERR_OR_ZERO(hwmon);62}63#endif6465static void mt7925_mac_init_basic_rates(struct mt792x_dev *dev)66{67int i;6869for (i = 0; i < ARRAY_SIZE(mt76_rates); i++) {70u16 rate = mt76_rates[i].hw_value;71u16 idx = MT792x_BASIC_RATES_TBL + i;7273rate = FIELD_PREP(MT_TX_RATE_MODE, rate >> 8) |74FIELD_PREP(MT_TX_RATE_IDX, rate & GENMASK(7, 0));75mt7925_mac_set_fixed_rate_table(dev, idx, rate);76}77}7879int mt7925_mac_init(struct mt792x_dev *dev)80{81int i;8283mt76_rmw_field(dev, MT_MDP_DCR1, MT_MDP_DCR1_MAX_RX_LEN, 1536);84/* enable hardware de-agg */85mt76_set(dev, MT_MDP_DCR0, MT_MDP_DCR0_DAMSDU_EN);8687for (i = 0; i < MT792x_WTBL_SIZE; i++)88mt7925_mac_wtbl_update(dev, i,89MT_WTBL_UPDATE_ADM_COUNT_CLEAR);90for (i = 0; i < 2; i++)91mt792x_mac_init_band(dev, i);9293mt7925_mac_init_basic_rates(dev);9495return 0;96}97EXPORT_SYMBOL_GPL(mt7925_mac_init);9899static int __mt7925_init_hardware(struct mt792x_dev *dev)100{101int ret;102103ret = mt792x_mcu_init(dev);104if (ret)105goto out;106107ret = mt76_eeprom_override(&dev->mphy);108if (ret)109goto out;110111ret = mt7925_mcu_set_eeprom(dev);112if (ret)113goto out;114115ret = mt7925_mac_init(dev);116if (ret)117goto out;118119out:120return ret;121}122123static int mt7925_init_hardware(struct mt792x_dev *dev)124{125int ret, i;126127set_bit(MT76_STATE_INITIALIZED, &dev->mphy.state);128129for (i = 0; i < MT792x_MCU_INIT_RETRY_COUNT; i++) {130ret = __mt7925_init_hardware(dev);131if (!ret)132break;133134mt792x_init_reset(dev);135}136137if (i == MT792x_MCU_INIT_RETRY_COUNT) {138dev_err(dev->mt76.dev, "hardware init failed\n");139return ret;140}141142return 0;143}144145static void mt7925_init_work(struct work_struct *work)146{147struct mt792x_dev *dev = container_of(work, struct mt792x_dev,148init_work);149int ret;150151ret = mt7925_init_hardware(dev);152if (ret)153return;154155mt76_set_stream_caps(&dev->mphy, true);156mt7925_set_stream_he_eht_caps(&dev->phy);157mt792x_config_mac_addr_list(dev);158159ret = mt7925_init_mlo_caps(&dev->phy);160if (ret) {161dev_err(dev->mt76.dev, "MLO init failed\n");162return;163}164165ret = mt76_register_device(&dev->mt76, true, mt76_rates,166ARRAY_SIZE(mt76_rates));167if (ret) {168dev_err(dev->mt76.dev, "register device failed\n");169return;170}171172#if !defined(__FreeBSD__) || defined(CONFIG_MT7925_DEBUGFS)173ret = mt7925_init_debugfs(dev);174if (ret) {175dev_err(dev->mt76.dev, "register debugfs failed\n");176return;177}178#endif179180#if defined(CONFIG_HWMON)181ret = mt7925_thermal_init(&dev->phy);182if (ret) {183dev_err(dev->mt76.dev, "thermal init failed\n");184return;185}186#endif187188ret = mt7925_mcu_set_thermal_protect(dev);189if (ret) {190dev_err(dev->mt76.dev, "thermal protection enable failed\n");191return;192}193194/* we support chip reset now */195dev->hw_init_done = true;196197mt7925_mcu_set_deep_sleep(dev, dev->pm.ds_enable);198}199200int mt7925_register_device(struct mt792x_dev *dev)201{202struct ieee80211_hw *hw = mt76_hw(dev);203int ret;204205dev->phy.dev = dev;206dev->phy.mt76 = &dev->mt76.phy;207dev->mt76.phy.priv = &dev->phy;208dev->mt76.tx_worker.fn = mt792x_tx_worker;209210INIT_DELAYED_WORK(&dev->pm.ps_work, mt792x_pm_power_save_work);211INIT_DELAYED_WORK(&dev->mlo_pm_work, mt7925_mlo_pm_work);212INIT_WORK(&dev->pm.wake_work, mt792x_pm_wake_work);213spin_lock_init(&dev->pm.wake.lock);214mutex_init(&dev->pm.mutex);215init_waitqueue_head(&dev->pm.wait);216init_waitqueue_head(&dev->wait);217spin_lock_init(&dev->pm.txq_lock);218INIT_DELAYED_WORK(&dev->mphy.mac_work, mt792x_mac_work);219INIT_DELAYED_WORK(&dev->phy.scan_work, mt7925_scan_work);220INIT_DELAYED_WORK(&dev->coredump.work, mt7925_coredump_work);221#if IS_ENABLED(CONFIG_IPV6)222INIT_WORK(&dev->ipv6_ns_work, mt7925_set_ipv6_ns_work);223skb_queue_head_init(&dev->ipv6_ns_list);224#endif225skb_queue_head_init(&dev->phy.scan_event_list);226skb_queue_head_init(&dev->coredump.msg_list);227228INIT_WORK(&dev->reset_work, mt7925_mac_reset_work);229INIT_WORK(&dev->init_work, mt7925_init_work);230231INIT_WORK(&dev->phy.roc_work, mt7925_roc_work);232timer_setup(&dev->phy.roc_timer, mt792x_roc_timer, 0);233init_waitqueue_head(&dev->phy.roc_wait);234235dev->pm.idle_timeout = MT792x_PM_TIMEOUT;236dev->pm.stats.last_wake_event = jiffies;237dev->pm.stats.last_doze_event = jiffies;238if (!mt76_is_usb(&dev->mt76)) {239dev->pm.enable_user = true;240dev->pm.enable = true;241dev->pm.ds_enable_user = true;242dev->pm.ds_enable = true;243}244245if (!mt76_is_mmio(&dev->mt76))246hw->extra_tx_headroom += MT_SDIO_TXD_SIZE + MT_SDIO_HDR_SIZE;247248mt792x_init_acpi_sar(dev);249250ret = mt792x_init_wcid(dev);251if (ret)252return ret;253254ret = mt792x_init_wiphy(hw);255if (ret)256return ret;257258hw->wiphy->reg_notifier = mt7925_regd_notifier;259dev->mphy.sband_2g.sband.ht_cap.cap |=260IEEE80211_HT_CAP_LDPC_CODING |261IEEE80211_HT_CAP_MAX_AMSDU;262dev->mphy.sband_2g.sband.ht_cap.ampdu_density =263IEEE80211_HT_MPDU_DENSITY_2;264dev->mphy.sband_5g.sband.ht_cap.cap |=265IEEE80211_HT_CAP_LDPC_CODING |266IEEE80211_HT_CAP_MAX_AMSDU;267dev->mphy.sband_2g.sband.ht_cap.ampdu_density =268IEEE80211_HT_MPDU_DENSITY_1;269dev->mphy.sband_5g.sband.vht_cap.cap |=270IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454 |271IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK |272IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE |273IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE |274(3 << IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT);275dev->mphy.sband_5g.sband.vht_cap.cap |=276IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ |277IEEE80211_VHT_CAP_SHORT_GI_160;278279dev->mphy.hw->wiphy->available_antennas_rx = dev->mphy.chainmask;280dev->mphy.hw->wiphy->available_antennas_tx = dev->mphy.chainmask;281282queue_work(system_percpu_wq, &dev->init_work);283284return 0;285}286EXPORT_SYMBOL_GPL(mt7925_register_device);287288289