Path: blob/main/sys/contrib/dev/mediatek/mt76/mt7915/eeprom.c
107707 views
// SPDX-License-Identifier: BSD-3-Clause-Clear1/* Copyright (C) 2020 MediaTek Inc. */23#if defined(__FreeBSD__)4#define LINUXKPI_PARAM_PREFIX mt7915_5#endif67#include <linux/firmware.h>8#include <linux/moduleparam.h>9#include "mt7915.h"10#include "eeprom.h"1112static bool enable_6ghz;13module_param(enable_6ghz, bool, 0644);14MODULE_PARM_DESC(enable_6ghz, "Enable 6 GHz instead of 5 GHz on hardware that supports both");1516static int mt7915_eeprom_load_precal(struct mt7915_dev *dev)17{18struct mt76_dev *mdev = &dev->mt76;19u8 *eeprom = mdev->eeprom.data;20u32 offs = is_mt7915(&dev->mt76) ? MT_EE_DO_PRE_CAL : MT_EE_DO_PRE_CAL_V2;21u32 size, val = eeprom[offs];22int ret;2324if (!dev->flash_mode || !val)25return 0;2627size = mt7915_get_cal_group_size(dev) + mt7915_get_cal_dpd_size(dev);2829dev->cal = devm_kzalloc(mdev->dev, size, GFP_KERNEL);30if (!dev->cal)31return -ENOMEM;3233offs = is_mt7915(&dev->mt76) ? MT_EE_PRECAL : MT_EE_PRECAL_V2;3435ret = mt76_get_of_data_from_mtd(mdev, dev->cal, offs, size);36if (!ret)37return ret;3839ret = mt76_get_of_data_from_nvmem(mdev, dev->cal, "precal", size);40if (!ret)41return ret;4243dev_warn(mdev->dev, "missing precal data, size=%d\n", size);44devm_kfree(mdev->dev, dev->cal);45dev->cal = NULL;4647return ret;48}4950static int mt7915_check_eeprom(struct mt7915_dev *dev)51{52u8 *eeprom = dev->mt76.eeprom.data;53u16 val = get_unaligned_le16(eeprom);5455#define CHECK_EEPROM_ERR(match) (match ? 0 : -EINVAL)56switch (val) {57case 0x7915:58return CHECK_EEPROM_ERR(is_mt7915(&dev->mt76));59case 0x7916:60return CHECK_EEPROM_ERR(is_mt7916(&dev->mt76));61case 0x7981:62return CHECK_EEPROM_ERR(is_mt7981(&dev->mt76));63case 0x7986:64return CHECK_EEPROM_ERR(is_mt7986(&dev->mt76));65default:66return -EINVAL;67}68}6970static char *mt7915_eeprom_name(struct mt7915_dev *dev)71{72switch (mt76_chip(&dev->mt76)) {73case 0x7915:74return dev->dbdc_support ?75MT7915_EEPROM_DEFAULT_DBDC : MT7915_EEPROM_DEFAULT;76case 0x7981:77/* mt7981 only supports mt7976 and only in DBDC mode */78return MT7981_EEPROM_MT7976_DEFAULT_DBDC;79case 0x7986:80switch (mt7915_check_adie(dev, true)) {81case MT7976_ONE_ADIE_DBDC:82return MT7986_EEPROM_MT7976_DEFAULT_DBDC;83case MT7975_ONE_ADIE:84return MT7986_EEPROM_MT7975_DEFAULT;85case MT7976_ONE_ADIE:86return MT7986_EEPROM_MT7976_DEFAULT;87case MT7975_DUAL_ADIE:88return MT7986_EEPROM_MT7975_DUAL_DEFAULT;89case MT7976_DUAL_ADIE:90return MT7986_EEPROM_MT7976_DUAL_DEFAULT;91default:92break;93}94return NULL;95default:96return MT7916_EEPROM_DEFAULT;97}98}99100static int101mt7915_eeprom_load_default(struct mt7915_dev *dev)102{103u8 *eeprom = dev->mt76.eeprom.data;104const struct firmware *fw = NULL;105int ret;106107ret = request_firmware(&fw, mt7915_eeprom_name(dev), dev->mt76.dev);108if (ret)109return ret;110111if (!fw || !fw->data) {112dev_err(dev->mt76.dev, "Invalid default bin\n");113ret = -EINVAL;114goto out;115}116117memcpy(eeprom, fw->data, mt7915_eeprom_size(dev));118dev->flash_mode = true;119120out:121release_firmware(fw);122123return ret;124}125126static int mt7915_eeprom_load(struct mt7915_dev *dev)127{128int ret;129u16 eeprom_size = mt7915_eeprom_size(dev);130131ret = mt76_eeprom_init(&dev->mt76, eeprom_size);132if (ret < 0)133return ret;134135if (ret) {136dev->flash_mode = true;137} else {138u8 free_block_num;139u32 block_num, i;140u32 eeprom_blk_size = MT7915_EEPROM_BLOCK_SIZE;141142ret = mt7915_mcu_get_eeprom_free_block(dev, &free_block_num);143if (ret < 0)144return ret;145146/* efuse info isn't enough */147if (free_block_num >= 29)148return -EINVAL;149150/* read eeprom data from efuse */151block_num = DIV_ROUND_UP(eeprom_size, eeprom_blk_size);152for (i = 0; i < block_num; i++) {153ret = mt7915_mcu_get_eeprom(dev, i * eeprom_blk_size, NULL);154if (ret < 0)155return ret;156}157}158159return mt7915_check_eeprom(dev);160}161162static void mt7915_eeprom_parse_band_config(struct mt7915_phy *phy)163{164struct mt7915_dev *dev = phy->dev;165u8 *eeprom = dev->mt76.eeprom.data;166u8 band = phy->mt76->band_idx;167u32 val;168169val = eeprom[MT_EE_WIFI_CONF + band];170val = FIELD_GET(MT_EE_WIFI_CONF0_BAND_SEL, val);171172if (!is_mt7915(&dev->mt76)) {173switch (val) {174case MT_EE_V2_BAND_SEL_5GHZ:175phy->mt76->cap.has_5ghz = true;176return;177case MT_EE_V2_BAND_SEL_6GHZ:178phy->mt76->cap.has_6ghz = true;179return;180case MT_EE_V2_BAND_SEL_5GHZ_6GHZ:181if (enable_6ghz) {182phy->mt76->cap.has_6ghz = true;183u8p_replace_bits(&eeprom[MT_EE_WIFI_CONF + band],184MT_EE_V2_BAND_SEL_6GHZ,185MT_EE_WIFI_CONF0_BAND_SEL);186} else {187phy->mt76->cap.has_5ghz = true;188u8p_replace_bits(&eeprom[MT_EE_WIFI_CONF + band],189MT_EE_V2_BAND_SEL_5GHZ,190MT_EE_WIFI_CONF0_BAND_SEL);191}192/* force to buffer mode */193dev->flash_mode = true;194195return;196default:197phy->mt76->cap.has_2ghz = true;198return;199}200} else if (val == MT_EE_BAND_SEL_DEFAULT && dev->dbdc_support) {201val = band ? MT_EE_BAND_SEL_5GHZ : MT_EE_BAND_SEL_2GHZ;202}203204switch (val) {205case MT_EE_BAND_SEL_5GHZ:206phy->mt76->cap.has_5ghz = true;207break;208case MT_EE_BAND_SEL_2GHZ:209phy->mt76->cap.has_2ghz = true;210break;211default:212phy->mt76->cap.has_2ghz = true;213phy->mt76->cap.has_5ghz = true;214break;215}216}217218void mt7915_eeprom_parse_hw_cap(struct mt7915_dev *dev,219struct mt7915_phy *phy)220{221u8 path, nss, nss_max = 4, *eeprom = dev->mt76.eeprom.data;222struct mt76_phy *mphy = phy->mt76;223u8 band = phy->mt76->band_idx;224225mt7915_eeprom_parse_band_config(phy);226227/* read tx/rx path from eeprom */228if (is_mt7915(&dev->mt76)) {229path = FIELD_GET(MT_EE_WIFI_CONF0_TX_PATH,230eeprom[MT_EE_WIFI_CONF]);231} else {232path = FIELD_GET(MT_EE_WIFI_CONF0_TX_PATH,233eeprom[MT_EE_WIFI_CONF + band]);234}235236if (!path || path > 4)237path = 4;238239/* read tx/rx stream */240nss = path;241if (dev->dbdc_support) {242if (is_mt7915(&dev->mt76)) {243path = min_t(u8, path, 2);244nss = FIELD_GET(MT_EE_WIFI_CONF3_TX_PATH_B0,245eeprom[MT_EE_WIFI_CONF + 3]);246if (band)247nss = FIELD_GET(MT_EE_WIFI_CONF3_TX_PATH_B1,248eeprom[MT_EE_WIFI_CONF + 3]);249} else {250nss = FIELD_GET(MT_EE_WIFI_CONF_STREAM_NUM,251eeprom[MT_EE_WIFI_CONF + 2 + band]);252}253254if (!is_mt798x(&dev->mt76))255nss_max = 2;256}257258if (!nss)259nss = nss_max;260nss = min_t(u8, min_t(u8, nss_max, nss), path);261262mphy->chainmask = BIT(path) - 1;263if (band)264mphy->chainmask <<= dev->chainshift;265mphy->antenna_mask = BIT(nss) - 1;266dev->chainmask |= mphy->chainmask;267dev->chainshift = hweight8(dev->mphy.chainmask);268}269270int mt7915_eeprom_init(struct mt7915_dev *dev)271{272int ret;273274ret = mt7915_eeprom_load(dev);275if (ret < 0) {276if (ret != -EINVAL)277return ret;278279dev_warn(dev->mt76.dev, "eeprom load fail, use default bin\n");280ret = mt7915_eeprom_load_default(dev);281if (ret)282return ret;283}284285mt7915_eeprom_load_precal(dev);286mt7915_eeprom_parse_hw_cap(dev, &dev->phy);287#if defined(__linux__)288memcpy(dev->mphy.macaddr, dev->mt76.eeprom.data + MT_EE_MAC_ADDR,289#elif defined(__FreeBSD__)290memcpy(dev->mphy.macaddr, (u8 *)dev->mt76.eeprom.data + MT_EE_MAC_ADDR,291#endif292ETH_ALEN);293294return mt76_eeprom_override(&dev->mphy);295}296297int mt7915_eeprom_get_target_power(struct mt7915_dev *dev,298struct ieee80211_channel *chan,299u8 chain_idx)300{301u8 *eeprom = dev->mt76.eeprom.data;302int index, target_power;303bool tssi_on, is_7976;304305if (chain_idx > 3)306return -EINVAL;307308tssi_on = mt7915_tssi_enabled(dev, chan->band);309is_7976 = mt7915_check_adie(dev, false) || is_mt7916(&dev->mt76);310311if (chan->band == NL80211_BAND_2GHZ) {312if (is_7976) {313index = MT_EE_TX0_POWER_2G_V2 + chain_idx;314target_power = eeprom[index];315} else {316index = MT_EE_TX0_POWER_2G + chain_idx * 3;317target_power = eeprom[index];318319if (!tssi_on)320target_power += eeprom[index + 1];321}322} else if (chan->band == NL80211_BAND_5GHZ) {323int group = mt7915_get_channel_group_5g(chan->hw_value, is_7976);324325if (is_7976) {326index = MT_EE_TX0_POWER_5G_V2 + chain_idx * 5;327target_power = eeprom[index + group];328} else {329index = MT_EE_TX0_POWER_5G + chain_idx * 12;330target_power = eeprom[index + group];331332if (!tssi_on)333target_power += eeprom[index + 8];334}335} else {336int group = mt7915_get_channel_group_6g(chan->hw_value);337338index = MT_EE_TX0_POWER_6G_V2 + chain_idx * 8;339target_power = is_7976 ? eeprom[index + group] : 0;340}341342return target_power;343}344345s8 mt7915_eeprom_get_power_delta(struct mt7915_dev *dev, int band)346{347u8 *eeprom = dev->mt76.eeprom.data;348u32 val, offs;349s8 delta;350bool is_7976 = mt7915_check_adie(dev, false) || is_mt7916(&dev->mt76);351352if (band == NL80211_BAND_2GHZ)353offs = is_7976 ? MT_EE_RATE_DELTA_2G_V2 : MT_EE_RATE_DELTA_2G;354else if (band == NL80211_BAND_5GHZ)355offs = is_7976 ? MT_EE_RATE_DELTA_5G_V2 : MT_EE_RATE_DELTA_5G;356else357offs = is_7976 ? MT_EE_RATE_DELTA_6G_V2 : 0;358359val = eeprom[offs];360361if (!offs || !(val & MT_EE_RATE_DELTA_EN))362return 0;363364delta = FIELD_GET(MT_EE_RATE_DELTA_MASK, val);365366return val & MT_EE_RATE_DELTA_SIGN ? delta : -delta;367}368369bool370mt7915_eeprom_has_background_radar(struct mt7915_dev *dev)371{372u8 val, buf[MT7915_EEPROM_BLOCK_SIZE];373u8 band_sel, tx_path, rx_path;374int offs = MT_EE_WIFI_CONF + 1;375376switch (mt76_chip(&dev->mt76)) {377case 0x7915:378return true;379case 0x7906:380/* read efuse to check background radar capability */381if (mt7915_mcu_get_eeprom(dev, offs, buf))382break;383384val = buf[offs % MT7915_EEPROM_BLOCK_SIZE];385band_sel = u8_get_bits(val, MT_EE_WIFI_CONF0_BAND_SEL);386tx_path = u8_get_bits(val, MT_EE_WIFI_CONF0_TX_PATH);387rx_path = u8_get_bits(val, MT_EE_WIFI_CONF0_RX_PATH);388389return (band_sel == MT_EE_V2_BAND_SEL_5GHZ &&390tx_path == rx_path && rx_path == 2);391case 0x7981:392case 0x7986:393default:394break;395}396397return false;398}399400const u8 mt7915_sku_group_len[] = {401[SKU_CCK] = 4,402[SKU_OFDM] = 8,403[SKU_HT_BW20] = 8,404[SKU_HT_BW40] = 9,405[SKU_VHT_BW20] = 12,406[SKU_VHT_BW40] = 12,407[SKU_VHT_BW80] = 12,408[SKU_VHT_BW160] = 12,409[SKU_HE_RU26] = 12,410[SKU_HE_RU52] = 12,411[SKU_HE_RU106] = 12,412[SKU_HE_RU242] = 12,413[SKU_HE_RU484] = 12,414[SKU_HE_RU996] = 12,415[SKU_HE_RU2x996] = 12416};417418419