Linux wireless drivers development
 help / color / mirror / Atom feed
* [PATCH 16/22] brcmfmac: Simplify counting transit count.
From: Arend van Spriel @ 2013-06-06 11:18 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless, Hante Meuleman, Arend van Spriel
In-Reply-To: <1370517487-14395-1-git-send-email-arend@broadcom.com>

From: Hante Meuleman <meuleman@broadcom.com>

Reviewed-by: Arend Van Spriel <arend@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 |   31 ++++++++------------
 1 file changed, 12 insertions(+), 19 deletions(-)

diff --git a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
index 159ed1d..ea37bd4 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
@@ -361,7 +361,6 @@ struct brcmf_fws_mac_descriptor {
 	u8 seq[BRCMF_FWS_FIFO_COUNT];
 	struct pktq psq;
 	int transit_count;
-	int suppress_count;
 	int suppr_transit_count;
 	bool send_tim_signal;
 	u8 traffic_pending_bmp;
@@ -1176,8 +1175,6 @@ static int brcmf_fws_enq(struct brcmf_fws_info *fws,
 
 	/* update the sk_buff state */
 	brcmf_skbcb(p)->state = state;
-	if (state == BRCMF_FWS_SKBSTATE_SUPPRESSED)
-		entry->suppress_count++;
 
 	/*
 	 * A packet has been pushed so update traffic
@@ -1217,9 +1214,8 @@ static struct sk_buff *brcmf_fws_deq(struct brcmf_fws_info *fws, int fifo)
 		p = brcmu_pktq_mdeq(&entry->psq, pmsk << (fifo * 2), &prec_out);
 		if (p == NULL) {
 			if (entry->suppressed) {
-				if (entry->suppr_transit_count >
-				    entry->suppress_count)
-					return NULL;
+				if (entry->suppr_transit_count)
+					continue;
 				entry->suppressed = false;
 				p = brcmu_pktq_mdeq(&entry->psq,
 						    1 << (fifo * 2), &prec_out);
@@ -1270,12 +1266,9 @@ static int brcmf_fws_txstatus_suppressed(struct brcmf_fws_info *fws, int fifo,
 	/* this packet was suppressed */
 	if (!entry->suppressed) {
 		entry->suppressed = true;
-		entry->suppress_count = brcmu_pktq_mlen(&entry->psq,
-							1 << (fifo * 2 + 1));
 		entry->suppr_transit_count = entry->transit_count;
-		brcmf_dbg(DATA, "suppress %s: supp_cnt %d transit %d\n",
-			  entry->name, entry->suppress_count,
-			  entry->transit_count);
+		brcmf_dbg(DATA, "suppress %s: transit %d\n",
+			  entry->name, entry->transit_count);
 	}
 
 	entry->generation = genbit;
@@ -1294,7 +1287,6 @@ static int brcmf_fws_txstatus_suppressed(struct brcmf_fws_info *fws, int fifo,
 		 * wlfc cleanup
 		 */
 		brcmf_fws_hanger_mark_suppressed(&fws->hanger, hslot);
-		entry->suppress_count++;
 	}
 
 	return ret;
@@ -1339,6 +1331,9 @@ brcmf_fws_txs_process(struct brcmf_fws_info *fws, u8 flags, u32 hslot,
 		brcmu_pkt_buf_free_skb(skb);
 		return -EINVAL;
 	}
+	entry->transit_count--;
+	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);
@@ -1352,13 +1347,9 @@ brcmf_fws_txs_process(struct brcmf_fws_info *fws, u8 flags, u32 hslot,
 	if (!remove_from_hanger)
 		ret = brcmf_fws_txstatus_suppressed(fws, fifo, skb, genbit);
 
-	if (remove_from_hanger || ret) {
-		entry->transit_count--;
-		if (entry->suppressed)
-			entry->suppr_transit_count--;
-
+	if (remove_from_hanger || ret)
 		brcmf_txfinalize(fws->drvr, skb, true);
-	}
+
 	return 0;
 }
 
@@ -1614,7 +1605,6 @@ static int brcmf_fws_precommit_skb(struct brcmf_fws_info *fws, int fifo,
 		free_ctr = entry->seq[fifo];
 		brcmf_skb_htod_tag_set_field(p, HSLOT, hslot);
 		brcmf_skb_htod_tag_set_field(p, FREERUN, free_ctr);
-		entry->transit_count++;
 		rc = brcmf_fws_hanger_pushpkt(&fws->hanger, p, hslot);
 		if (rc)
 			brcmf_err("hanger push failed: rc=%d\n", rc);
@@ -1768,6 +1758,9 @@ static int brcmf_fws_commit_skb(struct brcmf_fws_info *fws, int fifo,
 		goto rollback;
 	}
 
+	entry->transit_count++;
+	if (entry->suppressed)
+		entry->suppr_transit_count++;
 	entry->seq[fifo]++;
 	fws->stats.pkt2bus++;
 	if (brcmf_skbcb(skb)->if_flags & BRCMF_SKB_IF_FLAGS_CREDITCHECK_MASK) {
-- 
1.7.10.4



^ permalink raw reply related

* [PATCH 04/22] brcmfmac: rework credit pickup to assure consistent handling
From: Arend van Spriel @ 2013-06-06 11:17 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless, Arend van Spriel
In-Reply-To: <1370517487-14395-1-git-send-email-arend@broadcom.com>

Reworked brcmf_skb_pick_up_credit() so it can be used for both
fcmode flavours in the same way.

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/fwsignal.c |   30 +++++++++-----------
 1 file changed, 13 insertions(+), 17 deletions(-)

diff --git a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
index c1930ef5..a7a0247 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
@@ -1040,24 +1040,21 @@ static void brcmf_fws_schedule_deq(struct brcmf_fws_info *fws)
 		queue_work(fws->fws_wq, &fws->fws_dequeue_work);
 }
 
-static void brcmf_skb_pick_up_credit(struct brcmf_fws_info *fws, int fifo,
+static void brcmf_fws_skb_pickup_credit(struct brcmf_fws_info *fws, int fifo,
 				     struct sk_buff *p)
 {
 	struct brcmf_fws_mac_descriptor *entry = brcmf_skbcb(p)->mac;
 
-	if (brcmf_skbcb(p)->if_flags & BRCMF_SKB_IF_FLAGS_CREDITCHECK_MASK) {
-		if (fws->fcmode != BRCMF_FWS_FCMODE_IMPLIED_CREDIT)
-			return;
+	if (brcmf_skbcb(p)->if_flags & BRCMF_SKB_IF_FLAGS_CREDITCHECK_MASK)
 		brcmf_fws_return_credits(fws, fifo, 1);
-	} else {
+	else if (!brcmf_skb_if_flags_get_field(p, REQUESTED))
 		/*
 		 * if this packet did not count against FIFO credit, it
 		 * must have taken a requested_credit from the destination
 		 * entry (for pspoll etc.)
 		 */
-		if (!brcmf_skb_if_flags_get_field(p, REQUESTED))
-			entry->requested_credit++;
-	}
+		entry->requested_credit++;
+
 	brcmf_fws_schedule_deq(fws);
 }
 
@@ -1272,7 +1269,9 @@ brcmf_fws_txstatus_process(struct brcmf_fws_info *fws, u8 flags, u32 hslot,
 
 	/* pick up the implicit credit from this packet */
 	fifo = brcmf_skb_htod_tag_get_field(skb, FIFO);
-	brcmf_skb_pick_up_credit(fws, fifo, skb);
+	if (fws->fcmode == BRCMF_FWS_FCMODE_IMPLIED_CREDIT ||
+	    !(brcmf_skbcb(skb)->if_flags & BRCMF_SKB_IF_FLAGS_CREDITCHECK_MASK))
+		brcmf_fws_skb_pickup_credit(fws, fifo, skb);
 
 	if (!remove_from_hanger)
 		ret = brcmf_fws_txstatus_suppressed(fws, fifo, skb, genbit);
@@ -1845,7 +1844,7 @@ int brcmf_fws_process_skb(struct brcmf_if *ifp, struct sk_buff *skb)
 	} else {
 		if (brcmf_fws_commit_skb(fws, fifo, skb))
 			if (!multicast)
-				brcmf_skb_pick_up_credit(fws, fifo, skb);
+				brcmf_fws_skb_pickup_credit(fws, fifo, skb);
 	}
 	brcmf_fws_unlock(drvr, flags);
 	return 0;
@@ -2053,18 +2052,15 @@ bool brcmf_fws_fc_active(struct brcmf_fws_info *fws)
 void brcmf_fws_bustxfail(struct brcmf_fws_info *fws, struct sk_buff *skb)
 {
 	ulong flags;
+	int fifo;
 
 	brcmf_fws_lock(fws->drvr, flags);
 	brcmf_fws_txstatus_process(fws, BRCMF_FWS_TXSTATUS_FW_TOSSED,
 				   brcmf_skb_htod_tag_get_field(skb, HSLOT), 0);
 	/* the packet never reached firmware so reclaim credit */
-	if (fws->fcmode == BRCMF_FWS_FCMODE_EXPLICIT_CREDIT &&
-	    brcmf_skbcb(skb)->if_flags & BRCMF_SKB_IF_FLAGS_CREDITCHECK_MASK) {
-		brcmf_fws_return_credits(fws,
-					 brcmf_skb_htod_tag_get_field(skb,
-								      FIFO),
-					 1);
-		brcmf_fws_schedule_deq(fws);
+	if (fws->fcmode == BRCMF_FWS_FCMODE_EXPLICIT_CREDIT) {
+		fifo = brcmf_skb_htod_tag_get_field(skb, FIFO);
+		brcmf_fws_skb_pickup_credit(fws, fifo, skb);
 	}
 	brcmf_fws_unlock(fws->drvr, flags);
 }
-- 
1.7.10.4



^ permalink raw reply related

* [PATCH 09/22] brcmfmac: Correct creditmap when credit borrowing is active.
From: Arend van Spriel @ 2013-06-06 11:17 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless, Hante Meuleman, Arend van Spriel
In-Reply-To: <1370517487-14395-1-git-send-email-arend@broadcom.com>

From: Hante Meuleman <meuleman@broadcom.com>

When credit borrowing is active the BE credits have been depleted,
however the worker should still be scheduled. In case of credit
borrowing correct credit map to make sure worker remains active.

Reviewed-by: Arend Van Spriel <arend@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 |    9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
index 682ac62..abba7f7 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
@@ -1020,6 +1020,8 @@ static void brcmf_fws_return_credits(struct brcmf_fws_info *fws,
 	if (!credits)
 		return;
 
+	fws->fifo_credit_map |= 1 << fifo;
+
 	if ((fifo == BRCMF_FWS_FIFO_AC_BE) &&
 	    (fws->credits_borrowed[0])) {
 		for (lender_ac = BRCMF_FWS_FIFO_AC_VO; lender_ac >= 0;
@@ -1041,7 +1043,6 @@ static void brcmf_fws_return_credits(struct brcmf_fws_info *fws,
 		}
 	}
 
-	fws->fifo_credit_map |= 1 << fifo;
 	fws->fifo_credit[fifo] += credits;
 }
 
@@ -1675,8 +1676,10 @@ static int brcmf_fws_borrow_credit(struct brcmf_fws_info *fws)
 {
 	int lender_ac;
 
-	if (time_after(fws->borrow_defer_timestamp, jiffies))
+	if (time_after(fws->borrow_defer_timestamp, jiffies)) {
+		fws->fifo_credit_map &= ~(1 << BRCMF_FWS_FIFO_AC_BE);
 		return -ENAVAIL;
+	}
 
 	for (lender_ac = 0; lender_ac <= BRCMF_FWS_FIFO_AC_VO; lender_ac++) {
 		if (fws->fifo_credit[lender_ac]) {
@@ -1684,10 +1687,12 @@ static int brcmf_fws_borrow_credit(struct brcmf_fws_info *fws)
 			fws->fifo_credit[lender_ac]--;
 			if (fws->fifo_credit[lender_ac] == 0)
 				fws->fifo_credit_map &= ~(1 << lender_ac);
+			fws->fifo_credit_map |= (1 << BRCMF_FWS_FIFO_AC_BE);
 			brcmf_dbg(DATA, "borrow credit from: %d\n", lender_ac);
 			return 0;
 		}
 	}
+	fws->fifo_credit_map &= ~(1 << BRCMF_FWS_FIFO_AC_BE);
 	return -ENAVAIL;
 }
 
-- 
1.7.10.4



^ permalink raw reply related

* [PATCH 05/22] brcmfmac: explicitly indicate sk_buff is sent upon request credit
From: Arend van Spriel @ 2013-06-06 11:17 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless, Arend van Spriel
In-Reply-To: <1370517487-14395-1-git-send-email-arend@broadcom.com>

Firmware can request the driver for transmit packets using two different
signals. Only for one signal a flag was set in the sk_buff control
buffer. This patch adds explicit flag for the other signal as well.

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/fwsignal.c |  122 +++++++++-----------
 1 file changed, 53 insertions(+), 69 deletions(-)

diff --git a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
index a7a0247..d080874 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
@@ -190,13 +190,16 @@ struct brcmf_skbuff_cb {
 /*
  * sk_buff control if flags
  *
- *	b[11]  - packet sent upon firmware request.
+ *	b[12]  - packet sent upon credit request.
+ *	b[11]  - packet sent upon packet request.
  *	b[10]  - packet only contains signalling data.
  *	b[9]   - packet is a tx packet.
  *	b[8]   - packet uses FIFO credit (non-pspoll).
  *	b[7]   - interface in AP mode.
  *	b[3:0] - interface index.
  */
+#define BRCMF_SKB_IF_FLAGS_REQ_CREDIT_MASK	0x1000
+#define BRCMF_SKB_IF_FLAGS_REQ_CREDIT_SHIFT	12
 #define BRCMF_SKB_IF_FLAGS_REQUESTED_MASK	0x0800
 #define BRCMF_SKB_IF_FLAGS_REQUESTED_SHIFT	11
 #define BRCMF_SKB_IF_FLAGS_SIGNAL_ONLY_MASK	0x0400
@@ -998,6 +1001,37 @@ static int brcmf_fws_request_indicate(struct brcmf_fws_info *fws, u8 type,
 	return BRCMF_FWS_RET_OK_SCHEDULE;
 }
 
+static int brcmf_fws_macdesc_use_credit(struct brcmf_fws_mac_descriptor *entry,
+					struct sk_buff *skb)
+{
+	int use_credit = 1;
+
+	if (entry->state == BRCMF_FWS_STATE_CLOSE) {
+		if (entry->requested_credit > 0) {
+			/*
+			 * if the packet was pulled out while destination is in
+			 * closed state but had a non-zero packets requested,
+			 * then this should not count against the FIFO credit.
+			 * That is due to the fact that the firmware will
+			 * most likely hold onto this packet until a suitable
+			 * time later to push it to the appropriate AC FIFO.
+			 */
+			entry->requested_credit--;
+			brcmf_skb_if_flags_set_field(skb, REQ_CREDIT, 1);
+			use_credit = 0;
+		} else if (entry->requested_packet > 0) {
+			entry->requested_packet--;
+			brcmf_skb_if_flags_set_field(skb, REQUESTED, 1);
+			use_credit = 0;
+		}
+	} else {
+		WARN_ON(entry->requested_credit);
+		WARN_ON(entry->requested_packet);
+	}
+	brcmf_skb_if_flags_set_field(skb, CREDITCHECK, use_credit);
+	return use_credit;
+}
+
 static void brcmf_fws_return_credits(struct brcmf_fws_info *fws,
 				     u8 fifo, u8 credits)
 {
@@ -1047,10 +1081,11 @@ static void brcmf_fws_skb_pickup_credit(struct brcmf_fws_info *fws, int fifo,
 
 	if (brcmf_skbcb(p)->if_flags & BRCMF_SKB_IF_FLAGS_CREDITCHECK_MASK)
 		brcmf_fws_return_credits(fws, fifo, 1);
-	else if (!brcmf_skb_if_flags_get_field(p, REQUESTED))
+	else if (brcmf_skb_if_flags_get_field(p, REQ_CREDIT) &&
+		 entry->state == BRCMF_FWS_STATE_CLOSE)
 		/*
 		 * if this packet did not count against FIFO credit, it
-		 * must have taken a requested_credit from the destination
+		 * could have taken a requested_credit from the destination
 		 * entry (for pspoll etc.)
 		 */
 		entry->requested_credit++;
@@ -1108,7 +1143,6 @@ static struct sk_buff *brcmf_fws_deq(struct brcmf_fws_info *fws, int fifo)
 	struct brcmf_fws_mac_descriptor *table;
 	struct brcmf_fws_mac_descriptor *entry;
 	struct sk_buff *p;
-	int use_credit = 1;
 	int num_nodes;
 	int node_pos;
 	int prec_out;
@@ -1143,26 +1177,7 @@ static struct sk_buff *brcmf_fws_deq(struct brcmf_fws_info *fws, int fifo)
 		if  (p == NULL)
 			continue;
 
-		/* did the packet come from suppress sub-queue? */
-		if (entry->requested_credit > 0) {
-			entry->requested_credit--;
-			/*
-			 * if the packet was pulled out while destination is in
-			 * closed state but had a non-zero packets requested,
-			 * then this should not count against the FIFO credit.
-			 * That is due to the fact that the firmware will
-			 * most likely hold onto this packet until a suitable
-			 * time later to push it to the appropriate AC FIFO.
-			 */
-			if (entry->state == BRCMF_FWS_STATE_CLOSE)
-				use_credit = 0;
-		} else if (entry->requested_packet > 0) {
-			entry->requested_packet--;
-			brcmf_skb_if_flags_set_field(p, REQUESTED, 1);
-			if (entry->state == BRCMF_FWS_STATE_CLOSE)
-				use_credit = 0;
-		}
-		brcmf_skb_if_flags_set_field(p, CREDITCHECK, use_credit);
+		brcmf_fws_macdesc_use_credit(entry, p);
 
 		/* move dequeue position to ensure fair round-robin */
 		fws->deq_node_pos[fifo] = (node_pos + i + 1) % num_nodes;
@@ -1664,13 +1679,6 @@ brcmf_fws_rollback_toq(struct brcmf_fws_info *fws,
 			/* decrement sequence count */
 			entry->seq[fifo]--;
 		}
-		/*
-		if this packet did not count against FIFO credit, it must have
-		taken a requested_credit from the firmware (for pspoll etc.)
-		*/
-		if (!(brcmf_skbcb(skb)->if_flags &
-		      BRCMF_SKB_IF_FLAGS_CREDITCHECK_MASK))
-			entry->requested_credit++;
 	} else {
 		brcmf_err("no mac entry linked\n");
 		rc = -ENOENT;
@@ -1679,10 +1687,12 @@ brcmf_fws_rollback_toq(struct brcmf_fws_info *fws,
 
 fail:
 	if (rc) {
-		brcmf_txfinalize(fws->drvr, skb, false);
+		brcmf_fws_bustxfail(fws, skb);
 		fws->stats.rollback_failed++;
-	} else
+	} else {
 		fws->stats.rollback_success++;
+		brcmf_fws_skb_pickup_credit(fws, fifo, skb);
+	}
 }
 
 static int brcmf_fws_borrow_credit(struct brcmf_fws_info *fws)
@@ -1710,30 +1720,10 @@ static int brcmf_fws_consume_credit(struct brcmf_fws_info *fws, int fifo,
 {
 	struct brcmf_fws_mac_descriptor *entry = brcmf_skbcb(skb)->mac;
 	int *credit = &fws->fifo_credit[fifo];
-	int use_credit = 1;
 
 	brcmf_dbg(TRACE, "enter: ac=%d, credits=%d\n", fifo, *credit);
 
-	if (entry->requested_credit > 0) {
-		/*
-		 * if the packet was pulled out while destination is in
-		 * closed state but had a non-zero packets requested,
-		 * then this should not count against the FIFO credit.
-		 * That is due to the fact that the firmware will
-		 * most likely hold onto this packet until a suitable
-		 * time later to push it to the appropriate AC FIFO.
-		 */
-		entry->requested_credit--;
-		if (entry->state == BRCMF_FWS_STATE_CLOSE)
-			use_credit = 0;
-	} else if (entry->requested_packet > 0) {
-		entry->requested_packet--;
-		brcmf_skb_if_flags_set_field(skb, REQUESTED, 1);
-		if (entry->state == BRCMF_FWS_STATE_CLOSE)
-			use_credit = 0;
-	}
-	brcmf_skb_if_flags_set_field(skb, CREDITCHECK, use_credit);
-	if (!use_credit) {
+	if (!brcmf_fws_macdesc_use_credit(entry, skb)) {
 		brcmf_dbg(TRACE, "exit: no creditcheck set\n");
 		return 0;
 	}
@@ -1842,9 +1832,7 @@ int brcmf_fws_process_skb(struct brcmf_if *ifp, struct sk_buff *skb)
 		drvr->fws->fifo_delay_map |= 1 << fifo;
 		brcmf_fws_enq(fws, BRCMF_FWS_SKBSTATE_DELAYED, fifo, skb);
 	} else {
-		if (brcmf_fws_commit_skb(fws, fifo, skb))
-			if (!multicast)
-				brcmf_fws_skb_pickup_credit(fws, fifo, skb);
+		brcmf_fws_commit_skb(fws, fifo, skb);
 	}
 	brcmf_fws_unlock(drvr, flags);
 	return 0;
@@ -1900,7 +1888,6 @@ static void brcmf_fws_dequeue_worker(struct work_struct *worker)
 	struct sk_buff *skb;
 	ulong flags;
 	int fifo;
-	int credit;
 
 	fws = container_of(worker, struct brcmf_fws_info, fws_dequeue_work);
 
@@ -1910,35 +1897,32 @@ static void brcmf_fws_dequeue_worker(struct work_struct *worker)
 	     fifo--) {
 		brcmf_dbg(TRACE, "fifo %d credit %d\n", fifo,
 			  fws->fifo_credit[fifo]);
-		for (credit = 0; credit < fws->fifo_credit[fifo]; /* nop */) {
+		while (fws->fifo_credit[fifo]) {
 			skb = brcmf_fws_deq(fws, fifo);
-			if (!skb || brcmf_fws_commit_skb(fws, fifo, skb))
+			if (!skb)
 				break;
 			if (brcmf_skbcb(skb)->if_flags &
 			    BRCMF_SKB_IF_FLAGS_CREDITCHECK_MASK)
-				credit++;
+				fws->fifo_credit[fifo]--;
+
+			if (brcmf_fws_commit_skb(fws, fifo, skb))
+				break;
 			if (fws->bus_flow_blocked)
 				break;
 		}
 		if ((fifo == BRCMF_FWS_FIFO_AC_BE) &&
-		    (credit == fws->fifo_credit[fifo]) &&
+		    (fws->fifo_credit[fifo] == 0) &&
 		    (!fws->bus_flow_blocked)) {
-			fws->fifo_credit[fifo] -= credit;
 			while (brcmf_fws_borrow_credit(fws) == 0) {
 				skb = brcmf_fws_deq(fws, fifo);
 				if (!skb) {
 					brcmf_fws_return_credits(fws, fifo, 1);
 					break;
 				}
-				if (brcmf_fws_commit_skb(fws, fifo, skb)) {
-					brcmf_fws_return_credits(fws, fifo, 1);
-					break;
-				}
+				brcmf_fws_commit_skb(fws, fifo, skb);
 				if (fws->bus_flow_blocked)
 					break;
 			}
-		} else {
-			fws->fifo_credit[fifo] -= credit;
 		}
 	}
 	brcmf_fws_unlock(fws->drvr, flags);
-- 
1.7.10.4



^ permalink raw reply related

* [PATCH 01/22] brcmfmac: allow firmware-signal tlv to be longer than specified
From: Arend van Spriel @ 2013-06-06 11:17 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless, Arend van Spriel
In-Reply-To: <1370517487-14395-1-git-send-email-arend@broadcom.com>

The firmware-signal API specification defines length for the different
tlv. During testing on different devices it turned out not all firmware
used the tlv length according specification. Therefore the length check
is made less strict with this patch.

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/fwsignal.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
index 5352dc1..d6f05ae 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
@@ -1433,7 +1433,7 @@ int brcmf_fws_hdrpull(struct brcmf_pub *drvr, int ifidx, s16 signal_len,
 		if (data_len < len + 2)
 			break;
 
-		if (len != brcmf_fws_get_tlv_len(fws, type))
+		if (len < brcmf_fws_get_tlv_len(fws, type))
 			break;
 
 		err = BRCMF_FWS_RET_OK_NOSCHEDULE;
-- 
1.7.10.4



^ permalink raw reply related

* [PATCH 00/22] brcmfmac: firmware-signalling fixes and cleanup
From: Arend van Spriel @ 2013-06-06 11:17 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless, Arend van Spriel

This series is intended for v3.11 and resolves a number of issues observed
testing firmware-signalling feature with power-save stations and P2P scenarios
as well as several patches for code cleanup.

The series applies to the master branch of the wireless-next repository.

Arend van Spriel (11):
  brcmfmac: allow firmware-signal tlv to be longer than specified
  brcmfmac: remove fifo bitfield from brcmf_skbuff_cb::if_flags
  brcmfmac: rework credit pickup to assure consistent handling
  brcmfmac: explicitly indicate sk_buff is sent upon request credit
  brcmfmac: reducing debug logging in firmware-signalling code
  brcmfmac: Sent TIM information in case of data available.
  brcmfmac: fix send_pkts statistic counter in firmware-signalling
  brcmfmac: use credit mechanism for BC/MC if support by firmware
  brcmfmac: add trace event for capturing BDC header
  brcmfmac: increment hard_header_len instead of overriding
  brcmfmac: add debugfs statistics for firmware-signalling

Hante Meuleman (11):
  brcmfmac: Take bus flowcontrol at credit mgmt into account.
  brcmfmac: On bus flow control use fw signalling or netif.
  brcmfmac: For FW signalling it is necessary to track gen bit.
  brcmfmac: Correct creditmap when credit borrowing is active.
  brcmfmac: Find correct MAC descriptor in case of TDLS.
  brcmfmac: fix invalid ifp lookup in firmware-signalling
  brcmfmac: Accept only first creditmap event.
  brcmfmac: Signalling header push and pull on logic places.
  brcmfmac: Fix endless loop when brcmf_fws_commit_skb fails.
  brcmfmac: Simplify counting transit count.
  brcmfmac: Always use fifo_credits, also for requested credits.

 drivers/net/wireless/brcm80211/brcmfmac/dhd.h      |    2 +
 drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c  |    3 +
 drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.c  |   18 +-
 drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h  |    6 +-
 .../net/wireless/brcm80211/brcmfmac/dhd_linux.c    |   23 +-
 drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c |    2 +-
 drivers/net/wireless/brcm80211/brcmfmac/fweh.h     |    3 +-
 drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c |  730 ++++++++++----------
 drivers/net/wireless/brcm80211/brcmfmac/fwsignal.h |    1 +
 .../net/wireless/brcm80211/brcmfmac/tracepoint.h   |   21 +
 drivers/net/wireless/brcm80211/brcmfmac/usb.c      |    8 +
 11 files changed, 436 insertions(+), 381 deletions(-)

-- 
1.7.10.4



^ permalink raw reply

* [PATCH 17/22] brcmfmac: fix send_pkts statistic counter in firmware-signalling
From: Arend van Spriel @ 2013-06-06 11:18 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless, Arend van Spriel
In-Reply-To: <1370517487-14395-1-git-send-email-arend@broadcom.com>

The statistic counter send_pkts was wrongly counted conditionally.
Correcting the mistake.

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/fwsignal.c |    5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
index ea37bd4..534507a 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
@@ -1763,10 +1763,9 @@ static int brcmf_fws_commit_skb(struct brcmf_fws_info *fws, int fifo,
 		entry->suppr_transit_count++;
 	entry->seq[fifo]++;
 	fws->stats.pkt2bus++;
-	if (brcmf_skbcb(skb)->if_flags & BRCMF_SKB_IF_FLAGS_CREDITCHECK_MASK) {
-		fws->stats.send_pkts[fifo]++;
+	fws->stats.send_pkts[fifo]++;
+	if (brcmf_skbcb(skb)->if_flags & BRCMF_SKB_IF_FLAGS_CREDITCHECK_MASK)
 		fws->stats.fifo_credits_sent[fifo]++;
-	}
 
 	return rc;
 
-- 
1.7.10.4



^ permalink raw reply related

* Re: carl9170:5/10 MHz Channel Support on carl9170
From: Christian Lamparter @ 2013-06-06 11:09 UTC (permalink / raw)
  To: C.B. Wang, linux-wireless
In-Reply-To: <CAB-Tk7273qtgA0J-rvpFxNbMDErmXVdknybVOJmUTa73VhL1Cw@mail.gmail.com>

On Thursday, June 06, 2013 10:07:46 AM C.B. Wang wrote:
> Spectral analysis isn't supported by any Atheros USB
> chipsets, is it?
maybe by the ar7010+ar92xy combo. Anyway, if you need it
for your job, then you should help implementing it!

> The 802.11j standard defines 10mhz operation. I think
> it is mandatory. You can get a copy here
> http://www.it.iitb.ac.in/~mukesh/dokuwiki/lib/exe/fetch.php?cache=cache&media=mtp:802.11j-2004.pdf
Can you tell me on what page/chapter? Thanks!

> Channel 183(4815mhz),185(4925mhz),187(4935mhz),189(4945mhz)
> should also be added to the channel list of carl9170 driver.
Hey that's great. Please send us patch then. Testing is not
possible here in Germany, the regdomain doesn't allow it.

Regards,
	Chr

^ permalink raw reply

* [patch -next] cw1200: handle allocation failure in wsm_event_indication()
From: Dan Carpenter @ 2013-06-06 10:57 UTC (permalink / raw)
  To: Solomon Peachy; +Cc: John W. Linville, linux-wireless, kernel-janitors

Check for allocation failures and return -ENOMEM.  The caller
already expects it.

Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>

diff --git a/drivers/net/wireless/cw1200/wsm.c b/drivers/net/wireless/cw1200/wsm.c
index f3fd9b2..3ab25f6 100644
--- a/drivers/net/wireless/cw1200/wsm.c
+++ b/drivers/net/wireless/cw1200/wsm.c
@@ -929,6 +929,8 @@ static int wsm_event_indication(struct cw1200_common *priv, struct wsm_buf *buf)
 	}
 
 	event = kzalloc(sizeof(struct cw1200_wsm_event), GFP_KERNEL);
+	if (!event)
+		return -ENOMEM;
 
 	event->evt.id = __le32_to_cpu(WSM_GET32(buf));
 	event->evt.data = __le32_to_cpu(WSM_GET32(buf));

^ permalink raw reply related

* [patch] brcmfmac: move dereference under check for NULL
From: Dan Carpenter @ 2013-06-06 10:55 UTC (permalink / raw)
  To: Brett Rudley
  Cc: Arend van Spriel, Franky (Zhenhui) Lin, Hante Meuleman,
	John W. Linville, Pieter-Paul Giesberts, Piotr Haber,
	linux-wireless, brcm80211-dev-list, kernel-janitors

skb_pull() dereferences the skb parameter.

Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>

diff --git a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
index ea37bd4..c35296f 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
@@ -861,9 +861,9 @@ static bool brcmf_fws_tim_update(struct brcmf_fws_info *fws,
 		      BRCMF_FWS_TYPE_PENDING_TRAFFIC_BMP_LEN + 2 +
 		      4 + fws->drvr->hdrlen;
 		skb = brcmu_pkt_buf_get_skb(len);
-		skb_pull(skb, len);
 		if (skb == NULL)
 			return false;
+		skb_pull(skb, len);
 		skcb = brcmf_skbcb(skb);
 		skcb->mac = entry;
 		skcb->state = BRCMF_FWS_SKBSTATE_TIM;

^ permalink raw reply related

* Re: [patch] cw1200: remove an unreachable goto
From: Solomon Peachy @ 2013-06-06 10:55 UTC (permalink / raw)
  To: Dan Carpenter; +Cc: John W. Linville, linux-wireless, kernel-janitors
In-Reply-To: <20130606105145.GC12953@debian>

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

On Thu, Jun 06, 2013 at 03:51:45AM -0700, Dan Carpenter wrote:
> The "return" is correct and the unreachable "goto" line is wrong.
> I have deleted it.

A patch for this was posted earlier by Joe Perches.  It's in my tree 
now, awaiting merging.

 - Solomon
-- 
Solomon Peachy        		       pizza at shaftnet dot org	 
Delray Beach, FL                          ^^ (email/xmpp) ^^
Quidquid latine dictum sit, altum viditur.

[-- Attachment #2: Type: application/pgp-signature, Size: 190 bytes --]

^ permalink raw reply

* [patch] cw1200: remove an unreachable goto
From: Dan Carpenter @ 2013-06-06 10:51 UTC (permalink / raw)
  To: Solomon Peachy; +Cc: John W. Linville, linux-wireless, kernel-janitors

The "return" is correct and the unreachable "goto" line is wrong.
I have deleted it.

Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>

diff --git a/drivers/net/wireless/cw1200/hwio.c b/drivers/net/wireless/cw1200/hwio.c
index 1af7b3d..f6b5efd 100644
--- a/drivers/net/wireless/cw1200/hwio.c
+++ b/drivers/net/wireless/cw1200/hwio.c
@@ -178,7 +178,6 @@ int cw1200_indirect_read(struct cw1200_common *priv, u32 addr, void *buf,
 	if ((buf_len / 2) >= 0x1000) {
 		pr_err("Can't read more than 0xfff words.\n");
 		return -EINVAL;
-		goto out;
 	}
 
 	priv->sbus_ops->lock(priv->sbus_priv);

^ permalink raw reply related

* Re: [PATCH] ath5k: make use of the new rate control API
From: Thomas Hühn @ 2013-06-06 10:33 UTC (permalink / raw)
  To: Felix Fietkau
  Cc: linville, linux-wireless, johannes, mickflemm, mcgrof, rmanohar,
	adrian, ath5k-devel, bvahl
In-Reply-To: <51B063C7.5040509@openwrt.org>

HI,

> This patch is missing changes in the tx status path. At tx completion,
> info->status.rates needs to be filled with the contents of bf->rates
> before filling in retry counts.
> 

Thats right, I will fix this in V2.

>> 
>> +	txrate.count = bf->rates[0].count;
>> +
>> 	ret = ah->ah_setup_tx_desc(ah, ds, pktlen,
>> 		ieee80211_get_hdrlen_from_skb(skb), padsize,
>> 		get_hw_packet_type(skb),
>> 		(ah->ah_txpower.txp_requested * 2),
>> 		hw_rate,
>> -		info->control.rates[0].count, keyidx, ah->ah_tx_ant, flags,
>> +		txrate.count, keyidx, ah->ah_tx_ant, flags,
>> 		cts_rate, duration);
>> 	if (ret)
>> 		goto err_unmap;
> The txrate variable is pointless, you only use txrate.count where you
> could also just use bf->rates[0].count directly.
> 

I will remove this variable.

Thx for you review.

Thomas

> - Felix
> --
> 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

* Re: [PATCH] ath5k: make use of the new rate control API
From: Felix Fietkau @ 2013-06-06 10:26 UTC (permalink / raw)
  To: Thomas Huehn
  Cc: linville, linux-wireless, johannes, mickflemm, mcgrof, rmanohar,
	adrian, ath5k-devel, bvahl
In-Reply-To: <1370509492-24293-1-git-send-email-thomas@net.t-labs.tu-berlin.de>

On 2013-06-06 11:04 AM, Thomas Huehn wrote:
> This patch enabels ath5k to use the new rate table to lookup each
> mrr rate and retry information per packet.
> 
> Signed-off-by: Benjamin Vahl <bvahl@net.t-labs.tu-berlin.de>
> Signed-off-by: Thomas Huehn <thomas@net.t-labs.tu-berlin.de>
This patch is missing changes in the tx status path. At tx completion,
info->status.rates needs to be filled with the contents of bf->rates
before filling in retry counts.

> --- a/drivers/net/wireless/ath/ath5k/base.c
> +++ b/drivers/net/wireless/ath/ath5k/base.c
>  static int
>  ath5k_txbuf_setup(struct ath5k_hw *ah, struct ath5k_buf *bf,
> -		  struct ath5k_txq *txq, int padsize)
> +		  struct ath5k_txq *txq, int padsize,
> +		  struct ieee80211_tx_control *control)
>  {
>  	struct ath5k_desc *ds = bf->desc;
>  	struct sk_buff *skb = bf->skb;
>  	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
>  	unsigned int pktlen, flags, keyidx = AR5K_TXKEYIX_INVALID;
>  	struct ieee80211_rate *rate;
> +	struct ieee80211_tx_rate txrate;
>  	unsigned int mrr_rate[3], mrr_tries[3];
>  	int i, ret;
>  	u16 hw_rate;
> @@ -722,12 +765,15 @@ ath5k_txbuf_setup(struct ath5k_hw *ah, struct ath5k_buf *bf,
>  		duration = le16_to_cpu(ieee80211_ctstoself_duration(ah->hw,
>  			info->control.vif, pktlen, info));
>  	}
> +
> +	txrate.count = bf->rates[0].count;
> +
>  	ret = ah->ah_setup_tx_desc(ah, ds, pktlen,
>  		ieee80211_get_hdrlen_from_skb(skb), padsize,
>  		get_hw_packet_type(skb),
>  		(ah->ah_txpower.txp_requested * 2),
>  		hw_rate,
> -		info->control.rates[0].count, keyidx, ah->ah_tx_ant, flags,
> +		txrate.count, keyidx, ah->ah_tx_ant, flags,
>  		cts_rate, duration);
>  	if (ret)
>  		goto err_unmap;
The txrate variable is pointless, you only use txrate.count where you
could also just use bf->rates[0].count directly.

- Felix

^ permalink raw reply

* [PATCH] wil6210: Fix AP/PCP start flow
From: Kirshenbaum Erez @ 2013-06-06  8:35 UTC (permalink / raw)
  To: qca_vkondrat; +Cc: linux-wireless, Kirshenbaum Erez


Signed-off-by: Kirshenbaum Erez <erezk@wilocity.com>
---
 drivers/net/wireless/ath/wil6210/main.c | 35 ---------------------------------
 1 file changed, 35 deletions(-)

diff --git a/drivers/net/wireless/ath/wil6210/main.c b/drivers/net/wireless/ath/wil6210/main.c
index c97b864..271ee22 100644
--- a/drivers/net/wireless/ath/wil6210/main.c
+++ b/drivers/net/wireless/ath/wil6210/main.c
@@ -286,41 +286,31 @@ static int __wil_up(struct wil6210_priv *wil)
 {
 	struct net_device *ndev = wil_to_ndev(wil);
 	struct wireless_dev *wdev = wil->wdev;
-	struct ieee80211_channel *channel = wdev->preset_chandef.chan;
 	int rc;
-	int bi;
-	u16 wmi_nettype = wil_iftype_nl2wmi(wdev->iftype);
 
 	rc = wil_reset(wil);
 	if (rc)
 		return rc;
 
-	/* FIXME Firmware works now in PBSS mode(ToDS=0, FromDS=0) */
-	wmi_nettype = wil_iftype_nl2wmi(NL80211_IFTYPE_ADHOC);
 	switch (wdev->iftype) {
 	case NL80211_IFTYPE_STATION:
 		wil_dbg_misc(wil, "type: STATION\n");
-		bi = 0;
 		ndev->type = ARPHRD_ETHER;
 		break;
 	case NL80211_IFTYPE_AP:
 		wil_dbg_misc(wil, "type: AP\n");
-		bi = 100;
 		ndev->type = ARPHRD_ETHER;
 		break;
 	case NL80211_IFTYPE_P2P_CLIENT:
 		wil_dbg_misc(wil, "type: P2P_CLIENT\n");
-		bi = 0;
 		ndev->type = ARPHRD_ETHER;
 		break;
 	case NL80211_IFTYPE_P2P_GO:
 		wil_dbg_misc(wil, "type: P2P_GO\n");
-		bi = 100;
 		ndev->type = ARPHRD_ETHER;
 		break;
 	case NL80211_IFTYPE_MONITOR:
 		wil_dbg_misc(wil, "type: Monitor\n");
-		bi = 0;
 		ndev->type = ARPHRD_IEEE80211_RADIOTAP;
 		/* ARPHRD_IEEE80211 or ARPHRD_IEEE80211_RADIOTAP ? */
 		break;
@@ -328,34 +318,9 @@ static int __wil_up(struct wil6210_priv *wil)
 		return -EOPNOTSUPP;
 	}
 
-	/* Apply profile in the following order: */
-	/* SSID and channel for the AP */
-	switch (wdev->iftype) {
-	case NL80211_IFTYPE_AP:
-	case NL80211_IFTYPE_P2P_GO:
-		if (wdev->ssid_len == 0) {
-			wil_err(wil, "SSID not set\n");
-			return -EINVAL;
-		}
-		rc = wmi_set_ssid(wil, wdev->ssid_len, wdev->ssid);
-		if (rc)
-			return rc;
-		break;
-	default:
-		break;
-	}
-
 	/* MAC address - pre-requisite for other commands */
 	wmi_set_mac_address(wil, ndev->dev_addr);
 
-	/* Set up beaconing if required. */
-	if (bi > 0) {
-		rc = wmi_pcp_start(wil, bi, wmi_nettype,
-				   (channel ? channel->hw_value : 0));
-		if (rc)
-			return rc;
-	}
-
 	/* Rx VRING. After MAC and beacon */
 	wil_rx_init(wil);
 
-- 
1.7.11.7


^ permalink raw reply related

* Re: [PATCH 1/2] net: wireless: wl1251: Use module_spi_driver macro
From: Sachin Kamat @ 2013-06-06  9:18 UTC (permalink / raw)
  To: linux-wireless; +Cc: linville, sachin.kamat
In-Reply-To: <1369822703-27769-1-git-send-email-sachin.kamat@linaro.org>

On 29 May 2013 15:48, Sachin Kamat <sachin.kamat@linaro.org> wrote:
> module_spi_driver() eliminates some boiler plate and makes code
> simpler.
>
> Signed-off-by: Sachin Kamat <sachin.kamat@linaro.org>
> ---
>  drivers/net/wireless/ti/wl1251/spi.c |   24 +-----------------------
>  1 file changed, 1 insertion(+), 23 deletions(-)
>
> diff --git a/drivers/net/wireless/ti/wl1251/spi.c b/drivers/net/wireless/ti/wl1251/spi.c
> index 4c67c2f..dfd0877 100644
> --- a/drivers/net/wireless/ti/wl1251/spi.c
> +++ b/drivers/net/wireless/ti/wl1251/spi.c
> @@ -329,29 +329,7 @@ static struct spi_driver wl1251_spi_driver = {
>         .remove         = wl1251_spi_remove,
>  };
>
> -static int __init wl1251_spi_init(void)
> -{
> -       int ret;
> -
> -       ret = spi_register_driver(&wl1251_spi_driver);
> -       if (ret < 0) {
> -               wl1251_error("failed to register spi driver: %d", ret);
> -               goto out;
> -       }
> -
> -out:
> -       return ret;
> -}
> -
> -static void __exit wl1251_spi_exit(void)
> -{
> -       spi_unregister_driver(&wl1251_spi_driver);
> -
> -       wl1251_notice("unloaded");
> -}
> -
> -module_init(wl1251_spi_init);
> -module_exit(wl1251_spi_exit);
> +module_spi_driver(wl1251_spi_driver);
>
>  MODULE_LICENSE("GPL");
>  MODULE_AUTHOR("Kalle Valo <kvalo@adurom.com>");
> --
> 1.7.9.5
>

Gentle ping on this series John.

-- 
With warm regards,
Sachin

^ permalink raw reply

* [PATCH] ath5k: make use of the new rate control API
From: Thomas Huehn @ 2013-06-06  9:04 UTC (permalink / raw)
  To: linville
  Cc: linux-wireless, nbd, johannes, mickflemm, mcgrof, rmanohar,
	adrian, ath5k-devel, bvahl

This patch enabels ath5k to use the new rate table to lookup each
mrr rate and retry information per packet.

Signed-off-by: Benjamin Vahl <bvahl@net.t-labs.tu-berlin.de>
Signed-off-by: Thomas Huehn <thomas@net.t-labs.tu-berlin.de>
---
 drivers/net/wireless/ath/ath5k/base.c         |   73 +++++++++++++++++++++----
 drivers/net/wireless/ath/ath5k/base.h         |   14 +++--
 drivers/net/wireless/ath/ath5k/mac80211-ops.c |    2 +-
 3 files changed, 70 insertions(+), 19 deletions(-)

diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c
index 7f702fe..d447b6d 100644
--- a/drivers/net/wireless/ath/ath5k/base.c
+++ b/drivers/net/wireless/ath/ath5k/base.c
@@ -60,6 +60,7 @@
 
 #include <asm/unaligned.h>
 
+#include <net/mac80211.h>
 #include "base.h"
 #include "reg.h"
 #include "debug.h"
@@ -666,15 +667,53 @@ static enum ath5k_pkt_type get_hw_packet_type(struct sk_buff *skb)
 	return htype;
 }
 
+static struct ieee80211_rate *
+ath5k_get_rate(const struct ieee80211_hw *hw,
+	       const struct ieee80211_tx_info *info,
+	       struct ath5k_buf *bf, int idx)
+{
+	/*
+	* convert a ieee80211_tx_rate RC-table entry to
+	* the respective ieee80211_rate struct
+	*/
+	if (bf->rates[idx].idx < 0) {
+		return NULL;
+	}
+
+	return &hw->wiphy->bands[info->band]->bitrates[ bf->rates[idx].idx ];
+}
+
+static u16
+ath5k_get_rate_hw_value(const struct ieee80211_hw *hw,
+			const struct ieee80211_tx_info *info,
+			struct ath5k_buf *bf, int idx)
+{
+	struct ieee80211_rate *rate;
+	u16 hw_rate;
+	u8 rc_flags;
+
+	rate = ath5k_get_rate(hw, info, bf, idx);
+	if (!rate)
+		return 0;
+
+	rc_flags = bf->rates[idx].flags;
+	hw_rate = (rc_flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE) ?
+		   rate->hw_value_short : rate->hw_value;
+
+	return hw_rate;
+}
+
 static int
 ath5k_txbuf_setup(struct ath5k_hw *ah, struct ath5k_buf *bf,
-		  struct ath5k_txq *txq, int padsize)
+		  struct ath5k_txq *txq, int padsize,
+		  struct ieee80211_tx_control *control)
 {
 	struct ath5k_desc *ds = bf->desc;
 	struct sk_buff *skb = bf->skb;
 	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
 	unsigned int pktlen, flags, keyidx = AR5K_TXKEYIX_INVALID;
 	struct ieee80211_rate *rate;
+	struct ieee80211_tx_rate txrate;
 	unsigned int mrr_rate[3], mrr_tries[3];
 	int i, ret;
 	u16 hw_rate;
@@ -688,7 +727,11 @@ ath5k_txbuf_setup(struct ath5k_hw *ah, struct ath5k_buf *bf,
 	bf->skbaddr = dma_map_single(ah->dev, skb->data, skb->len,
 			DMA_TO_DEVICE);
 
-	rate = ieee80211_get_tx_rate(ah->hw, info);
+	ieee80211_get_tx_rates(info->control.vif, (control) ? control->sta : NULL, skb, bf->rates,
+			       ARRAY_SIZE(bf->rates));
+
+	rate = ath5k_get_rate(ah->hw, info, bf, 0);
+
 	if (!rate) {
 		ret = -EINVAL;
 		goto err_unmap;
@@ -698,8 +741,8 @@ ath5k_txbuf_setup(struct ath5k_hw *ah, struct ath5k_buf *bf,
 		flags |= AR5K_TXDESC_NOACK;
 
 	rc_flags = info->control.rates[0].flags;
-	hw_rate = (rc_flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE) ?
-		rate->hw_value_short : rate->hw_value;
+
+	hw_rate = ath5k_get_rate_hw_value(ah->hw, info, bf, 0);
 
 	pktlen = skb->len;
 
@@ -722,12 +765,15 @@ ath5k_txbuf_setup(struct ath5k_hw *ah, struct ath5k_buf *bf,
 		duration = le16_to_cpu(ieee80211_ctstoself_duration(ah->hw,
 			info->control.vif, pktlen, info));
 	}
+
+	txrate.count = bf->rates[0].count;
+
 	ret = ah->ah_setup_tx_desc(ah, ds, pktlen,
 		ieee80211_get_hdrlen_from_skb(skb), padsize,
 		get_hw_packet_type(skb),
 		(ah->ah_txpower.txp_requested * 2),
 		hw_rate,
-		info->control.rates[0].count, keyidx, ah->ah_tx_ant, flags,
+		txrate.count, keyidx, ah->ah_tx_ant, flags,
 		cts_rate, duration);
 	if (ret)
 		goto err_unmap;
@@ -736,13 +782,15 @@ ath5k_txbuf_setup(struct ath5k_hw *ah, struct ath5k_buf *bf,
 	if (ah->ah_capabilities.cap_has_mrr_support) {
 		memset(mrr_rate, 0, sizeof(mrr_rate));
 		memset(mrr_tries, 0, sizeof(mrr_tries));
+
 		for (i = 0; i < 3; i++) {
-			rate = ieee80211_get_alt_retry_rate(ah->hw, info, i);
+
+			rate = ath5k_get_rate(ah->hw, info, bf, i);
 			if (!rate)
 				break;
 
-			mrr_rate[i] = rate->hw_value;
-			mrr_tries[i] = info->control.rates[i + 1].count;
+			mrr_rate[i] = ath5k_get_rate_hw_value(ah->hw, info, bf, i);
+			mrr_tries[i] = bf->rates[i].count;
 		}
 
 		ath5k_hw_setup_mrr_tx_desc(ah, ds,
@@ -1515,7 +1563,7 @@ unlock:
 
 void
 ath5k_tx_queue(struct ieee80211_hw *hw, struct sk_buff *skb,
-	       struct ath5k_txq *txq)
+	       struct ath5k_txq *txq, struct ieee80211_tx_control *control)
 {
 	struct ath5k_hw *ah = hw->priv;
 	struct ath5k_buf *bf;
@@ -1555,7 +1603,7 @@ ath5k_tx_queue(struct ieee80211_hw *hw, struct sk_buff *skb,
 
 	bf->skb = skb;
 
-	if (ath5k_txbuf_setup(ah, bf, txq, padsize)) {
+	if (ath5k_txbuf_setup(ah, bf, txq, padsize, control)) {
 		bf->skb = NULL;
 		spin_lock_irqsave(&ah->txbuflock, flags);
 		list_add_tail(&bf->list, &ah->txbuf);
@@ -1917,7 +1965,7 @@ ath5k_beacon_send(struct ath5k_hw *ah)
 
 	skb = ieee80211_get_buffered_bc(ah->hw, vif);
 	while (skb) {
-		ath5k_tx_queue(ah->hw, skb, ah->cabq);
+		ath5k_tx_queue(ah->hw, skb, ah->cabq, NULL);
 
 		if (ah->cabq->txq_len >= ah->cabq->txq_max)
 			break;
@@ -2442,7 +2490,8 @@ ath5k_init_ah(struct ath5k_hw *ah, const struct ath_bus_ops *bus_ops)
 			IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
 			IEEE80211_HW_SIGNAL_DBM |
 			IEEE80211_HW_MFP_CAPABLE |
-			IEEE80211_HW_REPORTS_TX_ACK_STATUS;
+			IEEE80211_HW_REPORTS_TX_ACK_STATUS |
+			IEEE80211_HW_SUPPORTS_RC_TABLE;
 
 	hw->wiphy->interface_modes =
 		BIT(NL80211_IFTYPE_AP) |
diff --git a/drivers/net/wireless/ath/ath5k/base.h b/drivers/net/wireless/ath/ath5k/base.h
index 6c94c7f..ca9a83c 100644
--- a/drivers/net/wireless/ath/ath5k/base.h
+++ b/drivers/net/wireless/ath/ath5k/base.h
@@ -47,6 +47,7 @@ struct ath5k_hw;
 struct ath5k_txq;
 struct ieee80211_channel;
 struct ath_bus_ops;
+struct ieee80211_tx_control;
 enum nl80211_iftype;
 
 enum ath5k_srev_type {
@@ -61,11 +62,12 @@ struct ath5k_srev_name {
 };
 
 struct ath5k_buf {
-	struct list_head	list;
-	struct ath5k_desc	*desc;	/* virtual addr of desc */
-	dma_addr_t		daddr;	/* physical addr of desc */
-	struct sk_buff		*skb;	/* skbuff for buf */
-	dma_addr_t		skbaddr;/* physical addr of skb data */
+	struct list_head		list;
+	struct ath5k_desc		*desc;		/* virtual addr of desc */
+	dma_addr_t			daddr;		/* physical addr of desc */
+	struct sk_buff			*skb;		/* skbuff for buf */
+	dma_addr_t			skbaddr;	/* physical addr of skb data */
+	struct ieee80211_tx_rate	rates[4];	/* number of multi-rate stages */
 };
 
 struct ath5k_vif {
@@ -103,7 +105,7 @@ int ath5k_chan_set(struct ath5k_hw *ah, struct ieee80211_channel *chan);
 void ath5k_txbuf_free_skb(struct ath5k_hw *ah, struct ath5k_buf *bf);
 void ath5k_rxbuf_free_skb(struct ath5k_hw *ah, struct ath5k_buf *bf);
 void ath5k_tx_queue(struct ieee80211_hw *hw, struct sk_buff *skb,
-		    struct ath5k_txq *txq);
+		    struct ath5k_txq *txq, struct ieee80211_tx_control *control);
 
 const char *ath5k_chip_name(enum ath5k_srev_type type, u_int16_t val);
 
diff --git a/drivers/net/wireless/ath/ath5k/mac80211-ops.c b/drivers/net/wireless/ath/ath5k/mac80211-ops.c
index 06f86f4..81b686c 100644
--- a/drivers/net/wireless/ath/ath5k/mac80211-ops.c
+++ b/drivers/net/wireless/ath/ath5k/mac80211-ops.c
@@ -66,7 +66,7 @@ ath5k_tx(struct ieee80211_hw *hw, struct ieee80211_tx_control *control,
 		return;
 	}
 
-	ath5k_tx_queue(hw, skb, &ah->txqs[qnum]);
+	ath5k_tx_queue(hw, skb, &ah->txqs[qnum], control);
 }
 
 
-- 
1.7.9.5


^ permalink raw reply related

* Re: carl9170:5/10 MHz Channel Support on carl9170
From: C.B. Wang @ 2013-06-06  9:05 UTC (permalink / raw)
  To: Oleksij Rempel; +Cc: Adrian Chadd, Christian Lamparter, linux-wireless
In-Reply-To: <51B04585.9020108@gmx.net>

>> True, but again look at the vendor driver. I think it should
>> be very easy to implement "set coverage class". The slot time
>> can be set by "AR9170_MAC_REG_SLOT_TIME" register and the ack
>> timeout should be in "AR9170_MAC_REG_ACK_EXTENSION". That's
>> all the information I have. So what are you waiting for

In addition to what you have said above,can we also make longer range
communication
possible by sacrificing data rates and using 5/10 MHz narrow channels
which is Atheros's
extended range(xr) technology?


On 6/6/13, Oleksij Rempel <fishor@gmx.net> wrote:
> Am 06.06.2013 10:07, schrieb C.B. Wang:
>> Spectral analysis isn't supported by any Atheros USB chipsets,is it?
>
> ar7010 devices theoretically should support it.
>
>> The 802.11j standard defines 10mhz operation.I think it is mandatory.
>> You can get a copy here
>> http://www.it.iitb.ac.in/~mukesh/dokuwiki/lib/exe/fetch.php?cache=cache&media=mtp:802.11j-2004.pdf
>>
>> No,I don't know any.Most devices that use ZyDaS chipset are b/g
>> soloution.
>> It's rare even to see an a/b/g ZyDaS device.
>>
>> Channel 183(4815mhz),185(4925mhz),187(4935mhz),189(4945mhz) should also
>> be added to the channel list of carl9170 driver.
>>
>
>
>

^ permalink raw reply

* [PATCH] brcmfmac: Turn off ARP offloading when configured for AP.
From: Arend van Spriel @ 2013-06-06  8:55 UTC (permalink / raw)
  To: stable; +Cc: linux-wireless, Hante Meuleman, Arend van Spriel,
	John W. Linville

From: Hante Meuleman <meuleman@broadcom.com>

[backport of upstream commit b3657453f16a7b84eab9b93bb9a9a2901ffc70af]

ARP offloading should only be used in STA or P2P client mode. It
is currently configured once at init. When being configured for AP
ARP offloading should be turned off and when AP mode is left it can
be turned back on.

Reviewed-by: Arend Van Spriel <arend@broadcom.com>
Signed-off-by: Hante Meuleman <meuleman@broadcom.com>
Signed-off-by: Arend van Spriel <arend@broadcom.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Signed-off-by: Arend van Spriel <arend@broadcom.com>
---
 .../net/wireless/brcm80211/brcmfmac/dhd_common.c   |   18 ---------
 .../net/wireless/brcm80211/brcmfmac/fwil_types.h   |    6 +++
 .../net/wireless/brcm80211/brcmfmac/wl_cfg80211.c  |   40 +++++++++++++++++++-
 3 files changed, 45 insertions(+), 19 deletions(-)

diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c
index 4544342..9480e19 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c
@@ -26,7 +26,6 @@
 #include "fwil.h"
 
 #define PKTFILTER_BUF_SIZE		128
-#define BRCMF_ARPOL_MODE		0xb	/* agent|snoop|peer_autoreply */
 #define BRCMF_DEFAULT_BCN_TIMEOUT	3
 #define BRCMF_DEFAULT_SCAN_CHANNEL_TIME	40
 #define BRCMF_DEFAULT_SCAN_UNASSOC_TIME	40
@@ -337,23 +336,6 @@ int brcmf_c_preinit_dcmds(struct brcmf_if *ifp)
 		goto done;
 	}
 
-	/* Try to set and enable ARP offload feature, this may fail */
-	err = brcmf_fil_iovar_int_set(ifp, "arp_ol", BRCMF_ARPOL_MODE);
-	if (err) {
-		brcmf_dbg(TRACE, "failed to set ARP offload mode to 0x%x, err = %d\n",
-			  BRCMF_ARPOL_MODE, err);
-		err = 0;
-	} else {
-		err = brcmf_fil_iovar_int_set(ifp, "arpoe", 1);
-		if (err) {
-			brcmf_dbg(TRACE, "failed to enable ARP offload err = %d\n",
-				  err);
-			err = 0;
-		} else
-			brcmf_dbg(TRACE, "successfully enabled ARP offload to 0x%x\n",
-				  BRCMF_ARPOL_MODE);
-	}
-
 	/* Setup packet filter */
 	brcmf_c_pktfilter_offload_set(ifp, BRCMF_DEFAULT_PACKET_FILTER);
 	brcmf_c_pktfilter_offload_enable(ifp, BRCMF_DEFAULT_PACKET_FILTER,
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/fwil_types.h b/drivers/net/wireless/brcm80211/brcmfmac/fwil_types.h
index 0f2c83b..665ef69 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/fwil_types.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/fwil_types.h
@@ -23,6 +23,12 @@
 
 #define BRCMF_FIL_ACTION_FRAME_SIZE	1800
 
+/* ARP Offload feature flags for arp_ol iovar */
+#define BRCMF_ARP_OL_AGENT		0x00000001
+#define BRCMF_ARP_OL_SNOOP		0x00000002
+#define BRCMF_ARP_OL_HOST_AUTO_REPLY	0x00000004
+#define BRCMF_ARP_OL_PEER_AUTO_REPLY	0x00000008
+
 
 enum brcmf_fil_p2p_if_types {
 	BRCMF_FIL_P2P_IF_CLIENT,
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
index 78da3ef..d5c4e24 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
@@ -505,6 +505,38 @@ send_key_to_dongle(struct net_device *ndev, struct brcmf_wsec_key *key)
 	return err;
 }
 
+static s32
+brcmf_configure_arp_offload(struct brcmf_if *ifp, bool enable)
+{
+	s32 err;
+	u32 mode;
+
+	if (enable)
+		mode = BRCMF_ARP_OL_AGENT | BRCMF_ARP_OL_PEER_AUTO_REPLY;
+	else
+		mode = 0;
+
+	/* Try to set and enable ARP offload feature, this may fail, then it  */
+	/* is simply not supported and err 0 will be returned                 */
+	err = brcmf_fil_iovar_int_set(ifp, "arp_ol", mode);
+	if (err) {
+		brcmf_dbg(TRACE, "failed to set ARP offload mode to 0x%x, err = %d\n",
+			  mode, err);
+		err = 0;
+	} else {
+		err = brcmf_fil_iovar_int_set(ifp, "arpoe", enable);
+		if (err) {
+			brcmf_dbg(TRACE, "failed to configure (%d) ARP offload err = %d\n",
+				  enable, err);
+			err = 0;
+		} else
+			brcmf_dbg(TRACE, "successfully configured (%d) ARP offload to 0x%x\n",
+				  enable, mode);
+	}
+
+	return err;
+}
+
 static struct wireless_dev *brcmf_cfg80211_add_iface(struct wiphy *wiphy,
 						     const char *name,
 						     enum nl80211_iftype type,
@@ -3709,6 +3741,7 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
 	}
 
 	brcmf_set_mpc(ndev, 0);
+	brcmf_configure_arp_offload(ifp, false);
 
 	/* find the RSN_IE */
 	rsn_ie = brcmf_parse_tlvs((u8 *)settings->beacon.tail,
@@ -3815,8 +3848,10 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
 	set_bit(BRCMF_VIF_STATUS_AP_CREATED, &ifp->vif->sme_state);
 
 exit:
-	if (err)
+	if (err) {
 		brcmf_set_mpc(ndev, 1);
+		brcmf_configure_arp_offload(ifp, true);
+	}
 	return err;
 }
 
@@ -3857,6 +3892,7 @@ static int brcmf_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *ndev)
 			brcmf_err("bss_enable config failed %d\n", err);
 	}
 	brcmf_set_mpc(ndev, 1);
+	brcmf_configure_arp_offload(ifp, true);
 	set_bit(BRCMF_VIF_STATUS_AP_CREATING, &ifp->vif->sme_state);
 	clear_bit(BRCMF_VIF_STATUS_AP_CREATED, &ifp->vif->sme_state);
 
@@ -4995,6 +5031,8 @@ static s32 brcmf_config_dongle(struct brcmf_cfg80211_info *cfg)
 	if (err)
 		goto default_conf_out;
 
+	brcmf_configure_arp_offload(ifp, true);
+
 	cfg->dongle_up = true;
 default_conf_out:
 
-- 
1.7.10.4



^ permalink raw reply related

* Re: carl9170:5/10 MHz Channel Support on carl9170
From: Oleksij Rempel @ 2013-06-06  8:17 UTC (permalink / raw)
  To: C.B. Wang; +Cc: Adrian Chadd, Christian Lamparter, linux-wireless
In-Reply-To: <CAB-Tk7273qtgA0J-rvpFxNbMDErmXVdknybVOJmUTa73VhL1Cw@mail.gmail.com>

Am 06.06.2013 10:07, schrieb C.B. Wang:
> Spectral analysis isn't supported by any Atheros USB chipsets,is it?

ar7010 devices theoretically should support it.

> The 802.11j standard defines 10mhz operation.I think it is mandatory.
> You can get a copy here
> http://www.it.iitb.ac.in/~mukesh/dokuwiki/lib/exe/fetch.php?cache=cache&media=mtp:802.11j-2004.pdf
>
> No,I don't know any.Most devices that use ZyDaS chipset are b/g soloution.
> It's rare even to see an a/b/g ZyDaS device.
>
> Channel 183(4815mhz),185(4925mhz),187(4935mhz),189(4945mhz) should also
> be added to the channel list of carl9170 driver.
>



^ permalink raw reply

* Re: carl9170:5/10 MHz Channel Support on carl9170
From: C.B. Wang @ 2013-06-06  8:07 UTC (permalink / raw)
  To: Adrian Chadd; +Cc: Christian Lamparter, linux-wireless
In-Reply-To: <CAJ-Vmom6cmf-c-TJs5s9AvT953m0+tANVj_AxnSYwUCzegyPWQ@mail.gmail.com>

Spectral analysis isn't supported by any Atheros USB chipsets,is it?

The 802.11j standard defines 10mhz operation.I think it is mandatory.
You can get a copy here
http://www.it.iitb.ac.in/~mukesh/dokuwiki/lib/exe/fetch.php?cache=cache&media=mtp:802.11j-2004.pdf

No,I don't know any.Most devices that use ZyDaS chipset are b/g soloution.
It's rare even to see an a/b/g ZyDaS device.

Channel 183(4815mhz),185(4925mhz),187(4935mhz),189(4945mhz) should also
be added to the channel list of carl9170 driver.


On 6/6/13, Adrian Chadd <adrian@freebsd.org> wrote:
> Oh cool! I'm glad they included a half/quarter rate clock change bit.
>
> Just make sure you test it with adjacent channel interference; it may
> underclock the MAC/PHY but that doesn't necessarily mean that the
> analog filter is being changed.
>
>
> Adrian
>
> On 5 June 2013 14:35, Christian Lamparter <chunkeey@googlemail.com> wrote:
>> Hello Adrian
>>
>> On Wednesday, June 05, 2013 08:08:14 PM Adrian Chadd wrote:
>>> I think that the zydas mac doesn't officially support 5/10mhz operation.
>> Just checked, it looks like the bandwidth control is very similar to
>> ath9k.
>>
>> The settings is controlled by Bit 3 and 2 in AR9170_PWR_REG_CLOCK_SEL
>> (0x1d4008)
>> 00 <-- default
>> 01 <-- half
>>
>> There's a new firmware branch for this new feature:
>> <https://github.com/chunkeey/carl9170fw/tree/halfandquarter>
>>
>> The patch for the carl9170 driver will come later... Once mac/nl/cfg80211
>> and userspace have support for the 5/10 MHz channel bandwidth.
>>
>> So, if you [(Mr.?) Wang] is interested, please help us testing
>> and integrating the stack patchset into the kernel - NOW -:
>> "Add support for 5 and 10 MHz channels"
>> <http://www.spinics.net/lists/linux-wireless/msg107116.html>
>>
>>> > I've read the "otus" vendor driver and found that in the source file
>>> > /HalPlus/OTUS_FB50/hpreg.h on
>>> > line 1915,the comment says "Temporary discard channel that BW < 20MHz
>>> > (5 or 10MHz)   */
>>> >                             /*   Our architecture does not implemnt
>>> > it"
>>> > I think either the driver does not implement the 5/10 channels or
>>> > worse,the ar9170 chip does not support 5/10 mhz channel at all.
>> I think "architecture" could be just the software. At least an
>> ath9k spectral analyzer confirmed that at least the PHY can operate
>> on 10 MHz channels in the 5GHz band.
>>
>>> > But 802.11j has 10mhz channel support.To comply with the 802.11j
>>> > standard,the chip should support 10mhz channel width.
>> Oh, I don't have a 802.11j copy handy, is it a mandatory or optional
>> feature?
>>
>>> > Also the ar9170 MAC was indeed designed by ZyDaS berfore
>>> > the company was taken over by Atheros.
>> Do you know any 5 GHz solution from ZyDaS that sold as 802.11j
>> compliant?
>>
>>> > It has some problems with long distance links.
>> True, but again look at the vendor driver. I think it should
>> be very easy to implement "set coverage class". The slot time
>> can be set by "AR9170_MAC_REG_SLOT_TIME" register and the ack
>> timeout should be in "AR9170_MAC_REG_ACK_EXTENSION". That's
>> all the information I have. So what are you waiting for ;)
>>
>> Regards,
>>         Chr
>

^ permalink raw reply

* [patch] cw1200: read beyond end of array in debug code
From: Dan Carpenter @ 2013-06-06  7:43 UTC (permalink / raw)
  To: Solomon Peachy; +Cc: John W. Linville, linux-wireless, kernel-janitors

This has only one caller and rates[] is an array with
IEEE80211_TX_MAX_RATES (4) elements.

Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>

diff --git a/drivers/net/wireless/cw1200/txrx.c b/drivers/net/wireless/cw1200/txrx.c
index 0e40890..a254747 100644
--- a/drivers/net/wireless/cw1200/txrx.c
+++ b/drivers/net/wireless/cw1200/txrx.c
@@ -190,13 +190,12 @@ static void tx_policy_build(const struct cw1200_common *priv,
 		policy->retry_count += retries;
 	}
 
-	pr_debug("[TX policy] Policy (%zu): %d:%d, %d:%d, %d:%d, %d:%d, %d:%d\n",
+	pr_debug("[TX policy] Policy (%zu): %d:%d, %d:%d, %d:%d, %d:%d\n",
 		 count,
 		 rates[0].idx, rates[0].count,
 		 rates[1].idx, rates[1].count,
 		 rates[2].idx, rates[2].count,
-		 rates[3].idx, rates[3].count,
-		 rates[4].idx, rates[4].count);
+		 rates[3].idx, rates[3].count);
 }
 
 static inline bool tx_policy_is_equal(const struct tx_policy *wanted,

^ permalink raw reply related

* [PATCH v2 2/2] rt2x00: rt2800usb: nuke rt2800usb_ops_5592
From: Gabor Juhos @ 2013-06-06  7:36 UTC (permalink / raw)
  To: John Linville; +Cc: linux-wireless, users, Gabor Juhos
In-Reply-To: <1370504180-10950-1-git-send-email-juhosg@openwrt.org>

It is exactly the same like the generic rt2800usb_ops.
Remove the duplicate and use the generic ops for all
devices.

Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
---
 drivers/net/wireless/rt2x00/rt2800usb.c |   29 +++++------------------------
 1 file changed, 5 insertions(+), 24 deletions(-)

diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c
index 68ea00e..7edd903 100644
--- a/drivers/net/wireless/rt2x00/rt2800usb.c
+++ b/drivers/net/wireless/rt2x00/rt2800usb.c
@@ -914,22 +914,6 @@ static const struct rt2x00_ops rt2800usb_ops = {
 #endif /* CONFIG_RT2X00_LIB_DEBUGFS */
 };
 
-static const struct rt2x00_ops rt2800usb_ops_5592 = {
-	.name			= KBUILD_MODNAME,
-	.drv_data_size		= sizeof(struct rt2800_drv_data),
-	.max_ap_intf		= 8,
-	.eeprom_size		= EEPROM_SIZE,
-	.rf_size		= RF_SIZE,
-	.tx_queues		= NUM_TX_QUEUES,
-	.queue_init		= rt2800usb_queue_init,
-	.lib			= &rt2800usb_rt2x00_ops,
-	.drv			= &rt2800usb_rt2800_ops,
-	.hw			= &rt2800usb_mac80211_ops,
-#ifdef CONFIG_RT2X00_LIB_DEBUGFS
-	.debugfs		= &rt2800_rt2x00debug,
-#endif /* CONFIG_RT2X00_LIB_DEBUGFS */
-};
-
 /*
  * rt2800usb module information.
  */
@@ -1242,15 +1226,15 @@ static struct usb_device_id rt2800usb_device_table[] = {
 #endif
 #ifdef CONFIG_RT2800USB_RT55XX
 	/* Arcadyan */
-	{ USB_DEVICE(0x043e, 0x7a32), .driver_info = 5592 },
+	{ USB_DEVICE(0x043e, 0x7a32) },
 	/* AVM GmbH */
-	{ USB_DEVICE(0x057c, 0x8501), .driver_info = 5592 },
+	{ USB_DEVICE(0x057c, 0x8501) },
 	/* D-Link DWA-160-B2 */
-	{ USB_DEVICE(0x2001, 0x3c1a), .driver_info = 5592 },
+	{ USB_DEVICE(0x2001, 0x3c1a) },
 	/* Proware */
-	{ USB_DEVICE(0x043e, 0x7a13), .driver_info = 5592 },
+	{ USB_DEVICE(0x043e, 0x7a13) },
 	/* Ralink */
-	{ USB_DEVICE(0x148f, 0x5572), .driver_info = 5592 },
+	{ USB_DEVICE(0x148f, 0x5572) },
 #endif
 #ifdef CONFIG_RT2800USB_UNKNOWN
 	/*
@@ -1355,9 +1339,6 @@ MODULE_LICENSE("GPL");
 static int rt2800usb_probe(struct usb_interface *usb_intf,
 			   const struct usb_device_id *id)
 {
-	if (id->driver_info == 5592)
-		return rt2x00usb_probe(usb_intf, &rt2800usb_ops_5592);
-
 	return rt2x00usb_probe(usb_intf, &rt2800usb_ops);
 }
 
-- 
1.7.10


^ permalink raw reply related

* [PATCH v2 1/2] rt2x00: move extra_tx_headroom field from rt2x00_ops to rt2x00_dev
From: Gabor Juhos @ 2013-06-06  7:36 UTC (permalink / raw)
  To: John Linville; +Cc: linux-wireless, users, Gabor Juhos

The extra_tx_headroom field of struct rt2x00_ops
indicates the extra TX headroom size required for
a given device. This data is redundant, the value
can be computed from the desc_size and winfo_size
fields of the TX queues.

Move the extra_tx_headroom field to struct rt2x00_dev,
compute its value in the probe routine and use the
cached value in the rest of the code.

Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
---
v2:
  - remove the callbacks and compute the extra_tx_headroom
    value from winfo_size and desc_size instead
  - change subject

The patch depends on the 'rt2x00: get rid of static data queue descriptors'
series.
---
 drivers/net/wireless/rt2x00/rt2400pci.c   |    1 -
 drivers/net/wireless/rt2x00/rt2500pci.c   |    1 -
 drivers/net/wireless/rt2x00/rt2500usb.c   |    1 -
 drivers/net/wireless/rt2x00/rt2800pci.c   |    1 -
 drivers/net/wireless/rt2x00/rt2800usb.c   |    2 --
 drivers/net/wireless/rt2x00/rt2x00.h      |    4 +++-
 drivers/net/wireless/rt2x00/rt2x00dev.c   |   18 ++++++++++++++++--
 drivers/net/wireless/rt2x00/rt2x00queue.c |    6 +++---
 drivers/net/wireless/rt2x00/rt61pci.c     |    1 -
 drivers/net/wireless/rt2x00/rt73usb.c     |    1 -
 10 files changed, 22 insertions(+), 14 deletions(-)

diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c
index e1ec9a4..3d53a09 100644
--- a/drivers/net/wireless/rt2x00/rt2400pci.c
+++ b/drivers/net/wireless/rt2x00/rt2400pci.c
@@ -1813,7 +1813,6 @@ static const struct rt2x00_ops rt2400pci_ops = {
 	.eeprom_size		= EEPROM_SIZE,
 	.rf_size		= RF_SIZE,
 	.tx_queues		= NUM_TX_QUEUES,
-	.extra_tx_headroom	= 0,
 	.queue_init		= rt2400pci_queue_init,
 	.lib			= &rt2400pci_rt2x00_ops,
 	.hw			= &rt2400pci_mac80211_ops,
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c
index a1670e8..0ac5c58 100644
--- a/drivers/net/wireless/rt2x00/rt2500pci.c
+++ b/drivers/net/wireless/rt2x00/rt2500pci.c
@@ -2102,7 +2102,6 @@ static const struct rt2x00_ops rt2500pci_ops = {
 	.eeprom_size		= EEPROM_SIZE,
 	.rf_size		= RF_SIZE,
 	.tx_queues		= NUM_TX_QUEUES,
-	.extra_tx_headroom	= 0,
 	.queue_init		= rt2500pci_queue_init,
 	.lib			= &rt2500pci_rt2x00_ops,
 	.hw			= &rt2500pci_mac80211_ops,
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c
index e5e5479..85acc79 100644
--- a/drivers/net/wireless/rt2x00/rt2500usb.c
+++ b/drivers/net/wireless/rt2x00/rt2500usb.c
@@ -1913,7 +1913,6 @@ static const struct rt2x00_ops rt2500usb_ops = {
 	.eeprom_size		= EEPROM_SIZE,
 	.rf_size		= RF_SIZE,
 	.tx_queues		= NUM_TX_QUEUES,
-	.extra_tx_headroom	= TXD_DESC_SIZE,
 	.queue_init		= rt2500usb_queue_init,
 	.lib			= &rt2500usb_rt2x00_ops,
 	.hw			= &rt2500usb_mac80211_ops,
diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c
index 260c8b4..7c74782 100644
--- a/drivers/net/wireless/rt2x00/rt2800pci.c
+++ b/drivers/net/wireless/rt2x00/rt2800pci.c
@@ -1231,7 +1231,6 @@ static const struct rt2x00_ops rt2800pci_ops = {
 	.eeprom_size		= EEPROM_SIZE,
 	.rf_size		= RF_SIZE,
 	.tx_queues		= NUM_TX_QUEUES,
-	.extra_tx_headroom	= TXWI_DESC_SIZE,
 	.queue_init		= rt2800pci_queue_init,
 	.lib			= &rt2800pci_rt2x00_ops,
 	.drv			= &rt2800pci_rt2800_ops,
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c
index b81d509..68ea00e 100644
--- a/drivers/net/wireless/rt2x00/rt2800usb.c
+++ b/drivers/net/wireless/rt2x00/rt2800usb.c
@@ -905,7 +905,6 @@ static const struct rt2x00_ops rt2800usb_ops = {
 	.eeprom_size		= EEPROM_SIZE,
 	.rf_size		= RF_SIZE,
 	.tx_queues		= NUM_TX_QUEUES,
-	.extra_tx_headroom	= TXINFO_DESC_SIZE + TXWI_DESC_SIZE,
 	.queue_init		= rt2800usb_queue_init,
 	.lib			= &rt2800usb_rt2x00_ops,
 	.drv			= &rt2800usb_rt2800_ops,
@@ -922,7 +921,6 @@ static const struct rt2x00_ops rt2800usb_ops_5592 = {
 	.eeprom_size		= EEPROM_SIZE,
 	.rf_size		= RF_SIZE,
 	.tx_queues		= NUM_TX_QUEUES,
-	.extra_tx_headroom	= TXINFO_DESC_SIZE + TXWI_DESC_SIZE_5592,
 	.queue_init		= rt2800usb_queue_init,
 	.lib			= &rt2800usb_rt2x00_ops,
 	.drv			= &rt2800usb_rt2800_ops,
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h
index 2a17f7e..ee3fc57 100644
--- a/drivers/net/wireless/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/rt2x00/rt2x00.h
@@ -648,7 +648,6 @@ struct rt2x00_ops {
 	const unsigned int eeprom_size;
 	const unsigned int rf_size;
 	const unsigned int tx_queues;
-	const unsigned int extra_tx_headroom;
 	void (*queue_init)(struct data_queue *queue);
 	const struct rt2x00lib_ops *lib;
 	const void *drv;
@@ -1007,6 +1006,9 @@ struct rt2x00_dev {
 	 */
 	struct list_head bar_list;
 	spinlock_t bar_list_lock;
+
+	/* Extra TX headroom required for alignment purposes. */
+	unsigned int extra_tx_headroom;
 };
 
 struct rt2x00_bar_list_entry {
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c
index dff5012..f03e3bb 100644
--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
@@ -334,7 +334,7 @@ void rt2x00lib_txdone(struct queue_entry *entry,
 	/*
 	 * Remove the extra tx headroom from the skb.
 	 */
-	skb_pull(entry->skb, rt2x00dev->ops->extra_tx_headroom);
+	skb_pull(entry->skb, rt2x00dev->extra_tx_headroom);
 
 	/*
 	 * Signal that the TX descriptor is no longer in the skb.
@@ -1049,7 +1049,7 @@ static int rt2x00lib_probe_hw(struct rt2x00_dev *rt2x00dev)
 	 */
 	rt2x00dev->hw->extra_tx_headroom =
 		max_t(unsigned int, IEEE80211_TX_STATUS_HEADROOM,
-		      rt2x00dev->ops->extra_tx_headroom);
+		      rt2x00dev->extra_tx_headroom);
 
 	/*
 	 * Take TX headroom required for alignment into account.
@@ -1256,6 +1256,17 @@ static inline void rt2x00lib_set_if_combinations(struct rt2x00_dev *rt2x00dev)
 	rt2x00dev->hw->wiphy->n_iface_combinations = 1;
 }
 
+static unsigned int rt2x00dev_extra_tx_headroom(struct rt2x00_dev *rt2x00dev)
+{
+	if (WARN_ON(!rt2x00dev->tx))
+		return 0;
+
+	if (rt2x00_is_usb(rt2x00dev))
+		return rt2x00dev->tx[0].winfo_size + rt2x00dev->tx[0].desc_size;
+
+	return rt2x00dev->tx[0].winfo_size;
+}
+
 /*
  * driver allocation handlers.
  */
@@ -1330,6 +1341,9 @@ int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev)
 	if (retval)
 		goto exit;
 
+	/* Cache TX headroom value */
+	rt2x00dev->extra_tx_headroom = rt2x00dev_extra_tx_headroom(rt2x00dev);
+
 	/*
 	 * Determine which operating modes are supported, all modes
 	 * which require beaconing, depend on the availability of
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c
index c4f1e2b..6c0a91f 100644
--- a/drivers/net/wireless/rt2x00/rt2x00queue.c
+++ b/drivers/net/wireless/rt2x00/rt2x00queue.c
@@ -542,8 +542,8 @@ static int rt2x00queue_write_tx_data(struct queue_entry *entry,
 	/*
 	 * Add the requested extra tx headroom in front of the skb.
 	 */
-	skb_push(entry->skb, rt2x00dev->ops->extra_tx_headroom);
-	memset(entry->skb->data, 0, rt2x00dev->ops->extra_tx_headroom);
+	skb_push(entry->skb, rt2x00dev->extra_tx_headroom);
+	memset(entry->skb->data, 0, rt2x00dev->extra_tx_headroom);
 
 	/*
 	 * Call the driver's write_tx_data function, if it exists.
@@ -596,7 +596,7 @@ static void rt2x00queue_bar_check(struct queue_entry *entry)
 {
 	struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
 	struct ieee80211_bar *bar = (void *) (entry->skb->data +
-				    rt2x00dev->ops->extra_tx_headroom);
+				    rt2x00dev->extra_tx_headroom);
 	struct rt2x00_bar_list_entry *bar_entry;
 
 	if (likely(!ieee80211_is_back_req(bar->frame_control)))
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c
index 17507d1..53754bc6 100644
--- a/drivers/net/wireless/rt2x00/rt61pci.c
+++ b/drivers/net/wireless/rt2x00/rt61pci.c
@@ -3066,7 +3066,6 @@ static const struct rt2x00_ops rt61pci_ops = {
 	.eeprom_size		= EEPROM_SIZE,
 	.rf_size		= RF_SIZE,
 	.tx_queues		= NUM_TX_QUEUES,
-	.extra_tx_headroom	= 0,
 	.queue_init		= rt61pci_queue_init,
 	.lib			= &rt61pci_rt2x00_ops,
 	.hw			= &rt61pci_mac80211_ops,
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c
index b2e346a..1616ed4 100644
--- a/drivers/net/wireless/rt2x00/rt73usb.c
+++ b/drivers/net/wireless/rt2x00/rt73usb.c
@@ -2400,7 +2400,6 @@ static const struct rt2x00_ops rt73usb_ops = {
 	.eeprom_size		= EEPROM_SIZE,
 	.rf_size		= RF_SIZE,
 	.tx_queues		= NUM_TX_QUEUES,
-	.extra_tx_headroom	= TXD_DESC_SIZE,
 	.queue_init		= rt73usb_queue_init,
 	.lib			= &rt73usb_rt2x00_ops,
 	.hw			= &rt73usb_mac80211_ops,
-- 
1.7.10


^ permalink raw reply related

* Re: WLAN EAP methods verification.
From: Johannes Berg @ 2013-06-06  7:14 UTC (permalink / raw)
  To: Matt Chen; +Cc: linux-wireless, Michal Marek, oneukum, tiwai
In-Reply-To: <51B099FE0200009200022E0D@soto.provo.novell.com>

On Wed, 2013-06-05 at 22:17 -0600, Matt Chen wrote:

> I would like to ask if there is a policy or way to verify a WLAN
> driver in kernel such as ath9k, iwlwifi, rt2x00 or rtlwifi and so
> on ... pass all the EAP method [1] or WPA/WPA2 encryption ?

Not really. I think we all pretty much assume that once we support the
cipher algorithms (TKIP/CCMP) everything else works because it's
implemented in wpa_supplicant and the drivers don't have to do anything
but pass frames and eventually install keys.

The only driver where that's not true is the PS3 wifi driver ;-)

johannes


^ permalink raw reply


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