mt76x2: track rssi for gain adjustment per station

This preserves more sensitivity when weak stations are active

Signed-off-by: Felix Fietkau <[email protected]>
This commit is contained in:
Felix Fietkau
2018-06-19 11:15:19 +02:00
parent f450659334
commit 1d4ca10a56
5 changed files with 76 additions and 24 deletions
+3 -3
View File
@@ -69,9 +69,6 @@ struct mt76x2_rx_freq_cal {
struct mt76x2_calibration {
struct mt76x2_rx_freq_cal rx;
struct ewma_signal rssi;
u32 rssi_count;
u8 agc_gain_init[MT_MAX_CHAINS];
u8 agc_gain_cur[MT_MAX_CHAINS];
@@ -157,6 +154,9 @@ struct mt76x2_sta {
struct mt76x2_vif *vif;
struct mt76x2_tx_status status;
int n_frames;
struct ewma_signal rssi;
int inactive_count;
};
static inline bool is_mt7612(struct mt76x2_dev *dev)
-1
View File
@@ -657,7 +657,6 @@ struct mt76x2_dev *mt76x2_alloc_device(struct device *pdev)
mdev->drv = &drv_ops;
mutex_init(&dev->mutex);
spin_lock_init(&dev->irq_lock);
ewma_signal_init(&dev->cal.rssi);
return dev;
}
+23 -11
View File
@@ -282,21 +282,31 @@ static void mt76x2_remove_hdr_pad(struct sk_buff *skb, int len)
skb_pull(skb, len);
}
static struct mt76_wcid *
mt76x2_rx_get_sta_wcid(struct mt76x2_dev *dev, u8 idx, bool unicast)
static struct mt76x2_sta *
mt76x2_rx_get_sta(struct mt76x2_dev *dev, u8 idx)
{
struct mt76x2_sta *sta;
struct mt76_wcid *wcid;
if (idx >= ARRAY_SIZE(dev->wcid))
return NULL;
wcid = rcu_dereference(dev->wcid[idx]);
if (unicast || !wcid)
return wcid;
if (!wcid)
return NULL;
sta = container_of(wcid, struct mt76x2_sta, wcid);
return &sta->vif->group_wcid;
return container_of(wcid, struct mt76x2_sta, wcid);
}
static struct mt76_wcid *
mt76x2_rx_get_sta_wcid(struct mt76x2_dev *dev, struct mt76x2_sta *sta, bool unicast)
{
if (!sta)
return NULL;
if (unicast)
return &sta->wcid;
else
return &sta->vif->group_wcid;
}
int mt76x2_mac_process_rx(struct mt76x2_dev *dev, struct sk_buff *skb,
@@ -304,6 +314,7 @@ int mt76x2_mac_process_rx(struct mt76x2_dev *dev, struct sk_buff *skb,
{
struct mt76_rx_status *status = (struct mt76_rx_status *) skb->cb;
struct mt76x2_rxwi *rxwi = rxi;
struct mt76x2_sta *sta;
u32 rxinfo = le32_to_cpu(rxwi->rxinfo);
u32 ctl = le32_to_cpu(rxwi->ctl);
u16 rate = le16_to_cpu(rxwi->rate);
@@ -328,7 +339,8 @@ int mt76x2_mac_process_rx(struct mt76x2_dev *dev, struct sk_buff *skb,
}
wcid = FIELD_GET(MT_RXWI_CTL_WCID, ctl);
status->wcid = mt76x2_rx_get_sta_wcid(dev, wcid, unicast);
sta = mt76x2_rx_get_sta(dev, wcid);
status->wcid = mt76x2_rx_get_sta_wcid(dev, sta, unicast);
len = FIELD_GET(MT_RXWI_CTL_MPDU_LEN, ctl);
pn_len = FIELD_GET(MT_RXINFO_PN_LEN, rxinfo);
@@ -374,9 +386,9 @@ int mt76x2_mac_process_rx(struct mt76x2_dev *dev, struct sk_buff *skb,
status->tid = FIELD_GET(MT_RXWI_TID, tid_sn);
status->seqno = FIELD_GET(MT_RXWI_SN, tid_sn);
if (status->wcid) {
ewma_signal_add(&dev->cal.rssi, status->signal);
dev->cal.rssi_count++;
if (sta) {
ewma_signal_add(&sta->rssi, status->signal);
sta->inactive_count = 0;
}
return mt76x2_mac_process_rate(status, rate);
+2
View File
@@ -294,6 +294,8 @@ mt76x2_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
if (vif->type == NL80211_IFTYPE_AP)
set_bit(MT_WCID_FLAG_CHECK_PS, &msta->wcid.flags);
ewma_signal_init(&msta->rssi);
rcu_assign_pointer(dev->wcid[idx], &msta->wcid);
out:
+48 -9
View File
@@ -500,6 +500,53 @@ mt76x2_phy_adjust_vga_gain(struct mt76x2_dev *dev)
mt76x2_phy_set_gain_val(dev);
}
static int
mt76x2_phy_get_min_avg_rssi(struct mt76x2_dev *dev)
{
struct mt76x2_sta *sta;
struct mt76_wcid *wcid;
int i, j, min_rssi = 0;
s8 cur_rssi;
local_bh_disable();
rcu_read_lock();
for (i = 0; i < ARRAY_SIZE(dev->wcid_mask); i++) {
unsigned long mask = dev->wcid_mask[i];
if (!mask)
continue;
for (j = i * BITS_PER_LONG; mask; j++, mask >>= 1) {
if (!(mask & 1))
continue;
wcid = rcu_dereference(dev->wcid[j]);
if (!wcid)
continue;
sta = container_of(wcid, struct mt76x2_sta, wcid);
spin_lock(&dev->mt76.rx_lock);
if (sta->inactive_count++ < 5)
cur_rssi = ewma_signal_read(&sta->rssi);
else
cur_rssi = 0;
spin_unlock(&dev->mt76.rx_lock);
if (cur_rssi < min_rssi)
min_rssi = cur_rssi;
}
}
rcu_read_unlock();
local_bh_enable();
if (!min_rssi)
return -75;
return min_rssi;
}
static void
mt76x2_phy_update_channel_gain(struct mt76x2_dev *dev)
{
@@ -507,17 +554,9 @@ mt76x2_phy_update_channel_gain(struct mt76x2_dev *dev)
u8 low_gain_delta, gain_delta;
bool gain_change;
int low_gain;
u32 rssi_count;
u32 val;
spin_lock_bh(&dev->mt76.rx_lock);
dev->cal.avg_rssi_all = ewma_signal_read(&dev->cal.rssi);
rssi_count = dev->cal.rssi_count;
dev->cal.rssi_count = 0;
spin_unlock_bh(&dev->mt76.rx_lock);
if (!rssi_count)
dev->cal.avg_rssi_all = -75;
dev->cal.avg_rssi_all = mt76x2_phy_get_min_avg_rssi(dev);
low_gain = (dev->cal.avg_rssi_all > mt76x2_get_rssi_gain_thresh(dev)) +
(dev->cal.avg_rssi_all > mt76x2_get_low_rssi_gain_thresh(dev));