mt76x2: initialize channel power limits at probe time
authorFelix Fietkau <nbd@nbd.name>
Thu, 14 Dec 2017 15:39:11 +0000 (16:39 +0100)
committerKalle Valo <kvalo@codeaurora.org>
Mon, 8 Jan 2018 17:25:50 +0000 (19:25 +0200)
This allows user space to query the real hardware limits directly

Signed-off-by: Felix Fietkau <nbd@nbd.name>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
drivers/net/wireless/mediatek/mt76/mt76x2_eeprom.c
drivers/net/wireless/mediatek/mt76/mt76x2_eeprom.h
drivers/net/wireless/mediatek/mt76/mt76x2_init.c
drivers/net/wireless/mediatek/mt76/mt76x2_phy.c

index 79bc163..99049e4 100644 (file)
@@ -483,6 +483,17 @@ void mt76x2_get_rate_power(struct mt76x2_dev *dev, struct mt76_rate_power *t,
        t->vht[8] = t->vht[9] = mt76x2_rate_power_val(val >> 8);
 }
 
+int mt76x2_get_max_rate_power(struct mt76_rate_power *r)
+{
+       int i;
+       s8 ret = 0;
+
+       for (i = 0; i < sizeof(r->all); i++)
+               ret = max(ret, r->all[i]);
+
+       return ret;
+}
+
 static void
 mt76x2_get_power_info_2g(struct mt76x2_dev *dev, struct mt76x2_tx_power_info *t,
                         struct ieee80211_channel *chan, int chain, int offset)
index 6db2c6e..d791227 100644 (file)
@@ -148,6 +148,7 @@ mt76x2_eeprom_get(struct mt76x2_dev *dev, enum mt76x2_eeprom_field field)
 
 void mt76x2_get_rate_power(struct mt76x2_dev *dev, struct mt76_rate_power *t,
                           struct ieee80211_channel *chan);
+int mt76x2_get_max_rate_power(struct mt76_rate_power *r);
 void mt76x2_get_power_info(struct mt76x2_dev *dev,
                           struct mt76x2_tx_power_info *t,
                           struct ieee80211_channel *chan);
index d3f03a8..0755b45 100644 (file)
@@ -760,6 +760,34 @@ static void mt76x2_led_set_brightness(struct led_classdev *led_cdev,
                mt76x2_led_set_config(mt76, 0xff, 0);
 }
 
+static void
+mt76x2_init_txpower(struct mt76x2_dev *dev,
+                   struct ieee80211_supported_band *sband)
+{
+       struct ieee80211_channel *chan;
+       struct mt76x2_tx_power_info txp;
+       struct mt76_rate_power t = {};
+       int target_power;
+       int i;
+
+       for (i = 0; i < sband->n_channels; i++) {
+               chan = &sband->channels[i];
+
+               mt76x2_get_power_info(dev, &txp, chan);
+
+               target_power = max_t(int, (txp.chain[0].target_power +
+                                          txp.chain[0].delta),
+                                         (txp.chain[1].target_power +
+                                          txp.chain[1].delta));
+
+               mt76x2_get_rate_power(dev, &t, chan);
+
+               chan->max_power = mt76x2_get_max_rate_power(&t) +
+                                 target_power;
+               chan->max_power /= 2;
+       }
+}
+
 int mt76x2_register_device(struct mt76x2_dev *dev)
 {
        struct ieee80211_hw *hw = mt76_hw(dev);
@@ -828,6 +856,8 @@ int mt76x2_register_device(struct mt76x2_dev *dev)
                goto fail;
 
        mt76x2_init_debugfs(dev);
+       mt76x2_init_txpower(dev, &dev->mt76.sband_2g.sband);
+       mt76x2_init_txpower(dev, &dev->mt76.sband_5g.sband);
 
        return 0;
 
index 81cea7e..5b74274 100644 (file)
@@ -102,18 +102,6 @@ mt76x2_limit_rate_power(struct mt76_rate_power *r, int limit)
                        r->all[i] = limit;
 }
 
-static int
-mt76x2_get_max_power(struct mt76_rate_power *r)
-{
-       int i;
-       s8 ret = 0;
-
-       for (i = 0; i < sizeof(r->all); i++)
-               ret = max(ret, r->all[i]);
-
-       return ret;
-}
-
 void mt76x2_phy_set_txpower(struct mt76x2_dev *dev)
 {
        enum nl80211_chan_width width = dev->mt76.chandef.width;
@@ -136,7 +124,7 @@ void mt76x2_phy_set_txpower(struct mt76x2_dev *dev)
        mt76x2_add_rate_power_offset(&t, txp.chain[0].target_power +
                                   txp.chain[0].delta);
        mt76x2_limit_rate_power(&t, dev->txpower_conf);
-       dev->txpower_cur = mt76x2_get_max_power(&t);
+       dev->txpower_cur = mt76x2_get_max_rate_power(&t);
        mt76x2_add_rate_power_offset(&t, -(txp.chain[0].target_power +
                                         txp.chain[0].delta + delta));
        dev->target_power = txp.chain[0].target_power;