Linux wireless drivers development
 help / color / mirror / Atom feed
* [PATCH 4/5] ath10k: fix Native Wifi decap mode RX
From: Michal Kazior @ 2013-09-24 13:09 UTC (permalink / raw)
  To: ath10k; +Cc: linux-wireless, Michal Kazior
In-Reply-To: <1380028158-861-1-git-send-email-michal.kazior@tieto.com>

NWifi decap mode always reports 802.11 Data
Frames, even when QoS Data Frames are actually
received.

This made mac80211 not report frame priority
properly (since there was no QoS Control field).

Signed-off-by: Michal Kazior <michal.kazior@tieto.com>
---
 drivers/net/wireless/ath/ath10k/htt_rx.c |   32 +++++++++++++++++++++++++++---
 1 file changed, 29 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/htt_rx.c b/drivers/net/wireless/ath/ath10k/htt_rx.c
index f8620b0..c119057 100644
--- a/drivers/net/wireless/ath/ath10k/htt_rx.c
+++ b/drivers/net/wireless/ath/ath10k/htt_rx.c
@@ -618,7 +618,7 @@ static void ath10k_htt_rx_amsdu(struct ath10k_htt *htt,
 	enum rx_msdu_decap_format fmt;
 	enum htt_rx_mpdu_encrypt_type enctype;
 	struct ieee80211_hdr *hdr;
-	u8 hdr_buf[64];
+	u8 hdr_buf[64], addr[ETH_ALEN], *qos;
 	unsigned int hdr_len;
 
 	rxd = (void *)skb->data - sizeof(*rxd);
@@ -671,7 +671,25 @@ static void ath10k_htt_rx_amsdu(struct ath10k_htt *htt,
 			skb_trim(skb, skb->len - FCS_LEN);
 			break;
 		case RX_MSDU_DECAP_NATIVE_WIFI:
-			/* nothing to do */
+			/* pull decapped header and copy DA */
+			hdr = (struct ieee80211_hdr *)skb->data;
+			hdr_len = ieee80211_hdrlen(hdr->frame_control);
+			memcpy(addr, ieee80211_get_DA(hdr), ETH_ALEN);
+			skb_pull(skb, hdr_len);
+
+			/* push original 802.11 header */
+			hdr = (struct ieee80211_hdr *)hdr_buf;
+			hdr_len = ieee80211_hdrlen(hdr->frame_control);
+			memcpy(skb_push(skb, hdr_len), hdr, hdr_len);
+
+			/* original A-MSDU header has the bit set but we're
+			 * not including A-MSDU subframe header */
+			hdr = (struct ieee80211_hdr *)skb->data;
+			qos = ieee80211_get_qos_ctl(hdr);
+			qos[0] &= ~IEEE80211_QOS_CTL_A_MSDU_PRESENT;
+
+			/* original 802.11 header has a different DA */
+			memcpy(ieee80211_get_DA(hdr), addr, ETH_ALEN);
 			break;
 		case RX_MSDU_DECAP_ETHERNET2_DIX:
 			/* strip ethernet header and insert decapped 802.11
@@ -736,7 +754,15 @@ static void ath10k_htt_rx_msdu(struct ath10k_htt *htt, struct htt_rx_info *info)
 		skb_trim(skb, skb->len - FCS_LEN);
 		break;
 	case RX_MSDU_DECAP_NATIVE_WIFI:
-		/* nothing to do here */
+		/* Pull decapped header */
+		hdr = (struct ieee80211_hdr *)skb->data;
+		hdr_len = ieee80211_hdrlen(hdr->frame_control);
+		skb_pull(skb, hdr_len);
+
+		/* Push original header */
+		hdr = (struct ieee80211_hdr *)rxd->rx_hdr_status;
+		hdr_len = ieee80211_hdrlen(hdr->frame_control);
+		memcpy(skb_push(skb, hdr_len), hdr, hdr_len);
 		break;
 	case RX_MSDU_DECAP_ETHERNET2_DIX:
 		/* strip ethernet header and insert decapped 802.11 header and
-- 
1.7.9.5


^ permalink raw reply related

* [PATCH 5/5] ath10k: align RX frames properly
From: Michal Kazior @ 2013-09-24 13:09 UTC (permalink / raw)
  To: ath10k; +Cc: linux-wireless, Michal Kazior
In-Reply-To: <1380028158-861-1-git-send-email-michal.kazior@tieto.com>

Ethernet-like decapping mode leaves IP protocol
frame not aligned to 4-byte boundaries. This leads
to re-aligning in mac80211 which in turn leads to
poor CPU cache behaviour on some machines.

Since HW doesn't allow to change payload offset
properly the solution is to force HW to decap in
Native Wifi mode which always has 24-bytes long
802.11 header (even for QoS frames). This means IP
frame is properly aligned in this decap mode.

Signed-off-by: Michal Kazior <michal.kazior@tieto.com>
---
 drivers/net/wireless/ath/ath10k/hw.h |    6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/ath/ath10k/hw.h b/drivers/net/wireless/ath/ath10k/hw.h
index 643f0c9..8c1be768 100644
--- a/drivers/net/wireless/ath/ath10k/hw.h
+++ b/drivers/net/wireless/ath/ath10k/hw.h
@@ -74,7 +74,11 @@ enum ath10k_mcast2ucast_mode {
 #define TARGET_RX_CHAIN_MASK			(BIT(0) | BIT(1) | BIT(2))
 #define TARGET_RX_TIMEOUT_LO_PRI		100
 #define TARGET_RX_TIMEOUT_HI_PRI		40
-#define TARGET_RX_DECAP_MODE			ATH10K_HW_TXRX_ETHERNET
+
+/* Native Wifi decap mode is used to align IP frames to 4-byte boundaries and
+ * avoid a very expensive re-alignment in mac80211. */
+#define TARGET_RX_DECAP_MODE			ATH10K_HW_TXRX_NATIVE_WIFI
+
 #define TARGET_SCAN_MAX_PENDING_REQS		4
 #define TARGET_BMISS_OFFLOAD_MAX_VDEV		3
 #define TARGET_ROAM_OFFLOAD_MAX_VDEV		3
-- 
1.7.9.5


^ permalink raw reply related

* [PATCH 3/5] ath10k: cleanup RX decap handling
From: Michal Kazior @ 2013-09-24 13:09 UTC (permalink / raw)
  To: ath10k; +Cc: linux-wireless, Michal Kazior
In-Reply-To: <1380028158-861-1-git-send-email-michal.kazior@tieto.com>

Simplify decapping code and make it easier to
understand.

Signed-off-by: Michal Kazior <michal.kazior@tieto.com>
---
 drivers/net/wireless/ath/ath10k/htt_rx.c |   53 +++++++++++++++---------------
 1 file changed, 27 insertions(+), 26 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/htt_rx.c b/drivers/net/wireless/ath/ath10k/htt_rx.c
index f79f815..f8620b0 100644
--- a/drivers/net/wireless/ath/ath10k/htt_rx.c
+++ b/drivers/net/wireless/ath/ath10k/htt_rx.c
@@ -667,11 +667,16 @@ static void ath10k_htt_rx_amsdu(struct ath10k_htt *htt,
 
 		switch (fmt) {
 		case RX_MSDU_DECAP_RAW:
+			/* remove trailing FCS */
 			skb_trim(skb, skb->len - FCS_LEN);
 			break;
 		case RX_MSDU_DECAP_NATIVE_WIFI:
+			/* nothing to do */
 			break;
 		case RX_MSDU_DECAP_ETHERNET2_DIX:
+			/* strip ethernet header and insert decapped 802.11
+			 * header, amsdu subframe header and rfc1042 header */
+
 			decap_len = 0;
 			decap_len += sizeof(struct rfc1042_hdr);
 			decap_len += sizeof(struct amsdu_subframe_hdr);
@@ -681,6 +686,7 @@ static void ath10k_htt_rx_amsdu(struct ath10k_htt *htt,
 			memcpy(skb_push(skb, hdr_len), hdr, hdr_len);
 			break;
 		case RX_MSDU_DECAP_8023_SNAP_LLC:
+			/* insert decapped 802.11 header making a singly A-MSDU */
 			memcpy(skb_push(skb, hdr_len), hdr, hdr_len);
 			break;
 		}
@@ -704,6 +710,8 @@ static void ath10k_htt_rx_msdu(struct ath10k_htt *htt, struct htt_rx_info *info)
 	struct ieee80211_hdr *hdr;
 	enum rx_msdu_decap_format fmt;
 	enum htt_rx_mpdu_encrypt_type enctype;
+	int hdr_len;
+	void *rfc1042;
 
 	/* This shouldn't happen. If it does than it may be a FW bug. */
 	if (skb->next) {
@@ -717,46 +725,39 @@ static void ath10k_htt_rx_msdu(struct ath10k_htt *htt, struct htt_rx_info *info)
 			RX_MSDU_START_INFO1_DECAP_FORMAT);
 	enctype = MS(__le32_to_cpu(rxd->mpdu_start.info0),
 			RX_MPDU_START_INFO0_ENCRYPT_TYPE);
-	hdr = (void *)skb->data - RX_HTT_HDR_STATUS_LEN;
+	hdr = (struct ieee80211_hdr *)rxd->rx_hdr_status;
+	hdr_len = ieee80211_hdrlen(hdr->frame_control);
 
 	skb->ip_summed = ath10k_htt_rx_get_csum_state(skb);
 
 	switch (fmt) {
 	case RX_MSDU_DECAP_RAW:
 		/* remove trailing FCS */
-		skb_trim(skb, skb->len - 4);
+		skb_trim(skb, skb->len - FCS_LEN);
 		break;
 	case RX_MSDU_DECAP_NATIVE_WIFI:
 		/* nothing to do here */
 		break;
 	case RX_MSDU_DECAP_ETHERNET2_DIX:
-		/* macaddr[6] + macaddr[6] + ethertype[2] */
-		skb_pull(skb, 6 + 6 + 2);
-		break;
-	case RX_MSDU_DECAP_8023_SNAP_LLC:
-		/* macaddr[6] + macaddr[6] + len[2] */
-		/* we don't need this for non-A-MSDU */
-		skb_pull(skb, 6 + 6 + 2);
-		break;
-	}
-
-	if (fmt == RX_MSDU_DECAP_ETHERNET2_DIX) {
-		void *llc;
-		int llclen;
+		/* strip ethernet header and insert decapped 802.11 header and
+		 * rfc1042 header */
 
-		llclen = 8;
-		llc  = hdr;
-		llc += roundup(ieee80211_hdrlen(hdr->frame_control), 4);
-		llc += roundup(ath10k_htt_rx_crypto_param_len(enctype), 4);
+		rfc1042 = hdr;
+		rfc1042 += roundup(hdr_len, 4);
+		rfc1042 += roundup(ath10k_htt_rx_crypto_param_len(enctype), 4);
 
-		skb_push(skb, llclen);
-		memcpy(skb->data, llc, llclen);
-	}
+		skb_pull(skb, sizeof(struct ethhdr));
+		memcpy(skb_push(skb, sizeof(struct rfc1042_hdr)),
+		       rfc1042, sizeof(struct rfc1042_hdr));
+		memcpy(skb_push(skb, hdr_len), hdr, hdr_len);
+		break;
+	case RX_MSDU_DECAP_8023_SNAP_LLC:
+		/* remove A-MSDU subframe header and insert
+		 * decapped 802.11 header. rfc1042 header is already there */
 
-	if (fmt >= RX_MSDU_DECAP_ETHERNET2_DIX) {
-		int len = ieee80211_hdrlen(hdr->frame_control);
-		skb_push(skb, len);
-		memcpy(skb->data, hdr, len);
+		skb_pull(skb, sizeof(struct amsdu_subframe_hdr));
+		memcpy(skb_push(skb, hdr_len), hdr, hdr_len);
+		break;
 	}
 
 	info->skb = skb;
-- 
1.7.9.5


^ permalink raw reply related

* [PATCH 2/5] ath10k: document decap modes
From: Michal Kazior @ 2013-09-24 13:09 UTC (permalink / raw)
  To: ath10k; +Cc: linux-wireless, Michal Kazior
In-Reply-To: <1380028158-861-1-git-send-email-michal.kazior@tieto.com>

Clarify how each decap mode works in one place.

Signed-off-by: Michal Kazior <michal.kazior@tieto.com>
---
 drivers/net/wireless/ath/ath10k/rx_desc.h |   24 ++++++++++++++++++++++--
 1 file changed, 22 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/rx_desc.h b/drivers/net/wireless/ath/ath10k/rx_desc.h
index bfec6c8..1c584c4 100644
--- a/drivers/net/wireless/ath/ath10k/rx_desc.h
+++ b/drivers/net/wireless/ath/ath10k/rx_desc.h
@@ -422,10 +422,30 @@ struct rx_mpdu_end {
 #define RX_MSDU_START_INFO1_IP_FRAG             (1 << 14)
 #define RX_MSDU_START_INFO1_TCP_ONLY_ACK        (1 << 15)
 
+/* The decapped header (rx_hdr_status) contains the following:
+ *  a) 802.11 header
+ *  [padding to 4 bytes]
+ *  b) HW crypto parameter
+ *     - 0 bytes for no security
+ *     - 4 bytes for WEP
+ *     - 8 bytes for TKIP, AES
+ *  [padding to 4 bytes]
+ *  c) A-MSDU subframe header (14 bytes) if appliable
+ *  d) LLC/SNAP (RFC1042, 8 bytes)
+ *
+ * In case of A-MSDU only first frame in sequence contains (a) and (b). */
 enum rx_msdu_decap_format {
-	RX_MSDU_DECAP_RAW           = 0,
-	RX_MSDU_DECAP_NATIVE_WIFI   = 1,
+	RX_MSDU_DECAP_RAW = 0,
+
+	/* Note: QoS frames are reported as non-QoS. The rx_hdr_status in
+	 * htt_rx_desc contains the original decapped 802.11 header. */
+	RX_MSDU_DECAP_NATIVE_WIFI = 1,
+
+	/* Payload contains an ethernet header (struct ethhdr). */
 	RX_MSDU_DECAP_ETHERNET2_DIX = 2,
+
+	/* Payload contains two 48-bit addresses and 2-byte length (14 bytes
+	 * total), followed by an RFC1042 header (8 bytes). */
 	RX_MSDU_DECAP_8023_SNAP_LLC = 3
 };
 
-- 
1.7.9.5


^ permalink raw reply related

* [PATCH 1/5] ath10k: report A-MSDU subframes individually
From: Michal Kazior @ 2013-09-24 13:09 UTC (permalink / raw)
  To: ath10k; +Cc: linux-wireless, Michal Kazior
In-Reply-To: <1380028158-861-1-git-send-email-michal.kazior@tieto.com>

HW reports each A-MSDU subframe as a separate
sk_buff. It is impossible to configure it to
behave differently.

Until now ath10k was reconstructing A-MSDUs from
subframes which involved a lot of memory
operations. This proved to be a significant
contributor to degraded RX performance.

Signed-off-by: Michal Kazior <michal.kazior@tieto.com>
---
 drivers/net/wireless/ath/ath10k/htt_rx.c |  204 ++++++++++++------------------
 drivers/net/wireless/ath/ath10k/txrx.c   |    2 +
 2 files changed, 83 insertions(+), 123 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/htt_rx.c b/drivers/net/wireless/ath/ath10k/htt_rx.c
index 62ea9c8..f79f815 100644
--- a/drivers/net/wireless/ath/ath10k/htt_rx.c
+++ b/drivers/net/wireless/ath/ath10k/htt_rx.c
@@ -41,6 +41,10 @@
 /* when under memory pressure rx ring refill may fail and needs a retry */
 #define HTT_RX_RING_REFILL_RETRY_MS 50
 
+
+static int ath10k_htt_rx_get_csum_state(struct sk_buff *skb);
+
+
 static int ath10k_htt_rx_ring_size(struct ath10k_htt *htt)
 {
 	int size;
@@ -591,136 +595,109 @@ static bool ath10k_htt_rx_hdr_is_amsdu(struct ieee80211_hdr *hdr)
 	return false;
 }
 
-static int ath10k_htt_rx_amsdu(struct ath10k_htt *htt,
-			struct htt_rx_info *info)
+struct rfc1042_hdr {
+	u8 llc_dsap;
+	u8 llc_ssap;
+	u8 llc_ctrl;
+	u8 snap_oui[3];
+	__be16 snap_type;
+} __packed;
+
+struct amsdu_subframe_hdr {
+	u8 dst[ETH_ALEN];
+	u8 src[ETH_ALEN];
+	__be16 len;
+} __packed;
+
+static void ath10k_htt_rx_amsdu(struct ath10k_htt *htt,
+				struct htt_rx_info *info)
 {
 	struct htt_rx_desc *rxd;
-	struct sk_buff *amsdu;
 	struct sk_buff *first;
-	struct ieee80211_hdr *hdr;
 	struct sk_buff *skb = info->skb;
 	enum rx_msdu_decap_format fmt;
 	enum htt_rx_mpdu_encrypt_type enctype;
+	struct ieee80211_hdr *hdr;
+	u8 hdr_buf[64];
 	unsigned int hdr_len;
-	int crypto_len;
 
 	rxd = (void *)skb->data - sizeof(*rxd);
-	fmt = MS(__le32_to_cpu(rxd->msdu_start.info1),
-			RX_MSDU_START_INFO1_DECAP_FORMAT);
 	enctype = MS(__le32_to_cpu(rxd->mpdu_start.info0),
 			RX_MPDU_START_INFO0_ENCRYPT_TYPE);
 
-	/* FIXME: No idea what assumptions are safe here. Need logs */
-	if ((fmt == RX_MSDU_DECAP_RAW && skb->next)) {
-		ath10k_htt_rx_free_msdu_chain(skb->next);
-		skb->next = NULL;
-		return -ENOTSUPP;
-	}
+	hdr = (struct ieee80211_hdr *)rxd->rx_hdr_status;
+	hdr_len = ieee80211_hdrlen(hdr->frame_control);
+	memcpy(hdr_buf, hdr, hdr_len);
+	hdr = (struct ieee80211_hdr *)hdr_buf;
 
-	/* A-MSDU max is a little less than 8K */
-	amsdu = dev_alloc_skb(8*1024);
-	if (!amsdu) {
-		ath10k_warn("A-MSDU allocation failed\n");
-		ath10k_htt_rx_free_msdu_chain(skb->next);
-		skb->next = NULL;
-		return -ENOMEM;
-	}
-
-	if (fmt >= RX_MSDU_DECAP_NATIVE_WIFI) {
-		int hdrlen;
-
-		hdr = (void *)rxd->rx_hdr_status;
-		hdrlen = ieee80211_hdrlen(hdr->frame_control);
-		memcpy(skb_put(amsdu, hdrlen), hdr, hdrlen);
-	}
+	/* FIXME: Hopefully this is a temporary measure.
+	 *
+	 * Reporting individual A-MSDU subframes means each reported frame
+	 * shares the same sequence number.
+	 *
+	 * mac80211 drops frames it recognizes as duplicates, i.e.
+	 * retransmission flag is set and sequence number matches sequence
+	 * number from a previous frame (as per IEEE 802.11-2012: 9.3.2.10
+	 * "Duplicate detection and recovery")
+	 *
+	 * To avoid frames being dropped clear retransmission flag for all
+	 * received A-MSDUs.
+	 *
+	 * Worst case: actual duplicate frames will be reported but this should
+	 * still be handled gracefully by other OSI/ISO layers. */
+	hdr->frame_control &= cpu_to_le16(~IEEE80211_FCTL_RETRY);
 
 	first = skb;
 	while (skb) {
 		void *decap_hdr;
-		int decap_len = 0;
+		int decap_len;
 
 		rxd = (void *)skb->data - sizeof(*rxd);
 		fmt = MS(__le32_to_cpu(rxd->msdu_start.info1),
-				RX_MSDU_START_INFO1_DECAP_FORMAT);
+			 RX_MSDU_START_INFO1_DECAP_FORMAT);
 		decap_hdr = (void *)rxd->rx_hdr_status;
 
-		if (skb == first) {
-			/* We receive linked A-MSDU subframe skbuffs. The
-			 * first one contains the original 802.11 header (and
-			 * possible crypto param) in the RX descriptor. The
-			 * A-MSDU subframe header follows that. Each part is
-			 * aligned to 4 byte boundary. */
-
-			hdr = (void *)amsdu->data;
-			hdr_len = ieee80211_hdrlen(hdr->frame_control);
-			crypto_len = ath10k_htt_rx_crypto_param_len(enctype);
-
-			decap_hdr += roundup(hdr_len, 4);
-			decap_hdr += roundup(crypto_len, 4);
-		}
-
-		/* When fmt == RX_MSDU_DECAP_8023_SNAP_LLC:
-		 *
-		 * SNAP 802.3 consists of:
-		 * [dst:6][src:6][len:2][dsap:1][ssap:1][ctl:1][snap:5]
-		 * [data][fcs:4].
-		 *
-		 * Since this overlaps with A-MSDU header (da, sa, len)
-		 * there's nothing extra to do. */
-
-		if (fmt == RX_MSDU_DECAP_ETHERNET2_DIX) {
-			/* Ethernet2 decap inserts ethernet header in place of
-			 * A-MSDU subframe header. */
-			skb_pull(skb, 6 + 6 + 2);
-
-			/* A-MSDU subframe header length */
-			decap_len += 6 + 6 + 2;
-
-			/* Ethernet2 decap also strips the LLC/SNAP so we need
-			 * to re-insert it. The LLC/SNAP follows A-MSDU
-			 * subframe header. */
-			/* FIXME: Not all LLCs are 8 bytes long */
-			decap_len += 8;
-
-			memcpy(skb_put(amsdu, decap_len), decap_hdr, decap_len);
-		}
+		skb->ip_summed = ath10k_htt_rx_get_csum_state(skb);
 
-		if (fmt == RX_MSDU_DECAP_NATIVE_WIFI) {
-			/* Native Wifi decap inserts regular 802.11 header
-			 * in place of A-MSDU subframe header. */
-			hdr = (struct ieee80211_hdr *)skb->data;
-			skb_pull(skb, ieee80211_hdrlen(hdr->frame_control));
-
-			/* A-MSDU subframe header length */
-			decap_len += 6 + 6 + 2;
-
-			memcpy(skb_put(amsdu, decap_len), decap_hdr, decap_len);
+		/* First frame in an A-MSDU chain has more decapped data. */
+		if (skb == first) {
+			decap_hdr += round_up(ieee80211_hdrlen(hdr->frame_control), 4);
+			decap_hdr += round_up(ath10k_htt_rx_crypto_param_len(enctype), 4);
 		}
 
-		if (fmt == RX_MSDU_DECAP_RAW)
-			skb_trim(skb, skb->len - 4); /* remove FCS */
-
-		memcpy(skb_put(amsdu, skb->len), skb->data, skb->len);
-
-		/* A-MSDU subframes are padded to 4bytes
-		 * but relative to first subframe, not the whole MPDU */
-		if (skb->next && ((decap_len + skb->len) & 3)) {
-			int padlen = 4 - ((decap_len + skb->len) & 3);
-			memset(skb_put(amsdu, padlen), 0, padlen);
+		switch (fmt) {
+		case RX_MSDU_DECAP_RAW:
+			skb_trim(skb, skb->len - FCS_LEN);
+			break;
+		case RX_MSDU_DECAP_NATIVE_WIFI:
+			break;
+		case RX_MSDU_DECAP_ETHERNET2_DIX:
+			decap_len = 0;
+			decap_len += sizeof(struct rfc1042_hdr);
+			decap_len += sizeof(struct amsdu_subframe_hdr);
+
+			skb_pull(skb, sizeof(struct ethhdr));
+			memcpy(skb_push(skb, decap_len), decap_hdr, decap_len);
+			memcpy(skb_push(skb, hdr_len), hdr, hdr_len);
+			break;
+		case RX_MSDU_DECAP_8023_SNAP_LLC:
+			memcpy(skb_push(skb, hdr_len), hdr, hdr_len);
+			break;
 		}
 
+		info->skb = skb;
+		info->encrypt_type = enctype;
 		skb = skb->next;
-	}
-
-	info->skb = amsdu;
-	info->encrypt_type = enctype;
+		info->skb->next = NULL;
 
-	ath10k_htt_rx_free_msdu_chain(first);
+		ath10k_process_rx(htt->ar, info);
+	}
 
-	return 0;
+	/* FIXME: It might be nice to re-assemble the A-MSDU when there's a
+	 * monitor interface active for sniffing purposes. */
 }
 
-static int ath10k_htt_rx_msdu(struct ath10k_htt *htt, struct htt_rx_info *info)
+static void ath10k_htt_rx_msdu(struct ath10k_htt *htt, struct htt_rx_info *info)
 {
 	struct sk_buff *skb = info->skb;
 	struct htt_rx_desc *rxd;
@@ -742,6 +719,8 @@ static int ath10k_htt_rx_msdu(struct ath10k_htt *htt, struct htt_rx_info *info)
 			RX_MPDU_START_INFO0_ENCRYPT_TYPE);
 	hdr = (void *)skb->data - RX_HTT_HDR_STATUS_LEN;
 
+	skb->ip_summed = ath10k_htt_rx_get_csum_state(skb);
+
 	switch (fmt) {
 	case RX_MSDU_DECAP_RAW:
 		/* remove trailing FCS */
@@ -782,7 +761,8 @@ static int ath10k_htt_rx_msdu(struct ath10k_htt *htt, struct htt_rx_info *info)
 
 	info->skb = skb;
 	info->encrypt_type = enctype;
-	return 0;
+
+	ath10k_process_rx(htt->ar, info);
 }
 
 static bool ath10k_htt_rx_has_decrypt_err(struct sk_buff *skb)
@@ -854,8 +834,6 @@ static void ath10k_htt_rx_handler(struct ath10k_htt *htt,
 	int fw_desc_len;
 	u8 *fw_desc;
 	int i, j;
-	int ret;
-	int ip_summed;
 
 	memset(&info, 0, sizeof(info));
 
@@ -930,11 +908,6 @@ static void ath10k_htt_rx_handler(struct ath10k_htt *htt,
 				continue;
 			}
 
-			/* The skb is not yet processed and it may be
-			 * reallocated. Since the offload is in the original
-			 * skb extract the checksum now and assign it later */
-			ip_summed = ath10k_htt_rx_get_csum_state(msdu_head);
-
 			info.skb     = msdu_head;
 			info.fcs_err = ath10k_htt_rx_has_fcs_err(msdu_head);
 			info.signal  = ATH10K_DEFAULT_NOISE_FLOOR;
@@ -947,24 +920,9 @@ static void ath10k_htt_rx_handler(struct ath10k_htt *htt,
 			hdr = ath10k_htt_rx_skb_get_hdr(msdu_head);
 
 			if (ath10k_htt_rx_hdr_is_amsdu(hdr))
-				ret = ath10k_htt_rx_amsdu(htt, &info);
+				ath10k_htt_rx_amsdu(htt, &info);
 			else
-				ret = ath10k_htt_rx_msdu(htt, &info);
-
-			if (ret && !info.fcs_err) {
-				ath10k_warn("error processing msdus %d\n", ret);
-				dev_kfree_skb_any(info.skb);
-				continue;
-			}
-
-			if (ath10k_htt_rx_hdr_is_amsdu((void *)info.skb->data))
-				ath10k_dbg(ATH10K_DBG_HTT, "htt mpdu is amsdu\n");
-
-			info.skb->ip_summed = ip_summed;
-
-			ath10k_dbg_dump(ATH10K_DBG_HTT_DUMP, NULL, "htt mpdu: ",
-					info.skb->data, info.skb->len);
-			ath10k_process_rx(htt->ar, &info);
+				ath10k_htt_rx_msdu(htt, &info);
 		}
 	}
 
diff --git a/drivers/net/wireless/ath/ath10k/txrx.c b/drivers/net/wireless/ath/ath10k/txrx.c
index 57931d0..5ae373a 100644
--- a/drivers/net/wireless/ath/ath10k/txrx.c
+++ b/drivers/net/wireless/ath/ath10k/txrx.c
@@ -268,6 +268,8 @@ void ath10k_process_rx(struct ath10k *ar, struct htt_rx_info *info)
 		   status->vht_nss,
 		   status->freq,
 		   status->band);
+	ath10k_dbg_dump(ATH10K_DBG_HTT_DUMP, NULL, "rx skb: ",
+			info->skb->data, info->skb->len);
 
 	ieee80211_rx(ar->hw, info->skb);
 }
-- 
1.7.9.5


^ permalink raw reply related

* [PATCH 0/5] ath10k: improve RX performance
From: Michal Kazior @ 2013-09-24 13:09 UTC (permalink / raw)
  To: ath10k; +Cc: linux-wireless, Michal Kazior

Hi,

This patchset gives clear RX performance
improvement on AP135. Throughput is at least
doubled (300mbps -> 600mbps, UDP RX, 2x2).

This contains a workaround for
retransmission/duplication recovery.

There's a pending patch for mac80211 that will
allow proper individiual A-MSDU subframe
reporting.

Changes since RFC:
 * comments fixes (Kalle)
 * one patch extracted/split (Kalle)
 * commit message adjustments


Michal Kazior (5):
  ath10k: report A-MSDU subframes individually
  ath10k: document decap modes
  ath10k: cleanup RX decap handling
  ath10k: fix Native Wifi decap mode RX
  ath10k: align RX frames properly

 drivers/net/wireless/ath/ath10k/htt_rx.c  |  273 ++++++++++++++---------------
 drivers/net/wireless/ath/ath10k/hw.h      |    6 +-
 drivers/net/wireless/ath/ath10k/rx_desc.h |   24 ++-
 drivers/net/wireless/ath/ath10k/txrx.c    |    2 +
 4 files changed, 158 insertions(+), 147 deletions(-)

-- 
1.7.9.5


^ permalink raw reply

* [PATCH] ath10k: make monitor vdev down before stoping it
From: Marek Puzyniak @ 2013-09-24 12:06 UTC (permalink / raw)
  To: ath10k; +Cc: linux-wireless, Marek Puzyniak

Following sequence causes FW crash:
-monitor vdev up,
-monitor vdev stop,
-monitor vdev delete.
Making monitor vdev down before stoping it works ok:
-monitor vdev up,
-monitor vdev down,
-monitor vdev stop,
-monitor vdev delete.

Signed-off-by: Marek Puzyniak <marek.puzyniak@tieto.com>
---
 drivers/net/wireless/ath/ath10k/mac.c | 9 +++------
 1 file changed, 3 insertions(+), 6 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c
index 51988d9..24b94c8 100644
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
@@ -567,12 +567,9 @@ static int ath10k_monitor_stop(struct ath10k *ar)
 
 	lockdep_assert_held(&ar->conf_mutex);
 
-	/* For some reasons, ath10k_wmi_vdev_down() here couse
-	 * often ath10k_wmi_vdev_stop() to fail. Next we could
-	 * not run monitor vdev and driver reload
-	 * required. Don't see such problems we skip
-	 * ath10k_wmi_vdev_down() here.
-	 */
+	ret = ath10k_wmi_vdev_down(ar, ar->monitor_vdev_id);
+	if (ret)
+		ath10k_warn("Monitor vdev down failed: %d\n", ret);
 
 	ret = ath10k_wmi_vdev_stop(ar, ar->monitor_vdev_id);
 	if (ret)
-- 
1.8.1.2


^ permalink raw reply related

* Re: [PATCH 12/19] wireless: Change variable type to bool
From: Kalle Valo @ 2013-09-24 10:54 UTC (permalink / raw)
  To: Peter Senna Tschudin
  Cc: Larry.Finger, chaoming_li, linville, linux-wireless, netdev,
	linux-kernel, kernel-janitors
In-Reply-To: <1379802471-30252-12-git-send-email-peter.senna@gmail.com>

Peter Senna Tschudin <peter.senna@gmail.com> writes:

> The variable continual is only assigned the values true and false.
> Change its type to bool.
>
> The simplified semantic patch that find this problem is as
> follows (http://coccinelle.lip6.fr/):
>
> @exists@
> type T;
> identifier b;
> @@
> - T
> + bool
>   b = ...;
>   ... when any
>   b = \(true\|false\)
>
> Signed-off-by: Peter Senna Tschudin <peter.senna@gmail.com>
> ---
>  drivers/net/wireless/rtlwifi/efuse.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)

Please prefix the patch title with "rtlwifi:". We use "wireless:" for
changes to net/wireless.

-- 
Kalle Valo

^ permalink raw reply

* [PATCH] ath10k: replenish HTT RX buffers in a tasklet
From: Michal Kazior @ 2013-09-24  8:18 UTC (permalink / raw)
  To: ath10k; +Cc: linux-wireless, Michal Kazior

This starves FW RX ring buffer in case of
excessive RX. This prevents from CPU being
overwhelmed by RX indications/completions by
naturally forbiddin FW to submit more RX.

This fixes RX starvation on slow machines when
under heavy RX traffic.

Signed-off-by: Michal Kazior <michal.kazior@tieto.com>
---
PATCHv1 (since RFC) changes:
 * fix comment
 * remove empty line addition
 * re-order tasklet_kill() / del_timer_sync()

 drivers/net/wireless/ath/ath10k/htt.h    |    7 ++++++
 drivers/net/wireless/ath/ath10k/htt_rx.c |   35 +++++++++++++++++++++++++++---
 2 files changed, 39 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/htt.h b/drivers/net/wireless/ath/ath10k/htt.h
index e090902..3d71041 100644
--- a/drivers/net/wireless/ath/ath10k/htt.h
+++ b/drivers/net/wireless/ath/ath10k/htt.h
@@ -19,6 +19,7 @@
 #define _HTT_H_
 
 #include <linux/bug.h>
+#include <linux/interrupt.h>
 
 #include "htc.h"
 #include "rx_desc.h"
@@ -1268,6 +1269,7 @@ struct ath10k_htt {
 	/* set if host-fw communication goes haywire
 	 * used to avoid further failures */
 	bool rx_confused;
+	struct tasklet_struct rx_replenish_task;
 };
 
 #define RX_HTT_HDR_STATUS_LEN 64
@@ -1308,6 +1310,11 @@ struct htt_rx_desc {
 #define HTT_RX_BUF_SIZE 1920
 #define HTT_RX_MSDU_SIZE (HTT_RX_BUF_SIZE - (int)sizeof(struct htt_rx_desc))
 
+/* Refill a bunch of RX buffers for each refill round so that FW/HW can handle
+ * aggregated traffic more nicely. */
+#define ATH10K_HTT_MAX_NUM_REFILL 16
+
+
 /*
  * DMA_MAP expects the buffer to be an integral number of cache lines.
  * Rather than checking the actual cache line size, this code makes a
diff --git a/drivers/net/wireless/ath/ath10k/htt_rx.c b/drivers/net/wireless/ath/ath10k/htt_rx.c
index 62ea9c8..02028c6 100644
--- a/drivers/net/wireless/ath/ath10k/htt_rx.c
+++ b/drivers/net/wireless/ath/ath10k/htt_rx.c
@@ -178,10 +178,27 @@ static int ath10k_htt_rx_ring_fill_n(struct ath10k_htt *htt, int num)
 
 static void ath10k_htt_rx_msdu_buff_replenish(struct ath10k_htt *htt)
 {
-	int ret, num_to_fill;
+	int ret, num_deficit, num_to_fill;
 
+	/* Refilling the whole RX ring buffer proves to be a bad idea. The
+	 * reason is RX may take up significant amount of CPU cycles and starve
+	 * other tasks, e.g. TX on an ethernet device while acting as a bridge
+	 * with ath10k wlan interface. This ended up with very poor performance
+	 * once CPU the host system was overwhelmed with RX on ath10k.
+	 *
+	 * By limiting the number of refills the replenishing occurs
+	 * progressively. This in turns makes use of the fact tasklets are
+	 * processed in FIFO order. This means actual RX processing can starve
+	 * out refilling. If there's not enough buffers on RX ring FW will not
+	 * report RX until it is refilled with enough buffers. This
+	 * automatically balances load wrt to CPU power.
+	 *
+	 * This probably comes at a cost of lower maximum throughput but
+	 * improves the avarage and stability. */
 	spin_lock_bh(&htt->rx_ring.lock);
-	num_to_fill = htt->rx_ring.fill_level - htt->rx_ring.fill_cnt;
+	num_deficit = htt->rx_ring.fill_level - htt->rx_ring.fill_cnt;
+	num_to_fill = min(ATH10K_HTT_MAX_NUM_REFILL, num_deficit);
+	num_deficit -= num_to_fill;
 	ret = ath10k_htt_rx_ring_fill_n(htt, num_to_fill);
 	if (ret == -ENOMEM) {
 		/*
@@ -192,6 +209,8 @@ static void ath10k_htt_rx_msdu_buff_replenish(struct ath10k_htt *htt)
 		 */
 		mod_timer(&htt->rx_ring.refill_retry_timer, jiffies +
 			  msecs_to_jiffies(HTT_RX_RING_REFILL_RETRY_MS));
+	} else if (num_deficit > 0) {
+		tasklet_schedule(&htt->rx_replenish_task);
 	}
 	spin_unlock_bh(&htt->rx_ring.lock);
 }
@@ -213,6 +232,7 @@ void ath10k_htt_rx_detach(struct ath10k_htt *htt)
 	int sw_rd_idx = htt->rx_ring.sw_rd_idx.msdu_payld;
 
 	del_timer_sync(&htt->rx_ring.refill_retry_timer);
+	tasklet_kill(&htt->rx_replenish_task);
 
 	while (sw_rd_idx != __le32_to_cpu(*(htt->rx_ring.alloc_idx.vaddr))) {
 		struct sk_buff *skb =
@@ -442,6 +462,12 @@ static int ath10k_htt_rx_amsdu_pop(struct ath10k_htt *htt,
 	return msdu_chaining;
 }
 
+static void ath10k_htt_rx_replenish_task(unsigned long ptr)
+{
+	struct ath10k_htt *htt = (struct ath10k_htt *)ptr;
+	ath10k_htt_rx_msdu_buff_replenish(htt);
+}
+
 int ath10k_htt_rx_attach(struct ath10k_htt *htt)
 {
 	dma_addr_t paddr;
@@ -502,6 +528,9 @@ int ath10k_htt_rx_attach(struct ath10k_htt *htt)
 	if (__ath10k_htt_rx_ring_fill_n(htt, htt->rx_ring.fill_level))
 		goto err_fill_ring;
 
+	tasklet_init(&htt->rx_replenish_task, ath10k_htt_rx_replenish_task,
+		     (unsigned long)htt);
+
 	ath10k_dbg(ATH10K_DBG_BOOT, "htt rx ring size %d fill_level %d\n",
 		   htt->rx_ring.size, htt->rx_ring.fill_level);
 	return 0;
@@ -968,7 +997,7 @@ static void ath10k_htt_rx_handler(struct ath10k_htt *htt,
 		}
 	}
 
-	ath10k_htt_rx_msdu_buff_replenish(htt);
+	tasklet_schedule(&htt->rx_replenish_task);
 }
 
 static void ath10k_htt_rx_frag_handler(struct ath10k_htt *htt,
-- 
1.7.9.5


^ permalink raw reply related

* Re: brcmsmac causes soft lockup in 3.12-rc1
From: Arend van Spriel @ 2013-09-24  7:53 UTC (permalink / raw)
  To: linux-wireless
In-Reply-To: <20130924005224.GA27400@mail.catnarok.net>

On 09/24/2013 02:52 AM, Michael Stolovitzsky wrote:
> On Mon, Sep 23, 2013 at 10:13:49AM +0200, Arend van Spriel wrote:
>> On 09/22/2013 12:34 AM, Michael Stolovitzsky wrote:
>>> Hi,
>>>
>>> On 3.12-rc1, modprobe brcmsmac causes a soft lockup (trace #1), effectively killing the box. This is a Lenovo S206
>>> with BCM4313 (14e4:4727), which I believe is a bluetooth combo board. After a while,
>>> RCU scheduler code detects a lockup (trace #2).
>>>
>>> This did not happen in 3.11.1, although brcmsmac hasn't worked on this machine
>>> as far as I remember. In  the previous kernels (~3.2.0+), it loads, but the
>>> reception is extremely weak - you must be within few meters to the AP, and the card would
>>> die after several minutes. The proprietary wl.ko driver works fine.
>>>
>>> I've attached the dmesg output, the kernel configuration and the output of lspci -vnn.
>>> I'm comfortable with experimenting; please let me know how I can help here.
>>
>> A fix for this problem has been submitted to John. I think it is in
>> transit to mainline so probably will be in 3.12-rc2.
>>
>> Here the URL of the patch:
>>
>> https://git.kernel.org/cgit/linux/kernel/git/linville/wireless.git/patch/?id=aaa2ced15ad8dca8048666c9f70736424d696a6b
>>
>
> Arend, much thanks and an apology for not checking the patches. I will try this out ASAP.
>
> Is the (presumedly) low RX gain also a known problem with brcmsmac on BCM4313?

The patch is in 3.12-rc2. There have been more reports on that, but it 
still needs to be investigated. Can you provide content of 
/sys/kernel/debug/brcmsmac/bcma*/hardware? You need to have 
CONFIG_BRCMDBG selected.

Regards,
Arend

> --
> 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: Pull request: ath 20130930
From: Kalle Valo @ 2013-09-24  7:33 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless, ath10k, ath6kl-devel
In-Reply-To: <87wqmyz5i9.fsf@kamboji.qca.qualcomm.com>

Hi John,

when you start merging again please consider taking this pull request
which I sent too late last time. It should be still valid.

I have more patches queued up during the merge window, but I'm planning
to send them after you have pulled this. But if you prefer to have
everything in one go, I can do that as well.

Kalle

Kalle Valo <kvalo@qca.qualcomm.com> writes:

> Hi John,
>
> here are latest ath10k changes, I hope it's still time to get these to
> 3.12. The changelog for the pull request:
>
> Bartosz dropped support for qca98xx hw1.0 hardware from ath10k, it's
> just too much to support it. Michal added support for the new firmware
> interface. Marek fixed WEP in AP and IBSS mode. Rest of the changes are
> minor fixes or cleanups.
>
> The following changes since commit 9d0e2f0772d394060bf3b17cd1f3a35574365103:
>
>   ath6kl: Fix invalid pointer access on fuzz testing with AP mode (2013-08-07 10:58:59 +0300)
>
> are available in the git repository at:
>
>   git://github.com/kvalo/ath.git for-linville
>
> for you to fetch changes up to 763b8cd31493f452094fd0eaeedb8cad37c756a2:
>
>   ath10k: add chip_id file to debugfs (2013-09-03 09:59:53 +0300)
>
> ----------------------------------------------------------------
> Bartosz Markowski (2):
>       ath10k: Remove qca98xx hw1.0 support
>       ath10k: update supported FW build version
>
> Janusz Dziedzic (2):
>       ath10k: setup peer UAPSD flag correctly
>       ath10k: check allocation errors in CE
>
> Kalle Valo (10):
>       ath10k: remove un ar_pci->cacheline_sz field
>       ath10k: pci: make host_ce_config_wlan[] more readable
>       ath10k: make target_ce_config_wlan more readable
>       ath10k: remove void pointer from struct ath10k_pci_compl
>       ath10k: convert ath10k_pci_reg_read/write32() to take struct ath10k
>       ath10k: clean up ath10k_ce_completed_send_next_nolock()
>       ath10k: convert ath10k_pci_wake() to return
>       ath10k: simplify ath10k_ce_init() wake up handling
>       ath10k: check chip id from the soc register during probe
>       ath10k: add chip_id file to debugfs
>
> Marek Puzyniak (1):
>       ath10k: fix WEP in AP and IBSS mode
>
> Michal Kazior (15):
>       ath10k: clean up monitor start code
>       ath10k: use sizeof(*var) in kmalloc
>       ath10k: clean up PCI completion states
>       ath10k: print errcode when CE ring setup fails
>       ath10k: fix HTT service setup
>       ath10k: implement 802.3 SNAP rx decap type A-MSDU handling
>       ath10k: plug possible memory leak in WMI
>       ath10k: add support for firmware newer than 636
>       ath10k: add support for HTT 3.0
>       ath10k: use inline ce_state structure
>       ath10k: remove ce_op_state
>       ath10k: remove unused ce_attr parameters
>       ath10k: rename hif_ce_pipe_info to ath10k_pci_pipe
>       ath10k: rename ce_state to ath10k_ce_pipe
>       ath10k: rename ce_ring_state to ath10k_ce_ring
>
> Mohammed Shafi Shajakhan (1):
>       ath10k: Fix mutex unlock balance
>
>  drivers/net/wireless/ath/ath10k/ce.c     |  291 +++++++++++++-------------
>  drivers/net/wireless/ath/ath10k/ce.h     |   74 +++----
>  drivers/net/wireless/ath/ath10k/core.c   |   46 +++--
>  drivers/net/wireless/ath/ath10k/core.h   |   13 +-
>  drivers/net/wireless/ath/ath10k/debug.c  |   23 ++-
>  drivers/net/wireless/ath/ath10k/htc.c    |    8 +-
>  drivers/net/wireless/ath/ath10k/htt.c    |   19 +-
>  drivers/net/wireless/ath/ath10k/htt.h    |    6 +-
>  drivers/net/wireless/ath/ath10k/htt_rx.c |   12 +-
>  drivers/net/wireless/ath/ath10k/htt_tx.c |   74 +++++--
>  drivers/net/wireless/ath/ath10k/hw.h     |   19 +-
>  drivers/net/wireless/ath/ath10k/mac.c    |   22 +-
>  drivers/net/wireless/ath/ath10k/pci.c    |  325 ++++++++++++++++++++----------
>  drivers/net/wireless/ath/ath10k/pci.h    |   73 +++----
>  drivers/net/wireless/ath/ath10k/wmi.c    |   33 ++-
>  drivers/net/wireless/ath/ath10k/wmi.h    |   16 +-
>  16 files changed, 626 insertions(+), 428 deletions(-)

-- 
Kalle Valo

^ permalink raw reply

* Re: [RFC 0/4] ath10k: improve RX performance
From: Kalle Valo @ 2013-09-24  7:29 UTC (permalink / raw)
  To: Michal Kazior; +Cc: ath10k, linux-wireless
In-Reply-To: <CA+BoTQnxqgz_90+Q8_FhM6PZh8CEW12dOA+ZGqHeYjK=Bbu9wA@mail.gmail.com>

Michal Kazior <michal.kazior@tieto.com> writes:

> On 24 September 2013 08:42, Kalle Valo <kvalo@qca.qualcomm.com> wrote:
>> Michal Kazior <michal.kazior@tieto.com> writes:
>>
>>> This patchset gives clear RX performance
>>> improvement on AP135. Throughput is at least
>>> doubled (300mbps -> 600mbps, UDP RX, 2x2).
>>>
>>> Patches depend on my RFC patch "mac80211: support
>>> reporting A-MSDU subframes individually".
>>
>> Preferably I can apply these changes only after the mac80211 patch goes
>> to net-next (to avoid unnecessary rebasing). Is there a way to
>> workaround the need for the mac80211 patch in ath10k so that we could
>> apply these patches ASAP? And once the mac80211 patch is commited we
>> could just remove the workaround in ath10k.
>
> The workaround could be to clear the retransmission flag when
> reporting A-MSDU frames individually.

That sounds very good. Can you do that and resend the patchset, please?

-- 
Kalle Valo

^ permalink raw reply

* Re: [RFC 0/4] ath10k: improve RX performance
From: Michal Kazior @ 2013-09-24  7:19 UTC (permalink / raw)
  To: Kalle Valo; +Cc: ath10k, linux-wireless
In-Reply-To: <87mwn2bu0i.fsf@kamboji.qca.qualcomm.com>

On 24 September 2013 08:42, Kalle Valo <kvalo@qca.qualcomm.com> wrote:
> Michal Kazior <michal.kazior@tieto.com> writes:
>
>> This patchset gives clear RX performance
>> improvement on AP135. Throughput is at least
>> doubled (300mbps -> 600mbps, UDP RX, 2x2).
>>
>> Patches depend on my RFC patch "mac80211: support
>> reporting A-MSDU subframes individually".
>
> Preferably I can apply these changes only after the mac80211 patch goes
> to net-next (to avoid unnecessary rebasing). Is there a way to
> workaround the need for the mac80211 patch in ath10k so that we could
> apply these patches ASAP? And once the mac80211 patch is commited we
> could just remove the workaround in ath10k.

The workaround could be to clear the retransmission flag when
reporting A-MSDU frames individually.


Michał.

^ permalink raw reply

* Re: [RFC] ath10k: replenish HTT RX buffers in a tasklet
From: Kalle Valo @ 2013-09-24  6:59 UTC (permalink / raw)
  To: Michal Kazior; +Cc: ath10k, linux-wireless
In-Reply-To: <CA+BoTQ=Tg1Qv8qXqw8++hXiDsBXyeQKDjYesWdNg25ORMQJGRg@mail.gmail.com>

Michal Kazior <michal.kazior@tieto.com> writes:

> On 24 September 2013 08:22, Kalle Valo <kvalo@qca.qualcomm.com> wrote:
>> Michal Kazior <michal.kazior@tieto.com> writes:
>>
>>> This fixes system starvation when under heavy RX
>>> traffic. This problem could be observed on AP135
>>> and led to watchdog resetting the platform.
>>>
>>> Patch starves FW RX ring buffer by progressively
>>> replenishing buffers to auto-balance the RX
>>> handled to the host system.
>>>
>>> Signed-off-by: Michal Kazior <michal.kazior@tieto.com>
>>
>> Looks good to me. I suspect there is a better way to do this in long
>> term, but this looks like a viable short term solution.
>>
>> Does it decrease throughput in a noticeable way?
>
> I have yet to observe any regressions.

Good. If you think the patch should be applied please resend it as
"[PATCH]" so that I can apply it.

-- 
Kalle Valo

^ permalink raw reply

* Re: [RFC] ath10k: replenish HTT RX buffers in a tasklet
From: Michal Kazior @ 2013-09-24  6:51 UTC (permalink / raw)
  To: Kalle Valo; +Cc: ath10k, linux-wireless
In-Reply-To: <87r4cebuxm.fsf@kamboji.qca.qualcomm.com>

On 24 September 2013 08:22, Kalle Valo <kvalo@qca.qualcomm.com> wrote:
> Michal Kazior <michal.kazior@tieto.com> writes:
>
>> This fixes system starvation when under heavy RX
>> traffic. This problem could be observed on AP135
>> and led to watchdog resetting the platform.
>>
>> Patch starves FW RX ring buffer by progressively
>> replenishing buffers to auto-balance the RX
>> handled to the host system.
>>
>> Signed-off-by: Michal Kazior <michal.kazior@tieto.com>
>
> Looks good to me. I suspect there is a better way to do this in long
> term, but this looks like a viable short term solution.
>
> Does it decrease throughput in a noticeable way?

I have yet to observe any regressions.


Michał.

^ permalink raw reply

* Re: [RFC 3/4] ath10k: cleanup RX decap handling
From: Kalle Valo @ 2013-09-24  6:47 UTC (permalink / raw)
  To: Michal Kazior; +Cc: ath10k, linux-wireless
In-Reply-To: <CA+BoTQ=q9ojX4bp61rExY7b9Pk+=Zpg_qNxfXYvt8eXscdC=bA@mail.gmail.com>

Michal Kazior <michal.kazior@tieto.com> writes:

> On 16 September 2013 23:30, Kalle Valo <kvalo@qca.qualcomm.com> wrote:
>> Michal Kazior <michal.kazior@tieto.com> writes:
>>
>>> Native Wifi frames are always decapped as non-QoS
>>> data frames meaning mac80211 couldn't set sk_buff
>>> priority properly. The patch fixes this by using
>>> the original 802.11 header.
>>>
>>> Signed-off-by: Michal Kazior <michal.kazior@tieto.com>
>>
>> The patch title doesn't seem to match with the content. Unless I'm
>> mistaken it looks like you are adding native wifi frame format support
>> and doing some cleanup at the same time. They should be in separate
>> patches.
>
> You're right. I'll split it up.
>
> Nwifi was supported, however QoS Data frames were reported as Data
> frames though.

Oh, ok. It would be good to document that in the commit log as well.

>>>       case RX_MSDU_DECAP_RAW:
>>> -             /* remove trailing FCS */
>>> -             skb_trim(skb, skb->len - 4);
>>> +             skb_trim(skb, skb->len - FCS_LEN);
>>>               break;
>>
>> Please keep the comment still
>
> Why? The point of the comment was to explain the literal "4". Using
> define makes the comment redundant.

I know it's redundant, but this is just to improve readability.

>>>       case RX_MSDU_DECAP_ETHERNET2_DIX:
>>> -             /* macaddr[6] + macaddr[6] + ethertype[2] */
>>> -             skb_pull(skb, 6 + 6 + 2);
>>> +             rfc1042 = hdr;
>>> +             rfc1042 += roundup(hdr_len, 4);
>>> +             rfc1042 += roundup(ath10k_htt_rx_crypto_param_len(enctype), 4);
>>> +
>>> +             skb_pull(skb, sizeof(struct ethhdr));
>>> +             memcpy(skb_push(skb, sizeof(struct rfc1042_hdr)),
>>> +                    rfc1042, sizeof(struct rfc1042_hdr));
>>> +             memcpy(skb_push(skb, hdr_len), hdr, hdr_len);
>>>               break;
>>
>> Ditto.
>
> Comment was supposed to explain where those numbers come from. Using
> structures explains it now.

Sure, the structures are very good here. But like above, having small
comments improve readability. Think of it as a "title" or something like
that.

>>>       case RX_MSDU_DECAP_8023_SNAP_LLC:
>>> -             /* macaddr[6] + macaddr[6] + len[2] */
>>> -             /* we don't need this for non-A-MSDU */
>>> -             skb_pull(skb, 6 + 6 + 2);
>>> +             skb_pull(skb, sizeof(struct amsdu_subframe_hdr));
>>> +             memcpy(skb_push(skb, hdr_len), hdr, hdr_len);
>>>               break;
>>
>> And here.
>
> Ditto.

Same here :)

-- 
Kalle Valo

^ permalink raw reply

* Re: [RFC 0/4] ath10k: improve RX performance
From: Kalle Valo @ 2013-09-24  6:42 UTC (permalink / raw)
  To: Michal Kazior; +Cc: ath10k, linux-wireless
In-Reply-To: <1379335757-15180-1-git-send-email-michal.kazior@tieto.com>

Michal Kazior <michal.kazior@tieto.com> writes:

> This patchset gives clear RX performance
> improvement on AP135. Throughput is at least
> doubled (300mbps -> 600mbps, UDP RX, 2x2).
>
> Patches depend on my RFC patch "mac80211: support
> reporting A-MSDU subframes individually".

Preferably I can apply these changes only after the mac80211 patch goes
to net-next (to avoid unnecessary rebasing). Is there a way to
workaround the need for the mac80211 patch in ath10k so that we could
apply these patches ASAP? And once the mac80211 patch is commited we
could just remove the workaround in ath10k.

-- 
Kalle Valo

^ permalink raw reply

* Re: [RFC] ath10k: replenish HTT RX buffers in a tasklet
From: Kalle Valo @ 2013-09-24  6:22 UTC (permalink / raw)
  To: Michal Kazior; +Cc: ath10k, linux-wireless
In-Reply-To: <1379509691-19904-1-git-send-email-michal.kazior@tieto.com>

Michal Kazior <michal.kazior@tieto.com> writes:

> This fixes system starvation when under heavy RX
> traffic. This problem could be observed on AP135
> and led to watchdog resetting the platform.
>
> Patch starves FW RX ring buffer by progressively
> replenishing buffers to auto-balance the RX
> handled to the host system.
>
> Signed-off-by: Michal Kazior <michal.kazior@tieto.com>

Looks good to me. I suspect there is a better way to do this in long
term, but this looks like a viable short term solution.

Does it decrease throughput in a noticeable way?

-- 
Kalle Valo

^ permalink raw reply

* Re: [PATCH v5 1/2] Bluetooth: btmrvl: add setup handler
From: Marcel Holtmann @ 2013-09-24  4:23 UTC (permalink / raw)
  To: Bing Zhao
  Cc: linux-bluetooth@vger.kernel.org, Gustavo Padovan, Johan Hedberg,
	linux-wireless@vger.kernel.org, Mike Frysinger, Hyuckjoo Lee,
	Amitkumar Karwar
In-Reply-To: <477F20668A386D41ADCC57781B1F70430F44C59418@SC-VEXCH1.marvell.com>

Hi Bing,

>>> -	btmrvl_send_module_cfg_cmd(priv, MODULE_BRINGUP_REQ);
>>> +	hdev->setup = btmrvl_setup;
>> 
>> just to make sure you guys understand how ->setup() works. It is only called once. Bringing the
>> adapter down and up again does not call ->setup() a second time. So do you guys need this setup_done
>> variable and if so, then you need to be a bit more verbose and help me understand why.
> 
> It's observed that sometimes the setup handler is called twice when Bluetooth daemon is running in background. We will rebase to latest commit on bluetooth-next tree and test again. If the issue is gone with the latest code in -next tree we will remove the setup_done flag.

that is a bug. It should only be ever called once. Could this be due to RFKILL issue we had? Please re-test with Johan's patches applied and check if it makes a difference. Otherwise please send some logs since we want to get this fixed.

Regards

Marcel


^ permalink raw reply

* Re: [PATCH v5 2/2] Bluetooth: btmrvl: add calibration data download support
From: Marcel Holtmann @ 2013-09-24  4:21 UTC (permalink / raw)
  To: Bing Zhao
  Cc: linux-bluetooth@vger.kernel.org, Gustavo Padovan, Johan Hedberg,
	linux-wireless@vger.kernel.org, Mike Frysinger, Hyuckjoo Lee,
	Amitkumar Karwar
In-Reply-To: <477F20668A386D41ADCC57781B1F70430F44C59423@SC-VEXCH1.marvell.com>

Hi Bing,

>>> +	cmd = (struct btmrvl_cmd *)skb->data;
>>> +	cmd->ocf_ogf =
>>> +		cpu_to_le16(hci_opcode_pack(OGF, BT_CMD_LOAD_CONFIG_DATA));
>>> +	cmd->length = BT_CMD_DATA_SIZE;
>>> +	cmd->data[0] = 0x00;
>>> +	cmd->data[1] = 0x00;
>>> +	cmd->data[2] = 0x00;
>>> +	cmd->data[3] = BT_CMD_DATA_SIZE - 4;
>> 
>> why not use __hci_cmd_sync() here. It is designed to be used from ->setup() where it is guaranteed
>> that the HCI request lock is held. And it is guaranteed that ->setup() is executed in a workqueue.
> 
> The reason of not using __hci_cmd_sync() is that we are sending vendor specific command here (MRVL_VENDOR_PKT). The __hci_cmd_sync seems handle HCI_COMMAND_PKT only.
> Please let us know if you have any suggestion to solve this problem.

what is a MRVL_VENDOR_PKT actually?

If you guys are not using standard HCI command/event for vendor operation, then this obviously does not fit. However a similar model might make sense instead of manually building packets all the time.

Regards

Marcel


^ permalink raw reply

* [PATCH] mac80211: use exact-size allocation for authentication frame
From: Fred Zhou @ 2013-09-24  2:33 UTC (permalink / raw)
  To: johannes; +Cc: linux-wireless, Fred Zhou

The authentication frame has a fixied size of 30 bytes
(including header, algo num, trans seq num, and status)
followed by a variable challenge text.
Allocate using exact size, instead of over-allocation
by sizeof(ieee80211_mgmt).

Signed-off-by: Fred Zhou <fred.zy@gmail.com>
---
 net/mac80211/util.c |    5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index e1b34a1..674ab12 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -1083,9 +1083,10 @@ void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata,
 	struct sk_buff *skb;
 	struct ieee80211_mgmt *mgmt;
 	int err;
-
+
+	/* 30 = header + auth_algo + auth_transaction + status_code */
 	skb = dev_alloc_skb(local->hw.extra_tx_headroom +
-			    sizeof(*mgmt) + 6 + extra_len);
+			    30 + extra_len);
 	if (!skb)
 		return;
 
-- 
1.7.9.5


^ permalink raw reply related

* Re: brcmsmac causes soft lockup in 3.12-rc1
From: Michael Stolovitzsky @ 2013-09-24  0:52 UTC (permalink / raw)
  To: linux-wireless
In-Reply-To: <523FF83D.8030103@broadcom.com>

On Mon, Sep 23, 2013 at 10:13:49AM +0200, Arend van Spriel wrote:
> On 09/22/2013 12:34 AM, Michael Stolovitzsky wrote:
> >Hi,
> >
> >On 3.12-rc1, modprobe brcmsmac causes a soft lockup (trace #1), effectively killing the box. This is a Lenovo S206
> >with BCM4313 (14e4:4727), which I believe is a bluetooth combo board. After a while,
> >RCU scheduler code detects a lockup (trace #2).
> >
> >This did not happen in 3.11.1, although brcmsmac hasn't worked on this machine
> >as far as I remember. In  the previous kernels (~3.2.0+), it loads, but the
> >reception is extremely weak - you must be within few meters to the AP, and the card would
> >die after several minutes. The proprietary wl.ko driver works fine.
> >
> >I've attached the dmesg output, the kernel configuration and the output of lspci -vnn.
> >I'm comfortable with experimenting; please let me know how I can help here.
> 
> A fix for this problem has been submitted to John. I think it is in
> transit to mainline so probably will be in 3.12-rc2.
> 
> Here the URL of the patch:
> 
> https://git.kernel.org/cgit/linux/kernel/git/linville/wireless.git/patch/?id=aaa2ced15ad8dca8048666c9f70736424d696a6b
> 

Arend, much thanks and an apology for not checking the patches. I will try this out ASAP.

Is the (presumedly) low RX gain also a known problem with brcmsmac on BCM4313?

^ permalink raw reply

* pull request: bluetooth 2013-09-23
From: Gustavo Padovan @ 2013-09-23 21:00 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, linux-bluetooth, linux-kernel

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

Hi John,

First Bluetooth fixes to 3.12, it includes:

* 3 patches to add device id for 3 new hardwares.

* 2 patches from Johan to fix the rfkill behaviour during setup stage

* a small clean up in the rfcomm TTY code that fixes a potential racy
condition (by Gianluca Anzolin)

* 2 fixes to proper set encryption key size and security level in the
peripheral role of Bluetooth LE devices. (by Andre Guedes)

* a fix for dealing devices where pairing is not necessary, we were keeping
the Bluetooth ACL connection alive for too much time. (by Syam Sidhardhan)

Please pull or let me know of any problems! Thanks!


	Gustavo

---
The following changes since commit f4e1a4d3ecbb9e42bdf8e7869ee8a4ebfa27fb20:

  rt2800: change initialization sequence to fix system freeze (2013-09-09 14:44:34 -0400)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth master

for you to fetch changes up to 5bcecf325378218a8e248bb6bcae96ec7362f8ef:

  Bluetooth: btusb: Add support for Belkin F8065bf (2013-09-23 17:44:25 -0300)

----------------------------------------------------------------
Andre Guedes (2):
      Bluetooth: Fix security level for peripheral role
      Bluetooth: Fix encryption key size for peripheral role

Gianluca Anzolin (1):
      Bluetooth: don't release the port in rfcomm_dev_state_change()

Johan Hedberg (2):
      Bluetooth: Introduce a new HCI_RFKILLED flag
      Bluetooth: Fix rfkill functionality during the HCI setup stage

Ken O'Brien (1):
      Bluetooth: btusb: Add support for Belkin F8065bf

Peng Chen (1):
      Bluetooth: Add a new PID/VID 0cf3/e005 for AR3012.

Raphael Kubo da Costa (1):
      Bluetooth: Add support for BCM20702A0 [0b05, 17cb]

Syam Sidhardhan (1):
      Bluetooth: Fix ACL alive for long in case of non pariable devices

 drivers/bluetooth/ath3k.c   |  2 ++
 drivers/bluetooth/btusb.c   |  5 +++++
 include/net/bluetooth/hci.h |  1 +
 net/bluetooth/hci_core.c    | 26 ++++++++++++++++++++------
 net/bluetooth/hci_event.c   |  6 +++++-
 net/bluetooth/l2cap_core.c  |  7 +++++++
 net/bluetooth/rfcomm/tty.c  | 35 ++---------------------------------
 7 files changed, 42 insertions(+), 40 deletions(-)


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

^ permalink raw reply

* Re: [brcmfmac] BUG: unable to handle kernel paging request at ffffffff82196446
From: Arend van Spriel @ 2013-09-23 20:07 UTC (permalink / raw)
  To: Fengguang Wu
  Cc: Hante Meuleman, John W. Linville, linux-kernel, linux-wireless,
	brcm80211-dev-list
In-Reply-To: <20130923121402.GA12626@localhost>

On 09/23/2013 02:14 PM, Fengguang Wu wrote:
> On Mon, Sep 16, 2013 at 11:15:53AM +0200, Arend van Spriel wrote:
>> On 09/02/2013 12:23 PM, Fengguang Wu wrote:
>>> Greetings,
>>>
>>> I got the below dmesg and the first bad commit is
>>
>> Hi Fengguang,
>>
>> I could not reproduce this issue. Could you retest with the attached
>> patch file applied and let me know if that fixes the problem?
>
> Yeah it fixed the problem: no more oops in 1000 kernel boot tests. Thank you!

Whoa, 1000 boots. Thank you for being so thorough :-)

Regards,
Arend



^ permalink raw reply

* [PATCH 3.12 2/2] cw1200: Use a threaded oneshot irq handler for cw1200_spi
From: Solomon Peachy @ 2013-09-23 20:00 UTC (permalink / raw)
  To: linux-wireless; +Cc: Solomon Peachy
In-Reply-To: <1379966404-7047-1-git-send-email-pizza@shaftnet.org>

This supercedes the older patch ("cw1200: Don't perform SPI transfers in
interrupt context") that badly attempted to fix this problem.

This is a far simpler solution, which has the added benefit of 
actually working.

Signed-off-by: Solomon Peachy <pizza@shaftnet.org>
---
 drivers/net/wireless/cw1200/cw1200_spi.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/cw1200/cw1200_spi.c b/drivers/net/wireless/cw1200/cw1200_spi.c
index 5a64ac9..899cad3 100644
--- a/drivers/net/wireless/cw1200/cw1200_spi.c
+++ b/drivers/net/wireless/cw1200/cw1200_spi.c
@@ -250,9 +250,10 @@ static int cw1200_spi_irq_subscribe(struct hwbus_priv *self)
 
 	pr_debug("SW IRQ subscribe\n");
 
-	ret = request_any_context_irq(self->func->irq, cw1200_spi_irq_handler,
-				      IRQF_TRIGGER_HIGH,
-				      "cw1200_wlan_irq", self);
+	ret = request_threaded_irq(self->func->irq, NULL,
+				   cw1200_spi_irq_handler,
+				   IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
+				   "cw1200_wlan_irq", self);
 	if (WARN_ON(ret < 0))
 		goto exit;
 
-- 
1.8.3.1


^ permalink raw reply related


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