Linux wireless drivers development
 help / color / mirror / Atom feed
* [PATCH 09/12] brcmfmac: remove stale code from brcmf_sdcard_recv_chain()
From: Arend van Spriel @ 2013-10-15 13:44 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless, Arend van Spriel
In-Reply-To: <1381844697-24881-1-git-send-email-arend@broadcom.com>

The function brcmf_sdcard_recv_chain() has been reworked with
commit "brcmfmac: add sdio sg list support", but the incr_fix
variable is only assigned but not used so removing it now.

Reviewed-by: Franky Lin <frankyl@broadcom.com>
Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
Signed-off-by: Arend van Spriel <arend@broadcom.com>
---
 drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c |    2 --
 1 file changed, 2 deletions(-)

diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
index c88e267..92818d79 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
@@ -571,7 +571,6 @@ done:
 int brcmf_sdcard_recv_chain(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn,
 			    uint flags, struct sk_buff_head *pktq)
 {
-	uint incr_fix;
 	uint width;
 	int err = 0;
 
@@ -583,7 +582,6 @@ int brcmf_sdcard_recv_chain(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn,
 	if (err)
 		goto done;
 
-	incr_fix = (flags & SDIO_REQ_FIXED) ? SDIOH_DATA_FIX : SDIOH_DATA_INC;
 	err = brcmf_sdio_sglist_rw(sdiodev, fn, false, addr, pktq);
 
 done:
-- 
1.7.10.4



^ permalink raw reply related

* [PATCH 08/12] brcmfmac: verify result of brcmf_sdio_addrprep() calls
From: Arend van Spriel @ 2013-10-15 13:44 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless, Arend van Spriel
In-Reply-To: <1381844697-24881-1-git-send-email-arend@broadcom.com>

Not all calls to the function brcmf_sdio_addrprep() check
the return value, but it may fail so better verify it.

Reviewed-by: Franky Lin <frankyl@broadcom.com>
Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
Signed-off-by: Arend van Spriel <arend@broadcom.com>
---
 drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c |   15 +++++++++++----
 1 file changed, 11 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
index da02816..c88e267 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
@@ -238,7 +238,9 @@ brcmf_sdio_regrw_helper(struct brcmf_sdio_dev *sdiodev, u32 addr,
 		func_num = SDIO_FUNC_1;
 		reg_size = 4;
 
-		brcmf_sdio_addrprep(sdiodev, reg_size, &addr);
+		ret = brcmf_sdio_addrprep(sdiodev, reg_size, &addr);
+		if (ret)
+			goto done;
 	}
 
 	do {
@@ -254,6 +256,7 @@ brcmf_sdio_regrw_helper(struct brcmf_sdio_dev *sdiodev, u32 addr,
 						       func_num, addr, data, 4);
 	} while (ret != 0 && retry++ < SDIOH_API_ACCESS_RETRY_LIMIT);
 
+done:
 	if (ret != 0)
 		brcmf_err("failed with %d\n", ret);
 
@@ -605,9 +608,10 @@ brcmf_sdcard_send_buf(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn,
 	memcpy(mypkt->data, buf, nbytes);
 
 	width = (flags & SDIO_REQ_4BYTE) ? 4 : 2;
-	brcmf_sdio_addrprep(sdiodev, width, &addr);
+	err = brcmf_sdio_addrprep(sdiodev, width, &addr);
 
-	err = brcmf_sdio_buffrw(sdiodev, fn, true, addr, mypkt);
+	if (!err)
+		err = brcmf_sdio_buffrw(sdiodev, fn, true, addr, mypkt);
 
 	brcmu_pkt_buf_free_skb(mypkt);
 	return err;
@@ -619,12 +623,15 @@ brcmf_sdcard_send_pkt(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn,
 		      uint flags, struct sk_buff_head *pktq)
 {
 	uint width;
+	int err;
 
 	brcmf_dbg(SDIO, "fun = %d, addr = 0x%x, size = %d\n",
 		  fn, addr, pktq->qlen);
 
 	width = (flags & SDIO_REQ_4BYTE) ? 4 : 2;
-	brcmf_sdio_addrprep(sdiodev, width, &addr);
+	err = brcmf_sdio_addrprep(sdiodev, width, &addr);
+	if (err)
+		return err;
 
 	if (pktq->qlen == 1)
 		return brcmf_sdio_buffrw(sdiodev, fn, true, addr, pktq->next);
-- 
1.7.10.4



^ permalink raw reply related

* [PATCH 03/12] brcmfmac: rename variable max_seg_sz to max_seg_cnt for clarity
From: Arend van Spriel @ 2013-10-15 13:44 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless, Arend van Spriel
In-Reply-To: <1381844697-24881-1-git-send-email-arend@broadcom.com>

The variable max_seg_sz in brcmf_sdio_buffrw() respresents the maximum
number of buffers that can be sent in one MMC transfer request. Rename
it to max_seg_cnt to avoid confusion.

Reviewed-by: Franky Lin <frankyl@broadcom.com>
Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
Signed-off-by: Arend van Spriel <arend@broadcom.com>
---
 drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c |   11 ++++++-----
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
index e13b1a6..5dfc96c 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
@@ -332,7 +332,7 @@ static int brcmf_sdio_buffrw(struct brcmf_sdio_dev *sdiodev, uint fn,
 {
 	unsigned int req_sz, func_blk_sz, sg_cnt, sg_data_sz, pkt_offset;
 	unsigned int max_blks, max_req_sz, orig_offset, dst_offset;
-	unsigned short max_seg_sz, seg_sz;
+	unsigned short max_seg_cnt, seg_sz;
 	unsigned char *pkt_data, *orig_data, *dst_data;
 	struct sk_buff *pkt_next = NULL, *local_pkt_next;
 	struct sk_buff_head local_list, *target_list;
@@ -406,13 +406,14 @@ static int brcmf_sdio_buffrw(struct brcmf_sdio_dev *sdiodev, uint fn,
 	max_blks = min_t(unsigned int, host->max_blk_count, 511u);
 	max_req_sz = min_t(unsigned int, host->max_req_size,
 			   max_blks * func_blk_sz);
-	max_seg_sz = min_t(unsigned short, host->max_segs, SG_MAX_SINGLE_ALLOC);
-	max_seg_sz = min_t(unsigned short, max_seg_sz, target_list->qlen);
+	max_seg_cnt = min_t(unsigned short, host->max_segs,
+			    SG_MAX_SINGLE_ALLOC);
+	max_seg_cnt = min_t(unsigned short, max_seg_cnt, target_list->qlen);
 	seg_sz = target_list->qlen;
 	pkt_offset = 0;
 	pkt_next = target_list->next;
 
-	if (sg_alloc_table(&st, max_seg_sz, GFP_KERNEL)) {
+	if (sg_alloc_table(&st, max_seg_cnt, GFP_KERNEL)) {
 		ret = -ENOMEM;
 		goto exit;
 	}
@@ -444,7 +445,7 @@ static int brcmf_sdio_buffrw(struct brcmf_sdio_dev *sdiodev, uint fn,
 				pkt_next = pkt_next->next;
 			}
 
-			if (req_sz >= max_req_sz || sg_cnt >= max_seg_sz)
+			if (req_sz >= max_req_sz || sg_cnt >= max_seg_cnt)
 				break;
 		}
 		seg_sz -= sg_cnt;
-- 
1.7.10.4



^ permalink raw reply related

* [PATCH 07/12] brcmfmac: rework single packet transfers
From: Arend van Spriel @ 2013-10-15 13:44 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless, Arend van Spriel
In-Reply-To: <1381844697-24881-1-git-send-email-arend@broadcom.com>

The function brcmf_sdio_sglist_rw() does a different code path
when packet queue length is 1. Move this to a separate function
reducing overhead in the calling context.

Reviewed-by: Franky Lin <frankyl@broadcom.com>
Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
Signed-off-by: Arend van Spriel <arend@broadcom.com>
---
 drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c |   81 +++++++++++-----------
 1 file changed, 40 insertions(+), 41 deletions(-)

diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
index 344b2d2..da02816 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
@@ -314,6 +314,34 @@ void brcmf_sdio_regwl(struct brcmf_sdio_dev *sdiodev, u32 addr,
 		*ret = retval;
 }
 
+static int brcmf_sdio_buffrw(struct brcmf_sdio_dev *sdiodev, uint fn,
+			     bool write, u32 addr, struct sk_buff *pkt)
+{
+	unsigned int req_sz;
+
+	brcmf_pm_resume_wait(sdiodev, &sdiodev->request_buffer_wait);
+	if (brcmf_pm_resume_error(sdiodev))
+		return -EIO;
+
+	/* Single skb use the standard mmc interface */
+	req_sz = pkt->len + 3;
+	req_sz &= (uint)~3;
+
+	if (write)
+		return sdio_memcpy_toio(sdiodev->func[fn], addr,
+					((u8 *)(pkt->data)),
+					req_sz);
+	else if (fn == 1)
+		return sdio_memcpy_fromio(sdiodev->func[fn],
+					  ((u8 *)(pkt->data)),
+					  addr, req_sz);
+	else
+		/* function 2 read is FIFO operation */
+		return sdio_readsb(sdiodev->func[fn],
+				   ((u8 *)(pkt->data)), addr,
+				   req_sz);
+}
+
 /**
  * brcmf_sdio_sglist_rw - SDIO interface function for block data access
  * @sdiodev: brcmfmac sdio device
@@ -350,27 +378,6 @@ static int brcmf_sdio_sglist_rw(struct brcmf_sdio_dev *sdiodev, uint fn,
 	if (brcmf_pm_resume_error(sdiodev))
 		return -EIO;
 
-	/* Single skb use the standard mmc interface */
-	if (pktlist->qlen == 1) {
-		pkt_next = pktlist->next;
-		req_sz = pkt_next->len + 3;
-		req_sz &= (uint)~3;
-
-		if (write)
-			return sdio_memcpy_toio(sdiodev->func[fn], addr,
-						((u8 *)(pkt_next->data)),
-						req_sz);
-		else if (fn == 1)
-			return sdio_memcpy_fromio(sdiodev->func[fn],
-						  ((u8 *)(pkt_next->data)),
-						  addr, req_sz);
-		else
-			/* function 2 read is FIFO operation */
-			return sdio_readsb(sdiodev->func[fn],
-					   ((u8 *)(pkt_next->data)), addr,
-					   req_sz);
-	}
-
 	target_list = pktlist;
 	/* for host with broken sg support, prepare a page aligned list */
 	__skb_queue_head_init(&local_list);
@@ -543,7 +550,6 @@ brcmf_sdcard_recv_pkt(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn,
 {
 	uint width;
 	int err = 0;
-	struct sk_buff_head pkt_list;
 
 	brcmf_dbg(SDIO, "fun = %d, addr = 0x%x, size = %d\n",
 		  fn, addr, pkt->len);
@@ -553,10 +559,7 @@ brcmf_sdcard_recv_pkt(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn,
 	if (err)
 		goto done;
 
-	skb_queue_head_init(&pkt_list);
-	skb_queue_tail(&pkt_list, pkt);
-	err = brcmf_sdio_sglist_rw(sdiodev, fn, false, addr, &pkt_list);
-	skb_dequeue_tail(&pkt_list);
+	err = brcmf_sdio_buffrw(sdiodev, fn, false, addr, pkt);
 
 done:
 	return err;
@@ -589,7 +592,7 @@ brcmf_sdcard_send_buf(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn,
 		      uint flags, u8 *buf, uint nbytes)
 {
 	struct sk_buff *mypkt;
-	struct sk_buff_head pktq;
+	uint width;
 	int err;
 
 	mypkt = brcmu_pkt_buf_get_skb(nbytes);
@@ -600,10 +603,11 @@ brcmf_sdcard_send_buf(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn,
 	}
 
 	memcpy(mypkt->data, buf, nbytes);
-	__skb_queue_head_init(&pktq);
-	__skb_queue_tail(&pktq, mypkt);
-	err = brcmf_sdcard_send_pkt(sdiodev, addr, fn, flags, &pktq);
-	__skb_dequeue_tail(&pktq);
+
+	width = (flags & SDIO_REQ_4BYTE) ? 4 : 2;
+	brcmf_sdio_addrprep(sdiodev, width, &addr);
+
+	err = brcmf_sdio_buffrw(sdiodev, fn, true, addr, mypkt);
 
 	brcmu_pkt_buf_free_skb(mypkt);
 	return err;
@@ -615,7 +619,6 @@ brcmf_sdcard_send_pkt(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn,
 		      uint flags, struct sk_buff_head *pktq)
 {
 	uint width;
-	int err = 0;
 
 	brcmf_dbg(SDIO, "fun = %d, addr = 0x%x, size = %d\n",
 		  fn, addr, pktq->qlen);
@@ -623,9 +626,9 @@ brcmf_sdcard_send_pkt(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn,
 	width = (flags & SDIO_REQ_4BYTE) ? 4 : 2;
 	brcmf_sdio_addrprep(sdiodev, width, &addr);
 
-	err = brcmf_sdio_sglist_rw(sdiodev, fn, true, addr, pktq);
-
-	return err;
+	if (pktq->qlen == 1)
+		return brcmf_sdio_buffrw(sdiodev, fn, true, addr, pktq->next);
+	return brcmf_sdio_sglist_rw(sdiodev, fn, true, addr, pktq);
 }
 
 int
@@ -636,7 +639,6 @@ brcmf_sdio_ramrw(struct brcmf_sdio_dev *sdiodev, bool write, u32 address,
 	struct sk_buff *pkt;
 	u32 sdaddr;
 	uint dsize;
-	struct sk_buff_head pkt_list;
 
 	dsize = min_t(uint, SBSDIO_SB_OFT_ADDR_LIMIT, size);
 	pkt = dev_alloc_skb(dsize);
@@ -645,7 +647,6 @@ brcmf_sdio_ramrw(struct brcmf_sdio_dev *sdiodev, bool write, u32 address,
 		return -EIO;
 	}
 	pkt->priority = 0;
-	skb_queue_head_init(&pkt_list);
 
 	/* Determine initial transfer parameters */
 	sdaddr = address & SBSDIO_SB_OFT_ADDR_MASK;
@@ -673,10 +674,8 @@ brcmf_sdio_ramrw(struct brcmf_sdio_dev *sdiodev, bool write, u32 address,
 		skb_put(pkt, dsize);
 		if (write)
 			memcpy(pkt->data, data, dsize);
-		skb_queue_tail(&pkt_list, pkt);
-		bcmerror = brcmf_sdio_sglist_rw(sdiodev, SDIO_FUNC_1, write,
-						sdaddr, &pkt_list);
-		skb_dequeue_tail(&pkt_list);
+		bcmerror = brcmf_sdio_buffrw(sdiodev, SDIO_FUNC_1, write,
+					     sdaddr, pkt);
 		if (bcmerror) {
 			brcmf_err("membytes transfer failed\n");
 			break;
-- 
1.7.10.4



^ permalink raw reply related

* [PATCH 10/12] brcmfmac: fix brcmf_sdcard_send_pkt() for host without sg support
From: Arend van Spriel @ 2013-10-15 13:44 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless, Arend van Spriel
In-Reply-To: <1381844697-24881-1-git-send-email-arend@broadcom.com>

If the host does not support scatter-gather transmit the packets
in the pktq individually using brcmf_sdio_buffrw().

Reviewed-by: Franky Lin <frankyl@broadcom.com>
Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
Signed-off-by: Arend van Spriel <arend@broadcom.com>
---
 drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c |   14 +++++++++++---
 1 file changed, 11 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
index 92818d79..1103dc1 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
@@ -620,6 +620,7 @@ int
 brcmf_sdcard_send_pkt(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn,
 		      uint flags, struct sk_buff_head *pktq)
 {
+	struct sk_buff *skb;
 	uint width;
 	int err;
 
@@ -631,9 +632,16 @@ brcmf_sdcard_send_pkt(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn,
 	if (err)
 		return err;
 
-	if (pktq->qlen == 1)
-		return brcmf_sdio_buffrw(sdiodev, fn, true, addr, pktq->next);
-	return brcmf_sdio_sglist_rw(sdiodev, fn, true, addr, pktq);
+	if (pktq->qlen == 1 || !sdiodev->sg_support)
+		skb_queue_walk(pktq, skb) {
+			err = brcmf_sdio_buffrw(sdiodev, fn, true, addr, skb);
+			if (err)
+				break;
+		}
+	else
+		err = brcmf_sdio_sglist_rw(sdiodev, fn, true, addr, pktq);
+
+	return err;
 }
 
 int
-- 
1.7.10.4



^ permalink raw reply related

* [PATCH 06/12] brcmfmac: rename brcmf_sdio_buffrw()
From: Arend van Spriel @ 2013-10-15 13:44 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless, Arend van Spriel
In-Reply-To: <1381844697-24881-1-git-send-email-arend@broadcom.com>

The function brcmf_sdio_buffrw() is intended to be used for
transfering list of packets using scatter-gather functionality.
Rename function to brcmf_sdio_sglist_rw() to clarify this.

Reviewed-by: Franky Lin <frankyl@broadcom.com>
Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
Signed-off-by: Arend van Spriel <arend@broadcom.com>
---
 drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c |   17 +++++++++--------
 1 file changed, 9 insertions(+), 8 deletions(-)

diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
index ea716a4..344b2d2 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
@@ -315,7 +315,7 @@ void brcmf_sdio_regwl(struct brcmf_sdio_dev *sdiodev, u32 addr,
 }
 
 /**
- * brcmf_sdio_buffrw - SDIO interface function for block data access
+ * brcmf_sdio_sglist_rw - SDIO interface function for block data access
  * @sdiodev: brcmfmac sdio device
  * @fn: SDIO function number
  * @write: direction flag
@@ -326,8 +326,9 @@ void brcmf_sdio_regwl(struct brcmf_sdio_dev *sdiodev, u32 addr,
  * stack for block data access. It assumes that the skb passed down by the
  * caller has already been padded and aligned.
  */
-static int brcmf_sdio_buffrw(struct brcmf_sdio_dev *sdiodev, uint fn,
-			     bool write, u32 addr, struct sk_buff_head *pktlist)
+static int brcmf_sdio_sglist_rw(struct brcmf_sdio_dev *sdiodev, uint fn,
+				bool write, u32 addr,
+				struct sk_buff_head *pktlist)
 {
 	unsigned int req_sz, func_blk_sz, sg_cnt, sg_data_sz, pkt_offset;
 	unsigned int max_req_sz, orig_offset, dst_offset;
@@ -554,7 +555,7 @@ brcmf_sdcard_recv_pkt(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn,
 
 	skb_queue_head_init(&pkt_list);
 	skb_queue_tail(&pkt_list, pkt);
-	err = brcmf_sdio_buffrw(sdiodev, fn, false, addr, &pkt_list);
+	err = brcmf_sdio_sglist_rw(sdiodev, fn, false, addr, &pkt_list);
 	skb_dequeue_tail(&pkt_list);
 
 done:
@@ -577,7 +578,7 @@ int brcmf_sdcard_recv_chain(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn,
 		goto done;
 
 	incr_fix = (flags & SDIO_REQ_FIXED) ? SDIOH_DATA_FIX : SDIOH_DATA_INC;
-	err = brcmf_sdio_buffrw(sdiodev, fn, false, addr, pktq);
+	err = brcmf_sdio_sglist_rw(sdiodev, fn, false, addr, pktq);
 
 done:
 	return err;
@@ -622,7 +623,7 @@ brcmf_sdcard_send_pkt(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn,
 	width = (flags & SDIO_REQ_4BYTE) ? 4 : 2;
 	brcmf_sdio_addrprep(sdiodev, width, &addr);
 
-	err = brcmf_sdio_buffrw(sdiodev, fn, true, addr, pktq);
+	err = brcmf_sdio_sglist_rw(sdiodev, fn, true, addr, pktq);
 
 	return err;
 }
@@ -673,8 +674,8 @@ brcmf_sdio_ramrw(struct brcmf_sdio_dev *sdiodev, bool write, u32 address,
 		if (write)
 			memcpy(pkt->data, data, dsize);
 		skb_queue_tail(&pkt_list, pkt);
-		bcmerror = brcmf_sdio_buffrw(sdiodev, SDIO_FUNC_1, write,
-					     sdaddr, &pkt_list);
+		bcmerror = brcmf_sdio_sglist_rw(sdiodev, SDIO_FUNC_1, write,
+						sdaddr, &pkt_list);
 		skb_dequeue_tail(&pkt_list);
 		if (bcmerror) {
 			brcmf_err("membytes transfer failed\n");
-- 
1.7.10.4



^ permalink raw reply related

* [PATCH 01/12] brcmfmac: store address in trace_brcmf_hexdump()
From: Arend van Spriel @ 2013-10-15 13:44 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless, Arend van Spriel
In-Reply-To: <1381844697-24881-1-git-send-email-arend@broadcom.com>

The trace function trace_brcmf_hexdump() stores the length, but
having the address of the buffer being dumped helps putting it
in context.

Reviewed-by: Franky Lin <frankyl@broadcom.com>
Signed-off-by: Arend van Spriel <arend@broadcom.com>
---
 drivers/net/wireless/brcm80211/brcmfmac/tracepoint.h |    4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/brcm80211/brcmfmac/tracepoint.h b/drivers/net/wireless/brcm80211/brcmfmac/tracepoint.h
index bc29171..4605a1d 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/tracepoint.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/tracepoint.h
@@ -78,13 +78,15 @@ TRACE_EVENT(brcmf_hexdump,
 	TP_ARGS(data, len),
 	TP_STRUCT__entry(
 		__field(unsigned long, len)
+		__field(unsigned long, addr)
 		__dynamic_array(u8, hdata, len)
 	),
 	TP_fast_assign(
 		__entry->len = len;
+		__entry->addr = (unsigned long)data;
 		memcpy(__get_dynamic_array(hdata), data, len);
 	),
-	TP_printk("hexdump [length=%lu]", __entry->len)
+	TP_printk("hexdump [addr=%lx, length=%lu]", __entry->addr, __entry->len)
 );
 
 TRACE_EVENT(brcmf_bdchdr,
-- 
1.7.10.4



^ permalink raw reply related

* [PATCH 00/12] brcmfmac: fixes for MMC hosts without scatter-gather
From: Arend van Spriel @ 2013-10-15 13:44 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless, Arend van Spriel

On our internal test setups it turned out that the MMC host controller
did not support scatterlists (struct mmc_host::max_segs == 1). It took
a number of patches to cleanup and support this. While at it some debug
trace functions were modified and added.

Arend van Spriel (12):
  brcmfmac: store address in trace_brcmf_hexdump()
  brcmfmac: add tracepoint for capturing the SDPCM header
  brcmfmac: rename variable max_seg_sz to max_seg_cnt for clarity
  brcmfmac: determine host controller related variables during probe
  brcmfmac: rework scatter-gather code in brcmf_sdio_buffrw()
  brcmfmac: rename brcmf_sdio_buffrw()
  brcmfmac: rework single packet transfers
  brcmfmac: verify result of brcmf_sdio_addrprep() calls
  brcmfmac: remove stale code from brcmf_sdcard_recv_chain()
  brcmfmac: fix brcmf_sdcard_send_pkt() for host without sg support
  brcmfmac: fix brcmf_sdio_txpkt_prep() for host without sg support
  brcmfmac: fix brcmf_sdcard_recv_chain() for host without sg support

 drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c   |  186 +++++++++++---------
 .../net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c |   17 ++
 drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c |  111 +++++++-----
 .../net/wireless/brcm80211/brcmfmac/sdio_host.h    |    6 +-
 .../net/wireless/brcm80211/brcmfmac/tracepoint.h   |   21 ++-
 5 files changed, 216 insertions(+), 125 deletions(-)

-- 
1.7.10.4



^ permalink raw reply

* [PATCH 02/12] brcmfmac: add tracepoint for capturing the SDPCM header
From: Arend van Spriel @ 2013-10-15 13:44 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless, Arend van Spriel
In-Reply-To: <1381844697-24881-1-git-send-email-arend@broadcom.com>

Having the SDPCM header information in the traces is a valuable
piece of information.

Reviewed-by: Franky Lin <frankyl@broadcom.com>
Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
Signed-off-by: Arend van Spriel <arend@broadcom.com>
---
 drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c   |    3 +++
 drivers/net/wireless/brcm80211/brcmfmac/tracepoint.h |   17 +++++++++++++++++
 2 files changed, 20 insertions(+)

diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
index 67f05db..ab1c919 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
@@ -1147,6 +1147,8 @@ static int brcmf_sdio_hdparse(struct brcmf_sdio *bus, u8 *header,
 	u8 rx_seq, fc, tx_seq_max;
 	u32 swheader;
 
+	trace_brcmf_sdpcm_hdr(false, header);
+
 	/* hw header */
 	len = get_unaligned_le16(header);
 	checksum = get_unaligned_le16(header + sizeof(u16));
@@ -1269,6 +1271,7 @@ static void brcmf_sdio_hdpack(struct brcmf_sdio *bus, u8 *header,
 		     SDPCM_DOFFSET_MASK;
 	*(((__le32 *)header) + 1) = cpu_to_le32(sw_header);
 	*(((__le32 *)header) + 2) = 0;
+	trace_brcmf_sdpcm_hdr(true, header);
 }
 
 static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq)
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/tracepoint.h b/drivers/net/wireless/brcm80211/brcmfmac/tracepoint.h
index 4605a1d..3c67529 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/tracepoint.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/tracepoint.h
@@ -110,6 +110,23 @@ TRACE_EVENT(brcmf_bdchdr,
 	TP_printk("bdc: prio=%d siglen=%d", __entry->prio, __entry->siglen)
 );
 
+TRACE_EVENT(brcmf_sdpcm_hdr,
+	TP_PROTO(bool tx, void *data),
+	TP_ARGS(tx, data),
+	TP_STRUCT__entry(
+		__field(u8, tx)
+		__field(u16, len)
+		__array(u8, hdr, 12)
+	),
+	TP_fast_assign(
+		memcpy(__entry->hdr, data, 12);
+		__entry->len = __entry->hdr[0] | (__entry->hdr[1] << 8);
+		__entry->tx = tx ? 1 : 0;
+	),
+	TP_printk("sdpcm: %s len %u, seq %d", __entry->tx ? "TX" : "RX",
+		  __entry->len, __entry->hdr[4])
+);
+
 #ifdef CONFIG_BRCM_TRACING
 
 #undef TRACE_INCLUDE_PATH
-- 
1.7.10.4



^ permalink raw reply related

* [PATCH 11/12] brcmfmac: fix brcmf_sdio_txpkt_prep() for host without sg support
From: Arend van Spriel @ 2013-10-15 13:44 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless, Arend van Spriel
In-Reply-To: <1381844697-24881-1-git-send-email-arend@broadcom.com>

When running on a host controller that does not support scatter-gather
transfers the function brcmf_sdio_txpkt_prep() should not add tail
padding buffers.

Reviewed-by: Franky Lin <frankyl@broadcom.com>
Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
Signed-off-by: Arend van Spriel <arend@broadcom.com>
---
 drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c |  106 ++++++++++++--------
 1 file changed, 64 insertions(+), 42 deletions(-)

diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
index ab1c919..c927701 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
@@ -1880,6 +1880,56 @@ brcmf_sdbrcm_wait_event_wakeup(struct brcmf_sdio *bus)
 /* bit mask of data length chopped from the previous packet */
 #define ALIGN_SKB_CHOP_LEN_MASK	0x7fff
 
+static int brcmf_sdio_txpkt_prep_sg(struct brcmf_sdio_dev *sdiodev,
+				    struct sk_buff_head *pktq,
+				    struct sk_buff *pkt, uint chan)
+{
+	struct sk_buff *pkt_pad;
+	u16 tail_pad, tail_chop, sg_align;
+	unsigned int blksize;
+	u8 *dat_buf;
+	int ntail;
+
+	blksize = sdiodev->func[SDIO_FUNC_2]->cur_blksize;
+	sg_align = 4;
+	if (sdiodev->pdata && sdiodev->pdata->sd_sgentry_align > 4)
+		sg_align = sdiodev->pdata->sd_sgentry_align;
+	/* sg entry alignment should be a divisor of block size */
+	WARN_ON(blksize % sg_align);
+
+	/* Check tail padding */
+	pkt_pad = NULL;
+	tail_chop = pkt->len % sg_align;
+	tail_pad = sg_align - tail_chop;
+	tail_pad += blksize - (pkt->len + tail_pad) % blksize;
+	if (skb_tailroom(pkt) < tail_pad && pkt->len > blksize) {
+		pkt_pad = brcmu_pkt_buf_get_skb(tail_pad + tail_chop);
+		if (pkt_pad == NULL)
+			return -ENOMEM;
+		memcpy(pkt_pad->data,
+		       pkt->data + pkt->len - tail_chop,
+		       tail_chop);
+		*(u32 *)(pkt_pad->cb) = ALIGN_SKB_FLAG + tail_chop;
+		skb_trim(pkt, pkt->len - tail_chop);
+		__skb_queue_after(pktq, pkt, pkt_pad);
+	} else {
+		ntail = pkt->data_len + tail_pad -
+			(pkt->end - pkt->tail);
+		if (skb_cloned(pkt) || ntail > 0)
+			if (pskb_expand_head(pkt, 0, ntail, GFP_ATOMIC))
+				return -ENOMEM;
+		if (skb_linearize(pkt))
+			return -ENOMEM;
+		dat_buf = (u8 *)(pkt->data);
+		__skb_put(pkt, tail_pad);
+	}
+
+	if (pkt_pad)
+		return pkt->len + tail_chop;
+	else
+		return pkt->len - tail_pad;
+}
+
 /**
  * brcmf_sdio_txpkt_prep - packet preparation for transmit
  * @bus: brcmf_sdio structure pointer
@@ -1896,24 +1946,16 @@ static int
 brcmf_sdio_txpkt_prep(struct brcmf_sdio *bus, struct sk_buff_head *pktq,
 		      uint chan)
 {
-	u16 head_pad, tail_pad, tail_chop, head_align, sg_align;
-	int ntail;
-	struct sk_buff *pkt_next, *pkt_new;
+	u16 head_pad, head_align;
+	struct sk_buff *pkt_next;
 	u8 *dat_buf;
-	unsigned blksize = bus->sdiodev->func[SDIO_FUNC_2]->cur_blksize;
+	int err;
 	struct brcmf_sdio_hdrinfo hd_info = {0};
 
 	/* SDIO ADMA requires at least 32 bit alignment */
 	head_align = 4;
-	sg_align = 4;
-	if (bus->sdiodev->pdata) {
-		head_align = bus->sdiodev->pdata->sd_head_align > 4 ?
-			     bus->sdiodev->pdata->sd_head_align : 4;
-		sg_align = bus->sdiodev->pdata->sd_sgentry_align > 4 ?
-			   bus->sdiodev->pdata->sd_sgentry_align : 4;
-	}
-	/* sg entry alignment should be a divisor of block size */
-	WARN_ON(blksize % sg_align);
+	if (bus->sdiodev->pdata && bus->sdiodev->pdata->sd_head_align > 4)
+		head_align = bus->sdiodev->pdata->sd_head_align;
 
 	pkt_next = pktq->next;
 	dat_buf = (u8 *)(pkt_next->data);
@@ -1932,40 +1974,20 @@ brcmf_sdio_txpkt_prep(struct brcmf_sdio *bus, struct sk_buff_head *pktq,
 		memset(dat_buf, 0, head_pad + bus->tx_hdrlen);
 	}
 
-	/* Check tail padding */
-	pkt_new = NULL;
-	tail_chop = pkt_next->len % sg_align;
-	tail_pad = sg_align - tail_chop;
-	tail_pad += blksize - (pkt_next->len + tail_pad) % blksize;
-	if (skb_tailroom(pkt_next) < tail_pad && pkt_next->len > blksize) {
-		pkt_new = brcmu_pkt_buf_get_skb(tail_pad + tail_chop);
-		if (pkt_new == NULL)
-			return -ENOMEM;
-		memcpy(pkt_new->data,
-		       pkt_next->data + pkt_next->len - tail_chop,
-		       tail_chop);
-		*(u32 *)(pkt_new->cb) = ALIGN_SKB_FLAG + tail_chop;
-		skb_trim(pkt_next, pkt_next->len - tail_chop);
-		__skb_queue_after(pktq, pkt_next, pkt_new);
+	if (bus->sdiodev->sg_support && pktq->qlen > 1) {
+		err = brcmf_sdio_txpkt_prep_sg(bus->sdiodev, pktq,
+					       pkt_next, chan);
+		if (err < 0)
+			return err;
+		hd_info.len = (u16)err;
 	} else {
-		ntail = pkt_next->data_len + tail_pad -
-			(pkt_next->end - pkt_next->tail);
-		if (skb_cloned(pkt_next) || ntail > 0)
-			if (pskb_expand_head(pkt_next, 0, ntail, GFP_ATOMIC))
-				return -ENOMEM;
-		if (skb_linearize(pkt_next))
-			return -ENOMEM;
-		dat_buf = (u8 *)(pkt_next->data);
-		__skb_put(pkt_next, tail_pad);
+		hd_info.len = pkt_next->len;
 	}
 
-	/* Now prep the header */
-	if (pkt_new)
-		hd_info.len = pkt_next->len + tail_chop;
-	else
-		hd_info.len = pkt_next->len - tail_pad;
 	hd_info.channel = chan;
 	hd_info.dat_offset = head_pad + bus->tx_hdrlen;
+
+	/* Now fill the header */
 	brcmf_sdio_hdpack(bus, dat_buf, &hd_info);
 
 	if (BRCMF_BYTES_ON() &&
-- 
1.7.10.4



^ permalink raw reply related

* [PATCH 05/12] brcmfmac: rework scatter-gather code in brcmf_sdio_buffrw()
From: Arend van Spriel @ 2013-10-15 13:44 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless, Arend van Spriel
In-Reply-To: <1381844697-24881-1-git-send-email-arend@broadcom.com>

Moving a number of assignments outside of the loop as they are
the same for each request.

Reviewed-by: Franky Lin <frankyl@broadcom.com>
Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
Signed-off-by: Arend van Spriel <arend@broadcom.com>
---
 drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c |   34 ++++++++++++----------
 1 file changed, 19 insertions(+), 15 deletions(-)

diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
index 8c4b506..ea716a4 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
@@ -409,12 +409,26 @@ static int brcmf_sdio_buffrw(struct brcmf_sdio_dev *sdiodev, uint fn,
 		goto exit;
 	}
 
+	memset(&mmc_req, 0, sizeof(struct mmc_request));
+	memset(&mmc_cmd, 0, sizeof(struct mmc_command));
+	memset(&mmc_dat, 0, sizeof(struct mmc_data));
+
+	mmc_dat.sg = st.sgl;
+	mmc_dat.blksz = func_blk_sz;
+	mmc_dat.flags = write ? MMC_DATA_WRITE : MMC_DATA_READ;
+	mmc_cmd.opcode = SD_IO_RW_EXTENDED;
+	mmc_cmd.arg = write ? 1<<31 : 0;	/* write flag  */
+	mmc_cmd.arg |= (fn & 0x7) << 28;	/* SDIO func num */
+	mmc_cmd.arg |= 1<<27;			/* block mode */
+	/* for function 1 the addr will be incremented */
+	mmc_cmd.arg |= (fn == 1) ? 1<<26 : 0;
+	mmc_cmd.flags = MMC_RSP_SPI_R5 | MMC_RSP_R5 | MMC_CMD_ADTC;
+	mmc_req.cmd = &mmc_cmd;
+	mmc_req.data = &mmc_dat;
+
 	while (seg_sz) {
 		req_sz = 0;
 		sg_cnt = 0;
-		memset(&mmc_req, 0, sizeof(struct mmc_request));
-		memset(&mmc_cmd, 0, sizeof(struct mmc_command));
-		memset(&mmc_dat, 0, sizeof(struct mmc_data));
 		sgl = st.sgl;
 		/* prep sg table */
 		while (pkt_next != (struct sk_buff *)target_list) {
@@ -447,22 +461,12 @@ static int brcmf_sdio_buffrw(struct brcmf_sdio_dev *sdiodev, uint fn,
 			ret = -ENOTBLK;
 			goto exit;
 		}
-		mmc_dat.sg = st.sgl;
+
 		mmc_dat.sg_len = sg_cnt;
-		mmc_dat.blksz = func_blk_sz;
 		mmc_dat.blocks = req_sz / func_blk_sz;
-		mmc_dat.flags = write ? MMC_DATA_WRITE : MMC_DATA_READ;
-		mmc_cmd.opcode = SD_IO_RW_EXTENDED;
-		mmc_cmd.arg = write ? 1<<31 : 0;	/* write flag  */
-		mmc_cmd.arg |= (fn & 0x7) << 28;	/* SDIO func num */
-		mmc_cmd.arg |= 1<<27;			/* block mode */
-		/* incrementing addr for function 1 */
-		mmc_cmd.arg |= (fn == 1) ? 1<<26 : 0;
 		mmc_cmd.arg |= (addr & 0x1FFFF) << 9;	/* address */
 		mmc_cmd.arg |= mmc_dat.blocks & 0x1FF;	/* block count */
-		mmc_cmd.flags = MMC_RSP_SPI_R5 | MMC_RSP_R5 | MMC_CMD_ADTC;
-		mmc_req.cmd = &mmc_cmd;
-		mmc_req.data = &mmc_dat;
+		/* incrementing addr for function 1 */
 		if (fn == 1)
 			addr += req_sz;
 
-- 
1.7.10.4



^ permalink raw reply related

* [PATCH 04/12] brcmfmac: determine host controller related variables during probe
From: Arend van Spriel @ 2013-10-15 13:44 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless, Arend van Spriel
In-Reply-To: <1381844697-24881-1-git-send-email-arend@broadcom.com>

Instead of determining the limits for scatter-gather MMC transfer
request upon each transmit it is now determined during the probe
of the SDIO function.

Reviewed-by: Franky Lin <frankyl@broadcom.com>
Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
Signed-off-by: Arend van Spriel <arend@broadcom.com>
---
 drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c   |   23 ++++++--------------
 .../net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c |   17 +++++++++++++++
 .../net/wireless/brcm80211/brcmfmac/sdio_host.h    |    4 ++++
 3 files changed, 28 insertions(+), 16 deletions(-)

diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
index 5dfc96c..8c4b506 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
@@ -26,7 +26,6 @@
 #include <linux/mmc/sdio.h>
 #include <linux/mmc/sdio_func.h>
 #include <linux/mmc/card.h>
-#include <linux/mmc/host.h>
 #include <linux/platform_data/brcmfmac-sdio.h>
 
 #include <defs.h>
@@ -331,7 +330,7 @@ static int brcmf_sdio_buffrw(struct brcmf_sdio_dev *sdiodev, uint fn,
 			     bool write, u32 addr, struct sk_buff_head *pktlist)
 {
 	unsigned int req_sz, func_blk_sz, sg_cnt, sg_data_sz, pkt_offset;
-	unsigned int max_blks, max_req_sz, orig_offset, dst_offset;
+	unsigned int max_req_sz, orig_offset, dst_offset;
 	unsigned short max_seg_cnt, seg_sz;
 	unsigned char *pkt_data, *orig_data, *dst_data;
 	struct sk_buff *pkt_next = NULL, *local_pkt_next;
@@ -341,7 +340,6 @@ static int brcmf_sdio_buffrw(struct brcmf_sdio_dev *sdiodev, uint fn,
 	struct mmc_data mmc_dat;
 	struct sg_table st;
 	struct scatterlist *sgl;
-	struct mmc_host *host;
 	int ret = 0;
 
 	if (!pktlist->qlen)
@@ -398,17 +396,10 @@ static int brcmf_sdio_buffrw(struct brcmf_sdio_dev *sdiodev, uint fn,
 		target_list = &local_list;
 	}
 
-	host = sdiodev->func[fn]->card->host;
 	func_blk_sz = sdiodev->func[fn]->cur_blksize;
-	/* Blocks per command is limited by host count, host transfer
-	 * size and the maximum for IO_RW_EXTENDED of 511 blocks.
-	 */
-	max_blks = min_t(unsigned int, host->max_blk_count, 511u);
-	max_req_sz = min_t(unsigned int, host->max_req_size,
-			   max_blks * func_blk_sz);
-	max_seg_cnt = min_t(unsigned short, host->max_segs,
-			    SG_MAX_SINGLE_ALLOC);
-	max_seg_cnt = min_t(unsigned short, max_seg_cnt, target_list->qlen);
+	max_req_sz = sdiodev->max_request_size;
+	max_seg_cnt = min_t(unsigned short, sdiodev->max_segment_count,
+			    target_list->qlen);
 	seg_sz = target_list->qlen;
 	pkt_offset = 0;
 	pkt_next = target_list->next;
@@ -429,8 +420,8 @@ static int brcmf_sdio_buffrw(struct brcmf_sdio_dev *sdiodev, uint fn,
 		while (pkt_next != (struct sk_buff *)target_list) {
 			pkt_data = pkt_next->data + pkt_offset;
 			sg_data_sz = pkt_next->len - pkt_offset;
-			if (sg_data_sz > host->max_seg_size)
-				sg_data_sz = host->max_seg_size;
+			if (sg_data_sz > sdiodev->max_segment_size)
+				sg_data_sz = sdiodev->max_segment_size;
 			if (sg_data_sz > max_req_sz - req_sz)
 				sg_data_sz = max_req_sz - req_sz;
 
@@ -476,7 +467,7 @@ static int brcmf_sdio_buffrw(struct brcmf_sdio_dev *sdiodev, uint fn,
 			addr += req_sz;
 
 		mmc_set_data_timeout(&mmc_dat, sdiodev->func[fn]->card);
-		mmc_wait_for_req(host, &mmc_req);
+		mmc_wait_for_req(sdiodev->func[fn]->card->host, &mmc_req);
 
 		ret = mmc_cmd.error ? mmc_cmd.error : mmc_dat.error;
 		if (ret != 0) {
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c
index 2a23bf2..905704e 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c
@@ -21,6 +21,7 @@
 #include <linux/mmc/sdio_func.h>
 #include <linux/mmc/sdio_ids.h>
 #include <linux/mmc/card.h>
+#include <linux/mmc/host.h>
 #include <linux/suspend.h>
 #include <linux/errno.h>
 #include <linux/sched.h>	/* request_irq() */
@@ -315,6 +316,8 @@ static int brcmf_ops_sdio_probe(struct sdio_func *func,
 	int err;
 	struct brcmf_sdio_dev *sdiodev;
 	struct brcmf_bus *bus_if;
+	struct mmc_host *host;
+	uint max_blocks;
 
 	brcmf_dbg(SDIO, "Enter\n");
 	brcmf_dbg(SDIO, "Class=%x\n", func->class);
@@ -361,6 +364,20 @@ static int brcmf_ops_sdio_probe(struct sdio_func *func,
 		brcmf_err("F2 error, probe failed %d...\n", err);
 		goto fail;
 	}
+
+	/*
+	 * determine host related variables after brcmf_sdio_probe()
+	 * as func->cur_blksize is properly set and F2 init has been
+	 * completed successfully.
+	 */
+	host = func->card->host;
+	sdiodev->sg_support = host->max_segs > 1;
+	max_blocks = min_t(uint, host->max_blk_count, 511u);
+	sdiodev->max_request_size = min_t(uint, host->max_req_size,
+					  max_blocks * func->cur_blksize);
+	sdiodev->max_segment_count = min_t(uint, host->max_segs,
+					   SG_MAX_SINGLE_ALLOC);
+	sdiodev->max_segment_size = host->max_seg_size;
 	brcmf_dbg(SDIO, "F2 init completed...\n");
 	return 0;
 
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h b/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h
index 2b5407f..59c456f 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h
@@ -178,6 +178,10 @@ struct brcmf_sdio_dev {
 	bool irq_en;			/* irq enable flags */
 	spinlock_t irq_en_lock;
 	bool irq_wake;			/* irq wake enable flags */
+	bool sg_support;
+	uint max_request_size;
+	ushort max_segment_count;
+	uint max_segment_size;
 };
 
 /* Register/deregister interrupt handler. */
-- 
1.7.10.4



^ permalink raw reply related

* RE: [Ilw] drivers/net/wireless/iwlwifi/dvm/tx.c:456 iwlagn_tx_skb+0x6c5/0x883()
From: Grumbach, Emmanuel @ 2013-10-15 13:35 UTC (permalink / raw)
  To: Sander Eikelenboom
  Cc: John W. Linville, Berg, Johannes, ilw@linux.intel.com,
	netdev@vger.kernel.org, linux-wireless@vger.kernel.org
In-Reply-To: <1127865420.20131015151054@eikelenboom.it>

Please apply this:
diff --git a/drivers/net/wireless/iwlwifi/dvm/tx.c b/drivers/net/wireless/iwlwifi/dvm/tx.c
index d131f85..5968f19 100644
--- a/drivers/net/wireless/iwlwifi/dvm/tx.c
+++ b/drivers/net/wireless/iwlwifi/dvm/tx.c
@@ -457,8 +457,8 @@ int iwlagn_tx_skb(struct iwl_priv *priv,
        WARN_ON_ONCE(is_agg &&
                     priv->queue_to_mac80211[txq_id] != info->hw_queue);
 
-       IWL_DEBUG_TX(priv, "TX to [%d|%d] Q:%d - seq: 0x%x\n", sta_id, tid,
-                    txq_id, seq_number);
+       IWL_DEBUG_TX(priv, "TX to [%d|%d] Q:%d info Q %d - seq: 0x%x\n", sta_id, tid,
+                    txq_id, info->hw_queue, seq_number);
 
        if (iwl_trans_tx(priv->trans, skb, dev_cmd, txq_id))
                goto drop_unlock_sta;

and send the output back to me

Thanks.

> 
> >>
> >> Hi,
> >>
> >> I'm having a:
> >>
> >> 02:00.0 Network controller: Intel Corporation Centrino Advanced-N 6235
> (rev
> >> 24)
> >>
> >> And i'm running into this warning on boot with a 3.11.2 and 3.12-rc5
> kernel.
> >>
> >> [   23.904950] ------------[ cut here ]------------
> >> [   23.904957] WARNING: CPU: 0 PID: 2531 at
> >> drivers/net/wireless/iwlwifi/dvm/tx.c:456 iwlagn_tx_skb+0x6c5/0x883()
> 
> > Can you reproduce easily?
> > If yes, please reproduce with debug parameters:
> > modprobe iwlwifi debug=0xC0800000
> 
> > Also, please enable MAC80211_HT_DEBUG
> 
> > Thanks
> 
> It happens when starting hostapd:
> 
> [    7.101116] iwlwifi 0000:02:00.0: L1 Disabled; Enabling L0S
> [    7.110722] iwlwifi 0000:02:00.0: Radio type=0x2-0x1-0x0
> [    7.154478] iwlwifi 0000:02:00.0: U iwl_trans_pcie_txq_enable Activate
> queue 9 on FIFO 7 WrPtr: 0
> [    7.157691] iwlwifi 0000:02:00.0: U iwl_trans_pcie_txq_enable Activate
> queue 0 on FIFO 3 WrPtr: 0
> [    7.160812] iwlwifi 0000:02:00.0: U iwl_trans_pcie_txq_enable Activate
> queue 1 on FIFO 2 WrPtr: 0
> [    7.164900] iwlwifi 0000:02:00.0: U iwl_trans_pcie_txq_enable Activate
> queue 2 on FIFO 1 WrPtr: 0
> [    7.165019] iwlwifi 0000:02:00.0: U iwl_trans_pcie_txq_enable Activate
> queue 3 on FIFO 0 WrPtr: 0
> [    7.165139] iwlwifi 0000:02:00.0: U iwl_trans_pcie_txq_enable Activate
> queue 4 on FIFO 0 WrPtr: 0
> [    7.165258] iwlwifi 0000:02:00.0: U iwl_trans_pcie_txq_enable Activate
> queue 5 on FIFO 4 WrPtr: 0
> [    7.165377] iwlwifi 0000:02:00.0: U iwl_trans_pcie_txq_enable Activate
> queue 6 on FIFO 2 WrPtr: 0
> [    7.165495] iwlwifi 0000:02:00.0: U iwl_trans_pcie_txq_enable Activate
> queue 7 on FIFO 5 WrPtr: 0
> [    7.165614] iwlwifi 0000:02:00.0: U iwl_trans_pcie_txq_enable Activate
> queue 8 on FIFO 4 WrPtr: 0
> [    7.165733] iwlwifi 0000:02:00.0: U iwl_trans_pcie_txq_enable Activate
> queue 10 on FIFO 5 WrPtr: 0
> [    7.404295] iwlwifi 0000:02:00.0: L1 Disabled; Enabling L0S
> [    7.415368] iwlwifi 0000:02:00.0: Radio type=0x2-0x1-0x0
> [    7.462417] iwlwifi 0000:02:00.0: U iwl_trans_pcie_txq_enable Activate
> queue 9 on FIFO 7 WrPtr: 0
> [    7.466588] iwlwifi 0000:02:00.0: U iwl_trans_pcie_txq_enable Activate
> queue 0 on FIFO 3 WrPtr: 0
> [    7.470415] iwlwifi 0000:02:00.0: U iwl_trans_pcie_txq_enable Activate
> queue 1 on FIFO 2 WrPtr: 0
> [    7.474144] iwlwifi 0000:02:00.0: U iwl_trans_pcie_txq_enable Activate
> queue 2 on FIFO 1 WrPtr: 0
> [    7.477514] iwlwifi 0000:02:00.0: U iwl_trans_pcie_txq_enable Activate
> queue 3 on FIFO 0 WrPtr: 0
> [    7.480843] iwlwifi 0000:02:00.0: U iwl_trans_pcie_txq_enable Activate
> queue 4 on FIFO 0 WrPtr: 0
> [    7.484148] iwlwifi 0000:02:00.0: U iwl_trans_pcie_txq_enable Activate
> queue 5 on FIFO 4 WrPtr: 0
> [    7.487432] iwlwifi 0000:02:00.0: U iwl_trans_pcie_txq_enable Activate
> queue 6 on FIFO 2 WrPtr: 0
> [    7.490496] iwlwifi 0000:02:00.0: U iwl_trans_pcie_txq_enable Activate
> queue 7 on FIFO 5 WrPtr: 0
> [    7.493534] iwlwifi 0000:02:00.0: U iwl_trans_pcie_txq_enable Activate
> queue 8 on FIFO 4 WrPtr: 0
> [    7.496562] iwlwifi 0000:02:00.0: U iwl_trans_pcie_txq_enable Activate
> queue 10 on FIFO 5 WrPtr: 0
> [    7.542143] device wlan0 entered promiscuous mode
> [    7.544749] xen_bridge: port 2(wlan0) entered forwarding state
> [    7.546915] xen_bridge: port 2(wlan0) entered forwarding state
> [    7.548825] cfg80211: Pending regulatory request, waiting for it to be
> processed...
> [    7.552798] ------------[ cut here ]------------
> [    7.554821] WARNING: CPU: 1 PID: 2445 at
> drivers/net/wireless/iwlwifi/dvm/tx.c:456 iwlagn_tx_skb+0x776/0x979()
> [    7.554824] Modules linked in: acpi_cpufreq
> [    7.554827] CPU: 1 PID: 2445 Comm: hostapd Not tainted 3.12.0-rc5+ #1
> [    7.554828] Hardware name:                  /D53427RKE, BIOS
> RKPPT10H.86A.0017.2013.0425.1251 04/25/2013
> [    7.554831]  0000000000000000 0000000000000009 ffffffff818a8082
> 0000000000000000
> [    7.554833]  ffffffff8105a4f2 0000000000000000 ffffffff815f440a
> ffff8800d6df1c80
> [    7.554835]  ffff8800d6cb1790 ffff8800d6df1c80 0000000000000007
> 0000000000000000
> [    7.554835] Call Trace:
> [    7.554842]  [<ffffffff818a8082>] ? dump_stack+0x41/0x51
> [    7.554845]  [<ffffffff8105a4f2>] ? warn_slowpath_common+0x78/0x90
> [    7.554850]  [<ffffffff815f440a>] ? iwlagn_tx_skb+0x776/0x979
> [    7.554852]  [<ffffffff815f440a>] ? iwlagn_tx_skb+0x776/0x979
> [    7.554855]  [<ffffffff815f2407>] ? iwlagn_mac_tx+0x19/0x30
> [    7.554858]  [<ffffffff8187a259>] ? __ieee80211_tx+0x226/0x29b
> [    7.554860]  [<ffffffff8187bcd1>] ? ieee80211_tx+0xa6/0xb5
> [    7.554865]  [<ffffffff8187bf9f>] ?
> ieee80211_monitor_start_xmit+0x1e9/0x204
> [    7.554867]  [<ffffffff8172e1eb>] ? dev_hard_start_xmit+0x271/0x3ec
> [    7.554871]  [<ffffffff81746538>] ? sch_direct_xmit+0x66/0x164
> [    7.554873]  [<ffffffff8172e54b>] ? dev_queue_xmit+0x1e5/0x3c8
> [    7.554876]  [<ffffffff8180bfe6>] ? packet_sendmsg+0xac5/0xb3d
> [    7.554881]  [<ffffffff8171ad95>] ? sock_sendmsg+0x37/0x52
> [    7.554884]  [<ffffffff810f9e0c>] ? __do_fault+0x338/0x36b
> [    7.554886]  [<ffffffff81724bac>] ? verify_iovec+0x44/0x94
> [    7.554889]  [<ffffffff8171b1ef>] ? ___sys_sendmsg+0x1f1/0x283
> [    7.554893]  [<ffffffff81140a73>] ? __inode_wait_for_writeback+0x67/0xae
> [    7.554895]  [<ffffffff8111735e>] ? __cache_free.isra.46+0x178/0x187
> [    7.554897]  [<ffffffff811173b1>] ? kmem_cache_free+0x44/0x84
> [    7.554900]  [<ffffffff81132c22>] ? dentry_kill+0x13d/0x149
> [    7.554902]  [<ffffffff81132f6f>] ? dput+0xe5/0xef
> [    7.554905]  [<ffffffff81136e04>] ? fget_light+0x2e/0x7c
> [    7.554908]  [<ffffffff8171c1ee>] ? __sys_sendmsg+0x39/0x57
> [    7.554911]  [<ffffffff818b5e39>] ? system_call_fastpath+0x16/0x1b
> [    7.554912] ---[ end trace beb2b581b91027a7 ]---
> [    7.554917] iwlwifi 0000:02:00.0: I iwlagn_tx_skb TX to [14|8] Q:7 - seq: 0x0
> [    7.555036] device wlan0 left promiscuous mode
> [    7.555042] xen_bridge: port 2(wlan0) entered disabled state
> [    7.557861] iwlwifi 0000:02:00.0: I iwl_trans_pcie_reclaim [Q 7] 0 -> 1 (1)
> [    7.557865] iwlwifi 0000:02:00.0: I iwlagn_rx_reply_tx TXQ 7 status SUCCESS
> (0x00000201)
> [    7.557867] iwlwifi 0000:02:00.0: I iwlagn_rx_reply_tx
> initial_rate 0x820a retries 0, idx=0 ssn=1 seq_ctl=0x0
> [    7.626274] iwlwifi 0000:02:00.0: I iwl_pcie_txq_inc_wr_ptr Q:9 WR: 0x23
> [    7.670694] iwlwifi 0000:02:00.0: I iwl_pcie_txq_inc_wr_ptr Q:9 WR: 0x24
> [    7.673864] iwlwifi 0000:02:00.0: I iwl_pcie_txq_inc_wr_ptr Q:9 WR: 0x25
> [    7.677083] iwlwifi 0000:02:00.0: I iwl_pcie_txq_inc_wr_ptr Q:9 WR: 0x26
> [    7.681410] iwlwifi 0000:02:00.0: I iwl_pcie_txq_inc_wr_ptr Q:9 WR: 0x27
> [    7.684761] iwlwifi 0000:02:00.0: I iwl_pcie_txq_inc_wr_ptr Q:9 WR: 0x28
> [    7.686906] iwlwifi 0000:02:00.0: I iwl_pcie_txq_unmap Q 9 Free 39


^ permalink raw reply related

* Re: Lower throughput in Ad-hoc than in Infrastructure mode?
From: Felix Fietkau @ 2013-10-15 13:29 UTC (permalink / raw)
  To: Floris Van den Abeele, linux-wireless
In-Reply-To: <525CEE98.3010300@intec.ugent.be>

On 2013-10-15 9:28 AM, Floris Van den Abeele wrote:
> While running throughput experiments using iperf I noticed that UDP
> throughput in ad-hoc mode was considerably lower than in Infrastructure
> mode. The setups I'm comparing is a 802.11a ad-hoc network consisting of
> two clients vs a 802.11a infrastructure network consisting of an access
> point and a client (11a because the tests were run in the 5GHz band).
> 
> For ad-hoc mode I'm consistenly seeing a lower throughput than for
> infrastructure mode: i.e. 22.4 Mbits/sec vs 28.2 Mbits/sec. Note that
> while sniffing the medium radiotap headers report a PHY data rate of
> 54Mbit/s in both cases. There is no other traffic on the Wi-Fi channel
> in question (44). Considering the medium access for both setups is
> similair I would expect to find similair throughputs. Is this a known
> issue with the linux wireless/mac80211/ath9k driver stack or is this
> behaviour conform the 802.11 standard (based on my knowledge I would say
> no to the latter)? My test specs are below.
> 
> For testing I'm using Sparklan WPEA-111N NIC's (AR9280). The nodes are
> running OpenWrt attitude adjusment on r32482 (from 2012-06-21) with the
> REGD patch enabled. I believe that this build of OpenWRT uses the
> compat-wireless-2012-06-14.tar.bz2 drivers.
I'd suggest that you try a recent version of OpenWrt before
investigating further.

- Felix


^ permalink raw reply

* [PATCH 3.12 3/3] mac80211: sanity check WMM/QoS parameters
From: Johannes Berg @ 2013-10-15 13:17 UTC (permalink / raw)
  To: linux-wireless; +Cc: Johannes Berg
In-Reply-To: <1381843030-12260-1-git-send-email-johannes@sipsolutions.net>

From: Johannes Berg <johannes.berg@intel.com>

Check for invalid WMM parameters (AIFSN < 2 or CWmax < CWmin)
and try to set them to usable values in this case.

Notably the Sitecom WL-153 v1 with firmware 1.45 is sending
AIFSN, ECWmin and ECWmax as all zero.

Reported-and-tested-by: Antonio Quartulli <antonio@meshcoding.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
 net/mac80211/mlme.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 86e4ad5..058ae1c 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -1598,6 +1598,7 @@ static bool ieee80211_sta_wmm_params(struct ieee80211_local *local,
 	int count;
 	const u8 *pos;
 	u8 uapsd_queues = 0;
+	static const u8 default_aifs[] = { 2, 2, 3, 7 };
 
 	if (!local->ops->conf_tx)
 		return false;
@@ -1664,8 +1665,12 @@ static bool ieee80211_sta_wmm_params(struct ieee80211_local *local,
 		}
 
 		params.aifs = pos[0] & 0x0f;
+		if (params.aifs < 2)
+			params.aifs = default_aifs[queue];
 		params.cw_max = ecw2cw((pos[1] & 0xf0) >> 4);
 		params.cw_min = ecw2cw(pos[1] & 0x0f);
+		if (params.cw_max < params.cw_min)
+			params.cw_max = params.cw_min;
 		params.txop = get_unaligned_le16(pos + 2);
 		params.acm = acm;
 		params.uapsd = uapsd;
-- 
1.8.4.rc3


^ permalink raw reply related

* [PATCH 3.12 2/3] mac80211: respect rate mask in TX
From: Johannes Berg @ 2013-10-15 13:17 UTC (permalink / raw)
  To: linux-wireless; +Cc: Andrei Otcheretianski
In-Reply-To: <1381843030-12260-1-git-send-email-johannes@sipsolutions.net>

From: Andrei Otcheretianski <andrei.otcheretianski@intel.com>

Bitrate mask were not respected in transmissions, causing (for
example) P2P GO/client to use CCK rates for auth and assoc frames.
Fix it by considering the rate mask in __rate_control_send_low().

Signed-off-by: Andrei Otcheretianski <andrei.otcheretianski@intel.com>
Reviewed-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
 net/mac80211/rate.c | 12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/net/mac80211/rate.c b/net/mac80211/rate.c
index 7f7ce11..22b223f 100644
--- a/net/mac80211/rate.c
+++ b/net/mac80211/rate.c
@@ -235,7 +235,8 @@ static void rc_send_low_basicrate(s8 *idx, u32 basic_rates,
 static void __rate_control_send_low(struct ieee80211_hw *hw,
 				    struct ieee80211_supported_band *sband,
 				    struct ieee80211_sta *sta,
-				    struct ieee80211_tx_info *info)
+				    struct ieee80211_tx_info *info,
+				    u32 rate_mask)
 {
 	int i;
 	u32 rate_flags =
@@ -247,6 +248,9 @@ static void __rate_control_send_low(struct ieee80211_hw *hw,
 
 	info->control.rates[0].idx = 0;
 	for (i = 0; i < sband->n_bitrates; i++) {
+		if (!(rate_mask & BIT(i)))
+			continue;
+
 		if ((rate_flags & sband->bitrates[i].flags) != rate_flags)
 			continue;
 
@@ -277,7 +281,8 @@ bool rate_control_send_low(struct ieee80211_sta *pubsta,
 	bool use_basicrate = false;
 
 	if (!pubsta || !priv_sta || rc_no_data_or_no_ack_use_min(txrc)) {
-		__rate_control_send_low(txrc->hw, sband, pubsta, info);
+		__rate_control_send_low(txrc->hw, sband, pubsta, info,
+					txrc->rate_idx_mask);
 
 		if (!pubsta && txrc->bss) {
 			mcast_rate = txrc->bss_conf->mcast_rate[sband->band];
@@ -659,7 +664,8 @@ void ieee80211_get_tx_rates(struct ieee80211_vif *vif,
 		rate_control_apply_mask(sdata, sta, sband, info, dest, max_rates);
 
 	if (dest[0].idx < 0)
-		__rate_control_send_low(&sdata->local->hw, sband, sta, info);
+		__rate_control_send_low(&sdata->local->hw, sband, sta, info,
+					sdata->rc_rateidx_mask[info->band]);
 
 	if (sta)
 		rate_fixup_ratelist(vif, sband, info, dest, max_rates);
-- 
1.8.4.rc3


^ permalink raw reply related

* [PATCH 3.12 1/3] mac80211: fix honouring rate flags in low-rate transmit
From: Johannes Berg @ 2013-10-15 13:17 UTC (permalink / raw)
  To: linux-wireless; +Cc: Andrei Otcheretianski

From: Andrei Otcheretianski <andrei.otcheretianski@intel.com>

Transmissions with the IEEE80211_TX_CTL_NO_CCK_RATE flag set
(which can come from userspace) were no longer guaranteed to
be transmitted with allowed rates since commit 2103dec14792b
("mac80211: select and adjust bitrates according to channel
mode") due to a missing rate_flags check in that commit. The
commit also introduced the need to check the 5/10 MHz flags
but accidentally didn't. Fix it by adding the missing check.

Signed-off-by: Andrei Otcheretianski <andrei.otcheretianski@intel.com>
Reviewed-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
 net/mac80211/rate.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/net/mac80211/rate.c b/net/mac80211/rate.c
index e126605..7f7ce11 100644
--- a/net/mac80211/rate.c
+++ b/net/mac80211/rate.c
@@ -247,6 +247,9 @@ static void __rate_control_send_low(struct ieee80211_hw *hw,
 
 	info->control.rates[0].idx = 0;
 	for (i = 0; i < sband->n_bitrates; i++) {
+		if ((rate_flags & sband->bitrates[i].flags) != rate_flags)
+			continue;
+
 		if (!rate_supported(sta, sband->band, i))
 			continue;
 
-- 
1.8.4.rc3


^ permalink raw reply related

* Re: [Ilw] drivers/net/wireless/iwlwifi/dvm/tx.c:456 iwlagn_tx_skb+0x6c5/0x883()
From: Sander Eikelenboom @ 2013-10-15 13:10 UTC (permalink / raw)
  To: Grumbach, Emmanuel
  Cc: John W. Linville, Berg, Johannes, ilw@linux.intel.com,
	netdev@vger.kernel.org, linux-wireless@vger.kernel.org
In-Reply-To: <0BA3FCBA62E2DC44AF3030971E174FB301DC46E5@HASMSX103.ger.corp.intel.com>


Tuesday, October 15, 2013, 12:52:04 PM, you wrote:

>> 
>> Hi,
>> 
>> I'm having a:
>> 
>> 02:00.0 Network controller: Intel Corporation Centrino Advanced-N 6235 (rev
>> 24)
>> 
>> And i'm running into this warning on boot with a 3.11.2 and 3.12-rc5 kernel.
>> 
>> [   23.904950] ------------[ cut here ]------------
>> [   23.904957] WARNING: CPU: 0 PID: 2531 at
>> drivers/net/wireless/iwlwifi/dvm/tx.c:456 iwlagn_tx_skb+0x6c5/0x883()

> Can you reproduce easily?
> If yes, please reproduce with debug parameters:
> modprobe iwlwifi debug=0xC0800000

> Also, please enable MAC80211_HT_DEBUG

> Thanks

It happens when starting hostapd:

[    7.101116] iwlwifi 0000:02:00.0: L1 Disabled; Enabling L0S
[    7.110722] iwlwifi 0000:02:00.0: Radio type=0x2-0x1-0x0
[    7.154478] iwlwifi 0000:02:00.0: U iwl_trans_pcie_txq_enable Activate queue 9 on FIFO 7 WrPtr: 0
[    7.157691] iwlwifi 0000:02:00.0: U iwl_trans_pcie_txq_enable Activate queue 0 on FIFO 3 WrPtr: 0
[    7.160812] iwlwifi 0000:02:00.0: U iwl_trans_pcie_txq_enable Activate queue 1 on FIFO 2 WrPtr: 0
[    7.164900] iwlwifi 0000:02:00.0: U iwl_trans_pcie_txq_enable Activate queue 2 on FIFO 1 WrPtr: 0
[    7.165019] iwlwifi 0000:02:00.0: U iwl_trans_pcie_txq_enable Activate queue 3 on FIFO 0 WrPtr: 0
[    7.165139] iwlwifi 0000:02:00.0: U iwl_trans_pcie_txq_enable Activate queue 4 on FIFO 0 WrPtr: 0
[    7.165258] iwlwifi 0000:02:00.0: U iwl_trans_pcie_txq_enable Activate queue 5 on FIFO 4 WrPtr: 0
[    7.165377] iwlwifi 0000:02:00.0: U iwl_trans_pcie_txq_enable Activate queue 6 on FIFO 2 WrPtr: 0
[    7.165495] iwlwifi 0000:02:00.0: U iwl_trans_pcie_txq_enable Activate queue 7 on FIFO 5 WrPtr: 0
[    7.165614] iwlwifi 0000:02:00.0: U iwl_trans_pcie_txq_enable Activate queue 8 on FIFO 4 WrPtr: 0
[    7.165733] iwlwifi 0000:02:00.0: U iwl_trans_pcie_txq_enable Activate queue 10 on FIFO 5 WrPtr: 0
[    7.404295] iwlwifi 0000:02:00.0: L1 Disabled; Enabling L0S
[    7.415368] iwlwifi 0000:02:00.0: Radio type=0x2-0x1-0x0
[    7.462417] iwlwifi 0000:02:00.0: U iwl_trans_pcie_txq_enable Activate queue 9 on FIFO 7 WrPtr: 0
[    7.466588] iwlwifi 0000:02:00.0: U iwl_trans_pcie_txq_enable Activate queue 0 on FIFO 3 WrPtr: 0
[    7.470415] iwlwifi 0000:02:00.0: U iwl_trans_pcie_txq_enable Activate queue 1 on FIFO 2 WrPtr: 0
[    7.474144] iwlwifi 0000:02:00.0: U iwl_trans_pcie_txq_enable Activate queue 2 on FIFO 1 WrPtr: 0
[    7.477514] iwlwifi 0000:02:00.0: U iwl_trans_pcie_txq_enable Activate queue 3 on FIFO 0 WrPtr: 0
[    7.480843] iwlwifi 0000:02:00.0: U iwl_trans_pcie_txq_enable Activate queue 4 on FIFO 0 WrPtr: 0
[    7.484148] iwlwifi 0000:02:00.0: U iwl_trans_pcie_txq_enable Activate queue 5 on FIFO 4 WrPtr: 0
[    7.487432] iwlwifi 0000:02:00.0: U iwl_trans_pcie_txq_enable Activate queue 6 on FIFO 2 WrPtr: 0
[    7.490496] iwlwifi 0000:02:00.0: U iwl_trans_pcie_txq_enable Activate queue 7 on FIFO 5 WrPtr: 0
[    7.493534] iwlwifi 0000:02:00.0: U iwl_trans_pcie_txq_enable Activate queue 8 on FIFO 4 WrPtr: 0
[    7.496562] iwlwifi 0000:02:00.0: U iwl_trans_pcie_txq_enable Activate queue 10 on FIFO 5 WrPtr: 0
[    7.542143] device wlan0 entered promiscuous mode
[    7.544749] xen_bridge: port 2(wlan0) entered forwarding state
[    7.546915] xen_bridge: port 2(wlan0) entered forwarding state
[    7.548825] cfg80211: Pending regulatory request, waiting for it to be processed...
[    7.552798] ------------[ cut here ]------------
[    7.554821] WARNING: CPU: 1 PID: 2445 at drivers/net/wireless/iwlwifi/dvm/tx.c:456 iwlagn_tx_skb+0x776/0x979()
[    7.554824] Modules linked in: acpi_cpufreq
[    7.554827] CPU: 1 PID: 2445 Comm: hostapd Not tainted 3.12.0-rc5+ #1
[    7.554828] Hardware name:                  /D53427RKE, BIOS RKPPT10H.86A.0017.2013.0425.1251 04/25/2013
[    7.554831]  0000000000000000 0000000000000009 ffffffff818a8082 0000000000000000
[    7.554833]  ffffffff8105a4f2 0000000000000000 ffffffff815f440a ffff8800d6df1c80
[    7.554835]  ffff8800d6cb1790 ffff8800d6df1c80 0000000000000007 0000000000000000
[    7.554835] Call Trace:
[    7.554842]  [<ffffffff818a8082>] ? dump_stack+0x41/0x51
[    7.554845]  [<ffffffff8105a4f2>] ? warn_slowpath_common+0x78/0x90
[    7.554850]  [<ffffffff815f440a>] ? iwlagn_tx_skb+0x776/0x979
[    7.554852]  [<ffffffff815f440a>] ? iwlagn_tx_skb+0x776/0x979
[    7.554855]  [<ffffffff815f2407>] ? iwlagn_mac_tx+0x19/0x30
[    7.554858]  [<ffffffff8187a259>] ? __ieee80211_tx+0x226/0x29b
[    7.554860]  [<ffffffff8187bcd1>] ? ieee80211_tx+0xa6/0xb5
[    7.554865]  [<ffffffff8187bf9f>] ? ieee80211_monitor_start_xmit+0x1e9/0x204
[    7.554867]  [<ffffffff8172e1eb>] ? dev_hard_start_xmit+0x271/0x3ec
[    7.554871]  [<ffffffff81746538>] ? sch_direct_xmit+0x66/0x164
[    7.554873]  [<ffffffff8172e54b>] ? dev_queue_xmit+0x1e5/0x3c8
[    7.554876]  [<ffffffff8180bfe6>] ? packet_sendmsg+0xac5/0xb3d
[    7.554881]  [<ffffffff8171ad95>] ? sock_sendmsg+0x37/0x52
[    7.554884]  [<ffffffff810f9e0c>] ? __do_fault+0x338/0x36b
[    7.554886]  [<ffffffff81724bac>] ? verify_iovec+0x44/0x94
[    7.554889]  [<ffffffff8171b1ef>] ? ___sys_sendmsg+0x1f1/0x283
[    7.554893]  [<ffffffff81140a73>] ? __inode_wait_for_writeback+0x67/0xae
[    7.554895]  [<ffffffff8111735e>] ? __cache_free.isra.46+0x178/0x187
[    7.554897]  [<ffffffff811173b1>] ? kmem_cache_free+0x44/0x84
[    7.554900]  [<ffffffff81132c22>] ? dentry_kill+0x13d/0x149
[    7.554902]  [<ffffffff81132f6f>] ? dput+0xe5/0xef
[    7.554905]  [<ffffffff81136e04>] ? fget_light+0x2e/0x7c
[    7.554908]  [<ffffffff8171c1ee>] ? __sys_sendmsg+0x39/0x57
[    7.554911]  [<ffffffff818b5e39>] ? system_call_fastpath+0x16/0x1b
[    7.554912] ---[ end trace beb2b581b91027a7 ]---
[    7.554917] iwlwifi 0000:02:00.0: I iwlagn_tx_skb TX to [14|8] Q:7 - seq: 0x0
[    7.555036] device wlan0 left promiscuous mode
[    7.555042] xen_bridge: port 2(wlan0) entered disabled state
[    7.557861] iwlwifi 0000:02:00.0: I iwl_trans_pcie_reclaim [Q 7] 0 -> 1 (1)
[    7.557865] iwlwifi 0000:02:00.0: I iwlagn_rx_reply_tx TXQ 7 status SUCCESS (0x00000201)
[    7.557867] iwlwifi 0000:02:00.0: I iwlagn_rx_reply_tx                               initial_rate 0x820a retries 0, idx=0 ssn=1 seq_ctl=0x0
[    7.626274] iwlwifi 0000:02:00.0: I iwl_pcie_txq_inc_wr_ptr Q:9 WR: 0x23
[    7.670694] iwlwifi 0000:02:00.0: I iwl_pcie_txq_inc_wr_ptr Q:9 WR: 0x24
[    7.673864] iwlwifi 0000:02:00.0: I iwl_pcie_txq_inc_wr_ptr Q:9 WR: 0x25
[    7.677083] iwlwifi 0000:02:00.0: I iwl_pcie_txq_inc_wr_ptr Q:9 WR: 0x26
[    7.681410] iwlwifi 0000:02:00.0: I iwl_pcie_txq_inc_wr_ptr Q:9 WR: 0x27
[    7.684761] iwlwifi 0000:02:00.0: I iwl_pcie_txq_inc_wr_ptr Q:9 WR: 0x28
[    7.686906] iwlwifi 0000:02:00.0: I iwl_pcie_txq_unmap Q 9 Free 39


^ permalink raw reply

* Re: [PATCH 3.12] rt2x00: check if device is still available on rt2x00mac_flush()
From: Helmut Schaa @ 2013-10-15 13:00 UTC (permalink / raw)
  To: Stanislaw Gruszka; +Cc: linux-wireless, rt2x00 Users List
In-Reply-To: <20131015123112.GB6417@localhost.localdomain>

On Tue, Oct 15, 2013 at 2:31 PM, Stanislaw Gruszka <stf_xl@wp.pl> wrote:
> Fix random kernel panic with below messages when remove dongle.
>
> [ 2212.355447] BUG: unable to handle kernel NULL pointer dereference at 0000000000000250
> [ 2212.355527] IP: [<ffffffffa02667f2>] rt2x00usb_kick_tx_entry+0x12/0x160 [rt2x00usb]
> [ 2212.355599] PGD 0
> [ 2212.355626] Oops: 0000 [#1] SMP
> [ 2212.355664] Modules linked in: rt2800usb rt2x00usb rt2800lib crc_ccitt rt2x00lib mac80211 cfg80211 tun arc4 fuse rfcomm bnep snd_hda_codec_realtek snd_hda_intel snd_hda_codec btusb uvcvideo bluetooth snd_hwdep x86_pkg_temp_thermal snd_seq coretemp aesni_intel aes_x86_64 snd_seq_device glue_helper snd_pcm ablk_helper videobuf2_vmalloc sdhci_pci videobuf2_memops videobuf2_core sdhci videodev mmc_core serio_raw snd_page_alloc microcode i2c_i801 snd_timer hid_multitouch thinkpad_acpi lpc_ich mfd_core snd tpm_tis wmi tpm tpm_bios soundcore acpi_cpufreq i915 i2c_algo_bit drm_kms_helper drm i2c_core video [last unloaded: cfg80211]
> [ 2212.356224] CPU: 0 PID: 34 Comm: khubd Not tainted 3.12.0-rc3-wl+ #3
> [ 2212.356268] Hardware name: LENOVO 3444CUU/3444CUU, BIOS G6ET93WW (2.53 ) 02/04/2013
> [ 2212.356319] task: ffff880212f687c0 ti: ffff880212f66000 task.ti: ffff880212f66000
> [ 2212.356392] RIP: 0010:[<ffffffffa02667f2>]  [<ffffffffa02667f2>] rt2x00usb_kick_tx_entry+0x12/0x160 [rt2x00usb]
> [ 2212.356481] RSP: 0018:ffff880212f67750  EFLAGS: 00010202
> [ 2212.356519] RAX: 000000000000000c RBX: 000000000000000c RCX: 0000000000000293
> [ 2212.356568] RDX: ffff8801f4dc219a RSI: 0000000000000000 RDI: 0000000000000240
> [ 2212.356617] RBP: ffff880212f67778 R08: ffffffffa02667e0 R09: 0000000000000002
> [ 2212.356665] R10: 0001f95254ab4b40 R11: ffff880212f675be R12: ffff8801f4dc2150
> [ 2212.356712] R13: 0000000000000000 R14: ffffffffa02667e0 R15: 000000000000000d
> [ 2212.356761] FS:  0000000000000000(0000) GS:ffff88021e200000(0000) knlGS:0000000000000000
> [ 2212.356813] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
> [ 2212.356852] CR2: 0000000000000250 CR3: 0000000001a0c000 CR4: 00000000001407f0
> [ 2212.356899] Stack:
> [ 2212.356917]  000000000000000c ffff8801f4dc2150 0000000000000000 ffffffffa02667e0
> [ 2212.356980]  000000000000000d ffff880212f677b8 ffffffffa03a31ad ffff8801f4dc219a
> [ 2212.357038]  ffff8801f4dc2150 0000000000000000 ffff8800b93217a0 ffff8801f49bc800
> [ 2212.357099] Call Trace:
> [ 2212.357122]  [<ffffffffa02667e0>] ? rt2x00usb_interrupt_txdone+0x90/0x90 [rt2x00usb]
> [ 2212.357174]  [<ffffffffa03a31ad>] rt2x00queue_for_each_entry+0xed/0x170 [rt2x00lib]
> [ 2212.357244]  [<ffffffffa026701c>] rt2x00usb_kick_queue+0x5c/0x60 [rt2x00usb]
> [ 2212.357314]  [<ffffffffa03a3682>] rt2x00queue_flush_queue+0x62/0xa0 [rt2x00lib]
> [ 2212.357386]  [<ffffffffa03a2930>] rt2x00mac_flush+0x30/0x70 [rt2x00lib]
> [ 2212.357470]  [<ffffffffa04edded>] ieee80211_flush_queues+0xbd/0x140 [mac80211]
> [ 2212.357555]  [<ffffffffa0502e52>] ieee80211_set_disassoc+0x2d2/0x3d0 [mac80211]
> [ 2212.357645]  [<ffffffffa0506da3>] ieee80211_mgd_deauth+0x1d3/0x240 [mac80211]
> [ 2212.357718]  [<ffffffff8108b17c>] ? try_to_wake_up+0xec/0x290
> [ 2212.357788]  [<ffffffffa04dbd18>] ieee80211_deauth+0x18/0x20 [mac80211]
> [ 2212.357872]  [<ffffffffa0418ddc>] cfg80211_mlme_deauth+0x9c/0x140 [cfg80211]
> [ 2212.357913]  [<ffffffffa041907c>] cfg80211_mlme_down+0x5c/0x60 [cfg80211]
> [ 2212.357962]  [<ffffffffa041cd18>] cfg80211_disconnect+0x188/0x1a0 [cfg80211]
> [ 2212.358014]  [<ffffffffa04013bc>] ? __cfg80211_stop_sched_scan+0x1c/0x130 [cfg80211]
> [ 2212.358067]  [<ffffffffa03f8954>] cfg80211_leave+0xc4/0xe0 [cfg80211]
> [ 2212.358124]  [<ffffffffa03f8d1b>] cfg80211_netdev_notifier_call+0x3ab/0x5e0 [cfg80211]
> [ 2212.358177]  [<ffffffff815140f8>] ? inetdev_event+0x38/0x510
> [ 2212.358217]  [<ffffffff81085a94>] ? __wake_up+0x44/0x50
> [ 2212.358254]  [<ffffffff8155995c>] notifier_call_chain+0x4c/0x70
> [ 2212.358293]  [<ffffffff81081156>] raw_notifier_call_chain+0x16/0x20
> [ 2212.358361]  [<ffffffff814b6dd5>] call_netdevice_notifiers_info+0x35/0x60
> [ 2212.358429]  [<ffffffff814b6ec9>] __dev_close_many+0x49/0xd0
> [ 2212.358487]  [<ffffffff814b7028>] dev_close_many+0x88/0x100
> [ 2212.358546]  [<ffffffff814b8150>] rollback_registered_many+0xb0/0x220
> [ 2212.358612]  [<ffffffff814b8319>] unregister_netdevice_many+0x19/0x60
> [ 2212.358694]  [<ffffffffa04d8eb2>] ieee80211_remove_interfaces+0x112/0x190 [mac80211]
> [ 2212.358791]  [<ffffffffa04c585f>] ieee80211_unregister_hw+0x4f/0x100 [mac80211]
> [ 2212.361994]  [<ffffffffa03a1221>] rt2x00lib_remove_dev+0x161/0x1a0 [rt2x00lib]
> [ 2212.365240]  [<ffffffffa0266e2e>] rt2x00usb_disconnect+0x2e/0x70 [rt2x00usb]
> [ 2212.368470]  [<ffffffff81419ce4>] usb_unbind_interface+0x64/0x1c0
> [ 2212.371734]  [<ffffffff813b446f>] __device_release_driver+0x7f/0xf0
> [ 2212.374999]  [<ffffffff813b4503>] device_release_driver+0x23/0x30
> [ 2212.378131]  [<ffffffff813b3c98>] bus_remove_device+0x108/0x180
> [ 2212.381358]  [<ffffffff813b0565>] device_del+0x135/0x1d0
> [ 2212.384454]  [<ffffffff81417760>] usb_disable_device+0xb0/0x270
> [ 2212.387451]  [<ffffffff8140d9cd>] usb_disconnect+0xad/0x1d0
> [ 2212.390294]  [<ffffffff8140f6cd>] hub_thread+0x63d/0x1660
> [ 2212.393034]  [<ffffffff8107c860>] ? wake_up_atomic_t+0x30/0x30
> [ 2212.395728]  [<ffffffff8140f090>] ? hub_port_debounce+0x130/0x130
> [ 2212.398412]  [<ffffffff8107baa0>] kthread+0xc0/0xd0
> [ 2212.401058]  [<ffffffff8107b9e0>] ? insert_kthread_work+0x40/0x40
> [ 2212.403639]  [<ffffffff8155de3c>] ret_from_fork+0x7c/0xb0
> [ 2212.406193]  [<ffffffff8107b9e0>] ? insert_kthread_work+0x40/0x40
> [ 2212.408732] Code: 24 58 08 00 00 bf 80 00 00 00 e8 3a c3 e0 e0 5b 41 5c 5d c3 0f 1f 44 00 00 0f 1f 44 00 00 55 48 89 e5 41 57 41 56 41 55 41 54 53 <48> 8b 47 10 48 89 fb 4c 8b 6f 28 4c 8b 20 49 8b 04 24 4c 8b 30
> [ 2212.414671] RIP  [<ffffffffa02667f2>] rt2x00usb_kick_tx_entry+0x12/0x160 [rt2x00usb]
> [ 2212.417646]  RSP <ffff880212f67750>
> [ 2212.420547] CR2: 0000000000000250
> [ 2212.441024] ---[ end trace 5442918f33832bce ]---
>
> Cc: stable@vger.kernel.org
> Signed-off-by: Stanislaw Gruszka <stf_xl@wp.pl>

Good catch Stanislaw! Fix looks good to me.

Acked-by: Helmut Schaa <helmut.schaa@googlemail.com>

> ---
>  drivers/net/wireless/rt2x00/rt2x00mac.c |    3 +++
>  1 files changed, 3 insertions(+), 0 deletions(-)
>
> diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c
> index 51f17cf..7c15785 100644
> --- a/drivers/net/wireless/rt2x00/rt2x00mac.c
> +++ b/drivers/net/wireless/rt2x00/rt2x00mac.c
> @@ -754,6 +754,9 @@ void rt2x00mac_flush(struct ieee80211_hw *hw, u32 queues, bool drop)
>         struct rt2x00_dev *rt2x00dev = hw->priv;
>         struct data_queue *queue;
>
> +       if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags))
> +               return;
> +
>         tx_queue_for_each(rt2x00dev, queue)
>                 rt2x00queue_flush_queue(queue, drop);
>  }
> --
> 1.7.4.4
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* [PATCH 3.12] rt2x00: check if device is still available on rt2x00mac_flush()
From: Stanislaw Gruszka @ 2013-10-15 12:31 UTC (permalink / raw)
  To: linux-wireless; +Cc: users

Fix random kernel panic with below messages when remove dongle.

[ 2212.355447] BUG: unable to handle kernel NULL pointer dereference at 0000000000000250
[ 2212.355527] IP: [<ffffffffa02667f2>] rt2x00usb_kick_tx_entry+0x12/0x160 [rt2x00usb]
[ 2212.355599] PGD 0
[ 2212.355626] Oops: 0000 [#1] SMP
[ 2212.355664] Modules linked in: rt2800usb rt2x00usb rt2800lib crc_ccitt rt2x00lib mac80211 cfg80211 tun arc4 fuse rfcomm bnep snd_hda_codec_realtek snd_hda_intel snd_hda_codec btusb uvcvideo bluetooth snd_hwdep x86_pkg_temp_thermal snd_seq coretemp aesni_intel aes_x86_64 snd_seq_device glue_helper snd_pcm ablk_helper videobuf2_vmalloc sdhci_pci videobuf2_memops videobuf2_core sdhci videodev mmc_core serio_raw snd_page_alloc microcode i2c_i801 snd_timer hid_multitouch thinkpad_acpi lpc_ich mfd_core snd tpm_tis wmi tpm tpm_bios soundcore acpi_cpufreq i915 i2c_algo_bit drm_kms_helper drm i2c_core video [last unloaded: cfg80211]
[ 2212.356224] CPU: 0 PID: 34 Comm: khubd Not tainted 3.12.0-rc3-wl+ #3
[ 2212.356268] Hardware name: LENOVO 3444CUU/3444CUU, BIOS G6ET93WW (2.53 ) 02/04/2013
[ 2212.356319] task: ffff880212f687c0 ti: ffff880212f66000 task.ti: ffff880212f66000
[ 2212.356392] RIP: 0010:[<ffffffffa02667f2>]  [<ffffffffa02667f2>] rt2x00usb_kick_tx_entry+0x12/0x160 [rt2x00usb]
[ 2212.356481] RSP: 0018:ffff880212f67750  EFLAGS: 00010202
[ 2212.356519] RAX: 000000000000000c RBX: 000000000000000c RCX: 0000000000000293
[ 2212.356568] RDX: ffff8801f4dc219a RSI: 0000000000000000 RDI: 0000000000000240
[ 2212.356617] RBP: ffff880212f67778 R08: ffffffffa02667e0 R09: 0000000000000002
[ 2212.356665] R10: 0001f95254ab4b40 R11: ffff880212f675be R12: ffff8801f4dc2150
[ 2212.356712] R13: 0000000000000000 R14: ffffffffa02667e0 R15: 000000000000000d
[ 2212.356761] FS:  0000000000000000(0000) GS:ffff88021e200000(0000) knlGS:0000000000000000
[ 2212.356813] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[ 2212.356852] CR2: 0000000000000250 CR3: 0000000001a0c000 CR4: 00000000001407f0
[ 2212.356899] Stack:
[ 2212.356917]  000000000000000c ffff8801f4dc2150 0000000000000000 ffffffffa02667e0
[ 2212.356980]  000000000000000d ffff880212f677b8 ffffffffa03a31ad ffff8801f4dc219a
[ 2212.357038]  ffff8801f4dc2150 0000000000000000 ffff8800b93217a0 ffff8801f49bc800
[ 2212.357099] Call Trace:
[ 2212.357122]  [<ffffffffa02667e0>] ? rt2x00usb_interrupt_txdone+0x90/0x90 [rt2x00usb]
[ 2212.357174]  [<ffffffffa03a31ad>] rt2x00queue_for_each_entry+0xed/0x170 [rt2x00lib]
[ 2212.357244]  [<ffffffffa026701c>] rt2x00usb_kick_queue+0x5c/0x60 [rt2x00usb]
[ 2212.357314]  [<ffffffffa03a3682>] rt2x00queue_flush_queue+0x62/0xa0 [rt2x00lib]
[ 2212.357386]  [<ffffffffa03a2930>] rt2x00mac_flush+0x30/0x70 [rt2x00lib]
[ 2212.357470]  [<ffffffffa04edded>] ieee80211_flush_queues+0xbd/0x140 [mac80211]
[ 2212.357555]  [<ffffffffa0502e52>] ieee80211_set_disassoc+0x2d2/0x3d0 [mac80211]
[ 2212.357645]  [<ffffffffa0506da3>] ieee80211_mgd_deauth+0x1d3/0x240 [mac80211]
[ 2212.357718]  [<ffffffff8108b17c>] ? try_to_wake_up+0xec/0x290
[ 2212.357788]  [<ffffffffa04dbd18>] ieee80211_deauth+0x18/0x20 [mac80211]
[ 2212.357872]  [<ffffffffa0418ddc>] cfg80211_mlme_deauth+0x9c/0x140 [cfg80211]
[ 2212.357913]  [<ffffffffa041907c>] cfg80211_mlme_down+0x5c/0x60 [cfg80211]
[ 2212.357962]  [<ffffffffa041cd18>] cfg80211_disconnect+0x188/0x1a0 [cfg80211]
[ 2212.358014]  [<ffffffffa04013bc>] ? __cfg80211_stop_sched_scan+0x1c/0x130 [cfg80211]
[ 2212.358067]  [<ffffffffa03f8954>] cfg80211_leave+0xc4/0xe0 [cfg80211]
[ 2212.358124]  [<ffffffffa03f8d1b>] cfg80211_netdev_notifier_call+0x3ab/0x5e0 [cfg80211]
[ 2212.358177]  [<ffffffff815140f8>] ? inetdev_event+0x38/0x510
[ 2212.358217]  [<ffffffff81085a94>] ? __wake_up+0x44/0x50
[ 2212.358254]  [<ffffffff8155995c>] notifier_call_chain+0x4c/0x70
[ 2212.358293]  [<ffffffff81081156>] raw_notifier_call_chain+0x16/0x20
[ 2212.358361]  [<ffffffff814b6dd5>] call_netdevice_notifiers_info+0x35/0x60
[ 2212.358429]  [<ffffffff814b6ec9>] __dev_close_many+0x49/0xd0
[ 2212.358487]  [<ffffffff814b7028>] dev_close_many+0x88/0x100
[ 2212.358546]  [<ffffffff814b8150>] rollback_registered_many+0xb0/0x220
[ 2212.358612]  [<ffffffff814b8319>] unregister_netdevice_many+0x19/0x60
[ 2212.358694]  [<ffffffffa04d8eb2>] ieee80211_remove_interfaces+0x112/0x190 [mac80211]
[ 2212.358791]  [<ffffffffa04c585f>] ieee80211_unregister_hw+0x4f/0x100 [mac80211]
[ 2212.361994]  [<ffffffffa03a1221>] rt2x00lib_remove_dev+0x161/0x1a0 [rt2x00lib]
[ 2212.365240]  [<ffffffffa0266e2e>] rt2x00usb_disconnect+0x2e/0x70 [rt2x00usb]
[ 2212.368470]  [<ffffffff81419ce4>] usb_unbind_interface+0x64/0x1c0
[ 2212.371734]  [<ffffffff813b446f>] __device_release_driver+0x7f/0xf0
[ 2212.374999]  [<ffffffff813b4503>] device_release_driver+0x23/0x30
[ 2212.378131]  [<ffffffff813b3c98>] bus_remove_device+0x108/0x180
[ 2212.381358]  [<ffffffff813b0565>] device_del+0x135/0x1d0
[ 2212.384454]  [<ffffffff81417760>] usb_disable_device+0xb0/0x270
[ 2212.387451]  [<ffffffff8140d9cd>] usb_disconnect+0xad/0x1d0
[ 2212.390294]  [<ffffffff8140f6cd>] hub_thread+0x63d/0x1660
[ 2212.393034]  [<ffffffff8107c860>] ? wake_up_atomic_t+0x30/0x30
[ 2212.395728]  [<ffffffff8140f090>] ? hub_port_debounce+0x130/0x130
[ 2212.398412]  [<ffffffff8107baa0>] kthread+0xc0/0xd0
[ 2212.401058]  [<ffffffff8107b9e0>] ? insert_kthread_work+0x40/0x40
[ 2212.403639]  [<ffffffff8155de3c>] ret_from_fork+0x7c/0xb0
[ 2212.406193]  [<ffffffff8107b9e0>] ? insert_kthread_work+0x40/0x40
[ 2212.408732] Code: 24 58 08 00 00 bf 80 00 00 00 e8 3a c3 e0 e0 5b 41 5c 5d c3 0f 1f 44 00 00 0f 1f 44 00 00 55 48 89 e5 41 57 41 56 41 55 41 54 53 <48> 8b 47 10 48 89 fb 4c 8b 6f 28 4c 8b 20 49 8b 04 24 4c 8b 30
[ 2212.414671] RIP  [<ffffffffa02667f2>] rt2x00usb_kick_tx_entry+0x12/0x160 [rt2x00usb]
[ 2212.417646]  RSP <ffff880212f67750>
[ 2212.420547] CR2: 0000000000000250
[ 2212.441024] ---[ end trace 5442918f33832bce ]---

Cc: stable@vger.kernel.org
Signed-off-by: Stanislaw Gruszka <stf_xl@wp.pl>
---
 drivers/net/wireless/rt2x00/rt2x00mac.c |    3 +++
 1 files changed, 3 insertions(+), 0 deletions(-)

diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c
index 51f17cf..7c15785 100644
--- a/drivers/net/wireless/rt2x00/rt2x00mac.c
+++ b/drivers/net/wireless/rt2x00/rt2x00mac.c
@@ -754,6 +754,9 @@ void rt2x00mac_flush(struct ieee80211_hw *hw, u32 queues, bool drop)
 	struct rt2x00_dev *rt2x00dev = hw->priv;
 	struct data_queue *queue;
 
+	if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags))
+		return;
+
 	tx_queue_for_each(rt2x00dev, queue)
 		rt2x00queue_flush_queue(queue, drop);
 }
-- 
1.7.4.4


^ permalink raw reply related

* [PATCH 3.12] rt2400pci: fix RSSI read
From: Stanislaw Gruszka @ 2013-10-15 12:28 UTC (permalink / raw)
  To: linux-wireless; +Cc: users

RSSI value is provided on word3 not on word2.

Cc: stable@vger.kernel.org
Signed-off-by: Stanislaw Gruszka <stf_xl@wp.pl>
---
 drivers/net/wireless/rt2x00/rt2400pci.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c
index 3d53a09..38ed9a3 100644
--- a/drivers/net/wireless/rt2x00/rt2400pci.c
+++ b/drivers/net/wireless/rt2x00/rt2400pci.c
@@ -1261,7 +1261,7 @@ static void rt2400pci_fill_rxdone(struct queue_entry *entry,
 	 */
 	rxdesc->timestamp = ((u64)rx_high << 32) | rx_low;
 	rxdesc->signal = rt2x00_get_field32(word2, RXD_W2_SIGNAL) & ~0x08;
-	rxdesc->rssi = rt2x00_get_field32(word2, RXD_W3_RSSI) -
+	rxdesc->rssi = rt2x00_get_field32(word3, RXD_W3_RSSI) -
 	    entry->queue->rt2x00dev->rssi_offset;
 	rxdesc->size = rt2x00_get_field32(word0, RXD_W0_DATABYTE_COUNT);
 
-- 
1.7.4.4


^ permalink raw reply related

* [PATCH 07/18] net: ethernet: use wrapper functions of net_ratelimit() to simplify code
From: Kefeng Wang @ 2013-10-15 11:45 UTC (permalink / raw)
  To: linux-kernel
  Cc: Greg Kroah-Hartman, David S. Miller, Pablo Neira Ayuso,
	Stephen Hemminger, Johannes Berg, John W. Linville,
	Stanislaw Gruszka, Johannes Berg, Francois Romieu, Ben Hutchings,
	Chas Williams, Marc Kleine-Budde, Samuel Ortiz, Paul Mackerras,
	Oliver Neukum, Konrad Rzeszutek Wilk, Boris Ostrovsky,
	David Vrabel, Rusty Russell, Michael S. Tsirkin, netfilter,
	netdev, linux-wireless, guohanjun
In-Reply-To: <1381837514-50660-1-git-send-email-wangkefeng.wang@huawei.com>

Wrapper functions net_ratelimited_function() and net_XXX_ratelimited()
are called to simplify code.

Signed-off-by: Kefeng Wang <wangkefeng.wang@huawei.com>
---
 drivers/net/ethernet/aeroflex/greth.c            | 16 ++++----
 drivers/net/ethernet/alteon/acenic.c             |  3 +-
 drivers/net/ethernet/arc/emac_main.c             |  7 ++--
 drivers/net/ethernet/broadcom/b44.c              |  4 +-
 drivers/net/ethernet/ethoc.c                     |  4 +-
 drivers/net/ethernet/faraday/ftgmac100.c         | 49 +++++++-----------------
 drivers/net/ethernet/faraday/ftmac100.c          | 45 +++++++---------------
 drivers/net/ethernet/freescale/fec_mpc52xx.c     |  3 +-
 drivers/net/ethernet/ibm/emac/mal.c              | 15 ++------
 drivers/net/ethernet/marvell/mv643xx_eth.c       |  6 +--
 drivers/net/ethernet/marvell/pxa168_eth.c        |  8 +---
 drivers/net/ethernet/marvell/sky2.c              | 42 ++++++++------------
 drivers/net/ethernet/myricom/myri10ge/myri10ge.c |  5 +--
 drivers/net/ethernet/realtek/r8169.c             | 13 +++----
 drivers/net/ethernet/sfc/rx.c                    |  8 ++--
 drivers/net/ethernet/sfc/siena_sriov.c           | 27 +++++--------
 drivers/net/ethernet/ti/davinci_emac.c           |  4 +-
 drivers/net/ethernet/tundra/tsi108_eth.c         | 12 ++----
 18 files changed, 90 insertions(+), 181 deletions(-)

diff --git a/drivers/net/ethernet/aeroflex/greth.c b/drivers/net/ethernet/aeroflex/greth.c
index e066945..6a1a97f 100644
--- a/drivers/net/ethernet/aeroflex/greth.c
+++ b/drivers/net/ethernet/aeroflex/greth.c
@@ -569,8 +569,8 @@ frag_map_error:
 		greth_write_bd(&bdp->stat, 0);
 	}
 map_error:
-	if (net_ratelimit())
-		dev_warn(greth->dev, "Could not create TX DMA mapping\n");
+	net_ratelimited_function(dev_warn,
+		greth->dev, "Could not create TX DMA mapping\n");
 	dev_kfree_skb(skb);
 out:
 	return err;
@@ -778,8 +778,8 @@ static int greth_rx(struct net_device *dev, int limit)
 
 			if (unlikely(skb == NULL)) {
 
-				if (net_ratelimit())
-					dev_warn(&dev->dev, "low on memory - " "packet dropped\n");
+				net_ratelimited_function(dev_warn, &dev->dev,
+						"low on memory - packet dropped\n");
 
 				dev->stats.rx_dropped++;
 
@@ -918,8 +918,8 @@ static int greth_rx_gbit(struct net_device *dev, int limit)
 				greth->rx_skbuff[greth->rx_cur] = newskb;
 				greth_write_bd(&bdp->addr, dma_addr);
 			} else {
-				if (net_ratelimit())
-					dev_warn(greth->dev, "Could not create DMA mapping, dropping packet\n");
+				net_ratelimited_function(dev_warn, greth->dev,
+					"Could not create DMA mapping, dropping packet\n");
 				dev_kfree_skb(newskb);
 				/* reusing current skb, so it is a drop */
 				dev->stats.rx_dropped++;
@@ -934,8 +934,8 @@ static int greth_rx_gbit(struct net_device *dev, int limit)
 			 * table handling should be divided into cleaning and
 			 * filling as the TX part of the driver
 			 */
-			if (net_ratelimit())
-				dev_warn(greth->dev, "Could not allocate SKB, dropping packet\n");
+			net_ratelimited_function(dev_warn, greth->dev,
+				"Could not allocate SKB, dropping packet\n");
 			/* reusing current skb, so it is a drop */
 			dev->stats.rx_dropped++;
 		}
diff --git a/drivers/net/ethernet/alteon/acenic.c b/drivers/net/ethernet/alteon/acenic.c
index 219be1b..432640b 100644
--- a/drivers/net/ethernet/alteon/acenic.c
+++ b/drivers/net/ethernet/alteon/acenic.c
@@ -1799,8 +1799,7 @@ static void ace_load_jumbo_rx_ring(struct net_device *dev, int nr_bufs)
 	clear_bit(0, &ap->jumbo_refill_busy);
 	return;
  error_out:
-	if (net_ratelimit())
-		printk(KERN_INFO "Out of memory when allocating "
+	net_info_ratelimited("Out of memory when allocating "
 		       "jumbo receive buffers\n");
 	goto out;
 }
diff --git a/drivers/net/ethernet/arc/emac_main.c b/drivers/net/ethernet/arc/emac_main.c
index 9e16014..fe659b8 100644
--- a/drivers/net/ethernet/arc/emac_main.c
+++ b/drivers/net/ethernet/arc/emac_main.c
@@ -221,8 +221,8 @@ static int arc_emac_rx(struct net_device *ndev, int budget)
 			/* We pre-allocate buffers of MTU size so incoming
 			 * packets won't be split/chained.
 			 */
-			if (net_ratelimit())
-				netdev_err(ndev, "incomplete packet received\n");
+			net_ratelimited_funciton(netdev_err, ndev,
+				"incomplete packet received\n");
 
 			/* Return ownership to EMAC */
 			rxbd->info = cpu_to_le32(FOR_EMAC | EMAC_BUFFER_SIZE);
@@ -258,8 +258,7 @@ static int arc_emac_rx(struct net_device *ndev, int budget)
 		addr = dma_map_single(&ndev->dev, (void *)rx_buff->skb->data,
 				      EMAC_BUFFER_SIZE, DMA_FROM_DEVICE);
 		if (dma_mapping_error(&ndev->dev, addr)) {
-			if (net_ratelimit())
-				netdev_err(ndev, "cannot dma map\n");
+			net_ratelimited_function(netdev_err, ndev, "cannot dma map\n");
 			dev_kfree_skb(rx_buff->skb);
 			stats->rx_errors++;
 			continue;
diff --git a/drivers/net/ethernet/broadcom/b44.c b/drivers/net/ethernet/broadcom/b44.c
index 9b017d9..7e422dc 100644
--- a/drivers/net/ethernet/broadcom/b44.c
+++ b/drivers/net/ethernet/broadcom/b44.c
@@ -187,8 +187,8 @@ static int b44_wait_bit(struct b44 *bp, unsigned long reg,
 		udelay(10);
 	}
 	if (i == timeout) {
-		if (net_ratelimit())
-			netdev_err(bp->dev, "BUG!  Timeout waiting for bit %08x of register %lx to %s\n",
+		net_ratelimited_function(netdev_err, bp->dev,
+				"BUG!  Timeout waiting for bit %08x of register %lx to %s\n",
 				   bit, reg, clear ? "clear" : "set");
 
 		return -ENODEV;
diff --git a/drivers/net/ethernet/ethoc.c b/drivers/net/ethernet/ethoc.c
index 4de8cfd..b61b56d 100644
--- a/drivers/net/ethernet/ethoc.c
+++ b/drivers/net/ethernet/ethoc.c
@@ -446,10 +446,8 @@ static int ethoc_rx(struct net_device *dev, int limit)
 				dev->stats.rx_bytes += size;
 				netif_receive_skb(skb);
 			} else {
-				if (net_ratelimit())
-					dev_warn(&dev->dev,
+				net_ratelimited_function(dev_warn, &dev->dev,
 					    "low on memory - packet dropped\n");
-
 				dev->stats.rx_dropped++;
 				break;
 			}
diff --git a/drivers/net/ethernet/faraday/ftgmac100.c b/drivers/net/ethernet/faraday/ftgmac100.c
index 212f44b..a289337 100644
--- a/drivers/net/ethernet/faraday/ftgmac100.c
+++ b/drivers/net/ethernet/faraday/ftgmac100.c
@@ -354,42 +354,30 @@ static bool ftgmac100_rx_packet_error(struct ftgmac100 *priv,
 	bool error = false;
 
 	if (unlikely(ftgmac100_rxdes_rx_error(rxdes))) {
-		if (net_ratelimit())
-			netdev_info(netdev, "rx err\n");
-
+		net_ratelimited_function(netdev_info, netdev, "rx err\n");
 		netdev->stats.rx_errors++;
 		error = true;
 	}
 
 	if (unlikely(ftgmac100_rxdes_crc_error(rxdes))) {
-		if (net_ratelimit())
-			netdev_info(netdev, "rx crc err\n");
-
+		net_ratelimited_function(netdev_info, netdev, "rx crc err\n");
 		netdev->stats.rx_crc_errors++;
 		error = true;
 	} else if (unlikely(ftgmac100_rxdes_ipcs_err(rxdes))) {
-		if (net_ratelimit())
-			netdev_info(netdev, "rx IP checksum err\n");
-
+		net_ratelimited_function(netdev_info, netdev, "rx IP checksum err\n");
 		error = true;
 	}
 
 	if (unlikely(ftgmac100_rxdes_frame_too_long(rxdes))) {
-		if (net_ratelimit())
-			netdev_info(netdev, "rx frame too long\n");
-
+		net_ratelimited_function(netdev_info, netdev, "rx frame too long\n");
 		netdev->stats.rx_length_errors++;
 		error = true;
 	} else if (unlikely(ftgmac100_rxdes_runt(rxdes))) {
-		if (net_ratelimit())
-			netdev_info(netdev, "rx runt\n");
-
+		net_ratelimited_function(netdev_info, netdev, "rx runt\n");
 		netdev->stats.rx_length_errors++;
 		error = true;
 	} else if (unlikely(ftgmac100_rxdes_odd_nibble(rxdes))) {
-		if (net_ratelimit())
-			netdev_info(netdev, "rx odd nibble\n");
-
+		net_ratelimited_function(netdev_info, netdev, "rx odd bibble\n");
 		netdev->stats.rx_length_errors++;
 		error = true;
 	}
@@ -403,8 +391,7 @@ static void ftgmac100_rx_drop_packet(struct ftgmac100 *priv)
 	struct ftgmac100_rxdes *rxdes = ftgmac100_current_rxdes(priv);
 	bool done = false;
 
-	if (net_ratelimit())
-		netdev_dbg(netdev, "drop packet %p\n", rxdes);
+	net_ratelimited_function(netdev_dbg, netdev, "drop packet %p\n", rxdes);
 
 	do {
 		if (ftgmac100_rxdes_last_segment(rxdes))
@@ -437,9 +424,7 @@ static bool ftgmac100_rx_packet(struct ftgmac100 *priv, int *processed)
 	/* start processing */
 	skb = netdev_alloc_skb_ip_align(netdev, 128);
 	if (unlikely(!skb)) {
-		if (net_ratelimit())
-			netdev_err(netdev, "rx skb alloc failed\n");
-
+		net_ratelimited_function(netdev_err, netdev, "rx skb alloc failed\n");
 		ftgmac100_rx_drop_packet(priv);
 		return true;
 	}
@@ -723,15 +708,13 @@ static int ftgmac100_alloc_rx_page(struct ftgmac100 *priv,
 
 	page = alloc_page(gfp);
 	if (!page) {
-		if (net_ratelimit())
-			netdev_err(netdev, "failed to allocate rx page\n");
+		net_ratelimited_function(netdev_err, netdev, "failed to allocate rx page\n");
 		return -ENOMEM;
 	}
 
 	map = dma_map_page(priv->dev, page, 0, RX_BUF_SIZE, DMA_FROM_DEVICE);
 	if (unlikely(dma_mapping_error(priv->dev, map))) {
-		if (net_ratelimit())
-			netdev_err(netdev, "failed to map rx page\n");
+		net_ratelimited_function(netdev_err, netdev, "failed to map rx page\n");
 		__free_page(page);
 		return -ENOMEM;
 	}
@@ -1043,8 +1026,8 @@ static int ftgmac100_poll(struct napi_struct *napi, int budget)
 
 	if (status & (FTGMAC100_INT_NO_RXBUF | FTGMAC100_INT_RPKT_LOST |
 		      FTGMAC100_INT_AHB_ERR | FTGMAC100_INT_PHYSTS_CHG)) {
-		if (net_ratelimit())
-			netdev_info(netdev, "[ISR] = 0x%x: %s%s%s%s\n", status,
+		net_ratelimited_function(netdev_info, netdev, "[ISR] = 0x%x: %s%s%s%s\n",
+					status,
 				    status & FTGMAC100_INT_NO_RXBUF ? "NO_RXBUF " : "",
 				    status & FTGMAC100_INT_RPKT_LOST ? "RPKT_LOST " : "",
 				    status & FTGMAC100_INT_AHB_ERR ? "AHB_ERR " : "",
@@ -1145,9 +1128,7 @@ static int ftgmac100_hard_start_xmit(struct sk_buff *skb,
 	dma_addr_t map;
 
 	if (unlikely(skb->len > MAX_PKT_SIZE)) {
-		if (net_ratelimit())
-			netdev_dbg(netdev, "tx packet too big\n");
-
+		net_ratelimited_function(netdev_dbg, netdev, "tx packet too big\n");
 		netdev->stats.tx_dropped++;
 		dev_kfree_skb(skb);
 		return NETDEV_TX_OK;
@@ -1156,9 +1137,7 @@ static int ftgmac100_hard_start_xmit(struct sk_buff *skb,
 	map = dma_map_single(priv->dev, skb->data, skb_headlen(skb), DMA_TO_DEVICE);
 	if (unlikely(dma_mapping_error(priv->dev, map))) {
 		/* drop packet */
-		if (net_ratelimit())
-			netdev_err(netdev, "map socket buffer failed\n");
-
+		net_ratelimited_function(netdev_err, netdev, "map socket buffer failed\n");
 		netdev->stats.tx_dropped++;
 		dev_kfree_skb(skb);
 		return NETDEV_TX_OK;
diff --git a/drivers/net/ethernet/faraday/ftmac100.c b/drivers/net/ethernet/faraday/ftmac100.c
index 8be5b40..ec8afe2 100644
--- a/drivers/net/ethernet/faraday/ftmac100.c
+++ b/drivers/net/ethernet/faraday/ftmac100.c
@@ -335,37 +335,27 @@ static bool ftmac100_rx_packet_error(struct ftmac100 *priv,
 	bool error = false;
 
 	if (unlikely(ftmac100_rxdes_rx_error(rxdes))) {
-		if (net_ratelimit())
-			netdev_info(netdev, "rx err\n");
-
+		net_ratelimited_function(netdev_info, netdev, "rx err\n");
 		netdev->stats.rx_errors++;
 		error = true;
 	}
 
 	if (unlikely(ftmac100_rxdes_crc_error(rxdes))) {
-		if (net_ratelimit())
-			netdev_info(netdev, "rx crc err\n");
-
+		net_ratelimited_function(netdev_info, netdev, "rx crc err\n");
 		netdev->stats.rx_crc_errors++;
 		error = true;
 	}
 
 	if (unlikely(ftmac100_rxdes_frame_too_long(rxdes))) {
-		if (net_ratelimit())
-			netdev_info(netdev, "rx frame too long\n");
-
+		net_ratelimited_function(netdev_info, netdev, "rx frame too long\n");
 		netdev->stats.rx_length_errors++;
 		error = true;
 	} else if (unlikely(ftmac100_rxdes_runt(rxdes))) {
-		if (net_ratelimit())
-			netdev_info(netdev, "rx runt\n");
-
+		net_ratelimited_function(netdev_info, netdev, "rx runt\n");
 		netdev->stats.rx_length_errors++;
 		error = true;
 	} else if (unlikely(ftmac100_rxdes_odd_nibble(rxdes))) {
-		if (net_ratelimit())
-			netdev_info(netdev, "rx odd nibble\n");
-
+		net_ratelimited_function(netdev_info, netdev, "rx odd nibble\n");
 		netdev->stats.rx_length_errors++;
 		error = true;
 	}
@@ -379,8 +369,7 @@ static void ftmac100_rx_drop_packet(struct ftmac100 *priv)
 	struct ftmac100_rxdes *rxdes = ftmac100_current_rxdes(priv);
 	bool done = false;
 
-	if (net_ratelimit())
-		netdev_dbg(netdev, "drop packet %p\n", rxdes);
+	net_ratelimited_function(netdev_dbg, netdev, "drop packet %p\n", rxdes);
 
 	do {
 		if (ftmac100_rxdes_last_segment(rxdes))
@@ -422,9 +411,7 @@ static bool ftmac100_rx_packet(struct ftmac100 *priv, int *processed)
 	/* start processing */
 	skb = netdev_alloc_skb_ip_align(netdev, 128);
 	if (unlikely(!skb)) {
-		if (net_ratelimit())
-			netdev_err(netdev, "rx skb alloc failed\n");
-
+		net_ratelimited_function(netdev_err, netdev, "rx skb alloc failed\n");
 		ftmac100_rx_drop_packet(priv);
 		return true;
 	}
@@ -676,15 +663,13 @@ static int ftmac100_alloc_rx_page(struct ftmac100 *priv,
 
 	page = alloc_page(gfp);
 	if (!page) {
-		if (net_ratelimit())
-			netdev_err(netdev, "failed to allocate rx page\n");
+		net_ratelimited_function(netdev_err, netdev, "failed to allocate rx page\n");
 		return -ENOMEM;
 	}
 
 	map = dma_map_page(priv->dev, page, 0, RX_BUF_SIZE, DMA_FROM_DEVICE);
 	if (unlikely(dma_mapping_error(priv->dev, map))) {
-		if (net_ratelimit())
-			netdev_err(netdev, "failed to map rx page\n");
+		net_ratelimited_function(netdev_err, netdev, "failed to map rx page\n");
 		__free_page(page);
 		return -ENOMEM;
 	}
@@ -919,8 +904,8 @@ static int ftmac100_poll(struct napi_struct *napi, int budget)
 
 	if (status & (FTMAC100_INT_NORXBUF | FTMAC100_INT_RPKT_LOST |
 		      FTMAC100_INT_AHB_ERR | FTMAC100_INT_PHYSTS_CHG)) {
-		if (net_ratelimit())
-			netdev_info(netdev, "[ISR] = 0x%x: %s%s%s%s\n", status,
+		net_ratelimited_function(netdev_info, netdev, "[ISR] = 0x%x: %s%s%s%s\n",
+					status,
 				    status & FTMAC100_INT_NORXBUF ? "NORXBUF " : "",
 				    status & FTMAC100_INT_RPKT_LOST ? "RPKT_LOST " : "",
 				    status & FTMAC100_INT_AHB_ERR ? "AHB_ERR " : "",
@@ -1015,9 +1000,7 @@ static int ftmac100_hard_start_xmit(struct sk_buff *skb, struct net_device *netd
 	dma_addr_t map;
 
 	if (unlikely(skb->len > MAX_PKT_SIZE)) {
-		if (net_ratelimit())
-			netdev_dbg(netdev, "tx packet too big\n");
-
+		net_ratelimited_function(netdev_dbg, netdev, "tx packet too big\n");
 		netdev->stats.tx_dropped++;
 		dev_kfree_skb(skb);
 		return NETDEV_TX_OK;
@@ -1026,9 +1009,7 @@ static int ftmac100_hard_start_xmit(struct sk_buff *skb, struct net_device *netd
 	map = dma_map_single(priv->dev, skb->data, skb_headlen(skb), DMA_TO_DEVICE);
 	if (unlikely(dma_mapping_error(priv->dev, map))) {
 		/* drop packet */
-		if (net_ratelimit())
-			netdev_err(netdev, "map socket buffer failed\n");
-
+		net_ratelimited_function(netdev_err, netdev, "map socket buffer failed\n");
 		netdev->stats.tx_dropped++;
 		dev_kfree_skb(skb);
 		return NETDEV_TX_OK;
diff --git a/drivers/net/ethernet/freescale/fec_mpc52xx.c b/drivers/net/ethernet/freescale/fec_mpc52xx.c
index 9947765..6b1feeb 100644
--- a/drivers/net/ethernet/freescale/fec_mpc52xx.c
+++ b/drivers/net/ethernet/freescale/fec_mpc52xx.c
@@ -313,8 +313,7 @@ static int mpc52xx_fec_start_xmit(struct sk_buff *skb, struct net_device *dev)
 	unsigned long flags;
 
 	if (bcom_queue_full(priv->tx_dmatsk)) {
-		if (net_ratelimit())
-			dev_err(&dev->dev, "transmit queue overrun\n");
+		net_ratelimited_function(dev_err, &dev->dev, "transmit queue overrun\n");
 		return NETDEV_TX_BUSY;
 	}
 
diff --git a/drivers/net/ethernet/ibm/emac/mal.c b/drivers/net/ethernet/ibm/emac/mal.c
index dac564c..9177345 100644
--- a/drivers/net/ethernet/ibm/emac/mal.c
+++ b/drivers/net/ethernet/ibm/emac/mal.c
@@ -240,20 +240,15 @@ static irqreturn_t mal_serr(int irq, void *dev_instance)
 			/* PLB error, it's probably buggy hardware or
 			 * incorrect physical address in BD (i.e. bug)
 			 */
-			if (net_ratelimit())
-				printk(KERN_ERR
-				       "mal%d: system error, "
-				       "PLB (ESR = 0x%08x)\n",
-				       mal->index, esr);
+			net_err_ratelimited("mal%d: system error, "
+				"PLB (ESR = 0x%08x)\n", mal->index, esr);
 			return IRQ_HANDLED;
 		}
 
 		/* OPB error, it's probably buggy hardware or incorrect
 		 * EBC setup
 		 */
-		if (net_ratelimit())
-			printk(KERN_ERR
-			       "mal%d: system error, OPB (ESR = 0x%08x)\n",
+		net_err_ratelimited("mal%d: system error, OPB (ESR = 0x%08x)\n",
 			       mal->index, esr);
 	}
 	return IRQ_HANDLED;
@@ -318,9 +313,7 @@ static irqreturn_t mal_txde(int irq, void *dev_instance)
 
 	MAL_DBG(mal, "txde %08x" NL, deir);
 
-	if (net_ratelimit())
-		printk(KERN_ERR
-		       "mal%d: TX descriptor error (TXDEIR = 0x%08x)\n",
+	net_err_ratelimited("mal%d: TX descriptor error (TXDEIR = 0x%08x)\n",
 		       mal->index, deir);
 
 	return IRQ_HANDLED;
diff --git a/drivers/net/ethernet/marvell/mv643xx_eth.c b/drivers/net/ethernet/marvell/mv643xx_eth.c
index 7fb5677..d1e23d7 100644
--- a/drivers/net/ethernet/marvell/mv643xx_eth.c
+++ b/drivers/net/ethernet/marvell/mv643xx_eth.c
@@ -573,8 +573,7 @@ err:
 
 		if ((cmd_sts & (RX_FIRST_DESC | RX_LAST_DESC)) !=
 			(RX_FIRST_DESC | RX_LAST_DESC)) {
-			if (net_ratelimit())
-				netdev_err(mp->dev,
+			net_ratelimited_function(netdev_err, mp->dev,
 					   "received packet spanning multiple descriptors\n");
 		}
 
@@ -818,8 +817,7 @@ static netdev_tx_t mv643xx_eth_xmit(struct sk_buff *skb, struct net_device *dev)
 	}
 
 	if (txq->tx_ring_size - txq->tx_desc_count < MAX_SKB_FRAGS + 1) {
-		if (net_ratelimit())
-			netdev_err(dev, "tx queue full?!\n");
+		net_ratelimited_function(netdev_err, dev, "tx queue full?!\n");
 		kfree_skb(skb);
 		return NETDEV_TX_OK;
 	}
diff --git a/drivers/net/ethernet/marvell/pxa168_eth.c b/drivers/net/ethernet/marvell/pxa168_eth.c
index fff6246..ce36745 100644
--- a/drivers/net/ethernet/marvell/pxa168_eth.c
+++ b/drivers/net/ethernet/marvell/pxa168_eth.c
@@ -744,8 +744,7 @@ static int txq_reclaim(struct net_device *dev, int force)
 			pep->tx_skb[tx_index] = NULL;
 
 		if (cmd_sts & TX_ERROR) {
-			if (net_ratelimit())
-				printk(KERN_ERR "%s: Error in TX\n", dev->name);
+			net_err_ratelimited("%s: Error in TX\n", dev->name);
 			dev->stats.tx_errors++;
 		}
 		dma_unmap_single(NULL, addr, count, DMA_TO_DEVICE);
@@ -832,10 +831,7 @@ static int rxq_process(struct net_device *dev, int budget)
 			stats->rx_dropped++;
 			if ((cmd_sts & (RX_FIRST_DESC | RX_LAST_DESC)) !=
 			    (RX_FIRST_DESC | RX_LAST_DESC)) {
-				if (net_ratelimit())
-					printk(KERN_ERR
-					       "%s: Rx pkt on multiple desc\n",
-					       dev->name);
+				net_err_ratelimited("%s: Rx pkt on multiple desc\n", dev->name);
 			}
 			if (cmd_sts & RX_ERROR)
 				stats->rx_errors++;
diff --git a/drivers/net/ethernet/marvell/sky2.c b/drivers/net/ethernet/marvell/sky2.c
index e09a8c6..42cad5d 100644
--- a/drivers/net/ethernet/marvell/sky2.c
+++ b/drivers/net/ethernet/marvell/sky2.c
@@ -1250,8 +1250,7 @@ map_page_error:
 			 PCI_DMA_FROMDEVICE);
 
 mapping_error:
-	if (net_ratelimit())
-		dev_warn(&pdev->dev, "%s: rx mapping error\n",
+	net_ratelimited_function(dev_warn, &pdev->dev, "%s: rx mapping error\n",
 			 skb->dev->name);
 	return -EIO;
 }
@@ -1998,8 +1997,8 @@ mapping_unwind:
 	}
 
 mapping_error:
-	if (net_ratelimit())
-		dev_warn(&hw->pdev->dev, "%s: tx mapping error\n", dev->name);
+	net_ratelimited_function(dev_warn, &hw->pdev->dev,
+		"%s: tx mapping error\n", dev->name);
 	dev_kfree_skb(skb);
 	return NETDEV_TX_OK;
 }
@@ -2633,8 +2632,7 @@ resubmit:
 error:
 	++dev->stats.rx_errors;
 
-	if (net_ratelimit())
-		netif_info(sky2, rx_err, dev,
+	net_ratelimited_function(netif_info, sky2, rx_err, dev,
 			   "rx error, status 0x%x length %d\n", status, length);
 
 	goto resubmit;
@@ -2809,8 +2807,7 @@ static int sky2_status_intr(struct sky2_hw *hw, int to_do, u16 idx)
 			break;
 
 		default:
-			if (net_ratelimit())
-				pr_warning("unknown status opcode 0x%x\n", opcode);
+			net_warn_ratelimited("unknown status opcode 0x%x\n", opcode);
 		}
 	} while (hw->st_idx != idx);
 
@@ -2828,38 +2825,33 @@ static void sky2_hw_error(struct sky2_hw *hw, unsigned port, u32 status)
 {
 	struct net_device *dev = hw->dev[port];
 
-	if (net_ratelimit())
-		netdev_info(dev, "hw error interrupt status 0x%x\n", status);
+	net_ratelimited_function(netdev_info, dev, "hw error interrupt status 0x%x\n",
+		status);
 
 	if (status & Y2_IS_PAR_RD1) {
-		if (net_ratelimit())
-			netdev_err(dev, "ram data read parity error\n");
+		net_ratelimited_function(netdev_err, dev, "ram data read parity error\n");
 		/* Clear IRQ */
 		sky2_write16(hw, RAM_BUFFER(port, B3_RI_CTRL), RI_CLR_RD_PERR);
 	}
 
 	if (status & Y2_IS_PAR_WR1) {
-		if (net_ratelimit())
-			netdev_err(dev, "ram data write parity error\n");
+		net_ratelimited_function(netdev_err, dev, "ram data write parity error\n");
 
 		sky2_write16(hw, RAM_BUFFER(port, B3_RI_CTRL), RI_CLR_WR_PERR);
 	}
 
 	if (status & Y2_IS_PAR_MAC1) {
-		if (net_ratelimit())
-			netdev_err(dev, "MAC parity error\n");
+		net_ratelimited_function(netdev_err, dev, "MAC parity error\n");
 		sky2_write8(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_CLI_TX_PE);
 	}
 
 	if (status & Y2_IS_PAR_RX1) {
-		if (net_ratelimit())
-			netdev_err(dev, "RX parity error\n");
+		net_ratelimited_function(netdev_err, dev, "RX parity error\n");
 		sky2_write32(hw, Q_ADDR(rxqaddr[port], Q_CSR), BMU_CLR_IRQ_PAR);
 	}
 
 	if (status & Y2_IS_TCP_TXA1) {
-		if (net_ratelimit())
-			netdev_err(dev, "TCP segmentation error\n");
+		net_ratelimited_function(netdev_err, dev, "TCP segmentation error\n");
 		sky2_write32(hw, Q_ADDR(txqaddr[port], Q_CSR), BMU_CLR_IRQ_TCP);
 	}
 }
@@ -2880,8 +2872,7 @@ static void sky2_hw_intr(struct sky2_hw *hw)
 
 		sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON);
 		pci_err = sky2_pci_read16(hw, PCI_STATUS);
-		if (net_ratelimit())
-			dev_err(&pdev->dev, "PCI hardware error (0x%x)\n",
+		net_ratelimited_function(dev_err, &pdev->dev, "PCI hardware error (0x%x)\n",
 			        pci_err);
 
 		sky2_pci_write16(hw, PCI_STATUS,
@@ -2897,8 +2888,7 @@ static void sky2_hw_intr(struct sky2_hw *hw)
 		err = sky2_read32(hw, Y2_CFG_AER + PCI_ERR_UNCOR_STATUS);
 		sky2_write32(hw, Y2_CFG_AER + PCI_ERR_UNCOR_STATUS,
 			     0xfffffffful);
-		if (net_ratelimit())
-			dev_err(&pdev->dev, "PCI Express error (0x%x)\n", err);
+		net_ratelimited_function(dev_err, &pdev->dev, "PCI Express error (0x%x)\n", err);
 
 		sky2_read32(hw, Y2_CFG_AER + PCI_ERR_UNCOR_STATUS);
 		sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
@@ -3017,8 +3007,8 @@ static void sky2_watchdog(unsigned long arg)
 /* Hardware/software error handling */
 static void sky2_err_intr(struct sky2_hw *hw, u32 status)
 {
-	if (net_ratelimit())
-		dev_warn(&hw->pdev->dev, "error interrupt status=%#x\n", status);
+	net_ratelimited_function(dev_warn, &hw->pdev->dev,
+		"error interrupt status=%#x\n", status);
 
 	if (status & Y2_IS_HW_ERR)
 		sky2_hw_intr(hw);
diff --git a/drivers/net/ethernet/myricom/myri10ge/myri10ge.c b/drivers/net/ethernet/myricom/myri10ge/myri10ge.c
index 149355b..920ef96 100644
--- a/drivers/net/ethernet/myricom/myri10ge/myri10ge.c
+++ b/drivers/net/ethernet/myricom/myri10ge/myri10ge.c
@@ -3559,9 +3559,8 @@ myri10ge_check_slice(struct myri10ge_slice_state *ss, int *reset_needed,
 	    ss->watchdog_tx_req != ss->watchdog_tx_done) {
 		/* nic seems like it might be stuck.. */
 		if (rx_pause_cnt != mgp->watchdog_pause) {
-			if (net_ratelimit())
-				netdev_warn(mgp->dev, "slice %d: TX paused, "
-					    "check link partner\n", slice);
+			net_ratelimited_function(netdev_warn, mgp->dev,
+				"slice %d: TX paused, check link partner\n", slice);
 		} else {
 			netdev_warn(mgp->dev,
 				    "slice %d: TX stuck %d %d %d %d %d %d\n",
diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c
index 3397cee..5e0ee96 100644
--- a/drivers/net/ethernet/realtek/r8169.c
+++ b/drivers/net/ethernet/realtek/r8169.c
@@ -1496,8 +1496,7 @@ static void __rtl8169_check_link_status(struct net_device *dev,
 		if (pm)
 			pm_request_resume(&tp->pci_dev->dev);
 		netif_carrier_on(dev);
-		if (net_ratelimit())
-			netif_info(tp, ifup, dev, "link up\n");
+		net_ratelimited_function(netif_info, tp, ifup, dev, "link up\n");
 	} else {
 		netif_carrier_off(dev);
 		netif_info(tp, ifdown, dev, "link down\n");
@@ -5732,8 +5731,8 @@ static struct sk_buff *rtl8169_alloc_rx_data(struct rtl8169_private *tp,
 	mapping = dma_map_single(d, rtl8169_align(data), rx_buf_sz,
 				 DMA_FROM_DEVICE);
 	if (unlikely(dma_mapping_error(d, mapping))) {
-		if (net_ratelimit())
-			netif_err(tp, drv, tp->dev, "Failed to map RX DMA!\n");
+		net_ratelimited_function(netif_err,
+			tp, drv, tp->dev, "Failed to map RX DMA!\n");
 		goto err_out;
 	}
 
@@ -5895,8 +5894,7 @@ static int rtl8169_xmit_frags(struct rtl8169_private *tp, struct sk_buff *skb,
 		addr = skb_frag_address(frag);
 		mapping = dma_map_single(d, addr, len, DMA_TO_DEVICE);
 		if (unlikely(dma_mapping_error(d, mapping))) {
-			if (net_ratelimit())
-				netif_err(tp, drv, tp->dev,
+			net_ratelimited_function(netif_err, tp, drv, tp->dev,
 					  "Failed to map TX fragments DMA!\n");
 			goto err_out;
 		}
@@ -5996,8 +5994,7 @@ static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb,
 	len = skb_headlen(skb);
 	mapping = dma_map_single(d, skb->data, len, DMA_TO_DEVICE);
 	if (unlikely(dma_mapping_error(d, mapping))) {
-		if (net_ratelimit())
-			netif_err(tp, drv, dev, "Failed to map TX DMA!\n");
+		net_ratelimited_function(netif_err, tp, drv, dev, "Failed to map TX DMA!\n");
 		goto err_dma_0;
 	}
 
diff --git a/drivers/net/ethernet/sfc/rx.c b/drivers/net/ethernet/sfc/rx.c
index 4a59672..b53f16d 100644
--- a/drivers/net/ethernet/sfc/rx.c
+++ b/drivers/net/ethernet/sfc/rx.c
@@ -397,19 +397,17 @@ static void efx_rx_packet__check_len(struct efx_rx_queue *rx_queue,
 	rx_buf->flags |= EFX_RX_PKT_DISCARD;
 
 	if ((len > rx_buf->len) && EFX_WORKAROUND_8071(efx)) {
-		if (net_ratelimit())
-			netif_err(efx, rx_err, efx->net_dev,
+		net_ratelimited_function(netif_err, efx, rx_err, efx->net_dev,
 				  " RX queue %d seriously overlength "
 				  "RX event (0x%x > 0x%x+0x%x). Leaking\n",
 				  efx_rx_queue_index(rx_queue), len, max_len,
 				  efx->type->rx_buffer_padding);
 		efx_schedule_reset(efx, RESET_TYPE_RX_RECOVERY);
 	} else {
-		if (net_ratelimit())
-			netif_err(efx, rx_err, efx->net_dev,
+		net_ratelimited_function(netif_err, efx, rx_err, efx->net_dev,
 				  " RX queue %d overlength RX event "
 				  "(0x%x > 0x%x)\n",
-				  efx_rx_queue_index(rx_queue), len, max_len);
+		efx_rx_queue_index(rx_queue), len, max_len);
 	}
 
 	efx_rx_queue_channel(rx_queue)->n_rx_overlength++;
diff --git a/drivers/net/ethernet/sfc/siena_sriov.c b/drivers/net/ethernet/sfc/siena_sriov.c
index 0c38f92..71ec42d 100644
--- a/drivers/net/ethernet/sfc/siena_sriov.c
+++ b/drivers/net/ethernet/sfc/siena_sriov.c
@@ -532,8 +532,7 @@ static int efx_vfdi_init_evq(struct efx_vf *vf)
 
 	if (bad_vf_index(efx, vf_evq) ||
 	    bad_buf_count(buf_count, EFX_MAX_VF_EVQ_SIZE)) {
-		if (net_ratelimit())
-			netif_err(efx, hw, efx->net_dev,
+		net_ratelimited_function(netif_err, efx, hw, efx->net_dev,
 				  "ERROR: Invalid INIT_EVQ from %s: evq %d bufs %d\n",
 				  vf->pci_name, vf_evq, buf_count);
 		return VFDI_RC_EINVAL;
@@ -575,8 +574,7 @@ static int efx_vfdi_init_rxq(struct efx_vf *vf)
 	if (bad_vf_index(efx, vf_evq) || bad_vf_index(efx, vf_rxq) ||
 	    vf_rxq >= VF_MAX_RX_QUEUES ||
 	    bad_buf_count(buf_count, EFX_MAX_DMAQ_SIZE)) {
-		if (net_ratelimit())
-			netif_err(efx, hw, efx->net_dev,
+		net_ratelimited_function(netif_err, efx, hw, efx->net_dev,
 				  "ERROR: Invalid INIT_RXQ from %s: rxq %d evq %d "
 				  "buf_count %d\n", vf->pci_name, vf_rxq,
 				  vf_evq, buf_count);
@@ -616,8 +614,7 @@ static int efx_vfdi_init_txq(struct efx_vf *vf)
 	if (bad_vf_index(efx, vf_evq) || bad_vf_index(efx, vf_txq) ||
 	    vf_txq >= vf_max_tx_channels ||
 	    bad_buf_count(buf_count, EFX_MAX_DMAQ_SIZE)) {
-		if (net_ratelimit())
-			netif_err(efx, hw, efx->net_dev,
+		net_ratelimited_function(netif_err, efx, hw, efx->net_dev,
 				  "ERROR: Invalid INIT_TXQ from %s: txq %d evq %d "
 				  "buf_count %d\n", vf->pci_name, vf_txq,
 				  vf_evq, buf_count);
@@ -759,8 +756,7 @@ static int efx_vfdi_insert_filter(struct efx_vf *vf)
 	unsigned flags;
 
 	if (bad_vf_index(efx, vf_rxq) || vf->rx_filtering) {
-		if (net_ratelimit())
-			netif_err(efx, hw, efx->net_dev,
+		net_ratelimited_function(netif_err, efx, hw, efx->net_dev,
 				  "ERROR: Invalid INSERT_FILTER from %s: rxq %d "
 				  "flags 0x%x\n", vf->pci_name, vf_rxq,
 				  req->u.mac_filter.flags);
@@ -802,8 +798,7 @@ static int efx_vfdi_set_status_page(struct efx_vf *vf)
 		/ sizeof(req->u.set_status_page.peer_page_addr[0]);
 
 	if (!req->u.set_status_page.dma_addr || page_count > max_page_count) {
-		if (net_ratelimit())
-			netif_err(efx, hw, efx->net_dev,
+		net_ratelimited_function(netif_err, efx, hw, efx->net_dev,
 				  "ERROR: Invalid SET_STATUS_PAGE from %s\n",
 				  vf->pci_name);
 		return VFDI_RC_EINVAL;
@@ -875,8 +870,7 @@ static void efx_sriov_vfdi(struct work_struct *work)
 	rc = efx_sriov_memcpy(efx, copy, 1);
 	if (rc) {
 		/* If we can't get the request, we can't reply to the caller */
-		if (net_ratelimit())
-			netif_err(efx, hw, efx->net_dev,
+		net_ratelimited_function(netif_err, efx, hw, efx->net_dev,
 				  "ERROR: Unable to fetch VFDI request from %s rc %d\n",
 				  vf->pci_name, -rc);
 		vf->busy = false;
@@ -963,8 +957,7 @@ static void efx_sriov_reset_vf(struct efx_vf *vf, struct efx_buffer *buffer)
 		}
 		rc = efx_sriov_memcpy(efx, copy_req, count);
 		if (rc) {
-			if (net_ratelimit())
-				netif_err(efx, hw, efx->net_dev,
+			net_ratelimited_function(netif_err, efx, hw, efx->net_dev,
 					  "ERROR: Unable to notify %s of reset"
 					  ": %d\n", vf->pci_name, -rc);
 			break;
@@ -1420,8 +1413,7 @@ void efx_sriov_event(struct efx_channel *channel, efx_qword_t *event)
 	}
 
 error:
-	if (net_ratelimit())
-		netif_err(efx, hw, efx->net_dev,
+	net_ratelimited_function(netif_err, efx, hw, efx->net_dev,
 			  "ERROR: Screaming VFDI request from %s\n",
 			  vf->pci_name);
 	/* Reset the request and sequence number */
@@ -1509,8 +1501,7 @@ void efx_sriov_desc_fetch_err(struct efx_nic *efx, unsigned dmaq)
 	if (map_vi_index(efx, dmaq, &vf, &rel))
 		return;
 
-	if (net_ratelimit())
-		netif_err(efx, hw, efx->net_dev,
+	net_ratelimited_function(netif_err, efx, hw, efx->net_dev,
 			  "VF %d DMA Q %d reports descriptor fetch error.\n",
 			  vf->index, rel);
 	queue_work(vfdi_workqueue, &vf->reset_work);
diff --git a/drivers/net/ethernet/ti/davinci_emac.c b/drivers/net/ethernet/ti/davinci_emac.c
index 67df09e..caab0a9 100644
--- a/drivers/net/ethernet/ti/davinci_emac.c
+++ b/drivers/net/ethernet/ti/davinci_emac.c
@@ -1408,10 +1408,8 @@ static int emac_poll(struct napi_struct *napi, int budget)
 		if (cause) {
 			ch = ((status & EMAC_MACSTATUS_TXERRCH_MASK) >>
 			      EMAC_MACSTATUS_TXERRCH_SHIFT);
-			if (net_ratelimit()) {
-				dev_err(emac_dev, "TX Host error %s on ch=%d\n",
+			net_ratelimited_function(dev_err, emac_dev, "TX Host error %s on ch=%d\n",
 					&emac_txhost_errcodes[cause][0], ch);
-			}
 		}
 		cause = ((status & EMAC_MACSTATUS_RXERRCODE_MASK) >>
 			 EMAC_MACSTATUS_RXERRCODE_SHIFT);
diff --git a/drivers/net/ethernet/tundra/tsi108_eth.c b/drivers/net/ethernet/tundra/tsi108_eth.c
index c4dbf98..467d76d 100644
--- a/drivers/net/ethernet/tundra/tsi108_eth.c
+++ b/drivers/net/ethernet/tundra/tsi108_eth.c
@@ -669,10 +669,7 @@ static int tsi108_send_packet(struct sk_buff * skb, struct net_device *dev)
 
 	if (data->txfree < MAX_SKB_FRAGS + 1) {
 		netif_stop_queue(dev);
-
-		if (net_ratelimit())
-			printk(KERN_ERR "%s: Transmit with full tx ring!\n",
-			       dev->name);
+		net_err_ratelimited("%s: Transmit with full tx ring!\n", dev->name);
 		return NETDEV_TX_BUSY;
 	}
 
@@ -869,9 +866,7 @@ static int tsi108_poll(struct napi_struct *napi, int budget)
 		TSI_WRITE(TSI108_EC_RXERR, err);
 
 		if (err) {
-			if (net_ratelimit())
-				printk(KERN_DEBUG "%s: RX error %x\n",
-				       dev->name, err);
+			net_dbg_ratelimited("%s: RX error %x\n", dev->name, err);
 
 			if (!(TSI_READ(TSI108_EC_RXSTAT) &
 			      TSI108_EC_RXSTAT_QUEUE0))
@@ -1024,8 +1019,7 @@ static irqreturn_t tsi108_irq(int irq, void *dev_id)
 		tsi108_rx_int(dev);
 
 	if (stat & TSI108_INT_SFN) {
-		if (net_ratelimit())
-			printk(KERN_DEBUG "%s: SFN error\n", dev->name);
+		net_dbg_ratelimited("%s: SFN error\n", dev->name);
 		TSI_WRITE(TSI108_EC_INTSTAT, TSI108_INT_SFN);
 	}
 
-- 
1.8.2.1



^ permalink raw reply related

* [PATCH 10/18] net: peak_usb: use wrapper functions of net_ratelimit() to simplify code
From: Kefeng Wang @ 2013-10-15 11:45 UTC (permalink / raw)
  To: linux-kernel
  Cc: Greg Kroah-Hartman, David S. Miller, Pablo Neira Ayuso,
	Stephen Hemminger, Johannes Berg, John W. Linville,
	Stanislaw Gruszka, Johannes Berg, Francois Romieu, Ben Hutchings,
	Chas Williams, Marc Kleine-Budde, Samuel Ortiz, Paul Mackerras,
	Oliver Neukum, Konrad Rzeszutek Wilk, Boris Ostrovsky,
	David Vrabel, Rusty Russell, Michael S. Tsirkin, netfilter,
	netdev, linux-wireless, guohanjun
In-Reply-To: <1381837514-50660-1-git-send-email-wangkefeng.wang@huawei.com>

net_ratelimited_function() is called to simplify code.

Signed-off-by: Kefeng Wang <wangkefeng.wang@huawei.com>
---
 drivers/net/can/usb/peak_usb/pcan_usb_core.c | 11 ++++-------
 1 file changed, 4 insertions(+), 7 deletions(-)

diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_core.c b/drivers/net/can/usb/peak_usb/pcan_usb_core.c
index 0b7a4c3..5166a1f 100644
--- a/drivers/net/can/usb/peak_usb/pcan_usb_core.c
+++ b/drivers/net/can/usb/peak_usb/pcan_usb_core.c
@@ -191,8 +191,7 @@ static void peak_usb_read_bulk_callback(struct urb *urb)
 		return;
 
 	default:
-		if (net_ratelimit())
-			netdev_err(netdev,
+		net_ratelimited_function(netdev_err, netdev,
 				   "Rx urb aborted (%d)\n", urb->status);
 		goto resubmit_urb;
 	}
@@ -260,9 +259,8 @@ static void peak_usb_write_bulk_callback(struct urb *urb)
 		break;
 
 	default:
-		if (net_ratelimit())
-			netdev_err(netdev, "Tx urb aborted (%d)\n",
-				   urb->status);
+		net_ratelimited_function(netdev_err, netdev,
+			"Tx urb aborted (%d)\n", urb->status);
 	case -EPROTO:
 	case -ENOENT:
 	case -ECONNRESET:
@@ -314,8 +312,7 @@ static netdev_tx_t peak_usb_ndo_start_xmit(struct sk_buff *skb,
 
 	err = dev->adapter->dev_encode_msg(dev, skb, obuf, &size);
 	if (err) {
-		if (net_ratelimit())
-			netdev_err(netdev, "packet dropped\n");
+		net_ratelimited_function(netdev_err, netdev, "packet dropped\n");
 		dev_kfree_skb(skb);
 		stats->tx_dropped++;
 		return NETDEV_TX_OK;
-- 
1.8.2.1



^ permalink raw reply related

* [PATCH 03/18] rt18187se: use wrapper functions of net_ratelimit() to simplify code
From: Kefeng Wang @ 2013-10-15 11:44 UTC (permalink / raw)
  To: linux-kernel
  Cc: Greg Kroah-Hartman, David S. Miller, Pablo Neira Ayuso,
	Stephen Hemminger, Johannes Berg, John W. Linville,
	Stanislaw Gruszka, Johannes Berg, Francois Romieu, Ben Hutchings,
	Chas Williams, Marc Kleine-Budde, Samuel Ortiz, Paul Mackerras,
	Oliver Neukum, Konrad Rzeszutek Wilk, Boris Ostrovsky,
	David Vrabel, Rusty Russell, Michael S. Tsirkin, netfilter,
	netdev, linux-wireless, guohanjun
In-Reply-To: <1381837514-50660-1-git-send-email-wangkefeng.wang@huawei.com>

Wrapper functions net_ratelimited_function() and net_XXX_ratelimited()
are called to simplify code.

Signed-off-by: Kefeng Wang <wangkefeng.wang@huawei.com>
---
 .../rtl8187se/ieee80211/ieee80211_crypt_ccmp.c     | 16 ++++---------
 .../rtl8187se/ieee80211/ieee80211_crypt_tkip.c     | 27 ++++++----------------
 drivers/staging/rtl8187se/ieee80211/ieee80211_rx.c |  4 +---
 drivers/staging/rtl8187se/ieee80211/ieee80211_tx.c |  7 ++----
 4 files changed, 14 insertions(+), 40 deletions(-)

diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_ccmp.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_ccmp.c
index f5949e8..be6c5a1 100644
--- a/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_ccmp.c
+++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_ccmp.c
@@ -282,10 +282,8 @@ static int ieee80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
 	pos = skb->data + hdr_len;
 	keyidx = pos[3];
 	if (!(keyidx & (1 << 5))) {
-		if (net_ratelimit()) {
-			pr_debug("received packet without ExtIV flag from %pM\n",
+		net_dbg_ratelimited("received packet without ExtIV flag from %pM\n",
 				 hdr->addr2);
-		}
 		key->dot11RSNAStatsCCMPFormatErrors++;
 		return -2;
 	}
@@ -296,10 +294,8 @@ static int ieee80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
 		return -6;
 	}
 	if (!key->key_set) {
-		if (net_ratelimit()) {
-			pr_debug("received packet from %pM with keyid=%d that does not have a configured key\n",
+		net_dbg_ratelimited("received packet from %pM with keyid=%d that does not have a configured key\n",
 				 hdr->addr2, keyidx);
-		}
 		return -3;
 	}
 
@@ -312,10 +308,8 @@ static int ieee80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
 	pos += 8;
 
 	if (memcmp(pn, key->rx_pn, CCMP_PN_LEN) <= 0) {
-		if (net_ratelimit()) {
-			pr_debug("replay detected: STA=%pM previous PN %pm received PN %pm\n",
+		net_dbg_ratelimited("replay detected: STA=%pM previous PN %pm received PN %pm\n",
 				 hdr->addr2, key->rx_pn, pn);
-		}
 		key->dot11RSNAStatsCCMPReplays++;
 		return -4;
 	}
@@ -340,9 +334,7 @@ static int ieee80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
 	}
 
 	if (memcmp(mic, a, CCMP_MIC_LEN) != 0) {
-		if (net_ratelimit())
-			pr_debug("decrypt failed: STA=%pM\n", hdr->addr2);
-
+		net_dbg_ratelimited("decrypt failed: STA=%pM\n", hdr->addr2);
 		key->dot11RSNAStatsCCMPDecryptErrors++;
 		return -5;
 	}
diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_tkip.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_tkip.c
index da24e43..03e1961 100644
--- a/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_tkip.c
+++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_tkip.c
@@ -381,10 +381,8 @@ static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
 	pos = skb->data + hdr_len;
 	keyidx = pos[3];
 	if (!(keyidx & (1 << 5))) {
-		if (net_ratelimit()) {
-			printk(KERN_DEBUG "TKIP: received packet without ExtIV"
+		net_dbg_ratelimited("TKIP: received packet without ExtIV"
 			       " flag from %pM\n", hdr->addr2);
-		}
 		return -2;
 	}
 	keyidx >>= 6;
@@ -394,11 +392,9 @@ static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
 		return -6;
 	}
 	if (!tkey->key_set) {
-		if (net_ratelimit()) {
-			printk(KERN_DEBUG "TKIP: received packet from %pM"
+		net_dbg_ratelimited("TKIP: received packet from %pM"
 			       " with keyid=%d that does not have a configured"
 			       " key\n", hdr->addr2, keyidx);
-		}
 		return -3;
 	}
 	iv16 = (pos[0] << 8) | pos[2];
@@ -407,12 +403,9 @@ static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
 
 	if (iv32 < tkey->rx_iv32 ||
 	    (iv32 == tkey->rx_iv32 && iv16 <= tkey->rx_iv16)) {
-		if (net_ratelimit()) {
-			printk(KERN_DEBUG "TKIP: replay detected: STA=%pM"
-			       " previous TSC %08x%04x received TSC "
-			       "%08x%04x\n", hdr->addr2,
-			       tkey->rx_iv32, tkey->rx_iv16, iv32, iv16);
-		}
+		net_dbg_ratelimited("TKIP: replay detected: STA=%pM"
+			" previous TSC %08x%04x received TSC %08x%04x\n",
+			hdr->addr2, tkey->rx_iv32, tkey->rx_iv16, iv32, iv16);
 		tkey->dot11RSNAStatsTKIPReplays++;
 		return -4;
 	}
@@ -427,11 +420,8 @@ static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
 	crypto_blkcipher_setkey(tkey->rx_tfm_arc4, rc4key, 16);
 	sg_init_one(&sg, pos, plen + 4);
 	if (crypto_blkcipher_decrypt(&desc, &sg, &sg, plen + 4)) {
-		if (net_ratelimit()) {
-			printk(KERN_DEBUG ": TKIP: failed to decrypt "
-			       "received packet from %pM\n",
+		net_dbg_ratelimited(": TKIP: failed to decrypt received packet from %pM\n",
 			       hdr->addr2);
-		}
 		return -7;
 	}
 
@@ -446,10 +436,7 @@ static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
 			 * it needs to be recalculated for the next packet. */
 			tkey->rx_phase1_done = 0;
 		}
-		if (net_ratelimit()) {
-			printk(KERN_DEBUG "TKIP: ICV error detected: STA="
-			       "%pM\n", hdr->addr2);
-		}
+		net_dbg_ratelimited("TKIP: ICV error detected: STA=%pM\n", hdr->addr2);
 		tkey->dot11RSNAStatsTKIPICVErrors++;
 		return -5;
 	}
diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_rx.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_rx.c
index 10b2210..fa125f2 100644
--- a/drivers/staging/rtl8187se/ieee80211/ieee80211_rx.c
+++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_rx.c
@@ -307,11 +307,9 @@ ieee80211_rx_frame_decrypt(struct ieee80211_device *ieee, struct sk_buff *skb,
 #ifdef CONFIG_IEEE80211_CRYPT_TKIP
 	if (ieee->tkip_countermeasures &&
 	    strcmp(crypt->ops->name, "TKIP") == 0) {
-		if (net_ratelimit()) {
-			netdev_dbg(ieee->dev,
+		net_ratelimited_function(netdev_dbg, ieee->dev,
 				   "TKIP countermeasures: dropped received packet from %pM\n",
 				   ieee->dev->name, hdr->addr2);
-		}
 		return -1;
 	}
 #endif
diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_tx.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_tx.c
index b346653..366b1df3 100644
--- a/drivers/staging/rtl8187se/ieee80211/ieee80211_tx.c
+++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_tx.c
@@ -196,11 +196,8 @@ int ieee80211_encrypt_fragment(
 	if (ieee->tkip_countermeasures &&
 	    crypt && crypt->ops && strcmp(crypt->ops->name, "TKIP") == 0) {
 		header = (struct ieee80211_hdr_4addr *)frag->data;
-		if (net_ratelimit()) {
-			printk(KERN_DEBUG "%s: TKIP countermeasures: dropped "
-			       "TX packet to %pM\n",
-			       ieee->dev->name, header->addr1);
-		}
+		net_dbg_ratelimited("%s: TKIP countermeasures: dropped "
+			"TX packet to %pM\n", ieee->dev->name, header->addr1);
 		return -1;
 	}
 #endif
-- 
1.8.2.1



^ permalink raw reply related

* [PATCH 17/18] net: vxlan: use wrapper functions of net_ratelimit() to simplify code
From: Kefeng Wang @ 2013-10-15 11:45 UTC (permalink / raw)
  To: linux-kernel
  Cc: Greg Kroah-Hartman, David S. Miller, Pablo Neira Ayuso,
	Stephen Hemminger, Johannes Berg, John W. Linville,
	Stanislaw Gruszka, Johannes Berg, Francois Romieu, Ben Hutchings,
	Chas Williams, Marc Kleine-Budde, Samuel Ortiz, Paul Mackerras,
	Oliver Neukum, Konrad Rzeszutek Wilk, Boris Ostrovsky,
	David Vrabel, Rusty Russell, Michael S. Tsirkin, netfilter,
	netdev, linux-wireless, guohanjun
In-Reply-To: <1381837514-50660-1-git-send-email-wangkefeng.wang@huawei.com>

net_ratelimited_function() is called to simplify code.

Signed-off-by: Kefeng Wang <wangkefeng.wang@huawei.com>
---
 drivers/net/vxlan.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c
index 2ef5b62..56583ab 100644
--- a/drivers/net/vxlan.c
+++ b/drivers/net/vxlan.c
@@ -893,8 +893,7 @@ static bool vxlan_snoop(struct net_device *dev,
 		if (f->state & NUD_NOARP)
 			return true;
 
-		if (net_ratelimit())
-			netdev_info(dev,
+		net_ratelimited_function(netdev_info, dev,
 				    "%pM migrated from %pIS to %pIS\n",
 				    src_mac, &rdst->remote_ip, &src_ip);
 
-- 
1.8.2.1



^ 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