diff options
Diffstat (limited to 'sys/contrib/dev/mediatek/mt76/mt7921/init.c')
-rw-r--r-- | sys/contrib/dev/mediatek/mt76/mt7921/init.c | 102 |
1 files changed, 95 insertions, 7 deletions
diff --git a/sys/contrib/dev/mediatek/mt76/mt7921/init.c b/sys/contrib/dev/mediatek/mt76/mt7921/init.c index bb2e1eb8d684..2498f6d30f4f 100644 --- a/sys/contrib/dev/mediatek/mt76/mt7921/init.c +++ b/sys/contrib/dev/mediatek/mt76/mt7921/init.c @@ -53,32 +53,118 @@ static int mt7921_thermal_init(struct mt792x_phy *phy) name = devm_kasprintf(&wiphy->dev, GFP_KERNEL, "mt7921_%s", wiphy_name(wiphy)); + if (!name) + return -ENOMEM; hwmon = devm_hwmon_device_register_with_groups(&wiphy->dev, name, phy, mt7921_hwmon_groups); - if (IS_ERR(hwmon)) - return PTR_ERR(hwmon); - - return 0; + return PTR_ERR_OR_ZERO(hwmon); } #endif static void +mt7921_regd_channel_update(struct wiphy *wiphy, struct mt792x_dev *dev) +{ +#define IS_UNII_INVALID(idx, sfreq, efreq) \ + (!(dev->phy.clc_chan_conf & BIT(idx)) && (cfreq) >= (sfreq) && (cfreq) <= (efreq)) + struct ieee80211_supported_band *sband; + struct mt76_dev *mdev = &dev->mt76; + struct device_node *np, *band_np; + struct ieee80211_channel *ch; + int i, cfreq; + + np = mt76_find_power_limits_node(mdev); + + sband = wiphy->bands[NL80211_BAND_5GHZ]; +#if defined(CONFIG_OF) + band_np = np ? of_get_child_by_name(np, "txpower-5g") : NULL; +#else + band_np = NULL; +#endif + for (i = 0; i < sband->n_channels; i++) { + ch = &sband->channels[i]; + cfreq = ch->center_freq; + + if (np && (!band_np || !mt76_find_channel_node(band_np, ch))) { + ch->flags |= IEEE80211_CHAN_DISABLED; + continue; + } + + /* UNII-4 */ + if (IS_UNII_INVALID(0, 5845, 5925)) + ch->flags |= IEEE80211_CHAN_DISABLED; + } + + sband = wiphy->bands[NL80211_BAND_6GHZ]; + if (!sband) + return; + +#if defined(CONFIG_OF) + band_np = np ? of_get_child_by_name(np, "txpower-6g") : NULL; +#else + band_np = NULL; +#endif + for (i = 0; i < sband->n_channels; i++) { + ch = &sband->channels[i]; + cfreq = ch->center_freq; + + if (np && (!band_np || !mt76_find_channel_node(band_np, ch))) { + ch->flags |= IEEE80211_CHAN_DISABLED; + continue; + } + + /* UNII-5/6/7/8 */ + if (IS_UNII_INVALID(1, 5925, 6425) || + IS_UNII_INVALID(2, 6425, 6525) || + IS_UNII_INVALID(3, 6525, 6875) || + IS_UNII_INVALID(4, 6875, 7125)) + ch->flags |= IEEE80211_CHAN_DISABLED; + } +} + +void mt7921_regd_update(struct mt792x_dev *dev) +{ + struct mt76_dev *mdev = &dev->mt76; + struct ieee80211_hw *hw = mdev->hw; + struct wiphy *wiphy = hw->wiphy; + + mt7921_mcu_set_clc(dev, mdev->alpha2, dev->country_ie_env); + mt7921_regd_channel_update(wiphy, dev); + mt76_connac_mcu_set_channel_domain(hw->priv); + mt7921_set_tx_sar_pwr(hw, NULL); +} +EXPORT_SYMBOL_GPL(mt7921_regd_update); + +static void mt7921_regd_notifier(struct wiphy *wiphy, struct regulatory_request *request) { struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy); struct mt792x_dev *dev = mt792x_hw_dev(hw); + struct mt76_connac_pm *pm = &dev->pm; memcpy(dev->mt76.alpha2, request->alpha2, sizeof(dev->mt76.alpha2)); dev->mt76.region = request->dfs_region; dev->country_ie_env = request->country_ie_env; + if (request->initiator == NL80211_REGDOM_SET_BY_USER) { + if (dev->mt76.alpha2[0] == '0' && dev->mt76.alpha2[1] == '0') + wiphy->regulatory_flags &= ~REGULATORY_COUNTRY_IE_IGNORE; + else + wiphy->regulatory_flags |= REGULATORY_COUNTRY_IE_IGNORE; + } + + if (pm->suspended) + return; + + dev->regd_in_progress = true; + mt792x_mutex_acquire(dev); - mt7921_mcu_set_clc(dev, request->alpha2, request->country_ie_env); - mt76_connac_mcu_set_channel_domain(hw->priv); - mt7921_set_tx_sar_pwr(hw, NULL); + mt7921_regd_update(dev); mt792x_mutex_release(dev); + + dev->regd_in_progress = false; + wake_up(&dev->wait); } int mt7921_mac_init(struct mt792x_dev *dev) @@ -158,6 +244,7 @@ static void mt7921_init_work(struct work_struct *work) mt76_set_stream_caps(&dev->mphy, true); mt7921_set_stream_he_caps(&dev->phy); + mt792x_config_mac_addr_list(dev); ret = mt76_register_device(&dev->mt76, true, mt76_rates, ARRAY_SIZE(mt76_rates)); @@ -203,6 +290,7 @@ int mt7921_register_device(struct mt792x_dev *dev) spin_lock_init(&dev->pm.wake.lock); mutex_init(&dev->pm.mutex); init_waitqueue_head(&dev->pm.wait); + init_waitqueue_head(&dev->wait); if (mt76_is_sdio(&dev->mt76)) init_waitqueue_head(&dev->mt76.sdio.wait); spin_lock_init(&dev->pm.txq_lock); |