Linux wireless drivers development
 help / color / mirror / Atom feed
* [PATCH 29/29] wl12xx: use round-robin policy for tx
From: Eliad Peller @ 2011-10-10  8:13 UTC (permalink / raw)
  To: Luciano Coelho; +Cc: linux-wireless
In-Reply-To: <1318234397-21081-1-git-send-email-eliad@wizery.com>

Currently, a single vif might starve all the other vifs.
Save the last vif we dequeued a packet from, and continue
with the following one using a round-robin policy.

Signed-off-by: Eliad Peller <eliad@wizery.com>
---
 drivers/net/wireless/wl12xx/main.c   |    2 ++
 drivers/net/wireless/wl12xx/tx.c     |   26 ++++++++++++++++++++------
 drivers/net/wireless/wl12xx/wl12xx.h |    6 ++++++
 3 files changed, 28 insertions(+), 6 deletions(-)

diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c
index e5edf64..e1d33b2 100644
--- a/drivers/net/wireless/wl12xx/main.c
+++ b/drivers/net/wireless/wl12xx/main.c
@@ -2277,6 +2277,8 @@ deinit:
 
 	wl12xx_tx_reset_wlvif(wl, wlvif);
 	wl1271_free_ap_keys(wl, wlvif);
+	if (wl->last_wlvif == wlvif)
+		wl->last_wlvif = NULL;
 	list_del(&wlvif->list);
 	memset(wlvif->ap.sta_hlid_map, 0, sizeof(wlvif->ap.sta_hlid_map));
 	wlvif->role_id = WL12XX_INVALID_ROLE_ID;
diff --git a/drivers/net/wireless/wl12xx/tx.c b/drivers/net/wireless/wl12xx/tx.c
index f434331..05968c6 100644
--- a/drivers/net/wireless/wl12xx/tx.c
+++ b/drivers/net/wireless/wl12xx/tx.c
@@ -590,14 +590,28 @@ static struct sk_buff *wl12xx_vif_skb_dequeue(struct wl1271 *wl,
 static struct sk_buff *wl1271_skb_dequeue(struct wl1271 *wl)
 {
 	unsigned long flags;
-	struct wl12xx_vif *wlvif;
+	struct wl12xx_vif *wlvif = wl->last_wlvif;
 	struct sk_buff *skb = NULL;
 
-	/* TODO: rememeber last vif and consider it */
-	wl12xx_for_each_wlvif(wl, wlvif) {
-		skb = wl12xx_vif_skb_dequeue(wl, wlvif);
-		if (skb)
-			break;
+	if (wlvif) {
+		wl12xx_for_each_wlvif_continue(wl, wlvif) {
+			skb = wl12xx_vif_skb_dequeue(wl, wlvif);
+			if (skb) {
+				wl->last_wlvif = wlvif;
+				break;
+			}
+		}
+	}
+
+	/* do another pass */
+	if (!skb) {
+		wl12xx_for_each_wlvif(wl, wlvif) {
+			skb = wl12xx_vif_skb_dequeue(wl, wlvif);
+			if (skb) {
+				wl->last_wlvif = wlvif;
+				break;
+			}
+		}
 	}
 
 	if (!skb &&
diff --git a/drivers/net/wireless/wl12xx/wl12xx.h b/drivers/net/wireless/wl12xx/wl12xx.h
index 3673994..94b24c2 100644
--- a/drivers/net/wireless/wl12xx/wl12xx.h
+++ b/drivers/net/wireless/wl12xx/wl12xx.h
@@ -549,6 +549,9 @@ struct wl1271 {
 
 	/* AP-mode - number of currently connected stations */
 	int active_sta_count;
+
+	/* last wlvif we transmitted from */
+	struct wl12xx_vif *last_wlvif;
 };
 
 struct wl1271_station {
@@ -690,6 +693,9 @@ struct ieee80211_vif *wl12xx_wlvif_to_vif(struct wl12xx_vif *wlvif)
 #define wl12xx_for_each_wlvif(wl, wlvif) \
 		list_for_each_entry(wlvif, &wl->wlvif_list, list)
 
+#define wl12xx_for_each_wlvif_continue(wl, wlvif) \
+		list_for_each_entry_continue(wlvif, &wl->wlvif_list, list)
+
 #define wl12xx_for_each_wlvif_bss_type(wl, wlvif, _bss_type)	\
 		wl12xx_for_each_wlvif(wl, wlvif)		\
 			if (wlvif->bss_type == _bss_type)
-- 
1.7.6.401.g6a319


^ permalink raw reply related

* Re: [PATCH 0/8] wireless: add DFS master support
From: Zefir Kurtisi @ 2011-10-10  9:13 UTC (permalink / raw)
  To: Luis R. Rodriguez; +Cc: linux-wireless, linville, Johannes Berg
In-Reply-To: <CAB=NE6UouofityugcjTvcXpBFx6cYEbAQ_FAe3gPO-GaS8Vh3w@mail.gmail.com>

On 10/08/2011 08:26 PM, Luis R. Rodriguez wrote:
> On Sat, Oct 8, 2011 at 10:46 AM, Zefir Kurtisi
> <zefir.kurtisi@neratec.com> wrote:
>> On 08.10.2011 00:32, Luis R. Rodriguez wrote:
>>>
>>> On Fri, Oct 7, 2011 at 3:29 PM, Luis R. Rodriguez
>>> <mcgrof@qca.qualcomm.com>  wrote:
>>>>
>>>> On Fri, Oct 7, 2011 at 2:11 PM, Luis R. Rodriguez
>>>> <mcgrof@qca.qualcomm.com>  wrote:
>>>>>
>>>>> On Tue, Oct 4, 2011 at 5:14 PM, Luis R. Rodriguez
>>>>> <mcgrof@qca.qualcomm.com>  wrote:
>>>>>>
>>>>>> On Tue, Oct 4, 2011 at 4:47 PM, Luis R. Rodriguez
>>>>>> <mcgrof@qca.qualcomm.com>  wrote:
>>>>>>>
>>>>>>> This set of 8 patches adds DFS master support to the Linux wireless
>>>>>>> subsystem.
>>>>>>> I've reviewed future possible changes to DFS master regions and it
>>>>>>> seems that
>>>>>>> we are not going to be having multiple DFS regions for one country,
>>>>>>> instead
>>>>>>> we'll always have one DFS region for one country.
>>>>>>>
>>>>>>> The changes here are spread out throughout wireless-regdb, crda the
>>>>>>> kernel and
>>>>>>> lastly iw. The changes made allow for older verions of CRDA to work
>>>>>>> with new
>>>>>>> wireless-regdb files with DFS region support. If you want DFS master
>>>>>>> region
>>>>>>> support you'll need to upgrade your CRDA, your kernel and then hope
>>>>>>> someone
>>>>>>> implements DFS master support for your respective driver.
>>>>>>>
>>>>>>> This patch series does not have specific driver changes, although some
>>>>>>> seem to
>>>>>>> be backing in the oven right now.
>>>>>>
>>>>>> Here's a puzzle though... If we change this series to use the other
>>>>>> pad byte that was available, the first pad byte, instead of the last
>>>>>> one, we loose backward compatibility support and I cannot figure out
>>>>>> why. What I ended up seeing was that crda sends the message, and for
>>>>>> some reason (return code is 222 from nl_wait_for_ack(), whatever that
>>>>>> is) the kernel rejects it. I suspect it may have to do with some sort
>>>>>> of offset to the *other* data that makes some of the rules output
>>>>>> invalid data for the attribute policy, but at least when I hexdump the
>>>>>> wireless-regdb the only changes I see are in the signature and the pad
>>>>>> shift.
>>>>>>
>>>>>> I got tired of trying though and after seeing flipping the pad bytes
>>>>>> things worked decided to stay with it. In my original RFC in December
>>>>>> I had used u16 instead, but since the data was in the last pad byte
>>>>>> things still worked. So something is fishy about only using the first
>>>>>> pad byte. The change below, as far as I can tell, should not have any
>>>>>> issues but it does with the older version of CRDA and even a new one.
>>>>>
>>>>> Johannes spotted the issue, I'll send the fix, thanks to Johannes.
>>>>> John, Johannes the patches still apply my fix goes on top of these
>>>>> changes, the fix is not addressing a regression introduced by this
>>>>> patchset, instead it fixes a long standing issue which would prevent
>>>>> us from using the next available pad byte.
>>>>
>>>> I'm going to respin this to make use of 2 bits:
>>>>
>>>> 00 unset
>>>> 01 FCC
>>>> 10 ETSI
>>>> 11 JP
>>>>
>>>> We may need some more DFS values later but
>>>
>>> Sorry I did not finish this e-mail I meant that we may later have a
>>> requirement for more DFS values but at this time we don't, we should
>>> consider whether or not we will want to leave more bits for usage of
>>> more DFS values and if so how many? Using two bits will give us
>>> support for what we know today but nothing for the future.
>>>
>> For the future things we do not know of today we should add another bit and
>> define
>>
>> 111 unknown / other
>>
>> to be able to mark special countrycodes that do not fully belong to the
>> three known domains.
> 
> I thought about this a bit more, so we'd have to define this as a U8
> attribute either way, so I would instead of calling NL80211_DFS_REGION
> call it something like NL80211_CTRY_REQS and for now only use 2 bits
> for the known DFS regions. We'd mask out the rest of the values. If we
> ever decide we need a new DFS region we could just extend the values
> on NL80211_CTRY_REQS after the last region. If we want to add a new
> requirement that is country specific other than DFS we could start at
> the end of the u8 instead of after the last DFS region. We could do
> this without making any explicit reservations.
> 
>> We could use some invalid coding for those CCs (like no
>> DFS domain set in CC
> 
> Sure, I should point out today every single regulatory domain will
> have this set except US, only because I added a patch to match US to
> DFS-FCC DFS region.
> 
>> but flag set for frequency band) to identify those
>> special domains,
> 
> So you're saying in case later we find out we need band specific DFS data later?
> 
No, I guess I initially misinterpreted the meaning of '00 unset' as a flag for countrycodes not restricted by DFS at all, but in fact this is done by not setting the per-band DFS flags.

So, if we consider the per-country DFS domain as an enabler for DFS support on top of per-band DFS restrictions (that otherwise remain disabled), we can support 'fancy' CCs by not setting the domain. The concern I brought up is therefore void.

WRT band specific DFS data, we agreed that this will break backwards compatibility and therefore needs some detailed planning. Adrian already brought up some issues we will face and why he is using per-band (or even per-channel) DFS properties.

I opt for keeping this proposed per-country DFS domain scheme until we get DFS fully working and find its limitations significant enough to start a major revision.

>> but using an additional bit would make things easier to
>> handle.
> 
> We can extend this as we go, and just ensure upon review of new code
> that we accommodate non -DFS crap at the end of the u8. Whatdya think?
> 
>   Luis

Zefir

^ permalink raw reply

* [PATCH 0/5] ath6kl: Debugging and roaming
From: Jouni Malinen @ 2011-10-10 10:43 UTC (permalink / raw)
  To: kvalo; +Cc: linux-wireless, Jouni Malinen

This set of patches adds some more ath6kl debugging information and
control to debugfs and enables additional roaming functionality.

Jouni Malinen (5):
  ath6kl: Add endpoint_stats debugfs file
  ath6kl: Add debugfs file for target roam table
  ath6kl: Add debugfs files for roaming control
  ath6kl: Add debugfs control for keepalive and disconnection timeout
  ath6kl: Allow CCKM AKM and KRK to be configured

 drivers/net/wireless/ath/ath6kl/cfg80211.c |   14 ++
 drivers/net/wireless/ath/ath6kl/core.h     |    7 +
 drivers/net/wireless/ath/ath6kl/debug.c    |  346 ++++++++++++++++++++++++++++
 drivers/net/wireless/ath/ath6kl/wmi.c      |   89 +++++++
 drivers/net/wireless/ath/ath6kl/wmi.h      |   28 ++-
 5 files changed, 478 insertions(+), 6 deletions(-)

-- 
1.7.4.1


^ permalink raw reply

* [PATCH 1/5] ath6kl: Add endpoint_stats debugfs file
From: Jouni Malinen @ 2011-10-10 10:43 UTC (permalink / raw)
  To: kvalo; +Cc: linux-wireless, Jouni Malinen
In-Reply-To: <1318243411-16110-1-git-send-email-jouni@qca.qualcomm.com>

This file can be used to fetch endpoint statistics counters and
to clear them by writing 0 to it.

Signed-off-by: Jouni Malinen <jouni@qca.qualcomm.com>
---
 drivers/net/wireless/ath/ath6kl/debug.c |  102 +++++++++++++++++++++++++++++++
 1 files changed, 102 insertions(+), 0 deletions(-)

diff --git a/drivers/net/wireless/ath/ath6kl/debug.c b/drivers/net/wireless/ath/ath6kl/debug.c
index ba3f23d..b9bf28d 100644
--- a/drivers/net/wireless/ath/ath6kl/debug.c
+++ b/drivers/net/wireless/ath/ath6kl/debug.c
@@ -595,6 +595,105 @@ static const struct file_operations fops_credit_dist_stats = {
 	.llseek = default_llseek,
 };
 
+static unsigned int print_endpoint_stat(struct htc_target *target, char *buf,
+					unsigned int buf_len, unsigned int len,
+					int offset, const char *name)
+{
+	int i;
+	struct htc_endpoint_stats *ep_st;
+	u32 *counter;
+
+	len += scnprintf(buf + len, buf_len - len, "%s:", name);
+	for (i = 0; i < ENDPOINT_MAX; i++) {
+		ep_st = &target->endpoint[i].ep_st;
+		counter = ((u32 *) ep_st) + (offset / 4);
+		len += scnprintf(buf + len, buf_len - len, " %u", *counter);
+	}
+	len += scnprintf(buf + len, buf_len - len, "\n");
+
+	return len;
+}
+
+static ssize_t ath6kl_endpoint_stats_read(struct file *file,
+					  char __user *user_buf,
+					  size_t count, loff_t *ppos)
+{
+	struct ath6kl *ar = file->private_data;
+	struct htc_target *target = ar->htc_target;
+	char *buf;
+	unsigned int buf_len, len = 0;
+	ssize_t ret_cnt;
+
+	buf_len = 1000 + ENDPOINT_MAX * 100;
+	buf = kzalloc(buf_len, GFP_KERNEL);
+	if (!buf)
+		return -ENOMEM;
+
+#define EPSTAT(name)							\
+	len = print_endpoint_stat(target, buf, buf_len, len,		\
+				  offsetof(struct htc_endpoint_stats, name), \
+				  #name)
+	EPSTAT(cred_low_indicate);
+	EPSTAT(tx_issued);
+	EPSTAT(tx_pkt_bundled);
+	EPSTAT(tx_bundles);
+	EPSTAT(tx_dropped);
+	EPSTAT(tx_cred_rpt);
+	EPSTAT(cred_rpt_from_rx);
+	EPSTAT(cred_rpt_ep0);
+	EPSTAT(cred_from_rx);
+	EPSTAT(cred_from_other);
+	EPSTAT(cred_from_ep0);
+	EPSTAT(cred_cosumd);
+	EPSTAT(cred_retnd);
+	EPSTAT(rx_pkts);
+	EPSTAT(rx_lkahds);
+	EPSTAT(rx_bundl);
+	EPSTAT(rx_bundle_lkahd);
+	EPSTAT(rx_bundle_from_hdr);
+	EPSTAT(rx_alloc_thresh_hit);
+	EPSTAT(rxalloc_thresh_byte);
+#undef EPSTAT
+
+	if (len > buf_len)
+		len = buf_len;
+
+	ret_cnt = simple_read_from_buffer(user_buf, count, ppos, buf, len);
+	kfree(buf);
+	return ret_cnt;
+}
+
+static ssize_t ath6kl_endpoint_stats_write(struct file *file,
+					   const char __user *user_buf,
+					   size_t count, loff_t *ppos)
+{
+	struct ath6kl *ar = file->private_data;
+	struct htc_target *target = ar->htc_target;
+	int ret, i;
+	u32 val;
+	struct htc_endpoint_stats *ep_st;
+
+	ret = kstrtou32_from_user(user_buf, count, 0, &val);
+	if (ret)
+		return ret;
+	if (val == 0) {
+		for (i = 0; i < ENDPOINT_MAX; i++) {
+			ep_st = &target->endpoint[i].ep_st;
+			memset(ep_st, 0, sizeof(*ep_st));
+		}
+	}
+
+	return count;
+}
+
+static const struct file_operations fops_endpoint_stats = {
+	.open = ath6kl_debugfs_open,
+	.read = ath6kl_endpoint_stats_read,
+	.write = ath6kl_endpoint_stats_write,
+	.owner = THIS_MODULE,
+	.llseek = default_llseek,
+};
+
 static unsigned long ath6kl_get_num_reg(void)
 {
 	int i;
@@ -901,6 +1000,9 @@ int ath6kl_debug_init(struct ath6kl *ar)
 	debugfs_create_file("credit_dist_stats", S_IRUSR, ar->debugfs_phy, ar,
 			    &fops_credit_dist_stats);
 
+	debugfs_create_file("endpoint_stats", S_IRUSR | S_IWUSR,
+			    ar->debugfs_phy, ar, &fops_endpoint_stats);
+
 	debugfs_create_file("fwlog", S_IRUSR, ar->debugfs_phy, ar,
 			    &fops_fwlog);
 
-- 
1.7.4.1


^ permalink raw reply related

* [PATCH 2/5] ath6kl: Add debugfs file for target roam table
From: Jouni Malinen @ 2011-10-10 10:43 UTC (permalink / raw)
  To: kvalo; +Cc: linux-wireless, Jouni Malinen
In-Reply-To: <1318243411-16110-1-git-send-email-jouni@qca.qualcomm.com>

The new roam_table debugfs file can be used to display the current
roam table from the target.

Signed-off-by: Jouni Malinen <jouni@qca.qualcomm.com>
---
 drivers/net/wireless/ath/ath6kl/core.h  |    4 ++
 drivers/net/wireless/ath/ath6kl/debug.c |   75 +++++++++++++++++++++++++++++++
 drivers/net/wireless/ath/ath6kl/wmi.c   |   41 +++++++++++++++++
 drivers/net/wireless/ath/ath6kl/wmi.h   |    7 +++
 4 files changed, 127 insertions(+), 0 deletions(-)

diff --git a/drivers/net/wireless/ath/ath6kl/core.h b/drivers/net/wireless/ath/ath6kl/core.h
index 6d8a484..c58cfad 100644
--- a/drivers/net/wireless/ath/ath6kl/core.h
+++ b/drivers/net/wireless/ath/ath6kl/core.h
@@ -397,6 +397,7 @@ struct ath6kl_req_key {
 #define TESTMODE	     13
 #define CLEAR_BSSFILTER_ON_BEACON 14
 #define DTIM_PERIOD_AVAIL    15
+#define ROAM_TBL_PEND        16
 
 struct ath6kl {
 	struct device *dev;
@@ -529,6 +530,9 @@ struct ath6kl {
 		struct {
 			unsigned int invalid_rate;
 		} war_stats;
+
+		u8 *roam_tbl;
+		unsigned int roam_tbl_len;
 	} debug;
 #endif /* CONFIG_ATH6KL_DEBUG */
 };
diff --git a/drivers/net/wireless/ath/ath6kl/debug.c b/drivers/net/wireless/ath/ath6kl/debug.c
index b9bf28d..0b7fa26 100644
--- a/drivers/net/wireless/ath/ath6kl/debug.c
+++ b/drivers/net/wireless/ath/ath6kl/debug.c
@@ -966,6 +966,77 @@ static const struct file_operations fops_diag_reg_write = {
 	.llseek = default_llseek,
 };
 
+static ssize_t ath6kl_roam_table_read(struct file *file, char __user *user_buf,
+				      size_t count, loff_t *ppos)
+{
+	struct ath6kl *ar = file->private_data;
+	int ret;
+	long left;
+	struct wmi_target_roam_tbl *tbl;
+	u16 num_entries, i;
+	char *buf;
+	unsigned int len, buf_len;
+	ssize_t ret_cnt;
+
+	if (down_interruptible(&ar->sem))
+		return -EBUSY;
+
+	set_bit(ROAM_TBL_PEND, &ar->flag);
+
+	ret = ath6kl_wmi_get_roam_tbl_cmd(ar->wmi);
+	if (ret) {
+		up(&ar->sem);
+		return ret;
+	}
+
+	left = wait_event_interruptible_timeout(
+		ar->event_wq, !test_bit(ROAM_TBL_PEND, &ar->flag), WMI_TIMEOUT);
+	up(&ar->sem);
+
+	if (left <= 0)
+		return -ETIMEDOUT;
+
+	if (ar->debug.roam_tbl == NULL)
+		return -ENOMEM;
+
+	tbl = (struct wmi_target_roam_tbl *) ar->debug.roam_tbl;
+	num_entries = le16_to_cpu(tbl->num_entries);
+
+	buf_len = 100 + num_entries * 100;
+	buf = kzalloc(buf_len, GFP_KERNEL);
+	if (buf == NULL)
+		return -ENOMEM;
+	len = 0;
+	len += scnprintf(buf + len, buf_len - len,
+			 "roam_mode=%u\n\n"
+			 "# roam_util bssid rssi rssidt last_rssi util bias\n",
+			 le16_to_cpu(tbl->roam_mode));
+
+	for (i = 0; i < num_entries; i++) {
+		struct wmi_bss_roam_info *info = &tbl->info[i];
+		len += scnprintf(buf + len, buf_len - len,
+				 "%d %pM %d %d %d %d %d\n",
+				 a_sle32_to_cpu(info->roam_util), info->bssid,
+				 info->rssi, info->rssidt, info->last_rssi,
+				 info->util, info->bias);
+	}
+
+	if (len > buf_len)
+		len = buf_len;
+
+	ret_cnt = simple_read_from_buffer(user_buf, count, ppos, buf, len);
+
+	kfree(buf);
+	return ret_cnt;
+}
+
+static const struct file_operations fops_roam_table = {
+	.read = ath6kl_roam_table_read,
+	.open = ath6kl_debugfs_open,
+	.owner = THIS_MODULE,
+	.llseek = default_llseek,
+};
+
 int ath6kl_debug_init(struct ath6kl *ar)
 {
 	ar->debug.fwlog_buf.buf = vmalloc(ATH6KL_FWLOG_SIZE);
@@ -1024,6 +1095,9 @@ int ath6kl_debug_init(struct ath6kl *ar)
 	debugfs_create_file("war_stats", S_IRUSR, ar->debugfs_phy, ar,
 			    &fops_war_stats);
 
+	debugfs_create_file("roam_table", S_IRUSR, ar->debugfs_phy, ar,
+			    &fops_roam_table);
+
 	return 0;
 }
 
@@ -1031,6 +1105,7 @@ void ath6kl_debug_cleanup(struct ath6kl *ar)
 {
 	vfree(ar->debug.fwlog_buf.buf);
 	kfree(ar->debug.fwlog_tmp);
+	kfree(ar->debug.roam_tbl);
 }
 
 #endif
diff --git a/drivers/net/wireless/ath/ath6kl/wmi.c b/drivers/net/wireless/ath/ath6kl/wmi.c
index ab782d7..425efb5 100644
--- a/drivers/net/wireless/ath/ath6kl/wmi.c
+++ b/drivers/net/wireless/ath/ath6kl/wmi.c
@@ -2407,6 +2407,11 @@ int ath6kl_wmi_get_tx_pwr_cmd(struct wmi *wmi)
 	return ath6kl_wmi_simple_cmd(wmi, WMI_GET_TX_PWR_CMDID);
 }
 
+int ath6kl_wmi_get_roam_tbl_cmd(struct wmi *wmi)
+{
+	return ath6kl_wmi_simple_cmd(wmi, WMI_GET_ROAM_TBL_CMDID);
+}
+
 int ath6kl_wmi_set_lpreamble_cmd(struct wmi *wmi, u8 status, u8 preamble_policy)
 {
 	struct sk_buff *skb;
@@ -2844,6 +2849,41 @@ static int ath6kl_wmi_control_rx_xtnd(struct wmi *wmi, struct sk_buff *skb)
 	return ret;
 }
 
+static int ath6kl_wmi_roam_tbl_event_rx(struct wmi *wmi, u8 *datap, int len)
+{
+#ifdef CONFIG_ATH6KL_DEBUG
+	struct ath6kl *ar = wmi->parent_dev;
+	struct wmi_target_roam_tbl *tbl;
+	u16 num_entries;
+
+	if (len < sizeof(*tbl))
+		return -EINVAL;
+
+	tbl = (struct wmi_target_roam_tbl *) datap;
+	num_entries = le16_to_cpu(tbl->num_entries);
+	if (sizeof(*tbl) + num_entries * sizeof(struct wmi_bss_roam_info) > len)
+		return -EINVAL;
+
+	if (ar->debug.roam_tbl == NULL ||
+	    ar->debug.roam_tbl_len < (unsigned int) len) {
+		kfree(ar->debug.roam_tbl);
+		ar->debug.roam_tbl = kmalloc(len, GFP_ATOMIC);
+		if (ar->debug.roam_tbl == NULL)
+			return -ENOMEM;
+	}
+
+	memcpy(ar->debug.roam_tbl, datap, len);
+	ar->debug.roam_tbl_len = len;
+
+	if (test_bit(ROAM_TBL_PEND, &ar->flag)) {
+		clear_bit(ROAM_TBL_PEND, &ar->flag);
+		wake_up(&ar->event_wq);
+	}
+#endif /* CONFIG_ATH6KL_DEBUG */
+
+	return 0;
+}
+
 /* Control Path */
 int ath6kl_wmi_control_rx(struct wmi *wmi, struct sk_buff *skb)
 {
@@ -2948,6 +2988,7 @@ int ath6kl_wmi_control_rx(struct wmi *wmi, struct sk_buff *skb)
 		break;
 	case WMI_REPORT_ROAM_TBL_EVENTID:
 		ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_REPORT_ROAM_TBL_EVENTID\n");
+		ret = ath6kl_wmi_roam_tbl_event_rx(wmi, datap, len);
 		break;
 	case WMI_EXTENSION_EVENTID:
 		ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_EXTENSION_EVENTID\n");
diff --git a/drivers/net/wireless/ath/ath6kl/wmi.h b/drivers/net/wireless/ath/ath6kl/wmi.h
index 96102c6..f986da1 100644
--- a/drivers/net/wireless/ath/ath6kl/wmi.h
+++ b/drivers/net/wireless/ath/ath6kl/wmi.h
@@ -1624,6 +1624,12 @@ struct wmi_bss_roam_info {
 	u8 reserved;
 } __packed;
 
+struct wmi_target_roam_tbl {
+	__le16 roam_mode;
+	__le16 num_entries;
+	struct wmi_bss_roam_info info[];
+} __packed;
+
 /* WMI_CAC_EVENTID */
 enum cac_indication {
 	CAC_INDICATION_ADMISSION = 0x00,
@@ -2221,6 +2227,7 @@ int ath6kl_wmi_setpmkid_cmd(struct wmi *wmi, const u8 *bssid,
 			    const u8 *pmkid, bool set);
 int ath6kl_wmi_set_tx_pwr_cmd(struct wmi *wmi, u8 dbM);
 int ath6kl_wmi_get_tx_pwr_cmd(struct wmi *wmi);
+int ath6kl_wmi_get_roam_tbl_cmd(struct wmi *wmi);
 
 int ath6kl_wmi_set_wmm_txop(struct wmi *wmi, enum wmi_txop_cfg cfg);
 int ath6kl_wmi_set_keepalive_cmd(struct wmi *wmi, u8 keep_alive_intvl);
-- 
1.7.4.1


^ permalink raw reply related

* [PATCH 3/5] ath6kl: Add debugfs files for roaming control
From: Jouni Malinen @ 2011-10-10 10:43 UTC (permalink / raw)
  To: kvalo; +Cc: linux-wireless, Jouni Malinen
In-Reply-To: <1318243411-16110-1-git-send-email-jouni@qca.qualcomm.com>

Roaming mode can be changed by writing roam mode (default, bssbias, or
lock) to roam_mode. Forced roam can be requested by writing the BSSID
into force_roam.

Signed-off-by: Jouni Malinen <jouni@qca.qualcomm.com>
---
 drivers/net/wireless/ath/ath6kl/debug.c |   84 +++++++++++++++++++++++++++++++
 drivers/net/wireless/ath/ath6kl/wmi.c   |   40 +++++++++++++++
 drivers/net/wireless/ath/ath6kl/wmi.h   |   21 ++++++--
 3 files changed, 139 insertions(+), 6 deletions(-)

diff --git a/drivers/net/wireless/ath/ath6kl/debug.c b/drivers/net/wireless/ath/ath6kl/debug.c
index 0b7fa26..51eb626 100644
--- a/drivers/net/wireless/ath/ath6kl/debug.c
+++ b/drivers/net/wireless/ath/ath6kl/debug.c
@@ -1037,6 +1037,84 @@ static const struct file_operations fops_roam_table = {
 	.llseek = default_llseek,
 };
 
+static ssize_t ath6kl_force_roam_write(struct file *file,
+				       const char __user *user_buf,
+				       size_t count, loff_t *ppos)
+{
+	struct ath6kl *ar = file->private_data;
+	int ret;
+	char buf[20];
+	size_t len;
+	u8 bssid[ETH_ALEN];
+	int i;
+	int addr[ETH_ALEN];
+
+	len = min(count, sizeof(buf) - 1);
+	if (copy_from_user(buf, user_buf, len))
+		return -EFAULT;
+	buf[len] = '\0';
+
+	if (sscanf(buf, "%02x:%02x:%02x:%02x:%02x:%02x",
+		   &addr[0], &addr[1], &addr[2], &addr[3], &addr[4], &addr[5])
+	    != ETH_ALEN)
+		return -EINVAL;
+	for (i = 0; i < ETH_ALEN; i++)
+		bssid[i] = addr[i];
+
+	ret = ath6kl_wmi_force_roam_cmd(ar->wmi, bssid);
+	if (ret)
+		return ret;
+
+	return count;
+}
+
+static const struct file_operations fops_force_roam = {
+	.write = ath6kl_force_roam_write,
+	.open = ath6kl_debugfs_open,
+	.owner = THIS_MODULE,
+	.llseek = default_llseek,
+};
+
+static ssize_t ath6kl_roam_mode_write(struct file *file,
+				      const char __user *user_buf,
+				      size_t count, loff_t *ppos)
+{
+	struct ath6kl *ar = file->private_data;
+	int ret;
+	char buf[20];
+	size_t len;
+	enum wmi_roam_mode mode;
+
+	len = min(count, sizeof(buf) - 1);
+	if (copy_from_user(buf, user_buf, len))
+		return -EFAULT;
+	buf[len] = '\0';
+	if (len > 0 && buf[len - 1] == '\n')
+		buf[len - 1] = '\0';
+
+	if (strcasecmp(buf, "default") == 0)
+		mode = WMI_DEFAULT_ROAM_MODE;
+	else if (strcasecmp(buf, "bssbias") == 0)
+		mode = WMI_HOST_BIAS_ROAM_MODE;
+	else if (strcasecmp(buf, "lock") == 0)
+		mode = WMI_LOCK_BSS_MODE;
+	else
+		return -EINVAL;
+
+	ret = ath6kl_wmi_set_roam_mode_cmd(ar->wmi, mode);
+	if (ret)
+		return ret;
+
+	return count;
+}
+
+static const struct file_operations fops_roam_mode = {
+	.write = ath6kl_roam_mode_write,
+	.open = ath6kl_debugfs_open,
+	.owner = THIS_MODULE,
+	.llseek = default_llseek,
+};
+
 int ath6kl_debug_init(struct ath6kl *ar)
 {
 	ar->debug.fwlog_buf.buf = vmalloc(ATH6KL_FWLOG_SIZE);
@@ -1098,6 +1176,12 @@ int ath6kl_debug_init(struct ath6kl *ar)
 	debugfs_create_file("roam_table", S_IRUSR, ar->debugfs_phy, ar,
 			    &fops_roam_table);
 
+	debugfs_create_file("force_roam", S_IWUSR, ar->debugfs_phy, ar,
+			    &fops_force_roam);
+
+	debugfs_create_file("roam_mode", S_IWUSR, ar->debugfs_phy, ar,
+			    &fops_roam_mode);
+
 	return 0;
 }
 
diff --git a/drivers/net/wireless/ath/ath6kl/wmi.c b/drivers/net/wireless/ath/ath6kl/wmi.c
index 425efb5..fdb3712 100644
--- a/drivers/net/wireless/ath/ath6kl/wmi.c
+++ b/drivers/net/wireless/ath/ath6kl/wmi.c
@@ -682,6 +682,46 @@ int ath6kl_wmi_set_roam_lrssi_cmd(struct wmi *wmi, u8 lrssi)
 	return 0;
 }
 
+int ath6kl_wmi_force_roam_cmd(struct wmi *wmi, const u8 *bssid)
+{
+	struct sk_buff *skb;
+	struct roam_ctrl_cmd *cmd;
+
+	skb = ath6kl_wmi_get_new_buf(sizeof(*cmd));
+	if (!skb)
+		return -ENOMEM;
+
+	cmd = (struct roam_ctrl_cmd *) skb->data;
+	memset(cmd, 0, sizeof(*cmd));
+
+	memcpy(cmd->info.bssid, bssid, ETH_ALEN);
+	cmd->roam_ctrl = WMI_FORCE_ROAM;
+
+	ath6kl_dbg(ATH6KL_DBG_WMI, "force roam to %pM\n", bssid);
+	return ath6kl_wmi_cmd_send(wmi, skb, WMI_SET_ROAM_CTRL_CMDID,
+				   NO_SYNC_WMIFLAG);
+}
+
+int ath6kl_wmi_set_roam_mode_cmd(struct wmi *wmi, enum wmi_roam_mode mode)
+{
+	struct sk_buff *skb;
+	struct roam_ctrl_cmd *cmd;
+
+	skb = ath6kl_wmi_get_new_buf(sizeof(*cmd));
+	if (!skb)
+		return -ENOMEM;
+
+	cmd = (struct roam_ctrl_cmd *) skb->data;
+	memset(cmd, 0, sizeof(*cmd));
+
+	cmd->info.roam_mode = mode;
+	cmd->roam_ctrl = WMI_SET_ROAM_MODE;
+
+	ath6kl_dbg(ATH6KL_DBG_WMI, "set roam mode %d\n", mode);
+	return ath6kl_wmi_cmd_send(wmi, skb, WMI_SET_ROAM_CTRL_CMDID,
+				   NO_SYNC_WMIFLAG);
+}
+
 static int ath6kl_wmi_connect_event_rx(struct wmi *wmi, u8 *datap, int len)
 {
 	struct wmi_connect_event *ev;
diff --git a/drivers/net/wireless/ath/ath6kl/wmi.h b/drivers/net/wireless/ath/ath6kl/wmi.h
index f986da1..f0ca899 100644
--- a/drivers/net/wireless/ath/ath6kl/wmi.h
+++ b/drivers/net/wireless/ath/ath6kl/wmi.h
@@ -1354,14 +1354,20 @@ enum wmi_roam_ctrl {
 	WMI_SET_LRSSI_SCAN_PARAMS,
 };
 
+enum wmi_roam_mode {
+	WMI_DEFAULT_ROAM_MODE = 1, /* RSSI based roam */
+	WMI_HOST_BIAS_ROAM_MODE = 2, /* Host bias based roam */
+	WMI_LOCK_BSS_MODE = 3, /* Lock to the current BSS */
+};
+
 struct bss_bias {
 	u8 bssid[ETH_ALEN];
-	u8  bias;
+	s8 bias;
 } __packed;
 
 struct bss_bias_info {
 	u8 num_bss;
-	struct bss_bias bss_bias[1];
+	struct bss_bias bss_bias[0];
 } __packed;
 
 struct low_rssi_scan_params {
@@ -1374,10 +1380,11 @@ struct low_rssi_scan_params {
 
 struct roam_ctrl_cmd {
 	union {
-		u8 bssid[ETH_ALEN];
-		u8 roam_mode;
-		struct bss_bias_info bss;
-		struct low_rssi_scan_params params;
+		u8 bssid[ETH_ALEN]; /* WMI_FORCE_ROAM */
+		u8 roam_mode; /* WMI_SET_ROAM_MODE */
+		struct bss_bias_info bss; /* WMI_SET_HOST_BIAS */
+		struct low_rssi_scan_params params; /* WMI_SET_LRSSI_SCAN_PARAMS
+						     */
 	} __packed info;
 	u8 roam_ctrl;
 } __packed;
@@ -2237,6 +2244,8 @@ s32 ath6kl_wmi_get_rate(s8 rate_index);
 
 int ath6kl_wmi_set_ip_cmd(struct wmi *wmi, struct wmi_set_ip_cmd *ip_cmd);
 int ath6kl_wmi_set_roam_lrssi_cmd(struct wmi *wmi, u8 lrssi);
+int ath6kl_wmi_force_roam_cmd(struct wmi *wmi, const u8 *bssid);
+int ath6kl_wmi_set_roam_mode_cmd(struct wmi *wmi, enum wmi_roam_mode mode);
 
 /* AP mode */
 int ath6kl_wmi_ap_profile_commit(struct wmi *wmip, struct wmi_connect_cmd *p);
-- 
1.7.4.1


^ permalink raw reply related

* [PATCH 4/5] ath6kl: Add debugfs control for keepalive and disconnection timeout
From: Jouni Malinen @ 2011-10-10 10:43 UTC (permalink / raw)
  To: kvalo; +Cc: linux-wireless, Jouni Malinen
In-Reply-To: <1318243411-16110-1-git-send-email-jouni@qca.qualcomm.com>

The new debugfs files keepalive and disconnect_timeout can be used to
fetch the current values and to change the values for keepalive and
disconnect event timeout (both in seconds).

Signed-off-by: Jouni Malinen <jouni@qca.qualcomm.com>
---
 drivers/net/wireless/ath/ath6kl/core.h  |    3 +
 drivers/net/wireless/ath/ath6kl/debug.c |   85 +++++++++++++++++++++++++++++++
 drivers/net/wireless/ath/ath6kl/wmi.c   |    8 +++
 3 files changed, 96 insertions(+), 0 deletions(-)

diff --git a/drivers/net/wireless/ath/ath6kl/core.h b/drivers/net/wireless/ath/ath6kl/core.h
index c58cfad..31e5c7e 100644
--- a/drivers/net/wireless/ath/ath6kl/core.h
+++ b/drivers/net/wireless/ath/ath6kl/core.h
@@ -533,6 +533,9 @@ struct ath6kl {
 
 		u8 *roam_tbl;
 		unsigned int roam_tbl_len;
+
+		u8 keepalive;
+		u8 disc_timeout;
 	} debug;
 #endif /* CONFIG_ATH6KL_DEBUG */
 };
diff --git a/drivers/net/wireless/ath/ath6kl/debug.c b/drivers/net/wireless/ath/ath6kl/debug.c
index 51eb626..9035002 100644
--- a/drivers/net/wireless/ath/ath6kl/debug.c
+++ b/drivers/net/wireless/ath/ath6kl/debug.c
@@ -1115,6 +1115,85 @@ static const struct file_operations fops_roam_mode = {
 	.llseek = default_llseek,
 };
 
+static ssize_t ath6kl_keepalive_read(struct file *file, char __user *user_buf,
+				     size_t count, loff_t *ppos)
+{
+	struct ath6kl *ar = file->private_data;
+	char buf[16];
+	int len;
+
+	len = snprintf(buf, sizeof(buf), "%u\n", ar->debug.keepalive);
+
+	return simple_read_from_buffer(user_buf, count, ppos, buf, len);
+}
+
+static ssize_t ath6kl_keepalive_write(struct file *file,
+				      const char __user *user_buf,
+				      size_t count, loff_t *ppos)
+{
+	struct ath6kl *ar = file->private_data;
+	int ret;
+	u8 val;
+
+	ret = kstrtou8_from_user(user_buf, count, 0, &val);
+	if (ret)
+		return ret;
+
+	ret = ath6kl_wmi_set_keepalive_cmd(ar->wmi, val);
+	if (ret)
+		return ret;
+
+	return count;
+}
+
+static const struct file_operations fops_keepalive = {
+	.open = ath6kl_debugfs_open,
+	.read = ath6kl_keepalive_read,
+	.write = ath6kl_keepalive_write,
+	.owner = THIS_MODULE,
+	.llseek = default_llseek,
+};
+
+static ssize_t ath6kl_disconnect_timeout_read(struct file *file,
+					      char __user *user_buf,
+					      size_t count, loff_t *ppos)
+{
+	struct ath6kl *ar = file->private_data;
+	char buf[16];
+	int len;
+
+	len = snprintf(buf, sizeof(buf), "%u\n", ar->debug.disc_timeout);
+
+	return simple_read_from_buffer(user_buf, count, ppos, buf, len);
+}
+
+static ssize_t ath6kl_disconnect_timeout_write(struct file *file,
+					       const char __user *user_buf,
+					       size_t count, loff_t *ppos)
+{
+	struct ath6kl *ar = file->private_data;
+	int ret;
+	u8 val;
+
+	ret = kstrtou8_from_user(user_buf, count, 0, &val);
+	if (ret)
+		return ret;
+
+	ret = ath6kl_wmi_disctimeout_cmd(ar->wmi, val);
+	if (ret)
+		return ret;
+
+	return count;
+}
+
+static const struct file_operations fops_disconnect_timeout = {
+	.open = ath6kl_debugfs_open,
+	.read = ath6kl_disconnect_timeout_read,
+	.write = ath6kl_disconnect_timeout_write,
+	.owner = THIS_MODULE,
+	.llseek = default_llseek,
+};
+
 int ath6kl_debug_init(struct ath6kl *ar)
 {
 	ar->debug.fwlog_buf.buf = vmalloc(ATH6KL_FWLOG_SIZE);
@@ -1182,6 +1261,12 @@ int ath6kl_debug_init(struct ath6kl *ar)
 	debugfs_create_file("roam_mode", S_IWUSR, ar->debugfs_phy, ar,
 			    &fops_roam_mode);
 
+	debugfs_create_file("keepalive", S_IRUSR | S_IWUSR, ar->debugfs_phy, ar,
+			    &fops_keepalive);
+
+	debugfs_create_file("disconnect_timeout", S_IRUSR | S_IWUSR,
+			    ar->debugfs_phy, ar, &fops_disconnect_timeout);
+
 	return 0;
 }
 
diff --git a/drivers/net/wireless/ath/ath6kl/wmi.c b/drivers/net/wireless/ath/ath6kl/wmi.c
index fdb3712..dd8110c 100644
--- a/drivers/net/wireless/ath/ath6kl/wmi.c
+++ b/drivers/net/wireless/ath/ath6kl/wmi.c
@@ -1940,6 +1940,10 @@ int ath6kl_wmi_disctimeout_cmd(struct wmi *wmi, u8 timeout)
 
 	ret = ath6kl_wmi_cmd_send(wmi, skb, WMI_SET_DISC_TIMEOUT_CMDID,
 				  NO_SYNC_WMIFLAG);
+#ifdef CONFIG_ATH6KL_DEBUG
+	if (ret == 0)
+		wmi->parent_dev->debug.disc_timeout = timeout;
+#endif /* CONFIG_ATH6KL_DEBUG */
 	return ret;
 }
 
@@ -2524,6 +2528,10 @@ int ath6kl_wmi_set_keepalive_cmd(struct wmi *wmi, u8 keep_alive_intvl)
 
 	ret = ath6kl_wmi_cmd_send(wmi, skb, WMI_SET_KEEPALIVE_CMDID,
 				  NO_SYNC_WMIFLAG);
+#ifdef CONFIG_ATH6KL_DEBUG
+	if (ret == 0)
+		wmi->parent_dev->debug.keepalive = keep_alive_intvl;
+#endif /* CONFIG_ATH6KL_DEBUG */
 	return ret;
 }
 
-- 
1.7.4.1


^ permalink raw reply related

* [PATCH 5/5] ath6kl: Allow CCKM AKM and KRK to be configured
From: Jouni Malinen @ 2011-10-10 10:43 UTC (permalink / raw)
  To: kvalo; +Cc: linux-wireless, Jouni Malinen
In-Reply-To: <1318243411-16110-1-git-send-email-jouni@qca.qualcomm.com>

Use vendor-specific suite selectors to allow CCKM to be configured.

Signed-off-by: Jouni Malinen <jouni@qca.qualcomm.com>
---
 drivers/net/wireless/ath/ath6kl/cfg80211.c |   14 ++++++++++++++
 1 files changed, 14 insertions(+), 0 deletions(-)

diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c
index b7b2c57..6b30b75 100644
--- a/drivers/net/wireless/ath/ath6kl/cfg80211.c
+++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c
@@ -121,6 +121,8 @@ static struct ieee80211_supported_band ath6kl_band_5ghz = {
 	.bitrates = ath6kl_a_rates,
 };
 
+#define CCKM_KRK_CIPHER_SUITE 0x004096ff /* use for KRK */
+
 static int ath6kl_set_wpa_version(struct ath6kl *ar,
 				  enum nl80211_wpa_versions wpa_version)
 {
@@ -217,6 +219,11 @@ static void ath6kl_set_key_mgmt(struct ath6kl *ar, u32 key_mgmt)
 			ar->auth_mode = WPA_PSK_AUTH;
 		else if (ar->auth_mode == WPA2_AUTH)
 			ar->auth_mode = WPA2_PSK_AUTH;
+	} else if (key_mgmt == 0x00409600) {
+		if (ar->auth_mode == WPA_AUTH)
+			ar->auth_mode = WPA_AUTH_CCKM;
+		else if (ar->auth_mode == WPA2_AUTH)
+			ar->auth_mode = WPA2_AUTH_CCKM;
 	} else if (key_mgmt != WLAN_AKM_SUITE_8021X) {
 		ar->auth_mode = NONE_AUTH;
 	}
@@ -758,6 +765,12 @@ static int ath6kl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
 	if (!ath6kl_cfg80211_ready(ar))
 		return -EIO;
 
+	if (params->cipher == CCKM_KRK_CIPHER_SUITE) {
+		if (params->key_len != WMI_KRK_LEN)
+			return -EINVAL;
+		return ath6kl_wmi_add_krk_cmd(ar->wmi, params->key);
+	}
+
 	if (key_index < WMI_MIN_KEY_INDEX || key_index > WMI_MAX_KEY_INDEX) {
 		ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
 			   "%s: key index %d out of bounds\n", __func__,
@@ -1228,6 +1241,7 @@ static const u32 cipher_suites[] = {
 	WLAN_CIPHER_SUITE_WEP104,
 	WLAN_CIPHER_SUITE_TKIP,
 	WLAN_CIPHER_SUITE_CCMP,
+	CCKM_KRK_CIPHER_SUITE,
 };
 
 static bool is_rate_legacy(s32 rate)
-- 
1.7.4.1


^ permalink raw reply related

* Re: [alsa-devel] Using spdiff for backporting
From: Takashi Iwai @ 2011-10-10 12:41 UTC (permalink / raw)
  To: Luis R. Rodriguez
  Cc: Jesper Andersen, linux-wireless, alsa-devel, julia, linux-kernel
In-Reply-To: <CAB=NE6X81KPvx-yt33MghmoftUznoP-jYO8sBxoeW_0fzQ1pdA@mail.gmail.com>

At Fri, 7 Oct 2011 10:41:06 -0700,
Luis R. Rodriguez wrote:
> 
> > Also, in the slides from the plumbers-conf. I think I saw it mentioned
> > that there's also an alsa-compat git-tree somewhere. Maybe that is a
> > more compelling usecase? I was unable to find it though so I'd
> > appreciate a link.
> 
> It was on kernel.org, but if it got rm -rf'd then its gone as I do not
> have a local copy.

Oh, I didn't know of such a tree.  So you created alsa driver build
system with your spdiff?  That's interesting.

> The compat-alsa stuff though was determined to be
> superflous with the ALSA's team's own backport work which is currently
> independent.

Yes, the external alsa-driver build tree has existed since 10 years
ago :)  It was even possible to build with 2.2/2.4 kernels until
recently.

The current tree is found in github,
	git://github.com/tiwai/alsa-driver-build.git

> My hope though is to unify these through the compat.git /
> compat-kernel (currently just called compat-wireless) effort.

The common framework would be really nice to have.
V4L also have own build system, and possible other subsystem trees too.


thanks,

Takashi

^ permalink raw reply

* Re: [PATCH 04/20] staging: brcm80211: various __iomem additions to softmac.
From: Rafał Miłecki @ 2011-10-10 14:23 UTC (permalink / raw)
  To: Franky Lin; +Cc: gregkh, devel, linux-wireless
In-Reply-To: <1317575685-3156-5-git-send-email-frankyl@broadcom.com>

2011/10/2 Franky Lin <frankyl@broadcom.com>:
> From: Roland Vossen <rvossen@broadcom.com>
>
> So it is clear to the reader what memory is IO mapped
>
> Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
> Reviewed-by: Arend van Spriel <arend@broadcom.com>
> Signed-off-by: Franky Lin <frankyl@broadcom.com>
> ---
>  drivers/staging/brcm80211/brcmsmac/aiutils.c |  107 ++++++++++++++------------
>  drivers/staging/brcm80211/brcmsmac/aiutils.h |   16 ++--
>  drivers/staging/brcm80211/brcmsmac/main.c    |    2 +-
>  drivers/staging/brcm80211/brcmsmac/nicpci.c  |   45 ++++++-----
>  drivers/staging/brcm80211/brcmsmac/nicpci.h  |    9 +-
>  drivers/staging/brcm80211/brcmsmac/otp.c     |    9 +-
>  drivers/staging/brcm80211/brcmsmac/pmu.c     |   16 ++--
>  drivers/staging/brcm80211/brcmsmac/srom.c    |   20 +++--
>  drivers/staging/brcm80211/brcmsmac/srom.h    |    2 +-
>  9 files changed, 123 insertions(+), 103 deletions(-)
>
> diff --git a/drivers/staging/brcm80211/brcmsmac/aiutils.c b/drivers/staging/brcm80211/brcmsmac/aiutils.c
> index 790fdce..0b3ba6a 100644
> --- a/drivers/staging/brcm80211/brcmsmac/aiutils.c
> +++ b/drivers/staging/brcm80211/brcmsmac/aiutils.c
> @@ -323,7 +323,8 @@
>                     (((si)->pub.buscoretype == PCI_CORE_ID) && \
>                      (si)->pub.buscorerev >= 13))
>
> -#define CCREGS_FAST(si) (((char *)((si)->curmap) + PCI_16KB0_CCREGS_OFFSET))
> +#define CCREGS_FAST(si) (((char __iomem *)((si)->curmap) + \
> +                         PCI_16KB0_CCREGS_OFFSET))

I've a question (not to just you), should we prefer u8/u16/u32 types in code?
If so, you could think to changing this since you already touch this code.

-- 
Rafał

^ permalink raw reply

* Re: [PATCH v3 21/25] staging: brcm80211: use endian annotated structures in brcmsmac
From: Rafał Miłecki @ 2011-10-10 14:35 UTC (permalink / raw)
  To: Franky Lin; +Cc: gregkh, devel, linux-wireless
In-Reply-To: <1317335676-3424-22-git-send-email-frankyl@broadcom.com>

2011/9/30 Franky Lin <frankyl@broadcom.com>:
> From: Arend van Spriel <arend@broadcom.com>


> +struct d11rxhdr_le {
> +       __le16 RxFrameSize;
> +       u16 PAD;
> +       __le16 PhyRxStatus_0;
> +       __le16 PhyRxStatus_1;
> +       __le16 PhyRxStatus_2;
> +       __le16 PhyRxStatus_3;
> +       __le16 PhyRxStatus_4;
> +       __le16 PhyRxStatus_5;
> +       __le16 RxStatus1;
> +       __le16 RxStatus2;
> +       __le16 RxTSFTime;
> +       __le16 RxChan;
> +} __packed;

So you decided to use __packed here anyway for some reason? ;)


>  struct d11rxhdr {
>        u16 RxFrameSize;
>        u16 PAD;
> @@ -1392,20 +1407,18 @@ struct d11rxhdr {
>        u16 RxStatus2;
>        u16 RxTSFTime;
>        u16 RxChan;
> -} __packed;
> +};

You should be right, none compiler should break that alignment...
still no idea why usage of __packed hurt anyone, made code clear
according to me.

-- 
Rafał

^ permalink raw reply

* [PATCH 00/34] update for 3.2
From: Wey-Yi Guy @ 2011-10-10 14:26 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, Wey-Yi Guy

We address the performance issue cause by earlier path which disable too many calibration.
We include few more bugs fix and enhancement patches for WoWLAN operations
We continue remove un-needed code and clean up after driver split
We also include new SKUs for both 6005 and 105 series of devices

Don Fry (1):
  iwlagn: eliminate bus pointer from iwl_priv structure

Emmanuel Grumbach (7):
  iwlagn: kill hw_params.max_stations
  iwlagn: fix a race in the unmapping of the TFDs
  iwlagn: warn only once if AGG state is wrong
  iwlagn: move iwl_beacon_time_mask_XXX near to usage
  iwlagn: move iwl_enable_rfkill_int and kill iwl-helpers.h
  iwlagn: remove uneeded include to iwl-dev.h
  iwlagn: add missing include to iwl-agn-rs.h

Johannes Berg (6):
  iwlagn: update beacon smarter
  iwlagn: don't assign seqno to QoS Null frames
  iwlagn: send simple LQ command for WoWLAN
  iwlagn: stop interrupts when suspending
  iwlagn: remove 5000 hw header
  iwlagn: remove 6000 hw header

Wey-Yi Guy (20):
  iwlagn: add cmd queue pointer info when timeout
  iwlagn: add REPLY_ECHO host command
  iwlagn: add WARN if tx cmd complete come back late
  iwlagn: add "echo" test when command queue stuck
  iwlagn: check rf kill in queue stuck
  iwlagn: add "echo test" command to debugfs
  iwlagn: remove un-necessary step
  iwlagn: set rts retry limit
  iwlagn: add "_d" sku to 6005 series of devices
  iwlagn: Add "_d" sku to 105 series of devices
  iwlagn: separate init calib and rt calib
  iwlagn: do nothing when disable agg in wrong state
  iwlagn: use low retry limit for WoWLAN
  iwlwifi: update comments on how to enable debug flag
  iwlagn: more info on warning for shutdown agg queue
  iwlagn: don't stop rts/cts until last aggregation queue close
  iwlagn: add debug for mac80211 callback
  iwlagn: rename all the mac80211 callback functions
  iwlagn: merge station management functions
  iwlagn: rename iwl-rx.c to iwl-agn-rx.c

these patches are also available from wireless-next-2.6 branch on
 git://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi.git

Because the file system problem, all the patches are not push into 
git.kernel.org yet. I will push as soon as the file system issue addressed


 drivers/net/wireless/iwlwifi/Kconfig             |    4 +-
 drivers/net/wireless/iwlwifi/Makefile            |    3 +-
 drivers/net/wireless/iwlwifi/iwl-1000.c          |    3 -
 drivers/net/wireless/iwlwifi/iwl-2000.c          |   10 +-
 drivers/net/wireless/iwlwifi/iwl-5000-hw.h       |   88 --
 drivers/net/wireless/iwlwifi/iwl-5000.c          |   22 +-
 drivers/net/wireless/iwlwifi/iwl-6000-hw.h       |   81 --
 drivers/net/wireless/iwlwifi/iwl-6000.c          |   12 +-
 drivers/net/wireless/iwlwifi/iwl-agn-hw.h        |   15 +-
 drivers/net/wireless/iwlwifi/iwl-agn-lib.c       |    2 -
 drivers/net/wireless/iwlwifi/iwl-agn-rs.c        |    4 +-
 drivers/net/wireless/iwlwifi/iwl-agn-rs.h        |    4 +
 drivers/net/wireless/iwlwifi/iwl-agn-rx.c        | 1143 ++++++++++++++++++++++
 drivers/net/wireless/iwlwifi/iwl-agn-rxon.c      |    6 +-
 drivers/net/wireless/iwlwifi/iwl-agn-sta.c       |  861 ++++++++++++++++-
 drivers/net/wireless/iwlwifi/iwl-agn-tx.c        |   32 +-
 drivers/net/wireless/iwlwifi/iwl-agn-ucode.c     |    1 -
 drivers/net/wireless/iwlwifi/iwl-agn.c           |  126 ++-
 drivers/net/wireless/iwlwifi/iwl-agn.h           |  131 +++-
 drivers/net/wireless/iwlwifi/iwl-cfg.h           |    2 +
 drivers/net/wireless/iwlwifi/iwl-commands.h      |   11 +
 drivers/net/wireless/iwlwifi/iwl-core.c          |   83 ++-
 drivers/net/wireless/iwlwifi/iwl-core.h          |   20 +-
 drivers/net/wireless/iwlwifi/iwl-debug.h         |    8 +-
 drivers/net/wireless/iwlwifi/iwl-debugfs.c       |   22 +-
 drivers/net/wireless/iwlwifi/iwl-dev.h           |    3 -
 drivers/net/wireless/iwlwifi/iwl-helpers.h       |   72 --
 drivers/net/wireless/iwlwifi/iwl-led.c           |    3 +-
 drivers/net/wireless/iwlwifi/iwl-pci.c           |    2 +
 drivers/net/wireless/iwlwifi/iwl-power.c         |    2 +-
 drivers/net/wireless/iwlwifi/iwl-rx.c            | 1141 ---------------------
 drivers/net/wireless/iwlwifi/iwl-scan.c          |    4 +-
 drivers/net/wireless/iwlwifi/iwl-shared.h        |    2 -
 drivers/net/wireless/iwlwifi/iwl-sta.c           |  835 ----------------
 drivers/net/wireless/iwlwifi/iwl-sta.h           |  141 ---
 drivers/net/wireless/iwlwifi/iwl-sv-open.c       |    8 +-
 drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c |    1 -
 drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c |   23 +-
 drivers/net/wireless/iwlwifi/iwl-trans-pcie.c    |   21 +-
 39 files changed, 2422 insertions(+), 2530 deletions(-)
 delete mode 100644 drivers/net/wireless/iwlwifi/iwl-5000-hw.h
 delete mode 100644 drivers/net/wireless/iwlwifi/iwl-6000-hw.h
 create mode 100644 drivers/net/wireless/iwlwifi/iwl-agn-rx.c
 delete mode 100644 drivers/net/wireless/iwlwifi/iwl-helpers.h
 delete mode 100644 drivers/net/wireless/iwlwifi/iwl-rx.c
 delete mode 100644 drivers/net/wireless/iwlwifi/iwl-sta.c
 delete mode 100644 drivers/net/wireless/iwlwifi/iwl-sta.h


^ permalink raw reply

* [PATCH 04/34] iwlagn: add "echo" test when command queue stuck
From: Wey-Yi Guy @ 2011-10-10 14:26 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, Wey-Yi Guy
In-Reply-To: <1318256839-31837-1-git-send-email-wey-yi.w.guy@intel.com>

When detect command queue stuck, instead of reload the firmware
do the "echo" test to make sure it is really stuck before reload

Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
---
 drivers/net/wireless/iwlwifi/iwl-core.c |   23 ++++++++++++++++++++++-
 drivers/net/wireless/iwlwifi/iwl-core.h |    1 +
 2 files changed, 23 insertions(+), 1 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index 0725603..59d1968 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -1732,10 +1732,31 @@ int iwl_mac_change_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
 	return err;
 }
 
+int iwl_cmd_echo_test(struct iwl_priv *priv)
+{
+	struct iwl_host_cmd cmd = {
+		.id = REPLY_ECHO,
+		.flags = CMD_SYNC,
+	};
+
+	return iwl_trans_send_cmd(trans(priv), &cmd);
+}
+
 static inline int iwl_check_stuck_queue(struct iwl_priv *priv, int txq)
 {
 	if (iwl_trans_check_stuck_queue(trans(priv), txq)) {
-		int ret = iwl_force_reset(priv, IWL_FW_RESET, false);
+		int ret;
+		if (txq == priv->shrd->cmd_queue) {
+			/*
+			 * validate command queue still working
+			 * by sending "ECHO" command
+			 */
+			if (!iwl_cmd_echo_test(priv))
+				return 0;
+			else
+				IWL_DEBUG_HC(priv, "echo testing fail\n");
+		}
+		ret = iwl_force_reset(priv, IWL_FW_RESET, false);
 		return (ret == -EAGAIN) ? 0 : 1;
 	}
 	return 0;
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index db50b65..080c355 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -266,6 +266,7 @@ void iwl_mac_remove_interface(struct ieee80211_hw *hw,
 int iwl_mac_change_interface(struct ieee80211_hw *hw,
 			     struct ieee80211_vif *vif,
 			     enum nl80211_iftype newtype, bool newp2p);
+int iwl_cmd_echo_test(struct iwl_priv *priv);
 #ifdef CONFIG_IWLWIFI_DEBUGFS
 int iwl_alloc_traffic_mem(struct iwl_priv *priv);
 void iwl_free_traffic_mem(struct iwl_priv *priv);
-- 
1.7.0.4


^ permalink raw reply related

* [PATCH 05/34] iwlagn: check rf kill in queue stuck
From: Wey-Yi Guy @ 2011-10-10 14:26 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, Wey-Yi Guy
In-Reply-To: <1318256839-31837-1-git-send-email-wey-yi.w.guy@intel.com>

check the RF KILL flag in queue stuck watch dog function

Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
---
 drivers/net/wireless/iwlwifi/iwl-core.c |    3 +++
 1 files changed, 3 insertions(+), 0 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index 59d1968..9cb6c75 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -1781,6 +1781,9 @@ void iwl_bg_watchdog(unsigned long data)
 	if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status))
 		return;
 
+	if (iwl_is_rfkill(priv->shrd))
+		return;
+
 	timeout = priv->cfg->base_params->wd_timeout;
 	if (timeout == 0)
 		return;
-- 
1.7.0.4


^ permalink raw reply related

* [PATCH 03/34] iwlagn: add WARN if tx cmd complete come back late
From: Wey-Yi Guy @ 2011-10-10 14:26 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, Wey-Yi Guy
In-Reply-To: <1318256839-31837-1-git-send-email-wey-yi.w.guy@intel.com>

For error condition, STATUS_HCMD_ACTIVE already got clear before receive
tx cmd complete, give warning

Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
---
 drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c |    5 +++++
 1 files changed, 5 insertions(+), 0 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c
index f57b868..fa2ce39 100644
--- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c
@@ -950,6 +950,11 @@ void iwl_tx_cmd_complete(struct iwl_trans *trans, struct iwl_rx_mem_buffer *rxb,
 	iwl_hcmd_queue_reclaim(trans, txq_id, index);
 
 	if (!(meta->flags & CMD_ASYNC)) {
+		if (!test_bit(STATUS_HCMD_ACTIVE, &trans->shrd->status)) {
+			IWL_WARN(trans,
+				 "HCMD_ACTIVE already clear for command %s\n",
+				 get_cmd_string(cmd->hdr.cmd));
+		}
 		clear_bit(STATUS_HCMD_ACTIVE, &trans->shrd->status);
 		IWL_DEBUG_INFO(trans, "Clearing HCMD_ACTIVE for command %s\n",
 			       get_cmd_string(cmd->hdr.cmd));
-- 
1.7.0.4


^ permalink raw reply related

* [PATCH 02/34] iwlagn: add REPLY_ECHO host command
From: Wey-Yi Guy @ 2011-10-10 14:26 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, Wey-Yi Guy
In-Reply-To: <1318256839-31837-1-git-send-email-wey-yi.w.guy@intel.com>

Add "echo" host command for testing and drebugging to make sure uCode still
responding

Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
---
 drivers/net/wireless/iwlwifi/iwl-commands.h |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h
index 64593aa..9a5d993 100644
--- a/drivers/net/wireless/iwlwifi/iwl-commands.h
+++ b/drivers/net/wireless/iwlwifi/iwl-commands.h
@@ -89,6 +89,7 @@ struct iwl_priv;
 enum {
 	REPLY_ALIVE = 0x1,
 	REPLY_ERROR = 0x2,
+	REPLY_ECHO = 0x3,		/* test command */
 
 	/* RXON and QOS commands */
 	REPLY_RXON = 0x10,
-- 
1.7.0.4


^ permalink raw reply related

* [PATCH 01/34] iwlagn: add cmd queue pointer info when timeout
From: Wey-Yi Guy @ 2011-10-10 14:26 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, Wey-Yi Guy
In-Reply-To: <1318256839-31837-1-git-send-email-wey-yi.w.guy@intel.com>

When detect cmd queue time out, display the current read/write pointer

Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
---
 drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c |    9 +++++++++
 1 files changed, 9 insertions(+), 0 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c
index ee7059d..f57b868 100644
--- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c
@@ -1013,11 +1013,20 @@ static int iwl_send_cmd_sync(struct iwl_trans *trans, struct iwl_host_cmd *cmd)
 			HOST_COMPLETE_TIMEOUT);
 	if (!ret) {
 		if (test_bit(STATUS_HCMD_ACTIVE, &trans->shrd->status)) {
+			struct iwl_priv *priv = priv(trans);
+			struct iwl_tx_queue *txq =
+				&trans_pcie->txq[priv->shrd->cmd_queue];
+			struct iwl_queue *q = &txq->q;
+
 			IWL_ERR(trans,
 				"Error sending %s: time out after %dms.\n",
 				get_cmd_string(cmd->id),
 				jiffies_to_msecs(HOST_COMPLETE_TIMEOUT));
 
+			IWL_ERR(trans,
+				"Current CMD queue read_ptr %d write_ptr %d\n",
+				q->read_ptr, q->write_ptr);
+
 			clear_bit(STATUS_HCMD_ACTIVE, &trans->shrd->status);
 			IWL_DEBUG_INFO(trans, "Clearing HCMD_ACTIVE for command"
 				 "%s\n", get_cmd_string(cmd->id));
-- 
1.7.0.4


^ permalink raw reply related

* [PATCH 07/34] iwlagn: update beacon smarter
From: Wey-Yi Guy @ 2011-10-10 14:26 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, Johannes Berg, Wey-Yi Guy
In-Reply-To: <1318256839-31837-1-git-send-email-wey-yi.w.guy@intel.com>

From: Johannes Berg <johannes.berg@intel.com>

Updating the beacon every time right after one was
transmitted is pointless, most of the time we might
not even have to update it. We will update it every
time it changes, which includes from set_tim(), a
callback iwlwifi didn't implement so far.

This also reduces latency for clients, previously
we would update the beacon right after the previous
one was transmitted, and then a TIM change would
only take effect after that again -- updating the
beacon right after the TIM changes makes the TIM
change go out to the air faster.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
---
 drivers/net/wireless/iwlwifi/iwl-agn.c |   11 +++++++++++
 drivers/net/wireless/iwlwifi/iwl-rx.c  |    2 --
 2 files changed, 11 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index d0fd6f0..74ac478 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -3074,6 +3074,16 @@ static void iwl_mac_rssi_callback(struct ieee80211_hw *hw,
 	mutex_unlock(&priv->shrd->mutex);
 }
 
+static int iwl_mac_set_tim(struct ieee80211_hw *hw,
+			   struct ieee80211_sta *sta, bool set)
+{
+	struct iwl_priv *priv = hw->priv;
+
+	queue_work(priv->shrd->workqueue, &priv->beacon_update);
+
+	return 0;
+}
+
 struct ieee80211_ops iwlagn_hw_ops = {
 	.tx = iwlagn_mac_tx,
 	.start = iwlagn_mac_start,
@@ -3107,6 +3117,7 @@ struct ieee80211_ops iwlagn_hw_ops = {
 	CFG80211_TESTMODE_DUMP(iwl_testmode_dump)
 	.tx_sync = iwl_mac_tx_sync,
 	.finish_tx_sync = iwl_mac_finish_tx_sync,
+	.set_tim = iwl_mac_set_tim,
 };
 
 static u32 iwl_hw_detect(struct iwl_priv *priv)
diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c
index bbd6740..1d781bc 100644
--- a/drivers/net/wireless/iwlwifi/iwl-rx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-rx.c
@@ -243,8 +243,6 @@ static int iwl_rx_beacon_notif(struct iwl_priv *priv,
 
 	priv->ibss_manager = le32_to_cpu(beacon->ibss_mgr_status);
 
-	if (!test_bit(STATUS_EXIT_PENDING, &priv->shrd->status))
-		queue_work(priv->shrd->workqueue, &priv->beacon_update);
 	return 0;
 }
 
-- 
1.7.0.4


^ permalink raw reply related

* [PATCH 06/34] iwlagn: add "echo test" command to debugfs
From: Wey-Yi Guy @ 2011-10-10 14:26 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, Wey-Yi Guy
In-Reply-To: <1318256839-31837-1-git-send-email-wey-yi.w.guy@intel.com>

For command queue testing, add "echo test" to debugfs

Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
---
 drivers/net/wireless/iwlwifi/iwl-core.c    |    8 +++++++-
 drivers/net/wireless/iwlwifi/iwl-debugfs.c |   19 +++++++++++++++++++
 drivers/net/wireless/iwlwifi/iwl-rx.c      |    1 +
 3 files changed, 27 insertions(+), 1 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index 9cb6c75..2cc6399 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -1734,12 +1734,18 @@ int iwl_mac_change_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
 
 int iwl_cmd_echo_test(struct iwl_priv *priv)
 {
+	int ret;
 	struct iwl_host_cmd cmd = {
 		.id = REPLY_ECHO,
 		.flags = CMD_SYNC,
 	};
 
-	return iwl_trans_send_cmd(trans(priv), &cmd);
+	ret = iwl_trans_send_cmd(trans(priv), &cmd);
+	if (ret)
+		IWL_ERR(priv, "echo testing fail: 0X%x\n", ret);
+	else
+		IWL_DEBUG_INFO(priv, "echo testing pass\n");
+	return ret;
 }
 
 static inline int iwl_check_stuck_queue(struct iwl_priv *priv, int txq)
diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
index 6d49dfb..ea1452c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
@@ -2444,6 +2444,23 @@ static ssize_t iwl_dbgfs_protection_mode_write(struct file *file,
 	return count;
 }
 
+static ssize_t iwl_dbgfs_echo_test_write(struct file *file,
+					const char __user *user_buf,
+					size_t count, loff_t *ppos)
+{
+	struct iwl_priv *priv = file->private_data;
+	char buf[8];
+	int buf_size;
+
+	memset(buf, 0, sizeof(buf));
+	buf_size = min(count, sizeof(buf) -  1);
+	if (copy_from_user(buf, user_buf, buf_size))
+		return -EFAULT;
+
+	iwl_cmd_echo_test(priv);
+	return count;
+}
+
 DEBUGFS_READ_FILE_OPS(rx_statistics);
 DEBUGFS_READ_FILE_OPS(tx_statistics);
 DEBUGFS_READ_WRITE_FILE_OPS(traffic_log);
@@ -2467,6 +2484,7 @@ DEBUGFS_WRITE_FILE_OPS(wd_timeout);
 DEBUGFS_READ_FILE_OPS(bt_traffic);
 DEBUGFS_READ_WRITE_FILE_OPS(protection_mode);
 DEBUGFS_READ_FILE_OPS(reply_tx_error);
+DEBUGFS_WRITE_FILE_OPS(echo_test);
 
 #ifdef CONFIG_IWLWIFI_DEBUG
 static ssize_t iwl_dbgfs_debug_level_read(struct file *file,
@@ -2575,6 +2593,7 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name)
 	DEBUGFS_ADD_FILE(rxon_flags, dir_debug, S_IWUSR);
 	DEBUGFS_ADD_FILE(rxon_filter_flags, dir_debug, S_IWUSR);
 	DEBUGFS_ADD_FILE(wd_timeout, dir_debug, S_IWUSR);
+	DEBUGFS_ADD_FILE(echo_test, dir_debug, S_IWUSR);
 	if (iwl_advanced_bt_coexist(priv))
 		DEBUGFS_ADD_FILE(bt_traffic, dir_debug, S_IRUSR);
 #ifdef CONFIG_IWLWIFI_DEBUG
diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c
index bcd7f64..bbd6740 100644
--- a/drivers/net/wireless/iwlwifi/iwl-rx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-rx.c
@@ -47,6 +47,7 @@ const char *get_cmd_string(u8 cmd)
 	switch (cmd) {
 		IWL_CMD(REPLY_ALIVE);
 		IWL_CMD(REPLY_ERROR);
+		IWL_CMD(REPLY_ECHO);
 		IWL_CMD(REPLY_RXON);
 		IWL_CMD(REPLY_RXON_ASSOC);
 		IWL_CMD(REPLY_QOS_PARAM);
-- 
1.7.0.4


^ permalink raw reply related

* [PATCH 09/34] iwlagn: send simple LQ command for WoWLAN
From: Wey-Yi Guy @ 2011-10-10 14:26 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, Johannes Berg, Wey-Yi Guy
In-Reply-To: <1318256839-31837-1-git-send-email-wey-yi.w.guy@intel.com>

From: Johannes Berg <johannes.berg@intel.com>

For some reason, WoWLAN doesn't always seem to
be happy with more advanced LQ commands. Since
we don't need them as we're not going to send
a lot of data, simply program the station with
the very simple default LQ command.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
---
 drivers/net/wireless/iwlwifi/iwl-agn-sta.c |   27 ++++++++++++++++++---------
 drivers/net/wireless/iwlwifi/iwl-sta.c     |    7 +++++--
 drivers/net/wireless/iwlwifi/iwl-sta.h     |    2 ++
 3 files changed, 25 insertions(+), 11 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-sta.c b/drivers/net/wireless/iwlwifi/iwl-agn-sta.c
index 8f0b86d..8e7177b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-sta.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-sta.c
@@ -35,22 +35,17 @@
 #include "iwl-agn.h"
 #include "iwl-trans.h"
 
-static struct iwl_link_quality_cmd *
-iwl_sta_alloc_lq(struct iwl_priv *priv, struct iwl_rxon_context *ctx, u8 sta_id)
+void iwl_sta_fill_lq(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
+		     u8 sta_id, struct iwl_link_quality_cmd *link_cmd)
 {
 	int i, r;
-	struct iwl_link_quality_cmd *link_cmd;
 	u32 rate_flags = 0;
 	__le32 rate_n_flags;
 
-	link_cmd = kzalloc(sizeof(struct iwl_link_quality_cmd), GFP_KERNEL);
-	if (!link_cmd) {
-		IWL_ERR(priv, "Unable to allocate memory for LQ cmd.\n");
-		return NULL;
-	}
-
 	lockdep_assert_held(&priv->shrd->mutex);
 
+	memset(link_cmd, 0, sizeof(*link_cmd));
+
 	/* Set up the rate scaling to start at selected rate, fall back
 	 * all the way down to 1M in IEEE order, and then spin on 1M */
 	if (priv->band == IEEE80211_BAND_5GHZ)
@@ -87,6 +82,20 @@ iwl_sta_alloc_lq(struct iwl_priv *priv, struct iwl_rxon_context *ctx, u8 sta_id)
 		cpu_to_le16(LINK_QUAL_AGG_TIME_LIMIT_DEF);
 
 	link_cmd->sta_id = sta_id;
+}
+
+static struct iwl_link_quality_cmd *
+iwl_sta_alloc_lq(struct iwl_priv *priv, struct iwl_rxon_context *ctx, u8 sta_id)
+{
+	struct iwl_link_quality_cmd *link_cmd;
+
+	link_cmd = kzalloc(sizeof(struct iwl_link_quality_cmd), GFP_KERNEL);
+	if (!link_cmd) {
+		IWL_ERR(priv, "Unable to allocate memory for LQ cmd.\n");
+		return NULL;
+	}
+
+	iwl_sta_fill_lq(priv, ctx, sta_id, link_cmd);
 
 	return link_cmd;
 }
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c
index 580a4d7..30bfdd3 100644
--- a/drivers/net/wireless/iwlwifi/iwl-sta.c
+++ b/drivers/net/wireless/iwlwifi/iwl-sta.c
@@ -595,8 +595,11 @@ void iwl_restore_stations(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
 			       sizeof(struct iwl_addsta_cmd));
 			send_lq = false;
 			if (priv->stations[i].lq) {
-				memcpy(&lq, priv->stations[i].lq,
-				       sizeof(struct iwl_link_quality_cmd));
+				if (priv->shrd->wowlan)
+					iwl_sta_fill_lq(priv, ctx, i, &lq);
+				else
+					memcpy(&lq, priv->stations[i].lq,
+					       sizeof(struct iwl_link_quality_cmd));
 				send_lq = true;
 			}
 			spin_unlock_irqrestore(&priv->shrd->sta_lock,
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.h b/drivers/net/wireless/iwlwifi/iwl-sta.h
index 1bca0da..b86c893 100644
--- a/drivers/net/wireless/iwlwifi/iwl-sta.h
+++ b/drivers/net/wireless/iwlwifi/iwl-sta.h
@@ -58,6 +58,8 @@ int iwl_mac_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
 u8 iwl_prep_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
 		    const u8 *addr, bool is_ap, struct ieee80211_sta *sta);
 
+void iwl_sta_fill_lq(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
+		     u8 sta_id, struct iwl_link_quality_cmd *link_cmd);
 int iwl_send_lq_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
 		    struct iwl_link_quality_cmd *lq, u8 flags, bool init);
 void iwl_reprogram_ap_sta(struct iwl_priv *priv, struct iwl_rxon_context *ctx);
-- 
1.7.0.4


^ permalink raw reply related

* [PATCH 08/34] iwlagn: don't assign seqno to QoS Null frames
From: Wey-Yi Guy @ 2011-10-10 14:26 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, Johannes Berg, Wey-Yi GUy
In-Reply-To: <1318256839-31837-1-git-send-email-wey-yi.w.guy@intel.com>

From: Johannes Berg <johannes.berg@intel.com>

802.11 says:
"Sequence numbers for QoS (+)Null frames may be
set to any value."

However, if we use the normal counters then peers
will get confused with aggregation since there'll
be holes in the sequence number sequence.

To avoid that, don't assign sequence numbers to
QoS Null frames.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Wey-Yi GUy <wey-yi.w.guy@intel.com>
---
 drivers/net/wireless/iwlwifi/iwl-trans-pcie.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c
index 416e992..60a8ecc 100644
--- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c
+++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c
@@ -1077,7 +1077,7 @@ static int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb,
 		txq_id =
 		    trans_pcie->ac_to_queue[ctx][skb_get_queue_mapping(skb)];
 
-	if (ieee80211_is_data_qos(fc)) {
+	if (ieee80211_is_data_qos(fc) && !ieee80211_is_qos_nullfunc(fc)) {
 		u8 *qc = NULL;
 		struct iwl_tid_data *tid_data;
 		qc = ieee80211_get_qos_ctl(hdr);
@@ -1206,7 +1206,7 @@ static int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb,
 	q->write_ptr = iwl_queue_inc_wrap(q->write_ptr, q->n_bd);
 	iwl_txq_update_write_ptr(trans, txq);
 
-	if (ieee80211_is_data_qos(fc)) {
+	if (ieee80211_is_data_qos(fc) && !ieee80211_is_qos_nullfunc(fc)) {
 		trans->shrd->tid_data[sta_id][tid].tfds_in_queue++;
 		if (!ieee80211_has_morefrags(fc))
 			trans->shrd->tid_data[sta_id][tid].seq_number =
-- 
1.7.0.4


^ permalink raw reply related

* [PATCH 11/34] iwlagn: eliminate bus pointer from iwl_priv structure
From: Wey-Yi Guy @ 2011-10-10 14:26 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, Don Fry, Wey-Yi Guy
In-Reply-To: <1318256839-31837-1-git-send-email-wey-yi.w.guy@intel.com>

From: Don Fry <donald.h.fry@intel.com>

A pointer to the bus structure is still in iwl_priv.  Finish
cleanup and remove it.

Signed-off-by: Don Fry <donald.h.fry@intel.com>
Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
---
 drivers/net/wireless/iwlwifi/iwl-agn.c     |   17 ++++++++---------
 drivers/net/wireless/iwlwifi/iwl-core.c    |    4 ++--
 drivers/net/wireless/iwlwifi/iwl-dev.h     |    3 ---
 drivers/net/wireless/iwlwifi/iwl-led.c     |    3 +--
 drivers/net/wireless/iwlwifi/iwl-power.c   |    2 +-
 drivers/net/wireless/iwlwifi/iwl-sv-open.c |    4 ++--
 6 files changed, 14 insertions(+), 19 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index 74ac478..90ca2d0 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -463,7 +463,7 @@ static void iwl_bg_tx_flush(struct work_struct *work)
 static void iwl_free_fw_desc(struct iwl_priv *priv, struct fw_desc *desc)
 {
 	if (desc->v_addr)
-		dma_free_coherent(priv->bus->dev, desc->len,
+		dma_free_coherent(bus(priv)->dev, desc->len,
 				  desc->v_addr, desc->p_addr);
 	desc->v_addr = NULL;
 	desc->len = 0;
@@ -490,7 +490,7 @@ static int iwl_alloc_fw_desc(struct iwl_priv *priv, struct fw_desc *desc,
 		return -EINVAL;
 	}
 
-	desc->v_addr = dma_alloc_coherent(priv->bus->dev, len,
+	desc->v_addr = dma_alloc_coherent(bus(priv)->dev, len,
 					  &desc->p_addr, GFP_KERNEL);
 	if (!desc->v_addr)
 		return -ENOMEM;
@@ -602,7 +602,7 @@ static int __must_check iwl_request_firmware(struct iwl_priv *priv, bool first)
 		       priv->firmware_name);
 
 	return request_firmware_nowait(THIS_MODULE, 1, priv->firmware_name,
-				       priv->bus->dev,
+				       bus(priv)->dev,
 				       GFP_KERNEL, priv, iwl_ucode_callback);
 }
 
@@ -1161,7 +1161,7 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
 	iwl_dealloc_ucode(priv);
  out_unbind:
 	complete(&priv->firmware_loading_complete);
-	device_release_driver(priv->bus->dev);
+	device_release_driver(bus(priv)->dev);
 	release_firmware(ucode_raw);
 }
 
@@ -1701,7 +1701,7 @@ static int iwl_mac_setup_register(struct iwl_priv *priv,
 			    WIPHY_FLAG_DISABLE_BEACON_HINTS |
 			    WIPHY_FLAG_IBSS_RSN;
 
-	if (priv->ucode_wowlan.code.len && device_can_wakeup(priv->bus->dev)) {
+	if (priv->ucode_wowlan.code.len && device_can_wakeup(bus(priv)->dev)) {
 		hw->wiphy->wowlan.flags = WIPHY_WOWLAN_MAGIC_PKT |
 					  WIPHY_WOWLAN_DISCONNECT |
 					  WIPHY_WOWLAN_EAP_IDENTITY_REQ |
@@ -2188,7 +2188,7 @@ static int iwlagn_mac_suspend(struct ieee80211_hw *hw,
 	if (ret)
 		goto error;
 
-	device_set_wakeup_enable(priv->bus->dev, true);
+	device_set_wakeup_enable(bus(priv)->dev, true);
 
 	/* Now let the ucode operate on its own */
 	iwl_write32(bus(priv), CSR_UCODE_DRV_GP1_SET,
@@ -2251,7 +2251,7 @@ static int iwlagn_mac_resume(struct ieee80211_hw *hw)
 
 	priv->shrd->wowlan = false;
 
-	device_set_wakeup_enable(priv->bus->dev, false);
+	device_set_wakeup_enable(bus(priv)->dev, false);
 
 	iwlagn_prepare_restart(priv);
 
@@ -3193,7 +3193,6 @@ int iwl_probe(struct iwl_bus *bus, const struct iwl_trans_ops *trans_ops,
 	}
 
 	priv = hw->priv;
-	priv->bus = bus;
 	priv->shrd = &priv->_shrd;
 	bus->shrd = priv->shrd;
 	priv->shrd->bus = bus;
@@ -3207,7 +3206,7 @@ int iwl_probe(struct iwl_bus *bus, const struct iwl_trans_ops *trans_ops,
 
 	/* At this point both hw and priv are allocated. */
 
-	SET_IEEE80211_DEV(hw, priv->bus->dev);
+	SET_IEEE80211_DEV(hw, bus(priv)->dev);
 
 	IWL_DEBUG_INFO(priv, "*** LOAD DRIVER ***\n");
 	priv->cfg = cfg;
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index 2cc6399..132fbfc 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -211,7 +211,7 @@ int iwl_init_geos(struct iwl_priv *priv)
 	if ((priv->bands[IEEE80211_BAND_5GHZ].n_channels == 0) &&
 	     priv->cfg->sku & EEPROM_SKU_CAP_BAND_52GHZ) {
 		char buf[32];
-		bus_get_hw_id(priv->bus, buf, sizeof(buf));
+		bus_get_hw_id(bus(priv), buf, sizeof(buf));
 		IWL_INFO(priv, "Incorrectly detected BG card as ABG. "
 			"Please send your %s to maintainer.\n", buf);
 		priv->cfg->sku &= ~EEPROM_SKU_CAP_BAND_52GHZ;
@@ -979,7 +979,7 @@ int iwl_apm_init(struct iwl_priv *priv)
 	iwl_set_bit(bus(priv), CSR_HW_IF_CONFIG_REG,
 				    CSR_HW_IF_CONFIG_REG_BIT_HAP_WAKE_L1A);
 
-	bus_apm_config(priv->bus);
+	bus_apm_config(bus(priv));
 
 	/* Configure analog phase-lock-loop before activating to D0A */
 	if (priv->cfg->base_params->pll_cfg_val)
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index 257aa9a..6c00a44 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -894,9 +894,6 @@ struct iwl_priv {
 	u8 scan_tx_ant[IEEE80211_NUM_BANDS];
 	u8 mgmt_tx_ant;
 
-	/*TODO: remove these pointers - use bus(priv) instead */
-	struct iwl_bus *bus;	/* bus specific data */
-
 	/* max number of station keys */
 	u8 sta_key_max_num;
 
diff --git a/drivers/net/wireless/iwlwifi/iwl-led.c b/drivers/net/wireless/iwlwifi/iwl-led.c
index f149165..eb54173 100644
--- a/drivers/net/wireless/iwlwifi/iwl-led.c
+++ b/drivers/net/wireless/iwlwifi/iwl-led.c
@@ -202,8 +202,7 @@ void iwl_leds_init(struct iwl_priv *priv)
 		break;
 	}
 
-	ret = led_classdev_register(priv->bus->dev,
-				    &priv->led);
+	ret = led_classdev_register(bus(priv)->dev, &priv->led);
 	if (ret) {
 		kfree(priv->led.name);
 		return;
diff --git a/drivers/net/wireless/iwlwifi/iwl-power.c b/drivers/net/wireless/iwlwifi/iwl-power.c
index 62cd781..4eaab20 100644
--- a/drivers/net/wireless/iwlwifi/iwl-power.c
+++ b/drivers/net/wireless/iwlwifi/iwl-power.c
@@ -436,7 +436,7 @@ int iwl_power_update_mode(struct iwl_priv *priv, bool force)
 /* initialize to default */
 void iwl_power_initialize(struct iwl_priv *priv)
 {
-	priv->power_data.bus_pm = bus_get_pm_support(priv->bus);
+	priv->power_data.bus_pm = bus_get_pm_support(bus(priv));
 
 	priv->power_data.debug_sleep_level_override = -1;
 
diff --git a/drivers/net/wireless/iwlwifi/iwl-sv-open.c b/drivers/net/wireless/iwlwifi/iwl-sv-open.c
index 3335d31..1d1622d 100644
--- a/drivers/net/wireless/iwlwifi/iwl-sv-open.c
+++ b/drivers/net/wireless/iwlwifi/iwl-sv-open.c
@@ -184,7 +184,7 @@ static void iwl_trace_cleanup(struct iwl_priv *priv)
 	if (priv->testmode_trace.trace_enabled) {
 		if (priv->testmode_trace.cpu_addr &&
 		    priv->testmode_trace.dma_addr)
-			dma_free_coherent(priv->bus->dev,
+			dma_free_coherent(bus(priv)->dev,
 					priv->testmode_trace.total_size,
 					priv->testmode_trace.cpu_addr,
 					priv->testmode_trace.dma_addr);
@@ -484,7 +484,7 @@ static int iwl_testmode_trace(struct ieee80211_hw *hw, struct nlattr **tb)
 	struct iwl_priv *priv = hw->priv;
 	struct sk_buff *skb;
 	int status = 0;
-	struct device *dev = priv->bus->dev;
+	struct device *dev = bus(priv)->dev;
 
 	switch (nla_get_u32(tb[IWL_TM_ATTR_COMMAND])) {
 	case IWL_TM_CMD_APP2DEV_BEGIN_TRACE:
-- 
1.7.0.4


^ permalink raw reply related

* [PATCH 12/34] iwlagn: stop interrupts when suspending
From: Wey-Yi Guy @ 2011-10-10 14:26 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, Johannes Berg, Wey-Yi Guy
In-Reply-To: <1318256839-31837-1-git-send-email-wey-yi.w.guy@intel.com>

From: Johannes Berg <johannes.berg@intel.com>

Occasionally, the device will send interrupts
while it is resuming, at a point where we are
not set up again to handle them. This causes
the core IRQ handling to completely disable
the IRQ, and then the driver won't work again
until it is reloaded/rebound.

To fix this issue disable the IRQ on suspend,
this will cause us to only get interrupts
again after we've setup everything on resume.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
---
 drivers/net/wireless/iwlwifi/iwl-trans-pcie.c |    7 ++++++-
 1 files changed, 6 insertions(+), 1 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c
index 60a8ecc..60067c7 100644
--- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c
+++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c
@@ -1377,8 +1377,13 @@ static int iwl_trans_pcie_suspend(struct iwl_trans *trans)
 	 * But of course ... if we have configured WoWLAN then we did other
 	 * things already :-)
 	 */
-	if (!trans->shrd->wowlan)
+	if (!trans->shrd->wowlan) {
 		iwl_apm_stop(priv(trans));
+	} else {
+		iwl_disable_interrupts(trans);
+		iwl_clear_bit(bus(trans), CSR_GP_CNTRL,
+			      CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
+	}
 
 	return 0;
 }
-- 
1.7.0.4


^ permalink raw reply related

* [PATCH 10/34] iwlagn: kill hw_params.max_stations
From: Wey-Yi Guy @ 2011-10-10 14:26 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, Emmanuel Grumbach, Wey-Yi Guy
In-Reply-To: <1318256839-31837-1-git-send-email-wey-yi.w.guy@intel.com>

From: Emmanuel Grumbach <emmanuel.grumbach@intel.com>

Not needed since driver split.

Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
---
 drivers/net/wireless/iwlwifi/iwl-1000.c    |    1 -
 drivers/net/wireless/iwlwifi/iwl-2000.c    |    1 -
 drivers/net/wireless/iwlwifi/iwl-5000.c    |    2 --
 drivers/net/wireless/iwlwifi/iwl-6000.c    |    1 -
 drivers/net/wireless/iwlwifi/iwl-debugfs.c |    3 +--
 drivers/net/wireless/iwlwifi/iwl-shared.h  |    2 --
 drivers/net/wireless/iwlwifi/iwl-sta.c     |   11 +++++------
 7 files changed, 6 insertions(+), 15 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c
index 887f9ac..dfd81de 100644
--- a/drivers/net/wireless/iwlwifi/iwl-1000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-1000.c
@@ -130,7 +130,6 @@ static int iwl1000_hw_set_hw_params(struct iwl_priv *priv)
 			iwlagn_mod_params.num_of_queues;
 
 	hw_params(priv).max_txq_num = priv->cfg->base_params->num_of_queues;
-	hw_params(priv).max_stations = IWLAGN_STATION_COUNT;
 	priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id = IWLAGN_BROADCAST_ID;
 
 	hw_params(priv).max_data_size = IWLAGN_RTC_DATA_SIZE;
diff --git a/drivers/net/wireless/iwlwifi/iwl-2000.c b/drivers/net/wireless/iwlwifi/iwl-2000.c
index db88958..09a6b8e 100644
--- a/drivers/net/wireless/iwlwifi/iwl-2000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-2000.c
@@ -127,7 +127,6 @@ static int iwl2000_hw_set_hw_params(struct iwl_priv *priv)
 			iwlagn_mod_params.num_of_queues;
 
 	hw_params(priv).max_txq_num = priv->cfg->base_params->num_of_queues;
-	hw_params(priv).max_stations = IWLAGN_STATION_COUNT;
 	priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id = IWLAGN_BROADCAST_ID;
 
 	hw_params(priv).max_data_size = IWL60_RTC_DATA_SIZE;
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c
index 2907016..14b4c5a 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-5000.c
@@ -158,7 +158,6 @@ static int iwl5000_hw_set_hw_params(struct iwl_priv *priv)
 			iwlagn_mod_params.num_of_queues;
 
 	hw_params(priv).max_txq_num = priv->cfg->base_params->num_of_queues;
-	hw_params(priv).max_stations = IWLAGN_STATION_COUNT;
 	priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id = IWLAGN_BROADCAST_ID;
 
 	hw_params(priv).max_data_size = IWLAGN_RTC_DATA_SIZE;
@@ -195,7 +194,6 @@ static int iwl5150_hw_set_hw_params(struct iwl_priv *priv)
 			iwlagn_mod_params.num_of_queues;
 
 	hw_params(priv).max_txq_num = priv->cfg->base_params->num_of_queues;
-	hw_params(priv).max_stations = IWLAGN_STATION_COUNT;
 	priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id = IWLAGN_BROADCAST_ID;
 
 	hw_params(priv).max_data_size = IWLAGN_RTC_DATA_SIZE;
diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c
index 37837f7..d81c87d 100644
--- a/drivers/net/wireless/iwlwifi/iwl-6000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-6000.c
@@ -147,7 +147,6 @@ static int iwl6000_hw_set_hw_params(struct iwl_priv *priv)
 			iwlagn_mod_params.num_of_queues;
 
 	hw_params(priv).max_txq_num = priv->cfg->base_params->num_of_queues;
-	hw_params(priv).max_stations = IWLAGN_STATION_COUNT;
 	priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id = IWLAGN_BROADCAST_ID;
 
 	hw_params(priv).max_data_size = IWL60_RTC_DATA_SIZE;
diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
index ea1452c..a1670e3 100644
--- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
@@ -349,7 +349,6 @@ static ssize_t iwl_dbgfs_stations_read(struct file *file, char __user *user_buf,
 	struct iwl_priv *priv = file->private_data;
 	struct iwl_station_entry *station;
 	struct iwl_tid_data *tid_data;
-	int max_sta = hw_params(priv).max_stations;
 	char *buf;
 	int i, j, pos = 0;
 	ssize_t ret;
@@ -363,7 +362,7 @@ static ssize_t iwl_dbgfs_stations_read(struct file *file, char __user *user_buf,
 	pos += scnprintf(buf + pos, bufsz - pos, "num of stations: %d\n\n",
 			priv->num_stations);
 
-	for (i = 0; i < max_sta; i++) {
+	for (i = 0; i < IWLAGN_STATION_COUNT; i++) {
 		station = &priv->stations[i];
 		if (!station->used)
 			continue;
diff --git a/drivers/net/wireless/iwlwifi/iwl-shared.h b/drivers/net/wireless/iwlwifi/iwl-shared.h
index 3a24b47..1f7a93c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-shared.h
+++ b/drivers/net/wireless/iwlwifi/iwl-shared.h
@@ -165,7 +165,6 @@ struct iwl_mod_params {
  * @rx_chains_num: Number of RX chains
  * @valid_tx_ant: usable antennas for TX
  * @valid_rx_ant: usable antennas for RX
- * @max_stations: the maximal number of stations
  * @ht40_channel: is 40MHz width possible: BIT(IEEE80211_BAND_XXX)
  * @sku: sku read from EEPROM
  * @rx_page_order: Rx buffer page order
@@ -186,7 +185,6 @@ struct iwl_hw_params {
 	u8  rx_chains_num;
 	u8  valid_tx_ant;
 	u8  valid_rx_ant;
-	u8  max_stations;
 	u8  ht40_channel;
 	bool shadow_reg_enable;
 	u16 sku;
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c
index 30bfdd3..23a9364 100644
--- a/drivers/net/wireless/iwlwifi/iwl-sta.c
+++ b/drivers/net/wireless/iwlwifi/iwl-sta.c
@@ -248,8 +248,7 @@ u8 iwl_prep_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
 	else if (is_broadcast_ether_addr(addr))
 		sta_id = ctx->bcast_sta_id;
 	else
-		for (i = IWL_STA_ID;
-		     i < hw_params(priv).max_stations; i++) {
+		for (i = IWL_STA_ID; i < IWLAGN_STATION_COUNT; i++) {
 			if (!compare_ether_addr(priv->stations[i].sta.sta.addr,
 						addr)) {
 				sta_id = i;
@@ -535,7 +534,7 @@ void iwl_clear_ucode_stations(struct iwl_priv *priv,
 	IWL_DEBUG_INFO(priv, "Clearing ucode stations in driver\n");
 
 	spin_lock_irqsave(&priv->shrd->sta_lock, flags_spin);
-	for (i = 0; i < hw_params(priv).max_stations; i++) {
+	for (i = 0; i < IWLAGN_STATION_COUNT; i++) {
 		if (ctx && ctx->ctxid != priv->stations[i].ctxid)
 			continue;
 
@@ -576,7 +575,7 @@ void iwl_restore_stations(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
 
 	IWL_DEBUG_ASSOC(priv, "Restoring all known stations ... start.\n");
 	spin_lock_irqsave(&priv->shrd->sta_lock, flags_spin);
-	for (i = 0; i < hw_params(priv).max_stations; i++) {
+	for (i = 0; i < IWLAGN_STATION_COUNT; i++) {
 		if (ctx->ctxid != priv->stations[i].ctxid)
 			continue;
 		if ((priv->stations[i].used & IWL_STA_DRIVER_ACTIVE) &&
@@ -589,7 +588,7 @@ void iwl_restore_stations(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
 		}
 	}
 
-	for (i = 0; i < hw_params(priv).max_stations; i++) {
+	for (i = 0; i < IWLAGN_STATION_COUNT; i++) {
 		if ((priv->stations[i].used & IWL_STA_UCODE_INPROGRESS)) {
 			memcpy(&sta_cmd, &priv->stations[i].sta,
 			       sizeof(struct iwl_addsta_cmd));
@@ -692,7 +691,7 @@ void iwl_dealloc_bcast_stations(struct iwl_priv *priv)
 	int i;
 
 	spin_lock_irqsave(&priv->shrd->sta_lock, flags);
-	for (i = 0; i < hw_params(priv).max_stations; i++) {
+	for (i = 0; i < IWLAGN_STATION_COUNT; i++) {
 		if (!(priv->stations[i].used & IWL_STA_BCAST))
 			continue;
 
-- 
1.7.0.4


^ permalink raw reply related

* [PATCH 13/34] iwlagn: remove un-necessary step
From: Wey-Yi Guy @ 2011-10-10 14:26 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, Wey-Yi Guy
In-Reply-To: <1318256839-31837-1-git-send-email-wey-yi.w.guy@intel.com>

No need to copy twice.

Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
---
 drivers/net/wireless/iwlwifi/iwl-agn-rs.c |    3 +--
 1 files changed, 1 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
index 7d6a3bf..353af8f 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
@@ -2666,8 +2666,7 @@ lq_update:
 
 out:
 	tbl->current_rate = rate_n_flags_from_tbl(priv, tbl, index, is_green);
-	i = index;
-	lq_sta->last_txrate_idx = i;
+	lq_sta->last_txrate_idx = index;
 }
 
 /**
-- 
1.7.0.4


^ permalink raw reply related


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