mt7603: use a skb queue for status queueing

Signed-off-by: Felix Fietkau <[email protected]>
This commit is contained in:
Felix Fietkau
2016-03-03 21:40:11 +01:00
parent 0048598580
commit fc412aab0d
3 changed files with 21 additions and 35 deletions
+5 -17
View File
@@ -85,7 +85,6 @@ struct mt7603_vif {
#define MT7603_CB_TXS_FAILED BIT(2)
struct mt7603_cb {
struct list_head list;
u8 wcid;
u8 pktid;
u8 flags;
@@ -107,7 +106,7 @@ struct mt7603_dev {
struct mt76_wcid __rcu *wcid[MT7603_WTBL_SIZE];
spinlock_t status_lock;
struct list_head status_list;
struct sk_buff_head status_list;
struct mt7603_sta global_sta;
@@ -159,24 +158,13 @@ static inline bool is_mt7628(struct mt7603_dev *dev)
static inline struct mt7603_cb *mt7603_skb_cb(struct sk_buff *skb)
{
return ((void *) IEEE80211_SKB_CB(skb)->rate_driver_data) +
MT_RATE_DRIVER_DATA_OFFSET;
}
static inline struct sk_buff *mt7603_cb_skb(struct mt7603_cb *cb)
{
struct ieee80211_tx_info *info;
void *ptr = cb;
BUILD_BUG_ON(offsetof(struct ieee80211_tx_info, status.ampdu_len) >=
(offsetof(struct ieee80211_tx_info, rate_driver_data) +
MT_RATE_DRIVER_DATA_OFFSET));
BUILD_BUG_ON(sizeof(*cb) + MT_RATE_DRIVER_DATA_OFFSET >
sizeof(info->rate_driver_data));
info = container_of(ptr - MT_RATE_DRIVER_DATA_OFFSET,
struct ieee80211_tx_info, rate_driver_data);
ptr = info;
return container_of(ptr, struct sk_buff, cb);
BUILD_BUG_ON(sizeof(struct mt7603_cb) + MT_RATE_DRIVER_DATA_OFFSET >
IEEE80211_TX_INFO_RATE_DRIVER_DATA_SIZE);
return ((void *) IEEE80211_SKB_CB(skb)->rate_driver_data) +
MT_RATE_DRIVER_DATA_OFFSET;
}
u32 mt7603_reg_map(struct mt7603_dev *dev, u32 addr);
+1 -1
View File
@@ -342,7 +342,7 @@ int mt7603_register_device(struct mt7603_dev *dev)
mutex_init(&dev->mutex);
spin_lock_init(&dev->status_lock);
INIT_LIST_HEAD(&dev->status_list);
__skb_queue_head_init(&dev->status_list);
INIT_DELAYED_WORK(&dev->mac_work, mt7603_mac_work);
tasklet_init(&dev->pre_tbtt_tasklet, mt7603_pre_tbtt_tasklet, (unsigned long) dev);
+15 -17
View File
@@ -703,11 +703,12 @@ int mt7603_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
pid = msta->pid;
cb->wcid = wcid->idx;
cb->pktid = pid;
list_add_tail(&cb->list, &dev->status_list);
__skb_queue_tail(&dev->status_list, skb);
spin_unlock_bh(&dev->status_lock);
} else {
INIT_LIST_HEAD(&cb->list);
skb->next = skb->prev = NULL;
}
mt7603_mac_write_txwi(dev, txwi_ptr, skb, q, wcid, sta, pid, key);
@@ -793,25 +794,22 @@ mt7603_skb_done(struct mt7603_dev *dev, struct sk_buff *skb, u8 flags)
struct sk_buff *
mt7603_mac_status_skb(struct mt7603_dev *dev, struct mt7603_sta *sta, int pktid)
{
struct mt7603_cb *cb, *tmp;
struct sk_buff *skb = NULL;
struct sk_buff *skb, *tmp;
list_for_each_entry_safe(cb, tmp, &dev->status_list, list) {
skb_queue_walk_safe(&dev->status_list, skb, tmp) {
struct mt7603_cb *cb = mt7603_skb_cb(skb);
if (sta && cb->wcid != sta->wcid.idx)
continue;
list_del_init(&cb->list);
skb = mt7603_cb_skb(cb);
__skb_unlink(skb, &dev->status_list);
if (cb->pktid == pktid)
break;
return skb;
mt7603_skb_done(dev, skb,
MT7603_CB_TXS_FAILED | MT7603_CB_TXS_DONE);
skb = NULL;
}
return skb;
return NULL;
}
static bool
@@ -886,28 +884,28 @@ void mt7603_tx_complete_skb(struct mt76_dev *mdev, struct mt76_queue *q,
struct mt76_queue_entry *e, bool flush)
{
struct mt7603_dev *dev = container_of(mdev, struct mt7603_dev, mt76);
struct mt7603_cb *cb = mt7603_skb_cb(e->skb);
struct sk_buff *skb = e->skb;
bool free = true;
if (!e->txwi) {
dev_kfree_skb_any(e->skb);
dev_kfree_skb_any(skb);
return;
}
/* will be freed by tx status handling codepath */
if (!list_empty(&cb->list)) {
if (skb->prev) {
spin_lock_bh(&dev->status_lock);
if (!flush) {
mt7603_skb_done(dev, e->skb, MT7603_CB_DMA_DONE);
mt7603_skb_done(dev, skb, MT7603_CB_DMA_DONE);
free = false;
} else {
list_del_init(&cb->list);
__skb_unlink(skb, &dev->status_list);
}
spin_unlock_bh(&dev->status_lock);
}
if (free)
ieee80211_free_txskb(mdev->hw, e->skb);
ieee80211_free_txskb(mdev->hw, skb);
}
static bool