Linux wireless drivers development
 help / color / mirror / Atom feed
* [RFC 01/12] mt76usb: change mt76u_submit_buf
From: Stanislaw Gruszka @ 2019-03-12 15:05 UTC (permalink / raw)
  To: linux-wireless; +Cc: Felix Fietkau, Lorenzo Bianconi, Stanislaw Gruszka
In-Reply-To: <1552403166-3821-1-git-send-email-sgruszka@redhat.com>

Remove unnecessery arguments and change the function name since is
now used only for RX.

Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
---
 drivers/net/wireless/mediatek/mt76/usb.c | 30 ++++++++++++------------------
 1 file changed, 12 insertions(+), 18 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/usb.c b/drivers/net/wireless/mediatek/mt76/usb.c
index c5f3b2cdd9b1..661a65cb9c35 100644
--- a/drivers/net/wireless/mediatek/mt76/usb.c
+++ b/drivers/net/wireless/mediatek/mt76/usb.c
@@ -394,18 +394,6 @@ static void mt76u_buf_free(struct mt76u_buf *buf)
 			  complete_fn, context);
 }
 
-static int
-mt76u_submit_buf(struct mt76_dev *dev, int dir, int index,
-		 struct mt76u_buf *buf, gfp_t gfp,
-		 usb_complete_t complete_fn, void *context)
-{
-	mt76u_fill_bulk_urb(dev, dir, index, buf, complete_fn,
-			    context);
-	trace_submit_urb(dev, buf->urb);
-
-	return usb_submit_urb(buf->urb, gfp);
-}
-
 static inline struct mt76u_buf
 *mt76u_get_next_rx_entry(struct mt76_queue *q)
 {
@@ -513,6 +501,16 @@ static void mt76u_complete_rx(struct urb *urb)
 	spin_unlock_irqrestore(&q->lock, flags);
 }
 
+static int
+mt76u_submit_rx_buf(struct mt76_dev *dev, struct mt76u_buf *buf)
+{
+	mt76u_fill_bulk_urb(dev, USB_DIR_IN, MT_EP_IN_PKT_RX, buf,
+			    mt76u_complete_rx, dev);
+	trace_submit_urb(dev, buf->urb);
+
+	return usb_submit_urb(buf->urb, GFP_ATOMIC);
+}
+
 static void mt76u_rx_tasklet(unsigned long data)
 {
 	struct mt76_dev *dev = (struct mt76_dev *)data;
@@ -534,9 +532,7 @@ static void mt76u_rx_tasklet(unsigned long data)
 			if (err < 0)
 				break;
 		}
-		mt76u_submit_buf(dev, USB_DIR_IN, MT_EP_IN_PKT_RX,
-				 buf, GFP_ATOMIC,
-				 mt76u_complete_rx, dev);
+		mt76u_submit_rx_buf(dev, buf);
 	}
 	mt76_rx_poll_complete(dev, MT_RXQ_MAIN, NULL);
 
@@ -551,9 +547,7 @@ int mt76u_submit_rx_buffers(struct mt76_dev *dev)
 
 	spin_lock_irqsave(&q->lock, flags);
 	for (i = 0; i < q->ndesc; i++) {
-		err = mt76u_submit_buf(dev, USB_DIR_IN, MT_EP_IN_PKT_RX,
-				       &q->entry[i].ubuf, GFP_ATOMIC,
-				       mt76u_complete_rx, dev);
+		err = mt76u_submit_rx_buf(dev, &q->entry[i].ubuf);
 		if (err < 0)
 			break;
 	}
-- 
1.9.3


^ permalink raw reply related

* [RFC 02/12] mt76: remove rx_page_lock
From: Stanislaw Gruszka @ 2019-03-12 15:05 UTC (permalink / raw)
  To: linux-wireless; +Cc: Felix Fietkau, Lorenzo Bianconi, Stanislaw Gruszka
In-Reply-To: <1552403166-3821-1-git-send-email-sgruszka@redhat.com>

We can not run mt76u_alloc_buf() concurently, rx_tasklet is stooped
when mt76u_submit_rx_buffers(). We can remove rx_page_lock.

Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
---
 drivers/net/wireless/mediatek/mt76/mt76.h | 1 -
 drivers/net/wireless/mediatek/mt76/usb.c  | 8 +-------
 2 files changed, 1 insertion(+), 8 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h
index 3d3f0a5fc426..424f9090680d 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76.h
@@ -132,7 +132,6 @@ struct mt76_queue {
 	dma_addr_t desc_dma;
 	struct sk_buff *rx_head;
 	struct page_frag_cache rx_page;
-	spinlock_t rx_page_lock;
 };
 
 struct mt76_sw_queue {
diff --git a/drivers/net/wireless/mediatek/mt76/usb.c b/drivers/net/wireless/mediatek/mt76/usb.c
index 661a65cb9c35..883e8a2b519f 100644
--- a/drivers/net/wireless/mediatek/mt76/usb.c
+++ b/drivers/net/wireless/mediatek/mt76/usb.c
@@ -292,7 +292,6 @@ static bool mt76u_check_sg(struct mt76_dev *dev)
 	struct urb *urb = buf->urb;
 	int i;
 
-	spin_lock_bh(&q->rx_page_lock);
 	for (i = 0; i < nsgs; i++) {
 		struct page *page;
 		void *data;
@@ -306,7 +305,6 @@ static bool mt76u_check_sg(struct mt76_dev *dev)
 		offset = data - page_address(page);
 		sg_set_page(&urb->sg[i], page, sglen, offset);
 	}
-	spin_unlock_bh(&q->rx_page_lock);
 
 	if (i < nsgs) {
 		int j;
@@ -569,7 +567,6 @@ static int mt76u_alloc_rx(struct mt76_dev *dev)
 	if (!usb->mcu.data)
 		return -ENOMEM;
 
-	spin_lock_init(&q->rx_page_lock);
 	spin_lock_init(&q->lock);
 	q->entry = devm_kcalloc(dev->dev,
 				MT_NUM_RX_ENTRIES, sizeof(*q->entry),
@@ -597,15 +594,12 @@ static void mt76u_free_rx(struct mt76_dev *dev)
 	for (i = 0; i < q->ndesc; i++)
 		mt76u_buf_free(&q->entry[i].ubuf);
 
-	spin_lock_bh(&q->rx_page_lock);
 	if (!q->rx_page.va)
-		goto out;
+		return;
 
 	page = virt_to_page(q->rx_page.va);
 	__page_frag_cache_drain(page, q->rx_page.pagecnt_bias);
 	memset(&q->rx_page, 0, sizeof(q->rx_page));
-out:
-	spin_unlock_bh(&q->rx_page_lock);
 }
 
 static void mt76u_stop_rx(struct mt76_dev *dev)
-- 
1.9.3


^ permalink raw reply related

* [RFC 03/12] mt76usb: change mt76u_fill_rx_sg arguments
From: Stanislaw Gruszka @ 2019-03-12 15:05 UTC (permalink / raw)
  To: linux-wireless; +Cc: Felix Fietkau, Lorenzo Bianconi, Stanislaw Gruszka
In-Reply-To: <1552403166-3821-1-git-send-email-sgruszka@redhat.com>

We do not need to pass len and sglen to the function.
Additionally pass gfp to control allocation context.

Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
---
 drivers/net/wireless/mediatek/mt76/usb.c | 11 ++++++-----
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/usb.c b/drivers/net/wireless/mediatek/mt76/usb.c
index 883e8a2b519f..dbabf7971798 100644
--- a/drivers/net/wireless/mediatek/mt76/usb.c
+++ b/drivers/net/wireless/mediatek/mt76/usb.c
@@ -285,11 +285,13 @@ static bool mt76u_check_sg(struct mt76_dev *dev)
 }
 
 static int
-mt76u_fill_rx_sg(struct mt76_dev *dev, struct mt76u_buf *buf,
-		 int nsgs, int len, int sglen)
+mt76u_fill_rx_sg(struct mt76_dev *dev, struct mt76u_buf *buf, int nsgs,
+		 gfp_t gfp)
 {
 	struct mt76_queue *q = &dev->q_rx[MT_RXQ_MAIN];
+	int sglen = SKB_WITH_OVERHEAD(q->buf_size);
 	struct urb *urb = buf->urb;
+
 	int i;
 
 	for (i = 0; i < nsgs; i++) {
@@ -297,7 +299,7 @@ static bool mt76u_check_sg(struct mt76_dev *dev)
 		void *data;
 		int offset;
 
-		data = page_frag_alloc(&q->rx_page, len, GFP_ATOMIC);
+		data = page_frag_alloc(&q->rx_page, q->buf_size, gfp);
 		if (!data)
 			break;
 
@@ -326,8 +328,7 @@ static bool mt76u_check_sg(struct mt76_dev *dev)
 		struct mt76u_buf *buf, int nsgs, gfp_t gfp)
 {
 	if (dev->usb.sg_en) {
-		return mt76u_fill_rx_sg(dev, buf, nsgs, q->buf_size,
-					SKB_WITH_OVERHEAD(q->buf_size));
+		return mt76u_fill_rx_sg(dev, buf, nsgs, gfp);
 	} else {
 		buf->buf = page_frag_alloc(&q->rx_page, q->buf_size, gfp);
 		return buf->buf ? 0 : -ENOMEM;
-- 
1.9.3


^ permalink raw reply related

* [RFC 04/12] mt76usb: use usb_dev private data
From: Stanislaw Gruszka @ 2019-03-12 15:05 UTC (permalink / raw)
  To: linux-wireless; +Cc: Felix Fietkau, Lorenzo Bianconi, Stanislaw Gruszka
In-Reply-To: <1552403166-3821-1-git-send-email-sgruszka@redhat.com>

Setup usb device private data. This allows to remove mt76u_buf->dev
and simplify some routines as no longer we need to get usb device
through usb interface.

Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
---
 drivers/net/wireless/mediatek/mt76/mt76.h       |  4 +---
 drivers/net/wireless/mediatek/mt76/mt76x0/usb.c |  2 +-
 drivers/net/wireless/mediatek/mt76/mt76x2/usb.c |  4 +++-
 drivers/net/wireless/mediatek/mt76/usb.c        | 13 ++++---------
 4 files changed, 9 insertions(+), 14 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h
index 424f9090680d..89cdfe4abf33 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76.h
@@ -84,7 +84,6 @@ struct mt76_queue_buf {
 };
 
 struct mt76u_buf {
-	struct mt76_dev *dev;
 	struct urb *urb;
 	size_t len;
 	void *buf;
@@ -744,8 +743,7 @@ static inline u8 q2ep(u8 qid)
 mt76u_bulk_msg(struct mt76_dev *dev, void *data, int len, int *actual_len,
 	       int timeout)
 {
-	struct usb_interface *intf = to_usb_interface(dev->dev);
-	struct usb_device *udev = interface_to_usbdev(intf);
+	struct usb_device *udev = to_usb_device(dev->dev);
 	struct mt76_usb *usb = &dev->usb;
 	unsigned int pipe;
 
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c b/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c
index 69d6328a098d..1ef00e971cfa 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c
@@ -234,7 +234,7 @@ static int mt76x0u_probe(struct usb_interface *usb_intf,
 	u32 mac_rev;
 	int ret;
 
-	mdev = mt76_alloc_device(&usb_intf->dev, sizeof(*dev), &mt76x0u_ops,
+	mdev = mt76_alloc_device(&usb_dev->dev, sizeof(*dev), &mt76x0u_ops,
 				 &drv_ops);
 	if (!mdev)
 		return -ENOMEM;
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/usb.c b/drivers/net/wireless/mediatek/mt76/mt76x2/usb.c
index 47fe536bf896..0a7df308b2f8 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x2/usb.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x2/usb.c
@@ -50,7 +50,7 @@ static int mt76x2u_probe(struct usb_interface *intf,
 	struct mt76_dev *mdev;
 	int err;
 
-	mdev = mt76_alloc_device(&intf->dev, sizeof(*dev), &mt76x2u_ops,
+	mdev = mt76_alloc_device(&udev->dev, sizeof(*dev), &mt76x2u_ops,
 				 &drv_ops);
 	if (!mdev)
 		return -ENOMEM;
@@ -60,6 +60,8 @@ static int mt76x2u_probe(struct usb_interface *intf,
 	udev = usb_get_dev(udev);
 	usb_reset_device(udev);
 
+	usb_set_intfdata(intf, dev);
+
 	mt76x02u_init_mcu(mdev);
 	err = mt76u_init(mdev, intf);
 	if (err < 0)
diff --git a/drivers/net/wireless/mediatek/mt76/usb.c b/drivers/net/wireless/mediatek/mt76/usb.c
index dbabf7971798..954feb311620 100644
--- a/drivers/net/wireless/mediatek/mt76/usb.c
+++ b/drivers/net/wireless/mediatek/mt76/usb.c
@@ -31,8 +31,7 @@ static int __mt76u_vendor_request(struct mt76_dev *dev, u8 req,
 				  u8 req_type, u16 val, u16 offset,
 				  void *buf, size_t len)
 {
-	struct usb_interface *intf = to_usb_interface(dev->dev);
-	struct usb_device *udev = interface_to_usbdev(intf);
+	struct usb_device *udev = to_usb_device(dev->dev);
 	unsigned int pipe;
 	int i, ret;
 
@@ -247,8 +246,7 @@ void mt76u_single_wr(struct mt76_dev *dev, const u8 req,
 
 static bool mt76u_check_sg(struct mt76_dev *dev)
 {
-	struct usb_interface *intf = to_usb_interface(dev->dev);
-	struct usb_device *udev = interface_to_usbdev(intf);
+	struct usb_device *udev = to_usb_device(dev->dev);
 
 	return (!disable_usb_sg && udev->bus->sg_tablesize > 0 &&
 		(udev->bus->no_sg_constraint ||
@@ -341,7 +339,6 @@ static bool mt76u_check_sg(struct mt76_dev *dev)
 	struct mt76_queue *q = &dev->q_rx[MT_RXQ_MAIN];
 
 	buf->len = SKB_WITH_OVERHEAD(q->buf_size);
-	buf->dev = dev;
 
 	buf->urb = usb_alloc_urb(0, GFP_KERNEL);
 	if (!buf->urb)
@@ -379,8 +376,7 @@ static void mt76u_buf_free(struct mt76u_buf *buf)
 		    struct mt76u_buf *buf, usb_complete_t complete_fn,
 		    void *context)
 {
-	struct usb_interface *intf = to_usb_interface(dev->dev);
-	struct usb_device *udev = interface_to_usbdev(intf);
+	struct usb_device *udev = to_usb_device(dev->dev);
 	u8 *data = buf->urb->num_sgs ? NULL : buf->buf;
 	unsigned int pipe;
 
@@ -694,8 +690,8 @@ static void mt76u_tx_status_data(struct work_struct *work)
 
 static void mt76u_complete_tx(struct urb *urb)
 {
+	struct mt76_dev *dev = dev_get_drvdata(&urb->dev->dev);
 	struct mt76u_buf *buf = urb->context;
-	struct mt76_dev *dev = buf->dev;
 
 	if (mt76u_urb_error(urb))
 		dev_err(dev->dev, "tx urb failed: %d\n", urb->status);
@@ -806,7 +802,6 @@ static int mt76u_alloc_tx(struct mt76_dev *dev)
 		q->ndesc = MT_NUM_TX_ENTRIES;
 		for (j = 0; j < q->ndesc; j++) {
 			buf = &q->entry[j].ubuf;
-			buf->dev = dev;
 
 			buf->urb = usb_alloc_urb(0, GFP_KERNEL);
 			if (!buf->urb)
-- 
1.9.3


^ permalink raw reply related

* [RFC 05/12] mt76usb: remove mt76u_buf redundant fileds
From: Stanislaw Gruszka @ 2019-03-12 15:05 UTC (permalink / raw)
  To: linux-wireless; +Cc: Felix Fietkau, Lorenzo Bianconi, Stanislaw Gruszka
In-Reply-To: <1552403166-3821-1-git-send-email-sgruszka@redhat.com>

Remove mt76u_buf->{len, buf} fields and operate on corresponding
urb fields directly.

Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
---
 drivers/net/wireless/mediatek/mt76/mt76.h |  2 --
 drivers/net/wireless/mediatek/mt76/usb.c  | 40 +++++++++++++++++--------------
 2 files changed, 22 insertions(+), 20 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h
index 89cdfe4abf33..476cb39c99b7 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76.h
@@ -85,8 +85,6 @@ struct mt76_queue_buf {
 
 struct mt76u_buf {
 	struct urb *urb;
-	size_t len;
-	void *buf;
 	bool done;
 };
 
diff --git a/drivers/net/wireless/mediatek/mt76/usb.c b/drivers/net/wireless/mediatek/mt76/usb.c
index 954feb311620..86bf852c6e3d 100644
--- a/drivers/net/wireless/mediatek/mt76/usb.c
+++ b/drivers/net/wireless/mediatek/mt76/usb.c
@@ -315,7 +315,7 @@ static bool mt76u_check_sg(struct mt76_dev *dev)
 	}
 
 	urb->num_sgs = max_t(int, i, urb->num_sgs);
-	buf->len = urb->num_sgs * sglen,
+	urb->transfer_buffer_length = urb->num_sgs * sglen,
 	sg_init_marker(urb->sg, urb->num_sgs);
 
 	return i ? : -ENOMEM;
@@ -328,8 +328,11 @@ static bool mt76u_check_sg(struct mt76_dev *dev)
 	if (dev->usb.sg_en) {
 		return mt76u_fill_rx_sg(dev, buf, nsgs, gfp);
 	} else {
-		buf->buf = page_frag_alloc(&q->rx_page, q->buf_size, gfp);
-		return buf->buf ? 0 : -ENOMEM;
+		buf->urb->transfer_buffer_length =
+			SKB_WITH_OVERHEAD(q->buf_size);
+		buf->urb->transfer_buffer =
+			page_frag_alloc(&q->rx_page, q->buf_size, gfp);
+		return buf->urb->transfer_buffer ? 0 : -ENOMEM;
 	}
 }
 
@@ -338,8 +341,6 @@ static bool mt76u_check_sg(struct mt76_dev *dev)
 {
 	struct mt76_queue *q = &dev->q_rx[MT_RXQ_MAIN];
 
-	buf->len = SKB_WITH_OVERHEAD(q->buf_size);
-
 	buf->urb = usb_alloc_urb(0, GFP_KERNEL);
 	if (!buf->urb)
 		return -ENOMEM;
@@ -365,8 +366,8 @@ static void mt76u_buf_free(struct mt76u_buf *buf)
 	for (i = 0; i < urb->num_sgs; i++)
 		skb_free_frag(sg_virt(&urb->sg[i]));
 
-	if (buf->buf)
-		skb_free_frag(buf->buf);
+	if (urb->transfer_buffer)
+		skb_free_frag(urb->transfer_buffer);
 
 	usb_free_urb(buf->urb);
 }
@@ -377,7 +378,6 @@ static void mt76u_buf_free(struct mt76u_buf *buf)
 		    void *context)
 {
 	struct usb_device *udev = to_usb_device(dev->dev);
-	u8 *data = buf->urb->num_sgs ? NULL : buf->buf;
 	unsigned int pipe;
 
 	if (dir == USB_DIR_IN)
@@ -385,8 +385,10 @@ static void mt76u_buf_free(struct mt76u_buf *buf)
 	else
 		pipe = usb_sndbulkpipe(udev, dev->usb.out_ep[index]);
 
-	usb_fill_bulk_urb(buf->urb, udev, pipe, data, buf->len,
-			  complete_fn, context);
+	buf->urb->dev = udev;
+	buf->urb->pipe = pipe;
+	buf->urb->complete = complete_fn;
+	buf->urb->context = context;
 }
 
 static inline struct mt76u_buf
@@ -426,7 +428,7 @@ static int mt76u_get_rx_entry_len(u8 *data, u32 data_len)
 {
 	struct mt76_queue *q = &dev->q_rx[MT_RXQ_MAIN];
 	struct urb *urb = buf->urb;
-	u8 *data = urb->num_sgs ? sg_virt(&urb->sg[0]) : buf->buf;
+	u8 *data = urb->num_sgs ? sg_virt(&urb->sg[0]) : urb->transfer_buffer;
 	int data_len, len, nsgs = 1;
 	struct sk_buff *skb;
 
@@ -437,7 +439,7 @@ static int mt76u_get_rx_entry_len(u8 *data, u32 data_len)
 	if (len < 0)
 		return 0;
 
-	data_len = urb->num_sgs ? urb->sg[0].length : buf->len;
+	data_len = urb->num_sgs ? urb->sg[0].length : INT_MAX;
 	data_len = min_t(int, len, data_len - MT_DMA_HDR_LEN);
 	if (MT_DMA_HDR_LEN + data_len > SKB_WITH_OVERHEAD(q->buf_size))
 		return 0;
@@ -731,14 +733,16 @@ static void mt76u_complete_tx(struct urb *urb)
 		return err;
 
 	buf = &q->entry[idx].ubuf;
-	buf->buf = skb->data;
-	buf->len = skb->len;
+	if (!dev->usb.sg_en) {
+		buf->urb->transfer_buffer = skb->data;
+	} else {
+		err = mt76u_tx_build_sg(dev, skb, buf->urb);
+		if (err < 0)
+			return err;
+	}
+	buf->urb->transfer_buffer_length = skb->len;
 	buf->done = false;
 
-	err = mt76u_tx_build_sg(dev, skb, buf->urb);
-	if (err < 0)
-		return err;
-
 	mt76u_fill_bulk_urb(dev, USB_DIR_OUT, q2ep(q->hw_idx),
 			    buf, mt76u_complete_tx, buf);
 
-- 
1.9.3


^ permalink raw reply related

* [RFC 06/12] mt76usb: move mt76u_buf->done to queue entry
From: Stanislaw Gruszka @ 2019-03-12 15:06 UTC (permalink / raw)
  To: linux-wireless; +Cc: Felix Fietkau, Lorenzo Bianconi, Stanislaw Gruszka
In-Reply-To: <1552403166-3821-1-git-send-email-sgruszka@redhat.com>

mt76_queue_entry has alreay one bool variable, adding new one will
not increase it's size. Removing ->done filed from mt76u_buf will
allow to use urb directly in mt76usb code.

Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
---
 drivers/net/wireless/mediatek/mt76/mt76.h |  2 +-
 drivers/net/wireless/mediatek/mt76/usb.c  | 12 +++++-------
 2 files changed, 6 insertions(+), 8 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h
index 476cb39c99b7..998505064dee 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76.h
@@ -85,7 +85,6 @@ struct mt76_queue_buf {
 
 struct mt76u_buf {
 	struct urb *urb;
-	bool done;
 };
 
 struct mt76_queue_entry {
@@ -99,6 +98,7 @@ struct mt76_queue_entry {
 	};
 	enum mt76_txq_id qid;
 	bool schedule;
+	bool done;
 };
 
 struct mt76_queue_regs {
diff --git a/drivers/net/wireless/mediatek/mt76/usb.c b/drivers/net/wireless/mediatek/mt76/usb.c
index 86bf852c6e3d..a4ef9bb1603d 100644
--- a/drivers/net/wireless/mediatek/mt76/usb.c
+++ b/drivers/net/wireless/mediatek/mt76/usb.c
@@ -615,7 +615,6 @@ static void mt76u_tx_tasklet(unsigned long data)
 	struct mt76_dev *dev = (struct mt76_dev *)data;
 	struct mt76_queue_entry entry;
 	struct mt76_sw_queue *sq;
-	struct mt76u_buf *buf;
 	struct mt76_queue *q;
 	bool wake;
 	int i;
@@ -626,8 +625,7 @@ static void mt76u_tx_tasklet(unsigned long data)
 
 		spin_lock_bh(&q->lock);
 		while (true) {
-			buf = &q->entry[q->head].ubuf;
-			if (!buf->done || !q->queued)
+			if (!q->entry[q->head].done || !q->queued)
 				break;
 
 			if (q->entry[q->head].schedule) {
@@ -693,11 +691,11 @@ static void mt76u_tx_status_data(struct work_struct *work)
 static void mt76u_complete_tx(struct urb *urb)
 {
 	struct mt76_dev *dev = dev_get_drvdata(&urb->dev->dev);
-	struct mt76u_buf *buf = urb->context;
+	struct mt76_queue_entry *e = urb->context;
 
 	if (mt76u_urb_error(urb))
 		dev_err(dev->dev, "tx urb failed: %d\n", urb->status);
-	buf->done = true;
+	e->done = true;
 
 	tasklet_schedule(&dev->usb.tx_tasklet);
 }
@@ -732,6 +730,7 @@ static void mt76u_complete_tx(struct urb *urb)
 	if (err < 0)
 		return err;
 
+	q->entry[idx].done = false;
 	buf = &q->entry[idx].ubuf;
 	if (!dev->usb.sg_en) {
 		buf->urb->transfer_buffer = skb->data;
@@ -741,10 +740,9 @@ static void mt76u_complete_tx(struct urb *urb)
 			return err;
 	}
 	buf->urb->transfer_buffer_length = skb->len;
-	buf->done = false;
 
 	mt76u_fill_bulk_urb(dev, USB_DIR_OUT, q2ep(q->hw_idx),
-			    buf, mt76u_complete_tx, buf);
+			    buf, mt76u_complete_tx, &q->entry[idx]);
 
 	q->tail = (q->tail + 1) % q->ndesc;
 	q->entry[idx].skb = skb;
-- 
1.9.3


^ permalink raw reply related

* [RFC 07/12] mt76usb: remove mt76u_buf and use urb directly
From: Stanislaw Gruszka @ 2019-03-12 15:06 UTC (permalink / raw)
  To: linux-wireless; +Cc: Felix Fietkau, Lorenzo Bianconi, Stanislaw Gruszka
In-Reply-To: <1552403166-3821-1-git-send-email-sgruszka@redhat.com>

Put urb pointer in mt76_queue_entry directly instead of mt76u_buf
structure.

Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
---
 drivers/net/wireless/mediatek/mt76/mt76.h |   6 +-
 drivers/net/wireless/mediatek/mt76/usb.c  | 132 +++++++++++++++---------------
 2 files changed, 65 insertions(+), 73 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h
index 998505064dee..859d0325583b 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76.h
@@ -83,10 +83,6 @@ struct mt76_queue_buf {
 	int len;
 };
 
-struct mt76u_buf {
-	struct urb *urb;
-};
-
 struct mt76_queue_entry {
 	union {
 		void *buf;
@@ -94,7 +90,7 @@ struct mt76_queue_entry {
 	};
 	union {
 		struct mt76_txwi_cache *txwi;
-		struct mt76u_buf ubuf;
+		struct urb *urb;
 	};
 	enum mt76_txq_id qid;
 	bool schedule;
diff --git a/drivers/net/wireless/mediatek/mt76/usb.c b/drivers/net/wireless/mediatek/mt76/usb.c
index a4ef9bb1603d..2c21f4773a19 100644
--- a/drivers/net/wireless/mediatek/mt76/usb.c
+++ b/drivers/net/wireless/mediatek/mt76/usb.c
@@ -283,12 +283,11 @@ static bool mt76u_check_sg(struct mt76_dev *dev)
 }
 
 static int
-mt76u_fill_rx_sg(struct mt76_dev *dev, struct mt76u_buf *buf, int nsgs,
+mt76u_fill_rx_sg(struct mt76_dev *dev, struct urb *urb, int nsgs,
 		 gfp_t gfp)
 {
 	struct mt76_queue *q = &dev->q_rx[MT_RXQ_MAIN];
 	int sglen = SKB_WITH_OVERHEAD(q->buf_size);
-	struct urb *urb = buf->urb;
 
 	int i;
 
@@ -323,44 +322,43 @@ static bool mt76u_check_sg(struct mt76_dev *dev)
 
 static int
 mt76u_refill_rx(struct mt76_dev *dev, struct mt76_queue *q,
-		struct mt76u_buf *buf, int nsgs, gfp_t gfp)
+		struct urb *urb, int nsgs, gfp_t gfp)
 {
 	if (dev->usb.sg_en) {
-		return mt76u_fill_rx_sg(dev, buf, nsgs, gfp);
+		return mt76u_fill_rx_sg(dev, urb, nsgs, gfp);
 	} else {
-		buf->urb->transfer_buffer_length =
-			SKB_WITH_OVERHEAD(q->buf_size);
-		buf->urb->transfer_buffer =
-			page_frag_alloc(&q->rx_page, q->buf_size, gfp);
-		return buf->urb->transfer_buffer ? 0 : -ENOMEM;
+		urb->transfer_buffer_length = SKB_WITH_OVERHEAD(q->buf_size);
+		urb->transfer_buffer = page_frag_alloc(&q->rx_page,
+						       q->buf_size, gfp);
+		return urb->transfer_buffer ? 0 : -ENOMEM;
 	}
 }
 
 static int
-mt76u_buf_alloc(struct mt76_dev *dev, struct mt76u_buf *buf)
+mt76u_urb_alloc(struct mt76_dev *dev, struct mt76_queue_entry *e)
 {
 	struct mt76_queue *q = &dev->q_rx[MT_RXQ_MAIN];
+	struct urb *urb;
 
-	buf->urb = usb_alloc_urb(0, GFP_KERNEL);
-	if (!buf->urb)
+	urb = usb_alloc_urb(0, GFP_KERNEL);
+	if (!urb)
 		return -ENOMEM;
+	e->urb = urb;
 
 	if (dev->usb.sg_en) {
-		buf->urb->sg = devm_kcalloc(dev->dev, MT_SG_MAX_SIZE,
-					    sizeof(*buf->urb->sg),
-					    GFP_KERNEL);
-		if (!buf->urb->sg)
+		urb->sg = devm_kcalloc(dev->dev, MT_SG_MAX_SIZE,
+				       sizeof(urb->sg), GFP_KERNEL);
+		if (!urb->sg)
 			return -ENOMEM;
 
-		sg_init_table(buf->urb->sg, MT_SG_MAX_SIZE);
+		sg_init_table(urb->sg, MT_SG_MAX_SIZE);
 	}
 
-	return mt76u_refill_rx(dev, q, buf, MT_SG_MAX_SIZE, GFP_KERNEL);
+	return mt76u_refill_rx(dev, q, urb, MT_SG_MAX_SIZE, GFP_KERNEL);
 }
 
-static void mt76u_buf_free(struct mt76u_buf *buf)
+static void mt76u_urb_free(struct urb *urb)
 {
-	struct urb *urb = buf->urb;
 	int i;
 
 	for (i = 0; i < urb->num_sgs; i++)
@@ -369,12 +367,12 @@ static void mt76u_buf_free(struct mt76u_buf *buf)
 	if (urb->transfer_buffer)
 		skb_free_frag(urb->transfer_buffer);
 
-	usb_free_urb(buf->urb);
+	usb_free_urb(urb);
 }
 
 static void
 mt76u_fill_bulk_urb(struct mt76_dev *dev, int dir, int index,
-		    struct mt76u_buf *buf, usb_complete_t complete_fn,
+		    struct urb *urb, usb_complete_t complete_fn,
 		    void *context)
 {
 	struct usb_device *udev = to_usb_device(dev->dev);
@@ -385,27 +383,27 @@ static void mt76u_buf_free(struct mt76u_buf *buf)
 	else
 		pipe = usb_sndbulkpipe(udev, dev->usb.out_ep[index]);
 
-	buf->urb->dev = udev;
-	buf->urb->pipe = pipe;
-	buf->urb->complete = complete_fn;
-	buf->urb->context = context;
+	urb->dev = udev;
+	urb->pipe = pipe;
+	urb->complete = complete_fn;
+	urb->context = context;
 }
 
-static inline struct mt76u_buf
-*mt76u_get_next_rx_entry(struct mt76_queue *q)
+static inline struct urb *
+mt76u_get_next_rx_entry(struct mt76_queue *q)
 {
-	struct mt76u_buf *buf = NULL;
+	struct urb *urb = NULL;
 	unsigned long flags;
 
 	spin_lock_irqsave(&q->lock, flags);
 	if (q->queued > 0) {
-		buf = &q->entry[q->head].ubuf;
+		urb = q->entry[q->head].urb;
 		q->head = (q->head + 1) % q->ndesc;
 		q->queued--;
 	}
 	spin_unlock_irqrestore(&q->lock, flags);
 
-	return buf;
+	return urb;
 }
 
 static int mt76u_get_rx_entry_len(u8 *data, u32 data_len)
@@ -424,10 +422,9 @@ static int mt76u_get_rx_entry_len(u8 *data, u32 data_len)
 }
 
 static int
-mt76u_process_rx_entry(struct mt76_dev *dev, struct mt76u_buf *buf)
+mt76u_process_rx_entry(struct mt76_dev *dev, struct urb *urb)
 {
 	struct mt76_queue *q = &dev->q_rx[MT_RXQ_MAIN];
-	struct urb *urb = buf->urb;
 	u8 *data = urb->num_sgs ? sg_virt(&urb->sg[0]) : urb->transfer_buffer;
 	int data_len, len, nsgs = 1;
 	struct sk_buff *skb;
@@ -488,7 +485,7 @@ static void mt76u_complete_rx(struct urb *urb)
 	}
 
 	spin_lock_irqsave(&q->lock, flags);
-	if (WARN_ONCE(q->entry[q->tail].ubuf.urb != urb, "rx urb mismatch"))
+	if (WARN_ONCE(q->entry[q->tail].urb != urb, "rx urb mismatch"))
 		goto out;
 
 	q->tail = (q->tail + 1) % q->ndesc;
@@ -499,37 +496,37 @@ static void mt76u_complete_rx(struct urb *urb)
 }
 
 static int
-mt76u_submit_rx_buf(struct mt76_dev *dev, struct mt76u_buf *buf)
+mt76u_submit_rx_buf(struct mt76_dev *dev, struct urb *urb)
 {
-	mt76u_fill_bulk_urb(dev, USB_DIR_IN, MT_EP_IN_PKT_RX, buf,
+	mt76u_fill_bulk_urb(dev, USB_DIR_IN, MT_EP_IN_PKT_RX, urb,
 			    mt76u_complete_rx, dev);
-	trace_submit_urb(dev, buf->urb);
+	trace_submit_urb(dev, urb);
 
-	return usb_submit_urb(buf->urb, GFP_ATOMIC);
+	return usb_submit_urb(urb, GFP_ATOMIC);
 }
 
 static void mt76u_rx_tasklet(unsigned long data)
 {
 	struct mt76_dev *dev = (struct mt76_dev *)data;
 	struct mt76_queue *q = &dev->q_rx[MT_RXQ_MAIN];
-	struct mt76u_buf *buf;
+	struct urb *urb;
 	int err, count;
 
 	rcu_read_lock();
 
 	while (true) {
-		buf = mt76u_get_next_rx_entry(q);
-		if (!buf)
+		urb = mt76u_get_next_rx_entry(q);
+		if (!urb)
 			break;
 
-		count = mt76u_process_rx_entry(dev, buf);
+		count = mt76u_process_rx_entry(dev, urb);
 		if (count > 0) {
-			err = mt76u_refill_rx(dev, q, buf, count,
+			err = mt76u_refill_rx(dev, q, urb, count,
 					      GFP_ATOMIC);
 			if (err < 0)
 				break;
 		}
-		mt76u_submit_rx_buf(dev, buf);
+		mt76u_submit_rx_buf(dev, urb);
 	}
 	mt76_rx_poll_complete(dev, MT_RXQ_MAIN, NULL);
 
@@ -544,7 +541,7 @@ int mt76u_submit_rx_buffers(struct mt76_dev *dev)
 
 	spin_lock_irqsave(&q->lock, flags);
 	for (i = 0; i < q->ndesc; i++) {
-		err = mt76u_submit_rx_buf(dev, &q->entry[i].ubuf);
+		err = mt76u_submit_rx_buf(dev, q->entry[i].urb);
 		if (err < 0)
 			break;
 	}
@@ -576,7 +573,7 @@ static int mt76u_alloc_rx(struct mt76_dev *dev)
 	q->buf_size = dev->usb.sg_en ? MT_RX_BUF_SIZE : PAGE_SIZE;
 	q->ndesc = MT_NUM_RX_ENTRIES;
 	for (i = 0; i < q->ndesc; i++) {
-		err = mt76u_buf_alloc(dev, &q->entry[i].ubuf);
+		err = mt76u_urb_alloc(dev, &q->entry[i]);
 		if (err < 0)
 			return err;
 	}
@@ -591,7 +588,7 @@ static void mt76u_free_rx(struct mt76_dev *dev)
 	int i;
 
 	for (i = 0; i < q->ndesc; i++)
-		mt76u_buf_free(&q->entry[i].ubuf);
+		mt76u_urb_free(q->entry[i].urb);
 
 	if (!q->rx_page.va)
 		return;
@@ -607,7 +604,7 @@ static void mt76u_stop_rx(struct mt76_dev *dev)
 	int i;
 
 	for (i = 0; i < q->ndesc; i++)
-		usb_kill_urb(q->entry[i].ubuf.urb);
+		usb_kill_urb(q->entry[i].urb);
 }
 
 static void mt76u_tx_tasklet(unsigned long data)
@@ -718,7 +715,7 @@ static void mt76u_complete_tx(struct urb *urb)
 		   struct ieee80211_sta *sta)
 {
 	struct mt76_queue *q = dev->q_tx[qid].q;
-	struct mt76u_buf *buf;
+	struct urb *urb;
 	u16 idx = q->tail;
 	int err;
 
@@ -731,18 +728,18 @@ static void mt76u_complete_tx(struct urb *urb)
 		return err;
 
 	q->entry[idx].done = false;
-	buf = &q->entry[idx].ubuf;
+	urb = q->entry[idx].urb;
 	if (!dev->usb.sg_en) {
-		buf->urb->transfer_buffer = skb->data;
+		urb->transfer_buffer = skb->data;
 	} else {
-		err = mt76u_tx_build_sg(dev, skb, buf->urb);
+		err = mt76u_tx_build_sg(dev, skb, urb);
 		if (err < 0)
 			return err;
 	}
-	buf->urb->transfer_buffer_length = skb->len;
+	urb->transfer_buffer_length = skb->len;
 
 	mt76u_fill_bulk_urb(dev, USB_DIR_OUT, q2ep(q->hw_idx),
-			    buf, mt76u_complete_tx, &q->entry[idx]);
+			    urb, mt76u_complete_tx, &q->entry[idx]);
 
 	q->tail = (q->tail + 1) % q->ndesc;
 	q->entry[idx].skb = skb;
@@ -753,14 +750,14 @@ static void mt76u_complete_tx(struct urb *urb)
 
 static void mt76u_tx_kick(struct mt76_dev *dev, struct mt76_queue *q)
 {
-	struct mt76u_buf *buf;
+	struct urb *urb;
 	int err;
 
 	while (q->first != q->tail) {
-		buf = &q->entry[q->first].ubuf;
+		urb = q->entry[q->first].urb;
 
-		trace_submit_urb(dev, buf->urb);
-		err = usb_submit_urb(buf->urb, GFP_ATOMIC);
+		trace_submit_urb(dev, urb);
+		err = usb_submit_urb(urb, GFP_ATOMIC);
 		if (err < 0) {
 			if (err == -ENODEV)
 				set_bit(MT76_REMOVED, &dev->state);
@@ -775,7 +772,7 @@ static void mt76u_tx_kick(struct mt76_dev *dev, struct mt76_queue *q)
 
 static int mt76u_alloc_tx(struct mt76_dev *dev)
 {
-	struct mt76u_buf *buf;
+	struct urb *urb;
 	struct mt76_queue *q;
 	int i, j;
 
@@ -803,19 +800,18 @@ static int mt76u_alloc_tx(struct mt76_dev *dev)
 
 		q->ndesc = MT_NUM_TX_ENTRIES;
 		for (j = 0; j < q->ndesc; j++) {
-			buf = &q->entry[j].ubuf;
-
-			buf->urb = usb_alloc_urb(0, GFP_KERNEL);
-			if (!buf->urb)
+			urb = usb_alloc_urb(0, GFP_KERNEL);
+			if (!urb)
 				return -ENOMEM;
+			q->entry[j].urb = urb;
 
 			if (dev->usb.sg_en) {
 				size_t size = MT_SG_MAX_SIZE *
 					      sizeof(struct scatterlist);
 
-				buf->urb->sg = devm_kzalloc(dev->dev, size,
-							    GFP_KERNEL);
-				if (!buf->urb->sg)
+				urb->sg = devm_kzalloc(dev->dev, size,
+						       GFP_KERNEL);
+				if (!urb->sg)
 					return -ENOMEM;
 			}
 		}
@@ -831,7 +827,7 @@ static void mt76u_free_tx(struct mt76_dev *dev)
 	for (i = 0; i < IEEE80211_NUM_ACS; i++) {
 		q = dev->q_tx[i].q;
 		for (j = 0; j < q->ndesc; j++)
-			usb_free_urb(q->entry[j].ubuf.urb);
+			usb_free_urb(q->entry[j].urb);
 	}
 }
 
@@ -843,7 +839,7 @@ static void mt76u_stop_tx(struct mt76_dev *dev)
 	for (i = 0; i < IEEE80211_NUM_ACS; i++) {
 		q = dev->q_tx[i].q;
 		for (j = 0; j < q->ndesc; j++)
-			usb_kill_urb(q->entry[j].ubuf.urb);
+			usb_kill_urb(q->entry[j].urb);
 	}
 }
 
-- 
1.9.3


^ permalink raw reply related

* [RFC 08/12] mt76usb: remove MT_RXQ_MAIN queue from mt76u_urb_alloc
From: Stanislaw Gruszka @ 2019-03-12 15:06 UTC (permalink / raw)
  To: linux-wireless; +Cc: Felix Fietkau, Lorenzo Bianconi, Stanislaw Gruszka
In-Reply-To: <1552403166-3821-1-git-send-email-sgruszka@redhat.com>

Get the RX queue inside mt76u_refill_rx. This will allow to reuse
mt76u_urb_alloc for TX allocations.

Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
---
 drivers/net/wireless/mediatek/mt76/usb.c | 19 ++++++++-----------
 1 file changed, 8 insertions(+), 11 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/usb.c b/drivers/net/wireless/mediatek/mt76/usb.c
index 2c21f4773a19..ca62ddc03be2 100644
--- a/drivers/net/wireless/mediatek/mt76/usb.c
+++ b/drivers/net/wireless/mediatek/mt76/usb.c
@@ -283,12 +283,10 @@ static bool mt76u_check_sg(struct mt76_dev *dev)
 }
 
 static int
-mt76u_fill_rx_sg(struct mt76_dev *dev, struct urb *urb, int nsgs,
-		 gfp_t gfp)
+mt76u_fill_rx_sg(struct mt76_dev *dev, struct mt76_queue *q, struct urb *urb,
+		 int nsgs, gfp_t gfp)
 {
-	struct mt76_queue *q = &dev->q_rx[MT_RXQ_MAIN];
 	int sglen = SKB_WITH_OVERHEAD(q->buf_size);
-
 	int i;
 
 	for (i = 0; i < nsgs; i++) {
@@ -321,11 +319,12 @@ static bool mt76u_check_sg(struct mt76_dev *dev)
 }
 
 static int
-mt76u_refill_rx(struct mt76_dev *dev, struct mt76_queue *q,
-		struct urb *urb, int nsgs, gfp_t gfp)
+mt76u_refill_rx(struct mt76_dev *dev, struct urb *urb, int nsgs, gfp_t gfp)
 {
+	struct mt76_queue *q = &dev->q_rx[MT_RXQ_MAIN];
+
 	if (dev->usb.sg_en) {
-		return mt76u_fill_rx_sg(dev, urb, nsgs, gfp);
+		return mt76u_fill_rx_sg(dev, q, urb, nsgs, gfp);
 	} else {
 		urb->transfer_buffer_length = SKB_WITH_OVERHEAD(q->buf_size);
 		urb->transfer_buffer = page_frag_alloc(&q->rx_page,
@@ -337,7 +336,6 @@ static bool mt76u_check_sg(struct mt76_dev *dev)
 static int
 mt76u_urb_alloc(struct mt76_dev *dev, struct mt76_queue_entry *e)
 {
-	struct mt76_queue *q = &dev->q_rx[MT_RXQ_MAIN];
 	struct urb *urb;
 
 	urb = usb_alloc_urb(0, GFP_KERNEL);
@@ -354,7 +352,7 @@ static bool mt76u_check_sg(struct mt76_dev *dev)
 		sg_init_table(urb->sg, MT_SG_MAX_SIZE);
 	}
 
-	return mt76u_refill_rx(dev, q, urb, MT_SG_MAX_SIZE, GFP_KERNEL);
+	return mt76u_refill_rx(dev, urb, MT_SG_MAX_SIZE, GFP_KERNEL);
 }
 
 static void mt76u_urb_free(struct urb *urb)
@@ -521,8 +519,7 @@ static void mt76u_rx_tasklet(unsigned long data)
 
 		count = mt76u_process_rx_entry(dev, urb);
 		if (count > 0) {
-			err = mt76u_refill_rx(dev, q, urb, count,
-					      GFP_ATOMIC);
+			err = mt76u_refill_rx(dev, urb, count, GFP_ATOMIC);
 			if (err < 0)
 				break;
 		}
-- 
1.9.3


^ permalink raw reply related

* [RFC 09/12] mt76usb: resue mt76u_urb_alloc for tx
From: Stanislaw Gruszka @ 2019-03-12 15:06 UTC (permalink / raw)
  To: linux-wireless; +Cc: Felix Fietkau, Lorenzo Bianconi, Stanislaw Gruszka
In-Reply-To: <1552403166-3821-1-git-send-email-sgruszka@redhat.com>

Add new rx_urb_alloc routine and reuse common urb_alloc for tx
allocations.

Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
---
 drivers/net/wireless/mediatek/mt76/usb.c | 36 ++++++++++++++++----------------
 1 file changed, 18 insertions(+), 18 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/usb.c b/drivers/net/wireless/mediatek/mt76/usb.c
index ca62ddc03be2..64fac91f1a72 100644
--- a/drivers/net/wireless/mediatek/mt76/usb.c
+++ b/drivers/net/wireless/mediatek/mt76/usb.c
@@ -352,7 +352,19 @@ static bool mt76u_check_sg(struct mt76_dev *dev)
 		sg_init_table(urb->sg, MT_SG_MAX_SIZE);
 	}
 
-	return mt76u_refill_rx(dev, urb, MT_SG_MAX_SIZE, GFP_KERNEL);
+	return 0;
+}
+
+static int
+mt76u_rx_urb_alloc(struct mt76_dev *dev, struct mt76_queue_entry *e)
+{
+	int err;
+
+	err = mt76u_urb_alloc(dev, e);
+	if (err)
+		return err;
+
+	return mt76u_refill_rx(dev, e->urb, MT_SG_MAX_SIZE, GFP_KERNEL);
 }
 
 static void mt76u_urb_free(struct urb *urb)
@@ -570,7 +582,7 @@ static int mt76u_alloc_rx(struct mt76_dev *dev)
 	q->buf_size = dev->usb.sg_en ? MT_RX_BUF_SIZE : PAGE_SIZE;
 	q->ndesc = MT_NUM_RX_ENTRIES;
 	for (i = 0; i < q->ndesc; i++) {
-		err = mt76u_urb_alloc(dev, &q->entry[i]);
+		err = mt76u_rx_urb_alloc(dev, &q->entry[i]);
 		if (err < 0)
 			return err;
 	}
@@ -769,9 +781,8 @@ static void mt76u_tx_kick(struct mt76_dev *dev, struct mt76_queue *q)
 
 static int mt76u_alloc_tx(struct mt76_dev *dev)
 {
-	struct urb *urb;
 	struct mt76_queue *q;
-	int i, j;
+	int i, j, err;
 
 	for (i = 0; i <= MT_TXQ_PSD; i++) {
 		INIT_LIST_HEAD(&dev->q_tx[i].swq);
@@ -797,20 +808,9 @@ static int mt76u_alloc_tx(struct mt76_dev *dev)
 
 		q->ndesc = MT_NUM_TX_ENTRIES;
 		for (j = 0; j < q->ndesc; j++) {
-			urb = usb_alloc_urb(0, GFP_KERNEL);
-			if (!urb)
-				return -ENOMEM;
-			q->entry[j].urb = urb;
-
-			if (dev->usb.sg_en) {
-				size_t size = MT_SG_MAX_SIZE *
-					      sizeof(struct scatterlist);
-
-				urb->sg = devm_kzalloc(dev->dev, size,
-						       GFP_KERNEL);
-				if (!urb->sg)
-					return -ENOMEM;
-			}
+			err = mt76u_urb_alloc(dev, &q->entry[j]);
+			if (err < 0)
+				return err;
 		}
 	}
 	return 0;
-- 
1.9.3


^ permalink raw reply related

* [RFC 10/12] mt76usb: remove unneded sg_init_table
From: Stanislaw Gruszka @ 2019-03-12 15:06 UTC (permalink / raw)
  To: linux-wireless; +Cc: Felix Fietkau, Lorenzo Bianconi, Stanislaw Gruszka
In-Reply-To: <1552403166-3821-1-git-send-email-sgruszka@redhat.com>

We already allocate with GFP_ZERO and sg marker is set later for
both RX and TX.

Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
---
 drivers/net/wireless/mediatek/mt76/usb.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/usb.c b/drivers/net/wireless/mediatek/mt76/usb.c
index 64fac91f1a72..0b9f0b5fd37d 100644
--- a/drivers/net/wireless/mediatek/mt76/usb.c
+++ b/drivers/net/wireless/mediatek/mt76/usb.c
@@ -348,8 +348,6 @@ static bool mt76u_check_sg(struct mt76_dev *dev)
 				       sizeof(urb->sg), GFP_KERNEL);
 		if (!urb->sg)
 			return -ENOMEM;
-
-		sg_init_table(urb->sg, MT_SG_MAX_SIZE);
 	}
 
 	return 0;
-- 
1.9.3


^ permalink raw reply related

* [RFC 11/12] mt76usb: allocate urb and sg as linear data
From: Stanislaw Gruszka @ 2019-03-12 15:06 UTC (permalink / raw)
  To: linux-wireless; +Cc: Felix Fietkau, Lorenzo Bianconi, Stanislaw Gruszka
In-Reply-To: <1552403166-3821-1-git-send-email-sgruszka@redhat.com>

Alloc sg table at the end of urb structure. This will increase
cache usage.

Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
---
 drivers/net/wireless/mediatek/mt76/usb.c | 20 ++++++++++----------
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/usb.c b/drivers/net/wireless/mediatek/mt76/usb.c
index 0b9f0b5fd37d..dd487f65f44e 100644
--- a/drivers/net/wireless/mediatek/mt76/usb.c
+++ b/drivers/net/wireless/mediatek/mt76/usb.c
@@ -336,19 +336,19 @@ static bool mt76u_check_sg(struct mt76_dev *dev)
 static int
 mt76u_urb_alloc(struct mt76_dev *dev, struct mt76_queue_entry *e)
 {
-	struct urb *urb;
+	unsigned int size = sizeof(struct urb);
+
+	if (dev->usb.sg_en)
+		size += MT_SG_MAX_SIZE * sizeof(struct scatterlist);
 
-	urb = usb_alloc_urb(0, GFP_KERNEL);
-	if (!urb)
+	e->urb = kzalloc(size, GFP_KERNEL);
+	if (!e->urb)
 		return -ENOMEM;
-	e->urb = urb;
 
-	if (dev->usb.sg_en) {
-		urb->sg = devm_kcalloc(dev->dev, MT_SG_MAX_SIZE,
-				       sizeof(urb->sg), GFP_KERNEL);
-		if (!urb->sg)
-			return -ENOMEM;
-	}
+	usb_init_urb(e->urb);
+
+	if (dev->usb.sg_en)
+		e->urb->sg = (struct scatterlist *)((u8 *)e->urb + sizeof(struct urb));
 
 	return 0;
 }
-- 
1.9.3


^ permalink raw reply related

* [RFC 12/12] mt76usb: remove queue variable from rx_tasklet
From: Stanislaw Gruszka @ 2019-03-12 15:06 UTC (permalink / raw)
  To: linux-wireless; +Cc: Felix Fietkau, Lorenzo Bianconi, Stanislaw Gruszka
In-Reply-To: <1552403166-3821-1-git-send-email-sgruszka@redhat.com>

Since now only mt76u_get_next_rx_entry use queue argument move
it to this function.

Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
---
 drivers/net/wireless/mediatek/mt76/usb.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/usb.c b/drivers/net/wireless/mediatek/mt76/usb.c
index dd487f65f44e..6a23e1852d2a 100644
--- a/drivers/net/wireless/mediatek/mt76/usb.c
+++ b/drivers/net/wireless/mediatek/mt76/usb.c
@@ -398,8 +398,9 @@ static void mt76u_urb_free(struct urb *urb)
 }
 
 static inline struct urb *
-mt76u_get_next_rx_entry(struct mt76_queue *q)
+mt76u_get_next_rx_entry(struct mt76_dev *dev)
 {
+	struct mt76_queue *q = &dev->q_rx[MT_RXQ_MAIN];
 	struct urb *urb = NULL;
 	unsigned long flags;
 
@@ -516,14 +517,13 @@ static void mt76u_complete_rx(struct urb *urb)
 static void mt76u_rx_tasklet(unsigned long data)
 {
 	struct mt76_dev *dev = (struct mt76_dev *)data;
-	struct mt76_queue *q = &dev->q_rx[MT_RXQ_MAIN];
 	struct urb *urb;
 	int err, count;
 
 	rcu_read_lock();
 
 	while (true) {
-		urb = mt76u_get_next_rx_entry(q);
+		urb = mt76u_get_next_rx_entry(dev);
 		if (!urb)
 			break;
 
-- 
1.9.3


^ permalink raw reply related

* Re: [PATCH] iommu/amd: fix sg->dma_address for sg->offset bigger than PAGE_SIZE
From: Alexander Duyck @ 2019-03-12 15:18 UTC (permalink / raw)
  To: Stanislaw Gruszka
  Cc: Rosen Penev, Joerg Roedel, Lorenzo Bianconi, linux-wireless,
	Samuel Sieb, iommu, linux-kernel, linux-nvme, jan.viktorin
In-Reply-To: <20190312070832.GA2483@redhat.com>

On Tue, 2019-03-12 at 08:08 +0100, Stanislaw Gruszka wrote:
> On Mon, Mar 11, 2019 at 08:47:44AM -0700, Alexander Duyck wrote:
> > >  drivers/iommu/amd_iommu.c | 2 +-
> > >  1 file changed, 1 insertion(+), 1 deletion(-)
> > > 
> > > diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c
> > > index 6b0760dafb3e..949621f33624 100644
> > > --- a/drivers/iommu/amd_iommu.c
> > > +++ b/drivers/iommu/amd_iommu.c
> > > @@ -2604,7 +2604,7 @@ static int map_sg(struct device *dev, struct scatterlist *sglist,
> > >  
> > >  	/* Everything is mapped - write the right values into s->dma_address */
> > >  	for_each_sg(sglist, s, nelems, i) {
> > > -		s->dma_address += address + s->offset;
> > > +		s->dma_address += address + (s->offset & ~PAGE_MASK);
> > >  		s->dma_length   = s->length;
> > >  	}
> > >  
> > 
> > You should add a comment calling out that this is needed because the
> > sg_phys(s) call above this is masked with PAGE_MASK. Then this makes
> > much more sense. Otherwise I would have assumed you needed either the
> > full offset or none.
> 
> Would something like this 
> 
> /*
>  * Everything is mapped - write the right values into s->dma_address. 
>  * Take into account s->offset can be bigger than page size and sg_phys(s)
>  * address has to be aligned to page granularity.
>  */
> 
> be appropriate ?
> 
> Stanislaw
> 

No, that isn't a good description. If you take a look at the code a few
lines up you find:
	phys_addr = (sg_phys(s) & PAGE_MASK) + (j << PAGE_SHIFT);

Now if I am not mistaken the whole reason why you are having to make
the change here is because the application of PAGE_MASK in this line.
Basically what sg_phys() will do is take the address of the page,
convert it to a physical address and add the offset. However what the
mask is doing is limiting how much of that offset can be added. As a
result you have to add the remainder that was masked out. So maybe a
better comment would be something like:

/*
 * Add in the remaining piece of the scatter-gather offset that was 
 * masked out when we were determining the physical address via
 * (sg_phys(s) & PAGE_MASK) earlier.
 */




^ permalink raw reply

* Re: [PATCH] rtlwifi: fix potential NULL pointer dereference
From: Kangjie Lu @ 2019-03-12 15:20 UTC (permalink / raw)
  To: pkshih, kvalo; +Cc: linux-wireless, Larry.Finger
In-Reply-To: <20190312090648.30750-1-pkshih@realtek.com>

Thanks for reporting the cases. There are still a few more such
cases; we will report them soon.

On 3/12/19 4:06 AM, pkshih@realtek.com wrote:
> From: Ping-Ke Shih <pkshih@realtek.com>
>
> In case dev_alloc_skb fails, the fix safely returns to avoid
> potential NULL pointer dereference.
>
> Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
> ---
>   drivers/net/wireless/realtek/rtlwifi/rtl8188ee/fw.c       | 2 ++
>   drivers/net/wireless/realtek/rtlwifi/rtl8192c/fw_common.c | 2 ++
>   drivers/net/wireless/realtek/rtlwifi/rtl8192ee/fw.c       | 2 ++
>   drivers/net/wireless/realtek/rtlwifi/rtl8723ae/fw.c       | 2 ++
>   drivers/net/wireless/realtek/rtlwifi/rtl8723be/fw.c       | 2 ++
>   drivers/net/wireless/realtek/rtlwifi/rtl8821ae/fw.c       | 4 ++++
>   6 files changed, 14 insertions(+)
>
> diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/fw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/fw.c
> index 203e7b574e84..e2e0bfbc24fe 100644
> --- a/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/fw.c
> +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/fw.c
> @@ -600,6 +600,8 @@ void rtl88e_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool b_dl_finished)
>   		      u1rsvdpageloc, 3);
>   
>   	skb = dev_alloc_skb(totalpacketlen);
> +	if (!skb)
> +		return;
>   	skb_put_data(skb, &reserved_page_packet, totalpacketlen);
>   
>   	rtstatus = rtl_cmd_send_packet(hw, skb);
> diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192c/fw_common.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192c/fw_common.c
> index 18c76990a089..86b1b88cc4ed 100644
> --- a/drivers/net/wireless/realtek/rtlwifi/rtl8192c/fw_common.c
> +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192c/fw_common.c
> @@ -623,6 +623,8 @@ void rtl92c_set_fw_rsvdpagepkt(struct ieee80211_hw *hw,
>   		      u1rsvdpageloc, 3);
>   
>   	skb = dev_alloc_skb(totalpacketlen);
> +	if (!skb)
> +		return;
>   	skb_put_data(skb, &reserved_page_packet, totalpacketlen);
>   
>   	if (cmd_send_packet)
> diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/fw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/fw.c
> index 7c5b54b71a92..67305ce915ec 100644
> --- a/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/fw.c
> +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/fw.c
> @@ -744,6 +744,8 @@ void rtl92ee_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool b_dl_finished)
>   		      u1rsvdpageloc, 3);
>   
>   	skb = dev_alloc_skb(totalpacketlen);
> +	if (!skb)
> +		return;
>   	skb_put_data(skb, &reserved_page_packet, totalpacketlen);
>   
>   	rtstatus = rtl_cmd_send_packet(hw, skb);
> diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/fw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/fw.c
> index be451a6f7dbe..33481232fad0 100644
> --- a/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/fw.c
> +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/fw.c
> @@ -448,6 +448,8 @@ void rtl8723e_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool b_dl_finished)
>   		      u1rsvdpageloc, 3);
>   
>   	skb = dev_alloc_skb(totalpacketlen);
> +	if (!skb)
> +		return;
>   	skb_put_data(skb, &reserved_page_packet, totalpacketlen);
>   
>   	rtstatus = rtl_cmd_send_packet(hw, skb);
> diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8723be/fw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/fw.c
> index 4d7fa27f55ca..aa56058af56e 100644
> --- a/drivers/net/wireless/realtek/rtlwifi/rtl8723be/fw.c
> +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/fw.c
> @@ -562,6 +562,8 @@ void rtl8723be_set_fw_rsvdpagepkt(struct ieee80211_hw *hw,
>   		      u1rsvdpageloc, sizeof(u1rsvdpageloc));
>   
>   	skb = dev_alloc_skb(totalpacketlen);
> +	if (!skb)
> +		return;
>   	skb_put_data(skb, &reserved_page_packet, totalpacketlen);
>   
>   	rtstatus = rtl_cmd_send_packet(hw, skb);
> diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/fw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/fw.c
> index dc0eb692088f..fe32d397d287 100644
> --- a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/fw.c
> +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/fw.c
> @@ -1623,6 +1623,8 @@ void rtl8812ae_set_fw_rsvdpagepkt(struct ieee80211_hw *hw,
>   		      &reserved_page_packet_8812[0], totalpacketlen);
>   
>   	skb = dev_alloc_skb(totalpacketlen);
> +	if (!skb)
> +		return;
>   	skb_put_data(skb, &reserved_page_packet_8812, totalpacketlen);
>   
>   	rtstatus = rtl_cmd_send_packet(hw, skb);
> @@ -1759,6 +1761,8 @@ void rtl8821ae_set_fw_rsvdpagepkt(struct ieee80211_hw *hw,
>   		      &reserved_page_packet_8821[0], totalpacketlen);
>   
>   	skb = dev_alloc_skb(totalpacketlen);
> +	if (!skb)
> +		return;
>   	skb_put_data(skb, &reserved_page_packet_8821, totalpacketlen);
>   
>   	rtstatus = rtl_cmd_send_packet(hw, skb);

^ permalink raw reply

* Re: [PATCH 0/5] introduce mt76_sw_queue data structure
From: Felix Fietkau @ 2019-03-12 15:59 UTC (permalink / raw)
  To: Lorenzo Bianconi
  Cc: linux-wireless, sgruszka, lorenzo.bianconi, roychl666, ryder.lee
In-Reply-To: <cover.1551533068.git.lorenzo@kernel.org>

On 2019-03-02 14:47, Lorenzo Bianconi wrote:
> Add mt76_sw_queue data structure in order to support new
> chipsets (e.g. mt7615) that have a shared hardware queue for all traffic
> identifiers. mt76_sw_queue is used to track outstanding packets.
> Add mt76_txq_id field to mt76_queue_entry in order to properly
> track outstanding frames
> 
> Lorenzo Bianconi (5):
>   mt76: remove mt76_queue dependency from tx_queue_skb function pointer
>   mt76: remove mt76_queue dependency from tx_prepare_skb function
>     pointer
>   mt76: remove mt76_queue dependency from tx_complete_skb function
>     pointer
>   mt76: introduce mt76_sw_queue data structure
>   mt76: introduce mt76_txq_id field in mt76_queue_entry
Applied, thanks.

- Felix

^ permalink raw reply

* Re: [RFC 05/12] mt76usb: remove mt76u_buf redundant fileds
From: Lorenzo Bianconi @ 2019-03-12 16:25 UTC (permalink / raw)
  To: Stanislaw Gruszka; +Cc: linux-wireless, Felix Fietkau
In-Reply-To: <1552403166-3821-6-git-send-email-sgruszka@redhat.com>

[-- Attachment #1: Type: text/plain, Size: 3038 bytes --]

> Remove mt76u_buf->{len, buf} fields and operate on corresponding
> urb fields directly.
> 
> Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
> ---
>  drivers/net/wireless/mediatek/mt76/mt76.h |  2 --
>  drivers/net/wireless/mediatek/mt76/usb.c  | 40 +++++++++++++++++--------------
>  2 files changed, 22 insertions(+), 20 deletions(-)
> 
> diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h
> index 89cdfe4abf33..476cb39c99b7 100644
> --- a/drivers/net/wireless/mediatek/mt76/mt76.h
> +++ b/drivers/net/wireless/mediatek/mt76/mt76.h
> @@ -85,8 +85,6 @@ struct mt76_queue_buf {
>  

[...]

> @@ -377,7 +378,6 @@ static void mt76u_buf_free(struct mt76u_buf *buf)
>  		    void *context)
>  {
>  	struct usb_device *udev = to_usb_device(dev->dev);
> -	u8 *data = buf->urb->num_sgs ? NULL : buf->buf;
>  	unsigned int pipe;
>  
>  	if (dir == USB_DIR_IN)
> @@ -385,8 +385,10 @@ static void mt76u_buf_free(struct mt76u_buf *buf)
>  	else
>  		pipe = usb_sndbulkpipe(udev, dev->usb.out_ep[index]);
>  
> -	usb_fill_bulk_urb(buf->urb, udev, pipe, data, buf->len,
> -			  complete_fn, context);
> +	buf->urb->dev = udev;
> +	buf->urb->pipe = pipe;
> +	buf->urb->complete = complete_fn;
> +	buf->urb->context = context;
>  }
>  
>  static inline struct mt76u_buf
> @@ -426,7 +428,7 @@ static int mt76u_get_rx_entry_len(u8 *data, u32 data_len)
>  {
>  	struct mt76_queue *q = &dev->q_rx[MT_RXQ_MAIN];
>  	struct urb *urb = buf->urb;
> -	u8 *data = urb->num_sgs ? sg_virt(&urb->sg[0]) : buf->buf;
> +	u8 *data = urb->num_sgs ? sg_virt(&urb->sg[0]) : urb->transfer_buffer;
>  	int data_len, len, nsgs = 1;
>  	struct sk_buff *skb;
>  
> @@ -437,7 +439,7 @@ static int mt76u_get_rx_entry_len(u8 *data, u32 data_len)
>  	if (len < 0)
>  		return 0;
>  
> -	data_len = urb->num_sgs ? urb->sg[0].length : buf->len;
> +	data_len = urb->num_sgs ? urb->sg[0].length : INT_MAX;

In this way we only use len, maybe better to do:
	data_len = urb->num_sgs ? urb->sg[0].length :
				  SKB_WITH_OVERHEAD(q->buf_size)

>  	data_len = min_t(int, len, data_len - MT_DMA_HDR_LEN);
>  	if (MT_DMA_HDR_LEN + data_len > SKB_WITH_OVERHEAD(q->buf_size))
>  		return 0;
> @@ -731,14 +733,16 @@ static void mt76u_complete_tx(struct urb *urb)
>  		return err;
>  
>  	buf = &q->entry[idx].ubuf;
> -	buf->buf = skb->data;
> -	buf->len = skb->len;
> +	if (!dev->usb.sg_en) {
> +		buf->urb->transfer_buffer = skb->data;

I think you can move this in mt76u_tx_build_sg or remove the if condition in
mt76u_tx_build_sg()

Regards,
Lorenzo

> +	} else {
> +		err = mt76u_tx_build_sg(dev, skb, buf->urb);
> +		if (err < 0)
> +			return err;
> +	}
> +	buf->urb->transfer_buffer_length = skb->len;
>  	buf->done = false;
>  
> -	err = mt76u_tx_build_sg(dev, skb, buf->urb);
> -	if (err < 0)
> -		return err;
> -
>  	mt76u_fill_bulk_urb(dev, USB_DIR_OUT, q2ep(q->hw_idx),
>  			    buf, mt76u_complete_tx, buf);
>  
> -- 
> 1.9.3
> 

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

^ permalink raw reply

* Re: [RFC 07/12] mt76usb: remove mt76u_buf and use urb directly
From: Lorenzo Bianconi @ 2019-03-12 16:27 UTC (permalink / raw)
  To: Stanislaw Gruszka; +Cc: linux-wireless, Felix Fietkau
In-Reply-To: <1552403166-3821-8-git-send-email-sgruszka@redhat.com>

[-- Attachment #1: Type: text/plain, Size: 11997 bytes --]

> Put urb pointer in mt76_queue_entry directly instead of mt76u_buf
> structure.
> 
> Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
> ---
>  drivers/net/wireless/mediatek/mt76/mt76.h |   6 +-
>  drivers/net/wireless/mediatek/mt76/usb.c  | 132 +++++++++++++++---------------
>  2 files changed, 65 insertions(+), 73 deletions(-)
> 
> diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h
> index 998505064dee..859d0325583b 100644
> --- a/drivers/net/wireless/mediatek/mt76/mt76.h
> +++ b/drivers/net/wireless/mediatek/mt76/mt76.h
> @@ -83,10 +83,6 @@ struct mt76_queue_buf {
>  	int len;
>  };
>  
> -struct mt76u_buf {
> -	struct urb *urb;
> -};
> -
>  struct mt76_queue_entry {
>  	union {
>  		void *buf;
> @@ -94,7 +90,7 @@ struct mt76_queue_entry {
>  	};
>  	union {
>  		struct mt76_txwi_cache *txwi;
> -		struct mt76u_buf ubuf;
> +		struct urb *urb;
>  	};
>  	enum mt76_txq_id qid;
>  	bool schedule;
> diff --git a/drivers/net/wireless/mediatek/mt76/usb.c b/drivers/net/wireless/mediatek/mt76/usb.c
> index a4ef9bb1603d..2c21f4773a19 100644
> --- a/drivers/net/wireless/mediatek/mt76/usb.c
> +++ b/drivers/net/wireless/mediatek/mt76/usb.c
> @@ -283,12 +283,11 @@ static bool mt76u_check_sg(struct mt76_dev *dev)
>  }
>  
>  static int
> -mt76u_fill_rx_sg(struct mt76_dev *dev, struct mt76u_buf *buf, int nsgs,
> +mt76u_fill_rx_sg(struct mt76_dev *dev, struct urb *urb, int nsgs,
>  		 gfp_t gfp)
>  {
>  	struct mt76_queue *q = &dev->q_rx[MT_RXQ_MAIN];
>  	int sglen = SKB_WITH_OVERHEAD(q->buf_size);
> -	struct urb *urb = buf->urb;
>  
>  	int i;
>  
> @@ -323,44 +322,43 @@ static bool mt76u_check_sg(struct mt76_dev *dev)
>  
>  static int
>  mt76u_refill_rx(struct mt76_dev *dev, struct mt76_queue *q,
> -		struct mt76u_buf *buf, int nsgs, gfp_t gfp)
> +		struct urb *urb, int nsgs, gfp_t gfp)
>  {
>  	if (dev->usb.sg_en) {
> -		return mt76u_fill_rx_sg(dev, buf, nsgs, gfp);
> +		return mt76u_fill_rx_sg(dev, urb, nsgs, gfp);
>  	} else {
> -		buf->urb->transfer_buffer_length =
> -			SKB_WITH_OVERHEAD(q->buf_size);
> -		buf->urb->transfer_buffer =
> -			page_frag_alloc(&q->rx_page, q->buf_size, gfp);
> -		return buf->urb->transfer_buffer ? 0 : -ENOMEM;
> +		urb->transfer_buffer_length = SKB_WITH_OVERHEAD(q->buf_size);
> +		urb->transfer_buffer = page_frag_alloc(&q->rx_page,
> +						       q->buf_size, gfp);
> +		return urb->transfer_buffer ? 0 : -ENOMEM;
>  	}
>  }
>  
>  static int
> -mt76u_buf_alloc(struct mt76_dev *dev, struct mt76u_buf *buf)
> +mt76u_urb_alloc(struct mt76_dev *dev, struct mt76_queue_entry *e)
>  {
>  	struct mt76_queue *q = &dev->q_rx[MT_RXQ_MAIN];
> +	struct urb *urb;
>  
> -	buf->urb = usb_alloc_urb(0, GFP_KERNEL);
> -	if (!buf->urb)
> +	urb = usb_alloc_urb(0, GFP_KERNEL);

I guess here you can do:
	e->urb = usb_alloc_urb(0, GFP_KERNEL);
	if (!e->urb)
		return -ENOMEM;

Regards,
Lorenzo

> +	if (!urb)
>  		return -ENOMEM;
> +	e->urb = urb;
>  
>  	if (dev->usb.sg_en) {
> -		buf->urb->sg = devm_kcalloc(dev->dev, MT_SG_MAX_SIZE,
> -					    sizeof(*buf->urb->sg),
> -					    GFP_KERNEL);
> -		if (!buf->urb->sg)
> +		urb->sg = devm_kcalloc(dev->dev, MT_SG_MAX_SIZE,
> +				       sizeof(urb->sg), GFP_KERNEL);
> +		if (!urb->sg)
>  			return -ENOMEM;
>  
> -		sg_init_table(buf->urb->sg, MT_SG_MAX_SIZE);
> +		sg_init_table(urb->sg, MT_SG_MAX_SIZE);
>  	}
>  
> -	return mt76u_refill_rx(dev, q, buf, MT_SG_MAX_SIZE, GFP_KERNEL);
> +	return mt76u_refill_rx(dev, q, urb, MT_SG_MAX_SIZE, GFP_KERNEL);
>  }
>  
> -static void mt76u_buf_free(struct mt76u_buf *buf)
> +static void mt76u_urb_free(struct urb *urb)
>  {
> -	struct urb *urb = buf->urb;
>  	int i;
>  
>  	for (i = 0; i < urb->num_sgs; i++)
> @@ -369,12 +367,12 @@ static void mt76u_buf_free(struct mt76u_buf *buf)
>  	if (urb->transfer_buffer)
>  		skb_free_frag(urb->transfer_buffer);
>  
> -	usb_free_urb(buf->urb);
> +	usb_free_urb(urb);
>  }
>  
>  static void
>  mt76u_fill_bulk_urb(struct mt76_dev *dev, int dir, int index,
> -		    struct mt76u_buf *buf, usb_complete_t complete_fn,
> +		    struct urb *urb, usb_complete_t complete_fn,
>  		    void *context)
>  {
>  	struct usb_device *udev = to_usb_device(dev->dev);
> @@ -385,27 +383,27 @@ static void mt76u_buf_free(struct mt76u_buf *buf)
>  	else
>  		pipe = usb_sndbulkpipe(udev, dev->usb.out_ep[index]);
>  
> -	buf->urb->dev = udev;
> -	buf->urb->pipe = pipe;
> -	buf->urb->complete = complete_fn;
> -	buf->urb->context = context;
> +	urb->dev = udev;
> +	urb->pipe = pipe;
> +	urb->complete = complete_fn;
> +	urb->context = context;
>  }
>  
> -static inline struct mt76u_buf
> -*mt76u_get_next_rx_entry(struct mt76_queue *q)
> +static inline struct urb *
> +mt76u_get_next_rx_entry(struct mt76_queue *q)
>  {
> -	struct mt76u_buf *buf = NULL;
> +	struct urb *urb = NULL;
>  	unsigned long flags;
>  
>  	spin_lock_irqsave(&q->lock, flags);
>  	if (q->queued > 0) {
> -		buf = &q->entry[q->head].ubuf;
> +		urb = q->entry[q->head].urb;
>  		q->head = (q->head + 1) % q->ndesc;
>  		q->queued--;
>  	}
>  	spin_unlock_irqrestore(&q->lock, flags);
>  
> -	return buf;
> +	return urb;
>  }
>  
>  static int mt76u_get_rx_entry_len(u8 *data, u32 data_len)
> @@ -424,10 +422,9 @@ static int mt76u_get_rx_entry_len(u8 *data, u32 data_len)
>  }
>  
>  static int
> -mt76u_process_rx_entry(struct mt76_dev *dev, struct mt76u_buf *buf)
> +mt76u_process_rx_entry(struct mt76_dev *dev, struct urb *urb)
>  {
>  	struct mt76_queue *q = &dev->q_rx[MT_RXQ_MAIN];
> -	struct urb *urb = buf->urb;
>  	u8 *data = urb->num_sgs ? sg_virt(&urb->sg[0]) : urb->transfer_buffer;
>  	int data_len, len, nsgs = 1;
>  	struct sk_buff *skb;
> @@ -488,7 +485,7 @@ static void mt76u_complete_rx(struct urb *urb)
>  	}
>  
>  	spin_lock_irqsave(&q->lock, flags);
> -	if (WARN_ONCE(q->entry[q->tail].ubuf.urb != urb, "rx urb mismatch"))
> +	if (WARN_ONCE(q->entry[q->tail].urb != urb, "rx urb mismatch"))
>  		goto out;
>  
>  	q->tail = (q->tail + 1) % q->ndesc;
> @@ -499,37 +496,37 @@ static void mt76u_complete_rx(struct urb *urb)
>  }
>  
>  static int
> -mt76u_submit_rx_buf(struct mt76_dev *dev, struct mt76u_buf *buf)
> +mt76u_submit_rx_buf(struct mt76_dev *dev, struct urb *urb)
>  {
> -	mt76u_fill_bulk_urb(dev, USB_DIR_IN, MT_EP_IN_PKT_RX, buf,
> +	mt76u_fill_bulk_urb(dev, USB_DIR_IN, MT_EP_IN_PKT_RX, urb,
>  			    mt76u_complete_rx, dev);
> -	trace_submit_urb(dev, buf->urb);
> +	trace_submit_urb(dev, urb);
>  
> -	return usb_submit_urb(buf->urb, GFP_ATOMIC);
> +	return usb_submit_urb(urb, GFP_ATOMIC);
>  }
>  
>  static void mt76u_rx_tasklet(unsigned long data)
>  {
>  	struct mt76_dev *dev = (struct mt76_dev *)data;
>  	struct mt76_queue *q = &dev->q_rx[MT_RXQ_MAIN];
> -	struct mt76u_buf *buf;
> +	struct urb *urb;
>  	int err, count;
>  
>  	rcu_read_lock();
>  
>  	while (true) {
> -		buf = mt76u_get_next_rx_entry(q);
> -		if (!buf)
> +		urb = mt76u_get_next_rx_entry(q);
> +		if (!urb)
>  			break;
>  
> -		count = mt76u_process_rx_entry(dev, buf);
> +		count = mt76u_process_rx_entry(dev, urb);
>  		if (count > 0) {
> -			err = mt76u_refill_rx(dev, q, buf, count,
> +			err = mt76u_refill_rx(dev, q, urb, count,
>  					      GFP_ATOMIC);
>  			if (err < 0)
>  				break;
>  		}
> -		mt76u_submit_rx_buf(dev, buf);
> +		mt76u_submit_rx_buf(dev, urb);
>  	}
>  	mt76_rx_poll_complete(dev, MT_RXQ_MAIN, NULL);
>  
> @@ -544,7 +541,7 @@ int mt76u_submit_rx_buffers(struct mt76_dev *dev)
>  
>  	spin_lock_irqsave(&q->lock, flags);
>  	for (i = 0; i < q->ndesc; i++) {
> -		err = mt76u_submit_rx_buf(dev, &q->entry[i].ubuf);
> +		err = mt76u_submit_rx_buf(dev, q->entry[i].urb);
>  		if (err < 0)
>  			break;
>  	}
> @@ -576,7 +573,7 @@ static int mt76u_alloc_rx(struct mt76_dev *dev)
>  	q->buf_size = dev->usb.sg_en ? MT_RX_BUF_SIZE : PAGE_SIZE;
>  	q->ndesc = MT_NUM_RX_ENTRIES;
>  	for (i = 0; i < q->ndesc; i++) {
> -		err = mt76u_buf_alloc(dev, &q->entry[i].ubuf);
> +		err = mt76u_urb_alloc(dev, &q->entry[i]);
>  		if (err < 0)
>  			return err;
>  	}
> @@ -591,7 +588,7 @@ static void mt76u_free_rx(struct mt76_dev *dev)
>  	int i;
>  
>  	for (i = 0; i < q->ndesc; i++)
> -		mt76u_buf_free(&q->entry[i].ubuf);
> +		mt76u_urb_free(q->entry[i].urb);
>  
>  	if (!q->rx_page.va)
>  		return;
> @@ -607,7 +604,7 @@ static void mt76u_stop_rx(struct mt76_dev *dev)
>  	int i;
>  
>  	for (i = 0; i < q->ndesc; i++)
> -		usb_kill_urb(q->entry[i].ubuf.urb);
> +		usb_kill_urb(q->entry[i].urb);
>  }
>  
>  static void mt76u_tx_tasklet(unsigned long data)
> @@ -718,7 +715,7 @@ static void mt76u_complete_tx(struct urb *urb)
>  		   struct ieee80211_sta *sta)
>  {
>  	struct mt76_queue *q = dev->q_tx[qid].q;
> -	struct mt76u_buf *buf;
> +	struct urb *urb;
>  	u16 idx = q->tail;
>  	int err;
>  
> @@ -731,18 +728,18 @@ static void mt76u_complete_tx(struct urb *urb)
>  		return err;
>  
>  	q->entry[idx].done = false;
> -	buf = &q->entry[idx].ubuf;
> +	urb = q->entry[idx].urb;
>  	if (!dev->usb.sg_en) {
> -		buf->urb->transfer_buffer = skb->data;
> +		urb->transfer_buffer = skb->data;
>  	} else {
> -		err = mt76u_tx_build_sg(dev, skb, buf->urb);
> +		err = mt76u_tx_build_sg(dev, skb, urb);
>  		if (err < 0)
>  			return err;
>  	}
> -	buf->urb->transfer_buffer_length = skb->len;
> +	urb->transfer_buffer_length = skb->len;
>  
>  	mt76u_fill_bulk_urb(dev, USB_DIR_OUT, q2ep(q->hw_idx),
> -			    buf, mt76u_complete_tx, &q->entry[idx]);
> +			    urb, mt76u_complete_tx, &q->entry[idx]);
>  
>  	q->tail = (q->tail + 1) % q->ndesc;
>  	q->entry[idx].skb = skb;
> @@ -753,14 +750,14 @@ static void mt76u_complete_tx(struct urb *urb)
>  
>  static void mt76u_tx_kick(struct mt76_dev *dev, struct mt76_queue *q)
>  {
> -	struct mt76u_buf *buf;
> +	struct urb *urb;
>  	int err;
>  
>  	while (q->first != q->tail) {
> -		buf = &q->entry[q->first].ubuf;
> +		urb = q->entry[q->first].urb;
>  
> -		trace_submit_urb(dev, buf->urb);
> -		err = usb_submit_urb(buf->urb, GFP_ATOMIC);
> +		trace_submit_urb(dev, urb);
> +		err = usb_submit_urb(urb, GFP_ATOMIC);
>  		if (err < 0) {
>  			if (err == -ENODEV)
>  				set_bit(MT76_REMOVED, &dev->state);
> @@ -775,7 +772,7 @@ static void mt76u_tx_kick(struct mt76_dev *dev, struct mt76_queue *q)
>  
>  static int mt76u_alloc_tx(struct mt76_dev *dev)
>  {
> -	struct mt76u_buf *buf;
> +	struct urb *urb;
>  	struct mt76_queue *q;
>  	int i, j;
>  
> @@ -803,19 +800,18 @@ static int mt76u_alloc_tx(struct mt76_dev *dev)
>  
>  		q->ndesc = MT_NUM_TX_ENTRIES;
>  		for (j = 0; j < q->ndesc; j++) {
> -			buf = &q->entry[j].ubuf;
> -
> -			buf->urb = usb_alloc_urb(0, GFP_KERNEL);
> -			if (!buf->urb)
> +			urb = usb_alloc_urb(0, GFP_KERNEL);
> +			if (!urb)
>  				return -ENOMEM;
> +			q->entry[j].urb = urb;
>  
>  			if (dev->usb.sg_en) {
>  				size_t size = MT_SG_MAX_SIZE *
>  					      sizeof(struct scatterlist);
>  
> -				buf->urb->sg = devm_kzalloc(dev->dev, size,
> -							    GFP_KERNEL);
> -				if (!buf->urb->sg)
> +				urb->sg = devm_kzalloc(dev->dev, size,
> +						       GFP_KERNEL);
> +				if (!urb->sg)
>  					return -ENOMEM;
>  			}
>  		}
> @@ -831,7 +827,7 @@ static void mt76u_free_tx(struct mt76_dev *dev)
>  	for (i = 0; i < IEEE80211_NUM_ACS; i++) {
>  		q = dev->q_tx[i].q;
>  		for (j = 0; j < q->ndesc; j++)
> -			usb_free_urb(q->entry[j].ubuf.urb);
> +			usb_free_urb(q->entry[j].urb);
>  	}
>  }
>  
> @@ -843,7 +839,7 @@ static void mt76u_stop_tx(struct mt76_dev *dev)
>  	for (i = 0; i < IEEE80211_NUM_ACS; i++) {
>  		q = dev->q_tx[i].q;
>  		for (j = 0; j < q->ndesc; j++)
> -			usb_kill_urb(q->entry[j].ubuf.urb);
> +			usb_kill_urb(q->entry[j].urb);
>  	}
>  }
>  
> -- 
> 1.9.3
> 

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

^ permalink raw reply

* Re: [RFC 11/12] mt76usb: allocate urb and sg as linear data
From: Lorenzo Bianconi @ 2019-03-12 16:34 UTC (permalink / raw)
  To: Stanislaw Gruszka; +Cc: linux-wireless, Felix Fietkau
In-Reply-To: <1552403166-3821-12-git-send-email-sgruszka@redhat.com>

[-- Attachment #1: Type: text/plain, Size: 1534 bytes --]

> Alloc sg table at the end of urb structure. This will increase
> cache usage.
> 

I am curious, have you observed any performance improvement doing so?

> Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
> ---
>  drivers/net/wireless/mediatek/mt76/usb.c | 20 ++++++++++----------
>  1 file changed, 10 insertions(+), 10 deletions(-)
> 
> diff --git a/drivers/net/wireless/mediatek/mt76/usb.c b/drivers/net/wireless/mediatek/mt76/usb.c
> index 0b9f0b5fd37d..dd487f65f44e 100644
> --- a/drivers/net/wireless/mediatek/mt76/usb.c
> +++ b/drivers/net/wireless/mediatek/mt76/usb.c
> @@ -336,19 +336,19 @@ static bool mt76u_check_sg(struct mt76_dev *dev)
>  static int
>  mt76u_urb_alloc(struct mt76_dev *dev, struct mt76_queue_entry *e)
>  {
> -	struct urb *urb;
> +	unsigned int size = sizeof(struct urb);
> +
> +	if (dev->usb.sg_en)
> +		size += MT_SG_MAX_SIZE * sizeof(struct scatterlist);
>  
> -	urb = usb_alloc_urb(0, GFP_KERNEL);
> -	if (!urb)
> +	e->urb = kzalloc(size, GFP_KERNEL);
> +	if (!e->urb)
>  		return -ENOMEM;
> -	e->urb = urb;
>  
> -	if (dev->usb.sg_en) {
> -		urb->sg = devm_kcalloc(dev->dev, MT_SG_MAX_SIZE,
> -				       sizeof(urb->sg), GFP_KERNEL);
> -		if (!urb->sg)
> -			return -ENOMEM;
> -	}
> +	usb_init_urb(e->urb);
> +
> +	if (dev->usb.sg_en)
> +		e->urb->sg = (struct scatterlist *)((u8 *)e->urb + sizeof(struct urb));

You can avoid u8 cast doing:
(struct scatterlist *)(e->urb + 1)

Regards,
Lorenzo

>  
>  	return 0;
>  }
> -- 
> 1.9.3
> 

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

^ permalink raw reply

* Re: [PATCH v2] mt76: fix schedule while atomic in mt76x02_reset_state
From: Lorenzo Bianconi @ 2019-03-12 16:48 UTC (permalink / raw)
  To: Stanislaw Gruszka; +Cc: Lorenzo Bianconi, Felix Fietkau, linux-wireless
In-Reply-To: <20190312140339.GA5881@redhat.com>

>
> On Mon, Mar 11, 2019 at 02:24:35PM +0100, Lorenzo Bianconi wrote:
> > Fix following schedule while atomic in mt76x02_reset_state
> > since synchronize_rcu is run inside a RCU section
> >
> > [44036.944222] mt76x2e 0000:06:00.0: MCU message 31 (seq 3) timed out
> > [44036.944281] BUG: sleeping function called from invalid context at kernel/rcu/tree_exp.h:818
> > [44036.944284] in_atomic(): 1, irqs_disabled(): 0, pid: 28066, name: kworker/u4:1
> > [44036.944287] INFO: lockdep is turned off.
> > [44036.944292] CPU: 1 PID: 28066 Comm: kworker/u4:1 Tainted: G        W         5.0.0-rc7-wdn-t1+ #7
> > [44036.944294] Hardware name: Dell Inc. Studio XPS 1340/0K183D, BIOS A11 09/08/2009
> > [44036.944305] Workqueue: phy1 mt76x02_wdt_work [mt76x02_lib]
> > [44036.944308] Call Trace:
> > [44036.944317]  dump_stack+0x67/0x90
> > [44036.944322]  ___might_sleep.cold.88+0x9f/0xaf
> > [44036.944327]  rcu_blocking_is_gp+0x13/0x50
> > [44036.944330]  synchronize_rcu+0x17/0x80
> > [44036.944337]  mt76_sta_state+0x138/0x1d0 [mt76]
> > [44036.944349]  mt76x02_wdt_work+0x1c9/0x610 [mt76x02_lib]
> > [44036.944355]  process_one_work+0x2a5/0x620
> > [44036.944361]  worker_thread+0x35/0x3e0
> > [44036.944368]  kthread+0x11c/0x140
> > [44036.944376]  ret_from_fork+0x3a/0x50
> > [44036.944384] BUG: scheduling while atomic: kworker/u4:1/28066/0x00000002
> > [44036.944387] INFO: lockdep is turned off.
> > [44036.944389] Modules linked in: cmac ctr ccm af_packet snd_hda_codec_hdmi
>
> Does the patch fix the issue for you ? For me on my MT7612E device it
> make the BUG warning gone, but instead of that I have total system hung
> without any error message except information about hw restart.
>
Hi Stanislaw,

this patch just fixes the 'schedule while atomic' issue.

> [  174.425507] mt76x2e 0000:04:00.0: mac specific condition occurred
> [  176.590750] mt76x2e 0000:04:00.0: MCU message 31 (seq 13) timed out
> [  176.861345] mt76x2e 0000:04:00.0: Firmware Version: 0.0.00
> [  176.867214] mt76x2e 0000:04:00.0: Build: 1
> [  176.876563] mt76x2e 0000:04:00.0: Build Time: 201507311614____
> [  176.908095] mt76x2e 0000:04:00.0: Firmware running!
> [  176.920030] ieee80211 phy0: Hardware restart was requested
>
> ... hung at this point.
>
> This is with this fix and Felix's
> [PATCH] mac80211: do not call driver wake_tx_queue op during reconfig
> on latest nbd/wireless tree.
>
> Stanislaw
>

are you using U7612E-H1? I am still having issues on this card but I had no time
to look at it yet.

Regards,
Lorenzo

-- 
UNIX is Sexy: who | grep -i blonde | talk; cd ~; wine; talk; touch;
unzip; touch; strip; gasp; finger; gasp; mount; fsck; more; yes; gasp;
umount; make clean; sleep

^ permalink raw reply

* [RFC] iwlwifi: enable TX AMPDU for some iwldvm
From: Kevin Locke @ 2019-03-12 17:12 UTC (permalink / raw)
  To: linuxwifi, linux-wireless; +Cc: Emmanuel Grumbach

Hi Wireless Developers,

I have a Lenovo ThinkPad T430 (2342-CTO) with an Intel Centrino
Ultimate-N 6300 (8086:4238) wireless card.  With the help of Reventlov
and johill on #linux-wireless, we discovered that enabling TX AMPDU,
by passing module option 11n_disable=8 (IWL_ENABLE_HT_TXAGG) to
iwlwifi, increased TCP throughput significantly:

With an ASUS RT-ACRH13 AP and `iperf3 -s` running on a server with a
1Gbps wired connection, `iperf3 -R -c` on the ThinkPad increased from
63.2 to 104 Mbits/sec (using MCS 15 40MHz short GI).  With a Buffalo
WZR-600DHP running OpenWRT, `iperf3 -R -c` increased from 63.2 to
76.9.

TX AMPDU was disabled by default for all iwldvm cards in 205e2210daa9
because "iwldvm don't handle well TX AMPDU".  However, I have been
using this configuration for >2 weeks without any issues or measurable
change in ping times to the AP.  Are there any other potential
side-effects I can check?

Would it be possible to enable TX AMPDU by default for at least some
of these cards?  If so, what additional information would be required?

Thanks for considering,
Kevin

^ permalink raw reply

* Re: wireless workshop coming soon :-)
From: Kirtika Ruchandani @ 2019-03-12 18:47 UTC (permalink / raw)
  To: Johannes Berg; +Cc: Toke Høiland-Jørgensen, linux-wireless
In-Reply-To: <5d26367411cf2b50d4cf237640598d1952f17673.camel@sipsolutions.net>

On Fri, Mar 1, 2019 at 3:12 AM Johannes Berg <johannes@sipsolutions.net> wrote:
>
> On Fri, 2019-03-01 at 12:11 +0100, Toke Høiland-Jørgensen wrote:
> > Johannes Berg <johannes@sipsolutions.net> writes:
> >
> > > Please add your favourite topics to
> > >
> > > https://wireless.wiki.kernel.org/en/developers/summits/prague-2019
> > >
> > > I've added a few I think we should discuss at this stage, so also see if
> > > you have an opinion on those :-)
> >
> > Cool! Could we schedule the scheduling and airtime fairness topics after
> > 10:30? Have a tutorial to run in the morning and would obviously like to
> > participate in those discussions ;)
>
> Yeah, I'm aware. I also have a conflict with the netlink workshop, so
> Kalle will have to take over for me some of the time :-)
>

More people may be interested in knowing what is being covered
at the wireless workshop until 10.30 so we can make a call on which
one to attend?

^ permalink raw reply

* [PATCH 1/2] ath: drop duplicated include
From: Tomislav Požega @ 2019-03-12 19:10 UTC (permalink / raw)
  To: linux-wireless; +Cc: kvalo, Tomislav Po�ega

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset=UTF-8, Size: 546 bytes --]

Signed-off-by: Tomislav Po¸ega <pozega.tomislav@gmail.com>
---
 drivers/net/wireless/ath/regd.h |    1 -
 1 files changed, 0 insertions(+), 1 deletions(-)

diff --git a/drivers/net/wireless/ath/regd.h b/drivers/net/wireless/ath/regd.h
index 75ddaef..8d5a16b 100644
--- a/drivers/net/wireless/ath/regd.h
+++ b/drivers/net/wireless/ath/regd.h
@@ -28,7 +28,6 @@ enum ctl_group {
 	CTL_ETSI = 0x30,
 };
 
-#define NO_CTL 0xff
 #define SD_NO_CTL               0xE0
 #define NO_CTL                  0xff
 #define CTL_11A                 0
-- 
1.7.0.4


^ permalink raw reply related

* [PATCH 2/2] ath9k: drop redundant code in ar9003_hw_set_channel
From: Tomislav Požega @ 2019-03-12 19:10 UTC (permalink / raw)
  To: linux-wireless; +Cc: kvalo, Tomislav Po�ega
In-Reply-To: <1552417843-10935-1-git-send-email-pozega.tomislav@gmail.com>

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset=UTF-8, Size: 2232 bytes --]

AR9330, AR9485, AR9531, AR9550, AR9561 and AR9565 all use same
channel set register configuration which allows for small code
size reduction.

Signed-off-by: Tomislav Po¸ega <pozega.tomislav@gmail.com>
---
 drivers/net/wireless/ath/ath9k/ar9003_phy.c |   24 +++---------------------
 1 files changed, 3 insertions(+), 21 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
index 98c5f52..daf30f9 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
@@ -157,7 +157,9 @@ static int ar9003_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan)
 	freq = centers.synth_center;
 
 	if (freq < 4800) {     /* 2 GHz, fractional mode */
-		if (AR_SREV_9330(ah)) {
+		if (AR_SREV_9330(ah) || AR_SREV_9485(ah) ||
+		    AR_SREV_9531(ah) || AR_SREV_9550(ah) ||
+		    AR_SREV_9561(ah) || AR_SREV_9565(ah)) {
 			if (ah->is_clk_25mhz)
 				div = 75;
 			else
@@ -166,16 +168,6 @@ static int ar9003_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan)
 			channelSel = (freq * 4) / div;
 			chan_frac = (((freq * 4) % div) * 0x20000) / div;
 			channelSel = (channelSel << 17) | chan_frac;
-		} else if (AR_SREV_9485(ah) || AR_SREV_9565(ah)) {
-			/*
-			 * freq_ref = 40 / (refdiva >> amoderefsel);
-			 * where refdiva=1 and amoderefsel=0
-			 * ndiv = ((chan_mhz * 4) / 3) / freq_ref;
-			 * chansel = int(ndiv), chanfrac = (ndiv - chansel) * 0x20000
-			 */
-			channelSel = (freq * 4) / 120;
-			chan_frac = (((freq * 4) % 120) * 0x20000) / 120;
-			channelSel = (channelSel << 17) | chan_frac;
 		} else if (AR_SREV_9340(ah)) {
 			if (ah->is_clk_25mhz) {
 				channelSel = (freq * 2) / 75;
@@ -184,16 +176,6 @@ static int ar9003_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan)
 			} else {
 				channelSel = CHANSEL_2G(freq) >> 1;
 			}
-		} else if (AR_SREV_9550(ah) || AR_SREV_9531(ah) ||
-			   AR_SREV_9561(ah)) {
-			if (ah->is_clk_25mhz)
-				div = 75;
-			else
-				div = 120;
-
-			channelSel = (freq * 4) / div;
-			chan_frac = (((freq * 4) % div) * 0x20000) / div;
-			channelSel = (channelSel << 17) | chan_frac;
 		} else {
 			channelSel = CHANSEL_2G(freq);
 		}
-- 
1.7.0.4


^ permalink raw reply related

* [PATCH 1/2] rt2x00: code-style fix in rt2800usb.c
From: Tomislav Požega @ 2019-03-12 19:11 UTC (permalink / raw)
  To: linux-wireless; +Cc: kvalo, sgruszka, daniel, Tomislav Po�ega

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset=UTF-8, Size: 1085 bytes --]

Signed-off-by: Tomislav Po¸ega <pozega.tomislav@gmail.com>
---
 drivers/net/wireless/ralink/rt2x00/rt2800usb.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/ralink/rt2x00/rt2800usb.c b/drivers/net/wireless/ralink/rt2x00/rt2800usb.c
index 19eabf1..091a607 100644
--- a/drivers/net/wireless/ralink/rt2x00/rt2800usb.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800usb.c
@@ -562,13 +562,13 @@ static void rt2800usb_fill_rxdone(struct queue_entry *entry,
 		 * stripped it from the frame. Signal this to mac80211.
 		 */
 		rxdesc->flags |= RX_FLAG_MMIC_STRIPPED;
-        
+
 		if (rxdesc->cipher_status == RX_CRYPTO_SUCCESS) {
 			rxdesc->flags |= RX_FLAG_DECRYPTED;
 		} else if (rxdesc->cipher_status == RX_CRYPTO_FAIL_MIC) {
 			/*
 			 * In order to check the Michael Mic, the packet must have
-			 * been decrypted.  Mac80211 doesnt check the MMIC failure 
+			 * been decrypted.  Mac80211 doesnt check the MMIC failure
 			 * flag to initiate MMIC countermeasures if the decoded flag
 			 * has not been set.
 			 */
-- 
1.7.0.4


^ permalink raw reply related

* [PATCH 2/2] rt2x00: enable experimental MFP with HW crypt
From: Tomislav Požega @ 2019-03-12 19:11 UTC (permalink / raw)
  To: linux-wireless; +Cc: kvalo, sgruszka, daniel, Tomislav Po�ega
In-Reply-To: <1552417902-11040-1-git-send-email-pozega.tomislav@gmail.com>

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset=UTF-8, Size: 1885 bytes --]

MFP can work with enabled HW crypt engine, but in this case
available bandwidth is reduced at least when connecting to
Archer C7 (QCA9558). Enable the feature for known to work chipsets-
MT7620, RT3070 and RT5390. Userspace setting for ieee80211w should
default to 0 in order to prevent unintentional bandwidth drop.

Signed-off-by: Tomislav Po¸ega <pozega.tomislav@gmail.com>
---
 drivers/net/wireless/ralink/rt2x00/rt2800lib.c |   11 +++++++----
 1 files changed, 7 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
index a03b528..bb8204d 100644
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
@@ -9326,6 +9326,13 @@ static int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
 	ieee80211_hw_set(rt2x00dev->hw, SIGNAL_DBM);
 	ieee80211_hw_set(rt2x00dev->hw, SUPPORTS_PS);
 
+	/* Experimental: Set MFP with HW crypto enabled. */
+	if (rt2x00_rt(rt2x00dev, RT3070) || rt2x00_rt(rt2x00dev, RT5390) ||
+	    rt2x00_rt(rt2x00dev, RT6352))
+		ieee80211_hw_set(rt2x00dev->hw, MFP_CAPABLE);
+	else /* Set MFP if HW crypto is disabled. */
+		if (rt2800_hwcrypt_disabled(rt2x00dev))
+			ieee80211_hw_set(rt2x00dev->hw, MFP_CAPABLE);
 	/*
 	 * Don't set IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING for USB devices
 	 * unless we are capable of sending the buffered frames out after the
@@ -9336,10 +9343,6 @@ static int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
 	if (!rt2x00_is_usb(rt2x00dev))
 		ieee80211_hw_set(rt2x00dev->hw, HOST_BROADCAST_PS_BUFFERING);
 
-	/* Set MFP if HW crypto is disabled. */
-	if (rt2800_hwcrypt_disabled(rt2x00dev))
-		ieee80211_hw_set(rt2x00dev->hw, MFP_CAPABLE);
-
 	SET_IEEE80211_DEV(rt2x00dev->hw, rt2x00dev->dev);
 	SET_IEEE80211_PERM_ADDR(rt2x00dev->hw,
 				rt2800_eeprom_addr(rt2x00dev,
-- 
1.7.0.4


^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox