linux-wireless.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/7] brcm80211: cleanup fixes and out-of-order fix
@ 2013-11-06 22:07 Arend van Spriel
  2013-11-06 22:07 ` [PATCH 1/7] brcmfmac: Update fwsignal to fix out of order tx Arend van Spriel
                   ` (7 more replies)
  0 siblings, 8 replies; 13+ messages in thread
From: Arend van Spriel @ 2013-11-06 22:07 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless, Arend van Spriel

This series contains a couple of small cleanup fixes and one fix
from Hante to get rid of out-of-order transmit seen doing UDP iperf.

This series is intended for 3.13 if the merge window has not yet
opened. It applies to the master branch of the wireless-next
repository.

Arend van Spriel (5):
  brcmfmac: add separate function for passing bus tx overhead
  brcmfmac: replace dongle command list with .preinit() callback
  brcmfmac: start netif queues only when setup is completed successful
  brcmfmac: reduce logging noise accessing SDIO SleepCSR register
  brcmsmac: select CONFIG_BCMA when possible

Franky Lin (1):
  brcmfmac: remove empty brcmf_proto_stop

Hante Meuleman (1):
  brcmfmac: Update fwsignal to fix out of order tx.

 drivers/net/wireless/brcm80211/Kconfig             |   3 +-
 .../net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c |  19 ++-
 drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h  |  15 +-
 drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c  |   5 -
 .../net/wireless/brcm80211/brcmfmac/dhd_common.c   |  15 +-
 .../net/wireless/brcm80211/brcmfmac/dhd_linux.c    |  36 +++--
 .../net/wireless/brcm80211/brcmfmac/dhd_proto.h    |   3 -
 drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c |  60 ++++----
 drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c | 167 ++++++++++++++++++---
 drivers/net/wireless/brcm80211/brcmfmac/usb.c      |   4 +-
 10 files changed, 236 insertions(+), 91 deletions(-)

-- 
1.8.1.3



^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH 1/7] brcmfmac: Update fwsignal to fix out of order tx.
  2013-11-06 22:07 [PATCH 0/7] brcm80211: cleanup fixes and out-of-order fix Arend van Spriel
@ 2013-11-06 22:07 ` Arend van Spriel
  2013-11-06 22:07 ` [PATCH 2/7] brcmfmac: add separate function for passing bus tx overhead Arend van Spriel
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 13+ messages in thread
From: Arend van Spriel @ 2013-11-06 22:07 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless, Hante Meuleman, Arend van Spriel

From: Hante Meuleman <meuleman@broadcom.com>

When using fwsignal it is possible that tx packets get delivered out
of order. This patch fixes that by reordering suppressed packets and
tracking generation bit and sequence number per packet.

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

diff --git a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
index d0cd0bf..784cf94 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
@@ -105,6 +105,9 @@ static struct {
 };
 #undef BRCMF_FWS_TLV_DEF
 
+#define BRCMF_FWS_TYPE_SEQ_LEN				2
+
+
 static const char *brcmf_fws_get_tlv_name(enum brcmf_fws_tlv_type id)
 {
 	int i;
@@ -147,8 +150,15 @@ static const char *brcmf_fws_get_tlv_name(enum brcmf_fws_tlv_type id)
 #define BRCMF_FWS_HTOD_FLAG_PKTFROMHOST			0x01
 #define BRCMF_FWS_HTOD_FLAG_PKT_REQUESTED		0x02
 
-#define BRCMF_FWS_RET_OK_NOSCHEDULE	0
-#define BRCMF_FWS_RET_OK_SCHEDULE	1
+#define BRCMF_FWS_RET_OK_NOSCHEDULE			0
+#define BRCMF_FWS_RET_OK_SCHEDULE			1
+
+#define BRCMF_FWS_MODE_REUSESEQ_SHIFT			3	/* seq reuse */
+#define BRCMF_FWS_MODE_SET_REUSESEQ(x, val)	((x) = \
+		((x) & ~(1 << BRCMF_FWS_MODE_REUSESEQ_SHIFT)) | \
+		(((val) & 1) << BRCMF_FWS_MODE_REUSESEQ_SHIFT))
+#define BRCMF_FWS_MODE_GET_REUSESEQ(x)	\
+		(((x) >> BRCMF_FWS_MODE_REUSESEQ_SHIFT) & 1)
 
 /**
  * enum brcmf_fws_skb_state - indicates processing state of skb.
@@ -171,6 +181,7 @@ enum brcmf_fws_skb_state {
  * @bus_flags: 2 bytes reserved for bus specific parameters
  * @if_flags: holds interface index and packet related flags.
  * @htod: host to device packet identifier (used in PKTTAG tlv).
+ * @htod_seq: this 16-bit is original seq number for every suppress packet.
  * @state: transmit state of the packet.
  * @mac: descriptor related to destination for this packet.
  *
@@ -181,6 +192,7 @@ struct brcmf_skbuff_cb {
 	u16 bus_flags;
 	u16 if_flags;
 	u32 htod;
+	u16 htod_seq;
 	enum brcmf_fws_skb_state state;
 	struct brcmf_fws_mac_descriptor *mac;
 };
@@ -257,6 +269,22 @@ struct brcmf_skbuff_cb {
 			BRCMF_SKB_HTOD_TAG_ ## field ## _MASK, \
 			BRCMF_SKB_HTOD_TAG_ ## field ## _SHIFT)
 
+#define BRCMF_SKB_HTOD_SEQ_FROMFW_MASK			0x2000
+#define BRCMF_SKB_HTOD_SEQ_FROMFW_SHIFT			13
+#define BRCMF_SKB_HTOD_SEQ_FROMDRV_MASK			0x1000
+#define BRCMF_SKB_HTOD_SEQ_FROMDRV_SHIFT		12
+#define BRCMF_SKB_HTOD_SEQ_NR_MASK			0x0fff
+#define BRCMF_SKB_HTOD_SEQ_NR_SHIFT			0
+
+#define brcmf_skb_htod_seq_set_field(skb, field, value) \
+	brcmu_maskset16(&(brcmf_skbcb(skb)->htod_seq), \
+			BRCMF_SKB_HTOD_SEQ_ ## field ## _MASK, \
+			BRCMF_SKB_HTOD_SEQ_ ## field ## _SHIFT, (value))
+#define brcmf_skb_htod_seq_get_field(skb, field) \
+	brcmu_maskget16(brcmf_skbcb(skb)->htod_seq, \
+			BRCMF_SKB_HTOD_SEQ_ ## field ## _MASK, \
+			BRCMF_SKB_HTOD_SEQ_ ## field ## _SHIFT)
+
 #define BRCMF_FWS_TXSTAT_GENERATION_MASK	0x80000000
 #define BRCMF_FWS_TXSTAT_GENERATION_SHIFT	31
 #define BRCMF_FWS_TXSTAT_FLAGS_MASK		0x78000000
@@ -265,8 +293,8 @@ struct brcmf_skbuff_cb {
 #define BRCMF_FWS_TXSTAT_FIFO_SHIFT		24
 #define BRCMF_FWS_TXSTAT_HSLOT_MASK		0x00FFFF00
 #define BRCMF_FWS_TXSTAT_HSLOT_SHIFT		8
-#define BRCMF_FWS_TXSTAT_PKTID_MASK		0x00FFFFFF
-#define BRCMF_FWS_TXSTAT_PKTID_SHIFT		0
+#define BRCMF_FWS_TXSTAT_FREERUN_MASK		0x000000FF
+#define BRCMF_FWS_TXSTAT_FREERUN_SHIFT		0
 
 #define brcmf_txstatus_get_field(txs, field) \
 	brcmu_maskget32(txs, BRCMF_FWS_TXSTAT_ ## field ## _MASK, \
@@ -443,6 +471,7 @@ struct brcmf_fws_info {
 	unsigned long borrow_defer_timestamp;
 	bool bus_flow_blocked;
 	bool creditmap_received;
+	u8 mode;
 };
 
 /*
@@ -812,13 +841,16 @@ static int brcmf_fws_hdrpush(struct brcmf_fws_info *fws, struct sk_buff *skb)
 	u16 data_offset = 0;
 	u8 fillers;
 	__le32 pkttag = cpu_to_le32(brcmf_skbcb(skb)->htod);
+	__le16 pktseq = cpu_to_le16(brcmf_skbcb(skb)->htod_seq);
 
-	brcmf_dbg(TRACE, "enter: %s, idx=%d pkttag=0x%08X, hslot=%d\n",
+	brcmf_dbg(TRACE, "enter: %s, idx=%d hslot=%d htod %X seq %X\n",
 		  entry->name, brcmf_skb_if_flags_get_field(skb, INDEX),
-		  le32_to_cpu(pkttag), (le32_to_cpu(pkttag) >> 8) & 0xffff);
+		  (le32_to_cpu(pkttag) >> 8) & 0xffff,
+		  brcmf_skbcb(skb)->htod, brcmf_skbcb(skb)->htod_seq);
 	if (entry->send_tim_signal)
 		data_offset += 2 + BRCMF_FWS_TYPE_PENDING_TRAFFIC_BMP_LEN;
-
+	if (BRCMF_FWS_MODE_GET_REUSESEQ(fws->mode))
+		data_offset += BRCMF_FWS_TYPE_SEQ_LEN;
 	/* +2 is for Type[1] and Len[1] in TLV, plus TIM signal */
 	data_offset += 2 + BRCMF_FWS_TYPE_PKTTAG_LEN;
 	fillers = round_up(data_offset, 4) - data_offset;
@@ -830,7 +862,12 @@ static int brcmf_fws_hdrpush(struct brcmf_fws_info *fws, struct sk_buff *skb)
 	wlh[0] = BRCMF_FWS_TYPE_PKTTAG;
 	wlh[1] = BRCMF_FWS_TYPE_PKTTAG_LEN;
 	memcpy(&wlh[2], &pkttag, sizeof(pkttag));
-	wlh += BRCMF_FWS_TYPE_PKTTAG_LEN + 2;
+	if (BRCMF_FWS_MODE_GET_REUSESEQ(fws->mode)) {
+		wlh[1] += BRCMF_FWS_TYPE_SEQ_LEN;
+		memcpy(&wlh[2 + BRCMF_FWS_TYPE_PKTTAG_LEN], &pktseq,
+		       sizeof(pktseq));
+	}
+	wlh += wlh[1] + 2;
 
 	if (entry->send_tim_signal) {
 		entry->send_tim_signal = 0;
@@ -875,6 +912,7 @@ static bool brcmf_fws_tim_update(struct brcmf_fws_info *fws,
 		/* create a dummy packet and sent that. The traffic          */
 		/* bitmap info will automatically be attached to that packet */
 		len = BRCMF_FWS_TYPE_PKTTAG_LEN + 2 +
+		      BRCMF_FWS_TYPE_SEQ_LEN +
 		      BRCMF_FWS_TYPE_PENDING_TRAFFIC_BMP_LEN + 2 +
 		      4 + fws->drvr->hdrlen;
 		skb = brcmu_pkt_buf_get_skb(len);
@@ -884,6 +922,8 @@ static bool brcmf_fws_tim_update(struct brcmf_fws_info *fws,
 		skcb = brcmf_skbcb(skb);
 		skcb->mac = entry;
 		skcb->state = BRCMF_FWS_SKBSTATE_TIM;
+		skcb->htod = 0;
+		skcb->htod_seq = 0;
 		bus = fws->drvr->bus_if;
 		err = brcmf_fws_hdrpush(fws, skb);
 		if (err == 0) {
@@ -1172,8 +1212,13 @@ static int brcmf_fws_enq(struct brcmf_fws_info *fws,
 {
 	int prec = 2 * fifo;
 	u32 *qfull_stat = &fws->stats.delayq_full_error;
-
 	struct brcmf_fws_mac_descriptor *entry;
+	struct pktq *pq;
+	struct sk_buff_head *queue;
+	struct sk_buff *p_head;
+	struct sk_buff *p_tail;
+	u32 fr_new;
+	u32 fr_compare;
 
 	entry = brcmf_skbcb(p)->mac;
 	if (entry == NULL) {
@@ -1185,9 +1230,55 @@ static int brcmf_fws_enq(struct brcmf_fws_info *fws,
 	if (state == BRCMF_FWS_SKBSTATE_SUPPRESSED) {
 		prec += 1;
 		qfull_stat = &fws->stats.supprq_full_error;
-	}
 
-	if (brcmu_pktq_penq(&entry->psq, prec, p) == NULL) {
+		/* Fix out of order delivery of frames. Dont assume frame    */
+		/* can be inserted at the end, but look for correct position */
+		pq = &entry->psq;
+		if (pktq_full(pq) || pktq_pfull(pq, prec)) {
+			*qfull_stat += 1;
+			return -ENFILE;
+		}
+		queue = &pq->q[prec].skblist;
+
+		p_head = skb_peek(queue);
+		p_tail = skb_peek_tail(queue);
+		fr_new = brcmf_skb_htod_tag_get_field(p, FREERUN);
+
+		while (p_head != p_tail) {
+			fr_compare = brcmf_skb_htod_tag_get_field(p_tail,
+								  FREERUN);
+			/* be sure to handle wrap of 256 */
+			if (((fr_new > fr_compare) &&
+			     ((fr_new - fr_compare) < 128)) ||
+			    ((fr_new < fr_compare) &&
+			     ((fr_compare - fr_new) > 128)))
+				break;
+			p_tail = skb_queue_prev(queue, p_tail);
+		}
+		/* Position found. Determine what to do */
+		if (p_tail == NULL) {
+			/* empty list */
+			__skb_queue_tail(queue, p);
+		} else {
+			fr_compare = brcmf_skb_htod_tag_get_field(p_tail,
+								  FREERUN);
+			if (((fr_new > fr_compare) &&
+			     ((fr_new - fr_compare) < 128)) ||
+			    ((fr_new < fr_compare) &&
+			     ((fr_compare - fr_new) > 128))) {
+				/* After tail */
+				__skb_queue_after(queue, p_tail, p);
+			} else {
+				/* Before tail */
+				__skb_insert(p, p_tail->prev, p_tail, queue);
+			}
+		}
+
+		/* Complete the counters and statistics */
+		pq->len++;
+		if (pq->hi_prec < prec)
+			pq->hi_prec = (u8) prec;
+	} else if (brcmu_pktq_penq(&entry->psq, prec, p) == NULL) {
 		*qfull_stat += 1;
 		return -ENFILE;
 	}
@@ -1277,7 +1368,8 @@ done:
 }
 
 static int brcmf_fws_txstatus_suppressed(struct brcmf_fws_info *fws, int fifo,
-					 struct sk_buff *skb, u32 genbit)
+					 struct sk_buff *skb, u32 genbit,
+					 u16 seq)
 {
 	struct brcmf_fws_mac_descriptor *entry = brcmf_skbcb(skb)->mac;
 	u32 hslot;
@@ -1298,6 +1390,14 @@ static int brcmf_fws_txstatus_suppressed(struct brcmf_fws_info *fws, int fifo,
 
 	ret = brcmf_proto_hdrpull(fws->drvr, false, &ifidx, skb);
 	if (ret == 0)
+		brcmf_skb_htod_tag_set_field(skb, GENERATION, genbit);
+		brcmf_skbcb(skb)->htod_seq = seq;
+		if (brcmf_skb_htod_seq_get_field(skb, FROMFW)) {
+			brcmf_skb_htod_seq_set_field(skb, FROMDRV, 1);
+			brcmf_skb_htod_seq_set_field(skb, FROMFW, 0);
+		} else {
+			brcmf_skb_htod_seq_set_field(skb, FROMDRV, 0);
+		}
 		ret = brcmf_fws_enq(fws, BRCMF_FWS_SKBSTATE_SUPPRESSED, fifo,
 				    skb);
 	if (ret != 0) {
@@ -1317,7 +1417,7 @@ static int brcmf_fws_txstatus_suppressed(struct brcmf_fws_info *fws, int fifo,
 
 static int
 brcmf_fws_txs_process(struct brcmf_fws_info *fws, u8 flags, u32 hslot,
-			   u32 genbit)
+		      u32 genbit, u16 seq)
 {
 	u32 fifo;
 	int ret;
@@ -1360,8 +1460,8 @@ brcmf_fws_txs_process(struct brcmf_fws_info *fws, u8 flags, u32 hslot,
 	if (entry->suppressed && entry->suppr_transit_count)
 		entry->suppr_transit_count--;
 
-	brcmf_dbg(DATA, "%s flags %X htod %X\n", entry->name, skcb->if_flags,
-		  skcb->htod);
+	brcmf_dbg(DATA, "%s flags %d htod %X seq %X\n", entry->name, flags,
+		  skcb->htod, seq);
 
 	/* pick up the implicit credit from this packet */
 	fifo = brcmf_skb_htod_tag_get_field(skb, FIFO);
@@ -1374,7 +1474,8 @@ brcmf_fws_txs_process(struct brcmf_fws_info *fws, u8 flags, u32 hslot,
 	brcmf_fws_macdesc_return_req_credit(skb);
 
 	if (!remove_from_hanger)
-		ret = brcmf_fws_txstatus_suppressed(fws, fifo, skb, genbit);
+		ret = brcmf_fws_txstatus_suppressed(fws, fifo, skb, genbit,
+						    seq);
 
 	if (remove_from_hanger || ret)
 		brcmf_txfinalize(fws->drvr, skb, true);
@@ -1406,10 +1507,12 @@ static int brcmf_fws_fifocreditback_indicate(struct brcmf_fws_info *fws,
 static int brcmf_fws_txstatus_indicate(struct brcmf_fws_info *fws, u8 *data)
 {
 	__le32 status_le;
+	__le16 seq_le;
 	u32 status;
 	u32 hslot;
 	u32 genbit;
 	u8 flags;
+	u16 seq;
 
 	fws->stats.txs_indicate++;
 	memcpy(&status_le, data, sizeof(status_le));
@@ -1417,9 +1520,16 @@ static int brcmf_fws_txstatus_indicate(struct brcmf_fws_info *fws, u8 *data)
 	flags = brcmf_txstatus_get_field(status, FLAGS);
 	hslot = brcmf_txstatus_get_field(status, HSLOT);
 	genbit = brcmf_txstatus_get_field(status, GENERATION);
+	if (BRCMF_FWS_MODE_GET_REUSESEQ(fws->mode)) {
+		memcpy(&seq_le, &data[BRCMF_FWS_TYPE_PKTTAG_LEN],
+		       sizeof(seq_le));
+		seq = le16_to_cpu(seq_le);
+	} else {
+		seq = 0;
+	}
 
 	brcmf_fws_lock(fws);
-	brcmf_fws_txs_process(fws, flags, hslot, genbit);
+	brcmf_fws_txs_process(fws, flags, hslot, genbit, seq);
 	brcmf_fws_unlock(fws);
 	return BRCMF_FWS_RET_OK_NOSCHEDULE;
 }
@@ -1610,8 +1720,8 @@ static void brcmf_fws_precommit_skb(struct brcmf_fws_info *fws, int fifo,
 	struct brcmf_fws_mac_descriptor *entry = skcb->mac;
 	u8 flags;
 
-	brcmf_skb_if_flags_set_field(p, TRANSMIT, 1);
-	brcmf_skb_htod_tag_set_field(p, GENERATION, entry->generation);
+	if (skcb->state != BRCMF_FWS_SKBSTATE_SUPPRESSED)
+		brcmf_skb_htod_tag_set_field(p, GENERATION, entry->generation);
 	flags = BRCMF_FWS_HTOD_FLAG_PKTFROMHOST;
 	if (brcmf_skb_if_flags_get_field(p, REQUESTED)) {
 		/*
@@ -1652,7 +1762,7 @@ static void brcmf_fws_rollback_toq(struct brcmf_fws_info *fws,
 		fws->stats.rollback_failed++;
 		hslot = brcmf_skb_htod_tag_get_field(skb, HSLOT);
 		brcmf_fws_txs_process(fws, BRCMF_FWS_TXSTATUS_HOST_TOSSED,
-				      hslot, 0);
+				      hslot, 0, 0);
 	} else {
 		fws->stats.rollback_success++;
 		brcmf_fws_return_credits(fws, fifo, 1);
@@ -1732,6 +1842,8 @@ static int brcmf_fws_assign_htod(struct brcmf_fws_info *fws, struct sk_buff *p,
 	struct brcmf_skbuff_cb *skcb = brcmf_skbcb(p);
 	int rc, hslot;
 
+	skcb->htod = 0;
+	skcb->htod_seq = 0;
 	hslot = brcmf_fws_hanger_get_free_slot(&fws->hanger);
 	brcmf_skb_htod_tag_set_field(p, HSLOT, hslot);
 	brcmf_skb_htod_tag_set_field(p, FREERUN, skcb->mac->seq[fifo]);
@@ -1908,6 +2020,7 @@ int brcmf_fws_init(struct brcmf_pub *drvr)
 	struct brcmf_fws_info *fws;
 	u32 tlv = BRCMF_FWS_FLAGS_RSSI_SIGNALS;
 	int rc;
+	u32 mode;
 
 	drvr->fws = kzalloc(sizeof(*(drvr->fws)), GFP_KERNEL);
 	if (!drvr->fws) {
@@ -1966,6 +2079,18 @@ int brcmf_fws_init(struct brcmf_pub *drvr)
 	if (brcmf_fil_iovar_int_set(drvr->iflist[0], "ampdu_hostreorder", 1))
 		brcmf_dbg(INFO, "enabling AMPDU host-reorder failed\n");
 
+	/* Enable seq number reuse, if supported */
+	if (brcmf_fil_iovar_int_get(drvr->iflist[0], "wlfc_mode", &mode) == 0) {
+		if (BRCMF_FWS_MODE_GET_REUSESEQ(mode)) {
+			mode = 0;
+			BRCMF_FWS_MODE_SET_REUSESEQ(mode, 1);
+			if (brcmf_fil_iovar_int_set(drvr->iflist[0],
+						    "wlfc_mode", mode) == 0) {
+				BRCMF_FWS_MODE_SET_REUSESEQ(fws->mode, 1);
+			}
+		}
+	}
+
 	brcmf_fws_hanger_init(&fws->hanger);
 	brcmf_fws_macdesc_init(&fws->desc.other, NULL, 0);
 	brcmf_fws_macdesc_set_name(fws, &fws->desc.other);
@@ -2022,7 +2147,7 @@ void brcmf_fws_bustxfail(struct brcmf_fws_info *fws, struct sk_buff *skb)
 	}
 	brcmf_fws_lock(fws);
 	hslot = brcmf_skb_htod_tag_get_field(skb, HSLOT);
-	brcmf_fws_txs_process(fws, BRCMF_FWS_TXSTATUS_HOST_TOSSED, hslot, 0);
+	brcmf_fws_txs_process(fws, BRCMF_FWS_TXSTATUS_HOST_TOSSED, hslot, 0, 0);
 	brcmf_fws_unlock(fws);
 }
 
-- 
1.8.1.3



^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH 2/7] brcmfmac: add separate function for passing bus tx overhead
  2013-11-06 22:07 [PATCH 0/7] brcm80211: cleanup fixes and out-of-order fix Arend van Spriel
  2013-11-06 22:07 ` [PATCH 1/7] brcmfmac: Update fwsignal to fix out of order tx Arend van Spriel
@ 2013-11-06 22:07 ` Arend van Spriel
  2013-11-06 22:07 ` [PATCH 3/7] brcmfmac: replace dongle command list with .preinit() callback Arend van Spriel
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 13+ messages in thread
From: Arend van Spriel @ 2013-11-06 22:07 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless, Arend van Spriel

The common driver needs the packet overhead for the bus in order
to reserve headroom for sk_buffs. For the SDIO driver this depends
on firmware features so it is not possible to provide it in the
brcmf_attach() call.

Reviewed-by: Franky Lin <frankyl@broadcom.com>
Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
Signed-off-by: Arend van Spriel <arend@broadcom.com>
---
 drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h   |  3 ++-
 drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c | 14 ++++++++++++--
 drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c  |  4 +++-
 drivers/net/wireless/brcm80211/brcmfmac/usb.c       |  4 ++--
 4 files changed, 19 insertions(+), 6 deletions(-)

diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h
index 7640d8a..392fc28 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h
@@ -139,7 +139,7 @@ extern bool brcmf_c_prec_enq(struct device *dev, struct pktq *q,
 extern void brcmf_rx_frame(struct device *dev, struct sk_buff *rxp);
 
 /* Indication from bus module regarding presence/insertion of dongle. */
-extern int brcmf_attach(uint bus_hdrlen, struct device *dev);
+extern int brcmf_attach(struct device *dev);
 /* Indication from bus module regarding removal/absence of dongle */
 extern void brcmf_detach(struct device *dev);
 /* Indication from bus module that dongle should be reset */
@@ -152,6 +152,7 @@ extern void brcmf_txcomplete(struct device *dev, struct sk_buff *txp,
 			     bool success);
 
 extern int brcmf_bus_start(struct device *dev);
+extern void brcmf_bus_add_txhdrlen(struct device *dev, uint len);
 
 #ifdef CONFIG_BRCMFMAC_SDIO
 extern void brcmf_sdio_exit(void);
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
index 64e9cff..0c4c230 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
@@ -1016,7 +1016,7 @@ void brcmf_del_if(struct brcmf_pub *drvr, s32 bssidx)
 	}
 }
 
-int brcmf_attach(uint bus_hdrlen, struct device *dev)
+int brcmf_attach(struct device *dev)
 {
 	struct brcmf_pub *drvr = NULL;
 	int ret = 0;
@@ -1031,7 +1031,7 @@ int brcmf_attach(uint bus_hdrlen, struct device *dev)
 	mutex_init(&drvr->proto_block);
 
 	/* Link to bus module */
-	drvr->hdrlen = bus_hdrlen;
+	drvr->hdrlen = 0;
 	drvr->bus_if = dev_get_drvdata(dev);
 	drvr->bus_if->drvr = drvr;
 
@@ -1138,6 +1138,16 @@ fail:
 	return 0;
 }
 
+void brcmf_bus_add_txhdrlen(struct device *dev, uint len)
+{
+	struct brcmf_bus *bus_if = dev_get_drvdata(dev);
+	struct brcmf_pub *drvr = bus_if->drvr;
+
+	if (drvr) {
+		drvr->hdrlen += len;
+	}
+}
+
 static void brcmf_bus_detach(struct brcmf_pub *drvr)
 {
 	brcmf_dbg(TRACE, "Enter\n");
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
index b02953c..928983b 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
@@ -3983,7 +3983,7 @@ void *brcmf_sdbrcm_probe(u32 regsva, struct brcmf_sdio_dev *sdiodev)
 	bus->tx_hdrlen = SDPCM_HWHDR_LEN + SDPCM_SWHDR_LEN;
 
 	/* Attach to the common layer, reserve hdr space */
-	ret = brcmf_attach(bus->tx_hdrlen, bus->sdiodev->dev);
+	ret = brcmf_attach(bus->sdiodev->dev);
 	if (ret != 0) {
 		brcmf_err("brcmf_attach failed\n");
 		goto fail;
@@ -4027,6 +4027,8 @@ void *brcmf_sdbrcm_probe(u32 regsva, struct brcmf_sdio_dev *sdiodev)
 		list_add(&dlst->list, &bus->sdiodev->bus_if->dcmd_list);
 	}
 
+	brcmf_bus_add_txhdrlen(bus->sdiodev->dev, bus->tx_hdrlen);
+
 	/* if firmware path present try to download and bring up bus */
 	ret = brcmf_bus_start(bus->sdiodev->dev);
 	if (ret != 0) {
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/usb.c b/drivers/net/wireless/brcm80211/brcmfmac/usb.c
index 422f44c..51c4de0 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/usb.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/usb.c
@@ -1255,7 +1255,7 @@ static int brcmf_usb_probe_cb(struct brcmf_usbdev_info *devinfo)
 	bus->chiprev = bus_pub->chiprev;
 
 	/* Attach to the common driver interface */
-	ret = brcmf_attach(0, dev);
+	ret = brcmf_attach(dev);
 	if (ret) {
 		brcmf_err("brcmf_attach failed\n");
 		goto fail;
@@ -1454,7 +1454,7 @@ static int brcmf_usb_resume(struct usb_interface *intf)
 	struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(&usb->dev);
 
 	brcmf_dbg(USB, "Enter\n");
-	if (!brcmf_attach(0, devinfo->dev))
+	if (!brcmf_attach(devinfo->dev))
 		return brcmf_bus_start(&usb->dev);
 
 	return 0;
-- 
1.8.1.3



^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH 3/7] brcmfmac: replace dongle command list with .preinit() callback
  2013-11-06 22:07 [PATCH 0/7] brcm80211: cleanup fixes and out-of-order fix Arend van Spriel
  2013-11-06 22:07 ` [PATCH 1/7] brcmfmac: Update fwsignal to fix out of order tx Arend van Spriel
  2013-11-06 22:07 ` [PATCH 2/7] brcmfmac: add separate function for passing bus tx overhead Arend van Spriel
@ 2013-11-06 22:07 ` Arend van Spriel
  2013-11-06 22:07 ` [PATCH 4/7] brcmfmac: start netif queues only when setup is completed successful Arend van Spriel
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 13+ messages in thread
From: Arend van Spriel @ 2013-11-06 22:07 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless, Arend van Spriel

The bus-specific interface allowed a list of dongle commands to be
provided to the common driver part. However, upcoming functionality
requires a more dynamic behaviour. Hence the list is replaced
by a new callback function so the bus-specific driver part can
implement this behaviour.

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_bus.h  | 12 ++++-
 .../net/wireless/brcm80211/brcmfmac/dhd_common.c   | 15 +-----
 .../net/wireless/brcm80211/brcmfmac/dhd_linux.c    | 10 +++-
 drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c | 58 +++++++++++-----------
 4 files changed, 51 insertions(+), 44 deletions(-)

diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h
index 392fc28..dfa9bdd 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h
@@ -34,6 +34,7 @@ struct brcmf_bus_dcmd {
 /**
  * struct brcmf_bus_ops - bus callback operations.
  *
+ * @preinit: execute bus/device specific dongle init commands (optional).
  * @init: prepare for communication with dongle.
  * @stop: clear pending frames, disable data flow.
  * @txdata: send a data frame to the dongle. When the data
@@ -51,6 +52,7 @@ struct brcmf_bus_dcmd {
  * indicated otherwise these callbacks are mandatory.
  */
 struct brcmf_bus_ops {
+	int (*preinit)(struct device *dev);
 	int (*init)(struct device *dev);
 	void (*stop)(struct device *dev);
 	int (*txdata)(struct device *dev, struct sk_buff *skb);
@@ -85,7 +87,6 @@ struct brcmf_bus {
 	unsigned long tx_realloc;
 	u32 chip;
 	u32 chiprev;
-	struct list_head dcmd_list;
 
 	struct brcmf_bus_ops *ops;
 };
@@ -93,6 +94,13 @@ struct brcmf_bus {
 /*
  * callback wrappers
  */
+static inline int brcmf_bus_preinit(struct brcmf_bus *bus)
+{
+	if (!bus->ops->preinit)
+		return 0;
+	return bus->ops->preinit(bus->dev);
+}
+
 static inline int brcmf_bus_init(struct brcmf_bus *bus)
 {
 	return bus->ops->init(bus->dev);
@@ -152,6 +160,8 @@ extern void brcmf_txcomplete(struct device *dev, struct sk_buff *txp,
 			     bool success);
 
 extern int brcmf_bus_start(struct device *dev);
+extern s32 brcmf_iovar_data_set(struct device *dev, char *name, void *data,
+				u32 len);
 extern void brcmf_bus_add_txhdrlen(struct device *dev, uint len);
 
 #ifdef CONFIG_BRCMFMAC_SDIO
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c
index 9431af2..5c0c919 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c
@@ -257,8 +257,6 @@ int brcmf_c_preinit_dcmds(struct brcmf_if *ifp)
 	u8 buf[BRCMF_DCMD_SMLEN];
 	char *ptr;
 	s32 err;
-	struct brcmf_bus_dcmd *cmdlst;
-	struct list_head *cur, *q;
 
 	/* retreive mac address */
 	err = brcmf_fil_iovar_data_get(ifp, "cur_etheraddr", ifp->mac_addr,
@@ -342,17 +340,8 @@ int brcmf_c_preinit_dcmds(struct brcmf_if *ifp)
 	brcmf_c_pktfilter_offload_enable(ifp, BRCMF_DEFAULT_PACKET_FILTER,
 					 0, true);
 
-	/* set bus specific command if there is any */
-	list_for_each_safe(cur, q, &ifp->drvr->bus_if->dcmd_list) {
-		cmdlst = list_entry(cur, struct brcmf_bus_dcmd, list);
-		if (cmdlst->name && cmdlst->param && cmdlst->param_len) {
-			brcmf_fil_iovar_data_set(ifp, cmdlst->name,
-						 cmdlst->param,
-						 cmdlst->param_len);
-		}
-		list_del(cur);
-		kfree(cmdlst);
-	}
+	/* do bus specific preinit here */
+	err = brcmf_bus_preinit(ifp->drvr->bus_if);
 done:
 	return err;
 }
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
index 0c4c230..ab207e2 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
@@ -1048,8 +1048,6 @@ int brcmf_attach(struct device *dev)
 	/* attach firmware event handler */
 	brcmf_fweh_attach(drvr);
 
-	INIT_LIST_HEAD(&drvr->bus_if->dcmd_list);
-
 	return ret;
 
 fail:
@@ -1206,6 +1204,14 @@ void brcmf_detach(struct device *dev)
 	kfree(drvr);
 }
 
+s32 brcmf_iovar_data_set(struct device *dev, char *name, void *data, u32 len)
+{
+	struct brcmf_bus *bus_if = dev_get_drvdata(dev);
+	struct brcmf_if *ifp = bus_if->drvr->iflist[0];
+
+	return brcmf_fil_iovar_data_set(ifp, name, data, len);
+}
+
 static int brcmf_get_pend_8021x_cnt(struct brcmf_if *ifp)
 {
 	return atomic_read(&ifp->pend_8021x_cnt);
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
index 928983b..2597a53 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
@@ -3425,6 +3425,35 @@ brcmf_sdbrcm_download_firmware(struct brcmf_sdio *bus)
 	return ret;
 }
 
+static int brcmf_sdbrcm_bus_preinit(struct device *dev)
+{
+	struct brcmf_bus *bus_if = dev_get_drvdata(dev);
+	struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
+	struct brcmf_sdio *bus = sdiodev->bus;
+	u32 value;
+	u8 idx;
+	int err;
+
+	/* sdio bus core specific dcmd */
+	idx = brcmf_sdio_chip_getinfidx(bus->ci, BCMA_CORE_SDIO_DEV);
+	if (bus->ci->c_inf[idx].rev < 12) {
+		/* for sdio core rev < 12, disable txgloming */
+		value = 0;
+		err = brcmf_iovar_data_set(dev, "bus:txglom", &value,
+					   sizeof(u32));
+	} else {
+		/* otherwise, set txglomalign */
+		value = 4;
+		if (sdiodev->pdata)
+			value = sdiodev->pdata->sd_sgentry_align;
+		/* SDIO ADMA requires at least 32 bit alignment */
+		value = max_t(u32, value, 4);
+		err = brcmf_iovar_data_set(dev, "bus:txglomalign", &value,
+					   sizeof(u32));
+	}
+	return err;
+}
+
 static int brcmf_sdbrcm_bus_init(struct device *dev)
 {
 	struct brcmf_bus *bus_if = dev_get_drvdata(dev);
@@ -3905,6 +3934,7 @@ static void brcmf_sdbrcm_release(struct brcmf_sdio *bus)
 
 static struct brcmf_bus_ops brcmf_sdio_bus_ops = {
 	.stop = brcmf_sdbrcm_bus_stop,
+	.preinit = brcmf_sdbrcm_bus_preinit,
 	.init = brcmf_sdbrcm_bus_init,
 	.txdata = brcmf_sdbrcm_bus_txdata,
 	.txctl = brcmf_sdbrcm_bus_txctl,
@@ -3916,10 +3946,6 @@ void *brcmf_sdbrcm_probe(u32 regsva, struct brcmf_sdio_dev *sdiodev)
 {
 	int ret;
 	struct brcmf_sdio *bus;
-	struct brcmf_bus_dcmd *dlst;
-	u32 dngl_txglom;
-	u32 txglomalign = 0;
-	u8 idx;
 
 	brcmf_dbg(TRACE, "Enter\n");
 
@@ -4003,30 +4029,6 @@ void *brcmf_sdbrcm_probe(u32 regsva, struct brcmf_sdio_dev *sdiodev)
 	brcmf_sdio_debugfs_create(bus);
 	brcmf_dbg(INFO, "completed!!\n");
 
-	/* sdio bus core specific dcmd */
-	idx = brcmf_sdio_chip_getinfidx(bus->ci, BCMA_CORE_SDIO_DEV);
-	dlst = kzalloc(sizeof(struct brcmf_bus_dcmd), GFP_KERNEL);
-	if (dlst) {
-		if (bus->ci->c_inf[idx].rev < 12) {
-			/* for sdio core rev < 12, disable txgloming */
-			dngl_txglom = 0;
-			dlst->name = "bus:txglom";
-			dlst->param = (char *)&dngl_txglom;
-			dlst->param_len = sizeof(u32);
-		} else {
-			/* otherwise, set txglomalign */
-			if (sdiodev->pdata)
-				txglomalign = sdiodev->pdata->sd_sgentry_align;
-			/* SDIO ADMA requires at least 32 bit alignment */
-			if (txglomalign < 4)
-				txglomalign = 4;
-			dlst->name = "bus:txglomalign";
-			dlst->param = (char *)&txglomalign;
-			dlst->param_len = sizeof(u32);
-		}
-		list_add(&dlst->list, &bus->sdiodev->bus_if->dcmd_list);
-	}
-
 	brcmf_bus_add_txhdrlen(bus->sdiodev->dev, bus->tx_hdrlen);
 
 	/* if firmware path present try to download and bring up bus */
-- 
1.8.1.3



^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH 4/7] brcmfmac: start netif queues only when setup is completed successful
  2013-11-06 22:07 [PATCH 0/7] brcm80211: cleanup fixes and out-of-order fix Arend van Spriel
                   ` (2 preceding siblings ...)
  2013-11-06 22:07 ` [PATCH 3/7] brcmfmac: replace dongle command list with .preinit() callback Arend van Spriel
@ 2013-11-06 22:07 ` Arend van Spriel
  2013-11-06 22:07 ` [PATCH 5/7] brcmfmac: remove empty brcmf_proto_stop Arend van Spriel
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 13+ messages in thread
From: Arend van Spriel @ 2013-11-06 22:07 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless, Arend van Spriel

Moving the call to netif_start_queue() after brcmf_cfg80211_up() is
completed successful. If not return -EIO instead of -1 as that results
in 'Operation not permitted' which can put user on wrong track.

Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
Signed-off-by: Arend van Spriel <arend@broadcom.com>
---
 drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c | 9 ++++-----
 1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
index ab207e2..f4eeaa1 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
@@ -769,7 +769,6 @@ static int brcmf_netdev_open(struct net_device *ndev)
 	struct brcmf_pub *drvr = ifp->drvr;
 	struct brcmf_bus *bus_if = drvr->bus_if;
 	u32 toe_ol;
-	s32 ret = 0;
 
 	brcmf_dbg(TRACE, "Enter, idx=%d\n", ifp->bssidx);
 
@@ -788,14 +787,14 @@ static int brcmf_netdev_open(struct net_device *ndev)
 	else
 		ndev->features &= ~NETIF_F_IP_CSUM;
 
-	/* Allow transmit calls */
-	netif_start_queue(ndev);
 	if (brcmf_cfg80211_up(ndev)) {
 		brcmf_err("failed to bring up cfg80211\n");
-		return -1;
+		return -EIO;
 	}
 
-	return ret;
+	/* Allow transmit calls */
+	netif_start_queue(ndev);
+	return 0;
 }
 
 static const struct net_device_ops brcmf_netdev_ops_pri = {
-- 
1.8.1.3



^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH 5/7] brcmfmac: remove empty brcmf_proto_stop
  2013-11-06 22:07 [PATCH 0/7] brcm80211: cleanup fixes and out-of-order fix Arend van Spriel
                   ` (3 preceding siblings ...)
  2013-11-06 22:07 ` [PATCH 4/7] brcmfmac: start netif queues only when setup is completed successful Arend van Spriel
@ 2013-11-06 22:07 ` Arend van Spriel
  2013-11-06 22:07 ` [PATCH 6/7] brcmfmac: reduce logging noise accessing SDIO SleepCSR register Arend van Spriel
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 13+ messages in thread
From: Arend van Spriel @ 2013-11-06 22:07 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless, Franky Lin, Arend van Spriel

From: Franky Lin <frankyl@broadcom.com>

remove empty brcmf_proto_stop from protocol layer

Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
Reviewed-by: Arend Van Spriel <arend@broadcom.com>
Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
Signed-off-by: Franky Lin <frankyl@broadcom.com>
Signed-off-by: Arend van Spriel <arend@broadcom.com>
---
 drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c   | 5 -----
 drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c | 3 ---
 drivers/net/wireless/brcm80211/brcmfmac/dhd_proto.h | 3 ---
 3 files changed, 11 deletions(-)

diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c
index dd85401..42aaf10 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c
@@ -385,8 +385,3 @@ void brcmf_proto_detach(struct brcmf_pub *drvr)
 	kfree(drvr->prot);
 	drvr->prot = NULL;
 }
-
-void brcmf_proto_stop(struct brcmf_pub *drvr)
-{
-	/* Nothing to do for CDC */
-}
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
index f4eeaa1..c34ca70 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
@@ -1150,9 +1150,6 @@ static void brcmf_bus_detach(struct brcmf_pub *drvr)
 	brcmf_dbg(TRACE, "Enter\n");
 
 	if (drvr) {
-		/* Stop the protocol module */
-		brcmf_proto_stop(drvr);
-
 		/* Stop the bus module */
 		brcmf_bus_stop(drvr->bus_if);
 	}
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_proto.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd_proto.h
index ef91798..0780fb7 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_proto.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_proto.h
@@ -27,9 +27,6 @@ extern int brcmf_proto_attach(struct brcmf_pub *drvr);
 /* Unlink, frees allocated protocol memory (including brcmf_proto) */
 extern void brcmf_proto_detach(struct brcmf_pub *drvr);
 
-/* Stop protocol: sync w/dongle state. */
-extern void brcmf_proto_stop(struct brcmf_pub *drvr);
-
 /* Add any protocol-specific data header.
  * Caller must reserve prot_hdrlen prepend space.
  */
-- 
1.8.1.3



^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH 6/7] brcmfmac: reduce logging noise accessing SDIO SleepCSR register
  2013-11-06 22:07 [PATCH 0/7] brcm80211: cleanup fixes and out-of-order fix Arend van Spriel
                   ` (4 preceding siblings ...)
  2013-11-06 22:07 ` [PATCH 5/7] brcmfmac: remove empty brcmf_proto_stop Arend van Spriel
@ 2013-11-06 22:07 ` Arend van Spriel
  2013-11-06 23:53   ` Joe Perches
  2013-11-06 22:07 ` [PATCH 7/7] brcmsmac: select CONFIG_BCMA when possible Arend van Spriel
  2013-11-20  9:36 ` [PATCH 0/7] brcm80211: cleanup fixes and out-of-order fix Arend van Spriel
  7 siblings, 1 reply; 13+ messages in thread
From: Arend van Spriel @ 2013-11-06 22:07 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless, Arend van Spriel

The SleepCSR register is accessed to wakeup the device from the
host side. Depending on the state of the device this may take
multiple attempts. The failed attempt are not real failures so
reduce the log level specifically for this register. The calling
function will scream when the multiple attempts all failed.

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

diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c
index 905704e..009d2a0 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c
@@ -156,10 +156,21 @@ int brcmf_sdioh_request_byte(struct brcmf_sdio_dev *sdiodev, uint rw, uint func,
 		}
 	}
 
-	if (err_ret)
-		brcmf_err("Failed to %s byte F%d:@0x%05x=%02x, Err: %d\n",
-			  rw ? "write" : "read", func, regaddr, *byte, err_ret);
-
+	if (err_ret) {
+		/*
+		 * SleepCSR register access can fail when
+		 * waking up the device so reduce this noise
+		 * in the logs.
+		 */
+		if (regaddr != SBSDIO_FUNC1_SLEEPCSR)
+			brcmf_err("Failed to %s byte F%d:@0x%05x=%02x, Err: %d\n",
+				  rw ? "write" : "read", func, regaddr, *byte,
+				  err_ret);
+		else
+			brcmf_dbg(SDIO, "Failed to %s byte F%d:@0x%05x=%02x, Err: %d\n",
+				  rw ? "write" : "read", func, regaddr, *byte,
+				  err_ret);
+	}
 	return err_ret;
 }
 
-- 
1.8.1.3



^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH 7/7] brcmsmac: select CONFIG_BCMA when possible
  2013-11-06 22:07 [PATCH 0/7] brcm80211: cleanup fixes and out-of-order fix Arend van Spriel
                   ` (5 preceding siblings ...)
  2013-11-06 22:07 ` [PATCH 6/7] brcmfmac: reduce logging noise accessing SDIO SleepCSR register Arend van Spriel
@ 2013-11-06 22:07 ` Arend van Spriel
  2013-11-20  9:36 ` [PATCH 0/7] brcm80211: cleanup fixes and out-of-order fix Arend van Spriel
  7 siblings, 0 replies; 13+ messages in thread
From: Arend van Spriel @ 2013-11-06 22:07 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless, Arend van Spriel

The brcmsmac relies BCMA functionality to access the device. This
patch selects CONFIG_BCMA when CONFIG_BCMA_POSSIBLE is set. This
way the user does not need to be select BCMA to make the brcmsmac
driver show up in his menuconfig.

Reported-by: Dan Carpenter <dan.carpenter@oracle.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/Kconfig | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/brcm80211/Kconfig b/drivers/net/wireless/brcm80211/Kconfig
index b00a7e9..d9d85e9 100644
--- a/drivers/net/wireless/brcm80211/Kconfig
+++ b/drivers/net/wireless/brcm80211/Kconfig
@@ -4,7 +4,8 @@ config BRCMUTIL
 config BRCMSMAC
 	tristate "Broadcom IEEE802.11n PCIe SoftMAC WLAN driver"
 	depends on MAC80211
-	depends on BCMA
+	depends on BCMA_POSSIBLE
+	select BCMA
 	select BRCMUTIL
 	select FW_LOADER
 	select CRC_CCITT
-- 
1.8.1.3



^ permalink raw reply related	[flat|nested] 13+ messages in thread

* Re: [PATCH 6/7] brcmfmac: reduce logging noise accessing SDIO SleepCSR register
  2013-11-06 22:07 ` [PATCH 6/7] brcmfmac: reduce logging noise accessing SDIO SleepCSR register Arend van Spriel
@ 2013-11-06 23:53   ` Joe Perches
  2013-11-07  9:31     ` Arend van Spriel
  0 siblings, 1 reply; 13+ messages in thread
From: Joe Perches @ 2013-11-06 23:53 UTC (permalink / raw)
  To: Arend van Spriel; +Cc: John W. Linville, linux-wireless

On Wed, 2013-11-06 at 23:07 +0100, Arend van Spriel wrote:
> The SleepCSR register is accessed to wakeup the device from the
> host side. Depending on the state of the device this may take
> multiple attempts. The failed attempt are not real failures so
> reduce the log level specifically for this register. The calling
> function will scream when the multiple attempts all failed.
[]
> diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c
[]
> +	if (err_ret) {

Maybe better as:

	if (err_ret && net_ratelimit()) { ?

> +		/*
> +		 * SleepCSR register access can fail when
> +		 * waking up the device so reduce this noise
> +		 * in the logs.
> +		 */
> +		if (regaddr != SBSDIO_FUNC1_SLEEPCSR)
> +			brcmf_err("Failed to %s byte F%d:@0x%05x=%02x, Err: %d\n",
> +				  rw ? "write" : "read", func, regaddr, *byte,
> +				  err_ret);
> +		else
> +			brcmf_dbg(SDIO, "Failed to %s byte F%d:@0x%05x=%02x, Err: %d\n",
> +				  rw ? "write" : "read", func, regaddr, *byte,
> +				  err_ret);
> +	}



^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH 6/7] brcmfmac: reduce logging noise accessing SDIO SleepCSR register
  2013-11-06 23:53   ` Joe Perches
@ 2013-11-07  9:31     ` Arend van Spriel
  0 siblings, 0 replies; 13+ messages in thread
From: Arend van Spriel @ 2013-11-07  9:31 UTC (permalink / raw)
  To: Joe Perches; +Cc: John W. Linville, linux-wireless

On 11/07/2013 12:53 AM, Joe Perches wrote:
> On Wed, 2013-11-06 at 23:07 +0100, Arend van Spriel wrote:
>> The SleepCSR register is accessed to wakeup the device from the
>> host side. Depending on the state of the device this may take
>> multiple attempts. The failed attempt are not real failures so
>> reduce the log level specifically for this register. The calling
>> function will scream when the multiple attempts all failed.
> []
>> diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c
> []
>> +	if (err_ret) {
>
> Maybe better as:
>
> 	if (err_ret && net_ratelimit()) { ?

Hi Joe,

It actually does not occur that much. It prints a few lines every 5-10 
seconds. I guess net_ratelimit() does not kick in. To boot brcmf_err() 
already has net_ratelimit().

Regards,
Arend

>> +		/*
>> +		 * SleepCSR register access can fail when
>> +		 * waking up the device so reduce this noise
>> +		 * in the logs.
>> +		 */
>> +		if (regaddr != SBSDIO_FUNC1_SLEEPCSR)
>> +			brcmf_err("Failed to %s byte F%d:@0x%05x=%02x, Err: %d\n",
>> +				  rw ? "write" : "read", func, regaddr, *byte,
>> +				  err_ret);
>> +		else
>> +			brcmf_dbg(SDIO, "Failed to %s byte F%d:@0x%05x=%02x, Err: %d\n",
>> +				  rw ? "write" : "read", func, regaddr, *byte,
>> +				  err_ret);
>> +	}
>
>
>



^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH 0/7] brcm80211: cleanup fixes and out-of-order fix
  2013-11-06 22:07 [PATCH 0/7] brcm80211: cleanup fixes and out-of-order fix Arend van Spriel
                   ` (6 preceding siblings ...)
  2013-11-06 22:07 ` [PATCH 7/7] brcmsmac: select CONFIG_BCMA when possible Arend van Spriel
@ 2013-11-20  9:36 ` Arend van Spriel
  2013-11-20 16:29   ` John W. Linville
  7 siblings, 1 reply; 13+ messages in thread
From: Arend van Spriel @ 2013-11-20  9:36 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless, Arend van Spriel

On 11/06/2013 11:07 PM, Arend van Spriel wrote:
> This series contains a couple of small cleanup fixes and one fix
> from Hante to get rid of out-of-order transmit seen doing UDP iperf.
>
> This series is intended for 3.13 if the merge window has not yet
> opened. It applies to the master branch of the wireless-next
> repository.

This series was sent two weeks ago, but did not pop up in your repos. Is 
it put in 3.14 queue?

Regards,
Arend



^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH 0/7] brcm80211: cleanup fixes and out-of-order fix
  2013-11-20  9:36 ` [PATCH 0/7] brcm80211: cleanup fixes and out-of-order fix Arend van Spriel
@ 2013-11-20 16:29   ` John W. Linville
  2013-11-20 17:30     ` Arend van Spriel
  0 siblings, 1 reply; 13+ messages in thread
From: John W. Linville @ 2013-11-20 16:29 UTC (permalink / raw)
  To: Arend van Spriel; +Cc: linux-wireless

On Wed, Nov 20, 2013 at 10:36:38AM +0100, Arend van Spriel wrote:
> On 11/06/2013 11:07 PM, Arend van Spriel wrote:
> >This series contains a couple of small cleanup fixes and one fix
> >from Hante to get rid of out-of-order transmit seen doing UDP iperf.
> >
> >This series is intended for 3.13 if the merge window has not yet
> >opened. It applies to the master branch of the wireless-next
> >repository.
> 
> This series was sent two weeks ago, but did not pop up in your
> repos. Is it put in 3.14 queue?

I still have the series.  The wireless-next tree is inactive until
after -rc1 gets released.

John
-- 
John W. Linville		Someday the world will need a hero, and you
linville@tuxdriver.com			might be all we have.  Be ready.

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH 0/7] brcm80211: cleanup fixes and out-of-order fix
  2013-11-20 16:29   ` John W. Linville
@ 2013-11-20 17:30     ` Arend van Spriel
  0 siblings, 0 replies; 13+ messages in thread
From: Arend van Spriel @ 2013-11-20 17:30 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless

On 11/20/13 17:29, John W. Linville wrote:
> On Wed, Nov 20, 2013 at 10:36:38AM +0100, Arend van Spriel wrote:
>> On 11/06/2013 11:07 PM, Arend van Spriel wrote:
>>> This series contains a couple of small cleanup fixes and one fix
>> >from Hante to get rid of out-of-order transmit seen doing UDP iperf.
>>>
>>> This series is intended for 3.13 if the merge window has not yet
>>> opened. It applies to the master branch of the wireless-next
>>> repository.
>>
>> This series was sent two weeks ago, but did not pop up in your
>> repos. Is it put in 3.14 queue?
>
> I still have the series.  The wireless-next tree is inactive until
> after -rc1 gets released.

Ok. So it will go into wireless-next for 3.14 after -rc1 release. I just 
was not sure whether it made it before the merge window. It looked a bit 
racy :-)

Regards,
Arend


^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2013-11-20 17:31 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-11-06 22:07 [PATCH 0/7] brcm80211: cleanup fixes and out-of-order fix Arend van Spriel
2013-11-06 22:07 ` [PATCH 1/7] brcmfmac: Update fwsignal to fix out of order tx Arend van Spriel
2013-11-06 22:07 ` [PATCH 2/7] brcmfmac: add separate function for passing bus tx overhead Arend van Spriel
2013-11-06 22:07 ` [PATCH 3/7] brcmfmac: replace dongle command list with .preinit() callback Arend van Spriel
2013-11-06 22:07 ` [PATCH 4/7] brcmfmac: start netif queues only when setup is completed successful Arend van Spriel
2013-11-06 22:07 ` [PATCH 5/7] brcmfmac: remove empty brcmf_proto_stop Arend van Spriel
2013-11-06 22:07 ` [PATCH 6/7] brcmfmac: reduce logging noise accessing SDIO SleepCSR register Arend van Spriel
2013-11-06 23:53   ` Joe Perches
2013-11-07  9:31     ` Arend van Spriel
2013-11-06 22:07 ` [PATCH 7/7] brcmsmac: select CONFIG_BCMA when possible Arend van Spriel
2013-11-20  9:36 ` [PATCH 0/7] brcm80211: cleanup fixes and out-of-order fix Arend van Spriel
2013-11-20 16:29   ` John W. Linville
2013-11-20 17:30     ` Arend van Spriel

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).