All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/7] ath6kl: patches upto 2011-08-23
@ 2011-08-23  8:16 Kalle Valo
  2011-08-23  8:16 ` [PATCH 1/7] ath6kl: Release ar->lock right afer updating net_stats in ath6kl_rx() Kalle Valo
                   ` (6 more replies)
  0 siblings, 7 replies; 8+ messages in thread
From: Kalle Valo @ 2011-08-23  8:16 UTC (permalink / raw)
  To: linux-wireless

Hi,

here are few patches I have applied to ath6kl tree. I will send
a merge request later, maybe next week or so.

>From now on we will send patches first to the mailing list for review
and only then I will apply them to the tree.

Kalle

Kalle Valo (1):
  ath6kl: implement suspend support

Vasanthakumar Thiagarajan (6):
  ath6kl: Release ar->lock right afer updating net_stats in ath6kl_rx()
  ath6kl: Minor cleanup in min_hdr_len computation
  ath6kl: Cleanup ath6kl_wmi_data_hdr_remove()
  ath6kl: Fix bug in computing AMSU subframe padding
  ath6kl: Fix buffer alignment for scatter-gather I/O
  ath6kl: Fix system freeze under heavy data load

 drivers/net/wireless/ath/ath6kl/cfg80211.c |   14 ++++++++++
 drivers/net/wireless/ath/ath6kl/core.h     |    4 +++
 drivers/net/wireless/ath/ath6kl/hif-ops.h  |    5 ++++
 drivers/net/wireless/ath/ath6kl/hif.h      |    1 +
 drivers/net/wireless/ath/ath6kl/htc.c      |   14 ++++++++++
 drivers/net/wireless/ath/ath6kl/init.c     |    2 +-
 drivers/net/wireless/ath/ath6kl/main.c     |   37 +++++++++++++++++++++++++++-
 drivers/net/wireless/ath/ath6kl/sdio.c     |   36 +++++++++++++++++++-------
 drivers/net/wireless/ath/ath6kl/txrx.c     |   18 +++++++------
 drivers/net/wireless/ath/ath6kl/wmi.c      |   10 -------
 drivers/net/wireless/ath/ath6kl/wmi.h      |    1 -
 11 files changed, 111 insertions(+), 31 deletions(-)


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

* [PATCH 1/7] ath6kl: Release ar->lock right afer updating net_stats in ath6kl_rx()
  2011-08-23  8:16 [PATCH 0/7] ath6kl: patches upto 2011-08-23 Kalle Valo
@ 2011-08-23  8:16 ` Kalle Valo
  2011-08-23  8:16 ` [PATCH 2/7] ath6kl: Minor cleanup in min_hdr_len computation Kalle Valo
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Kalle Valo @ 2011-08-23  8:16 UTC (permalink / raw)
  To: linux-wireless; +Cc: Vasanthakumar Thiagarajan

From: Vasanthakumar Thiagarajan <vthiagar@qca.qualcomm.com>

This lock is intended to protect stats there, not neccessary to
hold it beyond that.

Signed-off-by: Vasanthakumar Thiagarajan <vthiagar@qca.qualcomm.com>
Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
---
 drivers/net/wireless/ath/ath6kl/txrx.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/ath/ath6kl/txrx.c b/drivers/net/wireless/ath/ath6kl/txrx.c
index 167bdb9..d546051 100644
--- a/drivers/net/wireless/ath/ath6kl/txrx.c
+++ b/drivers/net/wireless/ath/ath6kl/txrx.c
@@ -1044,13 +1044,13 @@ void ath6kl_rx(struct htc_target *target, struct htc_packet *packet)
 	ar->net_stats.rx_packets++;
 	ar->net_stats.rx_bytes += packet->act_len;
 
+	spin_unlock_bh(&ar->lock);
+
 	skb_put(skb, packet->act_len + HTC_HDR_LENGTH);
 	skb_pull(skb, HTC_HDR_LENGTH);
 
 	ath6kl_dbg_dump(ATH6KL_DBG_RAW_BYTES, __func__, skb->data, skb->len);
 
-	spin_unlock_bh(&ar->lock);
-
 	skb->dev = ar->net_dev;
 
 	if (!test_bit(WMI_ENABLED, &ar->flag)) {
-- 
1.7.1


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

* [PATCH 2/7] ath6kl: Minor cleanup in min_hdr_len computation
  2011-08-23  8:16 [PATCH 0/7] ath6kl: patches upto 2011-08-23 Kalle Valo
  2011-08-23  8:16 ` [PATCH 1/7] ath6kl: Release ar->lock right afer updating net_stats in ath6kl_rx() Kalle Valo
@ 2011-08-23  8:16 ` Kalle Valo
  2011-08-23  8:16 ` [PATCH 3/7] ath6kl: Cleanup ath6kl_wmi_data_hdr_remove() Kalle Valo
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Kalle Valo @ 2011-08-23  8:16 UTC (permalink / raw)
  To: linux-wireless; +Cc: Vasanthakumar Thiagarajan

From: Vasanthakumar Thiagarajan <vthiagar@qca.qualcomm.com>

Signed-off-by: Vasanthakumar Thiagarajan <vthiagar@qca.qualcomm.com>
Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
---
 drivers/net/wireless/ath/ath6kl/txrx.c |    5 ++---
 1 files changed, 2 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/ath/ath6kl/txrx.c b/drivers/net/wireless/ath/ath6kl/txrx.c
index d546051..fb67c24 100644
--- a/drivers/net/wireless/ath/ath6kl/txrx.c
+++ b/drivers/net/wireless/ath/ath6kl/txrx.c
@@ -1065,9 +1065,8 @@ void ath6kl_rx(struct htc_target *target, struct htc_packet *packet)
 		return;
 	}
 
-	min_hdr_len = sizeof(struct ethhdr);
-	min_hdr_len += sizeof(struct wmi_data_hdr) +
-		       sizeof(struct ath6kl_llc_snap_hdr);
+	min_hdr_len = sizeof(struct ethhdr) + sizeof(struct wmi_data_hdr) +
+		      sizeof(struct ath6kl_llc_snap_hdr);
 
 	dhdr = (struct wmi_data_hdr *) skb->data;
 
-- 
1.7.1


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

* [PATCH 3/7] ath6kl: Cleanup ath6kl_wmi_data_hdr_remove()
  2011-08-23  8:16 [PATCH 0/7] ath6kl: patches upto 2011-08-23 Kalle Valo
  2011-08-23  8:16 ` [PATCH 1/7] ath6kl: Release ar->lock right afer updating net_stats in ath6kl_rx() Kalle Valo
  2011-08-23  8:16 ` [PATCH 2/7] ath6kl: Minor cleanup in min_hdr_len computation Kalle Valo
@ 2011-08-23  8:16 ` Kalle Valo
  2011-08-23  8:16 ` [PATCH 4/7] ath6kl: Fix bug in computing AMSU subframe padding Kalle Valo
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Kalle Valo @ 2011-08-23  8:16 UTC (permalink / raw)
  To: linux-wireless; +Cc: Vasanthakumar Thiagarajan

From: Vasanthakumar Thiagarajan <vthiagar@qca.qualcomm.com>

Signed-off-by: Vasanthakumar Thiagarajan <vthiagar@qca.qualcomm.com>
Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
---
 drivers/net/wireless/ath/ath6kl/txrx.c |    3 +--
 drivers/net/wireless/ath/ath6kl/wmi.c  |   10 ----------
 drivers/net/wireless/ath/ath6kl/wmi.h  |    1 -
 3 files changed, 1 insertions(+), 13 deletions(-)

diff --git a/drivers/net/wireless/ath/ath6kl/txrx.c b/drivers/net/wireless/ath/ath6kl/txrx.c
index fb67c24..5d3d4b6 100644
--- a/drivers/net/wireless/ath/ath6kl/txrx.c
+++ b/drivers/net/wireless/ath/ath6kl/txrx.c
@@ -1162,8 +1162,7 @@ void ath6kl_rx(struct htc_target *target, struct htc_packet *packet)
 	seq_no = wmi_data_hdr_get_seqno(dhdr);
 	meta_type = wmi_data_hdr_get_meta(dhdr);
 	dot11_hdr = wmi_data_hdr_get_dot11(dhdr);
-
-	ath6kl_wmi_data_hdr_remove(ar->wmi, skb);
+	skb_pull(skb, sizeof(struct wmi_data_hdr));
 
 	switch (meta_type) {
 	case WMI_META_VERSION_1:
diff --git a/drivers/net/wireless/ath/ath6kl/wmi.c b/drivers/net/wireless/ath/ath6kl/wmi.c
index f5aa33d..13b1a20 100644
--- a/drivers/net/wireless/ath/ath6kl/wmi.c
+++ b/drivers/net/wireless/ath/ath6kl/wmi.c
@@ -376,16 +376,6 @@ int ath6kl_wmi_dot3_2_dix(struct sk_buff *skb)
 	return 0;
 }
 
-int ath6kl_wmi_data_hdr_remove(struct wmi *wmi, struct sk_buff *skb)
-{
-	if (WARN_ON(skb == NULL))
-		return -EINVAL;
-
-	skb_pull(skb, sizeof(struct wmi_data_hdr));
-
-	return 0;
-}
-
 static void ath6kl_wmi_convert_bssinfo_hdr2_to_hdr(struct sk_buff *skb,
 						   u8 *datap)
 {
diff --git a/drivers/net/wireless/ath/ath6kl/wmi.h b/drivers/net/wireless/ath/ath6kl/wmi.h
index fe3ddce..8fa5d6e 100644
--- a/drivers/net/wireless/ath/ath6kl/wmi.h
+++ b/drivers/net/wireless/ath/ath6kl/wmi.h
@@ -1925,7 +1925,6 @@ int ath6kl_wmi_data_hdr_add(struct wmi *wmi, struct sk_buff *skb,
 
 int ath6kl_wmi_dot11_hdr_remove(struct wmi *wmi, struct sk_buff *skb);
 int ath6kl_wmi_dot3_2_dix(struct sk_buff *skb);
-int ath6kl_wmi_data_hdr_remove(struct wmi *wmi, struct sk_buff *skb);
 int ath6kl_wmi_implicit_create_pstream(struct wmi *wmi, struct sk_buff *skb,
 				       u32 layer2_priority, bool wmm_enabled,
 				       u8 *ac);
-- 
1.7.1


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

* [PATCH 4/7] ath6kl: Fix bug in computing AMSU subframe padding
  2011-08-23  8:16 [PATCH 0/7] ath6kl: patches upto 2011-08-23 Kalle Valo
                   ` (2 preceding siblings ...)
  2011-08-23  8:16 ` [PATCH 3/7] ath6kl: Cleanup ath6kl_wmi_data_hdr_remove() Kalle Valo
@ 2011-08-23  8:16 ` Kalle Valo
  2011-08-23  8:16 ` [PATCH 5/7] ath6kl: Fix buffer alignment for scatter-gather I/O Kalle Valo
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Kalle Valo @ 2011-08-23  8:16 UTC (permalink / raw)
  To: linux-wireless; +Cc: Vasanthakumar Thiagarajan

From: Vasanthakumar Thiagarajan <vthiagar@qca.qualcomm.com>

This fixes AMSDU rx, otherwise it fails with the following warnings.

"802.3 AMSDU frame bound check failed"

Signed-off-by: Vasanthakumar Thiagarajan <vthiagar@qca.qualcomm.com>
Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
---
 drivers/net/wireless/ath/ath6kl/txrx.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/net/wireless/ath/ath6kl/txrx.c b/drivers/net/wireless/ath/ath6kl/txrx.c
index 5d3d4b6..44bf227 100644
--- a/drivers/net/wireless/ath/ath6kl/txrx.c
+++ b/drivers/net/wireless/ath/ath6kl/txrx.c
@@ -812,7 +812,7 @@ static void aggr_slice_amsdu(struct aggr_info *p_aggr,
 		/* Add the length of A-MSDU subframe padding bytes -
 		 * Round to nearest word.
 		 */
-		frame_8023_len = ALIGN(frame_8023_len + 3, 3);
+		frame_8023_len = ALIGN(frame_8023_len, 4);
 
 		framep += frame_8023_len;
 		amsdu_len -= frame_8023_len;
-- 
1.7.1


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

* [PATCH 5/7] ath6kl: Fix buffer alignment for scatter-gather I/O
  2011-08-23  8:16 [PATCH 0/7] ath6kl: patches upto 2011-08-23 Kalle Valo
                   ` (3 preceding siblings ...)
  2011-08-23  8:16 ` [PATCH 4/7] ath6kl: Fix bug in computing AMSU subframe padding Kalle Valo
@ 2011-08-23  8:16 ` Kalle Valo
  2011-08-23  8:16 ` [PATCH 6/7] ath6kl: implement suspend support Kalle Valo
  2011-08-23  8:16 ` [PATCH 7/7] ath6kl: Fix system freeze under heavy data load Kalle Valo
  6 siblings, 0 replies; 8+ messages in thread
From: Kalle Valo @ 2011-08-23  8:16 UTC (permalink / raw)
  To: linux-wireless; +Cc: Vasanthakumar Thiagarajan

From: Vasanthakumar Thiagarajan <vthiagar@qca.qualcomm.com>

For non-scatter buffers, there is already a bounce buffer which
takes care of alignment. This patch is influenced by a rough patch of
Kalle.

Signed-off-by: Vasanthakumar Thiagarajan <vthiagar@qca.qualcomm.com>
Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
---
 drivers/net/wireless/ath/ath6kl/core.h |    3 +++
 drivers/net/wireless/ath/ath6kl/init.c |    2 +-
 drivers/net/wireless/ath/ath6kl/main.c |    2 +-
 drivers/net/wireless/ath/ath6kl/sdio.c |   25 +++++++++++++++----------
 drivers/net/wireless/ath/ath6kl/txrx.c |    2 ++
 5 files changed, 22 insertions(+), 12 deletions(-)

diff --git a/drivers/net/wireless/ath/ath6kl/core.h b/drivers/net/wireless/ath/ath6kl/core.h
index 214d114..a1aa2ef 100644
--- a/drivers/net/wireless/ath/ath6kl/core.h
+++ b/drivers/net/wireless/ath/ath6kl/core.h
@@ -42,6 +42,9 @@
 #define ATH6KL_MAX_ENDPOINTS   4
 #define MAX_NODE_NUM           15
 
+/* Extra bytes for htc header alignment */
+#define ATH6KL_HTC_ALIGN_BYTES 3
+
 /* MAX_HI_COOKIE_NUM are reserved for high priority traffic */
 #define MAX_DEF_COOKIE_NUM                180
 #define MAX_HI_COOKIE_NUM                 18	/* 10% of MAX_COOKIE_NUM */
diff --git a/drivers/net/wireless/ath/ath6kl/init.c b/drivers/net/wireless/ath/ath6kl/init.c
index df15bfa..75230ac 100644
--- a/drivers/net/wireless/ath/ath6kl/init.c
+++ b/drivers/net/wireless/ath/ath6kl/init.c
@@ -67,7 +67,7 @@ struct sk_buff *ath6kl_buf_alloc(int size)
 
 	/* Add chacheline space at front and back of buffer */
 	reserved = (2 * L1_CACHE_BYTES) + ATH6KL_DATA_OFFSET +
-		   sizeof(struct htc_packet);
+		   sizeof(struct htc_packet) + ATH6KL_HTC_ALIGN_BYTES;
 	skb = dev_alloc_skb(size + reserved);
 
 	if (skb)
diff --git a/drivers/net/wireless/ath/ath6kl/main.c b/drivers/net/wireless/ath/ath6kl/main.c
index f236aa8..868838b 100644
--- a/drivers/net/wireless/ath/ath6kl/main.c
+++ b/drivers/net/wireless/ath/ath6kl/main.c
@@ -1347,7 +1347,7 @@ void init_netdev(struct net_device *dev)
 	dev->needed_headroom = ETH_HLEN;
 	dev->needed_headroom += sizeof(struct ath6kl_llc_snap_hdr) +
 				sizeof(struct wmi_data_hdr) + HTC_HDR_LENGTH
-				+ WMI_MAX_TX_META_SZ;
+				+ WMI_MAX_TX_META_SZ + ATH6KL_HTC_ALIGN_BYTES;
 
 	return;
 }
diff --git a/drivers/net/wireless/ath/ath6kl/sdio.c b/drivers/net/wireless/ath/ath6kl/sdio.c
index 3417160..f393090 100644
--- a/drivers/net/wireless/ath/ath6kl/sdio.c
+++ b/drivers/net/wireless/ath/ath6kl/sdio.c
@@ -128,6 +128,17 @@ static int ath6kl_sdio_func0_cmd52_wr_byte(struct mmc_card *card,
 	return mmc_wait_for_cmd(card->host, &io_cmd, 0);
 }
 
+static void ath6kl_sdio_buf_align(u8 **buf, unsigned long len)
+{
+	u8 *align_addr;
+
+	if (!IS_ALIGNED((unsigned long) *buf, 4)) {
+		align_addr = PTR_ALIGN(*buf - 4, 4);
+		memmove(align_addr, *buf, len);
+		*buf = align_addr;
+	}
+}
+
 static int ath6kl_sdio_io(struct sdio_func *func, u32 request, u32 addr,
 			  u8 *buf, u32 len)
 {
@@ -213,16 +224,10 @@ static void ath6kl_sdio_setup_scat_data(struct hif_scatter_req *scat_req,
 
 	/* assemble SG list */
 	for (i = 0; i < scat_req->scat_entries; i++, sg++) {
-		if ((unsigned long)scat_req->scat_list[i].buf & 0x3)
-			/*
-			 * Some scatter engines can handle unaligned
-			 * buffers, print this as informational only.
-			 */
-			ath6kl_dbg(ATH6KL_DBG_SCATTER,
-				   "(%s) scatter buffer is unaligned 0x%p\n",
-				   scat_req->req & HIF_WRITE ? "WR" : "RD",
-				   scat_req->scat_list[i].buf);
-
+		/* No header is added to rx buf, so it shoule be aligned */
+		if (data->flags == MMC_DATA_WRITE)
+			ath6kl_sdio_buf_align(&scat_req->scat_list[i].buf,
+					      scat_req->scat_list[i].len);
 		ath6kl_dbg(ATH6KL_DBG_SCATTER, "%d: addr:0x%p, len:%d\n",
 			   i, scat_req->scat_list[i].buf,
 			   scat_req->scat_list[i].len);
diff --git a/drivers/net/wireless/ath/ath6kl/txrx.c b/drivers/net/wireless/ath/ath6kl/txrx.c
index 44bf227..ba1350d 100644
--- a/drivers/net/wireless/ath/ath6kl/txrx.c
+++ b/drivers/net/wireless/ath/ath6kl/txrx.c
@@ -689,6 +689,7 @@ void ath6kl_rx_refill(struct htc_target *target, enum htc_endpoint_id endpoint)
 			break;
 
 		packet = (struct htc_packet *) skb->head;
+		skb->data = PTR_ALIGN(skb->data - 4, 4);
 		set_htc_rxpkt_info(packet, skb, skb->data,
 				ATH6KL_BUFFER_SIZE, endpoint);
 		list_add_tail(&packet->list, &queue);
@@ -709,6 +710,7 @@ void ath6kl_refill_amsdu_rxbufs(struct ath6kl *ar, int count)
 			return;
 
 		packet = (struct htc_packet *) skb->head;
+		skb->data = PTR_ALIGN(skb->data - 4, 4);
 		set_htc_rxpkt_info(packet, skb, skb->data,
 				   ATH6KL_AMSDU_BUFFER_SIZE, 0);
 		spin_lock_bh(&ar->lock);
-- 
1.7.1


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

* [PATCH 6/7] ath6kl: implement suspend support
  2011-08-23  8:16 [PATCH 0/7] ath6kl: patches upto 2011-08-23 Kalle Valo
                   ` (4 preceding siblings ...)
  2011-08-23  8:16 ` [PATCH 5/7] ath6kl: Fix buffer alignment for scatter-gather I/O Kalle Valo
@ 2011-08-23  8:16 ` Kalle Valo
  2011-08-23  8:16 ` [PATCH 7/7] ath6kl: Fix system freeze under heavy data load Kalle Valo
  6 siblings, 0 replies; 8+ messages in thread
From: Kalle Valo @ 2011-08-23  8:16 UTC (permalink / raw)
  To: linux-wireless

For now this is implemented so that if host supports power is kept in
the chip. If that's not supported, an error is returned and sdio stack
will remove the device during suspend.

Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
---
 drivers/net/wireless/ath/ath6kl/cfg80211.c |   14 +++++++++++
 drivers/net/wireless/ath/ath6kl/core.h     |    1 +
 drivers/net/wireless/ath/ath6kl/hif-ops.h  |    5 ++++
 drivers/net/wireless/ath/ath6kl/hif.h      |    1 +
 drivers/net/wireless/ath/ath6kl/main.c     |   35 ++++++++++++++++++++++++++++
 drivers/net/wireless/ath/ath6kl/sdio.c     |   26 ++++++++++++++++++++
 6 files changed, 82 insertions(+), 0 deletions(-)

diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c
index b2b70e6..9128aa3 100644
--- a/drivers/net/wireless/ath/ath6kl/cfg80211.c
+++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c
@@ -17,6 +17,7 @@
 #include "core.h"
 #include "cfg80211.h"
 #include "debug.h"
+#include "hif-ops.h"
 
 #define RATETAB_ENT(_rate, _rateid, _flags) {   \
 	.bitrate    = (_rate),                  \
@@ -1424,6 +1425,16 @@ static int ath6kl_flush_pmksa(struct wiphy *wiphy, struct net_device *netdev)
 	return 0;
 }
 
+#ifdef CONFIG_PM
+static int ar6k_cfg80211_suspend(struct wiphy *wiphy,
+				 struct cfg80211_wowlan *wow)
+{
+	struct ath6kl *ar = wiphy_priv(wiphy);
+
+	return ath6kl_hif_suspend(ar);
+}
+#endif
+
 static struct cfg80211_ops ath6kl_cfg80211_ops = {
 	.change_virtual_intf = ath6kl_cfg80211_change_iface,
 	.scan = ath6kl_cfg80211_scan,
@@ -1443,6 +1454,9 @@ static struct cfg80211_ops ath6kl_cfg80211_ops = {
 	.set_pmksa = ath6kl_set_pmksa,
 	.del_pmksa = ath6kl_del_pmksa,
 	.flush_pmksa = ath6kl_flush_pmksa,
+#ifdef CONFIG_PM
+	.suspend = ar6k_cfg80211_suspend,
+#endif
 };
 
 struct wireless_dev *ath6kl_cfg80211_init(struct device *dev)
diff --git a/drivers/net/wireless/ath/ath6kl/core.h b/drivers/net/wireless/ath/ath6kl/core.h
index a1aa2ef..4405ab5 100644
--- a/drivers/net/wireless/ath/ath6kl/core.h
+++ b/drivers/net/wireless/ath/ath6kl/core.h
@@ -544,6 +544,7 @@ void ath6kl_pspoll_event(struct ath6kl *ar, u8 aid);
 
 void ath6kl_dtimexpiry_event(struct ath6kl *ar);
 void ath6kl_disconnect(struct ath6kl *ar);
+void ath6kl_deep_sleep_enable(struct ath6kl *ar);
 void aggr_recv_delba_req_evt(struct ath6kl *ar, u8 tid);
 void aggr_recv_addba_req_evt(struct ath6kl *ar, u8 tid, u16 seq_no,
 			     u8 win_sz);
diff --git a/drivers/net/wireless/ath/ath6kl/hif-ops.h b/drivers/net/wireless/ath/ath6kl/hif-ops.h
index c923979..d6c898f 100644
--- a/drivers/net/wireless/ath/ath6kl/hif-ops.h
+++ b/drivers/net/wireless/ath/ath6kl/hif-ops.h
@@ -69,4 +69,9 @@ static inline void ath6kl_hif_cleanup_scatter(struct ath6kl *ar)
 	return ar->hif_ops->cleanup_scatter(ar);
 }
 
+static inline int ath6kl_hif_suspend(struct ath6kl *ar)
+{
+	return ar->hif_ops->suspend(ar);
+}
+
 #endif
diff --git a/drivers/net/wireless/ath/ath6kl/hif.h b/drivers/net/wireless/ath/ath6kl/hif.h
index 5ceff54..797e2d1 100644
--- a/drivers/net/wireless/ath/ath6kl/hif.h
+++ b/drivers/net/wireless/ath/ath6kl/hif.h
@@ -202,6 +202,7 @@ struct ath6kl_hif_ops {
 	int (*scat_req_rw) (struct ath6kl *ar,
 			    struct hif_scatter_req *scat_req);
 	void (*cleanup_scatter)(struct ath6kl *ar);
+	int (*suspend)(struct ath6kl *ar);
 };
 
 #endif
diff --git a/drivers/net/wireless/ath/ath6kl/main.c b/drivers/net/wireless/ath/ath6kl/main.c
index 868838b..b64b2a3 100644
--- a/drivers/net/wireless/ath/ath6kl/main.c
+++ b/drivers/net/wireless/ath/ath6kl/main.c
@@ -795,6 +795,41 @@ void ath6kl_disconnect(struct ath6kl *ar)
 	}
 }
 
+void ath6kl_deep_sleep_enable(struct ath6kl *ar)
+{
+	switch (ar->sme_state) {
+	case SME_CONNECTING:
+		cfg80211_connect_result(ar->net_dev, ar->bssid, NULL, 0,
+					NULL, 0,
+					WLAN_STATUS_UNSPECIFIED_FAILURE,
+					GFP_KERNEL);
+		break;
+	case SME_CONNECTED:
+	default:
+		/*
+		 * FIXME: oddly enough smeState is in DISCONNECTED during
+		 * suspend, why? Need to send disconnected event in that
+		 * state.
+		 */
+		cfg80211_disconnected(ar->net_dev, 0, NULL, 0, GFP_KERNEL);
+		break;
+	}
+
+	if (test_bit(CONNECTED, &ar->flag) ||
+	    test_bit(CONNECT_PEND, &ar->flag))
+		ath6kl_wmi_disconnect_cmd(ar->wmi);
+
+	ar->sme_state = SME_DISCONNECTED;
+
+	/* disable scanning */
+	if (ath6kl_wmi_scanparams_cmd(ar->wmi, 0xFFFF, 0, 0, 0, 0, 0, 0, 0,
+				      0, 0) != 0)
+		printk(KERN_WARNING "ath6kl: failed to disable scan "
+		       "during suspend\n");
+
+	ath6kl_cfg80211_scan_complete_event(ar, -ECANCELED);
+}
+
 /* WMI Event handlers */
 
 static const char *get_hw_id_string(u32 id)
diff --git a/drivers/net/wireless/ath/ath6kl/sdio.c b/drivers/net/wireless/ath/ath6kl/sdio.c
index f393090..852a0cc 100644
--- a/drivers/net/wireless/ath/ath6kl/sdio.c
+++ b/drivers/net/wireless/ath/ath6kl/sdio.c
@@ -726,6 +726,31 @@ static int ath6kl_sdio_enable_scatter(struct ath6kl *ar)
 	return 0;
 }
 
+static int ath6kl_sdio_suspend(struct ath6kl *ar)
+{
+	struct ath6kl_sdio *ar_sdio = ath6kl_sdio_priv(ar);
+	struct sdio_func *func = ar_sdio->func;
+	mmc_pm_flag_t flags;
+	int ret;
+
+	flags = sdio_get_host_pm_caps(func);
+
+	if (!(flags & MMC_PM_KEEP_POWER))
+		/* as host doesn't support keep power we need to bail out */
+		return -EINVAL;
+
+	ret = sdio_set_host_pm_flags(func, MMC_PM_KEEP_POWER);
+	if (ret) {
+		printk(KERN_ERR "ath6kl: set sdio pm flags failed: %d\n",
+		       ret);
+		return ret;
+	}
+
+	ath6kl_deep_sleep_enable(ar);
+
+	return 0;
+}
+
 static const struct ath6kl_hif_ops ath6kl_sdio_ops = {
 	.read_write_sync = ath6kl_sdio_read_write_sync,
 	.write_async = ath6kl_sdio_write_async,
@@ -736,6 +761,7 @@ static const struct ath6kl_hif_ops ath6kl_sdio_ops = {
 	.enable_scatter = ath6kl_sdio_enable_scatter,
 	.scat_req_rw = ath6kl_sdio_async_rw_scatter,
 	.cleanup_scatter = ath6kl_sdio_cleanup_scatter,
+	.suspend = ath6kl_sdio_suspend,
 };
 
 static int ath6kl_sdio_probe(struct sdio_func *func,
-- 
1.7.1


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

* [PATCH 7/7] ath6kl: Fix system freeze under heavy data load
  2011-08-23  8:16 [PATCH 0/7] ath6kl: patches upto 2011-08-23 Kalle Valo
                   ` (5 preceding siblings ...)
  2011-08-23  8:16 ` [PATCH 6/7] ath6kl: implement suspend support Kalle Valo
@ 2011-08-23  8:16 ` Kalle Valo
  6 siblings, 0 replies; 8+ messages in thread
From: Kalle Valo @ 2011-08-23  8:16 UTC (permalink / raw)
  To: linux-wireless; +Cc: Vasanthakumar Thiagarajan

From: Vasanthakumar Thiagarajan <vthiagar@qca.qualcomm.com>

Patch "ath6kl: Fix buffer alignment for scatter-gather write" does
memmove for a length (scat_req->scat_list[i].len) which is not the
actual length of data that is suppossed to be moved. The right
lengh is packet->act_len + HTC_HDR_LENGTH. Using wrong length
for data move during buffer alignment causes system freeze after
the following WARN_ON and sometimes target assert.

WARNING: at drivers/net/wireless/ath/ath6kl/main.c:771 ath6k_credit_distribute+0x196/0x1a0
 [<ffffffffa051cf5f>] ath6kl_htc_rxmsg_pending_handler+0x83f/0xe00 [ath6kl]
 [<ffffffff8104a743>] ? __wake_up+0x53/0x70
 [<ffffffffa0518b18>] ath6kldev_intr_bh_handler+0x188/0x650 [ath6kl]
 [<ffffffffa052d316>] ath6kl_sdio_irq_handler+0x36/0x80 [ath6kl]
 [<ffffffff81492b3c>] sdio_irq_thread+0xfc/0x360
 [<ffffffff81051c52>] ? default_wake_function+0x12/0x20
 [<ffffffff81492a40>] ? sdio_claim_irq+0x220/0x220
 [<ffffffff81080c36>] kthread+0x96/0xa0
 [<ffffffff815b9fb4>] kernel_thread_helper+0x4/0x10
 [<ffffffff81080ba0>] ? kthread_worker_fn+0x190/0x190
 [<ffffffff815b9fb0>] ? gs_change+0x13/0x13

Signed-off-by: Vasanthakumar Thiagarajan <vthiagar@qca.qualcomm.com>
Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
---
 drivers/net/wireless/ath/ath6kl/htc.c  |   14 ++++++++++++++
 drivers/net/wireless/ath/ath6kl/sdio.c |   15 ---------------
 drivers/net/wireless/ath/ath6kl/txrx.c |    6 ++++--
 3 files changed, 18 insertions(+), 17 deletions(-)

diff --git a/drivers/net/wireless/ath/ath6kl/htc.c b/drivers/net/wireless/ath/ath6kl/htc.c
index 2001660..dc575a8 100644
--- a/drivers/net/wireless/ath/ath6kl/htc.c
+++ b/drivers/net/wireless/ath/ath6kl/htc.c
@@ -22,6 +22,17 @@
 
 #define CALC_TXRX_PADDED_LEN(dev, len)  (__ALIGN_MASK((len), (dev)->block_mask))
 
+static void ath6kl_htc_buf_align(u8 **buf, unsigned long len)
+{
+	u8 *align_addr;
+
+	if (!IS_ALIGNED((unsigned long) *buf, 4)) {
+		align_addr = PTR_ALIGN(*buf - 4, 4);
+		memmove(align_addr, *buf, len);
+		*buf = align_addr;
+	}
+}
+
 static void htc_prep_send_pkt(struct htc_packet *packet, u8 flags, int ctrl0,
 			      int ctrl1)
 {
@@ -391,6 +402,9 @@ static int htc_setup_send_scat_list(struct htc_target *target,
 		htc_prep_send_pkt(packet,
 				packet->info.tx.flags | HTC_FLAGS_SEND_BUNDLE,
 				cred_pad, packet->info.tx.seqno);
+		/* Make sure the buffer is 4-byte aligned */
+		ath6kl_htc_buf_align(&packet->buf,
+				     packet->act_len + HTC_HDR_LENGTH);
 		scat_req->scat_list[i].buf = packet->buf;
 		scat_req->scat_list[i].len = len;
 
diff --git a/drivers/net/wireless/ath/ath6kl/sdio.c b/drivers/net/wireless/ath/ath6kl/sdio.c
index 852a0cc..0cce801 100644
--- a/drivers/net/wireless/ath/ath6kl/sdio.c
+++ b/drivers/net/wireless/ath/ath6kl/sdio.c
@@ -128,17 +128,6 @@ static int ath6kl_sdio_func0_cmd52_wr_byte(struct mmc_card *card,
 	return mmc_wait_for_cmd(card->host, &io_cmd, 0);
 }
 
-static void ath6kl_sdio_buf_align(u8 **buf, unsigned long len)
-{
-	u8 *align_addr;
-
-	if (!IS_ALIGNED((unsigned long) *buf, 4)) {
-		align_addr = PTR_ALIGN(*buf - 4, 4);
-		memmove(align_addr, *buf, len);
-		*buf = align_addr;
-	}
-}
-
 static int ath6kl_sdio_io(struct sdio_func *func, u32 request, u32 addr,
 			  u8 *buf, u32 len)
 {
@@ -224,10 +213,6 @@ static void ath6kl_sdio_setup_scat_data(struct hif_scatter_req *scat_req,
 
 	/* assemble SG list */
 	for (i = 0; i < scat_req->scat_entries; i++, sg++) {
-		/* No header is added to rx buf, so it shoule be aligned */
-		if (data->flags == MMC_DATA_WRITE)
-			ath6kl_sdio_buf_align(&scat_req->scat_list[i].buf,
-					      scat_req->scat_list[i].len);
 		ath6kl_dbg(ATH6KL_DBG_SCATTER, "%d: addr:0x%p, len:%d\n",
 			   i, scat_req->scat_list[i].buf,
 			   scat_req->scat_list[i].len);
diff --git a/drivers/net/wireless/ath/ath6kl/txrx.c b/drivers/net/wireless/ath/ath6kl/txrx.c
index ba1350d..ba33370 100644
--- a/drivers/net/wireless/ath/ath6kl/txrx.c
+++ b/drivers/net/wireless/ath/ath6kl/txrx.c
@@ -689,7 +689,8 @@ void ath6kl_rx_refill(struct htc_target *target, enum htc_endpoint_id endpoint)
 			break;
 
 		packet = (struct htc_packet *) skb->head;
-		skb->data = PTR_ALIGN(skb->data - 4, 4);
+		if (!IS_ALIGNED((unsigned long) skb->data, 4))
+			skb->data = PTR_ALIGN(skb->data - 4, 4);
 		set_htc_rxpkt_info(packet, skb, skb->data,
 				ATH6KL_BUFFER_SIZE, endpoint);
 		list_add_tail(&packet->list, &queue);
@@ -710,7 +711,8 @@ void ath6kl_refill_amsdu_rxbufs(struct ath6kl *ar, int count)
 			return;
 
 		packet = (struct htc_packet *) skb->head;
-		skb->data = PTR_ALIGN(skb->data - 4, 4);
+		if (!IS_ALIGNED((unsigned long) skb->data, 4))
+			skb->data = PTR_ALIGN(skb->data - 4, 4);
 		set_htc_rxpkt_info(packet, skb, skb->data,
 				   ATH6KL_AMSDU_BUFFER_SIZE, 0);
 		spin_lock_bh(&ar->lock);
-- 
1.7.1


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

end of thread, other threads:[~2011-08-23  8:20 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-08-23  8:16 [PATCH 0/7] ath6kl: patches upto 2011-08-23 Kalle Valo
2011-08-23  8:16 ` [PATCH 1/7] ath6kl: Release ar->lock right afer updating net_stats in ath6kl_rx() Kalle Valo
2011-08-23  8:16 ` [PATCH 2/7] ath6kl: Minor cleanup in min_hdr_len computation Kalle Valo
2011-08-23  8:16 ` [PATCH 3/7] ath6kl: Cleanup ath6kl_wmi_data_hdr_remove() Kalle Valo
2011-08-23  8:16 ` [PATCH 4/7] ath6kl: Fix bug in computing AMSU subframe padding Kalle Valo
2011-08-23  8:16 ` [PATCH 5/7] ath6kl: Fix buffer alignment for scatter-gather I/O Kalle Valo
2011-08-23  8:16 ` [PATCH 6/7] ath6kl: implement suspend support Kalle Valo
2011-08-23  8:16 ` [PATCH 7/7] ath6kl: Fix system freeze under heavy data load Kalle Valo

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.