mt76: move mt76x02_mac_process_rx in mt76x02-lib module
Move mt76x02_mac_process_rx utility routine in mt76x02-lib in order to by reused by mt76x0 driver for rxwi parsing. Add stream number check in mt76x02_mac_process_rx since mt76x0 chipsets are 1x1:1 Signed-off-by: Lorenzo Bianconi <lorenzo.bianconi@redhat.com> Signed-off-by: Felix Fietkau <nbd@nbd.name>
This commit is contained in:
parent
b2d871c049
commit
d9f8934ed1
@ -582,3 +582,108 @@ void mt76x02_mac_setaddr(struct mt76_dev *dev, u8 *addr)
|
||||
FIELD_PREP(MT_MAC_ADDR_DW1_U2ME_MASK, 0xff));
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(mt76x02_mac_setaddr);
|
||||
|
||||
static int
|
||||
mt76x02_mac_get_rssi(struct mt76x02_dev *dev, s8 rssi, int chain)
|
||||
{
|
||||
struct mt76x02_rx_freq_cal *cal = &dev->cal.rx;
|
||||
|
||||
rssi += cal->rssi_offset[chain];
|
||||
rssi -= cal->lna_gain;
|
||||
|
||||
return rssi;
|
||||
}
|
||||
|
||||
int mt76x02_mac_process_rx(struct mt76x02_dev *dev, struct sk_buff *skb,
|
||||
void *rxi)
|
||||
{
|
||||
struct mt76_rx_status *status = (struct mt76_rx_status *) skb->cb;
|
||||
struct mt76x02_rxwi *rxwi = rxi;
|
||||
struct mt76x02_sta *sta;
|
||||
u32 rxinfo = le32_to_cpu(rxwi->rxinfo);
|
||||
u32 ctl = le32_to_cpu(rxwi->ctl);
|
||||
u16 rate = le16_to_cpu(rxwi->rate);
|
||||
u16 tid_sn = le16_to_cpu(rxwi->tid_sn);
|
||||
bool unicast = rxwi->rxinfo & cpu_to_le32(MT_RXINFO_UNICAST);
|
||||
int i, pad_len = 0, nstreams = dev->mt76.chainmask & 0xf;
|
||||
s8 signal;
|
||||
u8 pn_len;
|
||||
u8 wcid;
|
||||
int len;
|
||||
|
||||
if (!test_bit(MT76_STATE_RUNNING, &dev->mt76.state))
|
||||
return -EINVAL;
|
||||
|
||||
if (rxinfo & MT_RXINFO_L2PAD)
|
||||
pad_len += 2;
|
||||
|
||||
if (rxinfo & MT_RXINFO_DECRYPT) {
|
||||
status->flag |= RX_FLAG_DECRYPTED;
|
||||
status->flag |= RX_FLAG_MMIC_STRIPPED;
|
||||
status->flag |= RX_FLAG_MIC_STRIPPED;
|
||||
status->flag |= RX_FLAG_IV_STRIPPED;
|
||||
}
|
||||
|
||||
wcid = FIELD_GET(MT_RXWI_CTL_WCID, ctl);
|
||||
sta = mt76x02_rx_get_sta(&dev->mt76, wcid);
|
||||
status->wcid = mt76x02_rx_get_sta_wcid(sta, unicast);
|
||||
|
||||
len = FIELD_GET(MT_RXWI_CTL_MPDU_LEN, ctl);
|
||||
pn_len = FIELD_GET(MT_RXINFO_PN_LEN, rxinfo);
|
||||
if (pn_len) {
|
||||
int offset = ieee80211_get_hdrlen_from_skb(skb) + pad_len;
|
||||
u8 *data = skb->data + offset;
|
||||
|
||||
status->iv[0] = data[7];
|
||||
status->iv[1] = data[6];
|
||||
status->iv[2] = data[5];
|
||||
status->iv[3] = data[4];
|
||||
status->iv[4] = data[1];
|
||||
status->iv[5] = data[0];
|
||||
|
||||
/*
|
||||
* Driver CCMP validation can't deal with fragments.
|
||||
* Let mac80211 take care of it.
|
||||
*/
|
||||
if (rxinfo & MT_RXINFO_FRAG) {
|
||||
status->flag &= ~RX_FLAG_IV_STRIPPED;
|
||||
} else {
|
||||
pad_len += pn_len << 2;
|
||||
len -= pn_len << 2;
|
||||
}
|
||||
}
|
||||
|
||||
mt76x02_remove_hdr_pad(skb, pad_len);
|
||||
|
||||
if ((rxinfo & MT_RXINFO_BA) && !(rxinfo & MT_RXINFO_NULL))
|
||||
status->aggr = true;
|
||||
|
||||
if (WARN_ON_ONCE(len > skb->len))
|
||||
return -EINVAL;
|
||||
|
||||
pskb_trim(skb, len);
|
||||
|
||||
status->chains = BIT(0);
|
||||
signal = mt76x02_mac_get_rssi(dev, rxwi->rssi[0], 0);
|
||||
for (i = 1; i < nstreams; i++) {
|
||||
status->chains |= BIT(i);
|
||||
status->chain_signal[i] = mt76x02_mac_get_rssi(dev,
|
||||
rxwi->rssi[i],
|
||||
i);
|
||||
signal = max_t(s8, signal, status->chain_signal[i]);
|
||||
}
|
||||
status->signal = signal;
|
||||
status->freq = dev->mt76.chandef.chan->center_freq;
|
||||
status->band = dev->mt76.chandef.chan->band;
|
||||
|
||||
status->tid = FIELD_GET(MT_RXWI_TID, tid_sn);
|
||||
status->seqno = FIELD_GET(MT_RXWI_SN, tid_sn);
|
||||
|
||||
if (sta) {
|
||||
ewma_signal_add(&sta->rssi, status->signal);
|
||||
sta->inactive_count = 0;
|
||||
}
|
||||
|
||||
return mt76x02_mac_process_rate(status, rate);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(mt76x02_mac_process_rx);
|
||||
|
@ -20,6 +20,8 @@
|
||||
|
||||
#include <linux/average.h>
|
||||
|
||||
struct mt76x02_dev;
|
||||
|
||||
struct mt76x02_tx_status {
|
||||
u8 valid:1;
|
||||
u8 success:1;
|
||||
@ -195,6 +197,8 @@ bool mt76x02_mac_load_tx_status(struct mt76_dev *dev,
|
||||
struct mt76x02_tx_status *stat);
|
||||
void mt76x02_send_tx_status(struct mt76_dev *dev,
|
||||
struct mt76x02_tx_status *stat, u8 *update);
|
||||
int mt76x02_mac_process_rx(struct mt76x02_dev *dev, struct sk_buff *skb,
|
||||
void *rxi);
|
||||
int
|
||||
mt76x02_mac_process_rate(struct mt76_rx_status *status, u16 rate);
|
||||
void mt76x02_mac_setaddr(struct mt76_dev *dev, u8 *addr);
|
||||
|
@ -32,7 +32,7 @@ void mt76x2_queue_rx_skb(struct mt76_dev *mdev, enum mt76_rxq_id q,
|
||||
}
|
||||
|
||||
skb_pull(skb, sizeof(struct mt76x02_rxwi));
|
||||
if (mt76x2_mac_process_rx(dev, skb, rxwi)) {
|
||||
if (mt76x02_mac_process_rx(dev, skb, rxwi)) {
|
||||
dev_kfree_skb(skb);
|
||||
return;
|
||||
}
|
||||
|
@ -53,99 +53,3 @@ void mt76x2_mac_stop(struct mt76x02_dev *dev, bool force)
|
||||
mt76_wr(dev, MT_TX_RTS_CFG, rts_cfg);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(mt76x2_mac_stop);
|
||||
|
||||
int mt76x2_mac_get_rssi(struct mt76x02_dev *dev, s8 rssi, int chain)
|
||||
{
|
||||
struct mt76x02_rx_freq_cal *cal = &dev->cal.rx;
|
||||
|
||||
rssi += cal->rssi_offset[chain];
|
||||
rssi -= cal->lna_gain;
|
||||
|
||||
return rssi;
|
||||
}
|
||||
|
||||
int mt76x2_mac_process_rx(struct mt76x02_dev *dev, struct sk_buff *skb,
|
||||
void *rxi)
|
||||
{
|
||||
struct mt76_rx_status *status = (struct mt76_rx_status *) skb->cb;
|
||||
struct mt76x02_rxwi *rxwi = rxi;
|
||||
struct mt76x02_sta *sta;
|
||||
u32 rxinfo = le32_to_cpu(rxwi->rxinfo);
|
||||
u32 ctl = le32_to_cpu(rxwi->ctl);
|
||||
u16 rate = le16_to_cpu(rxwi->rate);
|
||||
u16 tid_sn = le16_to_cpu(rxwi->tid_sn);
|
||||
bool unicast = rxwi->rxinfo & cpu_to_le32(MT_RXINFO_UNICAST);
|
||||
int pad_len = 0;
|
||||
u8 pn_len;
|
||||
u8 wcid;
|
||||
int len;
|
||||
|
||||
if (!test_bit(MT76_STATE_RUNNING, &dev->mt76.state))
|
||||
return -EINVAL;
|
||||
|
||||
if (rxinfo & MT_RXINFO_L2PAD)
|
||||
pad_len += 2;
|
||||
|
||||
if (rxinfo & MT_RXINFO_DECRYPT) {
|
||||
status->flag |= RX_FLAG_DECRYPTED;
|
||||
status->flag |= RX_FLAG_MMIC_STRIPPED;
|
||||
status->flag |= RX_FLAG_MIC_STRIPPED;
|
||||
status->flag |= RX_FLAG_IV_STRIPPED;
|
||||
}
|
||||
|
||||
wcid = FIELD_GET(MT_RXWI_CTL_WCID, ctl);
|
||||
sta = mt76x02_rx_get_sta(&dev->mt76, wcid);
|
||||
status->wcid = mt76x02_rx_get_sta_wcid(sta, unicast);
|
||||
|
||||
len = FIELD_GET(MT_RXWI_CTL_MPDU_LEN, ctl);
|
||||
pn_len = FIELD_GET(MT_RXINFO_PN_LEN, rxinfo);
|
||||
if (pn_len) {
|
||||
int offset = ieee80211_get_hdrlen_from_skb(skb) + pad_len;
|
||||
u8 *data = skb->data + offset;
|
||||
|
||||
status->iv[0] = data[7];
|
||||
status->iv[1] = data[6];
|
||||
status->iv[2] = data[5];
|
||||
status->iv[3] = data[4];
|
||||
status->iv[4] = data[1];
|
||||
status->iv[5] = data[0];
|
||||
|
||||
/*
|
||||
* Driver CCMP validation can't deal with fragments.
|
||||
* Let mac80211 take care of it.
|
||||
*/
|
||||
if (rxinfo & MT_RXINFO_FRAG) {
|
||||
status->flag &= ~RX_FLAG_IV_STRIPPED;
|
||||
} else {
|
||||
pad_len += pn_len << 2;
|
||||
len -= pn_len << 2;
|
||||
}
|
||||
}
|
||||
|
||||
mt76x02_remove_hdr_pad(skb, pad_len);
|
||||
|
||||
if ((rxinfo & MT_RXINFO_BA) && !(rxinfo & MT_RXINFO_NULL))
|
||||
status->aggr = true;
|
||||
|
||||
if (WARN_ON_ONCE(len > skb->len))
|
||||
return -EINVAL;
|
||||
|
||||
pskb_trim(skb, len);
|
||||
status->chains = BIT(0) | BIT(1);
|
||||
status->chain_signal[0] = mt76x2_mac_get_rssi(dev, rxwi->rssi[0], 0);
|
||||
status->chain_signal[1] = mt76x2_mac_get_rssi(dev, rxwi->rssi[1], 1);
|
||||
status->signal = max(status->chain_signal[0], status->chain_signal[1]);
|
||||
status->freq = dev->mt76.chandef.chan->center_freq;
|
||||
status->band = dev->mt76.chandef.chan->band;
|
||||
|
||||
status->tid = FIELD_GET(MT_RXWI_TID, tid_sn);
|
||||
status->seqno = FIELD_GET(MT_RXWI_SN, tid_sn);
|
||||
|
||||
if (sta) {
|
||||
ewma_signal_add(&sta->rssi, status->signal);
|
||||
sta->inactive_count = 0;
|
||||
}
|
||||
|
||||
return mt76x02_mac_process_rate(status, rate);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(mt76x2_mac_process_rx);
|
||||
|
@ -46,9 +46,6 @@ void mt76x2_mac_stop(struct mt76x02_dev *dev, bool force);
|
||||
void mt76x2_mac_resume(struct mt76x02_dev *dev);
|
||||
void mt76x2_mac_set_bssid(struct mt76x02_dev *dev, u8 idx, const u8 *addr);
|
||||
|
||||
int mt76x2_mac_process_rx(struct mt76x02_dev *dev, struct sk_buff *skb,
|
||||
void *rxi);
|
||||
|
||||
int mt76x2_mac_set_beacon(struct mt76x02_dev *dev, u8 vif_idx,
|
||||
struct sk_buff *skb);
|
||||
void mt76x2_mac_set_beacon_enable(struct mt76x02_dev *dev, u8 vif_idx, bool val);
|
||||
|
@ -74,7 +74,6 @@ void mt76x2_phy_set_antenna(struct mt76x02_dev *dev);
|
||||
int mt76x2_phy_start(struct mt76x02_dev *dev);
|
||||
int mt76x2_phy_set_channel(struct mt76x02_dev *dev,
|
||||
struct cfg80211_chan_def *chandef);
|
||||
int mt76x2_mac_get_rssi(struct mt76x02_dev *dev, s8 rssi, int chain);
|
||||
void mt76x2_phy_calibrate(struct work_struct *work);
|
||||
void mt76x2_phy_set_txpower(struct mt76x02_dev *dev);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user