Linux wireless drivers development
 help / color / mirror / Atom feed
* [PATCH 0/6] rt2x00: fix beaconing on RT3593
From: Gabor Juhos @ 2013-08-17 17:56 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless, users, Gabor Juhos

Gabor Juhos (6):
  rt2x00: rt2800lib: move rt2800_drv_data declaration into rt2800lib.h
  rt2x00: rt2800lib: introduce RT2800_HAS_HIGH_SHARED_MEM flag
  rt2x00: rt2800: serialize shared memory access
  rt2x00: rt2800lib: add rt2800_hw_beacon_base helper
  rt2x00: rt2800lib: don't hardcode beacon offsets
  rt2x00: rt2800lib: fix beacon generation on RT3593

 drivers/net/wireless/rt2x00/rt2800.h    |   18 ++--
 drivers/net/wireless/rt2x00/rt2800lib.c |  146 ++++++++++++++++++++++++++++---
 drivers/net/wireless/rt2x00/rt2800lib.h |   42 +++++++++
 drivers/net/wireless/rt2x00/rt2800pci.c |   10 +++
 drivers/net/wireless/rt2x00/rt2800usb.c |    5 ++
 5 files changed, 198 insertions(+), 23 deletions(-)

--
1.7.10

^ permalink raw reply

* [PATCH v1 36/49] wireless: libertas_tf: prepare for enabling irq in complete()
From: Ming Lei @ 2013-08-17 16:25 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: linux-usb, Oliver Neukum, Alan Stern, Ming Lei, John W. Linville,
	libertas-dev, linux-wireless, netdev
In-Reply-To: <1376756714-25479-1-git-send-email-ming.lei@canonical.com>

Complete() will be run with interrupt enabled, so change to
spin_lock_irqsave().

Cc: "John W. Linville" <linville@tuxdriver.com>
Cc: libertas-dev@lists.infradead.org
Cc: linux-wireless@vger.kernel.org
Cc: netdev@vger.kernel.org
Signed-off-by: Ming Lei <ming.lei@canonical.com>
---
 drivers/net/wireless/libertas_tf/if_usb.c |    6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/libertas_tf/if_usb.c b/drivers/net/wireless/libertas_tf/if_usb.c
index d576dd6..0e9e972 100644
--- a/drivers/net/wireless/libertas_tf/if_usb.c
+++ b/drivers/net/wireless/libertas_tf/if_usb.c
@@ -610,6 +610,8 @@ static inline void process_cmdrequest(int recvlength, uint8_t *recvbuff,
 				      struct if_usb_card *cardp,
 				      struct lbtf_private *priv)
 {
+	unsigned long flags;
+
 	if (recvlength > LBS_CMD_BUFFER_SIZE) {
 		lbtf_deb_usbd(&cardp->udev->dev,
 			     "The receive buffer is too large\n");
@@ -619,12 +621,12 @@ static inline void process_cmdrequest(int recvlength, uint8_t *recvbuff,
 
 	BUG_ON(!in_interrupt());
 
-	spin_lock(&priv->driver_lock);
+	spin_lock_irqsave(&priv->driver_lock, flags);
 	memcpy(priv->cmd_resp_buff, recvbuff + MESSAGE_HEADER_LEN,
 	       recvlength - MESSAGE_HEADER_LEN);
 	kfree_skb(skb);
 	lbtf_cmd_response_rx(priv);
-	spin_unlock(&priv->driver_lock);
+	spin_unlock_irqrestore(&priv->driver_lock, flags);
 }
 
 /**
-- 
1.7.9.5


^ permalink raw reply related

* [PATCH v1 35/49] wireless: libertas: prepare for enabling irq in complete()
From: Ming Lei @ 2013-08-17 16:25 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: linux-usb, Oliver Neukum, Alan Stern, Ming Lei, John W. Linville,
	libertas-dev, linux-wireless, netdev
In-Reply-To: <1376756714-25479-1-git-send-email-ming.lei@canonical.com>

Complete() will be run with interrupt enabled, so change to
spin_lock_irqsave().

Cc: "John W. Linville" <linville@tuxdriver.com>
Cc: libertas-dev@lists.infradead.org
Cc: linux-wireless@vger.kernel.org
Cc: netdev@vger.kernel.org
Signed-off-by: Ming Lei <ming.lei@canonical.com>
---
 drivers/net/wireless/libertas/if_usb.c |    5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/libertas/if_usb.c b/drivers/net/wireless/libertas/if_usb.c
index 2798077..f6a8396 100644
--- a/drivers/net/wireless/libertas/if_usb.c
+++ b/drivers/net/wireless/libertas/if_usb.c
@@ -626,6 +626,7 @@ static inline void process_cmdrequest(int recvlength, uint8_t *recvbuff,
 				      struct lbs_private *priv)
 {
 	u8 i;
+	unsigned long flags;
 
 	if (recvlength > LBS_CMD_BUFFER_SIZE) {
 		lbs_deb_usbd(&cardp->udev->dev,
@@ -636,7 +637,7 @@ static inline void process_cmdrequest(int recvlength, uint8_t *recvbuff,
 
 	BUG_ON(!in_interrupt());
 
-	spin_lock(&priv->driver_lock);
+	spin_lock_irqsave(&priv->driver_lock, flags);
 
 	i = (priv->resp_idx == 0) ? 1 : 0;
 	BUG_ON(priv->resp_len[i]);
@@ -646,7 +647,7 @@ static inline void process_cmdrequest(int recvlength, uint8_t *recvbuff,
 	kfree_skb(skb);
 	lbs_notify_command_response(priv, i);
 
-	spin_unlock(&priv->driver_lock);
+	spin_unlock_irqrestore(&priv->driver_lock, flags);
 
 	lbs_deb_usbd(&cardp->udev->dev,
 		    "Wake up main thread to handle cmd response\n");
-- 
1.7.9.5


^ permalink raw reply related

* [PATCH v1 34/49] wireless: ath: carl9170: prepare for enabling irq in complete()
From: Ming Lei @ 2013-08-17 16:24 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: linux-usb, Oliver Neukum, Alan Stern, Ming Lei,
	Christian Lamparter, John W. Linville, linux-wireless, netdev
In-Reply-To: <1376756714-25479-1-git-send-email-ming.lei@canonical.com>

Complete() will be run with interrupt enabled, so change to
spin_lock_irqsave().

Cc: Christian Lamparter <chunkeey@googlemail.com>
Cc: "John W. Linville" <linville@tuxdriver.com>
Cc: linux-wireless@vger.kernel.org
Cc: netdev@vger.kernel.org
Signed-off-by: Ming Lei <ming.lei@canonical.com>
---
 drivers/net/wireless/ath/carl9170/rx.c |    5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/ath/carl9170/rx.c b/drivers/net/wireless/ath/carl9170/rx.c
index 4684dd9..61f62a6 100644
--- a/drivers/net/wireless/ath/carl9170/rx.c
+++ b/drivers/net/wireless/ath/carl9170/rx.c
@@ -129,6 +129,7 @@ static int carl9170_check_sequence(struct ar9170 *ar, unsigned int seq)
 
 static void carl9170_cmd_callback(struct ar9170 *ar, u32 len, void *buffer)
 {
+	unsigned long flags;
 	/*
 	 * Some commands may have a variable response length
 	 * and we cannot predict the correct length in advance.
@@ -148,7 +149,7 @@ static void carl9170_cmd_callback(struct ar9170 *ar, u32 len, void *buffer)
 		carl9170_restart(ar, CARL9170_RR_INVALID_RSP);
 	}
 
-	spin_lock(&ar->cmd_lock);
+	spin_lock_irqsave(&ar->cmd_lock, flags);
 	if (ar->readbuf) {
 		if (len >= 4)
 			memcpy(ar->readbuf, buffer + 4, len - 4);
@@ -156,7 +157,7 @@ static void carl9170_cmd_callback(struct ar9170 *ar, u32 len, void *buffer)
 		ar->readbuf = NULL;
 	}
 	complete(&ar->cmd_wait);
-	spin_unlock(&ar->cmd_lock);
+	spin_unlock_irqrestore(&ar->cmd_lock, flags);
 }
 
 void carl9170_handle_command_response(struct ar9170 *ar, void *buf, u32 len)
-- 
1.7.9.5


^ permalink raw reply related

* [PATCH v1 33/49] wireless: zd1211rw: prepare for enabling irq in complete()
From: Ming Lei @ 2013-08-17 16:24 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: linux-usb, Oliver Neukum, Alan Stern, Ming Lei, Daniel Drake,
	Ulrich Kunitz, John W. Linville, linux-wireless, netdev
In-Reply-To: <1376756714-25479-1-git-send-email-ming.lei@canonical.com>

Complete() will be run with interrupt enabled, so change to
spin_lock_irqsave().

Cc: Daniel Drake <dsd@gentoo.org>
Cc: Ulrich Kunitz <kune@deine-taler.de>
Cc: "John W. Linville" <linville@tuxdriver.com>
Cc: linux-wireless@vger.kernel.org
Cc: netdev@vger.kernel.org
Signed-off-by: Ming Lei <ming.lei@canonical.com>
---
 drivers/net/wireless/zd1211rw/zd_usb.c |   21 ++++++++++++---------
 1 file changed, 12 insertions(+), 9 deletions(-)

diff --git a/drivers/net/wireless/zd1211rw/zd_usb.c b/drivers/net/wireless/zd1211rw/zd_usb.c
index 7ef0b4a..8169ee0 100644
--- a/drivers/net/wireless/zd1211rw/zd_usb.c
+++ b/drivers/net/wireless/zd1211rw/zd_usb.c
@@ -372,14 +372,15 @@ static inline void handle_regs_int_override(struct urb *urb)
 {
 	struct zd_usb *usb = urb->context;
 	struct zd_usb_interrupt *intr = &usb->intr;
+	unsigned long flags;
 
-	spin_lock(&intr->lock);
+	spin_lock_irqsave(&intr->lock, flags);
 	if (atomic_read(&intr->read_regs_enabled)) {
 		atomic_set(&intr->read_regs_enabled, 0);
 		intr->read_regs_int_overridden = 1;
 		complete(&intr->read_regs.completion);
 	}
-	spin_unlock(&intr->lock);
+	spin_unlock_irqrestore(&intr->lock, flags);
 }
 
 static inline void handle_regs_int(struct urb *urb)
@@ -388,9 +389,10 @@ static inline void handle_regs_int(struct urb *urb)
 	struct zd_usb_interrupt *intr = &usb->intr;
 	int len;
 	u16 int_num;
+	unsigned long flags;
 
 	ZD_ASSERT(in_interrupt());
-	spin_lock(&intr->lock);
+	spin_lock_irqsave(&intr->lock, flags);
 
 	int_num = le16_to_cpu(*(__le16 *)(urb->transfer_buffer+2));
 	if (int_num == CR_INTERRUPT) {
@@ -426,7 +428,7 @@ static inline void handle_regs_int(struct urb *urb)
 	}
 
 out:
-	spin_unlock(&intr->lock);
+	spin_unlock_irqrestore(&intr->lock, flags);
 
 	/* CR_INTERRUPT might override read_reg too. */
 	if (int_num == CR_INTERRUPT && atomic_read(&intr->read_regs_enabled))
@@ -666,6 +668,7 @@ static void rx_urb_complete(struct urb *urb)
 	struct zd_usb_rx *rx;
 	const u8 *buffer;
 	unsigned int length;
+	unsigned long flags;
 
 	switch (urb->status) {
 	case 0:
@@ -694,14 +697,14 @@ static void rx_urb_complete(struct urb *urb)
 		/* If there is an old first fragment, we don't care. */
 		dev_dbg_f(urb_dev(urb), "*** first fragment ***\n");
 		ZD_ASSERT(length <= ARRAY_SIZE(rx->fragment));
-		spin_lock(&rx->lock);
+		spin_lock_irqsave(&rx->lock, flags);
 		memcpy(rx->fragment, buffer, length);
 		rx->fragment_length = length;
-		spin_unlock(&rx->lock);
+		spin_unlock_irqrestore(&rx->lock, flags);
 		goto resubmit;
 	}
 
-	spin_lock(&rx->lock);
+	spin_lock_irqsave(&rx->lock, flags);
 	if (rx->fragment_length > 0) {
 		/* We are on a second fragment, we believe */
 		ZD_ASSERT(length + rx->fragment_length <=
@@ -711,9 +714,9 @@ static void rx_urb_complete(struct urb *urb)
 		handle_rx_packet(usb, rx->fragment,
 			         rx->fragment_length + length);
 		rx->fragment_length = 0;
-		spin_unlock(&rx->lock);
+		spin_unlock_irqrestore(&rx->lock, flags);
 	} else {
-		spin_unlock(&rx->lock);
+		spin_unlock_irqrestore(&rx->lock, flags);
 		handle_rx_packet(usb, buffer, length);
 	}
 
-- 
1.7.9.5


^ permalink raw reply related

* [PATCH v1 32/49] wireless: ath9k: prepare for enabling irq in complete()
From: Ming Lei @ 2013-08-17 16:24 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: linux-usb, Oliver Neukum, Alan Stern, Ming Lei, Luis R. Rodriguez,
	John W. Linville, linux-wireless, netdev
In-Reply-To: <1376756714-25479-1-git-send-email-ming.lei@canonical.com>

Complete() will be run with interrupt enabled, so change to
spin_lock_irqsave().

Cc: "Luis R. Rodriguez" <mcgrof@qca.qualcomm.com>
Cc: "John W. Linville" <linville@tuxdriver.com>
Cc: linux-wireless@vger.kernel.org
Cc: netdev@vger.kernel.org
Signed-off-by: Ming Lei <ming.lei@canonical.com>
---
 drivers/net/wireless/ath/ath9k/hif_usb.c      |   29 ++++++++++++++-----------
 drivers/net/wireless/ath/ath9k/htc_drv_txrx.c |    9 ++++----
 drivers/net/wireless/ath/ath9k/wmi.c          |   11 +++++-----
 3 files changed, 27 insertions(+), 22 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c
index 6d5d716..5efc1f0 100644
--- a/drivers/net/wireless/ath/ath9k/hif_usb.c
+++ b/drivers/net/wireless/ath/ath9k/hif_usb.c
@@ -136,6 +136,7 @@ static void hif_usb_mgmt_cb(struct urb *urb)
 	struct cmd_buf *cmd = (struct cmd_buf *)urb->context;
 	struct hif_device_usb *hif_dev;
 	bool txok = true;
+	unsigned long flags;
 
 	if (!cmd || !cmd->skb || !cmd->hif_dev)
 		return;
@@ -155,14 +156,14 @@ static void hif_usb_mgmt_cb(struct urb *urb)
 		 * If the URBs are being flushed, no need to complete
 		 * this packet.
 		 */
-		spin_lock(&hif_dev->tx.tx_lock);
+		spin_lock_irqsave(&hif_dev->tx.tx_lock, flags);
 		if (hif_dev->tx.flags & HIF_USB_TX_FLUSH) {
-			spin_unlock(&hif_dev->tx.tx_lock);
+			spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags);
 			dev_kfree_skb_any(cmd->skb);
 			kfree(cmd);
 			return;
 		}
-		spin_unlock(&hif_dev->tx.tx_lock);
+		spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags);
 
 		break;
 	default:
@@ -253,6 +254,7 @@ static void hif_usb_tx_cb(struct urb *urb)
 	struct tx_buf *tx_buf = (struct tx_buf *) urb->context;
 	struct hif_device_usb *hif_dev;
 	bool txok = true;
+	unsigned long flags;
 
 	if (!tx_buf || !tx_buf->hif_dev)
 		return;
@@ -272,13 +274,13 @@ static void hif_usb_tx_cb(struct urb *urb)
 		 * If the URBs are being flushed, no need to add this
 		 * URB to the free list.
 		 */
-		spin_lock(&hif_dev->tx.tx_lock);
+		spin_lock_irqsave(&hif_dev->tx.tx_lock, flags);
 		if (hif_dev->tx.flags & HIF_USB_TX_FLUSH) {
-			spin_unlock(&hif_dev->tx.tx_lock);
+			spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags);
 			ath9k_skb_queue_purge(hif_dev, &tx_buf->skb_queue);
 			return;
 		}
-		spin_unlock(&hif_dev->tx.tx_lock);
+		spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags);
 
 		break;
 	default:
@@ -293,13 +295,13 @@ static void hif_usb_tx_cb(struct urb *urb)
 	__skb_queue_head_init(&tx_buf->skb_queue);
 
 	/* Add this TX buffer to the free list */
-	spin_lock(&hif_dev->tx.tx_lock);
+	spin_lock_irqsave(&hif_dev->tx.tx_lock, flags);
 	list_move_tail(&tx_buf->list, &hif_dev->tx.tx_buf);
 	hif_dev->tx.tx_buf_cnt++;
 	if (!(hif_dev->tx.flags & HIF_USB_TX_STOP))
 		__hif_usb_tx(hif_dev); /* Check for pending SKBs */
 	TX_STAT_INC(buf_completed);
-	spin_unlock(&hif_dev->tx.tx_lock);
+	spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags);
 }
 
 /* TX lock has to be taken */
@@ -530,8 +532,9 @@ static void ath9k_hif_usb_rx_stream(struct hif_device_usb *hif_dev,
 	int rx_remain_len, rx_pkt_len;
 	u16 pool_index = 0;
 	u8 *ptr;
+	unsigned long flags;
 
-	spin_lock(&hif_dev->rx_lock);
+	spin_lock_irqsave(&hif_dev->rx_lock, flags);
 
 	rx_remain_len = hif_dev->rx_remain_len;
 	rx_pkt_len = hif_dev->rx_transfer_len;
@@ -559,7 +562,7 @@ static void ath9k_hif_usb_rx_stream(struct hif_device_usb *hif_dev,
 		}
 	}
 
-	spin_unlock(&hif_dev->rx_lock);
+	spin_unlock_irqrestore(&hif_dev->rx_lock, flags);
 
 	while (index < len) {
 		u16 pkt_len;
@@ -585,7 +588,7 @@ static void ath9k_hif_usb_rx_stream(struct hif_device_usb *hif_dev,
 		index = index + 4 + pkt_len + pad_len;
 
 		if (index > MAX_RX_BUF_SIZE) {
-			spin_lock(&hif_dev->rx_lock);
+			spin_lock_irqsave(&hif_dev->rx_lock, flags);
 			hif_dev->rx_remain_len = index - MAX_RX_BUF_SIZE;
 			hif_dev->rx_transfer_len =
 				MAX_RX_BUF_SIZE - chk_idx - 4;
@@ -595,7 +598,7 @@ static void ath9k_hif_usb_rx_stream(struct hif_device_usb *hif_dev,
 			if (!nskb) {
 				dev_err(&hif_dev->udev->dev,
 					"ath9k_htc: RX memory allocation error\n");
-				spin_unlock(&hif_dev->rx_lock);
+				spin_unlock_irqrestore(&hif_dev->rx_lock, flags);
 				goto err;
 			}
 			skb_reserve(nskb, 32);
@@ -606,7 +609,7 @@ static void ath9k_hif_usb_rx_stream(struct hif_device_usb *hif_dev,
 
 			/* Record the buffer pointer */
 			hif_dev->remain_skb = nskb;
-			spin_unlock(&hif_dev->rx_lock);
+			spin_unlock_irqrestore(&hif_dev->rx_lock, flags);
 		} else {
 			nskb = __dev_alloc_skb(pkt_len + 32, GFP_ATOMIC);
 			if (!nskb) {
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
index e602c95..a6f34f8 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
@@ -1156,25 +1156,26 @@ void ath9k_htc_rxep(void *drv_priv, struct sk_buff *skb,
 	struct ath_hw *ah = priv->ah;
 	struct ath_common *common = ath9k_hw_common(ah);
 	struct ath9k_htc_rxbuf *rxbuf = NULL, *tmp_buf = NULL;
+	unsigned long flags;
 
-	spin_lock(&priv->rx.rxbuflock);
+	spin_lock_irqsave(&priv->rx.rxbuflock, flags);
 	list_for_each_entry(tmp_buf, &priv->rx.rxbuf, list) {
 		if (!tmp_buf->in_process) {
 			rxbuf = tmp_buf;
 			break;
 		}
 	}
-	spin_unlock(&priv->rx.rxbuflock);
+	spin_unlock_irqrestore(&priv->rx.rxbuflock, flags);
 
 	if (rxbuf == NULL) {
 		ath_dbg(common, ANY, "No free RX buffer\n");
 		goto err;
 	}
 
-	spin_lock(&priv->rx.rxbuflock);
+	spin_lock_irqsave(&priv->rx.rxbuflock, flags);
 	rxbuf->skb = skb;
 	rxbuf->in_process = true;
-	spin_unlock(&priv->rx.rxbuflock);
+	spin_unlock_irqrestore(&priv->rx.rxbuflock, flags);
 
 	tasklet_schedule(&priv->rx_tasklet);
 	return;
diff --git a/drivers/net/wireless/ath/ath9k/wmi.c b/drivers/net/wireless/ath/ath9k/wmi.c
index 65c8894..101b771 100644
--- a/drivers/net/wireless/ath/ath9k/wmi.c
+++ b/drivers/net/wireless/ath/ath9k/wmi.c
@@ -207,6 +207,7 @@ static void ath9k_wmi_ctrl_rx(void *priv, struct sk_buff *skb,
 	struct wmi *wmi = (struct wmi *) priv;
 	struct wmi_cmd_hdr *hdr;
 	u16 cmd_id;
+	unsigned long flags;
 
 	if (unlikely(wmi->stopped))
 		goto free_skb;
@@ -215,20 +216,20 @@ static void ath9k_wmi_ctrl_rx(void *priv, struct sk_buff *skb,
 	cmd_id = be16_to_cpu(hdr->command_id);
 
 	if (cmd_id & 0x1000) {
-		spin_lock(&wmi->wmi_lock);
+		spin_lock_irqsave(&wmi->wmi_lock, flags);
 		__skb_queue_tail(&wmi->wmi_event_queue, skb);
-		spin_unlock(&wmi->wmi_lock);
+		spin_unlock_irqrestore(&wmi->wmi_lock, flags);
 		tasklet_schedule(&wmi->wmi_event_tasklet);
 		return;
 	}
 
 	/* Check if there has been a timeout. */
-	spin_lock(&wmi->wmi_lock);
+	spin_lock_irqsave(&wmi->wmi_lock, flags);
 	if (cmd_id != wmi->last_cmd_id) {
-		spin_unlock(&wmi->wmi_lock);
+		spin_unlock_irqrestore(&wmi->wmi_lock, flags);
 		goto free_skb;
 	}
-	spin_unlock(&wmi->wmi_lock);
+	spin_unlock_irqrestore(&wmi->wmi_lock, flags);
 
 	/* WMI command response */
 	ath9k_wmi_rsp_callback(wmi, skb);
-- 
1.7.9.5


^ permalink raw reply related

* [PATCH v1 00/49] USB: prepare for enabling irq in complete()
From: Ming Lei @ 2013-08-17 16:24 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: linux-usb, Oliver Neukum, Alan Stern, linux-input,
	linux-bluetooth, netdev, linux-wireless, linux-media, alsa-devel

Hi,

As we are going to run URB->complete() in tasklet context[1][2], and
hard interrupt may be enabled when running URB completion handler[3],
so we might need to disable interrupt when acquiring one lock in
the completion handler for the below reasons:

- URB->complete() holds a subsystem wide lock which may be acquired
in another hard irq context, and the subsystem wide lock is acquired
by spin_lock()/read_lock()/write_lock() in complete()

- URB->complete() holds a private lock with spin_lock()/read_lock()/write_lock()
but driver may export APIs to make other drivers acquire the same private
lock in its interrupt handler.

For the sake of safety and making the change simple, this patch set
converts all spin_lock()/read_lock()/write_lock() in completion handler
path into their irqsave version mechanically.

But if you are sure the above two cases do not happen in your driver,
please let me know and I can drop the unnecessary change.

Also if you find some conversions are missed, also please let me know so
that I can add it in the next round.


[1], USB: URB documentation: claim complete() will be run with IRQs enabled
https://git.kernel.org/cgit/linux/kernel/git/gregkh/usb.git/commit/?h=usb-next&id=85721d45261c4be684730c7509a59daa6cda30d8

[2], USB: HCD: support giveback of URB in tasklet context
https://git.kernel.org/cgit/linux/kernel/git/gregkh/usb.git/commit/?h=usb-next&id=94dfd7edfd5c9b605caf7b562de7a813d216e011

[3], http://marc.info/?l=linux-usb&m=137286330626363&w=2

V1:
	- rename patchset title
	- add missed changes on 'usb_skeleon and usb sg lib'
	- remove several sound usb drivers which have been done via sound tree
	- some patch style fix
	- replace snd_pcm_stream_lock with snd_pcm_stream_lock_irqsave for related
	a/v drivers

Cc: linux-input@vger.kernel.org
Cc: linux-bluetooth@vger.kernel.org
Cc: netdev@vger.kernel.org
Cc: linux-wireless@vger.kernel.org
Cc: linux-media@vger.kernel.org
Cc: alsa-devel@alsa-project.org

 drivers/bluetooth/bfusb.c                     |   12 ++++----
 drivers/bluetooth/btusb.c                     |    5 ++--
 drivers/hid/usbhid/hid-core.c                 |    5 ++--
 drivers/input/misc/cm109.c                    |   10 ++++---
 drivers/isdn/hardware/mISDN/hfcsusb.c         |   36 ++++++++++++-----------
 drivers/media/dvb-core/dvb_demux.c            |   17 +++++++----
 drivers/media/usb/cx231xx/cx231xx-audio.c     |   10 ++++---
 drivers/media/usb/cx231xx/cx231xx-core.c      |   10 ++++---
 drivers/media/usb/cx231xx/cx231xx-vbi.c       |    5 ++--
 drivers/media/usb/em28xx/em28xx-audio.c       |    5 ++--
 drivers/media/usb/em28xx/em28xx-core.c        |    5 ++--
 drivers/media/usb/sn9c102/sn9c102_core.c      |    7 +++--
 drivers/media/usb/tlg2300/pd-alsa.c           |    5 ++--
 drivers/media/usb/tlg2300/pd-video.c          |    5 ++--
 drivers/media/usb/tm6000/tm6000-video.c       |    5 ++--
 drivers/net/usb/cdc-phonet.c                  |    5 ++--
 drivers/net/usb/hso.c                         |   38 ++++++++++++++-----------
 drivers/net/usb/kaweth.c                      |    7 +++--
 drivers/net/usb/rtl8150.c                     |    5 ++--
 drivers/net/wireless/ath/ath9k/hif_usb.c      |   29 ++++++++++---------
 drivers/net/wireless/ath/ath9k/htc_drv_txrx.c |    9 +++---
 drivers/net/wireless/ath/ath9k/wmi.c          |   11 +++----
 drivers/net/wireless/ath/carl9170/rx.c        |    5 ++--
 drivers/net/wireless/libertas/if_usb.c        |    5 ++--
 drivers/net/wireless/libertas_tf/if_usb.c     |    6 ++--
 drivers/net/wireless/zd1211rw/zd_usb.c        |   21 ++++++++------
 drivers/staging/bcm/InterfaceRx.c             |    5 ++--
 drivers/staging/btmtk_usb/btmtk_usb.c         |    5 ++--
 drivers/staging/ced1401/usb1401.c             |   35 ++++++++++++-----------
 drivers/staging/vt6656/usbpipe.c              |    9 +++---
 drivers/usb/class/cdc-wdm.c                   |   16 +++++++----
 drivers/usb/class/usblp.c                     |   10 ++++---
 drivers/usb/core/devio.c                      |    5 ++--
 drivers/usb/core/message.c                    |    5 ++--
 drivers/usb/misc/adutux.c                     |   10 ++++---
 drivers/usb/misc/iowarrior.c                  |    5 ++--
 drivers/usb/misc/ldusb.c                      |    7 +++--
 drivers/usb/misc/legousbtower.c               |    6 ++--
 drivers/usb/misc/usbtest.c                    |   10 ++++---
 drivers/usb/misc/uss720.c                     |    7 ++++-
 drivers/usb/serial/cyberjack.c                |   15 ++++++----
 drivers/usb/serial/digi_acceleport.c          |   23 ++++++++-------
 drivers/usb/serial/io_edgeport.c              |   14 +++++----
 drivers/usb/serial/io_ti.c                    |    5 ++--
 drivers/usb/serial/mos7720.c                  |    5 ++--
 drivers/usb/serial/mos7840.c                  |    5 ++--
 drivers/usb/serial/quatech2.c                 |    5 ++--
 drivers/usb/serial/sierra.c                   |    9 +++---
 drivers/usb/serial/symbolserial.c             |    5 ++--
 drivers/usb/serial/ti_usb_3410_5052.c         |    9 +++---
 drivers/usb/serial/usb_wwan.c                 |    5 ++--
 drivers/usb/usb-skeleton.c                    |   11 ++++---
 sound/usb/caiaq/audio.c                       |    5 ++--
 sound/usb/midi.c                              |    5 ++--
 54 files changed, 318 insertions(+), 221 deletions(-)


Thanks,
--
Ming Lei


^ permalink raw reply

* Re: [PATCH 1/1] Delete duplicate code. Use of the variable instead call a function
From: Sergey K @ 2013-08-17 15:53 UTC (permalink / raw)
  To: linux-wireless
In-Reply-To: <1376741797-25505-2-git-send-email-perplexus@ya.ru>

Sergey K <perplexus@...> writes:

> 
> ---
>  net/mac80211/tx.c | 4 +---
>  1 file changed, 1 insertion(+), 3 deletions(-)
> 
> diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
> index 098ae85..79db7f3 100644
> --- a/net/mac80211/tx.c
> +++ b/net/mac80211/tx.c
>  <at>  <at>  -1769,8 +1769,6  <at>  <at>  netdev_tx_t 
ieee80211_subif_start_xmit(struct sk_buff *skb,
>  			memcpy(hdr.addr3, skb->data, ETH_ALEN);
>  			memcpy(hdr.addr4, skb->data + ETH_ALEN, ETH_ALEN);
>  			hdrlen = 30;
> -			authorized = test_sta_flag(sta, 
WLAN_STA_AUTHORIZED);
> -			wme_sta = test_sta_flag(sta, WLAN_STA_WME);
>  		}
>  		ap_sdata = container_of(sdata->bss, struct 
ieee80211_sub_if_data,
>  					u.ap);
>  <at>  <at>  -1979,7 +1977,7  <at>  <at>  netdev_tx_t 
ieee80211_subif_start_xmit(struct sk_buff *skb,
>  	 * EAPOL frames from the local station.
>  	 */
>  	if (unlikely(!ieee80211_vif_is_mesh(&sdata->vif) &&
> -		     !is_multicast_ether_addr(hdr.addr1) && !authorized &&
> +		     !multicast && !authorized &&
>  		     (cpu_to_be16(ethertype) != sdata-
>control_port_protocol ||
>  		      !ether_addr_equal(sdata->vif.addr, skb->data + 
ETH_ALEN)))) {
>  #ifdef CONFIG_MAC80211_VERBOSE_DEBUG


We need to delete authorized and wme_sta flags, because these flags are set 
below:

1956         multicast = is_multicast_ether_addr(hdr.addr1);
1957         if (!multicast) {
1958                 sta = sta_info_get(sdata, hdr.addr1);
1959                 if (sta) {
1960                         authorized = test_sta_flag(sta, 
WLAN_STA_AUTHORIZED);
1961                         wme_sta = test_sta_flag(sta, WLAN_STA_WME);
1962                 }
1963         }



^ permalink raw reply

* [PATCH 1/1] Delete duplicate code. Use of the variable instead call a function
From: Sergey K @ 2013-08-17 12:16 UTC (permalink / raw)
  To: linux-wireless; +Cc: Sergey K
In-Reply-To: <1376741797-25505-1-git-send-email-perplexus@ya.ru>

---
 net/mac80211/tx.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 098ae85..79db7f3 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -1769,8 +1769,6 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
 			memcpy(hdr.addr3, skb->data, ETH_ALEN);
 			memcpy(hdr.addr4, skb->data + ETH_ALEN, ETH_ALEN);
 			hdrlen = 30;
-			authorized = test_sta_flag(sta, WLAN_STA_AUTHORIZED);
-			wme_sta = test_sta_flag(sta, WLAN_STA_WME);
 		}
 		ap_sdata = container_of(sdata->bss, struct ieee80211_sub_if_data,
 					u.ap);
@@ -1979,7 +1977,7 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
 	 * EAPOL frames from the local station.
 	 */
 	if (unlikely(!ieee80211_vif_is_mesh(&sdata->vif) &&
-		     !is_multicast_ether_addr(hdr.addr1) && !authorized &&
+		     !multicast && !authorized &&
 		     (cpu_to_be16(ethertype) != sdata->control_port_protocol ||
 		      !ether_addr_equal(sdata->vif.addr, skb->data + ETH_ALEN)))) {
 #ifdef CONFIG_MAC80211_VERBOSE_DEBUG
-- 
1.8.1.5


^ permalink raw reply related

* [PATCH 0/1] *** mac80211: delete duplicate code ***
From: Sergey K @ 2013-08-17 12:16 UTC (permalink / raw)
  To: linux-wireless; +Cc: Sergey K

*** BLURB HERE ***

Sergey K (1):
  Delete duplicate code. Use of the variable instead call a function

 net/mac80211/tx.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

-- 
1.8.1.5


^ permalink raw reply

* [PATCH v2 6/6] rt2x00: rt2800lib: adjust frequency offset for RF3053
From: Gabor Juhos @ 2013-08-17 12:09 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless, users, Gabor Juhos
In-Reply-To: <1376741373-10032-1-git-send-email-juhosg@openwrt.org>

Along with other chipsets, the Ralink driver uses the
frequency adjustment code for RF3053 as well. Remove
the bogus place-holder comment from the RF3053 specific
channel configuration function and call the frequency
adjustment function instead

Based on the DPO_RT5572_LinuxSTA_2.6.0.1_20120629
driver.

Reference:
  RT3593_ChipSwitchChannel function in chips/rt3593.c

Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
---
Changes since v1: ---
---
 drivers/net/wireless/rt2x00/rt2800lib.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
index 1b81fc9..aa6b6b0 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -2360,7 +2360,7 @@ static void rt2800_config_channel_rf3053(struct rt2x00_dev *rt2x00dev,
 	}
 	rt2800_rfcsr_write(rt2x00dev, 1, rfcsr);
 
-	/* TODO: frequency calibration? */
+	rt2800_adjust_freq_offset(rt2x00dev);
 
 	if (conf_is_ht40(conf)) {
 		txrx_agc_fc = rt2x00_get_field8(drv_data->calibration_bw40,
-- 
1.7.10

^ permalink raw reply related

* [PATCH v2 5/6] rt2x00: rt2800lib: move rt2800_adjust_freq_offset function
From: Gabor Juhos @ 2013-08-17 12:09 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless, users, Gabor Juhos
In-Reply-To: <1376741373-10032-1-git-send-email-juhosg@openwrt.org>

Move the rt2800_adjust_freq_offset function before
the channel configuration functions to make it usable
from those without a forward declaration.

The patch contains no functional changes.

Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
---
Changes since v1: ---
---
 drivers/net/wireless/rt2x00/rt2800lib.c |   73 ++++++++++++++++---------------
 1 file changed, 37 insertions(+), 36 deletions(-)

diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
index 623ad9d..1b81fc9 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -1875,6 +1875,43 @@ static void rt2800_config_lna_gain(struct rt2x00_dev *rt2x00dev,
 	rt2x00dev->lna_gain = lna_gain;
 }
 
+#define FREQ_OFFSET_BOUND	0x5f
+
+static void rt2800_adjust_freq_offset(struct rt2x00_dev *rt2x00dev)
+{
+	u8 freq_offset, prev_freq_offset;
+	u8 rfcsr, prev_rfcsr;
+
+	freq_offset = rt2x00_get_field8(rt2x00dev->freq_offset, RFCSR17_CODE);
+	freq_offset = min_t(u8, freq_offset, FREQ_OFFSET_BOUND);
+
+	rt2800_rfcsr_read(rt2x00dev, 17, &rfcsr);
+	prev_rfcsr = rfcsr;
+
+	rt2x00_set_field8(&rfcsr, RFCSR17_CODE, freq_offset);
+	if (rfcsr == prev_rfcsr)
+		return;
+
+	if (rt2x00_is_usb(rt2x00dev)) {
+		rt2800_mcu_request(rt2x00dev, MCU_FREQ_OFFSET, 0xff,
+				   freq_offset, prev_rfcsr);
+		return;
+	}
+
+	prev_freq_offset = rt2x00_get_field8(prev_rfcsr, RFCSR17_CODE);
+	while (prev_freq_offset != freq_offset) {
+		if (prev_freq_offset < freq_offset)
+			prev_freq_offset++;
+		else
+			prev_freq_offset--;
+
+		rt2x00_set_field8(&rfcsr, RFCSR17_CODE, prev_freq_offset);
+		rt2800_rfcsr_write(rt2x00dev, 17, rfcsr);
+
+		usleep_range(1000, 1500);
+	}
+}
+
 static void rt2800_config_channel_rf2xxx(struct rt2x00_dev *rt2x00dev,
 					 struct ieee80211_conf *conf,
 					 struct rf_channel *rf,
@@ -2492,42 +2529,6 @@ static void rt2800_config_channel_rf3053(struct rt2x00_dev *rt2x00dev,
 
 #define POWER_BOUND		0x27
 #define POWER_BOUND_5G		0x2b
-#define FREQ_OFFSET_BOUND	0x5f
-
-static void rt2800_adjust_freq_offset(struct rt2x00_dev *rt2x00dev)
-{
-	u8 freq_offset, prev_freq_offset;
-	u8 rfcsr, prev_rfcsr;
-
-	freq_offset = rt2x00_get_field8(rt2x00dev->freq_offset, RFCSR17_CODE);
-	freq_offset = min_t(u8, freq_offset, FREQ_OFFSET_BOUND);
-
-	rt2800_rfcsr_read(rt2x00dev, 17, &rfcsr);
-	prev_rfcsr = rfcsr;
-
-	rt2x00_set_field8(&rfcsr, RFCSR17_CODE, freq_offset);
-	if (rfcsr == prev_rfcsr)
-		return;
-
-	if (rt2x00_is_usb(rt2x00dev)) {
-		rt2800_mcu_request(rt2x00dev, MCU_FREQ_OFFSET, 0xff,
-				   freq_offset, prev_rfcsr);
-		return;
-	}
-
-	prev_freq_offset = rt2x00_get_field8(prev_rfcsr, RFCSR17_CODE);
-	while (prev_freq_offset != freq_offset) {
-		if (prev_freq_offset < freq_offset)
-			prev_freq_offset++;
-		else
-			prev_freq_offset--;
-
-		rt2x00_set_field8(&rfcsr, RFCSR17_CODE, prev_freq_offset);
-		rt2800_rfcsr_write(rt2x00dev, 17, rfcsr);
-
-		usleep_range(1000, 1500);
-	}
-}
 
 static void rt2800_config_channel_rf3290(struct rt2x00_dev *rt2x00dev,
 					 struct ieee80211_conf *conf,
-- 
1.7.10

^ permalink raw reply related

* [PATCH v2 4/6] rt2x00: rt2800lib: use step-by-step frequency offset adjustment on MMIO devices
From: Gabor Juhos @ 2013-08-17 12:09 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless, users, Gabor Juhos
In-Reply-To: <1376741373-10032-1-git-send-email-juhosg@openwrt.org>

According to the DPO_RT5572_LinuxSTA_2.6.0.1_20120629
driver, the RFCSR17 register can't be programmed in
one step on devices which are using the frequency
offset adjustment code.

Update the code to use step-by-step adjustment.

Reference:
  RT30xxWriteRFRegister function in common/rt_rf.c

Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
---
Changes since v1:
  - new patch
---
 drivers/net/wireless/rt2x00/rt2800lib.c |   19 ++++++++++++++++---
 1 file changed, 16 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
index bebc56f..623ad9d 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -2496,7 +2496,7 @@ static void rt2800_config_channel_rf3053(struct rt2x00_dev *rt2x00dev,
 
 static void rt2800_adjust_freq_offset(struct rt2x00_dev *rt2x00dev)
 {
-	u8 freq_offset;
+	u8 freq_offset, prev_freq_offset;
 	u8 rfcsr, prev_rfcsr;
 
 	freq_offset = rt2x00_get_field8(rt2x00dev->freq_offset, RFCSR17_CODE);
@@ -2509,11 +2509,24 @@ static void rt2800_adjust_freq_offset(struct rt2x00_dev *rt2x00dev)
 	if (rfcsr == prev_rfcsr)
 		return;
 
-	if (rt2x00_is_usb(rt2x00dev))
+	if (rt2x00_is_usb(rt2x00dev)) {
 		rt2800_mcu_request(rt2x00dev, MCU_FREQ_OFFSET, 0xff,
 				   freq_offset, prev_rfcsr);
-	else
+		return;
+	}
+
+	prev_freq_offset = rt2x00_get_field8(prev_rfcsr, RFCSR17_CODE);
+	while (prev_freq_offset != freq_offset) {
+		if (prev_freq_offset < freq_offset)
+			prev_freq_offset++;
+		else
+			prev_freq_offset--;
+
+		rt2x00_set_field8(&rfcsr, RFCSR17_CODE, prev_freq_offset);
 		rt2800_rfcsr_write(rt2x00dev, 17, rfcsr);
+
+		usleep_range(1000, 1500);
+	}
 }
 
 static void rt2800_config_channel_rf3290(struct rt2x00_dev *rt2x00dev,
-- 
1.7.10

^ permalink raw reply related

* [PATCH v2 3/6] rt2x00: rt2800lib: use a MCU command for frequency adjustment on USB devices
From: Gabor Juhos @ 2013-08-17 12:09 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless, users, Gabor Juhos
In-Reply-To: <1376741373-10032-1-git-send-email-juhosg@openwrt.org>

According to the Ralink driver, there is an MCU
command which can be used to send the frequency
offset value directly to the USB device without
going through the RFCSR writing sequence.

Based on the DPO_RT5572_LinuxSTA_2.6.0.1_20120629
driver.

Reference:
  RTMPAdjustFrequencyOffset function in common/rt_rf.c

Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
---
Changes since v1:
  - add a MCU_FREQ_OFFSET constant and use that instead
    of a hardcoded number
---
 drivers/net/wireless/rt2x00/rt2800.h    |    1 +
 drivers/net/wireless/rt2x00/rt2800lib.c |    6 +++++-
 2 files changed, 6 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/rt2x00/rt2800.h b/drivers/net/wireless/rt2x00/rt2800.h
index 6e69b96..e25e5bf 100644
--- a/drivers/net/wireless/rt2x00/rt2800.h
+++ b/drivers/net/wireless/rt2x00/rt2800.h
@@ -2794,6 +2794,7 @@ enum rt2800_eeprom_word {
 #define MCU_RADAR			0x60
 #define MCU_BOOT_SIGNAL			0x72
 #define MCU_ANT_SELECT			0X73
+#define MCU_FREQ_OFFSET			0x74
 #define MCU_BBP_SIGNAL			0x80
 #define MCU_POWER_SAVE			0x83
 #define MCU_BAND_SELECT		0x91
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
index 3407ac9..bebc56f 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -2509,7 +2509,11 @@ static void rt2800_adjust_freq_offset(struct rt2x00_dev *rt2x00dev)
 	if (rfcsr == prev_rfcsr)
 		return;
 
-	rt2800_rfcsr_write(rt2x00dev, 17, rfcsr);
+	if (rt2x00_is_usb(rt2x00dev))
+		rt2800_mcu_request(rt2x00dev, MCU_FREQ_OFFSET, 0xff,
+				   freq_offset, prev_rfcsr);
+	else
+		rt2800_rfcsr_write(rt2x00dev, 17, rfcsr);
 }
 
 static void rt2800_config_channel_rf3290(struct rt2x00_dev *rt2x00dev,
-- 
1.7.10

^ permalink raw reply related

* [PATCH v2 1/6] rt2x00: rt2800lib: fix frequency offset boundary calculation
From: Gabor Juhos @ 2013-08-17 12:09 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless, users, Gabor Juhos
In-Reply-To: <1376741373-10032-1-git-send-email-juhosg@openwrt.org>

The current code in the 'rt2800_adjust_freq_offset'
function limits the device specific frequency offset
value to FREQ_BOUND but ignores the fact that the
uppermost bit is not part of the frequency offset
value. As the result, the driver always uses the
FREQ_BOUND value if the uppermost bit is set.

Update the code to use the correct source value
for calculating the boundary.

Based on the DPO_RT5572_LinuxSTA_2.6.0.1_20120629
driver.

Reference:
  RTMPAdjustFrequencyOffset function in common/rt_rf.c

Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
---
Changes since v1: ---
---
 drivers/net/wireless/rt2x00/rt2800lib.c |    9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
index 2f64034..de27277 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -2496,13 +2496,14 @@ static void rt2800_config_channel_rf3053(struct rt2x00_dev *rt2x00dev,
 
 static void rt2800_adjust_freq_offset(struct rt2x00_dev *rt2x00dev)
 {
+	u8 freq_offset;
 	u8 rfcsr;
 
+	freq_offset = rt2x00_get_field8(rt2x00dev->freq_offset, RFCSR17_CODE);
+	freq_offset = min_t(u8, freq_offset, FREQ_OFFSET_BOUND);
+
 	rt2800_rfcsr_read(rt2x00dev, 17, &rfcsr);
-	if (rt2x00dev->freq_offset > FREQ_OFFSET_BOUND)
-		rt2x00_set_field8(&rfcsr, RFCSR17_CODE, FREQ_OFFSET_BOUND);
-	else
-		rt2x00_set_field8(&rfcsr, RFCSR17_CODE, rt2x00dev->freq_offset);
+	rt2x00_set_field8(&rfcsr, RFCSR17_CODE, freq_offset);
 	rt2800_rfcsr_write(rt2x00dev, 17, rfcsr);
 }
 
-- 
1.7.10

^ permalink raw reply related

* [PATCH v2 2/6] rt2x00: rt2800lib: optimize frequency offset adjustment
From: Gabor Juhos @ 2013-08-17 12:09 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless, users, Gabor Juhos
In-Reply-To: <1376741373-10032-1-git-send-email-juhosg@openwrt.org>

Don't write the new value into the register if it is
the same as the old value to avoid unncessary USB bus
traffic with USB devices. The change also saves a few
cycle on MMIO based devices.

Based on the DPO_RT5572_LinuxSTA_2.6.0.1_20120629
driver.

Reference:
  RTMPAdjustFrequencyOffset function in common/rt_rf.c

Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
---
Changes since v1: ---
---
 drivers/net/wireless/rt2x00/rt2800lib.c |    7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
index de27277..3407ac9 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -2497,13 +2497,18 @@ static void rt2800_config_channel_rf3053(struct rt2x00_dev *rt2x00dev,
 static void rt2800_adjust_freq_offset(struct rt2x00_dev *rt2x00dev)
 {
 	u8 freq_offset;
-	u8 rfcsr;
+	u8 rfcsr, prev_rfcsr;
 
 	freq_offset = rt2x00_get_field8(rt2x00dev->freq_offset, RFCSR17_CODE);
 	freq_offset = min_t(u8, freq_offset, FREQ_OFFSET_BOUND);
 
 	rt2800_rfcsr_read(rt2x00dev, 17, &rfcsr);
+	prev_rfcsr = rfcsr;
+
 	rt2x00_set_field8(&rfcsr, RFCSR17_CODE, freq_offset);
+	if (rfcsr == prev_rfcsr)
+		return;
+
 	rt2800_rfcsr_write(rt2x00dev, 17, rfcsr);
 }
 
-- 
1.7.10

^ permalink raw reply related

* [PATCH v2 0/6] rt2x00: rt2800lib: frequency offset adjustment fixes
From: Gabor Juhos @ 2013-08-17 12:09 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless, users, Gabor Juhos

The patch-set contain small fixes for the frequency adjustment
code of the rt2800 driver.

Gabor Juhos (6):
  rt2x00: rt2800lib: fix frequency offset boundary calculation
  rt2x00: rt2800lib: optimize frequency offset adjustment
  rt2x00: rt2800lib: use a MCU command for frequency adjustment on USB
    devices
  rt2x00: rt2800lib: use step-by-step frequency offset adjustment on
    MMIO devices
  rt2x00: rt2800lib: move rt2800_adjust_freq_offset function
  rt2x00: rt2800lib: adjust frequency offset for RF3053

 drivers/net/wireless/rt2x00/rt2800.h    |    1 +
 drivers/net/wireless/rt2x00/rt2800lib.c |   52 ++++++++++++++++++++++---------
 2 files changed, 39 insertions(+), 14 deletions(-)

--
1.7.10

^ permalink raw reply

* Re: [PATCH 0/5] rt2x00: rt2800lib: frequency offset adjustment fixes
From: Gabor Juhos @ 2013-08-17  9:50 UTC (permalink / raw)
  To: Gabor Juhos; +Cc: John W. Linville, linux-wireless, users
In-Reply-To: <1376685498-5167-1-git-send-email-juhosg@openwrt.org>

2013.08.16. 22:38 keltezéssel, Gabor Juhos írta:
> The patch-set contain small fixes for the frequency adjustment 
> code of the rt2800 driver.
> 
> Gabor Juhos (5):
>   rt2x00: rt2800lib: fix frequency offset boundary calculation
>   rt2x00: rt2800lib: optimize frequency offset adjustment
>   rt2x00: rt2800lib: use a MCU command for frequency adjustment on USB
>     devices
>   rt2x00: rt2800lib: move rt2800_adjust_freq_offset function
>   rt2x00: rt2800lib: adjust frequency offset for RF3053
> 
>  drivers/net/wireless/rt2x00/rt2800lib.c |   38 +++++++++++++++++++------------
>  1 file changed, 24 insertions(+), 14 deletions(-)
> 

John,

Please ignore this set. I will send a slightly improved version.

-Gabor

^ permalink raw reply

* Re: [PATCH] mac80211: implement STA CSA for drivers using channel contexts
From: Arik Nemtsov @ 2013-08-16 20:09 UTC (permalink / raw)
  To: Johannes Berg; +Cc: linux-wireless@vger.kernel.org
In-Reply-To: <1376650616.15299.16.camel@jlt4.sipsolutions.net>

On Fri, Aug 16, 2013 at 1:56 PM, Johannes Berg
<johannes@sipsolutions.net> wrote:
>> Well right now ieee80211_chswitch_work() takes care of it, and does
>> something a bit different there to accommodate the legacy behavior -
>> if the chan_switch op is defined, ieee80211_hw_config is not called.
>> Would you prefer that ieee80211_vif_change_channel() handle all this,
>> checking interface type to do the right thing?
>
> Well, it can't. If you look carefully then the old chan_switch op
> behaviour is to let the driver switch, not switch in software
> afterwards.

The right thing for chan_switch drivers would be not to call hw_config()..

>
>> I only added it since the current implementation of
>> ieee80211_vif_change_channel() bails if it's false. That said, I'm not
>> sure what's wrong here. This setting is per-vif.
>
> Yeah but it's (currently) meant for interfaces controlling the CSA (i.e.
> AP only right now) ... so I really think we need to make this
> controllable, I think that when we want to implement it for Intel MVM
> firmware then we'll let the firmware control the switch timing, etc.
> None of this can even be done today or with your patch.

The TI driver implements the chan_switch op and uses channel contexts.
If I catch your drift you would rather these kind of drivers (which
include MVM) use a new API exposed by mac80211 to complete the channel
switch. This API would basically be ieee80211_vif_change_channel(). Do
we still need to touch the cfg80211 chandef definition in ifmgd?

The above is maybe cleaner, but it's functionally equivalent to the
solution today - the low level driver decides when the channel switch
is completed, and ieee80211_chswitch_work() is called, which does the
right thing for all cases.
Note that with the above, the channel_contexts + software chan-switch
drivers will still need the kind of code that I wrote. So it would
just lead to replicated code. Or maybe you meant something else?

Also, where would you put csa_active = true (if at all) for a STA
interface? Unlike AP, the trigger here is mac80211 code. So putting it
there seemed appropriate.

Arik

^ permalink raw reply

* [PATCH 8/8] staging: vt6656: desc.h remove typedef tagSTxDataHead_a_FB  to new structure in rxtx.h
From: Malcolm Priestley @ 2013-08-16 22:51 UTC (permalink / raw)
  To: gregkh; +Cc: linux-wireless

To new structure.
typedef struct tagSTxDataHead_a_FB -> struct vnt_tx_datahead_a_fb

This is only needed by rxtc.c so moved to rxtx.h visible to
vnt_rts* structures which it will eventually form part of
their structure.

Signed-off-by: Malcolm Priestley <tvboxspy@gmail.com>
---
 drivers/staging/vt6656/desc.h | 15 ---------------
 drivers/staging/vt6656/rxtx.c | 15 ++++++++-------
 drivers/staging/vt6656/rxtx.h | 10 ++++++++++
 3 files changed, 18 insertions(+), 22 deletions(-)

diff --git a/drivers/staging/vt6656/desc.h b/drivers/staging/vt6656/desc.h
index d350fd3..b3e8cc1 100644
--- a/drivers/staging/vt6656/desc.h
+++ b/drivers/staging/vt6656/desc.h
@@ -164,21 +164,6 @@ STxShortBufHead, *PSTxShortBufHead;
 typedef const STxShortBufHead *PCSTxShortBufHead;
 
 /*
- * TX data header
- */
-typedef struct tagSTxDataHead_a_FB {
-    u8    bySignalField;
-    u8    byServiceField;
-    u16    wTransmitLength;
-    u16    wDuration;
-    u16    wTimeStampOff;
-    u16    wDuration_f0;
-    u16    wDuration_f1;
-} __attribute__ ((__packed__))
-STxDataHead_a_FB, *PSTxDataHead_a_FB;
-typedef const STxDataHead_a_FB *PCSTxDataHead_a_FB;
-
-/*
  * MICHDR data header
  */
 typedef struct tagSMICHDRHead {
diff --git a/drivers/staging/vt6656/rxtx.c b/drivers/staging/vt6656/rxtx.c
index a4d3728..d7f920d 100644
--- a/drivers/staging/vt6656/rxtx.c
+++ b/drivers/staging/vt6656/rxtx.c
@@ -563,7 +563,8 @@ static u32 s_uFillDataHead(struct vnt_private *pDevice,
     else if (byPktType == PK_TYPE_11A) {
         if ((byFBOption != AUTO_FB_NONE) && (uDMAIdx != TYPE_ATIMDMA) && (uDMAIdx != TYPE_BEACONDMA)) {
             // Auto Fallback
-            PSTxDataHead_a_FB pBuf = (PSTxDataHead_a_FB)pTxDataHead;
+		struct vnt_tx_datahead_a_fb *pBuf =
+			(struct vnt_tx_datahead_a_fb *)pTxDataHead;
             //Get SignalField,ServiceField,Length
             BBvCalculateParameter(pDevice, cbFrameLength, wCurrentRate, byPktType,
                 (u16 *)&(pBuf->wTransmitLength), (u8 *)&(pBuf->byServiceField), (u8 *)&(pBuf->bySignalField)
@@ -1262,12 +1263,12 @@ static int s_bPacketToWirelessUsb(struct vnt_private *pDevice, u8 byPktType,
 		pvRTS = (struct vnt_rts_a_fb *) (pbyTxBufferAddr + wTxBufSize +
 				sizeof(struct vnt_rrv_time_ab) + cbMICHDR);
                 pvCTS = NULL;
-		pvTxDataHd = (PSTxDataHead_a_FB) (pbyTxBufferAddr + wTxBufSize +
-			sizeof(struct vnt_rrv_time_ab) + cbMICHDR +
+		pvTxDataHd = (struct vnt_tx_datahead_a_fb *)(pbyTxBufferAddr +
+			wTxBufSize + sizeof(struct vnt_rrv_time_ab) + cbMICHDR +
 					sizeof(struct vnt_rts_a_fb));
 		cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_ab) +
 			cbMICHDR + sizeof(struct vnt_rts_a_fb) +
-					sizeof(STxDataHead_a_FB);
+					sizeof(struct vnt_tx_datahead_a_fb);
             }
             else if (bRTS == false) { //RTS_needless
 		pvRrvTime = (struct vnt_rrv_time_ab *)(pbyTxBufferAddr +
@@ -1276,10 +1277,10 @@ static int s_bPacketToWirelessUsb(struct vnt_private *pDevice, u8 byPktType,
 						sizeof(struct vnt_rrv_time_ab));
                 pvRTS = NULL;
                 pvCTS = NULL;
-		pvTxDataHd = (PSTxDataHead_a_FB) (pbyTxBufferAddr + wTxBufSize +
-			sizeof(struct vnt_rrv_time_ab) + cbMICHDR);
+		pvTxDataHd = (struct vnt_tx_datahead_a_fb *)(pbyTxBufferAddr +
+			wTxBufSize + sizeof(struct vnt_rrv_time_ab) + cbMICHDR);
 		cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_ab) +
-			cbMICHDR + sizeof(STxDataHead_a_FB);
+			cbMICHDR + sizeof(struct vnt_tx_datahead_a_fb);
             }
         } // Auto Fall Back
     }
diff --git a/drivers/staging/vt6656/rxtx.h b/drivers/staging/vt6656/rxtx.h
index d66d71d..b1ef90e 100644
--- a/drivers/staging/vt6656/rxtx.h
+++ b/drivers/staging/vt6656/rxtx.h
@@ -91,6 +91,16 @@ struct vnt_tx_datahead_ab {
 	u16 wTimeStampOff;
 } __packed;
 
+struct vnt_tx_datahead_a_fb {
+	u8 bySignalField;
+	u8 byServiceField;
+	u16 wTransmitLength;
+	u16 wDuration;
+	u16 wTimeStampOff;
+	u16 wDuration_f0;
+	u16 wDuration_f1;
+} __packed;
+
 /* RTS buffer header */
 struct vnt_rts_g {
 	u8 bySignalField_b;
-- 
1.8.1.2


^ permalink raw reply related

* [PATCH 7/8] staging: vt6656: desc.h remove typedef tagSTxDataHead_ab  to new structure in rxtx.h
From: Malcolm Priestley @ 2013-08-16 22:50 UTC (permalink / raw)
  To: gregkh; +Cc: linux-wireless

To new structure.
typedef struct tagSTxDataHead_ab -> struct vnt_tx_datahead_ab

This is only needed by rxtc.c so moved to rxtx.h visible to
vnt_rts* structures which it will eventually form part of
their structure.

Signed-off-by: Malcolm Priestley <tvboxspy@gmail.com>
---
 drivers/staging/vt6656/desc.h | 10 --------
 drivers/staging/vt6656/rxtx.c | 55 ++++++++++++++++++++++++-------------------
 drivers/staging/vt6656/rxtx.h |  8 +++++++
 3 files changed, 39 insertions(+), 34 deletions(-)

diff --git a/drivers/staging/vt6656/desc.h b/drivers/staging/vt6656/desc.h
index 1ee0331..d350fd3 100644
--- a/drivers/staging/vt6656/desc.h
+++ b/drivers/staging/vt6656/desc.h
@@ -166,16 +166,6 @@ typedef const STxShortBufHead *PCSTxShortBufHead;
 /*
  * TX data header
  */
-typedef struct tagSTxDataHead_ab {
-    u8    bySignalField;
-    u8    byServiceField;
-    u16    wTransmitLength;
-    u16    wDuration;
-    u16    wTimeStampOff;
-} __attribute__ ((__packed__))
-STxDataHead_ab, *PSTxDataHead_ab;
-typedef const STxDataHead_ab *PCSTxDataHead_ab;
-
 typedef struct tagSTxDataHead_a_FB {
     u8    bySignalField;
     u8    byServiceField;
diff --git a/drivers/staging/vt6656/rxtx.c b/drivers/staging/vt6656/rxtx.c
index 20c4656..a4d3728 100644
--- a/drivers/staging/vt6656/rxtx.c
+++ b/drivers/staging/vt6656/rxtx.c
@@ -500,7 +500,8 @@ static u32 s_uFillDataHead(struct vnt_private *pDevice,
 
     if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
 	if ((uDMAIdx == TYPE_ATIMDMA) || (uDMAIdx == TYPE_BEACONDMA)) {
-		PSTxDataHead_ab pBuf = (PSTxDataHead_ab) pTxDataHead;
+		struct vnt_tx_datahead_ab *pBuf =
+			(struct vnt_tx_datahead_ab *)pTxDataHead;
             //Get SignalField,ServiceField,Length
             BBvCalculateParameter(pDevice, cbFrameLength, wCurrentRate, byPktType,
                 (u16 *)&(pBuf->wTransmitLength), (u8 *)&(pBuf->byServiceField), (u8 *)&(pBuf->bySignalField)
@@ -579,7 +580,8 @@ static u32 s_uFillDataHead(struct vnt_private *pDevice,
             }
             return (pBuf->wDuration);
         } else {
-            PSTxDataHead_ab pBuf = (PSTxDataHead_ab)pTxDataHead;
+		struct vnt_tx_datahead_ab *pBuf =
+			(struct vnt_tx_datahead_ab *)pTxDataHead;
             //Get SignalField,ServiceField,Length
             BBvCalculateParameter(pDevice, cbFrameLength, wCurrentRate, byPktType,
                 (u16 *)&(pBuf->wTransmitLength), (u8 *)&(pBuf->byServiceField), (u8 *)&(pBuf->bySignalField)
@@ -595,7 +597,8 @@ static u32 s_uFillDataHead(struct vnt_private *pDevice,
         }
     }
     else if (byPktType == PK_TYPE_11B) {
-            PSTxDataHead_ab pBuf = (PSTxDataHead_ab)pTxDataHead;
+		struct vnt_tx_datahead_ab *pBuf =
+			(struct vnt_tx_datahead_ab *)pTxDataHead;
             //Get SignalField,ServiceField,Length
             BBvCalculateParameter(pDevice, cbFrameLength, wCurrentRate, byPktType,
                 (u16 *)&(pBuf->wTransmitLength), (u8 *)&(pBuf->byServiceField), (u8 *)&(pBuf->bySignalField)
@@ -1230,12 +1233,12 @@ static int s_bPacketToWirelessUsb(struct vnt_private *pDevice, u8 byPktType,
 		pvRTS = (struct vnt_rts_ab *) (pbyTxBufferAddr + wTxBufSize +
 				sizeof(struct vnt_rrv_time_ab) + cbMICHDR);
                 pvCTS = NULL;
-		pvTxDataHd = (PSTxDataHead_ab) (pbyTxBufferAddr + wTxBufSize +
-			sizeof(struct vnt_rrv_time_ab) + cbMICHDR +
+		pvTxDataHd = (struct vnt_tx_datahead_ab *)(pbyTxBufferAddr +
+			wTxBufSize + sizeof(struct vnt_rrv_time_ab) + cbMICHDR +
 						sizeof(struct vnt_rts_ab));
 		cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_ab) +
 			cbMICHDR + sizeof(struct vnt_rts_ab) +
-				sizeof(STxDataHead_ab);
+				sizeof(struct vnt_tx_datahead_ab);
             }
             else if (bRTS == false) { //RTS_needless, no MICHDR
 		pvRrvTime = (struct vnt_rrv_time_ab *)(pbyTxBufferAddr +
@@ -1244,10 +1247,10 @@ static int s_bPacketToWirelessUsb(struct vnt_private *pDevice, u8 byPktType,
 						sizeof(struct vnt_rrv_time_ab));
                 pvRTS = NULL;
                 pvCTS = NULL;
-		pvTxDataHd = (PSTxDataHead_ab) (pbyTxBufferAddr + wTxBufSize +
-				sizeof(struct vnt_rrv_time_ab) + cbMICHDR);
+		pvTxDataHd = (struct vnt_tx_datahead_ab *)(pbyTxBufferAddr +
+			wTxBufSize + sizeof(struct vnt_rrv_time_ab) + cbMICHDR);
 		cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_ab) +
-					cbMICHDR + sizeof(STxDataHead_ab);
+				cbMICHDR + sizeof(struct vnt_tx_datahead_ab);
             }
         } else {
             // Auto Fall Back
@@ -1700,10 +1703,10 @@ CMD_STATUS csMgmt_xmit(struct vnt_private *pDevice,
         pMICHDR = NULL;
         pvRTS = NULL;
         pCTS = NULL;
-	pvTxDataHd = (PSTxDataHead_ab) (pbyTxBufferAddr + wTxBufSize +
-					sizeof(struct vnt_rrv_time_ab));
+	pvTxDataHd = (struct vnt_tx_datahead_ab *) (pbyTxBufferAddr +
+		wTxBufSize + sizeof(struct vnt_rrv_time_ab));
 	cbHeaderSize = wTxBufSize + sizeof(struct vnt_rrv_time_ab) +
-		sizeof(STxDataHead_ab);
+		sizeof(struct vnt_tx_datahead_ab);
     }
 
     memcpy(&(sEthHeader.h_dest[0]),
@@ -1792,8 +1795,9 @@ CMD_STATUS csMgmt_xmit(struct vnt_private *pDevice,
 		((struct vnt_tx_datahead_g *)pvTxDataHd)->wDuration_b =
 			cpu_to_le16(pPacket->p80211Header->sA2.wDurationID);
 	} else {
-            ((PSTxDataHead_ab)pvTxDataHd)->wDuration = cpu_to_le16(pPacket->p80211Header->sA2.wDurationID);
-        }
+		((struct vnt_tx_datahead_ab *)pvTxDataHd)->wDuration =
+			cpu_to_le16(pPacket->p80211Header->sA2.wDurationID);
+	}
     }
 
     pTX_Buffer->wTxByteCount = cpu_to_le16((u16)(cbReqCount));
@@ -1824,7 +1828,7 @@ CMD_STATUS csBeacon_xmit(struct vnt_private *pDevice,
 	u16 wTxBufSize = sizeof(STxShortBufHead);
 	PSTxShortBufHead pTxBufHead;
 	struct ieee80211_hdr *pMACHeader;
-	PSTxDataHead_ab pTxDataHead;
+	struct vnt_tx_datahead_ab *pTxDataHead;
 	u16 wCurrentRate;
 	u32 cbFrameBodySize;
 	u32 cbReqCount;
@@ -1849,7 +1853,8 @@ CMD_STATUS csBeacon_xmit(struct vnt_private *pDevice,
 
     if (pDevice->byBBType == BB_TYPE_11A) {
         wCurrentRate = RATE_6M;
-        pTxDataHead = (PSTxDataHead_ab) (pbyTxBufferAddr + wTxBufSize);
+	pTxDataHead = (struct vnt_tx_datahead_ab *)
+			(pbyTxBufferAddr + wTxBufSize);
         //Get SignalField,ServiceField,Length
         BBvCalculateParameter(pDevice, cbFrameSize, wCurrentRate, PK_TYPE_11A,
             (u16 *)&(pTxDataHead->wTransmitLength), (u8 *)&(pTxDataHead->byServiceField), (u8 *)&(pTxDataHead->bySignalField)
@@ -1858,11 +1863,12 @@ CMD_STATUS csBeacon_xmit(struct vnt_private *pDevice,
 	pTxDataHead->wDuration = cpu_to_le16((u16)s_uGetDataDuration(pDevice,
 				DATADUR_A, PK_TYPE_11A, false));
         pTxDataHead->wTimeStampOff = wTimeStampOff[pDevice->byPreambleType%2][wCurrentRate%MAX_RATE];
-        cbHeaderSize = wTxBufSize + sizeof(STxDataHead_ab);
+	cbHeaderSize = wTxBufSize + sizeof(struct vnt_tx_datahead_ab);
     } else {
         wCurrentRate = RATE_1M;
         pTxBufHead->wFIFOCtl |= FIFOCTL_11B;
-        pTxDataHead = (PSTxDataHead_ab) (pbyTxBufferAddr + wTxBufSize);
+	pTxDataHead = (struct vnt_tx_datahead_ab *)
+				(pbyTxBufferAddr + wTxBufSize);
         //Get SignalField,ServiceField,Length
         BBvCalculateParameter(pDevice, cbFrameSize, wCurrentRate, PK_TYPE_11B,
             (u16 *)&(pTxDataHead->wTransmitLength), (u8 *)&(pTxDataHead->byServiceField), (u8 *)&(pTxDataHead->bySignalField)
@@ -1871,7 +1877,7 @@ CMD_STATUS csBeacon_xmit(struct vnt_private *pDevice,
 	pTxDataHead->wDuration = cpu_to_le16((u16)s_uGetDataDuration(pDevice,
 				DATADUR_B, PK_TYPE_11B, false));
         pTxDataHead->wTimeStampOff = wTimeStampOff[pDevice->byPreambleType%2][wCurrentRate%MAX_RATE];
-        cbHeaderSize = wTxBufSize + sizeof(STxDataHead_ab);
+	cbHeaderSize = wTxBufSize + sizeof(struct vnt_tx_datahead_ab);
     }
 
     //Generate Beacon Header
@@ -2111,10 +2117,10 @@ void vDMA0_tx_80211(struct vnt_private *pDevice, struct sk_buff *skb)
 		sizeof(struct vnt_rrv_time_ab));
         pvRTS = NULL;
         pvCTS = NULL;
-	pvTxDataHd = (PSTxDataHead_ab) (pbyTxBufferAddr + wTxBufSize +
-		sizeof(struct vnt_rrv_time_ab) + cbMICHDR);
+	pvTxDataHd = (struct vnt_tx_datahead_ab *)(pbyTxBufferAddr +
+		wTxBufSize + sizeof(struct vnt_rrv_time_ab) + cbMICHDR);
 	cbHeaderSize = wTxBufSize + sizeof(struct vnt_rrv_time_ab) + cbMICHDR +
-							sizeof(STxDataHead_ab);
+					sizeof(struct vnt_tx_datahead_ab);
     }
     memcpy(&(sEthHeader.h_dest[0]),
 	   &(p80211Header->sA3.abyAddr1[0]),
@@ -2248,8 +2254,9 @@ void vDMA0_tx_80211(struct vnt_private *pDevice, struct sk_buff *skb)
 		((struct vnt_tx_datahead_g *)pvTxDataHd)->wDuration_b =
 			cpu_to_le16(p80211Header->sA2.wDurationID);
 	} else {
-            ((PSTxDataHead_ab)pvTxDataHd)->wDuration = cpu_to_le16(p80211Header->sA2.wDurationID);
-        }
+		((struct vnt_tx_datahead_ab *)pvTxDataHd)->wDuration =
+			cpu_to_le16(p80211Header->sA2.wDurationID);
+	}
     }
 
     pTX_Buffer->wTxByteCount = cpu_to_le16((u16)(cbReqCount));
diff --git a/drivers/staging/vt6656/rxtx.h b/drivers/staging/vt6656/rxtx.h
index ba80271..d66d71d 100644
--- a/drivers/staging/vt6656/rxtx.h
+++ b/drivers/staging/vt6656/rxtx.h
@@ -83,6 +83,14 @@ struct vnt_tx_datahead_g_fb {
 	u16 wTimeStampOff_a;
 } __packed;
 
+struct vnt_tx_datahead_ab {
+	u8 bySignalField;
+	u8 byServiceField;
+	u16 wTransmitLength;
+	u16 wDuration;
+	u16 wTimeStampOff;
+} __packed;
+
 /* RTS buffer header */
 struct vnt_rts_g {
 	u8 bySignalField_b;
-- 
1.8.1.2


^ permalink raw reply related

* [PATCH 6/8] staging: vt6656: desc.h remove typedef tagSTxDataHead_g_FB  to new structure in rxtx.h
From: Malcolm Priestley @ 2013-08-16 22:49 UTC (permalink / raw)
  To: gregkh; +Cc: linux-wireless

To new structure.
typedef struct tagSTxDataHead_g_FB -> struct vnt_tx_datahead_g_fb

This is only needed by rxtc.c so moved to rxtx.h visible to
vnt_rts*/vnt_cts* structures which it will eventually form part of
their structure.

Signed-off-by: Malcolm Priestley <tvboxspy@gmail.com>
---
 drivers/staging/vt6656/desc.h | 17 -----------------
 drivers/staging/vt6656/rxtx.c | 15 ++++++++-------
 drivers/staging/vt6656/rxtx.h | 15 +++++++++++++++
 3 files changed, 23 insertions(+), 24 deletions(-)

diff --git a/drivers/staging/vt6656/desc.h b/drivers/staging/vt6656/desc.h
index b0cb8c4..1ee0331 100644
--- a/drivers/staging/vt6656/desc.h
+++ b/drivers/staging/vt6656/desc.h
@@ -166,23 +166,6 @@ typedef const STxShortBufHead *PCSTxShortBufHead;
 /*
  * TX data header
  */
-typedef struct tagSTxDataHead_g_FB {
-    u8    bySignalField_b;
-    u8    byServiceField_b;
-    u16    wTransmitLength_b;
-    u8    bySignalField_a;
-    u8    byServiceField_a;
-    u16    wTransmitLength_a;
-    u16    wDuration_b;
-    u16    wDuration_a;
-    u16    wDuration_a_f0;
-    u16    wDuration_a_f1;
-    u16    wTimeStampOff_b;
-    u16    wTimeStampOff_a;
-} __attribute__ ((__packed__))
-STxDataHead_g_FB, *PSTxDataHead_g_FB;
-typedef const STxDataHead_g_FB *PCSTxDataHead_g_FB;
-
 typedef struct tagSTxDataHead_ab {
     u8    bySignalField;
     u8    byServiceField;
diff --git a/drivers/staging/vt6656/rxtx.c b/drivers/staging/vt6656/rxtx.c
index 585a2e3..20c4656 100644
--- a/drivers/staging/vt6656/rxtx.c
+++ b/drivers/staging/vt6656/rxtx.c
@@ -535,7 +535,8 @@ static u32 s_uFillDataHead(struct vnt_private *pDevice,
                 return (pBuf->wDuration_a);
              } else {
                 // Auto Fallback
-                PSTxDataHead_g_FB pBuf = (PSTxDataHead_g_FB)pTxDataHead;
+		struct vnt_tx_datahead_g_fb *pBuf =
+			(struct vnt_tx_datahead_g_fb *)pTxDataHead;
                 //Get SignalField,ServiceField,Length
                 BBvCalculateParameter(pDevice, cbFrameLength, wCurrentRate, byPktType,
                     (u16 *)&(pBuf->wTransmitLength_a), (u8 *)&(pBuf->byServiceField_a), (u8 *)&(pBuf->bySignalField_a)
@@ -1195,12 +1196,12 @@ static int s_bPacketToWirelessUsb(struct vnt_private *pDevice, u8 byPktType,
 		pvRTS = (struct vnt_rts_g_fb *) (pbyTxBufferAddr + wTxBufSize +
 				sizeof(struct vnt_rrv_time_rts) + cbMICHDR);
                 pvCTS = NULL;
-		pvTxDataHd = (PSTxDataHead_g_FB) (pbyTxBufferAddr + wTxBufSize +
-			sizeof(struct vnt_rrv_time_rts) + cbMICHDR +
-					sizeof(struct vnt_rts_g_fb));
+		pvTxDataHd = (struct vnt_tx_datahead_g_fb *) (pbyTxBufferAddr +
+			wTxBufSize + sizeof(struct vnt_rrv_time_rts) +
+				cbMICHDR + sizeof(struct vnt_rts_g_fb));
 		cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_rts) +
 			cbMICHDR + sizeof(struct vnt_rts_g_fb) +
-				sizeof(STxDataHead_g_FB);
+				sizeof(struct vnt_tx_datahead_g_fb);
             }
             else if (bRTS == false) { //RTS_needless
 		pvRrvTime = (struct vnt_rrv_time_cts *)
@@ -1210,12 +1211,12 @@ static int s_bPacketToWirelessUsb(struct vnt_private *pDevice, u8 byPktType,
                 pvRTS = NULL;
 		pvCTS = (struct vnt_cts_fb *) (pbyTxBufferAddr + wTxBufSize +
 			sizeof(struct vnt_rrv_time_cts) + cbMICHDR);
-		pvTxDataHd = (PSTxDataHead_g_FB) (pbyTxBufferAddr +
+		pvTxDataHd = (struct vnt_tx_datahead_g_fb *) (pbyTxBufferAddr +
 			wTxBufSize + sizeof(struct vnt_rrv_time_cts) +
 				cbMICHDR + sizeof(struct vnt_cts_fb));
 		cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_cts) +
 				cbMICHDR + sizeof(struct vnt_cts_fb) +
-					sizeof(STxDataHead_g_FB);
+					sizeof(struct vnt_tx_datahead_g_fb);
             }
         } // Auto Fall Back
     }
diff --git a/drivers/staging/vt6656/rxtx.h b/drivers/staging/vt6656/rxtx.h
index 3c82623..ba80271 100644
--- a/drivers/staging/vt6656/rxtx.h
+++ b/drivers/staging/vt6656/rxtx.h
@@ -68,6 +68,21 @@ struct vnt_tx_datahead_g {
 	u16 wTimeStampOff_a;
 } __packed;
 
+struct vnt_tx_datahead_g_fb {
+	u8 bySignalField_b;
+	u8 byServiceField_b;
+	u16 wTransmitLength_b;
+	u8 bySignalField_a;
+	u8 byServiceField_a;
+	u16 wTransmitLength_a;
+	u16 wDuration_b;
+	u16 wDuration_a;
+	u16 wDuration_a_f0;
+	u16 wDuration_a_f1;
+	u16 wTimeStampOff_b;
+	u16 wTimeStampOff_a;
+} __packed;
+
 /* RTS buffer header */
 struct vnt_rts_g {
 	u8 bySignalField_b;
-- 
1.8.1.2


^ permalink raw reply related

* [PATCH 5/8] staging: vt6656: desc.h: remove typedef struct tagSTxDataHead_g to new structure in rxtx.h
From: Malcolm Priestley @ 2013-08-16 22:48 UTC (permalink / raw)
  To: gregkh; +Cc: linux-wireless

To new structure.
typedef struct tagSTxDataHead_g -> struct vnt_tx_datahead_g

This is only needed by rxtc.c so moved to rxtx.h visible to
vnt_rts*/vnt_cts* structures which it will eventually form part of
their structure.

Signed-off-by: Malcolm Priestley <tvboxspy@gmail.com>
---
 drivers/staging/vt6656/desc.h | 16 --------------
 drivers/staging/vt6656/rxtx.c | 49 ++++++++++++++++++++++++-------------------
 drivers/staging/vt6656/rxtx.h | 14 +++++++++++++
 3 files changed, 41 insertions(+), 38 deletions(-)

diff --git a/drivers/staging/vt6656/desc.h b/drivers/staging/vt6656/desc.h
index dc089ac..b0cb8c4 100644
--- a/drivers/staging/vt6656/desc.h
+++ b/drivers/staging/vt6656/desc.h
@@ -166,22 +166,6 @@ typedef const STxShortBufHead *PCSTxShortBufHead;
 /*
  * TX data header
  */
-typedef struct tagSTxDataHead_g {
-    u8    bySignalField_b;
-    u8    byServiceField_b;
-    u16    wTransmitLength_b;
-    u8    bySignalField_a;
-    u8    byServiceField_a;
-    u16    wTransmitLength_a;
-    u16    wDuration_b;
-    u16    wDuration_a;
-    u16    wTimeStampOff_b;
-    u16    wTimeStampOff_a;
-} __attribute__ ((__packed__))
-STxDataHead_g, *PSTxDataHead_g;
-
-typedef const STxDataHead_g *PCSTxDataHead_g;
-
 typedef struct tagSTxDataHead_g_FB {
     u8    bySignalField_b;
     u8    byServiceField_b;
diff --git a/drivers/staging/vt6656/rxtx.c b/drivers/staging/vt6656/rxtx.c
index b21a496..585a2e3 100644
--- a/drivers/staging/vt6656/rxtx.c
+++ b/drivers/staging/vt6656/rxtx.c
@@ -515,7 +515,8 @@ static u32 s_uFillDataHead(struct vnt_private *pDevice,
         }
         else { // DATA & MANAGE Frame
             if (byFBOption == AUTO_FB_NONE) {
-                PSTxDataHead_g pBuf = (PSTxDataHead_g)pTxDataHead;
+		struct vnt_tx_datahead_g *pBuf =
+				(struct vnt_tx_datahead_g *)pTxDataHead;
                 //Get SignalField,ServiceField,Length
                 BBvCalculateParameter(pDevice, cbFrameLength, wCurrentRate, byPktType,
                     (u16 *)&(pBuf->wTransmitLength_a), (u8 *)&(pBuf->byServiceField_a), (u8 *)&(pBuf->bySignalField_a)
@@ -1162,12 +1163,12 @@ static int s_bPacketToWirelessUsb(struct vnt_private *pDevice, u8 byPktType,
 		pvRTS = (struct vnt_rts_g *) (pbyTxBufferAddr + wTxBufSize +
 				sizeof(struct vnt_rrv_time_rts) + cbMICHDR);
                 pvCTS = NULL;
-		pvTxDataHd = (PSTxDataHead_g) (pbyTxBufferAddr + wTxBufSize +
-			sizeof(struct vnt_rrv_time_rts) + cbMICHDR +
-						sizeof(struct vnt_rts_g));
+		pvTxDataHd = (struct vnt_tx_datahead_g *) (pbyTxBufferAddr +
+			wTxBufSize + sizeof(struct vnt_rrv_time_rts) +
+				cbMICHDR + sizeof(struct vnt_rts_g));
 		cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_rts) +
 			cbMICHDR + sizeof(struct vnt_rts_g) +
-				sizeof(STxDataHead_g);
+				sizeof(struct vnt_tx_datahead_g);
             }
             else { //RTS_needless
 		pvRrvTime = (struct vnt_rrv_time_cts *)
@@ -1177,12 +1178,12 @@ static int s_bPacketToWirelessUsb(struct vnt_private *pDevice, u8 byPktType,
                 pvRTS = NULL;
 		pvCTS = (struct vnt_cts *) (pbyTxBufferAddr + wTxBufSize +
 				sizeof(struct vnt_rrv_time_cts) + cbMICHDR);
-		pvTxDataHd = (PSTxDataHead_g) (pbyTxBufferAddr + wTxBufSize +
-			sizeof(struct vnt_rrv_time_cts) + cbMICHDR +
-						sizeof(struct vnt_cts));
+		pvTxDataHd = (struct vnt_tx_datahead_g *)(pbyTxBufferAddr +
+			wTxBufSize + sizeof(struct vnt_rrv_time_cts) +
+				cbMICHDR + sizeof(struct vnt_cts));
 		cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_cts) +
 			cbMICHDR + sizeof(struct vnt_cts) +
-				sizeof(STxDataHead_g);
+				sizeof(struct vnt_tx_datahead_g);
             }
         } else {
             // Auto Fall Back
@@ -1688,10 +1689,10 @@ CMD_STATUS csMgmt_xmit(struct vnt_private *pDevice,
         pvRTS = NULL;
 	pCTS = (struct vnt_cts *) (pbyTxBufferAddr + wTxBufSize +
 					sizeof(struct vnt_rrv_time_cts));
-	pvTxDataHd = (PSTxDataHead_g) (pbyTxBufferAddr + wTxBufSize +
+	pvTxDataHd = (struct vnt_tx_datahead_g *)(pbyTxBufferAddr + wTxBufSize +
 		sizeof(struct vnt_rrv_time_cts) + sizeof(struct vnt_cts));
 	cbHeaderSize = wTxBufSize + sizeof(struct vnt_rrv_time_cts) +
-		sizeof(struct vnt_cts) + sizeof(STxDataHead_g);
+		sizeof(struct vnt_cts) + sizeof(struct vnt_tx_datahead_g);
     }
     else { // 802.11a/b packet
 	pvRrvTime = (struct vnt_rrv_time_ab *) (pbyTxBufferAddr + wTxBufSize);
@@ -1784,10 +1785,12 @@ CMD_STATUS csMgmt_xmit(struct vnt_private *pDevice,
         // This will cause AID-field of PS-POLL packet be incorrect (Because PS-POLL's AID field is
         // in the same place of other packet's Duration-field).
         // And it will cause Cisco-AP to issue Disassociation-packet
-        if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
-            ((PSTxDataHead_g)pvTxDataHd)->wDuration_a = cpu_to_le16(pPacket->p80211Header->sA2.wDurationID);
-            ((PSTxDataHead_g)pvTxDataHd)->wDuration_b = cpu_to_le16(pPacket->p80211Header->sA2.wDurationID);
-        } else {
+	if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
+		((struct vnt_tx_datahead_g *)pvTxDataHd)->wDuration_a =
+			cpu_to_le16(pPacket->p80211Header->sA2.wDurationID);
+		((struct vnt_tx_datahead_g *)pvTxDataHd)->wDuration_b =
+			cpu_to_le16(pPacket->p80211Header->sA2.wDurationID);
+	} else {
             ((PSTxDataHead_ab)pvTxDataHd)->wDuration = cpu_to_le16(pPacket->p80211Header->sA2.wDurationID);
         }
     }
@@ -2093,11 +2096,11 @@ void vDMA0_tx_80211(struct vnt_private *pDevice, struct sk_buff *skb)
         pvRTS = NULL;
 	pvCTS = (struct vnt_cts *) (pbyTxBufferAddr + wTxBufSize +
 			sizeof(struct vnt_rrv_time_cts) + cbMICHDR);
-	pvTxDataHd = (PSTxDataHead_g) (pbyTxBufferAddr + wTxBufSize +
-		sizeof(struct vnt_rrv_time_cts) + cbMICHDR +
+	pvTxDataHd = (struct vnt_tx_datahead_g *) (pbyTxBufferAddr +
+		wTxBufSize + sizeof(struct vnt_rrv_time_cts) + cbMICHDR +
 					sizeof(struct vnt_cts));
 	cbHeaderSize = wTxBufSize + sizeof(struct vnt_rrv_time_cts) + cbMICHDR +
-				sizeof(struct vnt_cts) + sizeof(STxDataHead_g);
+		sizeof(struct vnt_cts) + sizeof(struct vnt_tx_datahead_g);
 
     }
     else {//802.11a/b packet
@@ -2238,10 +2241,12 @@ void vDMA0_tx_80211(struct vnt_private *pDevice, struct sk_buff *skb)
         // This will cause AID-field of PS-POLL packet be incorrect (Because PS-POLL's AID field is
         // in the same place of other packet's Duration-field).
         // And it will cause Cisco-AP to issue Disassociation-packet
-        if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
-            ((PSTxDataHead_g)pvTxDataHd)->wDuration_a = cpu_to_le16(p80211Header->sA2.wDurationID);
-            ((PSTxDataHead_g)pvTxDataHd)->wDuration_b = cpu_to_le16(p80211Header->sA2.wDurationID);
-        } else {
+	if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
+		((struct vnt_tx_datahead_g *)pvTxDataHd)->wDuration_a =
+			cpu_to_le16(p80211Header->sA2.wDurationID);
+		((struct vnt_tx_datahead_g *)pvTxDataHd)->wDuration_b =
+			cpu_to_le16(p80211Header->sA2.wDurationID);
+	} else {
             ((PSTxDataHead_ab)pvTxDataHd)->wDuration = cpu_to_le16(p80211Header->sA2.wDurationID);
         }
     }
diff --git a/drivers/staging/vt6656/rxtx.h b/drivers/staging/vt6656/rxtx.h
index 7573760..3c82623 100644
--- a/drivers/staging/vt6656/rxtx.h
+++ b/drivers/staging/vt6656/rxtx.h
@@ -54,6 +54,20 @@ struct vnt_rrv_time_ab {
 	u16 wTxRrvTime;
 } __packed;
 
+/* TX data header */
+struct vnt_tx_datahead_g {
+	u8 bySignalField_b;
+	u8 byServiceField_b;
+	u16 wTransmitLength_b;
+	u8 bySignalField_a;
+	u8 byServiceField_a;
+	u16 wTransmitLength_a;
+	u16 wDuration_b;
+	u16 wDuration_a;
+	u16 wTimeStampOff_b;
+	u16 wTimeStampOff_a;
+} __packed;
+
 /* RTS buffer header */
 struct vnt_rts_g {
 	u8 bySignalField_b;
-- 
1.8.1.2


^ permalink raw reply related

* [PATCH v2] ath9k_htc: Restore skb headroom when returning skb to mac80211
From: Marc Kleine-Budde @ 2013-08-16 19:39 UTC (permalink / raw)
  To: linux-wireless; +Cc: linux, ath9k-devel, Helmut Schaa, Marc Kleine-Budde

From: Helmut Schaa <helmut.schaa@googlemail.com>

ath9k_htc adds padding between the 802.11 header and the payload during
TX by moving the header. When handing the frame back to mac80211 for TX
status handling the header is not moved back into its original position.
This can result in a too small skb headroom when entering ath9k_htc
again (due to a soft retransmission for example) causing an
skb_under_panic oops.

Fix this by moving the 802.11 header back into its original position
before returning the frame to mac80211 as other drivers like rt2x00
or ath5k do.

Reported-by: Marc Kleine-Budde <mkl@blackshift.org>
Signed-off-by: Helmut Schaa <helmut.schaa@googlemail.com>
Tested-by: Marc Kleine-Budde <mkl@blackshift.org>
Signed-off-by: Marc Kleine-Budde <mkl@blackshift.org>
---
Hello Helmut,

I've change the patch a bit, I've used ieee80211_get_hdrlen_from_skb() instead
of open coding it.

Tested in ARMv5 with USB device
  "ID 0cf3:7015 Atheros Communications, Inc. TP-Link TL-WN821N v3 802.11n [Atheros AR7010+AR9287]"
for four weeks. Without that patch the kernel oopes after about one week.

I think this is a candidate for stable, can you add stable to Cc?

regards,
Marc

changes since v1:
- use ieee80211_get_hdrlen_from_skb() instead of open coding it

 drivers/net/wireless/ath/ath9k/htc_drv_txrx.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
index e602c95..c028df7 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
@@ -448,6 +448,7 @@ static void ath9k_htc_tx_process(struct ath9k_htc_priv *priv,
 	struct ieee80211_conf *cur_conf = &priv->hw->conf;
 	bool txok;
 	int slot;
+	int hdrlen, padsize;
 
 	slot = strip_drv_header(priv, skb);
 	if (slot < 0) {
@@ -504,6 +505,15 @@ send_mac80211:
 
 	ath9k_htc_tx_clear_slot(priv, slot);
 
+	/* Remove padding before handing frame back to mac80211 */
+	hdrlen = ieee80211_get_hdrlen_from_skb(skb);
+
+	padsize = hdrlen & 3;
+	if (padsize && skb->len > hdrlen + padsize) {
+		memmove(skb->data + padsize, skb->data, hdrlen);
+		skb_pull(skb, padsize);
+	}
+
 	/* Send status to mac80211 */
 	ieee80211_tx_status(priv->hw, skb);
 }
-- 
1.8.3.1


^ permalink raw reply related

* [PATCH 4/8] staging: vt6656: desc.h remove dead code typedef struct tagSRrvTime_atim.
From: Malcolm Priestley @ 2013-08-16 22:46 UTC (permalink / raw)
  To: gregkh; +Cc: linux-wireless

Remove dead structure tagSRrvTime_atim.

Signed-off-by: Malcolm Priestley <tvboxspy@gmail.com>

---
 drivers/staging/vt6656/desc.h | 11 -----------
 1 file changed, 11 deletions(-)

diff --git a/drivers/staging/vt6656/desc.h b/drivers/staging/vt6656/desc.h
index c2dec3b..dc089ac 100644
--- a/drivers/staging/vt6656/desc.h
+++ b/drivers/staging/vt6656/desc.h
@@ -144,17 +144,6 @@
 #define TD_FLAGS_PS_RETRY  0x04 /* check if PS STA frame re-transmit */
 
 /*
- * RsvTime buffer header
- */
-typedef struct tagSRrvTime_atim {
-    u16        wCTSTxRrvTime_ba;
-    u16        wTxRrvTime_a;
-} __attribute__ ((__packed__))
-SRrvTime_atim, *PSRrvTime_atim;
-
-typedef const SRrvTime_atim *PCSRrvTime_atim;
-
-/*
  * TX FIFO header
  */
 typedef struct tagSTxBufHead {
-- 
1.8.1.2




^ 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