linux-wireless.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: "Arend van Spriel" <arend@broadcom.com>
To: "John W. Linville" <linville@tuxdriver.com>
Cc: linux-wireless <linux-wireless@vger.kernel.org>,
	"Hante Meuleman" <meuleman@broadcom.com>,
	"Arend van Spriel" <arend@broadcom.com>
Subject: [PATCH 18/22] brcmfmac: Always use fifo_credits, also for requested credits.
Date: Thu, 6 Jun 2013 13:18:03 +0200	[thread overview]
Message-ID: <1370517487-14395-19-git-send-email-arend@broadcom.com> (raw)
In-Reply-To: <1370517487-14395-1-git-send-email-arend@broadcom.com>

From: Hante Meuleman <meuleman@broadcom.com>

Currently firmware requested credits do not require fifo credits.
>From a buffer management point of view this is incorrect. So
firwmware requested credits require also fifo credits before the
packet can be transferred to the host.

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/dhd_dbg.c  |   10 +-
 drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h  |    3 +-
 drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c |  163 +++++++++-----------
 3 files changed, 79 insertions(+), 97 deletions(-)

diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.c
index 202869c..ce50686 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.c
@@ -179,11 +179,11 @@ ssize_t brcmf_debugfs_fws_stats_read(struct file *f, char __user *data,
 			fwstats->send_pkts[0], fwstats->send_pkts[1],
 			fwstats->send_pkts[2], fwstats->send_pkts[3],
 			fwstats->send_pkts[4],
-			fwstats->fifo_credits_sent[0],
-			fwstats->fifo_credits_sent[1],
-			fwstats->fifo_credits_sent[2],
-			fwstats->fifo_credits_sent[3],
-			fwstats->fifo_credits_sent[4]);
+			fwstats->requested_sent[0],
+			fwstats->requested_sent[1],
+			fwstats->requested_sent[2],
+			fwstats->requested_sent[3],
+			fwstats->requested_sent[4]);
 
 	return simple_read_from_buffer(data, count, ppos, buf, res);
 }
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h
index 009c87b..451ebac 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h
@@ -141,8 +141,7 @@ struct brcmf_fws_stats {
 	u32 header_pulls;
 	u32 pkt2bus;
 	u32 send_pkts[5];
-	u32 fifo_credits_sent[5];
-	u32 fifo_credits_back[6];
+	u32 requested_sent[5];
 	u32 generic_error;
 	u32 mac_update_failed;
 	u32 mac_ps_update_failed;
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
index 534507a..5d809c7 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
@@ -192,24 +192,21 @@ struct brcmf_skbuff_cb {
 /*
  * sk_buff control if flags
  *
- *	b[12]  - packet sent upon credit request.
- *	b[11]  - packet sent upon packet request.
+ *	b[11]  - packet sent upon firmware request.
  *	b[10]  - packet only contains signalling data.
  *	b[9]   - packet is a tx packet.
- *	b[8]   - packet uses FIFO credit (non-pspoll).
+ *	b[8]   - packet used requested credit
  *	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
 #define BRCMF_SKB_IF_FLAGS_SIGNAL_ONLY_SHIFT	10
 #define BRCMF_SKB_IF_FLAGS_TRANSMIT_MASK        0x0200
 #define BRCMF_SKB_IF_FLAGS_TRANSMIT_SHIFT	9
-#define BRCMF_SKB_IF_FLAGS_CREDITCHECK_MASK	0x0100
-#define BRCMF_SKB_IF_FLAGS_CREDITCHECK_SHIFT	8
+#define BRCMF_SKB_IF_FLAGS_REQ_CREDIT_MASK	0x0100
+#define BRCMF_SKB_IF_FLAGS_REQ_CREDIT_SHIFT	8
 #define BRCMF_SKB_IF_FLAGS_IF_AP_MASK		0x0080
 #define BRCMF_SKB_IF_FLAGS_IF_AP_SHIFT		7
 #define BRCMF_SKB_IF_FLAGS_INDEX_MASK		0x000f
@@ -311,12 +308,15 @@ enum brcmf_fws_fifo {
  *	firmware suppress the packet as device is already in PS mode.
  * @BRCMF_FWS_TXSTATUS_FW_TOSSED:
  *	firmware tossed the packet.
+ * @BRCMF_FWS_TXSTATUS_HOST_TOSSED:
+ *	host tossed the packet.
  */
 enum brcmf_fws_txstatus {
 	BRCMF_FWS_TXSTATUS_DISCARD,
 	BRCMF_FWS_TXSTATUS_CORE_SUPPRESS,
 	BRCMF_FWS_TXSTATUS_FW_PS_SUPPRESS,
-	BRCMF_FWS_TXSTATUS_FW_TOSSED
+	BRCMF_FWS_TXSTATUS_FW_TOSSED,
+	BRCMF_FWS_TXSTATUS_HOST_TOSSED
 };
 
 enum brcmf_fws_fcmode {
@@ -639,6 +639,7 @@ static void brcmf_fws_init_mac_descriptor(struct brcmf_fws_mac_descriptor *desc,
 	desc->occupied = 1;
 	desc->state = BRCMF_FWS_STATE_OPEN;
 	desc->requested_credit = 0;
+	desc->requested_packet = 0;
 	/* depending on use may need ifp->bssidx instead */
 	desc->interface_id = ifidx;
 	desc->ac_bitmap = 0xff; /* update this when handling APSD */
@@ -654,6 +655,7 @@ void brcmf_fws_clear_mac_descriptor(struct brcmf_fws_mac_descriptor *desc)
 	desc->occupied = 0;
 	desc->state = BRCMF_FWS_STATE_CLOSE;
 	desc->requested_credit = 0;
+	desc->requested_packet = 0;
 }
 
 static struct brcmf_fws_mac_descriptor *
@@ -1050,35 +1052,35 @@ 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)
+static void
+brcmf_fws_macdesc_use_req_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;
-		}
+	if (entry->requested_credit > 0) {
+		entry->requested_credit--;
+		brcmf_skb_if_flags_set_field(skb, REQUESTED, 1);
+		brcmf_skb_if_flags_set_field(skb, REQ_CREDIT, 1);
+		if (entry->state != BRCMF_FWS_STATE_CLOSE)
+			brcmf_err("requested credit set while mac not closed!\n");
+	} else if (entry->requested_packet > 0) {
+		entry->requested_packet--;
+		brcmf_skb_if_flags_set_field(skb, REQUESTED, 1);
+		brcmf_skb_if_flags_set_field(skb, REQ_CREDIT, 0);
+		if (entry->state != BRCMF_FWS_STATE_CLOSE)
+			brcmf_err("requested packet set while mac not closed!\n");
 	} else {
-		WARN_ON(entry->requested_credit);
-		WARN_ON(entry->requested_packet);
+		brcmf_skb_if_flags_set_field(skb, REQUESTED, 0);
+		brcmf_skb_if_flags_set_field(skb, REQ_CREDIT, 0);
 	}
-	brcmf_skb_if_flags_set_field(skb, CREDITCHECK, use_credit);
-	return use_credit;
+}
+
+static void brcmf_fws_macdesc_return_req_credit(struct sk_buff *skb)
+{
+	struct brcmf_fws_mac_descriptor *entry = brcmf_skbcb(skb)->mac;
+
+	if ((brcmf_skb_if_flags_get_field(skb, REQ_CREDIT)) &&
+	    (entry->state == BRCMF_FWS_STATE_CLOSE))
+		entry->requested_credit++;
 }
 
 static void brcmf_fws_return_credits(struct brcmf_fws_info *fws,
@@ -1124,25 +1126,6 @@ static void brcmf_fws_schedule_deq(struct brcmf_fws_info *fws)
 		queue_work(fws->fws_wq, &fws->fws_dequeue_work);
 }
 
-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)
-		brcmf_fws_return_credits(fws, fifo, 1);
-	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
-		 * could have taken a requested_credit from the destination
-		 * entry (for pspoll etc.)
-		 */
-		entry->requested_credit++;
-
-	brcmf_fws_schedule_deq(fws);
-}
-
 static int brcmf_fws_enq(struct brcmf_fws_info *fws,
 			 enum brcmf_fws_skb_state state, int fifo,
 			 struct sk_buff *p)
@@ -1224,7 +1207,7 @@ static struct sk_buff *brcmf_fws_deq(struct brcmf_fws_info *fws, int fifo)
 		if  (p == NULL)
 			continue;
 
-		brcmf_fws_macdesc_use_credit(entry, p);
+		brcmf_fws_macdesc_use_req_credit(entry, p);
 
 		/* move dequeue position to ensure fair round-robin */
 		fws->deq_node_pos[fifo] = (node_pos + i + 1) % num_nodes;
@@ -1313,7 +1296,8 @@ brcmf_fws_txs_process(struct brcmf_fws_info *fws, u8 flags, u32 hslot,
 	} else if (flags == BRCMF_FWS_TXSTATUS_FW_PS_SUPPRESS) {
 		fws->stats.txs_supp_ps++;
 		remove_from_hanger = false;
-	} else if (flags == BRCMF_FWS_TXSTATUS_FW_TOSSED)
+	} else if ((flags == BRCMF_FWS_TXSTATUS_FW_TOSSED) ||
+		   (flags == BRCMF_FWS_TXSTATUS_HOST_TOSSED))
 		fws->stats.txs_tossed++;
 	else
 		brcmf_err("unexpected txstatus\n");
@@ -1340,9 +1324,13 @@ brcmf_fws_txs_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);
-	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 ((fws->fcmode == BRCMF_FWS_FCMODE_IMPLIED_CREDIT) ||
+	    (brcmf_skb_if_flags_get_field(skb, REQ_CREDIT)) ||
+	    (flags == BRCMF_FWS_TXSTATUS_HOST_TOSSED)) {
+		brcmf_fws_return_credits(fws, fifo, 1);
+		brcmf_fws_schedule_deq(fws);
+	}
+	brcmf_fws_macdesc_return_req_credit(skb);
 
 	if (!remove_from_hanger)
 		ret = brcmf_fws_txstatus_suppressed(fws, fifo, skb, genbit);
@@ -1588,7 +1576,7 @@ static int brcmf_fws_precommit_skb(struct brcmf_fws_info *fws, int fifo,
 	brcmf_skb_htod_tag_set_field(p, FIFO, fifo);
 	brcmf_skb_htod_tag_set_field(p, GENERATION, entry->generation);
 	flags = BRCMF_FWS_HTOD_FLAG_PKTFROMHOST;
-	if (!(skcb->if_flags & BRCMF_SKB_IF_FLAGS_CREDITCHECK_MASK)) {
+	if (brcmf_skb_if_flags_get_field(p, REQUESTED)) {
 		/*
 		 * Indicate that this packet is being sent in response to an
 		 * explicit request from the firmware side.
@@ -1636,6 +1624,7 @@ brcmf_fws_rollback_toq(struct brcmf_fws_info *fws,
 
 	state = brcmf_skbcb(skb)->state;
 	entry = brcmf_skbcb(skb)->mac;
+	hslot = brcmf_skb_htod_tag_get_field(skb, HSLOT);
 
 	if (entry != NULL) {
 		if (state == BRCMF_FWS_SKBSTATE_SUPPRESSED) {
@@ -1647,8 +1636,6 @@ brcmf_fws_rollback_toq(struct brcmf_fws_info *fws,
 				rc = -ENOSPC;
 			}
 		} else {
-			hslot = brcmf_skb_htod_tag_get_field(skb, HSLOT);
-
 			/* delay-q packets are going to delay-q */
 			pktout = brcmu_pktq_penq_head(&entry->psq,
 						      2 * fifo, skb);
@@ -1670,11 +1657,13 @@ brcmf_fws_rollback_toq(struct brcmf_fws_info *fws,
 	}
 
 	if (rc) {
-		brcmf_fws_bustxfail(fws, skb);
 		fws->stats.rollback_failed++;
+		brcmf_fws_txs_process(fws, BRCMF_FWS_TXSTATUS_HOST_TOSSED,
+				      hslot, 0);
 	} else {
 		fws->stats.rollback_success++;
-		brcmf_fws_skb_pickup_credit(fws, fifo, skb);
+		brcmf_fws_return_credits(fws, fifo, 1);
+		brcmf_fws_macdesc_return_req_credit(skb);
 	}
 }
 
@@ -1708,26 +1697,28 @@ 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];
 
-	if (!brcmf_fws_macdesc_use_credit(entry, skb))
-		return 0;
-
 	if (fifo != BRCMF_FWS_FIFO_AC_BE)
 		fws->borrow_defer_timestamp = jiffies +
 					      BRCMF_FWS_BORROW_DEFER_PERIOD;
 
 	if (!(*credit)) {
 		/* Try to borrow a credit from other queue */
-		if (fifo == BRCMF_FWS_FIFO_AC_BE &&
-		    brcmf_fws_borrow_credit(fws) == 0)
-			return 0;
-
-		brcmf_dbg(DATA, "exit: ac=%d, credits depleted\n", fifo);
-		return -ENAVAIL;
+		if (fifo != BRCMF_FWS_FIFO_AC_BE ||
+		    (brcmf_fws_borrow_credit(fws) != 0)) {
+			brcmf_dbg(DATA, "ac=%d, credits depleted\n", fifo);
+			return -ENAVAIL;
+		}
+	} else {
+		(*credit)--;
+		if (!(*credit))
+			fws->fifo_credit_map &= ~(1 << fifo);
 	}
-	(*credit)--;
-	if (!(*credit))
-		fws->fifo_credit_map &= ~(1 << fifo);
-	brcmf_dbg(DATA, "exit: ac=%d, credits=%d\n", fifo, *credit);
+
+	brcmf_fws_macdesc_use_req_credit(entry, skb);
+
+	brcmf_dbg(DATA, "ac=%d, credits=%02d:%02d:%02d:%02d\n", fifo,
+		  fws->fifo_credit[0], fws->fifo_credit[1],
+		  fws->fifo_credit[2], fws->fifo_credit[3]);
 	return 0;
 }
 
@@ -1764,8 +1755,8 @@ static int brcmf_fws_commit_skb(struct brcmf_fws_info *fws, int fifo,
 	entry->seq[fifo]++;
 	fws->stats.pkt2bus++;
 	fws->stats.send_pkts[fifo]++;
-	if (brcmf_skbcb(skb)->if_flags & BRCMF_SKB_IF_FLAGS_CREDITCHECK_MASK)
-		fws->stats.fifo_credits_sent[fifo]++;
+	if (brcmf_skb_if_flags_get_field(skb, REQUESTED))
+		fws->stats.requested_sent[fifo]++;
 
 	return rc;
 
@@ -1888,10 +1879,7 @@ static void brcmf_fws_dequeue_worker(struct work_struct *worker)
 			skb = brcmf_fws_deq(fws, fifo);
 			if (!skb)
 				break;
-			if (brcmf_skbcb(skb)->if_flags &
-			    BRCMF_SKB_IF_FLAGS_CREDITCHECK_MASK)
-				fws->fifo_credit[fifo]--;
-
+			fws->fifo_credit[fifo]--;
 			if (brcmf_fws_commit_skb(fws, fifo, skb))
 				break;
 			if (fws->bus_flow_blocked)
@@ -2023,20 +2011,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;
+	u32 hslot;
 
 	if (brcmf_skbcb(skb)->state == BRCMF_FWS_SKBSTATE_TIM) {
 		brcmu_pkt_buf_free_skb(skb);
 		return;
 	}
 	brcmf_fws_lock(fws->drvr, flags);
-	brcmf_fws_txs_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) {
-		fifo = brcmf_skb_htod_tag_get_field(skb, FIFO);
-		brcmf_fws_skb_pickup_credit(fws, fifo, skb);
-	}
+	hslot = brcmf_skb_htod_tag_get_field(skb, HSLOT);
+	brcmf_fws_txs_process(fws, BRCMF_FWS_TXSTATUS_HOST_TOSSED, hslot, 0);
 	brcmf_fws_unlock(fws->drvr, flags);
 }
 
-- 
1.7.10.4



  parent reply	other threads:[~2013-06-06 11:19 UTC|newest]

Thread overview: 25+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-06-06 11:17 [PATCH 00/22] brcmfmac: firmware-signalling fixes and cleanup Arend van Spriel
2013-06-06 11:17 ` [PATCH 01/22] brcmfmac: allow firmware-signal tlv to be longer than specified Arend van Spriel
2013-06-06 11:17 ` [PATCH 02/22] brcmfmac: remove fifo bitfield from brcmf_skbuff_cb::if_flags Arend van Spriel
2013-06-06 11:17 ` [PATCH 03/22] brcmfmac: Take bus flowcontrol at credit mgmt into account Arend van Spriel
2013-06-06 11:17 ` [PATCH 04/22] brcmfmac: rework credit pickup to assure consistent handling Arend van Spriel
2013-06-06 11:17 ` [PATCH 05/22] brcmfmac: explicitly indicate sk_buff is sent upon request credit Arend van Spriel
2013-06-06 11:17 ` [PATCH 06/22] brcmfmac: reducing debug logging in firmware-signalling code Arend van Spriel
2013-06-06 11:17 ` [PATCH 07/22] brcmfmac: On bus flow control use fw signalling or netif Arend van Spriel
2013-06-06 11:17 ` [PATCH 08/22] brcmfmac: For FW signalling it is necessary to track gen bit Arend van Spriel
2013-06-06 11:17 ` [PATCH 09/22] brcmfmac: Correct creditmap when credit borrowing is active Arend van Spriel
2013-06-06 11:17 ` [PATCH 10/22] brcmfmac: Sent TIM information in case of data available Arend van Spriel
2013-06-06 11:17 ` [PATCH 11/22] brcmfmac: Find correct MAC descriptor in case of TDLS Arend van Spriel
2013-06-06 11:17 ` [PATCH 12/22] brcmfmac: fix invalid ifp lookup in firmware-signalling Arend van Spriel
2013-06-06 11:17 ` [PATCH 13/22] brcmfmac: Accept only first creditmap event Arend van Spriel
2013-06-06 11:17 ` [PATCH 14/22] brcmfmac: Signalling header push and pull on logic places Arend van Spriel
2013-06-06 11:18 ` [PATCH 15/22] brcmfmac: Fix endless loop when brcmf_fws_commit_skb fails Arend van Spriel
2013-06-06 11:18 ` [PATCH 16/22] brcmfmac: Simplify counting transit count Arend van Spriel
2013-06-06 11:18 ` [PATCH 17/22] brcmfmac: fix send_pkts statistic counter in firmware-signalling Arend van Spriel
2013-06-06 11:18 ` Arend van Spriel [this message]
2013-06-06 11:18 ` [PATCH 19/22] brcmfmac: use credit mechanism for BC/MC if support by firmware Arend van Spriel
2013-06-06 11:18 ` [PATCH 20/22] brcmfmac: add trace event for capturing BDC header Arend van Spriel
2013-06-06 11:18 ` [PATCH 21/22] brcmfmac: increment hard_header_len instead of overriding Arend van Spriel
2013-06-06 11:18 ` [PATCH 22/22] brcmfmac: add debugfs statistics for firmware-signalling Arend van Spriel
2013-06-11 20:27 ` [PATCH 00/22] brcmfmac: firmware-signalling fixes and cleanup Arend van Spriel
2013-06-11 20:59   ` John W. Linville

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1370517487-14395-19-git-send-email-arend@broadcom.com \
    --to=arend@broadcom.com \
    --cc=linux-wireless@vger.kernel.org \
    --cc=linville@tuxdriver.com \
    --cc=meuleman@broadcom.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).