2019-04-02 09:48:09

by Lorenzo Bianconi

[permalink] [raw]
Subject: [PATCH v2 0/4] add missing bits for mt7615 support

This is a preliminary series to add support for mt7615.
Dynamically allocate txwi descriptor.
Add missing bit in dma error data path.
This series is based on https://patchwork.kernel.org/patch/10856027/

Changes since v1:
- remove flags from mt76_txwi_cache

Lorenzo Bianconi (4):
mt76: set txwi_size according to the driver value
mt76: add skb pointer to mt76_tx_info
mt76: dma: introduce skb field in mt76_txwi_cache
mt76: dma: add skb check for dummy pointer

drivers/net/wireless/mediatek/mt76/dma.c | 29 +++++++++++--------
drivers/net/wireless/mediatek/mt76/dma.h | 2 ++
drivers/net/wireless/mediatek/mt76/mt76.h | 19 ++++++++----
.../net/wireless/mediatek/mt76/mt7603/mac.c | 11 +++----
.../wireless/mediatek/mt76/mt7603/mt7603.h | 4 +--
drivers/net/wireless/mediatek/mt76/mt76x02.h | 4 +--
.../net/wireless/mediatek/mt76/mt76x02_mac.c | 4 ++-
.../net/wireless/mediatek/mt76/mt76x02_mmio.c | 1 -
.../net/wireless/mediatek/mt76/mt76x02_txrx.c | 12 ++++----
.../net/wireless/mediatek/mt76/mt76x02_usb.h | 4 +--
.../wireless/mediatek/mt76/mt76x02_usb_core.c | 18 ++++++------
drivers/net/wireless/mediatek/mt76/tx.c | 13 +++++----
drivers/net/wireless/mediatek/mt76/usb.c | 14 +++++----
13 files changed, 79 insertions(+), 56 deletions(-)

--
2.20.1



2019-04-02 09:48:12

by Lorenzo Bianconi

[permalink] [raw]
Subject: [PATCH v2 1/4] mt76: set txwi_size according to the driver value

Dynamically allocate txwi since new chipsets will use longer txwi
descriptors

Signed-off-by: Lorenzo Bianconi <[email protected]>
---
drivers/net/wireless/mediatek/mt76/dma.c | 8 +++++---
drivers/net/wireless/mediatek/mt76/mt76.h | 10 +++++++---
drivers/net/wireless/mediatek/mt76/mt76x02_mac.c | 4 +++-
drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c | 1 -
drivers/net/wireless/mediatek/mt76/tx.c | 12 +++++++-----
5 files changed, 22 insertions(+), 13 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/dma.c b/drivers/net/wireless/mediatek/mt76/dma.c
index 7b8a998103d7..e0286fae8e79 100644
--- a/drivers/net/wireless/mediatek/mt76/dma.c
+++ b/drivers/net/wireless/mediatek/mt76/dma.c
@@ -290,12 +290,14 @@ mt76_dma_tx_queue_skb(struct mt76_dev *dev, enum mt76_txq_id qid,
struct mt76_txwi_cache *t;
struct sk_buff *iter;
dma_addr_t addr;
+ u8 *txwi;

t = mt76_get_txwi(dev);
if (!t) {
ieee80211_free_txskb(dev->hw, skb);
return -ENOMEM;
}
+ txwi = mt76_get_txwi_ptr(dev, t);

skb->prev = skb->next = NULL;
if (dev->drv->tx_aligned4_skbs)
@@ -325,11 +327,11 @@ mt76_dma_tx_queue_skb(struct mt76_dev *dev, enum mt76_txq_id qid,
}
tx_info.nbuf = n;

- dma_sync_single_for_cpu(dev->dev, t->dma_addr, sizeof(t->txwi),
+ dma_sync_single_for_cpu(dev->dev, t->dma_addr, dev->drv->txwi_size,
DMA_TO_DEVICE);
- ret = dev->drv->tx_prepare_skb(dev, &t->txwi, skb, qid, wcid, sta,
+ ret = dev->drv->tx_prepare_skb(dev, txwi, skb, qid, wcid, sta,
&tx_info);
- dma_sync_single_for_device(dev->dev, t->dma_addr, sizeof(t->txwi),
+ dma_sync_single_for_device(dev->dev, t->dma_addr, dev->drv->txwi_size,
DMA_TO_DEVICE);
if (ret < 0)
goto unmap;
diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h
index b432da3f55c7..277f6b754693 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76.h
@@ -228,12 +228,10 @@ struct mt76_txq {
};

struct mt76_txwi_cache {
- u32 txwi[8];
- dma_addr_t dma_addr;
struct list_head list;
+ dma_addr_t dma_addr;
};

-
struct mt76_rx_tid {
struct rcu_head rcu_head;

@@ -613,6 +611,12 @@ void mt76_seq_puts_array(struct seq_file *file, const char *str,
int mt76_eeprom_init(struct mt76_dev *dev, int len);
void mt76_eeprom_override(struct mt76_dev *dev);

+static inline u8 *
+mt76_get_txwi_ptr(struct mt76_dev *dev, struct mt76_txwi_cache *t)
+{
+ return (u8 *)t - dev->drv->txwi_size;
+}
+
/* increment with wrap-around */
static inline int mt76_incr(int val, int size)
{
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
index 1eb669ccd5a7..ffedb8e5d227 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
@@ -760,6 +760,7 @@ void mt76x02_tx_complete_skb(struct mt76_dev *mdev, enum mt76_txq_id qid,
{
struct mt76x02_dev *dev = container_of(mdev, struct mt76x02_dev, mt76);
struct mt76x02_txwi *txwi;
+ u8 *txwi_ptr;

if (!e->txwi) {
dev_kfree_skb_any(e->skb);
@@ -768,7 +769,8 @@ void mt76x02_tx_complete_skb(struct mt76_dev *mdev, enum mt76_txq_id qid,

mt76x02_mac_poll_tx_status(dev, false);

- txwi = (struct mt76x02_txwi *) &e->txwi->txwi;
+ txwi_ptr = mt76_get_txwi_ptr(mdev, e->txwi);
+ txwi = (struct mt76x02_txwi *)txwi_ptr;
trace_mac_txdone_add(dev, txwi->wcid, txwi->pktid);

mt76_tx_complete_skb(mdev, e->skb);
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c b/drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c
index 3116aa935ee4..518dea4b9425 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c
@@ -174,7 +174,6 @@ int mt76x02_dma_init(struct mt76x02_dev *dev)
struct mt76_queue *q;
void *status_fifo;

- BUILD_BUG_ON(sizeof(t->txwi) < sizeof(struct mt76x02_txwi));
BUILD_BUG_ON(sizeof(struct mt76x02_rxwi) > MT_RX_HEADROOM);

fifo_size = roundup_pow_of_two(32 * sizeof(struct mt76x02_tx_status));
diff --git a/drivers/net/wireless/mediatek/mt76/tx.c b/drivers/net/wireless/mediatek/mt76/tx.c
index 2c82db0b5834..08587d262469 100644
--- a/drivers/net/wireless/mediatek/mt76/tx.c
+++ b/drivers/net/wireless/mediatek/mt76/tx.c
@@ -21,15 +21,17 @@ mt76_alloc_txwi(struct mt76_dev *dev)
{
struct mt76_txwi_cache *t;
dma_addr_t addr;
+ u8 *txwi;
int size;

- size = (sizeof(*t) + L1_CACHE_BYTES - 1) & ~(L1_CACHE_BYTES - 1);
- t = devm_kzalloc(dev->dev, size, GFP_ATOMIC);
- if (!t)
+ size = L1_CACHE_ALIGN(dev->drv->txwi_size + sizeof(*t));
+ txwi = devm_kzalloc(dev->dev, size, GFP_ATOMIC);
+ if (!txwi)
return NULL;

- addr = dma_map_single(dev->dev, &t->txwi, sizeof(t->txwi),
+ addr = dma_map_single(dev->dev, txwi, dev->drv->txwi_size,
DMA_TO_DEVICE);
+ t = (struct mt76_txwi_cache *)(txwi + dev->drv->txwi_size);
t->dma_addr = addr;

return t;
@@ -78,7 +80,7 @@ void mt76_tx_free(struct mt76_dev *dev)
struct mt76_txwi_cache *t;

while ((t = __mt76_get_txwi(dev)) != NULL)
- dma_unmap_single(dev->dev, t->dma_addr, sizeof(t->txwi),
+ dma_unmap_single(dev->dev, t->dma_addr, dev->drv->txwi_size,
DMA_TO_DEVICE);
}

--
2.20.1


2019-04-02 09:48:15

by Lorenzo Bianconi

[permalink] [raw]
Subject: [PATCH v2 2/4] mt76: add skb pointer to mt76_tx_info

Pass skb pointer to tx_prepare_skb through mt76_tx_info data structure.
This is a preliminary patch to properly support dma error path for
new chipsets (e.g. 7615)

Signed-off-by: Lorenzo Bianconi <[email protected]>
---
drivers/net/wireless/mediatek/mt76/dma.c | 11 ++++++-----
drivers/net/wireless/mediatek/mt76/mt76.h | 4 ++--
.../net/wireless/mediatek/mt76/mt7603/mac.c | 11 ++++++-----
.../net/wireless/mediatek/mt76/mt7603/mt7603.h | 4 ++--
drivers/net/wireless/mediatek/mt76/mt76x02.h | 4 ++--
.../net/wireless/mediatek/mt76/mt76x02_txrx.c | 12 ++++++------
.../net/wireless/mediatek/mt76/mt76x02_usb.h | 4 ++--
.../wireless/mediatek/mt76/mt76x02_usb_core.c | 18 +++++++++---------
drivers/net/wireless/mediatek/mt76/usb.c | 14 ++++++++------
9 files changed, 43 insertions(+), 39 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/dma.c b/drivers/net/wireless/mediatek/mt76/dma.c
index e0286fae8e79..54e6d985d384 100644
--- a/drivers/net/wireless/mediatek/mt76/dma.c
+++ b/drivers/net/wireless/mediatek/mt76/dma.c
@@ -284,7 +284,9 @@ mt76_dma_tx_queue_skb(struct mt76_dev *dev, enum mt76_txq_id qid,
struct ieee80211_sta *sta)
{
struct mt76_queue *q = dev->q_tx[qid].q;
- struct mt76_tx_info tx_info = {};
+ struct mt76_tx_info tx_info = {
+ .skb = skb,
+ };
int len, n = 0, ret = -ENOMEM;
struct mt76_queue_entry e;
struct mt76_txwi_cache *t;
@@ -329,8 +331,7 @@ mt76_dma_tx_queue_skb(struct mt76_dev *dev, enum mt76_txq_id qid,

dma_sync_single_for_cpu(dev->dev, t->dma_addr, dev->drv->txwi_size,
DMA_TO_DEVICE);
- ret = dev->drv->tx_prepare_skb(dev, txwi, skb, qid, wcid, sta,
- &tx_info);
+ ret = dev->drv->tx_prepare_skb(dev, txwi, qid, wcid, sta, &tx_info);
dma_sync_single_for_device(dev->dev, t->dma_addr, dev->drv->txwi_size,
DMA_TO_DEVICE);
if (ret < 0)
@@ -342,7 +343,7 @@ mt76_dma_tx_queue_skb(struct mt76_dev *dev, enum mt76_txq_id qid,
}

return mt76_dma_add_buf(dev, q, tx_info.buf, tx_info.nbuf,
- tx_info.info, skb, t);
+ tx_info.info, tx_info.skb, t);

unmap:
for (n--; n > 0; n--)
@@ -350,7 +351,7 @@ mt76_dma_tx_queue_skb(struct mt76_dev *dev, enum mt76_txq_id qid,
tx_info.buf[n].len, DMA_TO_DEVICE);

free:
- e.skb = skb;
+ e.skb = tx_info.skb;
e.txwi = t;
dev->drv->tx_complete_skb(dev, qid, &e);
mt76_put_txwi(dev, t);
diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h
index 277f6b754693..91f9433bf979 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76.h
@@ -85,6 +85,7 @@ struct mt76_queue_buf {

struct mt76_tx_info {
struct mt76_queue_buf buf[32];
+ struct sk_buff *skb;
int nbuf;
u32 info;
};
@@ -290,8 +291,7 @@ struct mt76_driver_ops {
void (*update_survey)(struct mt76_dev *dev);

int (*tx_prepare_skb)(struct mt76_dev *dev, void *txwi_ptr,
- struct sk_buff *skb, enum mt76_txq_id qid,
- struct mt76_wcid *wcid,
+ enum mt76_txq_id qid, struct mt76_wcid *wcid,
struct ieee80211_sta *sta,
struct mt76_tx_info *tx_info);

diff --git a/drivers/net/wireless/mediatek/mt76/mt7603/mac.c b/drivers/net/wireless/mediatek/mt76/mt7603/mac.c
index 5f800467c628..b38b89a89322 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7603/mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7603/mac.c
@@ -937,13 +937,13 @@ mt7603_mac_write_txwi(struct mt7603_dev *dev, __le32 *txwi,
}

int mt7603_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
- struct sk_buff *skb, enum mt76_txq_id qid,
- struct mt76_wcid *wcid, struct ieee80211_sta *sta,
+ enum mt76_txq_id qid, struct mt76_wcid *wcid,
+ struct ieee80211_sta *sta,
struct mt76_tx_info *tx_info)
{
struct mt7603_dev *dev = container_of(mdev, struct mt7603_dev, mt76);
struct mt7603_sta *msta = container_of(wcid, struct mt7603_sta, wcid);
- struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx_info->skb);
struct ieee80211_key_conf *key = info->control.hw_key;
int pid;

@@ -959,7 +959,7 @@ int mt7603_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
mt7603_wtbl_set_ps(dev, msta, false);
}

- pid = mt76_tx_status_skb_add(mdev, wcid, skb);
+ pid = mt76_tx_status_skb_add(mdev, wcid, tx_info->skb);

if (info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE) {
spin_lock_bh(&dev->mt76.lock);
@@ -969,7 +969,8 @@ int mt7603_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
spin_unlock_bh(&dev->mt76.lock);
}

- mt7603_mac_write_txwi(dev, txwi_ptr, skb, qid, wcid, sta, pid, key);
+ mt7603_mac_write_txwi(dev, txwi_ptr, tx_info->skb, qid, wcid,
+ sta, pid, key);

return 0;
}
diff --git a/drivers/net/wireless/mediatek/mt76/mt7603/mt7603.h b/drivers/net/wireless/mediatek/mt76/mt7603/mt7603.h
index 9cc8ca7a4d1c..72352559a212 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7603/mt7603.h
+++ b/drivers/net/wireless/mediatek/mt76/mt7603/mt7603.h
@@ -223,8 +223,8 @@ void mt7603_wtbl_set_smps(struct mt7603_dev *dev, struct mt7603_sta *sta,
void mt7603_filter_tx(struct mt7603_dev *dev, int idx, bool abort);

int mt7603_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
- struct sk_buff *skb, enum mt76_txq_id qid,
- struct mt76_wcid *wcid, struct ieee80211_sta *sta,
+ enum mt76_txq_id qid, struct mt76_wcid *wcid,
+ struct ieee80211_sta *sta,
struct mt76_tx_info *tx_info);

void mt7603_tx_complete_skb(struct mt76_dev *mdev, enum mt76_txq_id qid,
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02.h b/drivers/net/wireless/mediatek/mt76/mt76x02.h
index 0d817a142e76..fdf2f32b26dc 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02.h
@@ -184,8 +184,8 @@ irqreturn_t mt76x02_irq_handler(int irq, void *dev_instance);
void mt76x02_tx(struct ieee80211_hw *hw, struct ieee80211_tx_control *control,
struct sk_buff *skb);
int mt76x02_tx_prepare_skb(struct mt76_dev *mdev, void *txwi,
- struct sk_buff *skb, enum mt76_txq_id qid,
- struct mt76_wcid *wcid, struct ieee80211_sta *sta,
+ enum mt76_txq_id qid, struct mt76_wcid *wcid,
+ struct ieee80211_sta *sta,
struct mt76_tx_info *tx_info);
void mt76x02_sw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
const u8 *mac);
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_txrx.c b/drivers/net/wireless/mediatek/mt76/mt76x02_txrx.c
index dd7d04b9b8db..cf7abd9b7d2e 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_txrx.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_txrx.c
@@ -147,12 +147,12 @@ bool mt76x02_tx_status_data(struct mt76_dev *mdev, u8 *update)
EXPORT_SYMBOL_GPL(mt76x02_tx_status_data);

int mt76x02_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
- struct sk_buff *skb, enum mt76_txq_id qid,
- struct mt76_wcid *wcid, struct ieee80211_sta *sta,
+ enum mt76_txq_id qid, struct mt76_wcid *wcid,
+ struct ieee80211_sta *sta,
struct mt76_tx_info *tx_info)
{
struct mt76x02_dev *dev = container_of(mdev, struct mt76x02_dev, mt76);
- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
+ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx_info->skb->data;
struct mt76x02_txwi *txwi = txwi_ptr;
int hdrlen, len, pid, qsel = MT_QSEL_EDCA;

@@ -160,10 +160,10 @@ int mt76x02_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
mt76x02_mac_wcid_set_drop(dev, wcid->idx, false);

hdrlen = ieee80211_hdrlen(hdr->frame_control);
- len = skb->len - (hdrlen & 2);
- mt76x02_mac_write_txwi(dev, txwi, skb, wcid, sta, len);
+ len = tx_info->skb->len - (hdrlen & 2);
+ mt76x02_mac_write_txwi(dev, txwi, tx_info->skb, wcid, sta, len);

- pid = mt76_tx_status_skb_add(mdev, wcid, skb);
+ pid = mt76_tx_status_skb_add(mdev, wcid, tx_info->skb);
txwi->pktid = pid;

if (pid >= MT_PACKET_ID_FIRST)
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_usb.h b/drivers/net/wireless/mediatek/mt76/mt76x02_usb.h
index a012410c5ae7..7b53f9e57f29 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_usb.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_usb.h
@@ -26,8 +26,8 @@ int mt76x02u_mcu_fw_send_data(struct mt76x02_dev *dev, const void *data,

int mt76x02u_skb_dma_info(struct sk_buff *skb, int port, u32 flags);
int mt76x02u_tx_prepare_skb(struct mt76_dev *mdev, void *data,
- struct sk_buff *skb, enum mt76_txq_id qid,
- struct mt76_wcid *wcid, struct ieee80211_sta *sta,
+ enum mt76_txq_id qid, struct mt76_wcid *wcid,
+ struct ieee80211_sta *sta,
struct mt76_tx_info *tx_info);
void mt76x02u_tx_complete_skb(struct mt76_dev *mdev, enum mt76_txq_id qid,
struct mt76_queue_entry *e);
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_usb_core.c b/drivers/net/wireless/mediatek/mt76/mt76x02_usb_core.c
index c403218533da..818b96064dec 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_usb_core.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_usb_core.c
@@ -72,23 +72,23 @@ int mt76x02u_skb_dma_info(struct sk_buff *skb, int port, u32 flags)
}

int mt76x02u_tx_prepare_skb(struct mt76_dev *mdev, void *data,
- struct sk_buff *skb, enum mt76_txq_id qid,
- struct mt76_wcid *wcid, struct ieee80211_sta *sta,
+ enum mt76_txq_id qid, struct mt76_wcid *wcid,
+ struct ieee80211_sta *sta,
struct mt76_tx_info *tx_info)
{
struct mt76x02_dev *dev = container_of(mdev, struct mt76x02_dev, mt76);
- int pid, len = skb->len, ep = q2ep(mdev->q_tx[qid].q->hw_idx);
+ int pid, len = tx_info->skb->len, ep = q2ep(mdev->q_tx[qid].q->hw_idx);
struct mt76x02_txwi *txwi;
enum mt76_qsel qsel;
u32 flags;

- mt76_insert_hdr_pad(skb);
+ mt76_insert_hdr_pad(tx_info->skb);

- txwi = (struct mt76x02_txwi *)(skb->data - sizeof(struct mt76x02_txwi));
- mt76x02_mac_write_txwi(dev, txwi, skb, wcid, sta, len);
- skb_push(skb, sizeof(struct mt76x02_txwi));
+ txwi = (struct mt76x02_txwi *)(tx_info->skb->data - sizeof(*txwi));
+ mt76x02_mac_write_txwi(dev, txwi, tx_info->skb, wcid, sta, len);
+ skb_push(tx_info->skb, sizeof(*txwi));

- pid = mt76_tx_status_skb_add(mdev, wcid, skb);
+ pid = mt76_tx_status_skb_add(mdev, wcid, tx_info->skb);
txwi->pktid = pid;

if (pid >= MT_PACKET_ID_FIRST || ep == MT_EP_OUT_HCCA)
@@ -101,7 +101,7 @@ int mt76x02u_tx_prepare_skb(struct mt76_dev *mdev, void *data,
if (!wcid || wcid->hw_key_idx == 0xff || wcid->sw_iv)
flags |= MT_TXD_INFO_WIV;

- return mt76x02u_skb_dma_info(skb, WLAN_PORT, flags);
+ return mt76x02u_skb_dma_info(tx_info->skb, WLAN_PORT, flags);
}
EXPORT_SYMBOL_GPL(mt76x02u_tx_prepare_skb);

diff --git a/drivers/net/wireless/mediatek/mt76/usb.c b/drivers/net/wireless/mediatek/mt76/usb.c
index 3b5d30eaa31f..070eef631c43 100644
--- a/drivers/net/wireless/mediatek/mt76/usb.c
+++ b/drivers/net/wireless/mediatek/mt76/usb.c
@@ -735,7 +735,9 @@ mt76u_tx_queue_skb(struct mt76_dev *dev, enum mt76_txq_id qid,
struct ieee80211_sta *sta)
{
struct mt76_queue *q = dev->q_tx[qid].q;
- struct urb *urb;
+ struct mt76_tx_info tx_info = {
+ .skb = skb,
+ };
u16 idx = q->tail;
int err;

@@ -743,20 +745,20 @@ mt76u_tx_queue_skb(struct mt76_dev *dev, enum mt76_txq_id qid,
return -ENOSPC;

skb->prev = skb->next = NULL;
- err = dev->drv->tx_prepare_skb(dev, NULL, skb, qid, wcid, sta, NULL);
+ err = dev->drv->tx_prepare_skb(dev, NULL, qid, wcid, sta, &tx_info);
if (err < 0)
return err;

- urb = q->entry[idx].urb;
- err = mt76u_tx_setup_buffers(dev, skb, urb);
+ err = mt76u_tx_setup_buffers(dev, tx_info.skb, q->entry[idx].urb);
if (err < 0)
return err;

mt76u_fill_bulk_urb(dev, USB_DIR_OUT, q2ep(q->hw_idx),
- urb, mt76u_complete_tx, &q->entry[idx]);
+ q->entry[idx].urb, mt76u_complete_tx,
+ &q->entry[idx]);

q->tail = (q->tail + 1) % q->ndesc;
- q->entry[idx].skb = skb;
+ q->entry[idx].skb = tx_info.skb;
q->queued++;

return idx;
--
2.20.1


2019-04-02 09:48:18

by Lorenzo Bianconi

[permalink] [raw]
Subject: [PATCH v2 3/4] mt76: dma: introduce skb field in mt76_txwi_cache

Introduce skb field in mt76_txwi_cache. Moreover add txwi_flags
to mt76_driver_ops since new chipsets will release mt76_txwi_cache/skbs
at tx completion instead of dma one.
This is a preliminary patch to add mt7615 support

Signed-off-by: Lorenzo Bianconi <[email protected]>
---
drivers/net/wireless/mediatek/mt76/dma.c | 3 ++-
drivers/net/wireless/mediatek/mt76/mt76.h | 5 +++++
drivers/net/wireless/mediatek/mt76/tx.c | 1 +
3 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/mediatek/mt76/dma.c b/drivers/net/wireless/mediatek/mt76/dma.c
index 54e6d985d384..2bc5dd9a9e9f 100644
--- a/drivers/net/wireless/mediatek/mt76/dma.c
+++ b/drivers/net/wireless/mediatek/mt76/dma.c
@@ -176,7 +176,8 @@ mt76_dma_tx_cleanup(struct mt76_dev *dev, enum mt76_txq_id qid, bool flush)
}

if (entry.txwi) {
- mt76_put_txwi(dev, entry.txwi);
+ if (!(dev->drv->txwi_flags & MT_TXWI_NO_FREE))
+ mt76_put_txwi(dev, entry.txwi);
wake = !flush;
}

diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h
index 91f9433bf979..665f843008d0 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76.h
@@ -231,6 +231,8 @@ struct mt76_txq {
struct mt76_txwi_cache {
struct list_head list;
dma_addr_t dma_addr;
+
+ struct sk_buff *skb;
};

struct mt76_rx_tid {
@@ -284,8 +286,11 @@ struct mt76_hw_cap {
bool has_5ghz;
};

+#define MT_TXWI_NO_FREE BIT(0)
+
struct mt76_driver_ops {
bool tx_aligned4_skbs;
+ u32 txwi_flags;
u16 txwi_size;

void (*update_survey)(struct mt76_dev *dev);
diff --git a/drivers/net/wireless/mediatek/mt76/tx.c b/drivers/net/wireless/mediatek/mt76/tx.c
index 08587d262469..6a0c4b8a649d 100644
--- a/drivers/net/wireless/mediatek/mt76/tx.c
+++ b/drivers/net/wireless/mediatek/mt76/tx.c
@@ -74,6 +74,7 @@ mt76_put_txwi(struct mt76_dev *dev, struct mt76_txwi_cache *t)
list_add(&t->list, &dev->txwi_cache);
spin_unlock_bh(&dev->lock);
}
+EXPORT_SYMBOL_GPL(mt76_put_txwi);

void mt76_tx_free(struct mt76_dev *dev)
{
--
2.20.1


2019-04-02 09:48:20

by Lorenzo Bianconi

[permalink] [raw]
Subject: [PATCH v2 4/4] mt76: dma: add skb check for dummy pointer

Introduce skb check for dummy address in mt76_dma_tx_cleanup_idx.
This is a preliminary patch to add support for new chipsets (e.g. 7615)

Signed-off-by: Lorenzo Bianconi <[email protected]>
---
drivers/net/wireless/mediatek/mt76/dma.c | 9 +++++----
drivers/net/wireless/mediatek/mt76/dma.h | 2 ++
2 files changed, 7 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/dma.c b/drivers/net/wireless/mediatek/mt76/dma.c
index 2bc5dd9a9e9f..4ed3ea53a16d 100644
--- a/drivers/net/wireless/mediatek/mt76/dma.c
+++ b/drivers/net/wireless/mediatek/mt76/dma.c
@@ -18,8 +18,6 @@
#include "mt76.h"
#include "dma.h"

-#define DMA_DUMMY_TXWI ((void *) ~0)
-
static int
mt76_dma_alloc_queue(struct mt76_dev *dev, struct mt76_queue *q,
int idx, int n_desc, int bufsize,
@@ -67,7 +65,7 @@ mt76_dma_add_buf(struct mt76_dev *dev, struct mt76_queue *q,
int i, idx = -1;

if (txwi)
- q->entry[q->head].txwi = DMA_DUMMY_TXWI;
+ q->entry[q->head].txwi = DMA_DUMMY_DATA;

for (i = 0; i < nbufs; i += 2, buf += 2) {
u32 buf0 = buf[0].addr, buf1 = 0;
@@ -126,9 +124,12 @@ mt76_dma_tx_cleanup_idx(struct mt76_dev *dev, struct mt76_queue *q, int idx,
DMA_TO_DEVICE);
}

- if (e->txwi == DMA_DUMMY_TXWI)
+ if (e->txwi == DMA_DUMMY_DATA)
e->txwi = NULL;

+ if (e->skb == DMA_DUMMY_DATA)
+ e->skb = NULL;
+
*prev_e = *e;
memset(e, 0, sizeof(*e));
}
diff --git a/drivers/net/wireless/mediatek/mt76/dma.h b/drivers/net/wireless/mediatek/mt76/dma.h
index e3292df5e9b2..03dd2bafa4e8 100644
--- a/drivers/net/wireless/mediatek/mt76/dma.h
+++ b/drivers/net/wireless/mediatek/mt76/dma.h
@@ -16,6 +16,8 @@
#ifndef __MT76_DMA_H
#define __MT76_DMA_H

+#define DMA_DUMMY_DATA ((void *)~0)
+
#define MT_RING_SIZE 0x10

#define MT_DMA_CTL_SD_LEN1 GENMASK(13, 0)
--
2.20.1


2019-04-25 13:05:08

by Felix Fietkau

[permalink] [raw]
Subject: Re: [PATCH v2 0/4] add missing bits for mt7615 support

On 2019-04-02 11:47, Lorenzo Bianconi wrote:
> This is a preliminary series to add support for mt7615.
> Dynamically allocate txwi descriptor.
> Add missing bit in dma error data path.
> This series is based on https://patchwork.kernel.org/patch/10856027/
>
> Changes since v1:
> - remove flags from mt76_txwi_cache
>
> Lorenzo Bianconi (4):
> mt76: set txwi_size according to the driver value
> mt76: add skb pointer to mt76_tx_info
> mt76: dma: introduce skb field in mt76_txwi_cache
> mt76: dma: add skb check for dummy pointer
Applied, thanks.

- Felix