introduce SAR support to mt76x02 drivers
Subsystems (2)
Lorenzo Bianconi
maintainercover introduce SAR support to mt76x02 drivers
Add SAR spec support to mt76x02 driver to allow configuring SAR power limitations on the frequency ranges from the userland.
Lorenzo Bianconi (2):
mt76: move sar utilities to mt76-core module
mt76: mt76x02: introduce SAR support
drivers/net/wireless/mediatek/mt76/mac80211.c | 53 +++++++++++++++++++ drivers/net/wireless/mediatek/mt76/mt76.h | 5 ++ .../wireless/mediatek/mt76/mt76_connac_mcu.c | 27 +--------- .../net/wireless/mediatek/mt76/mt76x0/init.c | 5 +- .../net/wireless/mediatek/mt76/mt76x0/main.c | 34 +++++++++++- .../wireless/mediatek/mt76/mt76x0/mt76x0.h | 2 + .../net/wireless/mediatek/mt76/mt76x0/pci.c | 1 + .../net/wireless/mediatek/mt76/mt76x0/usb.c | 1 + drivers/net/wireless/mediatek/mt76/mt76x02.h | 2 +- .../net/wireless/mediatek/mt76/mt76x02_util.c | 11 +++- .../net/wireless/mediatek/mt76/mt76x2/init.c | 29 ++++++++++ .../wireless/mediatek/mt76/mt76x2/mt76x2.h | 2 + .../wireless/mediatek/mt76/mt76x2/pci_init.c | 5 +- .../wireless/mediatek/mt76/mt76x2/pci_main.c | 7 ++- .../wireless/mediatek/mt76/mt76x2/usb_init.c | 4 +- .../wireless/mediatek/mt76/mt76x2/usb_main.c | 9 +++- .../net/wireless/mediatek/mt76/mt7921/main.c | 26 ++------- 17 files changed, 164 insertions(+), 59 deletions(-)
Signature · 1 line
2.31.1
Lorenzo Bianconi
maintainerPATCH 1/2 mt76: move sar utilities to mt76-core module
Move mt76_get_sar_power and mt76_init_sar_power in the common code. This is a preliminary patch to add sar support to mt76x02 drivers.
Signed-off-by Lorenzo Bianconi <[email protected]>
--- drivers/net/wireless/mediatek/mt76/mac80211.c | 53 +++++++++++++++++++ drivers/net/wireless/mediatek/mt76/mt76.h | 5 ++ .../wireless/mediatek/mt76/mt76_connac_mcu.c | 27 +--------- .../net/wireless/mediatek/mt76/mt7921/main.c | 26 ++------- 4 files changed, 63 insertions(+), 48 deletions(-)
drivers/net/wireless/mediatek/mt76/mac80211.c +53 -0
@@ -1348,6 +1348,59 @@ int mt76_get_txpower(struct ieee80211_hw *hw, struct ieee80211_vif *vif, }EXPORT_SYMBOL_GPL (mt76_get_txpower); +int mt76_init_sar_power (struct ieee80211_hw *hw, +const struct cfg80211_sar_specs *sar) +{ +struct mt76_phy *phy = hw->priv; +const struct cfg80211_sar_capa *capa = hw->wiphy->sar_capa; +int i; + +if (sar->type !=NL80211_SAR_TYPE_POWER || !sar->num_sub_specs) +return -EINVAL ; + +for (i =0 ; i < sar->num_sub_specs; i++) { +u32 index = sar->sub_specs[i].freq_range_index; +/* SAR specifies power limitaton in 0.25dbm */ +s32 power = sar->sub_specs[i].power >>1 ; + +if (power >127 || power <-127 ) + power =127 ; + + phy->frp[index].range = &capa->freq_ranges[index]; + phy->frp[index].power = power; + } + +return 0 ; +} +EXPORT_SYMBOL_GPL (mt76_init_sar_power); + +int mt76_get_sar_power (struct mt76_phy *phy, +struct ieee80211_channel *chan, +int power) +{ +const struct cfg80211_sar_capa *capa = phy->hw->wiphy->sar_capa; +int freq, i; + +if (!capa || !phy->frp) +return power; + +if (power >127 || power <-127 ) + power =127 ; + + freq =ieee80211_channel_to_frequency (chan->hw_value, chan->band); +for (i =0 ; i < capa->num_freq_ranges; i++) { +if (phy->frp[i].range && + freq >= phy->frp[i].range->start_freq && + freq < phy->frp[i].range->end_freq) { + power =min_t (int, phy->frp[i].power, power); +break ; + } + } + +return power; +} +EXPORT_SYMBOL_GPL (mt76_get_sar_power); +static void __mt76_csa_finish (void *priv,u8 *mac,struct ieee80211_vif *vif) {
drivers/net/wireless/mediatek/mt76/mt76.h +5 -0
@@ -1157,6 +1157,11 @@ int mt76_get_min_avg_rssi(struct mt76_dev *dev, bool ext_phy);int mt76_get_txpower (struct ieee80211_hw *hw,struct ieee80211_vif *vif,int *dbm); +int mt76_init_sar_power (struct ieee80211_hw *hw, +const struct cfg80211_sar_specs *sar); +int mt76_get_sar_power (struct mt76_phy *phy, +struct ieee80211_channel *chan, +int power);void mt76_csa_check (struct mt76_dev *dev);void mt76_csa_finish (struct mt76_dev *dev);
drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c +1 -26
@@ -1881,30 +1881,6 @@ mt76_connac_mcu_build_sku(struct mt76_dev *dev, s8 *sku, } } -static s8 mt76_connac_get_sar_power (struct mt76_phy *phy, -struct ieee80211_channel *chan, -s8 target_power) -{ -const struct cfg80211_sar_capa *capa = phy->hw->wiphy->sar_capa; -struct mt76_freq_range_power *frp = phy->frp; -int freq, i; - -if (!capa || !frp) -return target_power; - - freq =ieee80211_channel_to_frequency (chan->hw_value, chan->band); -for (i =0 ; i < capa->num_freq_ranges; i++) { -if (frp[i].range && - freq >= frp[i].range->start_freq && - freq < frp[i].range->end_freq) { - target_power =min_t (s8, frp[i].power, target_power); -break ; - } - } - -return target_power; -} -static s8 mt76_connac_get_ch_power (struct mt76_phy *phy,struct ieee80211_channel *chan,s8 target_power)
@@ -2049,8 +2025,7 @@ mt76_connac_mcu_rate_txpower_band(struct mt76_phy *phy, reg_power =mt76_connac_get_ch_power (phy, &chan, tx_power); - sar_power =mt76_connac_get_sar_power (phy, &chan, - reg_power); + sar_power =mt76_get_sar_power (phy, &chan, reg_power);mt76_get_rate_power_limits (phy, &chan, &limits, sar_power);
drivers/net/wireless/mediatek/mt76/mt7921/main.c +4 -22
@@ -1338,35 +1338,17 @@ static void mt7921_sta_set_decap_offload(struct ieee80211_hw *hw,static int mt7921_set_sar_specs (struct ieee80211_hw *hw,const struct cfg80211_sar_specs *sar) { -const struct cfg80211_sar_capa *capa = hw->wiphy->sar_capa;struct mt7921_dev *dev =mt7921_hw_dev (hw); -struct mt76_freq_range_power *data, *frp;struct mt76_phy *mphy = hw->priv;int err; -u32 i; - -if (sar->type !=NL80211_SAR_TYPE_POWER || !sar->num_sub_specs) -return -EINVAL ;mt7921_mutex_acquire (dev); - - data = mphy->frp; - -for (i =0 ; i < sar->num_sub_specs; i++) { -u32 index = sar->sub_specs[i].freq_range_index; -/* SAR specifies power limitaton in 0.25dbm */ -s32 power = sar->sub_specs[i].power >>1 ; - -if (power >127 || power <-127 ) - power =127 ; - - frp = &data[index]; - frp->range = &capa->freq_ranges[index]; - frp->power = power; - } + err =mt76_init_sar_power (hw, sar); +if (err) + goto out; err =mt76_connac_mcu_set_rate_txpower (mphy); - +out:mt7921_mutex_release (dev);return err;
Signature · 1 line
2.31.1
Lorenzo Bianconi
maintainerPATCH 2/2 mt76: mt76x02: introduce SAR support
In reply to Lorenzo BianconiAdd SAR spec support to mt76x02 driver to allow configuring SAR power limitations on the frequency ranges from the userland.
Signed-off-by Lorenzo Bianconi <[email protected]>
--- .../net/wireless/mediatek/mt76/mt76x0/init.c | 5 ++- .../net/wireless/mediatek/mt76/mt76x0/main.c | 34 +++++++++++++++++-- .../wireless/mediatek/mt76/mt76x0/mt76x0.h | 2 ++ .../net/wireless/mediatek/mt76/mt76x0/pci.c | 1 + .../net/wireless/mediatek/mt76/mt76x0/usb.c | 1 + drivers/net/wireless/mediatek/mt76/mt76x02.h | 2 +- .../net/wireless/mediatek/mt76/mt76x02_util.c | 11 +++++- .../net/wireless/mediatek/mt76/mt76x2/init.c | 29 ++++++++++++++++ .../wireless/mediatek/mt76/mt76x2/mt76x2.h | 2 ++ .../wireless/mediatek/mt76/mt76x2/pci_init.c | 5 +-- .../wireless/mediatek/mt76/mt76x2/pci_main.c | 7 +++- .../wireless/mediatek/mt76/mt76x2/usb_init.c | 4 ++- .../wireless/mediatek/mt76/mt76x2/usb_main.c | 9 +++-- 13 files changed, 101 insertions(+), 11 deletions(-)
drivers/net/wireless/mediatek/mt76/mt76x0/init.c +4 -1
@@ -237,7 +237,10 @@ int mt76x0_register_device(struct mt76x02_dev *dev) {int ret; -mt76x02_init_device (dev); + ret =mt76x02_init_device (dev); +if (ret) +return ret; +mt76x02_config_mac_addr_list (dev); ret = mt76_register_device(&dev->mt76, true, mt76x02_rates,
drivers/net/wireless/mediatek/mt76/mt76x0/main.c +32 -2
@@ -31,6 +31,32 @@ mt76x0_set_channel(struct mt76x02_dev *dev, struct cfg80211_chan_def *chandef)mt76_txq_schedule_all (&dev->mphy); } +int mt76x0_set_sar_specs (struct ieee80211_hw *hw, +const struct cfg80211_sar_specs *sar) +{ +int err = -EINVAL , power = hw->conf.power_level *2 ; +struct mt76x02_dev *dev = hw->priv; +struct mt76_phy *mphy = &dev->mphy; + +mutex_lock (&dev->mt76.mutex); +if (!cfg80211_chandef_valid (&mphy->chandef)) + goto out; + + err =mt76_init_sar_power (hw, sar); +if (err) + goto out; + + dev->txpower_conf =mt76_get_sar_power (mphy, mphy->chandef.chan, + power); +if (test_bit (MT76_STATE_RUNNING , &mphy->state)) +mt76x0_phy_set_txpower (dev); +out: +mutex_unlock (&dev->mt76.mutex); + +return err; +} +EXPORT_SYMBOL_GPL (mt76x0_set_sar_specs); +int mt76x0_config (struct ieee80211_hw *hw,u32 changed) {struct mt76x02_dev *dev = hw->priv;
@@ -44,9 +70,13 @@ int mt76x0_config(struct ieee80211_hw *hw, u32 changed) }if (changed &IEEE80211_CONF_CHANGE_POWER ) { - dev->txpower_conf = hw->conf.power_level *2 ; +struct mt76_phy *mphy = &dev->mphy; -if (test_bit (MT76_STATE_RUNNING , &dev->mphy.state)) + dev->txpower_conf = hw->conf.power_level *2 ; + dev->txpower_conf =mt76_get_sar_power (mphy, + mphy->chandef.chan, + dev->txpower_conf); +if (test_bit (MT76_STATE_RUNNING , &mphy->state))mt76x0_phy_set_txpower (dev); }
drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h +2 -0
@@ -49,6 +49,8 @@ void mt76x0_chip_onoff(struct mt76x02_dev *dev, bool enable, bool reset);void mt76x0_mac_stop (struct mt76x02_dev *dev);int mt76x0_config (struct ieee80211_hw *hw,u32 changed); +int mt76x0_set_sar_specs (struct ieee80211_hw *hw, +const struct cfg80211_sar_specs *sar);/* PHY */ void mt76x0_phy_init (struct mt76x02_dev *dev);
drivers/net/wireless/mediatek/mt76/mt76x0/pci.c +1 -0
@@ -85,6 +85,7 @@ static const struct ieee80211_ops mt76x0e_ops = { .set_rts_threshold = mt76x02_set_rts_threshold, .get_antenna = mt76_get_antenna, .reconfig_complete = mt76x02_reconfig_complete, + .set_sar_specs = mt76x0_set_sar_specs, };static int mt76x0e_init_hardware (struct mt76x02_dev *dev,bool resume)
drivers/net/wireless/mediatek/mt76/mt76x0/usb.c +1 -0
@@ -141,6 +141,7 @@ static const struct ieee80211_ops mt76x0u_ops = { .set_tim = mt76_set_tim, .release_buffered_frames = mt76_release_buffered_frames, .get_antenna = mt76_get_antenna, + .set_sar_specs = mt76x0_set_sar_specs, };static int mt76x0u_init_hardware (struct mt76x02_dev *dev,bool reset)
drivers/net/wireless/mediatek/mt76/mt76x02.h +1 -1
@@ -133,7 +133,7 @@ struct mt76x02_dev {extern struct ieee80211_rate mt76x02_rates[12 ]; -void mt76x02_init_device (struct mt76x02_dev *dev); +int mt76x02_init_device (struct mt76x02_dev *dev);void mt76x02_configure_filter (struct ieee80211_hw *hw,unsigned int changed_flags,unsigned int *total_flags,u64 multicast);
drivers/net/wireless/mediatek/mt76/mt76x02_util.c +10 -1
@@ -138,7 +138,7 @@ mt76x02_led_set_brightness(struct led_classdev *led_cdev,mt76x02_led_set_config (mdev,0xff ,0 ); } -void mt76x02_init_device (struct mt76x02_dev *dev) +int mt76x02_init_device (struct mt76x02_dev *dev) {struct ieee80211_hw *hw =mt76_hw (dev);struct wiphy *wiphy = hw->wiphy;
@@ -174,6 +174,13 @@ void mt76x02_init_device(struct mt76x02_dev *dev) }wiphy_ext_feature_set (wiphy,NL80211_EXT_FEATURE_VHT_IBSS ); + wiphy->sar_capa = &mt76_sar_capa; + dev->mt76.phy.frp =devm_kcalloc (dev->mt76.dev, + wiphy->sar_capa->num_freq_ranges, +sizeof (struct mt76_freq_range_power ), +GFP_KERNEL ); +if (!dev->mt76.phy.frp) +return -ENOMEM ; hw->sta_data_size =sizeof (struct mt76x02_sta ); hw->vif_data_size =sizeof (struct mt76x02_vif );
@@ -197,6 +204,8 @@ void mt76x02_init_device(struct mt76x02_dev *dev) dev->mphy.chainmask =0x101 ; dev->mphy.antenna_mask =1 ; } + +return 0 ; }EXPORT_SYMBOL_GPL (mt76x02_init_device);
drivers/net/wireless/mediatek/mt76/mt76x2/init.c +29 -0
@@ -8,6 +8,35 @@#include "eeprom.h" #include "../mt76x02_phy.h" +int mt76x2_set_sar_specs (struct ieee80211_hw *hw, +const struct cfg80211_sar_specs *sar) +{ +int err = -EINVAL , power = hw->conf.power_level *2 ; +struct mt76x02_dev *dev = hw->priv; +struct mt76_phy *mphy = &dev->mphy; + +mutex_lock (&dev->mt76.mutex); +if (!cfg80211_chandef_valid (&mphy->chandef)) + goto out; + + err =mt76_init_sar_power (hw, sar); +if (err) + goto out; + + dev->txpower_conf =mt76_get_sar_power (mphy, mphy->chandef.chan, + power); +/* convert to per-chain power for 2x2 devices */ + dev->txpower_conf -=6 ; + +if (test_bit (MT76_STATE_RUNNING , &mphy->state)) +mt76x2_phy_set_txpower (dev); +out: +mutex_unlock (&dev->mt76.mutex); + +return err; +} +EXPORT_SYMBOL_GPL (mt76x2_set_sar_specs); +static void mt76x2_set_wlan_state (struct mt76x02_dev *dev,bool enable) {
drivers/net/wireless/mediatek/mt76/mt76x2/mt76x2.h +2 -0
@@ -41,6 +41,8 @@ extern const struct ieee80211_ops mt76x2_ops;int mt76x2_register_device (struct mt76x02_dev *dev);int mt76x2_resume_device (struct mt76x02_dev *dev); +int mt76x2_set_sar_specs (struct ieee80211_hw *hw, +const struct cfg80211_sar_specs *sar);void mt76x2_phy_power_on (struct mt76x02_dev *dev);void mt76x2_stop_hardware (struct mt76x02_dev *dev);int mt76x2_eeprom_init (struct mt76x02_dev *dev);
drivers/net/wireless/mediatek/mt76/mt76x2/pci_init.c +3 -2
@@ -292,8 +292,9 @@ int mt76x2_register_device(struct mt76x02_dev *dev)int ret;INIT_DELAYED_WORK (&dev->cal_work, mt76x2_phy_calibrate); - -mt76x02_init_device (dev); + ret =mt76x02_init_device (dev); +if (ret) +return ret; ret =mt76x2_init_hardware (dev);if (ret)
drivers/net/wireless/mediatek/mt76/mt76x2/pci_main.c +6 -1
@@ -78,8 +78,12 @@ mt76x2_config(struct ieee80211_hw *hw, u32 changed) }if (changed &IEEE80211_CONF_CHANGE_POWER ) { - dev->txpower_conf = hw->conf.power_level *2 ; +struct mt76_phy *mphy = &dev->mphy; + dev->txpower_conf = hw->conf.power_level *2 ; + dev->txpower_conf =mt76_get_sar_power (mphy, + mphy->chandef.chan, + dev->txpower_conf);/* convert to per-chain power for 2x2 devices */ dev->txpower_conf -=6 ;
@@ -155,5 +159,6 @@ const struct ieee80211_ops mt76x2_ops = { .get_antenna = mt76_get_antenna, .set_rts_threshold = mt76x02_set_rts_threshold, .reconfig_complete = mt76x02_reconfig_complete, + .set_sar_specs = mt76x2_set_sar_specs, };
drivers/net/wireless/mediatek/mt76/mt76x2/usb_init.c +3 -1
@@ -194,7 +194,9 @@ int mt76x2u_register_device(struct mt76x02_dev *dev)int err;INIT_DELAYED_WORK (&dev->cal_work, mt76x2u_phy_calibrate); -mt76x02_init_device (dev); + err =mt76x02_init_device (dev); +if (err) +return err; err =mt76x2u_init_eeprom (dev);if (err <0 )
drivers/net/wireless/mediatek/mt76/mt76x2/usb_main.c +7 -2
@@ -78,12 +78,16 @@ mt76x2u_config(struct ieee80211_hw *hw, u32 changed) }if (changed &IEEE80211_CONF_CHANGE_POWER ) { - dev->txpower_conf = hw->conf.power_level *2 ; +struct mt76_phy *mphy = &dev->mphy; + dev->txpower_conf = hw->conf.power_level *2 ; + dev->txpower_conf =mt76_get_sar_power (mphy, + mphy->chandef.chan, + dev->txpower_conf);/* convert to per-chain power for 2x2 devices */ dev->txpower_conf -=6 ; -if (test_bit (MT76_STATE_RUNNING , &dev->mphy.state)) +if (test_bit (MT76_STATE_RUNNING , &mphy->state))mt76x2_phy_set_txpower (dev); }
@@ -121,4 +125,5 @@ const struct ieee80211_ops mt76x2u_ops = { .set_tim = mt76_set_tim, .release_buffered_frames = mt76_release_buffered_frames, .get_antenna = mt76_get_antenna, + .set_sar_specs = mt76x2_set_sar_specs, };
Signature · 1 line
2.31.1