Linux wireless drivers development
 help / color / mirror / Atom feed
* RE: [PATCH v4] Bluetooth: btmrvl: add calibration data download support
From: Amitkumar Karwar @ 2013-09-16 15:51 UTC (permalink / raw)
  To: 'Mike Frysinger', Bing Zhao
  Cc: linux-bluetooth@vger.kernel.org, Marcel Holtmann, Gustavo Padovan,
	Johan Hedberg, linux-wireless@vger.kernel.org, Hyuckjoo Lee
In-Reply-To: <CAAbOScnG8RHWbPdjq6=e=EBJPr_f6+R4o36f3h0T=NxGgQt7AQ@mail.gmail.com>

Hi Mike,

Thanks for your comments. We will take care of them in updated version.

> 
> On Fri, Sep 13, 2013 at 7:32 PM, Bing Zhao wrote:
> > --- a/drivers/bluetooth/btmrvl_main.c
> > +++ b/drivers/bluetooth/btmrvl_main.c
> >
> > +static int btmrvl_parse_cal_cfg(const u8 *src, u32 len, u8 *dst, u32
> dst_size)
> 
> would be nice if you put a comment above this func explaining the
> expected format.  otherwise, we see arbitrary parsing with no idea if
> it's correct.

Sure. We will add below information.

Calibrated input data should contain hex bytes separated by space or
new line character. Here is an example
00 1C 01 37 FF FF FF FF 02 04 7F 01
CE BA 00 00 00 2D C6 C0 00 00 00 00
00 F0 00 00

> 
> > +       while ((s - src) < len) {
> > +               if (isspace(*s)) {
> > +                       s++;
> > +                       continue;
> > +               }
> > +
> > +               if (isxdigit(*s)) {
> > +                       if ((d - dst) >= dst_size) {
> > +                               BT_ERR("calibration data file too
> big!!!");
> > +                               return -EINVAL;
> > +                       }
> > +
> > +                       memcpy(tmp, s, 2);
> > +
> > +                       ret = kstrtou8(tmp, 16, d++);
> > +                       if (ret < 0)
> > +                               return ret;
> > +
> > +                       s += 2;
> > +               } else {
> > +                       s++;
> > +               }
> > +       }
> 
> so if it's a space, you skip it.  if it's a hexdigit, you parse two
> bytes.  if it's anything else, you skip it.  i'd imagine the "non
> space and non hexdigit" case should throw a warning if not reject the
> file out right.  otherwise, if you want to keep this logic, punt the
> explicit "isspace" check.

You are right. Rejecting the file containing non space, non new line and non hexdigit character makes sense.

> 
> you might also copy one more byte than you should ?  your limit is "(s
> - src) < len", yet the isxdigit code always copies two bytes.

Thanks for pointing this out. We will replace "(s - src) < len" with "(s -src) <= (len - 2)". 

> 
> > +static int btmrvl_load_cal_data(struct btmrvl_private *priv,
> > +                               u8 *config_data)
> > +{
> > +       struct sk_buff *skb;
> > +       struct btmrvl_cmd *cmd;
> > +       int i;
> > +
> > +       skb = bt_skb_alloc(sizeof(*cmd), GFP_ATOMIC);
> 
> maybe i'm unfamiliar with bluetooth and this is common, but why is
> your code so special as to require GFP_ATOMIC allocations ?

GFP_ATOMIC was used to match other usages in bluetooth code.
I just found that as per commit "Remove GFP_ATOMIC usage from l2cap_core.c"(commit id: 8bcde1f2ab..), since bluetooth core is now running in process context, we don't need to use GFP_ATOMIC.

We will replace it with GFP_KERNEL in updated version.

> 
> > +       for (i = 4; i < BT_CMD_DATA_SIZE; i++)
> > +               cmd->data[i] = config_data[(i/4)*8 - 1 - i];
> 
> style nit, but there should be spacing around those math operators.
> ignoring the fact that this is some funky funky buffer offsets.
> 
> i = 4
>  config_data[(4 / 4) * 8 - 1 - 4] ->
>  config_data[8 - 1 - 4] ->
>  config_data[3]
> 
> i = 5
>  config_data[(5 / 4) * 8 - 1 - 5] ->
>  config_data[8 - 1 - 5] ->
>  config_data[2]
> 
> i = 6
>  config_data[(6 / 4) * 8 - 1 - 6] ->
>  config_data[8 - 1 - 6] ->
>  config_data[1]
> 
> i = 7
>  config_data[(7 / 4) * 8 - 1 - 7] ->
>  config_data[8 - 1 - 7] ->
>  config_data[0]
> 
> i = 8
>  config_data[(8 / 4) * 8 - 1 - 8] ->
>  config_data[16 - 1 - 8] ->
>  config_data[7]
> 
> i = {4,5,6,7} -> config_data[{3,2,1,0}]
> i = {8,9,10,11} -> config_data[{7,6,5,4}]
> 
> that really could do with a comment explaining the mapping of input
> bytes to output bytes.

Sure. We add a comment here.
Actually each 4 bytes are being swapped. Considering 4 byte SDIO header offset, it becomes
input{3, 2, 1, 0} -> output{0+4, 1+4, 2+4, 3+4}

Regards,
Amitkumar Karwar

> -mike

^ permalink raw reply

* Re: guidance on struct alignment for rtl8192cu driver
From: Larry Finger @ 2013-09-16 15:33 UTC (permalink / raw)
  To: Seth Forshee; +Cc: Jason Andrews, linux-wireless@vger.kernel.org
In-Reply-To: <20130916143506.GC18593@thinkpad-t410>

On 09/16/2013 09:35 AM, Seth Forshee wrote:
> On Sat, Sep 14, 2013 at 09:08:34AM -0500, Larry Finger wrote:
>> On 09/14/2013 12:36 AM, Jason Andrews wrote:
>>> I'm using an ASUS USB N13 on an ARM platform with the rtl8192cu driver.
>>> Linux kernel is 3.10 so I probably don't have the latest and greatest driver.
>>>
>>> When I booted I got an ARM alignment trap caused by the driver.
>>>
>>> I determined the cause was the 1st argument to spin_lock_irqsave() has an unaligned address.
>>>
>>> By trial-and-error I found that if I edit wifi.h and insert 2 dummy bytes into the rtl_priv struct just above priv (last variable) the locks work and the driver works fine.
>>>
>>> What is the recommended way to make sure the last variable in the rtl_priv struct (u8 priv[0]) is aligned on a 4 byte boundary so the driver works on ARM machines?
>>
>> There are a lot of improvements for this driver in 3.11. The
>> backports release has that code. In addition, I am currently working
>> at improving the power management for 3.13.
>>
>> The presence of unaligned variables that cause alignment traps on
>> ARM does not surprise me as I test only on x86 and ppc
>> architectures. I now own a Raspberry Pi and I will soon be testing
>> with it as well.
>>
>> What does surprise me is that the first argument in all the calls to
>> spin_lock_irqsave() are contained within the rtl_locks struct and
>> everything there should be aligned. Perhaps some ARM expert will
>> know why aligning the last item in the rtl_priv struct fixes the
>> problem.
>
> Depending on architecture version and configuration ARM may or may not
> allow unaligned accesses. Even when allowed there is a cost though, so
> it's better to properly align the data. In the past this would have
> always meant 4-byte alignment, but my ARM experience is a bit dated now
> and I don't know about 64-bit ARM. That variable-size array probably
> only has byte alignment.
>
>> As far as I know, the proper way to do a 4-byte alignment is as in
>> the following patch:
>>
>> Index: wireless-testing-save/drivers/net/wireless/rtlwifi/wifi.h
>> ===================================================================
>> --- wireless-testing-save.orig/drivers/net/wireless/rtlwifi/wifi.h
>> +++ wireless-testing-save/drivers/net/wireless/rtlwifi/wifi.h
>> @@ -2057,7 +2057,7 @@ struct rtl_priv {
>>   	  that it points to the data allocated
>>   	  beyond  this structure like:
>>   	  rtl_pci_priv or rtl_usb_priv */
>> -	u8 priv[0];
>> +	u8 __aligned(4) priv[0];
>>   };
>
> __attribute__((aligned)) might be a safer bet, as this will align it to
> the largest alignment that could possibly be needed.

Seth,

Thanks for the help. So far, I have not heard if my original patch helps or not. 
When, and if, I hear, I will use your suggestion for the final patch.

Larry



^ permalink raw reply

* Re: guidance on struct alignment for rtl8192cu driver
From: Seth Forshee @ 2013-09-16 14:35 UTC (permalink / raw)
  To: Larry Finger; +Cc: Jason Andrews, linux-wireless@vger.kernel.org
In-Reply-To: <52346DE2.9090904@lwfinger.net>

On Sat, Sep 14, 2013 at 09:08:34AM -0500, Larry Finger wrote:
> On 09/14/2013 12:36 AM, Jason Andrews wrote:
> >I'm using an ASUS USB N13 on an ARM platform with the rtl8192cu driver.
> >Linux kernel is 3.10 so I probably don't have the latest and greatest driver.
> >
> >When I booted I got an ARM alignment trap caused by the driver.
> >
> >I determined the cause was the 1st argument to spin_lock_irqsave() has an unaligned address.
> >
> >By trial-and-error I found that if I edit wifi.h and insert 2 dummy bytes into the rtl_priv struct just above priv (last variable) the locks work and the driver works fine.
> >
> >What is the recommended way to make sure the last variable in the rtl_priv struct (u8 priv[0]) is aligned on a 4 byte boundary so the driver works on ARM machines?
> 
> There are a lot of improvements for this driver in 3.11. The
> backports release has that code. In addition, I am currently working
> at improving the power management for 3.13.
> 
> The presence of unaligned variables that cause alignment traps on
> ARM does not surprise me as I test only on x86 and ppc
> architectures. I now own a Raspberry Pi and I will soon be testing
> with it as well.
> 
> What does surprise me is that the first argument in all the calls to
> spin_lock_irqsave() are contained within the rtl_locks struct and
> everything there should be aligned. Perhaps some ARM expert will
> know why aligning the last item in the rtl_priv struct fixes the
> problem.

Depending on architecture version and configuration ARM may or may not
allow unaligned accesses. Even when allowed there is a cost though, so
it's better to properly align the data. In the past this would have
always meant 4-byte alignment, but my ARM experience is a bit dated now
and I don't know about 64-bit ARM. That variable-size array probably
only has byte alignment.

> As far as I know, the proper way to do a 4-byte alignment is as in
> the following patch:
> 
> Index: wireless-testing-save/drivers/net/wireless/rtlwifi/wifi.h
> ===================================================================
> --- wireless-testing-save.orig/drivers/net/wireless/rtlwifi/wifi.h
> +++ wireless-testing-save/drivers/net/wireless/rtlwifi/wifi.h
> @@ -2057,7 +2057,7 @@ struct rtl_priv {
>  	  that it points to the data allocated
>  	  beyond  this structure like:
>  	  rtl_pci_priv or rtl_usb_priv */
> -	u8 priv[0];
> +	u8 __aligned(4) priv[0];
>  };

__attribute__((aligned)) might be a safer bet, as this will align it to
the largest alignment that could possibly be needed.

Seth

^ permalink raw reply

* Re: [Ilw] [RFC 0/5] mac80211/iwlwifi: quiesce before restart hw
From: Stanislaw Gruszka @ 2013-09-16 14:10 UTC (permalink / raw)
  To: Grumbach, Emmanuel; +Cc: ilw@linux.intel.com, linux-wireless@vger.kernel.org
In-Reply-To: <0BA3FCBA62E2DC44AF3030971E174FB301DAF383@HASMSX103.ger.corp.intel.com>

On Sun, Sep 15, 2013 at 08:31:34AM +0000, Grumbach, Emmanuel wrote:
> BTW - I guess a dump_stack doesn't trigger the abrt, does it?

No, dump_stack does not trigger abrt, WARN* or BUG_ON (from process
context) is required for that.

Thanks
Stanislaw

^ permalink raw reply

* [RFC 4/4] ath10k: align RX frames properly
From: Michal Kazior @ 2013-09-16 12:49 UTC (permalink / raw)
  To: ath10k; +Cc: linux-wireless, Michal Kazior
In-Reply-To: <1379335757-15180-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
CPU cache thrashing on lower end host machines and
very poor performance.

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

* [RFC 3/4] ath10k: cleanup RX decap handling
From: Michal Kazior @ 2013-09-16 12:49 UTC (permalink / raw)
  To: ath10k; +Cc: linux-wireless, Michal Kazior
In-Reply-To: <1379335757-15180-1-git-send-email-michal.kazior@tieto.com>

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>
---
 drivers/net/wireless/ath/ath10k/htt_rx.c |   70 +++++++++++++++++-------------
 1 file changed, 41 insertions(+), 29 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/htt_rx.c b/drivers/net/wireless/ath/ath10k/htt_rx.c
index dad584f..083dd9a 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);
@@ -652,6 +652,19 @@ static void ath10k_htt_rx_amsdu(struct ath10k_htt *htt,
 			skb_trim(skb, skb->len - FCS_LEN);
 			break;
 		case RX_MSDU_DECAP_NATIVE_WIFI:
+			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);
+
+			hdr = (struct ieee80211_hdr *)hdr_buf;
+			hdr_len = ieee80211_hdrlen(hdr->frame_control);
+			memcpy(skb_push(skb, hdr_len), hdr, hdr_len);
+
+			hdr = (struct ieee80211_hdr *)skb->data;
+			qos = ieee80211_get_qos_ctl(hdr);
+			qos[0] &= ~IEEE80211_QOS_CTL_A_MSDU_PRESENT;
+			memcpy(ieee80211_get_DA(hdr), addr, ETH_ALEN);
 			break;
 		case RX_MSDU_DECAP_ETHERNET2_DIX:
 			decap_len = 0;
@@ -687,6 +700,9 @@ 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;
+	u8 addr[ETH_ALEN];
+	int hdr_len;
+	void *rfc1042;
 
 	/* This shouldn't happen. If it does than it may be a FW bug. */
 	if (skb->next) {
@@ -700,48 +716,44 @@ 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 */
+		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);
+
+		hdr = (struct ieee80211_hdr *)rxd->rx_hdr_status;
+		hdr_len = ieee80211_hdrlen(hdr->frame_control);
+		memcpy(skb_push(skb, hdr_len), hdr, hdr_len);
+
+		hdr = (struct ieee80211_hdr *)skb->data;
+		memcpy(ieee80211_get_DA(hdr), addr, ETH_ALEN);
 		break;
 	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;
 	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;
 	}
 
-	if (fmt == RX_MSDU_DECAP_ETHERNET2_DIX) {
-		void *llc;
-		int llclen;
-
-		llclen = 8;
-		llc  = hdr;
-		llc += roundup(ieee80211_hdrlen(hdr->frame_control), 4);
-		llc += roundup(ath10k_htt_rx_crypto_param_len(enctype), 4);
-
-		skb_push(skb, llclen);
-		memcpy(skb->data, llc, llclen);
-	}
-
-	if (fmt >= RX_MSDU_DECAP_ETHERNET2_DIX) {
-		int len = ieee80211_hdrlen(hdr->frame_control);
-		skb_push(skb, len);
-		memcpy(skb->data, hdr, len);
-	}
-
 	info->skb = skb;
 	info->encrypt_type = enctype;
 
-- 
1.7.9.5


^ permalink raw reply related

* [RFC 1/4] ath10k: report A-MSDU subframes individually
From: Michal Kazior @ 2013-09-16 12:49 UTC (permalink / raw)
  To: ath10k; +Cc: linux-wireless, Michal Kazior
In-Reply-To: <1379335757-15180-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.

This at least doubles RX performance on AP135.

Signed-off-by: Michal Kazior <michal.kazior@tieto.com>
---
 drivers/net/wireless/ath/ath10k/htt.h    |    1 +
 drivers/net/wireless/ath/ath10k/htt_rx.c |  189 ++++++++++--------------------
 drivers/net/wireless/ath/ath10k/txrx.c   |    5 +
 3 files changed, 71 insertions(+), 124 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/htt.h b/drivers/net/wireless/ath/ath10k/htt.h
index e090902..9bcff3e 100644
--- a/drivers/net/wireless/ath/ath10k/htt.h
+++ b/drivers/net/wireless/ath/ath10k/htt.h
@@ -1181,6 +1181,7 @@ struct htt_rx_info {
 		u32 info2;
 	} rate;
 	bool fcs_err;
+	bool amsdu_more;
 };
 
 struct ath10k_htt {
diff --git a/drivers/net/wireless/ath/ath10k/htt_rx.c b/drivers/net/wireless/ath/ath10k/htt_rx.c
index a39fbf4..dad584f 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,92 @@ 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;
-	}
-
-	/* 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);
-	}
+	hdr = (void *)rxd->rx_hdr_status;
+	hdr_len = ieee80211_hdrlen(hdr->frame_control);
+	memcpy(hdr_buf, hdr, hdr_len);
 
 	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);
-		}
-
-		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));
+		skb->ip_summed = ath10k_htt_rx_get_csum_state(skb);
 
-			/* 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_buf, hdr_len);
+			break;
+		case RX_MSDU_DECAP_8023_SNAP_LLC:
+			memcpy(skb_push(skb, hdr_len), hdr_buf, hdr_len);
+			break;
 		}
 
+		info->skb = skb;
+		info->amsdu_more = (skb->next != NULL);
+		info->encrypt_type = enctype;
 		skb = skb->next;
-	}
+		info->skb->next = NULL;
 
-	info->skb = amsdu;
-	info->encrypt_type = enctype;
-
-	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 +702,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 +744,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 +817,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 +891,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 +903,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 68b6fae..ed54bce 100644
--- a/drivers/net/wireless/ath/ath10k/txrx.c
+++ b/drivers/net/wireless/ath/ath10k/txrx.c
@@ -261,6 +261,9 @@ void ath10k_process_rx(struct ath10k *ar, struct htt_rx_info *info)
 	if (info->fcs_err)
 		status->flag |= RX_FLAG_FAILED_FCS_CRC;
 
+	if (info->amsdu_more)
+		status->flag |= RX_FLAG_AMSDU_MORE;
+
 	status->signal = info->signal;
 
 	spin_lock_bh(&ar->data_lock);
@@ -293,6 +296,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

* [RFC 2/4] ath10k: document decap modes
From: Michal Kazior @ 2013-09-16 12:49 UTC (permalink / raw)
  To: ath10k; +Cc: linux-wireless, Michal Kazior
In-Reply-To: <1379335757-15180-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

* [RFC 0/4] ath10k: improve RX performance
From: Michal Kazior @ 2013-09-16 12:49 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).

Patches depend on my RFC patch "mac80211: support
reporting A-MSDU subframes individually".


Michal.


Michal Kazior (4):
  ath10k: report A-MSDU subframes individually
  ath10k: document decap modes
  ath10k: cleanup RX decap handling
  ath10k: align RX frames properly

 drivers/net/wireless/ath/ath10k/htt.h     |    1 +
 drivers/net/wireless/ath/ath10k/htt_rx.c  |  251 ++++++++++++-----------------
 drivers/net/wireless/ath/ath10k/hw.h      |    6 +-
 drivers/net/wireless/ath/ath10k/rx_desc.h |   24 ++-
 drivers/net/wireless/ath/ath10k/txrx.c    |    5 +
 5 files changed, 135 insertions(+), 152 deletions(-)

-- 
1.7.9.5


^ permalink raw reply

* [RFC] mac80211: support reporting A-MSDU subframes individually
From: Michal Kazior @ 2013-09-16 12:38 UTC (permalink / raw)
  To: johannes; +Cc: linux-wireless, Michal Kazior

Some devices may not be able to report A-MSDUs in
single buffers. Drivers for such devices were
forced to re-assemble A-MSDUs which would then
be eventually disassembled by mac80211. This could
lead to CPU cache thrashing and poor performance.

Since A-MSDU has a single sequence number all
subframes share it. This was in conflict with
retransmission/duplication recovery
(IEEE802.11-2012: 9.3.2.10).

Patch introduces a new flag that is meant to be
set for all individually reported A-MSDU subframes
except the last one. This ensures the
last_seq_ctrl is updated after the last subframe
is processed. If an A-MSDU is actually a duplicate
transmission all reported subframes will be
properly discarded.

Signed-off-by: Michal Kazior <michal.kazior@tieto.com>
---
 include/net/mac80211.h |   10 ++++++++++
 net/mac80211/rx.c      |    2 +-
 2 files changed, 11 insertions(+), 1 deletion(-)

diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 06ffae8..f8f049d 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -829,6 +829,15 @@ ieee80211_tx_info_clear_status(struct ieee80211_tx_info *info)
  * @RX_FLAG_STBC_MASK: STBC 2 bit bitmask. 1 - Nss=1, 2 - Nss=2, 3 - Nss=3
  * @RX_FLAG_10MHZ: 10 MHz (half channel) was used
  * @RX_FLAG_5MHZ: 5 MHz (quarter channel) was used
+ * @RX_FLAG_AMSDU_MORE: Some drivers may prefer to report separate A-MSDU
+ *	subframes instead of a one huge frame for performance reasons.
+ *	All, but the last MSDU from an A-MSDU should have this flag set. E.g.
+ *	if an A-MSDU has 3 frames, the first 2 must have the flag set, while
+ *	the 3rd (last) one must not have this flag set. The flag is used to
+ *	deal with retransmission/duplication recovery properly since A-MSDU
+ *	subframes share the same sequence number. Reported subframes can be
+ *	either regular MSDU or singly A-MSDUs. Subframes must not be
+ *	interleaved with other frames.
  */
 enum mac80211_rx_flags {
 	RX_FLAG_MMIC_ERROR		= BIT(0),
@@ -859,6 +868,7 @@ enum mac80211_rx_flags {
 	RX_FLAG_STBC_MASK		= BIT(26) | BIT(27),
 	RX_FLAG_10MHZ			= BIT(28),
 	RX_FLAG_5MHZ			= BIT(29),
+	RX_FLAG_AMSDU_MORE		= BIT(30),
 };
 
 #define RX_FLAG_STBC_SHIFT		26
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 8e908e1..43bee02 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -995,7 +995,7 @@ ieee80211_rx_h_check(struct ieee80211_rx_data *rx)
 				rx->sta->num_duplicates++;
 			}
 			return RX_DROP_UNUSABLE;
-		} else
+		} else if (!(status->flag & RX_FLAG_AMSDU_MORE))
 			rx->sta->last_seq_ctrl[rx->seqno_idx] = hdr->seq_ctrl;
 	}
 
-- 
1.7.9.5


^ permalink raw reply related

* [PATCH] mwifiex: fix command timeout with SDIO interrupts enabled
From: Daniel Mack @ 2013-09-16 11:39 UTC (permalink / raw)
  To: linux-wireless
  Cc: s.neumann, afenkart, bzhao, linville, johannes.berg, Daniel Mack

We've been hunting a command timeout issue in the mwifiex driver which
occurs on an AM33xx platform when Andreas Fenkart's omap_hsmmc SDIO IRQ
patches are applied (they are not yet in the mainline kernel). We first
suspected the mmc host driver to be racy, but that wasn't the case.

I dug a little through the changes between 3.7 and 3.10 on the mwifiex
driver, and it turned out that the culprit is 601216e12 ("mwifiex:
process RX packets in SDIO IRQ thread directly"), especially the
situation where mwifiex_main_process() bails when mwifiex_processing is
set.

In other words: if an SDIO irq arrives while the driver is processing
mwifiex_main_process() from the work queue, we effectively loose the
interrupt, which then results in a command timeout.

I've written a little test case scenario that calls
mwifiex_dump_station_info() through the SIOCGIWSTATS ioctl excessively,
and that reproduces the problem after a couple of seconds already:

  https://gist.github.com/zonque/6579314


The fix for this issue is quite simple and works very well.


Thanks,
Daniel


Daniel Mack (1):
  mwifiex: queue main work from main process when bailing on races

 drivers/net/wireless/mwifiex/main.c | 1 +
 1 file changed, 1 insertion(+)

-- 
1.8.3.1


^ permalink raw reply

* [PATCH 1/1] mwifiex: queue main work from main process when bailing on races
From: Daniel Mack @ 2013-09-16 11:39 UTC (permalink / raw)
  To: linux-wireless
  Cc: s.neumann, afenkart, bzhao, linville, johannes.berg, Daniel Mack,
	stable
In-Reply-To: <1379331546-30617-1-git-send-email-zonque@gmail.com>

Queue main_work in case mwifiex_main_process() bails due to an already
processed transaction. This is particularly necessary because
mwifiex_main_process() is called from both the SDIO interrupt handler
and the workqueue. In case an interrupt occurs while the main process
is currently executed from the workqueue, the interrupt is lost,
resulting in a command timeout and consequently a card reset.

I'm marking this for stable kernel in version 3.7+, because on our
platform, the issue appears since 601216e12c ("mwifiex: process RX
packets in SDIO IRQ thread directly") went in.

Signed-off-by: Daniel Mack <zonque@gmail.com>
Reported-by: Sven Neumann <s.neumann@raumfeld.com>
Reported-by: Andreas Fenkart <andreas.fenkart@streamunlimited.com>
Cc: Bing Zhao <bzhao@marvell.com>
Cc: <stable@vger.kernel.org> [v3.7+]
---
 drivers/net/wireless/mwifiex/main.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/net/wireless/mwifiex/main.c b/drivers/net/wireless/mwifiex/main.c
index ff4ed96..0700bc2 100644
--- a/drivers/net/wireless/mwifiex/main.c
+++ b/drivers/net/wireless/mwifiex/main.c
@@ -235,6 +235,7 @@ int mwifiex_main_process(struct mwifiex_adapter *adapter)
 	/* Check if already processing */
 	if (adapter->mwifiex_processing) {
 		spin_unlock_irqrestore(&adapter->main_proc_lock, flags);
+		queue_work(adapter->workqueue, &adapter->main_work);
 		goto exit_main_proc;
 	} else {
 		adapter->mwifiex_processing = true;
-- 
1.8.3.1


^ permalink raw reply related

* Re: [brcmfmac] BUG: unable to handle kernel paging request at ffffffff82196446
From: Fengguang Wu @ 2013-09-16  9:50 UTC (permalink / raw)
  To: Arend van Spriel
  Cc: Hante Meuleman, John W. Linville, linux-kernel, linux-wireless,
	brcm80211-dev-list
In-Reply-To: <5236CC49.7000206@broadcom.com>

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?

Sure. I've queued the patch for testing. Will report back 1-2 days
later.

Thanks,
Fengguang

^ permalink raw reply

* RE: [PATCH 5/7: rtlwifi: Fix smatch warning in pci.c
From: David Laight @ 2013-09-16  9:26 UTC (permalink / raw)
  To: Larry Finger, linville; +Cc: linux-wireless, netdev
In-Reply-To: <1379094304-22041-6-git-send-email-Larry.Finger@lwfinger.net>

> Smatch reports the following:
>   CHECK   drivers/net/wireless/rtlwifi/pci.c
> drivers/net/wireless/rtlwifi/pci.c:739 _rtl_pci_rx_interrupt() warn: assigning (-98) to unsigned
> variable 'stats.noise'
> 
> This problem is fixed by changing the value to 256 - 98.
> 
> Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net>
> ---
>  drivers/net/wireless/rtlwifi/pci.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/net/wireless/rtlwifi/pci.c b/drivers/net/wireless/rtlwifi/pci.c
> index 703f839..bf498f5 100644
> --- a/drivers/net/wireless/rtlwifi/pci.c
> +++ b/drivers/net/wireless/rtlwifi/pci.c
> @@ -736,7 +736,7 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw)
> 
>  	struct rtl_stats stats = {
>  		.signal = 0,
> -		.noise = -98,
> +		.noise = 158,	/* -98 dBm */
>  		.rate = 0,
>  	};
>  	int index = rtlpci->rx_ring[rx_queue_idx].idx;

That doesn't look nice at all.
Something like (unsigned int)-98 would be slightly better,
but it looks as though something is actually wrong with
the type of 'noise' itself.

	David




^ permalink raw reply

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

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

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?

Regards,
Arend

> commit 668761ac01d6f5a36b8e5a24d4e154550e2c4c3b
> Author: Hante Meuleman <meuleman@broadcom.com>
> Date:   Fri Apr 12 10:55:55 2013 +0200
>
>      brcmfmac: define and use platform specific data for SDIO.
>
>      This patch adds support for platform specific data for SDIO
>      fullmac devices. Currently OOB interrupts are configured by Kconfig
>      BRCMFMAC_SDIO_OOB but that is now determined dynamically by checking
>      availibility of platform data.
>
>      Cc: Hauke Mehrtens <hauke@hauke-m.de>
>      Reviewed-by: Arend Van Spriel <arend@broadcom.com>
>      Reviewed-by: Franky (Zhenhui) Lin <frankyl@broadcom.com>
>      Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
>      Reviewed-by: Piotr Haber <phaber@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>
>
>
> [   48.966342] Switched to clocksource tsc
> [   48.970002] kernel tried to execute NX-protected page - exploit attempt? (uid: 0)
> [   48.970851] BUG: unable to handle kernel paging request at ffffffff82196446
> [   48.970957] IP: [<ffffffff82196446>] classes_init+0x26/0x26
> [   48.970957] PGD 1e76067 PUD 1e77063 PMD f388063 PTE 8000000002196163
> [   48.970957] Oops: 0011 [#1]
> [   48.970957] CPU: 0 PID: 17 Comm: kworker/0:1 Not tainted 3.11.0-rc7-00444-gc52dd7f #23
> [   48.970957] Workqueue: events brcmf_driver_init
> [   48.970957] task: ffff8800001d2000 ti: ffff8800001d4000 task.ti: ffff8800001d4000
> [   48.970957] RIP: 0010:[<ffffffff82196446>]  [<ffffffff82196446>] classes_init+0x26/0x26
> [   48.970957] RSP: 0000:ffff8800001d5d40  EFLAGS: 00000286
> [   48.970957] RAX: 0000000000000001 RBX: ffffffff820c5620 RCX: 0000000000000000
> [   48.970957] RDX: 0000000000000001 RSI: ffffffff816f7380 RDI: ffffffff820c56c0
> [   48.970957] RBP: ffff8800001d5d50 R08: ffff8800001d2508 R09: 0000000000000002
> [   48.970957] R10: 0000000000000000 R11: 0001f7ce298c5620 R12: ffff8800001c76b0
> [   48.970957] R13: ffffffff81e91d40 R14: 0000000000000000 R15: ffff88000e0ce300
> [   48.970957] FS:  0000000000000000(0000) GS:ffffffff81e84000(0000) knlGS:0000000000000000
> [   48.970957] CS:  0010 DS: 0000 ES: 0000 CR0: 000000008005003b
> [   48.970957] CR2: ffffffff82196446 CR3: 0000000001e75000 CR4: 00000000000006b0
> [   48.970957] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
> [   48.970957] DR3: 0000000000000000 DR6: 0000000000000000 DR7: 0000000000000000
> [   48.970957] Stack:
> [   48.970957]  ffffffff816f7df8 ffffffff820c5620 ffff8800001d5d60 ffffffff816eeec9
> [   48.970957]  ffff8800001d5de0 ffffffff81073dc5 ffffffff81073d68 ffff8800001d5db8
> [   48.970957]  0000000000000086 ffffffff820c5620 ffffffff824f7fd0 0000000000000000
> [   48.970957] Call Trace:
> [   48.970957]  [<ffffffff816f7df8>] ? brcmf_sdio_init+0x18/0x70
> [   48.970957]  [<ffffffff816eeec9>] brcmf_driver_init+0x9/0x10
> [   48.970957]  [<ffffffff81073dc5>] process_one_work+0x1d5/0x480
> [   48.970957]  [<ffffffff81073d68>] ? process_one_work+0x178/0x480
> [   48.970957]  [<ffffffff81074188>] worker_thread+0x118/0x3a0
> [   48.970957]  [<ffffffff81074070>] ? process_one_work+0x480/0x480
> [   48.970957]  [<ffffffff8107aa17>] kthread+0xe7/0xf0
> [   48.970957]  [<ffffffff810829f7>] ? finish_task_switch.constprop.57+0x37/0xd0
> [   48.970957]  [<ffffffff8107a930>] ? __kthread_parkme+0x80/0x80
> [   48.970957]  [<ffffffff81a6923a>] ret_from_fork+0x7a/0xb0
> [   48.970957]  [<ffffffff8107a930>] ? __kthread_parkme+0x80/0x80
> [   48.970957] Code: cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc <cc> cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc
> [   48.970957] RIP  [<ffffffff82196446>] classes_init+0x26/0x26
> [   48.970957]  RSP <ffff8800001d5d40>
> [   48.970957] CR2: ffffffff82196446
> [   48.970957] ---[ end trace 62980817cd525f14 ]---
>
> git bisect start v3.10 v3.9 --
> git bisect  bad 20b4fb485227404329e41ad15588afad3df23050  # 12:16      9-  Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
> git bisect good 19b344efa35dbc253e2d10403dafe6aafda73c56  # 17:54    800+  Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid
> git bisect  bad 20074f357da4a637430aec2879c9d864c5d2c23c  # 18:03      1-  filter: fix va_list build error
> git bisect good 953c96e0d85615d1ab1f100e525d376053294dc2  # 21:38    800+  tg3: Use bool not int
> git bisect  bad 4de41bef3e075dbc787f7c53b3562f23295f1d6d  # 22:21    102-  wil6210: Use cached copy of Tx descriptor
> git bisect good e73dcfbf061b524fe9aaef56cf3c2e234a45ec19  # 01:19    800+  Bluetooth: hidp: fix sending output reports on intr channel
> git bisect good c79490e1b5ebf35415147fe06f02d8e77ccfe6d4  # 07:18    800+  NFC: pn533: Avoid function declarations
> git bisect  bad 06d961a8e210035bff7e82f466107f9ab4a8fd94  # 07:49     55-  mac80211/minstrel: use the new rate control API
> git bisect good 97990a060e6757f48b931a3946b17c1c4362c3fb  # 10:43    800+  nl80211: allow using wdev identifiers to get scan results
> git bisect  bad 31ed07dc1e83b7926ce8ee2215ea21599a215990  # 11:15     77-  brcmfmac: remove ifidx variable from brcmf_fws_process_skb()
> git bisect good 1e9ab4dd258ecbb0f1c377fd4dbe227cdb93d9bd  # 14:16    800+  brcmfmac: setup SDIO reset behavior
> git bisect  bad 668761ac01d6f5a36b8e5a24d4e154550e2c4c3b  # 15:03     38-  brcmfmac: define and use platform specific data for SDIO.
> git bisect good 369508c5656db290f09b32d213effeea6c1431b8  # 18:30    800+  brcmfmac: Add 43143 SDIO support.
> git bisect good 979c29205ffa607c59ba2c9f9c083b967d356c97  # 19:54    800+  brcmfmac: Add drive strength programming for SDIO 43143.
> git bisect good 979c29205ffa607c59ba2c9f9c083b967d356c97  # 05:19   2400+  brcmfmac: Add drive strength programming for SDIO 43143.
> git bisect  bad c52dd7f94c5d5386413cb95462ac802847fa5f3a  # 05:20      0-  Merge remote-tracking branch 'sound/for-linus' into devel-cairo-x86_64-201308281454
> git bisect  bad d9eda0fae1394ea1e1c59c94d4a120ad9c06e64a  # 11:50     27-  Merge tag 'fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc
> git bisect  bad 797c8d18e6804f054e68555e6cf827827b6a073c  # 12:47      1-  Add linux-next specific files for 20130830
>
> Thanks,
> Fengguang
>


[-- Attachment #2: 0001-brcmfmac-obtain-platform-data-upon-module-initializa.patch --]
[-- Type: text/plain, Size: 7964 bytes --]

>From f2d01b847944dc329ed4fd420acb270319dc853d Mon Sep 17 00:00:00 2001
From: Arend van Spriel <arend@broadcom.com>
Date: Fri, 13 Sep 2013 15:36:05 +0200
Subject: [PATCH] brcmfmac: obtain platform data upon module initialization

The driver uses platform_driver_probe() to obtain platform data
if any. However, that function is placed in the .init section so
it must be called upon driver module initialization.

The problem was reported by Fenguang Wu resulting in a kernel
oops because the .init section was already freed.

[   48.966342] Switched to clocksource tsc
[   48.970002] kernel tried to execute NX-protected page - exploit attempt? (uid: 0)
[   48.970851] BUG: unable to handle kernel paging request at ffffffff82196446
[   48.970957] IP: [<ffffffff82196446>] classes_init+0x26/0x26
[   48.970957] PGD 1e76067 PUD 1e77063 PMD f388063 PTE 8000000002196163
[   48.970957] Oops: 0011 [#1]
[   48.970957] CPU: 0 PID: 17 Comm: kworker/0:1 Not tainted 3.11.0-rc7-00444-gc52dd7f #23
[   48.970957] Workqueue: events brcmf_driver_init
[   48.970957] task: ffff8800001d2000 ti: ffff8800001d4000 task.ti: ffff8800001d4000
[   48.970957] RIP: 0010:[<ffffffff82196446>]  [<ffffffff82196446>] classes_init+0x26/0x26
[   48.970957] RSP: 0000:ffff8800001d5d40  EFLAGS: 00000286
[   48.970957] RAX: 0000000000000001 RBX: ffffffff820c5620 RCX: 0000000000000000
[   48.970957] RDX: 0000000000000001 RSI: ffffffff816f7380 RDI: ffffffff820c56c0
[   48.970957] RBP: ffff8800001d5d50 R08: ffff8800001d2508 R09: 0000000000000002
[   48.970957] R10: 0000000000000000 R11: 0001f7ce298c5620 R12: ffff8800001c76b0
[   48.970957] R13: ffffffff81e91d40 R14: 0000000000000000 R15: ffff88000e0ce300
[   48.970957] FS:  0000000000000000(0000) GS:ffffffff81e84000(0000) knlGS:0000000000000000
[   48.970957] CS:  0010 DS: 0000 ES: 0000 CR0: 000000008005003b
[   48.970957] CR2: ffffffff82196446 CR3: 0000000001e75000 CR4: 00000000000006b0
[   48.970957] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
[   48.970957] DR3: 0000000000000000 DR6: 0000000000000000 DR7: 0000000000000000
[   48.970957] Stack:
[   48.970957]  ffffffff816f7df8 ffffffff820c5620 ffff8800001d5d60 ffffffff816eeec9
[   48.970957]  ffff8800001d5de0 ffffffff81073dc5 ffffffff81073d68 ffff8800001d5db8
[   48.970957]  0000000000000086 ffffffff820c5620 ffffffff824f7fd0 0000000000000000
[   48.970957] Call Trace:
[   48.970957]  [<ffffffff816f7df8>] ? brcmf_sdio_init+0x18/0x70
[   48.970957]  [<ffffffff816eeec9>] brcmf_driver_init+0x9/0x10
[   48.970957]  [<ffffffff81073dc5>] process_one_work+0x1d5/0x480
[   48.970957]  [<ffffffff81073d68>] ? process_one_work+0x178/0x480
[   48.970957]  [<ffffffff81074188>] worker_thread+0x118/0x3a0
[   48.970957]  [<ffffffff81074070>] ? process_one_work+0x480/0x480
[   48.970957]  [<ffffffff8107aa17>] kthread+0xe7/0xf0
[   48.970957]  [<ffffffff810829f7>] ? finish_task_switch.constprop.57+0x37/0xd0
[   48.970957]  [<ffffffff8107a930>] ? __kthread_parkme+0x80/0x80
[   48.970957]  [<ffffffff81a6923a>] ret_from_fork+0x7a/0xb0
[   48.970957]  [<ffffffff8107a930>] ? __kthread_parkme+0x80/0x80
[   48.970957] Code: cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc
cc cc cc cc cc cc <cc> cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc
[   48.970957] RIP  [<ffffffff82196446>] classes_init+0x26/0x26
[   48.970957]  RSP <ffff8800001d5d40>
[   48.970957] CR2: ffffffff82196446
[   48.970957] ---[ end trace 62980817cd525f14 ]---

Reported-by: Fengguang Wu <fengguang.wu@intel.com>
Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
Signed-off-by: Arend van Spriel <arend@broadcom.com>
---
 .../net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c |   28 +++++++++-----------
 drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h  |    3 ++-
 .../net/wireless/brcm80211/brcmfmac/dhd_linux.c    |   14 +++++-----
 drivers/net/wireless/brcm80211/brcmfmac/usb.c      |    2 +-
 4 files changed, 24 insertions(+), 23 deletions(-)

diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c
index f849d73..40dcfe5 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c
@@ -459,8 +459,6 @@ static struct sdio_driver brcmf_sdmmc_driver = {
 
 static int brcmf_sdio_pd_probe(struct platform_device *pdev)
 {
-	int ret;
-
 	brcmf_dbg(SDIO, "Enter\n");
 
 	brcmfmac_sdio_pdata = pdev->dev.platform_data;
@@ -468,11 +466,7 @@ static int brcmf_sdio_pd_probe(struct platform_device *pdev)
 	if (brcmfmac_sdio_pdata->power_on)
 		brcmfmac_sdio_pdata->power_on();
 
-	ret = sdio_register_driver(&brcmf_sdmmc_driver);
-	if (ret)
-		brcmf_err("sdio_register_driver failed: %d\n", ret);
-
-	return ret;
+	return 0;
 }
 
 static int brcmf_sdio_pd_remove(struct platform_device *pdev)
@@ -495,6 +489,15 @@ static struct platform_driver brcmf_sdio_pd = {
 	}
 };
 
+void brcmf_sdio_register(void)
+{
+	int ret;
+
+	ret = sdio_register_driver(&brcmf_sdmmc_driver);
+	if (ret)
+		brcmf_err("sdio_register_driver failed: %d\n", ret);
+}
+
 void brcmf_sdio_exit(void)
 {
 	brcmf_dbg(SDIO, "Enter\n");
@@ -505,18 +508,13 @@ void brcmf_sdio_exit(void)
 		sdio_unregister_driver(&brcmf_sdmmc_driver);
 }
 
-void brcmf_sdio_init(void)
+void __init brcmf_sdio_init(void)
 {
 	int ret;
 
 	brcmf_dbg(SDIO, "Enter\n");
 
 	ret = platform_driver_probe(&brcmf_sdio_pd, brcmf_sdio_pd_probe);
-	if (ret == -ENODEV) {
-		brcmf_dbg(SDIO, "No platform data available, registering without.\n");
-		ret = sdio_register_driver(&brcmf_sdmmc_driver);
-	}
-
-	if (ret)
-		brcmf_err("driver registration failed: %d\n", ret);
+	if (ret == -ENODEV)
+		brcmf_dbg(SDIO, "No platform data available.\n");
 }
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h
index f7c1985..74156f8 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h
@@ -156,10 +156,11 @@ extern int brcmf_bus_start(struct device *dev);
 #ifdef CONFIG_BRCMFMAC_SDIO
 extern void brcmf_sdio_exit(void);
 extern void brcmf_sdio_init(void);
+extern void brcmf_sdio_register(void);
 #endif
 #ifdef CONFIG_BRCMFMAC_USB
 extern void brcmf_usb_exit(void);
-extern void brcmf_usb_init(void);
+extern void brcmf_usb_register(void);
 #endif
 
 #endif				/* _BRCMF_BUS_H_ */
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
index b45a4e8..5b330c8 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
@@ -1230,21 +1230,23 @@ u32 brcmf_get_chip_info(struct brcmf_if *ifp)
 	return bus->chip << 4 | bus->chiprev;
 }
 
-static void brcmf_driver_init(struct work_struct *work)
+static void brcmf_driver_register(struct work_struct *work)
 {
-	brcmf_debugfs_init();
-
 #ifdef CONFIG_BRCMFMAC_SDIO
-	brcmf_sdio_init();
+	brcmf_sdio_register();
 #endif
 #ifdef CONFIG_BRCMFMAC_USB
-	brcmf_usb_init();
+	brcmf_usb_register();
 #endif
 }
-static DECLARE_WORK(brcmf_driver_work, brcmf_driver_init);
+static DECLARE_WORK(brcmf_driver_work, brcmf_driver_register);
 
 static int __init brcmfmac_module_init(void)
 {
+	brcmf_debugfs_init();
+#ifdef CONFIG_BRCMFMAC_SDIO
+	brcmf_sdio_init();
+#endif
 	if (!schedule_work(&brcmf_driver_work))
 		return -EBUSY;
 
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/usb.c b/drivers/net/wireless/brcm80211/brcmfmac/usb.c
index 39e01a7..f4aea47 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/usb.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/usb.c
@@ -1539,7 +1539,7 @@ void brcmf_usb_exit(void)
 	brcmf_release_fw(&fw_image_list);
 }
 
-void brcmf_usb_init(void)
+void brcmf_usb_register(void)
 {
 	brcmf_dbg(USB, "Enter\n");
 	INIT_LIST_HEAD(&fw_image_list);
-- 
1.7.10.4


^ permalink raw reply related

* Re: [PATCH] ar5523: Add USB ID of D-Link WUA-2340 rev A1
From: Pontus Fuchs @ 2013-09-16  6:54 UTC (permalink / raw)
  To: Albert Pool; +Cc: linux-wireless, linville
In-Reply-To: <1378751790-2465-1-git-send-email-albertpool@solcon.nl>

On 2013-09-09 20:36, Albert Pool wrote:
> Signed-off-by: Albert Pool <albertpool@solcon.nl>
> Reported-by: Michael Landrum <landrummd@gmail.com>
> ---
>   drivers/net/wireless/ath/ar5523/ar5523.c |    1 +
>   1 file changed, 1 insertion(+)
>
> diff --git a/drivers/net/wireless/ath/ar5523/ar5523.c b/drivers/net/wireless/ath/ar5523/ar5523.c
> index 17d7fec..280fc3d 100644
> --- a/drivers/net/wireless/ath/ar5523/ar5523.c
> +++ b/drivers/net/wireless/ath/ar5523/ar5523.c
> @@ -1762,6 +1762,7 @@ static struct usb_device_id ar5523_id_table[] = {
>   	AR5523_DEVICE_UX(0x2001, 0x3a00),	/* Dlink / DWLAG132 */
>   	AR5523_DEVICE_UG(0x2001, 0x3a02),	/* Dlink / DWLG132 */
>   	AR5523_DEVICE_UX(0x2001, 0x3a04),	/* Dlink / DWLAG122 */
> +	AR5523_DEVICE_UG(0x07d1, 0x3a07),	/* D-Link / WUA-2340 rev A1 */
>   	AR5523_DEVICE_UG(0x1690, 0x0712),	/* Gigaset / AR5523 */
>   	AR5523_DEVICE_UG(0x1690, 0x0710),	/* Gigaset / SMCWUSBTG */
>   	AR5523_DEVICE_UG(0x129b, 0x160c),	/* Gigaset / USB stick 108
>


Acked-by: Pontus Fuchs <pontus.fuchs@gmail.com>

Thanks,

Pontus

^ permalink raw reply

* ath9k pending patches
From: Sujith Manoharan @ 2013-09-16  6:04 UTC (permalink / raw)
  To: linux-wireless; +Cc: John Linville

Hi,

Stable patches (includes Felix's TX fixes):
http://msujith.org/patches/wl/Sep-16-2013/ath9k-pending-stable.patch

Patches for -next:
http://msujith.org/patches/wl/Sep-16-2013/ath9k-pending-next.patch

Sujith

^ permalink raw reply

* [PATCH] ath9k: Fix regression in LNA diversity
From: Sujith Manoharan @ 2013-09-16  5:57 UTC (permalink / raw)
  To: John Linville; +Cc: linux-wireless, stable

From: Sujith Manoharan <c_manoha@qca.qualcomm.com>

The commit "ath9k: Optimize LNA check" tried
to use the "rs_firstaggr" flag to optimize the LNA
combining algorithm when processing subframes in
an A-MPDU. This doesn't appear to work well in practice,
so revert it and use the old method of relying on
"rs_moreaggr".

Cc: stable@vger.kernel.org
Signed-off-by: Sujith Manoharan <c_manoha@qca.qualcomm.com>
---
 drivers/net/wireless/ath/ath9k/recv.c | 7 -------
 1 file changed, 7 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c
index 4ee472a..ab9e3a8 100644
--- a/drivers/net/wireless/ath/ath9k/recv.c
+++ b/drivers/net/wireless/ath/ath9k/recv.c
@@ -1270,13 +1270,6 @@ static void ath9k_antenna_check(struct ath_softc *sc,
 		return;
 
 	/*
-	 * All MPDUs in an aggregate will use the same LNA
-	 * as the first MPDU.
-	 */
-	if (rs->rs_isaggr && !rs->rs_firstaggr)
-		return;
-
-	/*
 	 * Change the default rx antenna if rx diversity
 	 * chooses the other antenna 3 times in a row.
 	 */
-- 
1.8.4


^ permalink raw reply related

* [PATCH 3/3] ath9k: Remove incorrect diversity initialization
From: Sujith Manoharan @ 2013-09-16  5:07 UTC (permalink / raw)
  To: John Linville; +Cc: linux-wireless
In-Reply-To: <1379308021-20891-1-git-send-email-sujith@msujith.org>

From: Sujith Manoharan <c_manoha@qca.qualcomm.com>

Fast antenna diversity is required only for single chain
chips and the diversity initialization is done in the
per-family board setup routines. Enabling of diversity
should be done based on the calibrated EEPROM/OTP data,
doing it for all chips is incorrect.

Remove the code that sets the fast_div bit for all cards, since
the documentation for the AR_PHY_CCK_DETECT register says:

reg 642: sig_detect_cck
enable_ant_fast_div : Only used for single chain chips.

Signed-off-by: Sujith Manoharan <c_manoha@qca.qualcomm.com>
---
 drivers/net/wireless/ath/ath9k/ar5008_phy.c | 3 ---
 drivers/net/wireless/ath/ath9k/ar9003_phy.c | 3 ---
 2 files changed, 6 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/ar5008_phy.c b/drivers/net/wireless/ath/ath9k/ar5008_phy.c
index 9e4e2a6..cb6435e 100644
--- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c
@@ -631,9 +631,6 @@ static void ar5008_hw_override_ini(struct ath_hw *ah,
 		REG_WRITE(ah, AR_PCU_MISC_MODE2, val);
 	}
 
-	REG_SET_BIT(ah, AR_PHY_CCK_DETECT,
-		    AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV);
-
 	if (AR_SREV_9280_20_OR_LATER(ah))
 		return;
 	/*
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
index ec37213..0131ba2 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
@@ -632,9 +632,6 @@ static void ar9003_hw_override_ini(struct ath_hw *ah)
 	       AR_PCU_MISC_MODE2_CFP_IGNORE;
 	REG_WRITE(ah, AR_PCU_MISC_MODE2, val);
 
-	REG_SET_BIT(ah, AR_PHY_CCK_DETECT,
-		    AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV);
-
 	if (AR_SREV_9462(ah) || AR_SREV_9565(ah)) {
 		REG_WRITE(ah, AR_GLB_SWREG_DISCONT_MODE,
 			  AR_GLB_SWREG_DISCONT_EN_BT_WLAN);
-- 
1.8.4


^ permalink raw reply related

* [PATCH 2/3] ath9k: Handle FATAL interrupts correctly
From: Sujith Manoharan @ 2013-09-16  5:07 UTC (permalink / raw)
  To: John Linville; +Cc: linux-wireless
In-Reply-To: <1379308021-20891-1-git-send-email-sujith@msujith.org>

From: Sujith Manoharan <c_manoha@qca.qualcomm.com>

When a FATAL interrupt is received, a full chip reset is
required, which is done in the main tasklet. But since
the reset routine is scheduled as a work item, make sure
that interrupts are not enabled in the tasklet before the
reset is done.

Signed-off-by: Sujith Manoharan <c_manoha@qca.qualcomm.com>
---
 drivers/net/wireless/ath/ath9k/main.c | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index e4f6590..cdb3b1e 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -362,6 +362,13 @@ void ath9k_tasklet(unsigned long data)
 			type = RESET_TYPE_BB_WATCHDOG;
 
 		ath9k_queue_reset(sc, type);
+
+		/*
+		 * Increment the ref. counter here so that
+		 * interrupts are enabled in the reset routine.
+		 */
+		atomic_inc(&ah->intr_ref_cnt);
+		ath_dbg(common, ANY, "FATAL: Skipping interrupts\n");
 		goto out;
 	}
 
@@ -400,10 +407,9 @@ void ath9k_tasklet(unsigned long data)
 
 	ath9k_btcoex_handle_interrupt(sc, status);
 
-out:
 	/* re-enable hardware interrupt */
 	ath9k_hw_enable_interrupts(ah);
-
+out:
 	spin_unlock(&sc->sc_pcu_lock);
 	ath9k_ps_restore(sc);
 }
-- 
1.8.4


^ permalink raw reply related

* [PATCH 1/3] ath9k: Fix NF calibration for single stream cards
From: Sujith Manoharan @ 2013-09-16  5:06 UTC (permalink / raw)
  To: John Linville; +Cc: linux-wireless

From: Sujith Manoharan <c_manoha@qca.qualcomm.com>

Rather than using the chip ID to read only chain-0 CCA
registers and avoid reading chain-1, use the RX chainmask
instead. There are some 1-stream PCI devices based on AR9287
such as TL-WN751ND. Improper NF calibration might result in
DMA errors/timeouts.

Signed-off-by: Sujith Manoharan <c_manoha@qca.qualcomm.com>
---
 drivers/net/wireless/ath/ath9k/ar9002_phy.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/wireless/ath/ath9k/ar9002_phy.c b/drivers/net/wireless/ath/ath9k/ar9002_phy.c
index 7a5569b..17970d4 100644
--- a/drivers/net/wireless/ath/ath9k/ar9002_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar9002_phy.c
@@ -485,7 +485,7 @@ static void ar9002_hw_do_getnf(struct ath_hw *ah,
 	if (IS_CHAN_HT40(ah->curchan))
 		nfarray[3] = sign_extend32(nf, 8);
 
-	if (AR_SREV_9285(ah) || AR_SREV_9271(ah))
+	if (!(ah->rxchainmask & BIT(1)))
 		return;
 
 	nf = MS(REG_READ(ah, AR_PHY_CH1_CCA), AR9280_PHY_CH1_MINCCA_PWR);
-- 
1.8.4


^ permalink raw reply related

* iwlwifi (5100 AGN) AP mode (experimental?)
From: Niccolò Belli @ 2013-09-15 20:33 UTC (permalink / raw)
  To: linux-wireless; +Cc: ilw

Hi,
I read[1] iwlwifi should have experimental support for AP mode.

Unfortunately ap mode isn't listed:

laptop ~ # iw list | grep -i ap
                 Capabilities: 0x1072
                 Capabilities: 0x1072
                  * start_ap
                  * set_noack_map
                  * AP: 0x00 0x10 0x20 0x30 0x40 0x50 0x60 0x70 0x80 
0x90 0xa0 0xb0 0xc0 0xd0 0xe0 0xf0
                  * AP/VLAN: 0x00 0x10 0x20 0x30 0x40 0x50 0x60 0x70 
0x80 0x90 0xa0 0xb0 0xc0 0xd0 0xe0 0xf0
                  * AP: 0x00 0x20 0x40 0xa0 0xb0 0xc0 0xd0
                  * AP/VLAN: 0x00 0x20 0x40 0xa0 0xb0 0xc0 0xd0
         HT Capability overrides:

Do I need a special firmware/kernel version? I'm using 3.11.0 and 
linux-firmware-20130728.

Thanks,
Niccolò

[1]http://wireless.kernel.org/en/users/Drivers/iwlwifi
-- 
http://www.linuxsystems.it

^ permalink raw reply

* Re: RTL8192CU continually reconnecting
From: Larry Finger @ 2013-09-15 20:26 UTC (permalink / raw)
  To: Mark Cave-Ayland; +Cc: Olivier Reuland, linux-wireless
In-Reply-To: <5235F2D0.6090505@ilande.co.uk>

On 09/15/2013 12:48 PM, Mark Cave-Ayland wrote:
> On 15/09/13 14:50, Larry Finger wrote:
>
>> There is a known problem with the dynamic power management code for this
>> chip. Unfortunately, the problem does not affect my system. At the
>> moment, my device that uses rtl8192cu has been connected for 12 hours
>> with no disconnects. The only evidence of a bug here is poor performance.
>
> Did my email to the list yesterday provide any further clues at all? I know that
> you're looking at re-working the power code, but if there is any chance of a
> stop-gap fix for 3.12 then I know it would be greatly appreciated :)

Yes, you provided some clues, but as I have no knowledge of the internal 
workings of the chips, I dare not set parameters willy-nilly as that might cause 
chips to burn out and fail.

The vendor driver provides better performance for my device than does rtl8192cu. 
I would provide the patches needed to compile it on a modern kernel; however, it 
causes a kernel panic whenever you try to unload it. I have no time nor 
inclination to debug that. Thus no one should use it unless you want to fix that 
problem.

I am trying to change the in-kernel dm code to match the vendor driver. That is 
difficult as nearly every variable is renamed.

Any patches will be pushed when they are ready, and not before. I will, however, 
provide them for testing. It remains to be seen if any such patches will be 
suitable for 3.12 and backporting to 3.11.

Larry



^ permalink raw reply

* Re: RTL8192CU continually reconnecting
From: Mark Cave-Ayland @ 2013-09-15 17:48 UTC (permalink / raw)
  To: Larry Finger; +Cc: Olivier Reuland, linux-wireless
In-Reply-To: <5235BB3B.5030800@lwfinger.net>

On 15/09/13 14:50, Larry Finger wrote:

> There is a known problem with the dynamic power management code for this
> chip. Unfortunately, the problem does not affect my system. At the
> moment, my device that uses rtl8192cu has been connected for 12 hours
> with no disconnects. The only evidence of a bug here is poor performance.

Did my email to the list yesterday provide any further clues at all? I 
know that you're looking at re-working the power code, but if there is 
any chance of a stop-gap fix for 3.12 then I know it would be greatly 
appreciated :)


ATB,

Mark.

^ permalink raw reply

* Re: RTL8192CU continually reconnecting
From: Larry Finger @ 2013-09-15 13:50 UTC (permalink / raw)
  To: Olivier Reuland; +Cc: linux-wireless
In-Reply-To: <loom.20130915T101439-276@post.gmane.org>

On 09/15/2013 03:17 AM, Olivier Reuland wrote:
> Hi,
>
> I'm facing the same issue with a slightly different device: "ID 0b05:17ab
> ASUSTek Computer, Inc. USB-N13 802.11n Network Adapter (rev. B1) [Realtek
> RTL8192CU]". I'm also using Ubuntu, Saucy: "Linux desktop 3.11.0-7-generic
> #13-Ubuntu SMP Tue Sep 10 20:55:38 UTC 2013 x86_64 x86_64 x86_64 GNU/Linux".

--snip--

>
> Let me know if there is anything I can do to help

There is a known problem with the dynamic power management code for this chip. 
Unfortunately, the problem does not affect my system. At the moment, my device 
that uses rtl8192cu has been connected for 12 hours with no disconnects. The 
only evidence of a bug here is poor performance.

Please describe your setup. What AP are you using? Is it an 802.11n or an 
802.11g connection? How far is your station from the AP? Are there any obstacles 
such as walls in the way? What is the signal strength as shown by iwconfig?

Larry


^ 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