mt7603: add rudimentary tx status parsing (no rates yet)

Signed-off-by: Felix Fietkau <[email protected]>
This commit is contained in:
Felix Fietkau
2016-01-31 21:32:41 +01:00
parent 86d31f6fff
commit bd4ce1d6f4
3 changed files with 78 additions and 3 deletions
+4 -1
View File
@@ -57,6 +57,8 @@ struct mt7603_vif {
struct mt7603_sta {
struct mt76_wcid wcid; /* must be first */
int ampdu_count;
int ampdu_acked;
};
struct mt7603_dev {
@@ -72,6 +74,7 @@ struct mt7603_dev {
u8 vif_mask;
unsigned long wcid_mask[MT7603_WTBL_SIZE / BITS_PER_LONG];
struct mt76_wcid __rcu *wcid[MT7603_WTBL_SIZE];
u8 rx_chains;
u8 tx_chains;
@@ -121,6 +124,7 @@ static inline void mt7603_irq_disable(struct mt7603_dev *dev, u32 mask)
void mt7603_mac_start(struct mt7603_dev *dev);
void mt7603_mac_stop(struct mt7603_dev *dev);
int mt7603_mac_fill_rx(struct mt7603_dev *dev, struct sk_buff *skb);
void mt7603_mac_add_txs(struct mt7603_dev *dev, void *data);
int mt7603_set_channel(struct mt7603_dev *dev, struct cfg80211_chan_def *def);
int mt7603_mcu_set_channel(struct mt7603_dev *dev);
@@ -134,5 +138,4 @@ void mt7603_wtbl_clear(struct mt7603_dev *dev, int idx);
int mt7603_mac_write_txwi(struct mt76_dev *mdev, void *txwi_ptr,
struct sk_buff *skb, struct mt76_wcid *wcid,
struct ieee80211_sta *sta);
#endif
+5
View File
@@ -104,6 +104,10 @@ mt7603_process_rx_skb(struct mt7603_dev *dev, struct mt76_queue *q,
type = MT76_GET(MT_RXD0_PKT_TYPE, le32_to_cpu(rxd[0]));
switch(type) {
case PKT_TYPE_TXS:
mt7603_mac_add_txs(dev, &rxd[1]);
dev_kfree_skb(skb);
break;
case PKT_TYPE_RX_EVENT:
skb_queue_tail(&dev->mcu.res_q, skb);
wake_up(&dev->mcu.wait);
@@ -116,6 +120,7 @@ mt7603_process_rx_skb(struct mt7603_dev *dev, struct mt76_queue *q,
/* fall through */
default:
dev_kfree_skb(skb);
break;
}
}
+69 -2
View File
@@ -282,6 +282,7 @@ int mt7603_mac_write_txwi(struct mt76_dev *mdev, void *txwi_ptr,
int hdr_len = ieee80211_get_hdrlen_from_skb(skb);
u8 frame_type, frame_subtype;
u8 nss, bw;
u8 pid = 0;
if (wcid)
wlan_idx = wcid->idx;
@@ -307,8 +308,10 @@ int mt7603_mac_write_txwi(struct mt76_dev *mdev, void *txwi_ptr,
MT76_SET(MT_TXD1_WLAN_IDX, wlan_idx)
);
if (info->flags & IEEE80211_TX_CTL_NO_ACK)
if (info->flags & IEEE80211_TX_CTL_NO_ACK) {
txwi[1] |= cpu_to_le32(MT_TXD1_NO_ACK);
pid |= BIT(7);
}
txwi[2] = cpu_to_le32(
MT76_SET(MT_TXD2_FRAME_TYPE, frame_type) |
@@ -320,7 +323,10 @@ int mt7603_mac_write_txwi(struct mt76_dev *mdev, void *txwi_ptr,
txwi[3] = cpu_to_le32(MT76_SET(MT_TXD3_REM_TX_COUNT, 0xf));
txwi[4] = 0;
txwi[5] = cpu_to_le32(MT_TXD5_TX_STATUS_HOST | MT_TXD5_SW_POWER_MGMT);
txwi[5] = cpu_to_le32(
MT_TXD5_TX_STATUS_HOST | MT_TXD5_SW_POWER_MGMT |
MT76_SET(MT_TXD5_PID, pid)
);
txwi[6] = 0;
spin_lock_bh(&dev->mt76.lock);
@@ -350,6 +356,67 @@ int mt7603_mac_write_txwi(struct mt76_dev *mdev, void *txwi_ptr,
return 0;
}
void mt7603_mac_add_txs(struct mt7603_dev *dev, void *data)
{
struct ieee80211_tx_info info = {};
struct ieee80211_sta *sta = NULL;
struct mt7603_sta *msta = NULL;
struct mt76_wcid *wcid;
__le32 *txs_data = data;
void *priv;
bool final_mpdu;
bool ampdu;
u32 txs;
u8 wcidx;
u8 pid;
txs = le32_to_cpu(txs_data[4]);
pid = MT76_GET(MT_TXS4_PID, txs);
if (pid & BIT(7)) /* No-ACK */
return;
final_mpdu = txs & MT_TXS4_ACKED_MPDU;
ampdu = txs & MT_TXS4_AMPDU;
txs = le32_to_cpu(txs_data[3]);
wcidx = MT76_GET(MT_TXS3_WCID, txs);
if (wcidx >= ARRAY_SIZE(dev->wcid))
return;
rcu_read_lock();
wcid = rcu_dereference(dev->wcid[wcidx]);
if (!wcid)
goto out;
priv = msta = container_of(wcid, struct mt7603_sta, wcid);
sta = container_of(priv, struct ieee80211_sta, drv_priv);
txs = le32_to_cpu(txs_data[0]);
if (!(txs & MT_TXS0_ACK_ERROR_MASK)) {
msta->ampdu_acked++;
info.flags |= IEEE80211_TX_STAT_ACK;
}
msta->ampdu_count++;
if (ampdu) {
if (!final_mpdu)
return;
info.flags |= IEEE80211_TX_CTL_AMPDU | IEEE80211_TX_STAT_AMPDU;
info.status.ampdu_len = msta->ampdu_count;
info.status.ampdu_ack_len = msta->ampdu_acked;
}
ieee80211_tx_status_noskb(mt76_hw(dev), sta, &info);
msta->ampdu_count = 0;
msta->ampdu_acked = 0;
out:
rcu_read_unlock();
}
void mt7603_mac_start(struct mt7603_dev *dev)
{
mt76_clear(dev, MT_WF_ARB_SCR, MT_WF_ARB_TX_DISABLE | MT_WF_ARB_RX_DISABLE);