Linux wireless drivers development
 help / color / mirror / Atom feed
* [PATCH v2] ath10k: fix device teardown
From: Michal Kazior @ 2013-08-02  7:15 UTC (permalink / raw)
  To: ath10k; +Cc: linux-wireless, Michal Kazior
In-Reply-To: <1374129572-6079-1-git-send-email-michal.kazior@tieto.com>

This fixes interrupt-related issue when no
interfaces were running thus the device was
considered powered down.

The power_down() function isn't really powering
down the device. It simply assumed it won't
interrupt. This wasn't true in some cases and
could lead to paging failures upon FW indication
interrupt (i.e. FW crash) because some structures
aren't allocated in that device state.

One reason for that was that ar_pci->started
wasn't reset. The other is interrupts should've
been masked when teardown starts.

The patch reorganized interrupt setup and makes
sure ar_pci->started is reset accordingly.

Reported-by: Ben Greear <greearb@candelatech.com>
Signed-off-by: Michal Kazior <michal.kazior@tieto.com>
---
v2:
 * updated commit message
 * added Reported-By: Ben
 * added disable_irq() in hif_stop()
 * added ar_pci->started resetting
 * removed ar_pci->intr_started

 drivers/net/wireless/ath/ath10k/pci.c |   41 ++++++++++++++++++++++++---------
 1 file changed, 30 insertions(+), 11 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/pci.c b/drivers/net/wireless/ath/ath10k/pci.c
index c71b488..690a8b4 100644
--- a/drivers/net/wireless/ath/ath10k/pci.c
+++ b/drivers/net/wireless/ath/ath10k/pci.c
@@ -56,6 +56,8 @@ static void ath10k_pci_rx_pipe_cleanup(struct hif_ce_pipe_info *pipe_info);
 static void ath10k_pci_stop_ce(struct ath10k *ar);
 static void ath10k_pci_device_reset(struct ath10k *ar);
 static int ath10k_pci_reset_target(struct ath10k *ar);
+static int ath10k_pci_start_intr(struct ath10k *ar);
+static void ath10k_pci_stop_intr(struct ath10k *ar);
 
 static const struct ce_attr host_ce_config_wlan[] = {
 	/* host->target HTC control and raw streams */
@@ -1254,10 +1256,25 @@ static void ath10k_pci_ce_deinit(struct ath10k *ar)
 	}
 }
 
+static void ath10k_pci_disable_irqs(struct ath10k *ar)
+{
+	struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
+	int i;
+
+	for (i = 0; i < max(1, ar_pci->num_msi_intrs); i++)
+		disable_irq(ar_pci->pdev->irq + i);
+}
+
 static void ath10k_pci_hif_stop(struct ath10k *ar)
 {
+	struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
+
 	ath10k_dbg(ATH10K_DBG_PCI, "%s\n", __func__);
 
+	/* Irqs are never explicitly re-enabled. They are implicitly re-enabled
+	 * by ath10k_pci_start_intr(). */
+	ath10k_pci_disable_irqs(ar);
+
 	ath10k_pci_stop_ce(ar);
 
 	/* At this point, asynchronous threads are stopped, the target should
@@ -1267,6 +1284,8 @@ static void ath10k_pci_hif_stop(struct ath10k *ar)
 	ath10k_pci_process_ce(ar);
 	ath10k_pci_cleanup_ce(ar);
 	ath10k_pci_buffer_cleanup(ar);
+
+	ar_pci->started = 0;
 }
 
 static int ath10k_pci_hif_exchange_bmi_msg(struct ath10k *ar,
@@ -1742,6 +1761,12 @@ static int ath10k_pci_hif_power_up(struct ath10k *ar)
 {
 	int ret;
 
+	ret = ath10k_pci_start_intr(ar);
+	if (ret) {
+		ath10k_err("could not start interrupt handling (%d)\n", ret);
+		goto err;
+	}
+
 	/*
 	 * Bring the target up cleanly.
 	 *
@@ -1756,7 +1781,7 @@ static int ath10k_pci_hif_power_up(struct ath10k *ar)
 
 	ret = ath10k_pci_reset_target(ar);
 	if (ret)
-		goto err;
+		goto err_irq;
 
 	if (ath10k_target_ps) {
 		ath10k_dbg(ATH10K_DBG_PCI, "on-chip power save enabled\n");
@@ -1787,12 +1812,15 @@ err_ce:
 err_ps:
 	if (!ath10k_target_ps)
 		ath10k_do_pci_sleep(ar);
+err_irq:
+	ath10k_pci_stop_intr(ar);
 err:
 	return ret;
 }
 
 static void ath10k_pci_hif_power_down(struct ath10k *ar)
 {
+	ath10k_pci_stop_intr(ar);
 	ath10k_pci_ce_deinit(ar);
 	if (!ath10k_target_ps)
 		ath10k_do_pci_sleep(ar);
@@ -2358,22 +2386,14 @@ static int ath10k_pci_probe(struct pci_dev *pdev,
 
 	ar_pci->cacheline_sz = dma_get_cache_alignment();
 
-	ret = ath10k_pci_start_intr(ar);
-	if (ret) {
-		ath10k_err("could not start interrupt handling (%d)\n", ret);
-		goto err_iomap;
-	}
-
 	ret = ath10k_core_register(ar);
 	if (ret) {
 		ath10k_err("could not register driver core (%d)\n", ret);
-		goto err_intr;
+		goto err_iomap;
 	}
 
 	return 0;
 
-err_intr:
-	ath10k_pci_stop_intr(ar);
 err_iomap:
 	pci_iounmap(pdev, mem);
 err_master:
@@ -2410,7 +2430,6 @@ static void ath10k_pci_remove(struct pci_dev *pdev)
 	tasklet_kill(&ar_pci->msi_fw_err);
 
 	ath10k_core_unregister(ar);
-	ath10k_pci_stop_intr(ar);
 
 	pci_set_drvdata(pdev, NULL);
 	pci_iounmap(pdev, ar_pci->mem);
-- 
1.7.9.5


^ permalink raw reply related

* Re: [PATCH 0/5] ath10k: fixes
From: Kalle Valo @ 2013-08-02  6:38 UTC (permalink / raw)
  To: Michal Kazior; +Cc: ath10k, linux-wireless
In-Reply-To: <1375260915-22500-1-git-send-email-michal.kazior@tieto.com>

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

> Hi,
>
> This is a batch up of a few fixes for ath10k
> driver I had in my queue for some time now.
>
>
> Michal Kazior (5):
>   ath10k: prevent using invalid ringbuffer indexes
>   ath10k: make sure to use passive scan when n_ssids is 0
>   ath10k: advertise more conservative intf combinations
>   ath10k: zero arvif memory on add_interface()
>   ath10k: fix failpath in MSI-X setup

All applied, thanks.

-- 
Kalle Valo

^ permalink raw reply

* Re: [PATCH v3] ath10k: implement get_survey()
From: Kalle Valo @ 2013-08-02  6:35 UTC (permalink / raw)
  To: Michal Kazior; +Cc: ath10k, linux-wireless
In-Reply-To: <1375259560-8784-1-git-send-email-michal.kazior@tieto.com>

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

> This implements a limited subset of what can be
> reported in the survey dump.
>
> This can be used for assessing approximate channel
> load, e.g. for automatic channel selection.
>
> Signed-off-by: Michal Kazior <michal.kazior@tieto.com>

Thanks, applied.

-- 
Kalle Valo

^ permalink raw reply

* Re: [PATCH 0/2] ath10k: implement checksum offloading
From: Kalle Valo @ 2013-08-02  6:31 UTC (permalink / raw)
  To: Michal Kazior; +Cc: ath10k, linux-wireless
In-Reply-To: <1375260477-17030-1-git-send-email-michal.kazior@tieto.com>

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

> Hi,
>
> This patchset adds tx and rx checksum offloading
> to ath10k driver.
>
> I don't have any hard numbers but I did observe a
> consistently sligthly better performance on AP135
> + ath10k. Nothing ground breaking though.
>
>
> Michal Kazior (2):
>   ath10k: implement rx checksum offloading
>   ath10k: implement tx checksum offloading

Applied, thanks.

-- 
Kalle Valo

^ permalink raw reply

* Re: [PATCH] mac80211: allow lowest basic rate for unicast management frame in mesh
From: Yeoh Chun-Yeow @ 2013-08-02  5:14 UTC (permalink / raw)
  To: devel@lists.open80211s.org
  Cc: Chun-Yeow Yeoh, linux-wireless@vger.kernel.org, John Linville
In-Reply-To: <1375343068.8608.11.camel@jlt4.sipsolutions.net>

> That doesn't seem like a good idea - IMHO you shouldn't use container_of
> on NULL even if it still works in the end.
>
> Also it might be a good idea to use more regular names: struct
> ieee80211_sta *pubsta, struct sta_info *sta.

Ok.

> I don't get this - that just duplicates the code above, no chance to
> refactor it a bit instead of duplicating the call?

I will take a look on this first.

---
Chun-Yeow

^ permalink raw reply

* [3.11 regression?] iwlwifi firmware takes two minutes to load
From: Andy Lutomirski @ 2013-08-02  4:38 UTC (permalink / raw)
  To: Linux Wireless List, Intel Linux Wireless

At boot, I get:
[   12.537108] iwlwifi 0000:03:00.0: irq 51 for MSI/MSI-X
...
[  132.676781] iwlwifi 0000:03:00.0: loaded firmware version 9.221.4.1
build 25532 op_mode iwldvm

This sounds familiar, but wasn't it fixed awhile ago?

--Andy

^ permalink raw reply

* Register Information required Intel4965AGN
From: Abdur Rehman @ 2013-08-01 22:21 UTC (permalink / raw)
  To: linux-wireless, ilw

Hi,
Can you provide the hardware register descriptions for Intel4965AGN.

Regards
AbdurRehman
Embedded Systems Developer
Whizz Systems, CA

^ permalink raw reply

* RE: [PATCH] ieee80211: add definition for interworking support
From: Bing Zhao @ 2013-08-01 21:09 UTC (permalink / raw)
  To: Johannes Berg; +Cc: linux-wireless@vger.kernel.org, Avinash Patil
In-Reply-To: <1375342361.8608.2.camel@jlt4.sipsolutions.net>

SGkgSm9oYW5uZXMsDQoNCj4gPiBGcm9tOiBBdmluYXNoIFBhdGlsIDxwYXRpbGFAbWFydmVsbC5j
b20+DQo+ID4NCj4gPiBJRUVFODAyLjExdSBpbnRlcndvcmtpbmcgc3VwcG9ydCBpcyBhZHZlcnRp
c2VkIHZpYSBleHRlbmRlZA0KPiA+IGNhcGFiaWxpdGllcyBJRSBiaXQgMzEuIFRoaXMgaXMgN3Ro
IGJpdCBvZiA0dGggYnl0ZSBvZiBleHRlbmRlZA0KPiA+IGNhcGFiaWxpdGllcy4NCj4gDQo+IEkn
dmUgYXBwbGllZCB0aGlzLCBidXQgd2h5IGlzIHRoaXMgbmVlZGVkIGluIHRoZSBrZXJuZWw/IElz
bid0IHRoZQ0KPiBzdXBwbGljYW50IG1hbmFnaW5nIHRoZSBpbnRlcndvcmtpbmcgc3R1ZmY/DQoN
CldlIGhhdmUgYSBtd2lmaWV4IHBhdGNoIGRlcGVuZHMgb24gaXQuIFBhcnQgb2YgdGhlIHBhdGNo
IGxvb2tzIHRoaXM6DQoNCisgICAgICAgICAgICAgICBpZiAoaGRyLT5sZW4gPiAzICYmDQorICAg
ICAgICAgICAgICAgICAgIGV4dF9jYXAtPmV4dF9jYXBhYlszXSAmIFdMQU5fRVhUX0NBUEE0X0lO
VEVSV09SS0lOR19FTkFCTEVEKQ0KKyAgICAgICAgICAgICAgICAgICAgICAgcHJpdi0+aHMyX2Vu
YWJsZWQgPSAxOw0KKyAgICAgICAgICAgICAgIGVsc2UNCisgICAgICAgICAgICAgICAgICAgICAg
IHByaXYtPmhzMl9lbmFibGVkID0gMDsNCg0KSWYgdGhpcyBiaXQgaXMgZW5hYmxlZCB3ZSB3aWxs
IGRyb3AgdGhlIEdBUlAgZnJhbWVzIHJlY2VpdmVkLiBUaGlzIGlzIHJlcXVpcmVkIGZvciBXRkEg
SG90c3BvdDIuMC4NCg0KVGhhbmtzLA0KQmluZw0KDQo=

^ permalink raw reply

* Re: [PATCH v2 8/8] ath9k: Add statistics for antenna diversity
From: John W. Linville @ 2013-08-01 19:53 UTC (permalink / raw)
  To: Sujith Manoharan; +Cc: linux-wireless
In-Reply-To: <20130801194418.GE13922@tuxdriver.com>

Nevermind -- I had a patch that I was applying out of order...

On Thu, Aug 01, 2013 at 03:44:18PM -0400, John W. Linville wrote:
> I can't get this one to apply.  Please check the latest tree and fix
> it up?
> 
> Thanks,
> 
> John
> 
> On Thu, Aug 01, 2013 at 08:57:06PM +0530, Sujith Manoharan wrote:
> > From: Sujith Manoharan <c_manoha@qca.qualcomm.com>
> > 
> > Signed-off-by: Sujith Manoharan <c_manoha@qca.qualcomm.com>
> > ---
> >  drivers/net/wireless/ath/ath9k/antenna.c | 18 ++++---
> >  drivers/net/wireless/ath/ath9k/debug.c   | 85 ++++++++++++++++++++++++++------
> >  drivers/net/wireless/ath/ath9k/debug.h   | 20 +++++---
> >  3 files changed, 95 insertions(+), 28 deletions(-)
> > 
> > diff --git a/drivers/net/wireless/ath/ath9k/antenna.c b/drivers/net/wireless/ath/ath9k/antenna.c
> > index 42f3b87..391d557 100644
> > --- a/drivers/net/wireless/ath/ath9k/antenna.c
> > +++ b/drivers/net/wireless/ath/ath9k/antenna.c
> > @@ -734,15 +734,18 @@ void ath_ant_comb_scan(struct ath_softc *sc, struct ath_rx_status *rs)
> >  		antcomb->main_total_rssi += main_rssi;
> >  		antcomb->alt_total_rssi  += alt_rssi;
> >  
> > -		if (main_ant_conf == rx_ant_conf) {
> > +		if (main_ant_conf == rx_ant_conf)
> >  			antcomb->main_recv_cnt++;
> > -			ANT_STAT_INC(ANT_MAIN, recv_cnt);
> > -			ANT_LNA_INC(ANT_MAIN, rx_ant_conf);
> > -		} else {
> > +		else
> >  			antcomb->alt_recv_cnt++;
> > -			ANT_STAT_INC(ANT_ALT, recv_cnt);
> > -			ANT_LNA_INC(ANT_ALT, rx_ant_conf);
> > -		}
> > +	}
> > +
> > +	if (main_ant_conf == rx_ant_conf) {
> > +		ANT_STAT_INC(ANT_MAIN, recv_cnt);
> > +		ANT_LNA_INC(ANT_MAIN, rx_ant_conf);
> > +	} else {
> > +		ANT_STAT_INC(ANT_ALT, recv_cnt);
> > +		ANT_LNA_INC(ANT_ALT, rx_ant_conf);
> >  	}
> >  
> >  	/* Short scan check */
> > @@ -821,6 +824,7 @@ void ath_ant_comb_scan(struct ath_softc *sc, struct ath_rx_status *rs)
> >  div_comb_done:
> >  	ath_ant_div_conf_fast_divbias(&div_ant_conf, antcomb, alt_ratio);
> >  	ath9k_hw_antdiv_comb_conf_set(sc->sc_ah, &div_ant_conf);
> > +	ath9k_debug_stat_ant(sc, &div_ant_conf, main_rssi_avg, alt_rssi_avg);
> >  
> >  	antcomb->scan_start_time = jiffies;
> >  	antcomb->total_pkt_count = 0;
> > diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c
> > index 56cbe5d..a43bd8c 100644
> > --- a/drivers/net/wireless/ath/ath9k/debug.c
> > +++ b/drivers/net/wireless/ath/ath9k/debug.c
> > @@ -321,6 +321,20 @@ static const struct file_operations fops_bt_ant_diversity = {
> >  	.llseek = default_llseek,
> >  };
> >  
> > +void ath9k_debug_stat_ant(struct ath_softc *sc,
> > +			  struct ath_hw_antcomb_conf *div_ant_conf,
> > +			  int main_rssi_avg, int alt_rssi_avg)
> > +{
> > +	struct ath_antenna_stats *as_main = &sc->debug.stats.ant_stats[ANT_MAIN];
> > +	struct ath_antenna_stats *as_alt = &sc->debug.stats.ant_stats[ANT_ALT];
> > +
> > +	as_main->lna_attempt_cnt[div_ant_conf->main_lna_conf]++;
> > +	as_alt->lna_attempt_cnt[div_ant_conf->alt_lna_conf]++;
> > +
> > +	as_main->rssi_avg = main_rssi_avg;
> > +	as_alt->rssi_avg = alt_rssi_avg;
> > +}
> > +
> >  static ssize_t read_file_antenna_diversity(struct file *file,
> >  					   char __user *user_buf,
> >  					   size_t count, loff_t *ppos)
> > @@ -330,9 +344,14 @@ static ssize_t read_file_antenna_diversity(struct file *file,
> >  	struct ath9k_hw_capabilities *pCap = &ah->caps;
> >  	struct ath_antenna_stats *as_main = &sc->debug.stats.ant_stats[ANT_MAIN];
> >  	struct ath_antenna_stats *as_alt = &sc->debug.stats.ant_stats[ANT_ALT];
> > +	struct ath_hw_antcomb_conf div_ant_conf;
> >  	unsigned int len = 0, size = 1024;
> >  	ssize_t retval = 0;
> >  	char *buf;
> > +	char *lna_conf_str[4] = {"LNA1_MINUS_LNA2",
> > +				 "LNA2",
> > +				 "LNA1",
> > +				 "LNA1_PLUS_LNA2"};
> >  
> >  	buf = kzalloc(size, GFP_KERNEL);
> >  	if (buf == NULL)
> > @@ -344,28 +363,66 @@ static ssize_t read_file_antenna_diversity(struct file *file,
> >  		goto exit;
> >  	}
> >  
> > +	ath9k_ps_wakeup(sc);
> > +	ath9k_hw_antdiv_comb_conf_get(ah, &div_ant_conf);
> > +	len += snprintf(buf + len, size - len, "Current MAIN config : %s\n",
> > +			lna_conf_str[div_ant_conf.main_lna_conf]);
> > +	len += snprintf(buf + len, size - len, "Current ALT config  : %s\n",
> > +			lna_conf_str[div_ant_conf.alt_lna_conf]);
> > +	len += snprintf(buf + len, size - len, "Average MAIN RSSI   : %d\n",
> > +			as_main->rssi_avg);
> > +	len += snprintf(buf + len, size - len, "Average ALT RSSI    : %d\n\n",
> > +			as_alt->rssi_avg);
> > +	ath9k_ps_restore(sc);
> > +
> > +	len += snprintf(buf + len, size - len, "Packet Receive Cnt:\n");
> > +	len += snprintf(buf + len, size - len, "-------------------\n");
> > +
> >  	len += snprintf(buf + len, size - len, "%30s%15s\n",
> >  			"MAIN", "ALT");
> > -	len += snprintf(buf + len, size - len, "%-15s%15d%15d\n",
> > -			"RECV CNT",
> > +	len += snprintf(buf + len, size - len, "%-14s:%15d%15d\n",
> > +			"TOTAL COUNT",
> >  			as_main->recv_cnt,
> >  			as_alt->recv_cnt);
> > -	len += snprintf(buf + len, size - len, "%-15s%15d%15d\n",
> > +	len += snprintf(buf + len, size - len, "%-14s:%15d%15d\n",
> > +			"LNA1",
> > +			as_main->lna_recv_cnt[ATH_ANT_DIV_COMB_LNA1],
> > +			as_alt->lna_recv_cnt[ATH_ANT_DIV_COMB_LNA1]);
> > +	len += snprintf(buf + len, size - len, "%-14s:%15d%15d\n",
> > +			"LNA2",
> > +			as_main->lna_recv_cnt[ATH_ANT_DIV_COMB_LNA2],
> > +			as_alt->lna_recv_cnt[ATH_ANT_DIV_COMB_LNA2]);
> > +	len += snprintf(buf + len, size - len, "%-14s:%15d%15d\n",
> > +			"LNA1 + LNA2",
> > +			as_main->lna_recv_cnt[ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2],
> > +			as_alt->lna_recv_cnt[ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2]);
> > +	len += snprintf(buf + len, size - len, "%-14s:%15d%15d\n",
> > +			"LNA1 - LNA2",
> > +			as_main->lna_recv_cnt[ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2],
> > +			as_alt->lna_recv_cnt[ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2]);
> > +
> > +	len += snprintf(buf + len, size - len, "\nLNA Config Attempts:\n");
> > +	len += snprintf(buf + len, size - len, "--------------------\n");
> > +
> > +	len += snprintf(buf + len, size - len, "%30s%15s\n",
> > +			"MAIN", "ALT");
> > +	len += snprintf(buf + len, size - len, "%-14s:%15d%15d\n",
> >  			"LNA1",
> > -			as_main->lna_config_cnt[ATH_ANT_DIV_COMB_LNA1],
> > -			as_alt->lna_config_cnt[ATH_ANT_DIV_COMB_LNA1]);
> > -	len += snprintf(buf + len, size - len, "%-15s%15d%15d\n",
> > +			as_main->lna_attempt_cnt[ATH_ANT_DIV_COMB_LNA1],
> > +			as_alt->lna_attempt_cnt[ATH_ANT_DIV_COMB_LNA1]);
> > +	len += snprintf(buf + len, size - len, "%-14s:%15d%15d\n",
> >  			"LNA2",
> > -			as_main->lna_config_cnt[ATH_ANT_DIV_COMB_LNA2],
> > -			as_alt->lna_config_cnt[ATH_ANT_DIV_COMB_LNA2]);
> > -	len += snprintf(buf + len, size - len, "%-15s%15d%15d\n",
> > +			as_main->lna_attempt_cnt[ATH_ANT_DIV_COMB_LNA2],
> > +			as_alt->lna_attempt_cnt[ATH_ANT_DIV_COMB_LNA2]);
> > +	len += snprintf(buf + len, size - len, "%-14s:%15d%15d\n",
> >  			"LNA1 + LNA2",
> > -			as_main->lna_config_cnt[ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2],
> > -			as_alt->lna_config_cnt[ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2]);
> > -	len += snprintf(buf + len, size - len, "%-15s%15d%15d\n",
> > +			as_main->lna_attempt_cnt[ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2],
> > +			as_alt->lna_attempt_cnt[ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2]);
> > +	len += snprintf(buf + len, size - len, "%-14s:%15d%15d\n",
> >  			"LNA1 - LNA2",
> > -			as_main->lna_config_cnt[ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2],
> > -			as_alt->lna_config_cnt[ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2]);
> > +			as_main->lna_attempt_cnt[ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2],
> > +			as_alt->lna_attempt_cnt[ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2]);
> > +
> >  exit:
> >  	if (len > size)
> >  		len = size;
> > diff --git a/drivers/net/wireless/ath/ath9k/debug.h b/drivers/net/wireless/ath/ath9k/debug.h
> > index a879e45..01c5c6a 100644
> > --- a/drivers/net/wireless/ath/ath9k/debug.h
> > +++ b/drivers/net/wireless/ath/ath9k/debug.h
> > @@ -29,7 +29,7 @@ struct fft_sample_tlv;
> >  #define TX_STAT_INC(q, c) sc->debug.stats.txstats[q].c++
> >  #define RESET_STAT_INC(sc, type) sc->debug.stats.reset[type]++
> >  #define ANT_STAT_INC(i, c) sc->debug.stats.ant_stats[i].c++
> > -#define ANT_LNA_INC(i, c) sc->debug.stats.ant_stats[i].lna_config_cnt[c]++;
> > +#define ANT_LNA_INC(i, c) sc->debug.stats.ant_stats[i].lna_recv_cnt[c]++;
> >  #else
> >  #define TX_STAT_INC(q, c) do { } while (0)
> >  #define RESET_STAT_INC(sc, type) do { } while (0)
> > @@ -252,7 +252,9 @@ struct ath_rx_stats {
> >  
> >  struct ath_antenna_stats {
> >  	u32 recv_cnt;
> > -	u32 lna_config_cnt[4];
> > +	u32 rssi_avg;
> > +	u32 lna_recv_cnt[4];
> > +	u32 lna_attempt_cnt[4];
> >  };
> >  
> >  struct ath_stats {
> > @@ -294,10 +296,11 @@ void ath9k_sta_remove_debugfs(struct ieee80211_hw *hw,
> >  			      struct ieee80211_vif *vif,
> >  			      struct ieee80211_sta *sta,
> >  			      struct dentry *dir);
> > -
> >  void ath_debug_send_fft_sample(struct ath_softc *sc,
> >  			       struct fft_sample_tlv *fft_sample);
> > -
> > +void ath9k_debug_stat_ant(struct ath_softc *sc,
> > +			  struct ath_hw_antcomb_conf *div_ant_conf,
> > +			  int main_rssi_avg, int alt_rssi_avg);
> >  #else
> >  
> >  #define RX_STAT_INC(c) /* NOP */
> > @@ -310,12 +313,10 @@ static inline int ath9k_init_debug(struct ath_hw *ah)
> >  static inline void ath9k_deinit_debug(struct ath_softc *sc)
> >  {
> >  }
> > -
> >  static inline void ath_debug_stat_interrupt(struct ath_softc *sc,
> >  					    enum ath9k_int status)
> >  {
> >  }
> > -
> >  static inline void ath_debug_stat_tx(struct ath_softc *sc,
> >  				     struct ath_buf *bf,
> >  				     struct ath_tx_status *ts,
> > @@ -323,11 +324,16 @@ static inline void ath_debug_stat_tx(struct ath_softc *sc,
> >  				     unsigned int flags)
> >  {
> >  }
> > -
> >  static inline void ath_debug_stat_rx(struct ath_softc *sc,
> >  				     struct ath_rx_status *rs)
> >  {
> >  }
> > +static inline void ath9k_debug_stat_ant(struct ath_softc *sc,
> > +					struct ath_hw_antcomb_conf *div_ant_conf,
> > +					int main_rssi_avg, int alt_rssi_avg)
> > +{
> > +
> > +}
> >  
> >  #endif /* CONFIG_ATH9K_DEBUGFS */
> >  
> > -- 
> > 1.8.3.4
> > 
> > --
> > To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
> > the body of a message to majordomo@vger.kernel.org
> > More majordomo info at  http://vger.kernel.org/majordomo-info.html
> > 
> 
> -- 
> John W. Linville		Someday the world will need a hero, and you
> linville@tuxdriver.com			might be all we have.  Be ready.

-- 
John W. Linville		Someday the world will need a hero, and you
linville@tuxdriver.com			might be all we have.  Be ready.

^ permalink raw reply

* Re: pull request: wireless 2013-08-01
From: David Miller @ 2013-08-01 19:58 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, netdev, linux-kernel
In-Reply-To: <20130801190144.GC13922@tuxdriver.com>

From: "John W. Linville" <linville@tuxdriver.com>
Date: Thu, 1 Aug 2013 15:01:44 -0400

> I'll remind my feeder maintainers to slowdown the patchflow.

Yes, please do :-)

>   git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless.git for-davem

Pulled, thanks.

^ permalink raw reply

* Re: [PATCH v2 8/8] ath9k: Add statistics for antenna diversity
From: John W. Linville @ 2013-08-01 19:44 UTC (permalink / raw)
  To: Sujith Manoharan; +Cc: linux-wireless
In-Reply-To: <1375370826-1387-1-git-send-email-sujith@msujith.org>

I can't get this one to apply.  Please check the latest tree and fix
it up?

Thanks,

John

On Thu, Aug 01, 2013 at 08:57:06PM +0530, Sujith Manoharan wrote:
> From: Sujith Manoharan <c_manoha@qca.qualcomm.com>
> 
> Signed-off-by: Sujith Manoharan <c_manoha@qca.qualcomm.com>
> ---
>  drivers/net/wireless/ath/ath9k/antenna.c | 18 ++++---
>  drivers/net/wireless/ath/ath9k/debug.c   | 85 ++++++++++++++++++++++++++------
>  drivers/net/wireless/ath/ath9k/debug.h   | 20 +++++---
>  3 files changed, 95 insertions(+), 28 deletions(-)
> 
> diff --git a/drivers/net/wireless/ath/ath9k/antenna.c b/drivers/net/wireless/ath/ath9k/antenna.c
> index 42f3b87..391d557 100644
> --- a/drivers/net/wireless/ath/ath9k/antenna.c
> +++ b/drivers/net/wireless/ath/ath9k/antenna.c
> @@ -734,15 +734,18 @@ void ath_ant_comb_scan(struct ath_softc *sc, struct ath_rx_status *rs)
>  		antcomb->main_total_rssi += main_rssi;
>  		antcomb->alt_total_rssi  += alt_rssi;
>  
> -		if (main_ant_conf == rx_ant_conf) {
> +		if (main_ant_conf == rx_ant_conf)
>  			antcomb->main_recv_cnt++;
> -			ANT_STAT_INC(ANT_MAIN, recv_cnt);
> -			ANT_LNA_INC(ANT_MAIN, rx_ant_conf);
> -		} else {
> +		else
>  			antcomb->alt_recv_cnt++;
> -			ANT_STAT_INC(ANT_ALT, recv_cnt);
> -			ANT_LNA_INC(ANT_ALT, rx_ant_conf);
> -		}
> +	}
> +
> +	if (main_ant_conf == rx_ant_conf) {
> +		ANT_STAT_INC(ANT_MAIN, recv_cnt);
> +		ANT_LNA_INC(ANT_MAIN, rx_ant_conf);
> +	} else {
> +		ANT_STAT_INC(ANT_ALT, recv_cnt);
> +		ANT_LNA_INC(ANT_ALT, rx_ant_conf);
>  	}
>  
>  	/* Short scan check */
> @@ -821,6 +824,7 @@ void ath_ant_comb_scan(struct ath_softc *sc, struct ath_rx_status *rs)
>  div_comb_done:
>  	ath_ant_div_conf_fast_divbias(&div_ant_conf, antcomb, alt_ratio);
>  	ath9k_hw_antdiv_comb_conf_set(sc->sc_ah, &div_ant_conf);
> +	ath9k_debug_stat_ant(sc, &div_ant_conf, main_rssi_avg, alt_rssi_avg);
>  
>  	antcomb->scan_start_time = jiffies;
>  	antcomb->total_pkt_count = 0;
> diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c
> index 56cbe5d..a43bd8c 100644
> --- a/drivers/net/wireless/ath/ath9k/debug.c
> +++ b/drivers/net/wireless/ath/ath9k/debug.c
> @@ -321,6 +321,20 @@ static const struct file_operations fops_bt_ant_diversity = {
>  	.llseek = default_llseek,
>  };
>  
> +void ath9k_debug_stat_ant(struct ath_softc *sc,
> +			  struct ath_hw_antcomb_conf *div_ant_conf,
> +			  int main_rssi_avg, int alt_rssi_avg)
> +{
> +	struct ath_antenna_stats *as_main = &sc->debug.stats.ant_stats[ANT_MAIN];
> +	struct ath_antenna_stats *as_alt = &sc->debug.stats.ant_stats[ANT_ALT];
> +
> +	as_main->lna_attempt_cnt[div_ant_conf->main_lna_conf]++;
> +	as_alt->lna_attempt_cnt[div_ant_conf->alt_lna_conf]++;
> +
> +	as_main->rssi_avg = main_rssi_avg;
> +	as_alt->rssi_avg = alt_rssi_avg;
> +}
> +
>  static ssize_t read_file_antenna_diversity(struct file *file,
>  					   char __user *user_buf,
>  					   size_t count, loff_t *ppos)
> @@ -330,9 +344,14 @@ static ssize_t read_file_antenna_diversity(struct file *file,
>  	struct ath9k_hw_capabilities *pCap = &ah->caps;
>  	struct ath_antenna_stats *as_main = &sc->debug.stats.ant_stats[ANT_MAIN];
>  	struct ath_antenna_stats *as_alt = &sc->debug.stats.ant_stats[ANT_ALT];
> +	struct ath_hw_antcomb_conf div_ant_conf;
>  	unsigned int len = 0, size = 1024;
>  	ssize_t retval = 0;
>  	char *buf;
> +	char *lna_conf_str[4] = {"LNA1_MINUS_LNA2",
> +				 "LNA2",
> +				 "LNA1",
> +				 "LNA1_PLUS_LNA2"};
>  
>  	buf = kzalloc(size, GFP_KERNEL);
>  	if (buf == NULL)
> @@ -344,28 +363,66 @@ static ssize_t read_file_antenna_diversity(struct file *file,
>  		goto exit;
>  	}
>  
> +	ath9k_ps_wakeup(sc);
> +	ath9k_hw_antdiv_comb_conf_get(ah, &div_ant_conf);
> +	len += snprintf(buf + len, size - len, "Current MAIN config : %s\n",
> +			lna_conf_str[div_ant_conf.main_lna_conf]);
> +	len += snprintf(buf + len, size - len, "Current ALT config  : %s\n",
> +			lna_conf_str[div_ant_conf.alt_lna_conf]);
> +	len += snprintf(buf + len, size - len, "Average MAIN RSSI   : %d\n",
> +			as_main->rssi_avg);
> +	len += snprintf(buf + len, size - len, "Average ALT RSSI    : %d\n\n",
> +			as_alt->rssi_avg);
> +	ath9k_ps_restore(sc);
> +
> +	len += snprintf(buf + len, size - len, "Packet Receive Cnt:\n");
> +	len += snprintf(buf + len, size - len, "-------------------\n");
> +
>  	len += snprintf(buf + len, size - len, "%30s%15s\n",
>  			"MAIN", "ALT");
> -	len += snprintf(buf + len, size - len, "%-15s%15d%15d\n",
> -			"RECV CNT",
> +	len += snprintf(buf + len, size - len, "%-14s:%15d%15d\n",
> +			"TOTAL COUNT",
>  			as_main->recv_cnt,
>  			as_alt->recv_cnt);
> -	len += snprintf(buf + len, size - len, "%-15s%15d%15d\n",
> +	len += snprintf(buf + len, size - len, "%-14s:%15d%15d\n",
> +			"LNA1",
> +			as_main->lna_recv_cnt[ATH_ANT_DIV_COMB_LNA1],
> +			as_alt->lna_recv_cnt[ATH_ANT_DIV_COMB_LNA1]);
> +	len += snprintf(buf + len, size - len, "%-14s:%15d%15d\n",
> +			"LNA2",
> +			as_main->lna_recv_cnt[ATH_ANT_DIV_COMB_LNA2],
> +			as_alt->lna_recv_cnt[ATH_ANT_DIV_COMB_LNA2]);
> +	len += snprintf(buf + len, size - len, "%-14s:%15d%15d\n",
> +			"LNA1 + LNA2",
> +			as_main->lna_recv_cnt[ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2],
> +			as_alt->lna_recv_cnt[ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2]);
> +	len += snprintf(buf + len, size - len, "%-14s:%15d%15d\n",
> +			"LNA1 - LNA2",
> +			as_main->lna_recv_cnt[ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2],
> +			as_alt->lna_recv_cnt[ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2]);
> +
> +	len += snprintf(buf + len, size - len, "\nLNA Config Attempts:\n");
> +	len += snprintf(buf + len, size - len, "--------------------\n");
> +
> +	len += snprintf(buf + len, size - len, "%30s%15s\n",
> +			"MAIN", "ALT");
> +	len += snprintf(buf + len, size - len, "%-14s:%15d%15d\n",
>  			"LNA1",
> -			as_main->lna_config_cnt[ATH_ANT_DIV_COMB_LNA1],
> -			as_alt->lna_config_cnt[ATH_ANT_DIV_COMB_LNA1]);
> -	len += snprintf(buf + len, size - len, "%-15s%15d%15d\n",
> +			as_main->lna_attempt_cnt[ATH_ANT_DIV_COMB_LNA1],
> +			as_alt->lna_attempt_cnt[ATH_ANT_DIV_COMB_LNA1]);
> +	len += snprintf(buf + len, size - len, "%-14s:%15d%15d\n",
>  			"LNA2",
> -			as_main->lna_config_cnt[ATH_ANT_DIV_COMB_LNA2],
> -			as_alt->lna_config_cnt[ATH_ANT_DIV_COMB_LNA2]);
> -	len += snprintf(buf + len, size - len, "%-15s%15d%15d\n",
> +			as_main->lna_attempt_cnt[ATH_ANT_DIV_COMB_LNA2],
> +			as_alt->lna_attempt_cnt[ATH_ANT_DIV_COMB_LNA2]);
> +	len += snprintf(buf + len, size - len, "%-14s:%15d%15d\n",
>  			"LNA1 + LNA2",
> -			as_main->lna_config_cnt[ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2],
> -			as_alt->lna_config_cnt[ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2]);
> -	len += snprintf(buf + len, size - len, "%-15s%15d%15d\n",
> +			as_main->lna_attempt_cnt[ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2],
> +			as_alt->lna_attempt_cnt[ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2]);
> +	len += snprintf(buf + len, size - len, "%-14s:%15d%15d\n",
>  			"LNA1 - LNA2",
> -			as_main->lna_config_cnt[ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2],
> -			as_alt->lna_config_cnt[ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2]);
> +			as_main->lna_attempt_cnt[ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2],
> +			as_alt->lna_attempt_cnt[ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2]);
> +
>  exit:
>  	if (len > size)
>  		len = size;
> diff --git a/drivers/net/wireless/ath/ath9k/debug.h b/drivers/net/wireless/ath/ath9k/debug.h
> index a879e45..01c5c6a 100644
> --- a/drivers/net/wireless/ath/ath9k/debug.h
> +++ b/drivers/net/wireless/ath/ath9k/debug.h
> @@ -29,7 +29,7 @@ struct fft_sample_tlv;
>  #define TX_STAT_INC(q, c) sc->debug.stats.txstats[q].c++
>  #define RESET_STAT_INC(sc, type) sc->debug.stats.reset[type]++
>  #define ANT_STAT_INC(i, c) sc->debug.stats.ant_stats[i].c++
> -#define ANT_LNA_INC(i, c) sc->debug.stats.ant_stats[i].lna_config_cnt[c]++;
> +#define ANT_LNA_INC(i, c) sc->debug.stats.ant_stats[i].lna_recv_cnt[c]++;
>  #else
>  #define TX_STAT_INC(q, c) do { } while (0)
>  #define RESET_STAT_INC(sc, type) do { } while (0)
> @@ -252,7 +252,9 @@ struct ath_rx_stats {
>  
>  struct ath_antenna_stats {
>  	u32 recv_cnt;
> -	u32 lna_config_cnt[4];
> +	u32 rssi_avg;
> +	u32 lna_recv_cnt[4];
> +	u32 lna_attempt_cnt[4];
>  };
>  
>  struct ath_stats {
> @@ -294,10 +296,11 @@ void ath9k_sta_remove_debugfs(struct ieee80211_hw *hw,
>  			      struct ieee80211_vif *vif,
>  			      struct ieee80211_sta *sta,
>  			      struct dentry *dir);
> -
>  void ath_debug_send_fft_sample(struct ath_softc *sc,
>  			       struct fft_sample_tlv *fft_sample);
> -
> +void ath9k_debug_stat_ant(struct ath_softc *sc,
> +			  struct ath_hw_antcomb_conf *div_ant_conf,
> +			  int main_rssi_avg, int alt_rssi_avg);
>  #else
>  
>  #define RX_STAT_INC(c) /* NOP */
> @@ -310,12 +313,10 @@ static inline int ath9k_init_debug(struct ath_hw *ah)
>  static inline void ath9k_deinit_debug(struct ath_softc *sc)
>  {
>  }
> -
>  static inline void ath_debug_stat_interrupt(struct ath_softc *sc,
>  					    enum ath9k_int status)
>  {
>  }
> -
>  static inline void ath_debug_stat_tx(struct ath_softc *sc,
>  				     struct ath_buf *bf,
>  				     struct ath_tx_status *ts,
> @@ -323,11 +324,16 @@ static inline void ath_debug_stat_tx(struct ath_softc *sc,
>  				     unsigned int flags)
>  {
>  }
> -
>  static inline void ath_debug_stat_rx(struct ath_softc *sc,
>  				     struct ath_rx_status *rs)
>  {
>  }
> +static inline void ath9k_debug_stat_ant(struct ath_softc *sc,
> +					struct ath_hw_antcomb_conf *div_ant_conf,
> +					int main_rssi_avg, int alt_rssi_avg)
> +{
> +
> +}
>  
>  #endif /* CONFIG_ATH9K_DEBUGFS */
>  
> -- 
> 1.8.3.4
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 

-- 
John W. Linville		Someday the world will need a hero, and you
linville@tuxdriver.com			might be all we have.  Be ready.

^ permalink raw reply

* Re: pull-request: mac80211-next 2013-07-26
From: John W. Linville @ 2013-08-01 19:27 UTC (permalink / raw)
  To: Johannes Berg; +Cc: linux-wireless
In-Reply-To: <1374827740.8248.15.camel@jlt4.sipsolutions.net>

On Fri, Jul 26, 2013 at 10:35:40AM +0200, Johannes Berg wrote:
> John,
> 
> This is a more traditional pull request without patches since they've
> all been to the list :-) First set of updates for mac80211-next.
> 
> The biggest change here is probably the initial 5/10 MHz support for
> IBSS, the remaining patches are smaller features and some cleanups.
> 
> Let me know if there's any problem.
> 
> johannes
> 
> 
> The following changes since commit ad81f0545ef01ea651886dddac4bef6cec930092:
> 
>   Linux 3.11-rc1 (2013-07-14 15:18:27 -0700)
> 
> are available in the git repository at:
> 
>   git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next.git for-john
> 
> for you to fetch changes up to c82b5a74cc739385db6e4275fe504a0e9469bf01:
> 
>   mac80211: make active monitor injection work w/ HW queue (2013-07-16 09:58:19 +0300)

Pulling now...

-- 
John W. Linville		Someday the world will need a hero, and you
linville@tuxdriver.com			might be all we have.  Be ready.

^ permalink raw reply

* Re: cross compile backports with LTIB
From: Jonathan Bagg @ 2013-08-01 19:17 UTC (permalink / raw)
  To: backports; +Cc: Solomon Peachy, linux-wireless
In-Reply-To: <51FAB31F.6050207@lenbrook.com>

On 13-08-01 03:12 PM, Jonathan Bagg wrote:
> On 13-08-01 01:47 PM, Solomon Peachy wrote:
>> On Thu, Aug 01, 2013 at 12:37:33PM -0400, Jonathan Bagg wrote:
>>> I've been cross compiling compat-wireless and now I'm trying
>>> backports.  It looks like conf.c and zconf.tab.c are being compiled
>>> as arm and then the build process is trying to run conf on my x86
>>> host.  Results using the below make parameters I was using for
>>> compat-wireless......
> Learned some things....Problem was LTIB (ltib = Freescale tool) 
> environment.  Outside of LTIB, backports cross compiles fine.  To get 
> backports happy in LTIB need to use UNSPOOF/SPOOF_PATH to switch 
> between host and cross environment....
>
(this is for the LTIBs spec file for backports = 
dist/lfs-5.1/backports/backports.spec - forgot to mention in previous post)
> %Build
> export PATH=$UNSPOOF_PATH
>
> make defconfig-cw1200 make prefix=%{_prefix} 
> CROSS_COMPILE=${TOOLCHAIN_PATH}/bin/${TOOLCHAIN_PREFIX} ARCH=$LINTARCH 
> KLIB=${TOP}/rootfs/lib/modules/%{kversion} 
> KLIB_BUILD=${TOP}/rpm/BUILD/linux
>
> export PATH=$SPOOF_PATH
>
> make prefix=%{_prefix} 
> CROSS_COMPILE=${TOOLCHAIN_PATH}/bin/${TOOLCHAIN_PREFIX} ARCH=$LINTARCH 
> KLIB=${TOP}/rootfs/lib/modules/%{kversion} 
> KLIB_BUILD=${TOP}/rpm/BUILD/linux
>
> Jon 

^ permalink raw reply

* pull request: wireless 2013-08-01
From: John W. Linville @ 2013-08-01 19:01 UTC (permalink / raw)
  To: davem; +Cc: linux-wireless, netdev, linux-kernel

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

Dave,

This pull request is intended for the 3.11 stream.  It is a bit
larger than usual, as it includes pulls from most of my feeder trees
as well...

For the Bluetooth bits, Gustavo says:

"A few fixes and devices ID additions for 3.11:

 * There are 4 new ath3k device ids
 * Fixed stack memory usage in ath3k.
 * Fixed the init process of BlueFRITZ! devices, they were failing to init
   due to an unsupported command we sent.
 * Fixed wrong use of PTR_ERR in btusb code that was preventing intel devices
   to work properly.
 * Fixed race condition between hci_register_dev() and hci_dev_open() that
   could cause a NULL pointer dereference.
 * Fixed race condition that could call hci_req_cmd_complete() and make some
   devices to fail as showed in the log added to the commit message."

Regarding the NFC bits, Samuel says:

"We have:

1) A build failure fix for the NCI SPI transport layer due to a
   missing CRC_CCITT Kconfig dependency.

2) A netlink command rename: CMD_FW_UPLOAD was merged during the 3.11
   merge window but the typical terminology for loading a firmware to a
   target is firmware download rather than upload. In order to avoid any
   confusion in a file exported to userspace, we rename this command to
   CMD_FW_DOWNLOAD."

Samuel's item #2 isn't strictly a fix, but it seems safe and should
avoid confusion in the future.

As for the mac80211 bits, Johannes says:

"I only have three fixes this time, a fix for a suspend regression, a
patch correcting the initiator in regulatory code and one fix for mesh
station powersave."

With respect to the iwlwifi bits, Johannes says:

"We have a scan fix for passive channels, a new PCI device ID for an old
device, a NIC reset fix, an RF-Kill fix, a fix for powersave when GO
interfaces are present as well as an aggregation session fix (for a
corner case) and a workaround for a firmware design issue - it only
supports a single GTK in D3."

Bringing-up the rear with the Atheros trees, Kalle says:

"Geert Uytterhoeven fixed an ath10k build problem when NO_DMA=y. I added
a missing MAINTAINERS entry for ath10k and updated ath6kl git tree
location."

Along with the above...

Arend van Spriel fixes a brcmfmac WARNING when unplugging the device.

Avinash Patil proves a couple of minor mwifiex fixes relating to P2P mode.

Luciano Coelho updates the MAINTAINERS entry for the wilink drivers.

Stanislaw Gruszka brings an rt2x00 fix for a queue start/stop problem.

Stone Piao fixes another mwifiex problem, a command timeout related to P2P mode.

Tomasz Moń corrects an endian problem in mwifiex.

I'll remind my feeder maintainers to slowdown the patchflow.
Beyond that, please let me know if there are problems!

Thanks,

John

---

The following changes since commit b00589af3b04736376f24625ab0b394642e89e29:

  bridge: disable snooping if there is no querier (2013-07-31 17:40:21 -0700)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless.git for-davem

for you to fetch changes up to 22e02a0272e5291a40ca28d2b7aea5231c832077:

  Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless into for-davem (2013-08-01 14:30:59 -0400)

----------------------------------------------------------------

AceLan Kao (2):
      Bluetooth: Add support for Atheros [0cf3:3121]
      Bluetooth: Add support for Atheros [0cf3:e003]

Adam Lee (1):
      Bluetooth: fix wrong use of PTR_ERR() in btusb

Arend van Spriel (1):
      brcmfmac: inform cfg80211 about disconnect when device is unplugged

Arik Nemtsov (1):
      regulatory: use correct regulatory initiator on wiphy register

Avinash Patil (2):
      mwifiex: check for bss_role instead of bss_mode for STA operations
      mwifiex: fix wrong data rates in P2P client

Chun-Yeow Yeoh (1):
      mac80211: prevent the buffering or frame transmission to non-assoc mesh STA

David Spinadel (1):
      iwlwifi: mvm: set SSID bits for passive channels

Emmanuel Grumbach (3):
      iwlwifi: add DELL SKU for 5150 HMC
      iwlwifi: pcie: reset the NIC before the bring up
      iwlwifi: pcie: clear RFKILL interrupt in AMPG

Frederic Danis (1):
      NFC: Fix NCI over SPI build

Geert Uytterhoeven (1):
      ath10k: ATH10K should depend on HAS_DMA

Gustavo Padovan (1):
      Bluetooth: Fix race between hci_register_dev() and hci_dev_open()

Ilan Peer (1):
      iwlwifi: mvm: Disable managed PS when GO is added

Jaganath Kanakkassery (1):
      Bluetooth: Fix invalid length check in l2cap_information_rsp()

Johan Hedberg (2):
      Bluetooth: Fix HCI init for BlueFRITZ! devices
      Bluetooth: Fix calling request callback more than once

Johannes Berg (2):
      iwlwifi: mvm: use only a single GTK in D3
      iwlwifi: mvm: fix flushing not started aggregation sessions

John W. Linville (6):
      Merge branch 'for-linville-current' of git://github.com/kvalo/ath
      Merge branch 'for-john' of git://git.kernel.org/.../iwlwifi/iwlwifi-fixes
      Merge branch 'for-john' of git://git.kernel.org/.../jberg/mac80211
      Merge branch 'master' of git://git.kernel.org/.../bluetooth/bluetooth
      Merge tag 'nfc-fixes-3.11-2' of git://git.kernel.org/.../sameo/nfc-fixes
      Merge branch 'master' of git://git.kernel.org/.../linville/wireless into for-davem

Kalle Valo (2):
      MAINTAINERS: add ath10k
      MAINTAINERS: update ath6kl git location

Luciano Coelho (1):
      MAINTAINERS: change email of TI WiLink drivers' maintainer

Samuel Ortiz (1):
      NFC: netlink: Rename CMD_FW_UPLOAD to CMD_FW_DOWNLOAD

Stanislaw Gruszka (3):
      mac80211: fix monitor interface suspend crash regression
      Bluetooth: ath3k: don't use stack memory for DMA
      rt2x00: fix stop queue

Stone Piao (1):
      mwifiex: fix command 0x2c timeout during p2p_find or p2p_connect

Sujith Manoharan (1):
      Bluetooth: ath3k: Add support for ID 0x13d3/0x3402

Thomas Loo (1):
      Bluetooth: ath3k: Add support for Fujitsu Lifebook UH5x2 [04c5:1330]

Tomasz Moń (1):
      mwifiex: Add missing endian conversion.

 MAINTAINERS                                        | 12 +++++-
 drivers/bluetooth/ath3k.c                          | 46 +++++++++++++++++-----
 drivers/bluetooth/btusb.c                          | 18 +++++----
 drivers/net/wireless/ath/ath10k/Kconfig            |  2 +-
 .../net/wireless/brcm80211/brcmfmac/wl_cfg80211.c  |  5 ++-
 drivers/net/wireless/iwlwifi/iwl-prph.h            |  2 +
 drivers/net/wireless/iwlwifi/mvm/d3.c              | 15 ++++---
 drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h     |  1 -
 drivers/net/wireless/iwlwifi/mvm/mac80211.c        | 42 ++++++++++----------
 drivers/net/wireless/iwlwifi/mvm/scan.c            | 11 +-----
 drivers/net/wireless/iwlwifi/mvm/sta.c             | 11 ++++--
 drivers/net/wireless/iwlwifi/pcie/drv.c            |  1 +
 drivers/net/wireless/iwlwifi/pcie/rx.c             |  8 ++++
 drivers/net/wireless/iwlwifi/pcie/trans.c          |  5 +++
 drivers/net/wireless/mwifiex/cfg80211.c            |  4 +-
 drivers/net/wireless/mwifiex/cfp.c                 |  3 +-
 drivers/net/wireless/mwifiex/join.c                |  6 ++-
 drivers/net/wireless/mwifiex/sdio.c                |  4 +-
 drivers/net/wireless/mwifiex/sta_ioctl.c           |  4 +-
 drivers/net/wireless/rt2x00/rt2x00queue.c          | 18 +++++----
 include/net/nfc/hci.h                              |  2 +-
 include/net/nfc/nfc.h                              |  4 +-
 include/uapi/linux/nfc.h                           |  6 +--
 net/bluetooth/hci_core.c                           | 26 +++++++-----
 net/mac80211/mesh_ps.c                             |  4 ++
 net/mac80211/pm.c                                  |  7 +++-
 net/nfc/core.c                                     | 20 +++++-----
 net/nfc/hci/core.c                                 |  8 ++--
 net/nfc/nci/Kconfig                                |  1 +
 net/nfc/netlink.c                                  | 12 +++---
 net/nfc/nfc.h                                      |  6 +--
 net/wireless/reg.c                                 |  5 ++-
 32 files changed, 203 insertions(+), 116 deletions(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index a26b10e..77be3f4 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1406,7 +1406,7 @@ ATHEROS ATH6KL WIRELESS DRIVER
 M:	Kalle Valo <kvalo@qca.qualcomm.com>
 L:	linux-wireless@vger.kernel.org
 W:	http://wireless.kernel.org/en/users/Drivers/ath6kl
-T:	git git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/ath6kl.git
+T:	git git://github.com/kvalo/ath.git
 S:	Supported
 F:	drivers/net/wireless/ath/ath6kl/
 
@@ -6726,6 +6726,14 @@ T:	git git://linuxtv.org/anttip/media_tree.git
 S:	Maintained
 F:	drivers/media/tuners/qt1010*
 
+QUALCOMM ATHEROS ATH10K WIRELESS DRIVER
+M:	Kalle Valo <kvalo@qca.qualcomm.com>
+L:	ath10k@lists.infradead.org
+W:	http://wireless.kernel.org/en/users/Drivers/ath10k
+T:	git git://github.com/kvalo/ath.git
+S:	Supported
+F:	drivers/net/wireless/ath/ath10k/
+
 QUALCOMM HEXAGON ARCHITECTURE
 M:	Richard Kuo <rkuo@codeaurora.org>
 L:	linux-hexagon@vger.kernel.org
@@ -8270,7 +8278,7 @@ S:	Maintained
 F:	sound/soc/codecs/twl4030*
 
 TI WILINK WIRELESS DRIVERS
-M:	Luciano Coelho <coelho@ti.com>
+M:	Luciano Coelho <luca@coelho.fi>
 L:	linux-wireless@vger.kernel.org
 W:	http://wireless.kernel.org/en/users/Drivers/wl12xx
 W:	http://wireless.kernel.org/en/users/Drivers/wl1251
diff --git a/drivers/bluetooth/ath3k.c b/drivers/bluetooth/ath3k.c
index 11f467c..a12b923 100644
--- a/drivers/bluetooth/ath3k.c
+++ b/drivers/bluetooth/ath3k.c
@@ -91,6 +91,10 @@ static struct usb_device_id ath3k_table[] = {
 	{ USB_DEVICE(0x0489, 0xe04e) },
 	{ USB_DEVICE(0x0489, 0xe056) },
 	{ USB_DEVICE(0x0489, 0xe04d) },
+	{ USB_DEVICE(0x04c5, 0x1330) },
+	{ USB_DEVICE(0x13d3, 0x3402) },
+	{ USB_DEVICE(0x0cf3, 0x3121) },
+	{ USB_DEVICE(0x0cf3, 0xe003) },
 
 	/* Atheros AR5BBU12 with sflash firmware */
 	{ USB_DEVICE(0x0489, 0xE02C) },
@@ -128,6 +132,10 @@ static struct usb_device_id ath3k_blist_tbl[] = {
 	{ USB_DEVICE(0x0489, 0xe04e), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x0489, 0xe056), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x0489, 0xe04d), .driver_info = BTUSB_ATH3012 },
+	{ USB_DEVICE(0x04c5, 0x1330), .driver_info = BTUSB_ATH3012 },
+	{ USB_DEVICE(0x13d3, 0x3402), .driver_info = BTUSB_ATH3012 },
+	{ USB_DEVICE(0x0cf3, 0x3121), .driver_info = BTUSB_ATH3012 },
+	{ USB_DEVICE(0x0cf3, 0xe003), .driver_info = BTUSB_ATH3012 },
 
 	/* Atheros AR5BBU22 with sflash firmware */
 	{ USB_DEVICE(0x0489, 0xE03C), .driver_info = BTUSB_ATH3012 },
@@ -193,24 +201,44 @@ error:
 
 static int ath3k_get_state(struct usb_device *udev, unsigned char *state)
 {
-	int pipe = 0;
+	int ret, pipe = 0;
+	char *buf;
+
+	buf = kmalloc(sizeof(*buf), GFP_KERNEL);
+	if (!buf)
+		return -ENOMEM;
 
 	pipe = usb_rcvctrlpipe(udev, 0);
-	return usb_control_msg(udev, pipe, ATH3K_GETSTATE,
-			USB_TYPE_VENDOR | USB_DIR_IN, 0, 0,
-			state, 0x01, USB_CTRL_SET_TIMEOUT);
+	ret = usb_control_msg(udev, pipe, ATH3K_GETSTATE,
+			      USB_TYPE_VENDOR | USB_DIR_IN, 0, 0,
+			      buf, sizeof(*buf), USB_CTRL_SET_TIMEOUT);
+
+	*state = *buf;
+	kfree(buf);
+
+	return ret;
 }
 
 static int ath3k_get_version(struct usb_device *udev,
 			struct ath3k_version *version)
 {
-	int pipe = 0;
+	int ret, pipe = 0;
+	struct ath3k_version *buf;
+	const int size = sizeof(*buf);
+
+	buf = kmalloc(size, GFP_KERNEL);
+	if (!buf)
+		return -ENOMEM;
 
 	pipe = usb_rcvctrlpipe(udev, 0);
-	return usb_control_msg(udev, pipe, ATH3K_GETVERSION,
-			USB_TYPE_VENDOR | USB_DIR_IN, 0, 0, version,
-			sizeof(struct ath3k_version),
-			USB_CTRL_SET_TIMEOUT);
+	ret = usb_control_msg(udev, pipe, ATH3K_GETVERSION,
+			      USB_TYPE_VENDOR | USB_DIR_IN, 0, 0,
+			      buf, size, USB_CTRL_SET_TIMEOUT);
+
+	memcpy(version, buf, size);
+	kfree(buf);
+
+	return ret;
 }
 
 static int ath3k_load_fwfile(struct usb_device *udev,
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index de4cf4d..8e16f0a 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -154,6 +154,10 @@ static struct usb_device_id blacklist_table[] = {
 	{ USB_DEVICE(0x0489, 0xe04e), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x0489, 0xe056), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x0489, 0xe04d), .driver_info = BTUSB_ATH3012 },
+	{ USB_DEVICE(0x04c5, 0x1330), .driver_info = BTUSB_ATH3012 },
+	{ USB_DEVICE(0x13d3, 0x3402), .driver_info = BTUSB_ATH3012 },
+	{ USB_DEVICE(0x0cf3, 0x3121), .driver_info = BTUSB_ATH3012 },
+	{ USB_DEVICE(0x0cf3, 0xe003), .driver_info = BTUSB_ATH3012 },
 
 	/* Atheros AR5BBU12 with sflash firmware */
 	{ USB_DEVICE(0x0489, 0xe02c), .driver_info = BTUSB_IGNORE },
@@ -1095,7 +1099,7 @@ static int btusb_setup_intel_patching(struct hci_dev *hdev,
 	if (IS_ERR(skb)) {
 		BT_ERR("%s sending Intel patch command (0x%4.4x) failed (%ld)",
 		       hdev->name, cmd->opcode, PTR_ERR(skb));
-		return -PTR_ERR(skb);
+		return PTR_ERR(skb);
 	}
 
 	/* It ensures that the returned event matches the event data read from
@@ -1147,7 +1151,7 @@ static int btusb_setup_intel(struct hci_dev *hdev)
 	if (IS_ERR(skb)) {
 		BT_ERR("%s sending initial HCI reset command failed (%ld)",
 		       hdev->name, PTR_ERR(skb));
-		return -PTR_ERR(skb);
+		return PTR_ERR(skb);
 	}
 	kfree_skb(skb);
 
@@ -1161,7 +1165,7 @@ static int btusb_setup_intel(struct hci_dev *hdev)
 	if (IS_ERR(skb)) {
 		BT_ERR("%s reading Intel fw version command failed (%ld)",
 		       hdev->name, PTR_ERR(skb));
-		return -PTR_ERR(skb);
+		return PTR_ERR(skb);
 	}
 
 	if (skb->len != sizeof(*ver)) {
@@ -1219,7 +1223,7 @@ static int btusb_setup_intel(struct hci_dev *hdev)
 		BT_ERR("%s entering Intel manufacturer mode failed (%ld)",
 		       hdev->name, PTR_ERR(skb));
 		release_firmware(fw);
-		return -PTR_ERR(skb);
+		return PTR_ERR(skb);
 	}
 
 	if (skb->data[0]) {
@@ -1276,7 +1280,7 @@ static int btusb_setup_intel(struct hci_dev *hdev)
 	if (IS_ERR(skb)) {
 		BT_ERR("%s exiting Intel manufacturer mode failed (%ld)",
 		       hdev->name, PTR_ERR(skb));
-		return -PTR_ERR(skb);
+		return PTR_ERR(skb);
 	}
 	kfree_skb(skb);
 
@@ -1292,7 +1296,7 @@ exit_mfg_disable:
 	if (IS_ERR(skb)) {
 		BT_ERR("%s exiting Intel manufacturer mode failed (%ld)",
 		       hdev->name, PTR_ERR(skb));
-		return -PTR_ERR(skb);
+		return PTR_ERR(skb);
 	}
 	kfree_skb(skb);
 
@@ -1310,7 +1314,7 @@ exit_mfg_deactivate:
 	if (IS_ERR(skb)) {
 		BT_ERR("%s exiting Intel manufacturer mode failed (%ld)",
 		       hdev->name, PTR_ERR(skb));
-		return -PTR_ERR(skb);
+		return PTR_ERR(skb);
 	}
 	kfree_skb(skb);
 
diff --git a/drivers/net/wireless/ath/ath10k/Kconfig b/drivers/net/wireless/ath/ath10k/Kconfig
index cde58fe..82e8088 100644
--- a/drivers/net/wireless/ath/ath10k/Kconfig
+++ b/drivers/net/wireless/ath/ath10k/Kconfig
@@ -1,6 +1,6 @@
 config ATH10K
         tristate "Atheros 802.11ac wireless cards support"
-        depends on MAC80211
+        depends on MAC80211 && HAS_DMA
 	select ATH_COMMON
         ---help---
           This module adds support for wireless adapters based on
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
index 277b37a..7fa71f7 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
@@ -1093,8 +1093,11 @@ static void brcmf_link_down(struct brcmf_cfg80211_vif *vif)
 		brcmf_dbg(INFO, "Call WLC_DISASSOC to stop excess roaming\n ");
 		err = brcmf_fil_cmd_data_set(vif->ifp,
 					     BRCMF_C_DISASSOC, NULL, 0);
-		if (err)
+		if (err) {
 			brcmf_err("WLC_DISASSOC failed (%d)\n", err);
+			cfg80211_disconnected(vif->wdev.netdev, 0,
+					      NULL, 0, GFP_KERNEL);
+		}
 		clear_bit(BRCMF_VIF_STATUS_CONNECTED, &vif->sme_state);
 	}
 	clear_bit(BRCMF_VIF_STATUS_CONNECTING, &vif->sme_state);
diff --git a/drivers/net/wireless/iwlwifi/iwl-prph.h b/drivers/net/wireless/iwlwifi/iwl-prph.h
index ff8cc75..a70c7b9 100644
--- a/drivers/net/wireless/iwlwifi/iwl-prph.h
+++ b/drivers/net/wireless/iwlwifi/iwl-prph.h
@@ -97,6 +97,8 @@
 
 #define APMG_PCIDEV_STT_VAL_L1_ACT_DIS		(0x00000800)
 
+#define APMG_RTC_INT_STT_RFKILL		(0x10000000)
+
 /* Device system time */
 #define DEVICE_SYSTEM_TIME_REG 0xA0206C
 
diff --git a/drivers/net/wireless/iwlwifi/mvm/d3.c b/drivers/net/wireless/iwlwifi/mvm/d3.c
index 7e5e5c2..83da884 100644
--- a/drivers/net/wireless/iwlwifi/mvm/d3.c
+++ b/drivers/net/wireless/iwlwifi/mvm/d3.c
@@ -134,7 +134,7 @@ struct wowlan_key_data {
 	struct iwl_wowlan_rsc_tsc_params_cmd *rsc_tsc;
 	struct iwl_wowlan_tkip_params_cmd *tkip;
 	bool error, use_rsc_tsc, use_tkip;
-	int gtk_key_idx;
+	int wep_key_idx;
 };
 
 static void iwl_mvm_wowlan_program_keys(struct ieee80211_hw *hw,
@@ -188,8 +188,8 @@ static void iwl_mvm_wowlan_program_keys(struct ieee80211_hw *hw,
 			wkc.wep_key.key_offset = 0;
 		} else {
 			/* others start at 1 */
-			data->gtk_key_idx++;
-			wkc.wep_key.key_offset = data->gtk_key_idx;
+			data->wep_key_idx++;
+			wkc.wep_key.key_offset = data->wep_key_idx;
 		}
 
 		ret = iwl_mvm_send_cmd_pdu(mvm, WEP_KEY, CMD_SYNC,
@@ -316,8 +316,13 @@ static void iwl_mvm_wowlan_program_keys(struct ieee80211_hw *hw,
 		mvm->ptk_ivlen = key->iv_len;
 		mvm->ptk_icvlen = key->icv_len;
 	} else {
-		data->gtk_key_idx++;
-		key->hw_key_idx = data->gtk_key_idx;
+		/*
+		 * firmware only supports TSC/RSC for a single key,
+		 * so if there are multiple keep overwriting them
+		 * with new ones -- this relies on mac80211 doing
+		 * list_add_tail().
+		 */
+		key->hw_key_idx = 1;
 		mvm->gtk_ivlen = key->iv_len;
 		mvm->gtk_icvlen = key->icv_len;
 	}
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h
index b60d141..365095a 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h
@@ -69,7 +69,6 @@
 /* Scan Commands, Responses, Notifications */
 
 /* Masks for iwl_scan_channel.type flags */
-#define SCAN_CHANNEL_TYPE_PASSIVE	0
 #define SCAN_CHANNEL_TYPE_ACTIVE	BIT(0)
 #define SCAN_CHANNEL_NARROW_BAND	BIT(22)
 
diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c
index 1eedc42..f19baf0 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c
+++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c
@@ -512,6 +512,27 @@ static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw,
 		goto out_unlock;
 
 	/*
+	 * TODO: remove this temporary code.
+	 * Currently MVM FW supports power management only on single MAC.
+	 * If new interface added, disable PM on existing interface.
+	 * P2P device is a special case, since it is handled by FW similary to
+	 * scan. If P2P deviced is added, PM remains enabled on existing
+	 * interface.
+	 * Note: the method below does not count the new interface being added
+	 * at this moment.
+	 */
+	if (vif->type != NL80211_IFTYPE_P2P_DEVICE)
+		mvm->vif_count++;
+	if (mvm->vif_count > 1) {
+		IWL_DEBUG_MAC80211(mvm,
+				   "Disable power on existing interfaces\n");
+		ieee80211_iterate_active_interfaces_atomic(
+					    mvm->hw,
+					    IEEE80211_IFACE_ITER_NORMAL,
+					    iwl_mvm_pm_disable_iterator, mvm);
+	}
+
+	/*
 	 * The AP binding flow can be done only after the beacon
 	 * template is configured (which happens only in the mac80211
 	 * start_ap() flow), and adding the broadcast station can happen
@@ -534,27 +555,6 @@ static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw,
 		goto out_unlock;
 	}
 
-	/*
-	 * TODO: remove this temporary code.
-	 * Currently MVM FW supports power management only on single MAC.
-	 * If new interface added, disable PM on existing interface.
-	 * P2P device is a special case, since it is handled by FW similary to
-	 * scan. If P2P deviced is added, PM remains enabled on existing
-	 * interface.
-	 * Note: the method below does not count the new interface being added
-	 * at this moment.
-	 */
-	if (vif->type != NL80211_IFTYPE_P2P_DEVICE)
-		mvm->vif_count++;
-	if (mvm->vif_count > 1) {
-		IWL_DEBUG_MAC80211(mvm,
-				   "Disable power on existing interfaces\n");
-		ieee80211_iterate_active_interfaces_atomic(
-					    mvm->hw,
-					    IEEE80211_IFACE_ITER_NORMAL,
-					    iwl_mvm_pm_disable_iterator, mvm);
-	}
-
 	ret = iwl_mvm_mac_ctxt_add(mvm, vif);
 	if (ret)
 		goto out_release;
diff --git a/drivers/net/wireless/iwlwifi/mvm/scan.c b/drivers/net/wireless/iwlwifi/mvm/scan.c
index 268f027..acdff6b 100644
--- a/drivers/net/wireless/iwlwifi/mvm/scan.c
+++ b/drivers/net/wireless/iwlwifi/mvm/scan.c
@@ -178,19 +178,12 @@ static void iwl_mvm_scan_fill_channels(struct iwl_scan_cmd *cmd,
 	struct iwl_scan_channel *chan = (struct iwl_scan_channel *)
 		(cmd->data + le16_to_cpu(cmd->tx_cmd.len));
 	int i;
-	__le32 chan_type_value;
-
-	if (req->n_ssids > 0)
-		chan_type_value = cpu_to_le32(BIT(req->n_ssids) - 1);
-	else
-		chan_type_value = SCAN_CHANNEL_TYPE_PASSIVE;
 
 	for (i = 0; i < cmd->channel_count; i++) {
 		chan->channel = cpu_to_le16(req->channels[i]->hw_value);
+		chan->type = cpu_to_le32(BIT(req->n_ssids) - 1);
 		if (req->channels[i]->flags & IEEE80211_CHAN_PASSIVE_SCAN)
-			chan->type = SCAN_CHANNEL_TYPE_PASSIVE;
-		else
-			chan->type = chan_type_value;
+			chan->type &= cpu_to_le32(~SCAN_CHANNEL_TYPE_ACTIVE);
 		chan->active_dwell = cpu_to_le16(active_dwell);
 		chan->passive_dwell = cpu_to_le16(passive_dwell);
 		chan->iteration_count = cpu_to_le16(1);
diff --git a/drivers/net/wireless/iwlwifi/mvm/sta.c b/drivers/net/wireless/iwlwifi/mvm/sta.c
index 85d4bbe..563f559 100644
--- a/drivers/net/wireless/iwlwifi/mvm/sta.c
+++ b/drivers/net/wireless/iwlwifi/mvm/sta.c
@@ -915,6 +915,7 @@ int iwl_mvm_sta_tx_agg_flush(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
 	struct iwl_mvm_sta *mvmsta = (void *)sta->drv_priv;
 	struct iwl_mvm_tid_data *tid_data = &mvmsta->tid_data[tid];
 	u16 txq_id;
+	enum iwl_mvm_agg_state old_state;
 
 	/*
 	 * First set the agg state to OFF to avoid calling
@@ -924,13 +925,17 @@ int iwl_mvm_sta_tx_agg_flush(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
 	txq_id = tid_data->txq_id;
 	IWL_DEBUG_TX_QUEUES(mvm, "Flush AGG: sta %d tid %d q %d state %d\n",
 			    mvmsta->sta_id, tid, txq_id, tid_data->state);
+	old_state = tid_data->state;
 	tid_data->state = IWL_AGG_OFF;
 	spin_unlock_bh(&mvmsta->lock);
 
-	if (iwl_mvm_flush_tx_path(mvm, BIT(txq_id), true))
-		IWL_ERR(mvm, "Couldn't flush the AGG queue\n");
+	if (old_state >= IWL_AGG_ON) {
+		if (iwl_mvm_flush_tx_path(mvm, BIT(txq_id), true))
+			IWL_ERR(mvm, "Couldn't flush the AGG queue\n");
+
+		iwl_trans_txq_disable(mvm->trans, tid_data->txq_id);
+	}
 
-	iwl_trans_txq_disable(mvm->trans, tid_data->txq_id);
 	mvm->queue_to_mac80211[tid_data->txq_id] =
 				IWL_INVALID_MAC80211_QUEUE;
 
diff --git a/drivers/net/wireless/iwlwifi/pcie/drv.c b/drivers/net/wireless/iwlwifi/pcie/drv.c
index 81f3ea5..ff13458 100644
--- a/drivers/net/wireless/iwlwifi/pcie/drv.c
+++ b/drivers/net/wireless/iwlwifi/pcie/drv.c
@@ -130,6 +130,7 @@ static DEFINE_PCI_DEVICE_TABLE(iwl_hw_card_ids) = {
 	{IWL_PCI_DEVICE(0x423C, 0x1306, iwl5150_abg_cfg)}, /* Half Mini Card */
 	{IWL_PCI_DEVICE(0x423C, 0x1221, iwl5150_agn_cfg)}, /* Mini Card */
 	{IWL_PCI_DEVICE(0x423C, 0x1321, iwl5150_agn_cfg)}, /* Half Mini Card */
+	{IWL_PCI_DEVICE(0x423C, 0x1326, iwl5150_abg_cfg)}, /* Half Mini Card */
 
 	{IWL_PCI_DEVICE(0x423D, 0x1211, iwl5150_agn_cfg)}, /* Mini Card */
 	{IWL_PCI_DEVICE(0x423D, 0x1311, iwl5150_agn_cfg)}, /* Half Mini Card */
diff --git a/drivers/net/wireless/iwlwifi/pcie/rx.c b/drivers/net/wireless/iwlwifi/pcie/rx.c
index fd848cd..f600e68 100644
--- a/drivers/net/wireless/iwlwifi/pcie/rx.c
+++ b/drivers/net/wireless/iwlwifi/pcie/rx.c
@@ -888,6 +888,14 @@ irqreturn_t iwl_pcie_irq_handler(int irq, void *dev_id)
 
 		iwl_op_mode_hw_rf_kill(trans->op_mode, hw_rfkill);
 		if (hw_rfkill) {
+			/*
+			 * Clear the interrupt in APMG if the NIC is going down.
+			 * Note that when the NIC exits RFkill (else branch), we
+			 * can't access prph and the NIC will be reset in
+			 * start_hw anyway.
+			 */
+			iwl_write_prph(trans, APMG_RTC_INT_STT_REG,
+				       APMG_RTC_INT_STT_RFKILL);
 			set_bit(STATUS_RFKILL, &trans_pcie->status);
 			if (test_and_clear_bit(STATUS_HCMD_ACTIVE,
 					       &trans_pcie->status))
diff --git a/drivers/net/wireless/iwlwifi/pcie/trans.c b/drivers/net/wireless/iwlwifi/pcie/trans.c
index 826c156..96cfcdd 100644
--- a/drivers/net/wireless/iwlwifi/pcie/trans.c
+++ b/drivers/net/wireless/iwlwifi/pcie/trans.c
@@ -670,6 +670,11 @@ static int iwl_trans_pcie_start_hw(struct iwl_trans *trans)
 		return err;
 	}
 
+	/* Reset the entire device */
+	iwl_set_bit(trans, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET);
+
+	usleep_range(10, 15);
+
 	iwl_pcie_apm_init(trans);
 
 	/* From now on, the op_mode will be kept updated about RF kill state */
diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c
index ef5fa89..89459db 100644
--- a/drivers/net/wireless/mwifiex/cfg80211.c
+++ b/drivers/net/wireless/mwifiex/cfg80211.c
@@ -1716,9 +1716,9 @@ mwifiex_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
 	struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
 	int ret;
 
-	if (priv->bss_mode != NL80211_IFTYPE_STATION) {
+	if (GET_BSS_ROLE(priv) != MWIFIEX_BSS_ROLE_STA) {
 		wiphy_err(wiphy,
-			  "%s: reject infra assoc request in non-STA mode\n",
+			  "%s: reject infra assoc request in non-STA role\n",
 			  dev->name);
 		return -EINVAL;
 	}
diff --git a/drivers/net/wireless/mwifiex/cfp.c b/drivers/net/wireless/mwifiex/cfp.c
index 988552d..5178c46 100644
--- a/drivers/net/wireless/mwifiex/cfp.c
+++ b/drivers/net/wireless/mwifiex/cfp.c
@@ -415,7 +415,8 @@ u32 mwifiex_get_supported_rates(struct mwifiex_private *priv, u8 *rates)
 	u32 k = 0;
 	struct mwifiex_adapter *adapter = priv->adapter;
 
-	if (priv->bss_mode == NL80211_IFTYPE_STATION) {
+	if (priv->bss_mode == NL80211_IFTYPE_STATION ||
+	    priv->bss_mode == NL80211_IFTYPE_P2P_CLIENT) {
 		switch (adapter->config_bands) {
 		case BAND_B:
 			dev_dbg(adapter->dev, "info: infra band=%d "
diff --git a/drivers/net/wireless/mwifiex/join.c b/drivers/net/wireless/mwifiex/join.c
index 1c8a771..12e7781 100644
--- a/drivers/net/wireless/mwifiex/join.c
+++ b/drivers/net/wireless/mwifiex/join.c
@@ -1291,8 +1291,10 @@ int mwifiex_associate(struct mwifiex_private *priv,
 {
 	u8 current_bssid[ETH_ALEN];
 
-	/* Return error if the adapter or table entry is not marked as infra */
-	if ((priv->bss_mode != NL80211_IFTYPE_STATION) ||
+	/* Return error if the adapter is not STA role or table entry
+	 * is not marked as infra.
+	 */
+	if ((GET_BSS_ROLE(priv) != MWIFIEX_BSS_ROLE_STA) ||
 	    (bss_desc->bss_mode != NL80211_IFTYPE_STATION))
 		return -1;
 
diff --git a/drivers/net/wireless/mwifiex/sdio.c b/drivers/net/wireless/mwifiex/sdio.c
index 5ef49f2..09185c9 100644
--- a/drivers/net/wireless/mwifiex/sdio.c
+++ b/drivers/net/wireless/mwifiex/sdio.c
@@ -1639,8 +1639,8 @@ static int mwifiex_sdio_host_to_card(struct mwifiex_adapter *adapter,
 	/* Allocate buffer and copy payload */
 	blk_size = MWIFIEX_SDIO_BLOCK_SIZE;
 	buf_block_len = (pkt_len + blk_size - 1) / blk_size;
-	*(u16 *) &payload[0] = (u16) pkt_len;
-	*(u16 *) &payload[2] = type;
+	*(__le16 *)&payload[0] = cpu_to_le16((u16)pkt_len);
+	*(__le16 *)&payload[2] = cpu_to_le16(type);
 
 	/*
 	 * This is SDIO specific header
diff --git a/drivers/net/wireless/mwifiex/sta_ioctl.c b/drivers/net/wireless/mwifiex/sta_ioctl.c
index 206c3e0..8af97ab 100644
--- a/drivers/net/wireless/mwifiex/sta_ioctl.c
+++ b/drivers/net/wireless/mwifiex/sta_ioctl.c
@@ -257,10 +257,10 @@ int mwifiex_bss_start(struct mwifiex_private *priv, struct cfg80211_bss *bss,
 			goto done;
 	}
 
-	if (priv->bss_mode == NL80211_IFTYPE_STATION) {
+	if (priv->bss_mode == NL80211_IFTYPE_STATION ||
+	    priv->bss_mode == NL80211_IFTYPE_P2P_CLIENT) {
 		u8 config_bands;
 
-		/* Infra mode */
 		ret = mwifiex_deauthenticate(priv, NULL);
 		if (ret)
 			goto done;
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c
index 6c0a91f..aa95c6c 100644
--- a/drivers/net/wireless/rt2x00/rt2x00queue.c
+++ b/drivers/net/wireless/rt2x00/rt2x00queue.c
@@ -936,13 +936,8 @@ void rt2x00queue_index_inc(struct queue_entry *entry, enum queue_index index)
 	spin_unlock_irqrestore(&queue->index_lock, irqflags);
 }
 
-void rt2x00queue_pause_queue(struct data_queue *queue)
+void rt2x00queue_pause_queue_nocheck(struct data_queue *queue)
 {
-	if (!test_bit(DEVICE_STATE_PRESENT, &queue->rt2x00dev->flags) ||
-	    !test_bit(QUEUE_STARTED, &queue->flags) ||
-	    test_and_set_bit(QUEUE_PAUSED, &queue->flags))
-		return;
-
 	switch (queue->qid) {
 	case QID_AC_VO:
 	case QID_AC_VI:
@@ -958,6 +953,15 @@ void rt2x00queue_pause_queue(struct data_queue *queue)
 		break;
 	}
 }
+void rt2x00queue_pause_queue(struct data_queue *queue)
+{
+	if (!test_bit(DEVICE_STATE_PRESENT, &queue->rt2x00dev->flags) ||
+	    !test_bit(QUEUE_STARTED, &queue->flags) ||
+	    test_and_set_bit(QUEUE_PAUSED, &queue->flags))
+		return;
+
+	rt2x00queue_pause_queue_nocheck(queue);
+}
 EXPORT_SYMBOL_GPL(rt2x00queue_pause_queue);
 
 void rt2x00queue_unpause_queue(struct data_queue *queue)
@@ -1019,7 +1023,7 @@ void rt2x00queue_stop_queue(struct data_queue *queue)
 		return;
 	}
 
-	rt2x00queue_pause_queue(queue);
+	rt2x00queue_pause_queue_nocheck(queue);
 
 	queue->rt2x00dev->ops->lib->stop_queue(queue);
 
diff --git a/include/net/nfc/hci.h b/include/net/nfc/hci.h
index 0af851c..b64b7bc 100644
--- a/include/net/nfc/hci.h
+++ b/include/net/nfc/hci.h
@@ -59,7 +59,7 @@ struct nfc_hci_ops {
 			      struct nfc_target *target);
 	int (*event_received)(struct nfc_hci_dev *hdev, u8 gate, u8 event,
 			      struct sk_buff *skb);
-	int (*fw_upload)(struct nfc_hci_dev *hdev, const char *firmware_name);
+	int (*fw_download)(struct nfc_hci_dev *hdev, const char *firmware_name);
 	int (*discover_se)(struct nfc_hci_dev *dev);
 	int (*enable_se)(struct nfc_hci_dev *dev, u32 se_idx);
 	int (*disable_se)(struct nfc_hci_dev *dev, u32 se_idx);
diff --git a/include/net/nfc/nfc.h b/include/net/nfc/nfc.h
index 0e353f1..5f286b7 100644
--- a/include/net/nfc/nfc.h
+++ b/include/net/nfc/nfc.h
@@ -68,7 +68,7 @@ struct nfc_ops {
 			     void *cb_context);
 	int (*tm_send)(struct nfc_dev *dev, struct sk_buff *skb);
 	int (*check_presence)(struct nfc_dev *dev, struct nfc_target *target);
-	int (*fw_upload)(struct nfc_dev *dev, const char *firmware_name);
+	int (*fw_download)(struct nfc_dev *dev, const char *firmware_name);
 
 	/* Secure Element API */
 	int (*discover_se)(struct nfc_dev *dev);
@@ -127,7 +127,7 @@ struct nfc_dev {
 	int targets_generation;
 	struct device dev;
 	bool dev_up;
-	bool fw_upload_in_progress;
+	bool fw_download_in_progress;
 	u8 rf_mode;
 	bool polling;
 	struct nfc_target *active_target;
diff --git a/include/uapi/linux/nfc.h b/include/uapi/linux/nfc.h
index caed0f3..8137dd8 100644
--- a/include/uapi/linux/nfc.h
+++ b/include/uapi/linux/nfc.h
@@ -69,8 +69,8 @@
  *	starting a poll from a device which has a secure element enabled means
  *	we want to do SE based card emulation.
  * @NFC_CMD_DISABLE_SE: Disable the physical link to a specific secure element.
- * @NFC_CMD_FW_UPLOAD: Request to Load/flash firmware, or event to inform that
- *	some firmware was loaded
+ * @NFC_CMD_FW_DOWNLOAD: Request to Load/flash firmware, or event to inform
+ *	that some firmware was loaded
  */
 enum nfc_commands {
 	NFC_CMD_UNSPEC,
@@ -94,7 +94,7 @@ enum nfc_commands {
 	NFC_CMD_DISABLE_SE,
 	NFC_CMD_LLC_SDREQ,
 	NFC_EVENT_LLC_SDRES,
-	NFC_CMD_FW_UPLOAD,
+	NFC_CMD_FW_DOWNLOAD,
 	NFC_EVENT_SE_ADDED,
 	NFC_EVENT_SE_REMOVED,
 /* private: internal use only */
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index e3a3499..cc27297 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -513,7 +513,10 @@ static void hci_init2_req(struct hci_request *req, unsigned long opt)
 
 	hci_setup_event_mask(req);
 
-	if (hdev->hci_ver > BLUETOOTH_VER_1_1)
+	/* AVM Berlin (31), aka "BlueFRITZ!", doesn't support the read
+	 * local supported commands HCI command.
+	 */
+	if (hdev->manufacturer != 31 && hdev->hci_ver > BLUETOOTH_VER_1_1)
 		hci_req_add(req, HCI_OP_READ_LOCAL_COMMANDS, 0, NULL);
 
 	if (lmp_ssp_capable(hdev)) {
@@ -2165,10 +2168,6 @@ int hci_register_dev(struct hci_dev *hdev)
 
 	BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus);
 
-	write_lock(&hci_dev_list_lock);
-	list_add(&hdev->list, &hci_dev_list);
-	write_unlock(&hci_dev_list_lock);
-
 	hdev->workqueue = alloc_workqueue("%s", WQ_HIGHPRI | WQ_UNBOUND |
 					  WQ_MEM_RECLAIM, 1, hdev->name);
 	if (!hdev->workqueue) {
@@ -2203,6 +2202,10 @@ int hci_register_dev(struct hci_dev *hdev)
 	if (hdev->dev_type != HCI_AMP)
 		set_bit(HCI_AUTO_OFF, &hdev->dev_flags);
 
+	write_lock(&hci_dev_list_lock);
+	list_add(&hdev->list, &hci_dev_list);
+	write_unlock(&hci_dev_list_lock);
+
 	hci_notify(hdev, HCI_DEV_REG);
 	hci_dev_hold(hdev);
 
@@ -2215,9 +2218,6 @@ err_wqueue:
 	destroy_workqueue(hdev->req_workqueue);
 err:
 	ida_simple_remove(&hci_index_ida, hdev->id);
-	write_lock(&hci_dev_list_lock);
-	list_del(&hdev->list);
-	write_unlock(&hci_dev_list_lock);
 
 	return error;
 }
@@ -3399,8 +3399,16 @@ void hci_req_cmd_complete(struct hci_dev *hdev, u16 opcode, u8 status)
 	 */
 	if (hdev->sent_cmd) {
 		req_complete = bt_cb(hdev->sent_cmd)->req.complete;
-		if (req_complete)
+
+		if (req_complete) {
+			/* We must set the complete callback to NULL to
+			 * avoid calling the callback more than once if
+			 * this function gets called again.
+			 */
+			bt_cb(hdev->sent_cmd)->req.complete = NULL;
+
 			goto call_complete;
+		}
 	}
 
 	/* Remove all pending commands belonging to this request */
diff --git a/net/mac80211/mesh_ps.c b/net/mac80211/mesh_ps.c
index 3b7bfc0..22290a9 100644
--- a/net/mac80211/mesh_ps.c
+++ b/net/mac80211/mesh_ps.c
@@ -229,6 +229,10 @@ void ieee80211_mps_sta_status_update(struct sta_info *sta)
 	enum nl80211_mesh_power_mode pm;
 	bool do_buffer;
 
+	/* For non-assoc STA, prevent buffering or frame transmission */
+	if (sta->sta_state < IEEE80211_STA_ASSOC)
+		return;
+
 	/*
 	 * use peer-specific power mode if peering is established and the
 	 * peer's power mode is known
diff --git a/net/mac80211/pm.c b/net/mac80211/pm.c
index 7fc5d0d..3401262 100644
--- a/net/mac80211/pm.c
+++ b/net/mac80211/pm.c
@@ -99,10 +99,13 @@ int __ieee80211_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan)
 	}
 	mutex_unlock(&local->sta_mtx);
 
-	/* remove all interfaces */
+	/* remove all interfaces that were created in the driver */
 	list_for_each_entry(sdata, &local->interfaces, list) {
-		if (!ieee80211_sdata_running(sdata))
+		if (!ieee80211_sdata_running(sdata) ||
+		    sdata->vif.type == NL80211_IFTYPE_AP_VLAN ||
+		    sdata->vif.type == NL80211_IFTYPE_MONITOR)
 			continue;
+
 		drv_remove_interface(local, sdata);
 	}
 
diff --git a/net/nfc/core.c b/net/nfc/core.c
index dc96a83..1d074dd 100644
--- a/net/nfc/core.c
+++ b/net/nfc/core.c
@@ -44,7 +44,7 @@ DEFINE_MUTEX(nfc_devlist_mutex);
 /* NFC device ID bitmap */
 static DEFINE_IDA(nfc_index_ida);
 
-int nfc_fw_upload(struct nfc_dev *dev, const char *firmware_name)
+int nfc_fw_download(struct nfc_dev *dev, const char *firmware_name)
 {
 	int rc = 0;
 
@@ -62,28 +62,28 @@ int nfc_fw_upload(struct nfc_dev *dev, const char *firmware_name)
 		goto error;
 	}
 
-	if (!dev->ops->fw_upload) {
+	if (!dev->ops->fw_download) {
 		rc = -EOPNOTSUPP;
 		goto error;
 	}
 
-	dev->fw_upload_in_progress = true;
-	rc = dev->ops->fw_upload(dev, firmware_name);
+	dev->fw_download_in_progress = true;
+	rc = dev->ops->fw_download(dev, firmware_name);
 	if (rc)
-		dev->fw_upload_in_progress = false;
+		dev->fw_download_in_progress = false;
 
 error:
 	device_unlock(&dev->dev);
 	return rc;
 }
 
-int nfc_fw_upload_done(struct nfc_dev *dev, const char *firmware_name)
+int nfc_fw_download_done(struct nfc_dev *dev, const char *firmware_name)
 {
-	dev->fw_upload_in_progress = false;
+	dev->fw_download_in_progress = false;
 
-	return nfc_genl_fw_upload_done(dev, firmware_name);
+	return nfc_genl_fw_download_done(dev, firmware_name);
 }
-EXPORT_SYMBOL(nfc_fw_upload_done);
+EXPORT_SYMBOL(nfc_fw_download_done);
 
 /**
  * nfc_dev_up - turn on the NFC device
@@ -110,7 +110,7 @@ int nfc_dev_up(struct nfc_dev *dev)
 		goto error;
 	}
 
-	if (dev->fw_upload_in_progress) {
+	if (dev->fw_download_in_progress) {
 		rc = -EBUSY;
 		goto error;
 	}
diff --git a/net/nfc/hci/core.c b/net/nfc/hci/core.c
index 7b1c186..fe66908 100644
--- a/net/nfc/hci/core.c
+++ b/net/nfc/hci/core.c
@@ -809,14 +809,14 @@ static void nfc_hci_recv_from_llc(struct nfc_hci_dev *hdev, struct sk_buff *skb)
 	}
 }
 
-static int hci_fw_upload(struct nfc_dev *nfc_dev, const char *firmware_name)
+static int hci_fw_download(struct nfc_dev *nfc_dev, const char *firmware_name)
 {
 	struct nfc_hci_dev *hdev = nfc_get_drvdata(nfc_dev);
 
-	if (!hdev->ops->fw_upload)
+	if (!hdev->ops->fw_download)
 		return -ENOTSUPP;
 
-	return hdev->ops->fw_upload(hdev, firmware_name);
+	return hdev->ops->fw_download(hdev, firmware_name);
 }
 
 static struct nfc_ops hci_nfc_ops = {
@@ -831,7 +831,7 @@ static struct nfc_ops hci_nfc_ops = {
 	.im_transceive = hci_transceive,
 	.tm_send = hci_tm_send,
 	.check_presence = hci_check_presence,
-	.fw_upload = hci_fw_upload,
+	.fw_download = hci_fw_download,
 	.discover_se = hci_discover_se,
 	.enable_se = hci_enable_se,
 	.disable_se = hci_disable_se,
diff --git a/net/nfc/nci/Kconfig b/net/nfc/nci/Kconfig
index 2a24160..a4f1e42 100644
--- a/net/nfc/nci/Kconfig
+++ b/net/nfc/nci/Kconfig
@@ -11,6 +11,7 @@ config NFC_NCI
 
 config NFC_NCI_SPI
 	depends on NFC_NCI && SPI
+	select CRC_CCITT
 	bool "NCI over SPI protocol support"
 	default n
 	help
diff --git a/net/nfc/netlink.c b/net/nfc/netlink.c
index b05ad90..f16fd59 100644
--- a/net/nfc/netlink.c
+++ b/net/nfc/netlink.c
@@ -1089,7 +1089,7 @@ exit:
 	return rc;
 }
 
-static int nfc_genl_fw_upload(struct sk_buff *skb, struct genl_info *info)
+static int nfc_genl_fw_download(struct sk_buff *skb, struct genl_info *info)
 {
 	struct nfc_dev *dev;
 	int rc;
@@ -1108,13 +1108,13 @@ static int nfc_genl_fw_upload(struct sk_buff *skb, struct genl_info *info)
 	nla_strlcpy(firmware_name, info->attrs[NFC_ATTR_FIRMWARE_NAME],
 		    sizeof(firmware_name));
 
-	rc = nfc_fw_upload(dev, firmware_name);
+	rc = nfc_fw_download(dev, firmware_name);
 
 	nfc_put_device(dev);
 	return rc;
 }
 
-int nfc_genl_fw_upload_done(struct nfc_dev *dev, const char *firmware_name)
+int nfc_genl_fw_download_done(struct nfc_dev *dev, const char *firmware_name)
 {
 	struct sk_buff *msg;
 	void *hdr;
@@ -1124,7 +1124,7 @@ int nfc_genl_fw_upload_done(struct nfc_dev *dev, const char *firmware_name)
 		return -ENOMEM;
 
 	hdr = genlmsg_put(msg, 0, 0, &nfc_genl_family, 0,
-			  NFC_CMD_FW_UPLOAD);
+			  NFC_CMD_FW_DOWNLOAD);
 	if (!hdr)
 		goto free_msg;
 
@@ -1251,8 +1251,8 @@ static struct genl_ops nfc_genl_ops[] = {
 		.policy = nfc_genl_policy,
 	},
 	{
-		.cmd = NFC_CMD_FW_UPLOAD,
-		.doit = nfc_genl_fw_upload,
+		.cmd = NFC_CMD_FW_DOWNLOAD,
+		.doit = nfc_genl_fw_download,
 		.policy = nfc_genl_policy,
 	},
 	{
diff --git a/net/nfc/nfc.h b/net/nfc/nfc.h
index ee85a1f..820a785 100644
--- a/net/nfc/nfc.h
+++ b/net/nfc/nfc.h
@@ -123,10 +123,10 @@ static inline void nfc_device_iter_exit(struct class_dev_iter *iter)
 	class_dev_iter_exit(iter);
 }
 
-int nfc_fw_upload(struct nfc_dev *dev, const char *firmware_name);
-int nfc_genl_fw_upload_done(struct nfc_dev *dev, const char *firmware_name);
+int nfc_fw_download(struct nfc_dev *dev, const char *firmware_name);
+int nfc_genl_fw_download_done(struct nfc_dev *dev, const char *firmware_name);
 
-int nfc_fw_upload_done(struct nfc_dev *dev, const char *firmware_name);
+int nfc_fw_download_done(struct nfc_dev *dev, const char *firmware_name);
 
 int nfc_dev_up(struct nfc_dev *dev);
 
diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index 5a950f3..de06d5d 100644
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -2247,10 +2247,13 @@ int reg_device_uevent(struct device *dev, struct kobj_uevent_env *env)
 
 void wiphy_regulatory_register(struct wiphy *wiphy)
 {
+	struct regulatory_request *lr;
+
 	if (!reg_dev_ignore_cell_hint(wiphy))
 		reg_num_devs_support_basehint++;
 
-	wiphy_update_regulatory(wiphy, NL80211_REGDOM_SET_BY_CORE);
+	lr = get_last_request();
+	wiphy_update_regulatory(wiphy, lr->initiator);
 }
 
 void wiphy_regulatory_deregister(struct wiphy *wiphy)
-- 
John W. Linville		Someday the world will need a hero, and you
linville@tuxdriver.com			might be all we have.  Be ready.

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

^ permalink raw reply related

* Re: cross compile backports with LTIB
From: Jonathan Bagg @ 2013-08-01 19:12 UTC (permalink / raw)
  To: backports; +Cc: Solomon Peachy, linux-wireless
In-Reply-To: <20130801174749.GC10904@shaftnet.org>

On 13-08-01 01:47 PM, Solomon Peachy wrote:
> On Thu, Aug 01, 2013 at 12:37:33PM -0400, Jonathan Bagg wrote:
>> I've been cross compiling compat-wireless and now I'm trying
>> backports.  It looks like conf.c and zconf.tab.c are being compiled
>> as arm and then the build process is trying to run conf on my x86
>> host.  Results using the below make parameters I was using for
>> compat-wireless......
Learned some things....Problem was LTIB (ltib = Freescale tool) 
environment.  Outside of LTIB, backports cross compiles fine.  To get 
backports happy in LTIB need to use UNSPOOF/SPOOF_PATH to switch between 
host and cross environment....

%Build
export PATH=$UNSPOOF_PATH

make defconfig-cw1200 make prefix=%{_prefix} 
CROSS_COMPILE=${TOOLCHAIN_PATH}/bin/${TOOLCHAIN_PREFIX} ARCH=$LINTARCH 
KLIB=${TOP}/rootfs/lib/modules/%{kversion} KLIB_BUILD=${TOP}/rpm/BUILD/linux

export PATH=$SPOOF_PATH

make prefix=%{_prefix} 
CROSS_COMPILE=${TOOLCHAIN_PATH}/bin/${TOOLCHAIN_PREFIX} ARCH=$LINTARCH 
KLIB=${TOP}/rootfs/lib/modules/%{kversion} KLIB_BUILD=${TOP}/rpm/BUILD/linux

Jon

> Howdy.  :)
>
> (btw, I'm CC'ing the backports mailing list, which is a better place to
>   ask these sorts of questions)
>
> I found that the backports cross-compile process worked much the same
> way as building compat-wireless.  This is what I'm doing currently in my
> build script:  (This is using a backports package generated last night
> using the backports git HEAD code with the cw1200 driver integrated)
>
>   set -a
>   CROSS_COMPILE=${CROSS_COMPILE}
>   ARCH=${TARGET_CPU}
>   KLIB_BUILD=${DEV_PATH}/${LINUX_DIR}
>   KLIB=${TARGET_ROOT_ON_HOST}
>   set +a
>   make oldconfig  # menuconfig worked here too
>   make
>   make install
>
> That said, the 'make install' target isn't currently sane for
> cross-builds due to the bacport_firmware_install script not respecting
> prefixes.  I just commented that script (and a few others like initrd
> updates) out of the Makefiles, and I had a successful build/install.
>
>   - Solomon


-- 
Jonathan Bagg
Software Developer
NAD Electronics | Lenbrook Industries Limited
633 Granite Court, Pickering, Ontario, Canada L1W 3K1 | 905-831-0799 ext 4478 | http://www.nadelectronics.com


^ permalink raw reply

* Re: cross compile backports?
From: Luis R. Rodriguez @ 2013-08-01 19:03 UTC (permalink / raw)
  To: Solomon Peachy; +Cc: Jonathan Bagg, linux-wireless, backports@vger.kernel.org
In-Reply-To: <20130801174749.GC10904@shaftnet.org>

On Thu, Aug 1, 2013 at 10:47 AM, Solomon Peachy <pizza@shaftnet.org> wrote:
> On Thu, Aug 01, 2013 at 12:37:33PM -0400, Jonathan Bagg wrote:
>> I've been cross compiling compat-wireless and now I'm trying
>> backports.  It looks like conf.c and zconf.tab.c are being compiled
>> as arm and then the build process is trying to run conf on my x86
>> host.  Results using the below make parameters I was using for
>> compat-wireless......
>
> Howdy.  :)
>
> (btw, I'm CC'ing the backports mailing list, which is a better place to
>  ask these sorts of questions)
>
> I found that the backports cross-compile process worked much the same
> way as building compat-wireless.  This is what I'm doing currently in my
> build script:  (This is using a backports package generated last night
> using the backports git HEAD code with the cw1200 driver integrated)
>
>  set -a
>  CROSS_COMPILE=${CROSS_COMPILE}
>  ARCH=${TARGET_CPU}
>  KLIB_BUILD=${DEV_PATH}/${LINUX_DIR}
>  KLIB=${TARGET_ROOT_ON_HOST}
>  set +a
>  make oldconfig  # menuconfig worked here too
>  make
>  make install
>
> That said, the 'make install' target isn't currently sane for
> cross-builds due to the bacport_firmware_install script not respecting
> prefixes.  I just commented that script (and a few others like initrd
> updates) out of the Makefiles, and I had a successful build/install.

Thanks, now:

https://backports.wiki.kernel.org/index.php/Documentation#Cross_compiling

Patches welcome to help improve the cross compile install target.

  Luis

^ permalink raw reply

* Re: cross compile backports?
From: Solomon Peachy @ 2013-08-01 17:47 UTC (permalink / raw)
  To: Jonathan Bagg; +Cc: linux-wireless, backports
In-Reply-To: <51FA8ECD.7070401@lenbrook.com>

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

On Thu, Aug 01, 2013 at 12:37:33PM -0400, Jonathan Bagg wrote:
> I've been cross compiling compat-wireless and now I'm trying
> backports.  It looks like conf.c and zconf.tab.c are being compiled
> as arm and then the build process is trying to run conf on my x86
> host.  Results using the below make parameters I was using for
> compat-wireless......

Howdy.  :)

(btw, I'm CC'ing the backports mailing list, which is a better place to 
 ask these sorts of questions)

I found that the backports cross-compile process worked much the same 
way as building compat-wireless.  This is what I'm doing currently in my 
build script:  (This is using a backports package generated last night 
using the backports git HEAD code with the cw1200 driver integrated)

 set -a
 CROSS_COMPILE=${CROSS_COMPILE} 
 ARCH=${TARGET_CPU}
 KLIB_BUILD=${DEV_PATH}/${LINUX_DIR}
 KLIB=${TARGET_ROOT_ON_HOST}
 set +a
 make oldconfig  # menuconfig worked here too
 make
 make install

That said, the 'make install' target isn't currently sane for 
cross-builds due to the bacport_firmware_install script not respecting 
prefixes.  I just commented that script (and a few others like initrd 
updates) out of the Makefiles, and I had a successful build/install.

 - Solomon
-- 
Solomon Peachy        		       pizza at shaftnet dot org
Delray Beach, FL                          ^^ (email/xmpp) ^^
Quidquid latine dictum sit, altum viditur.

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

^ permalink raw reply

* Re: [PATCH 0/8] include/net: next set of extern removals
From: Joe Perches @ 2013-08-01 17:05 UTC (permalink / raw)
  To: Eric Dumazet
  Cc: David Howells, netdev, linux-hams, linux-wireless, linux-kernel,
	linux-afs
In-Reply-To: <1375375486.10515.170.camel@edumazet-glaptop>

On Thu, 2013-08-01 at 09:44 -0700, Eric Dumazet wrote:
> 'extern' in include files are an easy way to have a grep friendly
> marker, and otherwise are harmless.
> 
> _You_ believe they are useless, other people think otherwise.

I believe I wrote superfluous.

> I learned C 30 years ago, and using 'extern' is quite natural for me.

I think I've got a few years headstart on you.
All that means is we're both relatively old...

cheers, Joe


^ permalink raw reply

* cross compile backports?
From: Jonathan Bagg @ 2013-08-01 16:37 UTC (permalink / raw)
  To: linux-wireless
In-Reply-To: <1375370826-1387-1-git-send-email-sujith@msujith.org>

Hello,

I've been cross compiling compat-wireless and now I'm trying backports.  
It looks like conf.c and zconf.tab.c are being compiled as arm and then 
the build process is trying to run conf on my x86 host.  Results using 
the below make parameters I was using for compat-wireless......

Generating local configuration database from kernel ... done.
gcc -Wall -Wmissing-prototypes -Wstrict-prototypes -O2 
-fomit-frame-pointer   -c -o conf.o conf.c
gcc -Wall -Wmissing-prototypes -Wstrict-prototypes -O2 
-fomit-frame-pointer   -c -o zconf.tab.o zconf.tab.c
gcc   conf.o zconf.tab.o   -o conf
./kconf/conf: ./kconf/conf: cannot execute binary file

There must be a way to build conf as x86 and the actual drivers as arm 
without butchering the makefile? I've been cross compiling 
compat-wireless with....

make    prefix=%{_prefix}
CROSS_COMPILE=/opt/freescale/usr/local/gcc-4.6.2-glibc-2.13-linaro-multilib-2011.12/fsl-linaro-toolchain/bin/arm-none-linux-gnueabi- 
\
     ARCH=arm \
     KLIB=/media/hdd1/ltibs/n100/rootfs/lib/modules/%{kversion} \
     KLIB_BUILD=/media/hdd1/ltibs/n100/rpm/BUILD/linux

Jon

^ permalink raw reply

* Re: [PATCH 0/8] include/net: next set of extern removals
From: Eric Dumazet @ 2013-08-01 16:44 UTC (permalink / raw)
  To: Joe Perches
  Cc: David Howells, netdev, linux-hams, linux-wireless, linux-kernel,
	linux-afs
In-Reply-To: <1375374560.2034.52.camel@joe-AO722>

On Thu, 2013-08-01 at 09:29 -0700, Joe Perches wrote:
> On Thu, 2013-08-01 at 13:04 +0100, David Howells wrote:
> > Joe Perches <joe@perches.com> wrote:
> > > Standardize on no extern use on function prototypes
> > Can we please standardise on _having_ externs on function prototypes?
> 
> Why?
> 
> What value is there in using extern for function prototypes?
> 
> Your argument for "picking out at a glance"
> https://lkml.org/lkml/2013/8/1/237
> really doesn't make sense to me.
> 
> Basically, anything with parentheses that's not a #define
> is an extern.
> 
> Exceptions exist for extern function pointers, but those
> are fairly unusual anyway.  Outside of netfilter,
> extern function pointers are only used about a dozen times
> total in the kernel tree.
> 
> So, please provide some examples supporting your view.

My main concern about these changes is they are a huge pain for us
doing bug tracking, rebases and backports. "git blame" and friends will
show lot of noise.

'extern' in include files are an easy way to have a grep friendly
marker, and otherwise are harmless.

_You_ believe they are useless, other people think otherwise.

I really don't see any value doing all these changes on existing code,
apart from adding noise to netdev and adding more work for us.

Using rules for new code is fine, but changing 10 years old code is
really not worth the pain.

I learned C 30 years ago, and using 'extern' is quite natural for me.

It's crazy the time we have to spend on these issues, while we have so
many bugs to fix in the kernel.




^ permalink raw reply

* Re: [PATCH 0/8] include/net: next set of extern removals
From: Joe Perches @ 2013-08-01 16:29 UTC (permalink / raw)
  To: David Howells; +Cc: netdev, linux-hams, linux-wireless, linux-kernel, linux-afs
In-Reply-To: <24958.1375358650@warthog.procyon.org.uk>

On Thu, 2013-08-01 at 13:04 +0100, David Howells wrote:
> Joe Perches <joe@perches.com> wrote:
> > Standardize on no extern use on function prototypes
> Can we please standardise on _having_ externs on function prototypes?

Why?

What value is there in using extern for function prototypes?

Your argument for "picking out at a glance"
https://lkml.org/lkml/2013/8/1/237
really doesn't make sense to me.

Basically, anything with parentheses that's not a #define
is an extern.

Exceptions exist for extern function pointers, but those
are fairly unusual anyway.  Outside of netfilter,
extern function pointers are only used about a dozen times
total in the kernel tree.

So, please provide some examples supporting your view.



^ permalink raw reply

* [[PATCHv2]rt2800usb: ampdu len] rt2800usb: update aggregation len
From: Sylvain ROGER RIEUNIER @ 2013-08-01 15:39 UTC (permalink / raw)
  To: linux-wireless; +Cc: users, Sylvain Roger Rieunier

From: Sylvain Roger Rieunier <sylvain.roger.rieunier@gmail.com>

I tried to read periodically TX_AGG_CNT registers on the rt2800usb driver.
I'had made USB synchronous and asynchronous read. But it's only reduces the
bandwidth.
Does anyone have an idea?


Signed-off-by: Sylvain ROGER RIEUNIER <sylvain.roger.rieunier@gmail.com>
---
 drivers/net/wireless/rt2x00/rt2800lib.c   |   69 ++++++++++++++++++++++
 drivers/net/wireless/rt2x00/rt2800usb.c   |   92 +++++++++++++++++++++++++++++
 drivers/net/wireless/rt2x00/rt2x00.h      |   28 +++++++++
 drivers/net/wireless/rt2x00/rt2x00debug.c |   66 +++++++++++++++++++++
 drivers/net/wireless/rt2x00/rt2x00dev.c   |    2 +
 drivers/net/wireless/rt2x00/rt2x00usb.c   |    2 +
 6 files changed, 259 insertions(+)

diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
index dedc3d4..0db45fb 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -1813,6 +1813,75 @@ void rt2800_config_ant(struct rt2x00_dev *rt2x00dev, struct antenna_setup *ant)
 }
 EXPORT_SYMBOL_GPL(rt2800_config_ant);
 
+void rt2800_update_aggr_stats(struct rt2x00_dev *rt2x00dev)
+{
+	u32 reg;
+	u32 all;
+	int i;
+
+	rt2800_register_read(rt2x00dev,TX_AGG_CNT, &reg);
+	rt2x00dev->aggr_stats.no_aggr =
+		rt2x00_get_field32(reg,TX_AGG_CNT_NON_AGG_TX_COUNT);
+	rt2x00dev->aggr_stats.all_aggr =
+		rt2x00_get_field32(reg,TX_AGG_CNT_AGG_TX_COUNT);
+
+	rt2800_register_read(rt2x00dev,TX_AGG_CNT0, &reg);
+	rt2x00dev->aggr_stats.ampduCount[0] =
+		rt2x00_get_field32(reg,TX_AGG_CNT0_AGG_SIZE_1_COUNT);
+	rt2x00dev->aggr_stats.ampduCount[1] =
+		rt2x00_get_field32(reg,TX_AGG_CNT0_AGG_SIZE_2_COUNT);
+
+	rt2800_register_read(rt2x00dev,TX_AGG_CNT1, &reg);
+	rt2x00dev->aggr_stats.ampduCount[2] =
+		rt2x00_get_field32(reg,TX_AGG_CNT1_AGG_SIZE_3_COUNT);
+	rt2x00dev->aggr_stats.ampduCount[3] =
+		rt2x00_get_field32(reg,TX_AGG_CNT1_AGG_SIZE_4_COUNT);
+
+	rt2800_register_read(rt2x00dev,TX_AGG_CNT2, &reg);
+	rt2x00dev->aggr_stats.ampduCount[4] =
+		rt2x00_get_field32(reg,TX_AGG_CNT2_AGG_SIZE_5_COUNT);
+	rt2x00dev->aggr_stats.ampduCount[5] =
+		rt2x00_get_field32(reg,TX_AGG_CNT2_AGG_SIZE_6_COUNT);
+
+	rt2800_register_read(rt2x00dev,TX_AGG_CNT3, &reg);
+	rt2x00dev->aggr_stats.ampduCount[6] =
+		rt2x00_get_field32(reg,TX_AGG_CNT3_AGG_SIZE_7_COUNT);
+	rt2x00dev->aggr_stats.ampduCount[7] =
+		rt2x00_get_field32(reg,TX_AGG_CNT3_AGG_SIZE_8_COUNT);
+
+	rt2800_register_read(rt2x00dev,TX_AGG_CNT4, &reg);
+	rt2x00dev->aggr_stats.ampduCount[8] =
+		rt2x00_get_field32(reg,TX_AGG_CNT4_AGG_SIZE_9_COUNT);
+	rt2x00dev->aggr_stats.ampduCount[9] =
+		rt2x00_get_field32(reg,TX_AGG_CNT4_AGG_SIZE_10_COUNT);
+
+	rt2800_register_read(rt2x00dev,TX_AGG_CNT5, &reg);
+	rt2x00dev->aggr_stats.ampduCount[10] =
+		rt2x00_get_field32(reg,TX_AGG_CNT5_AGG_SIZE_11_COUNT);
+	rt2x00dev->aggr_stats.ampduCount[11] =
+		rt2x00_get_field32(reg,TX_AGG_CNT5_AGG_SIZE_12_COUNT);
+
+	rt2800_register_read(rt2x00dev,TX_AGG_CNT6, &reg);
+	rt2x00dev->aggr_stats.ampduCount[12] =
+		rt2x00_get_field32(reg,TX_AGG_CNT6_AGG_SIZE_13_COUNT);
+	rt2x00dev->aggr_stats.ampduCount[13] =
+		rt2x00_get_field32(reg,TX_AGG_CNT6_AGG_SIZE_14_COUNT);
+
+	rt2800_register_read(rt2x00dev,TX_AGG_CNT7, &reg);
+	rt2x00dev->aggr_stats.ampduCount[14] =
+		rt2x00_get_field32(reg,TX_AGG_CNT7_AGG_SIZE_15_COUNT);
+	rt2x00dev->aggr_stats.ampduCount[15] =
+		rt2x00_get_field32(reg,TX_AGG_CNT7_AGG_SIZE_16_COUNT);
+
+	all = rt2x00dev->aggr_stats.no_aggr +
+		rt2x00dev->aggr_stats.all_aggr;
+
+	for( i = 0; i < 16 ; i++)
+		rt2x00dev->aggr_stats.ampduRatio[i] =
+			((rt2x00dev->aggr_stats.ampduCount[i] * 100) / all);
+}
+EXPORT_SYMBOL_GPL(rt2800_update_aggr_stats);
+
 static void rt2800_config_lna_gain(struct rt2x00_dev *rt2x00dev,
 				   struct rt2x00lib_conf *libconf)
 {
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c
index fc9efdf..6ca9cdb 100644
--- a/drivers/net/wireless/rt2x00/rt2800usb.c
+++ b/drivers/net/wireless/rt2x00/rt2800usb.c
@@ -225,6 +225,79 @@ static enum hrtimer_restart rt2800usb_tx_sta_fifo_timeout(struct hrtimer *timer)
 	return HRTIMER_NORESTART;
 }
 
+
+
+static bool rt2800usb_tx_agg_cnt_read_completed(struct rt2x00_dev *rt2x00dev,
+					   int urb_status, u32 reg)
+{
+
+	if (urb_status) {
+		WARNING(rt2x00dev, "TX status read failed %d\n", urb_status);
+		return false;
+	}
+
+	if(rt2x00dev->aggr_stats.cnt == 0) {
+		rt2x00dev->aggr_stats.no_aggr =
+			rt2x00_get_field32(reg,TX_AGG_CNT_NON_AGG_TX_COUNT);
+		rt2x00dev->aggr_stats.all_aggr =
+			rt2x00_get_field32(reg,TX_AGG_CNT_AGG_TX_COUNT);
+	} else {
+		unsigned int tmp = (rt2x00dev->aggr_stats.cnt - 1)*2;
+
+		rt2x00dev->aggr_stats.ampduCount[tmp] =
+		rt2x00_get_field32(reg,TX_AGG_CNT0_AGG_SIZE_1_COUNT);
+		rt2x00dev->aggr_stats.ampduCount[tmp+1] =
+		rt2x00_get_field32(reg,TX_AGG_CNT0_AGG_SIZE_2_COUNT);
+	}
+
+	if(rt2x00dev->aggr_stats.cnt == 9) {
+		rt2x00dev->aggr_stats.cnt = 0;
+		clear_bit(TX_AGG_TIMER, &rt2x00dev->aggr_stats.flags);
+	} else {
+		rt2x00dev->aggr_stats.cnt++;
+		/* Read next TX_AGG_CNT register after 1 ms */
+		hrtimer_start(&rt2x00dev->txaggcnt_timer,
+			      ktime_set(0, 1000000), HRTIMER_MODE_REL);
+	}
+
+	 return true;
+}
+
+static enum hrtimer_restart rt2800usb_tx_agg_cnt_timeout(struct hrtimer *timer)
+{
+	struct rt2x00_dev *rt2x00dev =
+	    container_of(timer, struct rt2x00_dev, txaggcnt_timer);
+	unsigned int offset;
+
+	offset = TX_AGG_CNT + rt2x00dev->aggr_stats.cnt*4;
+	rt2x00usb_register_read_async(rt2x00dev,offset,
+				      rt2800usb_tx_agg_cnt_read_completed);
+
+	return HRTIMER_NORESTART;
+}
+
+static void rt2800usb_async_read_tx_agg_cnt(struct rt2x00_dev *rt2x00dev)
+{
+
+	if (test_and_set_bit(TX_AGG_TIMER, &rt2x00dev->aggr_stats.flags))
+		return;
+
+	/* Read TX_AGG_CNT register after 1 ms */
+	hrtimer_start(&rt2x00dev->txaggcnt_timer, ktime_set(0, 1000000),
+		      HRTIMER_MODE_REL);
+}
+
+static void rt2800usb_timer_txagg(unsigned long data)
+{
+	struct rt2x00_dev *rt2x00dev = (struct rt2x00_dev *)data;
+
+	if (!test_bit(TX_AGG_TIMER, &rt2x00dev->aggr_stats.flags))
+		rt2800usb_async_read_tx_agg_cnt(rt2x00dev);
+
+	rt2x00dev->txagg_timer.expires += 5000;
+	add_timer(&rt2x00dev->txagg_timer);
+}
+
 /*
  * Firmware functions
  */
@@ -750,6 +823,7 @@ static int rt2800usb_read_eeprom(struct rt2x00_dev *rt2x00dev)
 static int rt2800usb_probe_hw(struct rt2x00_dev *rt2x00dev)
 {
 	int retval;
+	unsigned long j = jiffies;
 
 	retval = rt2800_probe_hw(rt2x00dev);
 	if (retval)
@@ -765,6 +839,24 @@ static int rt2800usb_probe_hw(struct rt2x00_dev *rt2x00dev)
 	 */
 	PREPARE_WORK(&rt2x00dev->txdone_work, rt2800usb_work_txdone);
 
+	/*
+	 * Set txaggcnt timer function. for usb async read
+	 */
+	rt2x00dev->txaggcnt_timer.function = rt2800usb_tx_agg_cnt_timeout;
+
+	/*
+	 * Set txagg timer function. periodic read
+	 */
+	clear_bit(TX_AGG_TIMER, &rt2x00dev->aggr_stats.flags);
+	rt2x00dev->aggr_stats.cnt = 0;
+	init_timer(&rt2x00dev->txagg_timer);
+	rt2x00dev->txagg_timer.function = rt2800usb_timer_txagg;
+	rt2x00dev->txagg_timer.data = (unsigned long)rt2x00dev;
+
+	j = jiffies;
+	rt2x00dev->txagg_timer.expires = j + 5000;
+	add_timer(&rt2x00dev->txagg_timer);
+
 	return 0;
 }
 
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h
index fe4c572..b6ae9f3 100644
--- a/drivers/net/wireless/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/rt2x00/rt2x00.h
@@ -637,6 +637,7 @@ struct rt2x00lib_ops {
 			struct ieee80211_sta *sta);
 	int (*sta_remove) (struct rt2x00_dev *rt2x00dev,
 			   int wcid);
+	void (*update_aggr_stats) (struct rt2x00_dev *rt2x00dev);
 };
 
 /*
@@ -733,6 +734,24 @@ enum {
 	NUM_IF_COMB,
 };
 
+#define RT2X00_AGGR_CNT_MAX 16
+
+/*
+ * rt2x00 aggregation state flags
+ */
+enum rt2x00_agg_state_flags {
+	TX_AGG_TIMER,
+};
+struct rt2x00_aggr_stats {
+	unsigned long flags;
+	unsigned int cnt;
+	u32 all_aggr;
+	u32 no_aggr;
+	u32 ampduCount[RT2X00_AGGR_CNT_MAX];
+	u32 ampduRatio[RT2X00_AGGR_CNT_MAX];
+};
+
+
 /*
  * rt2x00 device structure.
  */
@@ -764,6 +783,8 @@ struct rt2x00_dev {
 	enum ieee80211_band curr_band;
 	int curr_freq;
 
+	struct rt2x00_aggr_stats aggr_stats;
+
 	/*
 	 * If enabled, the debugfs interface structures
 	 * required for deregistration of debugfs.
@@ -984,6 +1005,13 @@ struct rt2x00_dev {
 	struct hrtimer txstatus_timer;
 
 	/*
+	 * Timer to ensure tx aggregation counter reports are read (rt2800usb).
+	 */
+	struct hrtimer txaggcnt_timer;
+
+	struct timer_list txagg_timer;
+
+	/*
 	 * Tasklet for processing tx status reports (rt2800pci).
 	 */
 	struct tasklet_struct txstatus_tasklet;
diff --git a/drivers/net/wireless/rt2x00/rt2x00debug.c b/drivers/net/wireless/rt2x00/rt2x00debug.c
index fe7a7f6..c41d5a8 100644
--- a/drivers/net/wireless/rt2x00/rt2x00debug.c
+++ b/drivers/net/wireless/rt2x00/rt2x00debug.c
@@ -75,6 +75,7 @@ struct rt2x00debug_intf {
 	 *     - frame dump file
 	 *     - queue stats file
 	 *     - crypto stats file
+	 *     - aggr stats file
 	 */
 	struct dentry *driver_folder;
 	struct dentry *driver_entry;
@@ -96,6 +97,7 @@ struct rt2x00debug_intf {
 	struct dentry *queue_frame_dump_entry;
 	struct dentry *queue_stats_entry;
 	struct dentry *crypto_stats_entry;
+	struct dentry *aggr_stats_entry;
 
 	/*
 	 * The frame dump file only allows a single reader,
@@ -589,6 +591,63 @@ static const struct file_operations rt2x00debug_fop_cap_flags = {
 	.llseek		= default_llseek,
 };
 
+
+static ssize_t rt2x00debug_read_aggr_stats(struct file *file,
+					  char __user *buf,
+					  size_t length,
+					  loff_t *offset)
+{
+	struct rt2x00debug_intf *intf =	file->private_data;
+	struct rt2x00_dev *rt2x00dev = intf->rt2x00dev;
+	size_t size;
+	char *data;
+	char *temp;
+	int i;
+
+	if (*offset)
+		return 0;
+
+	data = kzalloc(17 * MAX_LINE_LENGTH, GFP_KERNEL);
+	if (!data)
+		return 0;
+
+	temp = data;
+	temp += sprintf(temp, "all aggr(%u) no agg(%u) \n",
+		       rt2x00dev->aggr_stats.all_aggr,
+		       rt2x00dev->aggr_stats.no_aggr);
+
+	for (i = 0; i < 15 ; i++) {
+		temp += sprintf(temp, "%u AMPDU cnt(%u), ratio(%u)\n", (i+1),
+		       rt2x00dev->aggr_stats.ampduCount[i],
+		       rt2x00dev->aggr_stats.ampduRatio[i]);
+	}
+
+	temp += sprintf(temp, "16 or up AMPDU cnt(%u), ratio(%u)\n",
+			rt2x00dev->aggr_stats.ampduCount[i],
+			rt2x00dev->aggr_stats.ampduRatio[i]);
+
+	size = strlen(data);
+	size = min(size, length);
+
+	if (copy_to_user(buf, data, size)) {
+		kfree(data);
+		return -EFAULT;
+	}
+
+	kfree(data);
+
+	*offset += size;
+	return size;
+}
+
+static const struct file_operations rt2x00debug_fop_aggr_stats = {
+	.owner		= THIS_MODULE,
+	.read		= rt2x00debug_read_aggr_stats,
+	.open		= rt2x00debug_file_open,
+	.release	= rt2x00debug_file_release,
+	.llseek		= default_llseek,
+};
+
 static struct dentry *rt2x00debug_create_file_driver(const char *name,
 						     struct rt2x00debug_intf
 						     *intf,
@@ -694,6 +753,12 @@ void rt2x00debug_register(struct rt2x00_dev *rt2x00dev)
 	if (IS_ERR(intf->cap_flags) || !intf->cap_flags)
 		goto exit;
 
+	intf->aggr_stats_entry = debugfs_create_file("aggr_stats", S_IRUSR,
+					      intf->driver_folder, intf,
+					      &rt2x00debug_fop_aggr_stats);
+	if (IS_ERR(intf->aggr_stats_entry) || !intf->aggr_stats_entry)
+		goto exit;
+
 	intf->register_folder =
 	    debugfs_create_dir("register", intf->driver_folder);
 	if (IS_ERR(intf->register_folder) || !intf->register_folder)
@@ -794,6 +859,7 @@ void rt2x00debug_deregister(struct rt2x00_dev *rt2x00dev)
 	debugfs_remove(intf->chipset_entry);
 	debugfs_remove(intf->driver_entry);
 	debugfs_remove(intf->driver_folder);
+	debugfs_remove(intf->aggr_stats_entry);
 	kfree(intf->chipset_blob.data);
 	kfree(intf->driver_blob.data);
 	kfree(intf);
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c
index b16521e..935e8b1 100644
--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
@@ -1403,7 +1403,9 @@ void rt2x00lib_remove_dev(struct rt2x00_dev *rt2x00dev)
 	cancel_delayed_work_sync(&rt2x00dev->autowakeup_work);
 	cancel_work_sync(&rt2x00dev->sleep_work);
 	if (rt2x00_is_usb(rt2x00dev)) {
+		hrtimer_cancel(&rt2x00dev->txaggcnt_timer);
 		hrtimer_cancel(&rt2x00dev->txstatus_timer);
+		del_timer(&rt2x00dev->txagg_timer);
 		cancel_work_sync(&rt2x00dev->rxdone_work);
 		cancel_work_sync(&rt2x00dev->txdone_work);
 	}
diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c
index 8828987..0529f69 100644
--- a/drivers/net/wireless/rt2x00/rt2x00usb.c
+++ b/drivers/net/wireless/rt2x00/rt2x00usb.c
@@ -813,6 +813,8 @@ int rt2x00usb_probe(struct usb_interface *usb_intf,
 	INIT_WORK(&rt2x00dev->txdone_work, rt2x00usb_work_txdone);
 	hrtimer_init(&rt2x00dev->txstatus_timer, CLOCK_MONOTONIC,
 		     HRTIMER_MODE_REL);
+	hrtimer_init(&rt2x00dev->txaggcnt_timer, CLOCK_MONOTONIC,
+		     HRTIMER_MODE_REL);
 
 	retval = rt2x00usb_alloc_reg(rt2x00dev);
 	if (retval)
-- 
1.7.10.4


^ permalink raw reply related

* [PATCH v2 8/8] ath9k: Add statistics for antenna diversity
From: Sujith Manoharan @ 2013-08-01 15:27 UTC (permalink / raw)
  To: John Linville; +Cc: linux-wireless
In-Reply-To: <1375338204-2021-8-git-send-email-sujith@msujith.org>

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

Signed-off-by: Sujith Manoharan <c_manoha@qca.qualcomm.com>
---
 drivers/net/wireless/ath/ath9k/antenna.c | 18 ++++---
 drivers/net/wireless/ath/ath9k/debug.c   | 85 ++++++++++++++++++++++++++------
 drivers/net/wireless/ath/ath9k/debug.h   | 20 +++++---
 3 files changed, 95 insertions(+), 28 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/antenna.c b/drivers/net/wireless/ath/ath9k/antenna.c
index 42f3b87..391d557 100644
--- a/drivers/net/wireless/ath/ath9k/antenna.c
+++ b/drivers/net/wireless/ath/ath9k/antenna.c
@@ -734,15 +734,18 @@ void ath_ant_comb_scan(struct ath_softc *sc, struct ath_rx_status *rs)
 		antcomb->main_total_rssi += main_rssi;
 		antcomb->alt_total_rssi  += alt_rssi;
 
-		if (main_ant_conf == rx_ant_conf) {
+		if (main_ant_conf == rx_ant_conf)
 			antcomb->main_recv_cnt++;
-			ANT_STAT_INC(ANT_MAIN, recv_cnt);
-			ANT_LNA_INC(ANT_MAIN, rx_ant_conf);
-		} else {
+		else
 			antcomb->alt_recv_cnt++;
-			ANT_STAT_INC(ANT_ALT, recv_cnt);
-			ANT_LNA_INC(ANT_ALT, rx_ant_conf);
-		}
+	}
+
+	if (main_ant_conf == rx_ant_conf) {
+		ANT_STAT_INC(ANT_MAIN, recv_cnt);
+		ANT_LNA_INC(ANT_MAIN, rx_ant_conf);
+	} else {
+		ANT_STAT_INC(ANT_ALT, recv_cnt);
+		ANT_LNA_INC(ANT_ALT, rx_ant_conf);
 	}
 
 	/* Short scan check */
@@ -821,6 +824,7 @@ void ath_ant_comb_scan(struct ath_softc *sc, struct ath_rx_status *rs)
 div_comb_done:
 	ath_ant_div_conf_fast_divbias(&div_ant_conf, antcomb, alt_ratio);
 	ath9k_hw_antdiv_comb_conf_set(sc->sc_ah, &div_ant_conf);
+	ath9k_debug_stat_ant(sc, &div_ant_conf, main_rssi_avg, alt_rssi_avg);
 
 	antcomb->scan_start_time = jiffies;
 	antcomb->total_pkt_count = 0;
diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c
index 56cbe5d..a43bd8c 100644
--- a/drivers/net/wireless/ath/ath9k/debug.c
+++ b/drivers/net/wireless/ath/ath9k/debug.c
@@ -321,6 +321,20 @@ static const struct file_operations fops_bt_ant_diversity = {
 	.llseek = default_llseek,
 };
 
+void ath9k_debug_stat_ant(struct ath_softc *sc,
+			  struct ath_hw_antcomb_conf *div_ant_conf,
+			  int main_rssi_avg, int alt_rssi_avg)
+{
+	struct ath_antenna_stats *as_main = &sc->debug.stats.ant_stats[ANT_MAIN];
+	struct ath_antenna_stats *as_alt = &sc->debug.stats.ant_stats[ANT_ALT];
+
+	as_main->lna_attempt_cnt[div_ant_conf->main_lna_conf]++;
+	as_alt->lna_attempt_cnt[div_ant_conf->alt_lna_conf]++;
+
+	as_main->rssi_avg = main_rssi_avg;
+	as_alt->rssi_avg = alt_rssi_avg;
+}
+
 static ssize_t read_file_antenna_diversity(struct file *file,
 					   char __user *user_buf,
 					   size_t count, loff_t *ppos)
@@ -330,9 +344,14 @@ static ssize_t read_file_antenna_diversity(struct file *file,
 	struct ath9k_hw_capabilities *pCap = &ah->caps;
 	struct ath_antenna_stats *as_main = &sc->debug.stats.ant_stats[ANT_MAIN];
 	struct ath_antenna_stats *as_alt = &sc->debug.stats.ant_stats[ANT_ALT];
+	struct ath_hw_antcomb_conf div_ant_conf;
 	unsigned int len = 0, size = 1024;
 	ssize_t retval = 0;
 	char *buf;
+	char *lna_conf_str[4] = {"LNA1_MINUS_LNA2",
+				 "LNA2",
+				 "LNA1",
+				 "LNA1_PLUS_LNA2"};
 
 	buf = kzalloc(size, GFP_KERNEL);
 	if (buf == NULL)
@@ -344,28 +363,66 @@ static ssize_t read_file_antenna_diversity(struct file *file,
 		goto exit;
 	}
 
+	ath9k_ps_wakeup(sc);
+	ath9k_hw_antdiv_comb_conf_get(ah, &div_ant_conf);
+	len += snprintf(buf + len, size - len, "Current MAIN config : %s\n",
+			lna_conf_str[div_ant_conf.main_lna_conf]);
+	len += snprintf(buf + len, size - len, "Current ALT config  : %s\n",
+			lna_conf_str[div_ant_conf.alt_lna_conf]);
+	len += snprintf(buf + len, size - len, "Average MAIN RSSI   : %d\n",
+			as_main->rssi_avg);
+	len += snprintf(buf + len, size - len, "Average ALT RSSI    : %d\n\n",
+			as_alt->rssi_avg);
+	ath9k_ps_restore(sc);
+
+	len += snprintf(buf + len, size - len, "Packet Receive Cnt:\n");
+	len += snprintf(buf + len, size - len, "-------------------\n");
+
 	len += snprintf(buf + len, size - len, "%30s%15s\n",
 			"MAIN", "ALT");
-	len += snprintf(buf + len, size - len, "%-15s%15d%15d\n",
-			"RECV CNT",
+	len += snprintf(buf + len, size - len, "%-14s:%15d%15d\n",
+			"TOTAL COUNT",
 			as_main->recv_cnt,
 			as_alt->recv_cnt);
-	len += snprintf(buf + len, size - len, "%-15s%15d%15d\n",
+	len += snprintf(buf + len, size - len, "%-14s:%15d%15d\n",
+			"LNA1",
+			as_main->lna_recv_cnt[ATH_ANT_DIV_COMB_LNA1],
+			as_alt->lna_recv_cnt[ATH_ANT_DIV_COMB_LNA1]);
+	len += snprintf(buf + len, size - len, "%-14s:%15d%15d\n",
+			"LNA2",
+			as_main->lna_recv_cnt[ATH_ANT_DIV_COMB_LNA2],
+			as_alt->lna_recv_cnt[ATH_ANT_DIV_COMB_LNA2]);
+	len += snprintf(buf + len, size - len, "%-14s:%15d%15d\n",
+			"LNA1 + LNA2",
+			as_main->lna_recv_cnt[ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2],
+			as_alt->lna_recv_cnt[ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2]);
+	len += snprintf(buf + len, size - len, "%-14s:%15d%15d\n",
+			"LNA1 - LNA2",
+			as_main->lna_recv_cnt[ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2],
+			as_alt->lna_recv_cnt[ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2]);
+
+	len += snprintf(buf + len, size - len, "\nLNA Config Attempts:\n");
+	len += snprintf(buf + len, size - len, "--------------------\n");
+
+	len += snprintf(buf + len, size - len, "%30s%15s\n",
+			"MAIN", "ALT");
+	len += snprintf(buf + len, size - len, "%-14s:%15d%15d\n",
 			"LNA1",
-			as_main->lna_config_cnt[ATH_ANT_DIV_COMB_LNA1],
-			as_alt->lna_config_cnt[ATH_ANT_DIV_COMB_LNA1]);
-	len += snprintf(buf + len, size - len, "%-15s%15d%15d\n",
+			as_main->lna_attempt_cnt[ATH_ANT_DIV_COMB_LNA1],
+			as_alt->lna_attempt_cnt[ATH_ANT_DIV_COMB_LNA1]);
+	len += snprintf(buf + len, size - len, "%-14s:%15d%15d\n",
 			"LNA2",
-			as_main->lna_config_cnt[ATH_ANT_DIV_COMB_LNA2],
-			as_alt->lna_config_cnt[ATH_ANT_DIV_COMB_LNA2]);
-	len += snprintf(buf + len, size - len, "%-15s%15d%15d\n",
+			as_main->lna_attempt_cnt[ATH_ANT_DIV_COMB_LNA2],
+			as_alt->lna_attempt_cnt[ATH_ANT_DIV_COMB_LNA2]);
+	len += snprintf(buf + len, size - len, "%-14s:%15d%15d\n",
 			"LNA1 + LNA2",
-			as_main->lna_config_cnt[ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2],
-			as_alt->lna_config_cnt[ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2]);
-	len += snprintf(buf + len, size - len, "%-15s%15d%15d\n",
+			as_main->lna_attempt_cnt[ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2],
+			as_alt->lna_attempt_cnt[ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2]);
+	len += snprintf(buf + len, size - len, "%-14s:%15d%15d\n",
 			"LNA1 - LNA2",
-			as_main->lna_config_cnt[ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2],
-			as_alt->lna_config_cnt[ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2]);
+			as_main->lna_attempt_cnt[ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2],
+			as_alt->lna_attempt_cnt[ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2]);
+
 exit:
 	if (len > size)
 		len = size;
diff --git a/drivers/net/wireless/ath/ath9k/debug.h b/drivers/net/wireless/ath/ath9k/debug.h
index a879e45..01c5c6a 100644
--- a/drivers/net/wireless/ath/ath9k/debug.h
+++ b/drivers/net/wireless/ath/ath9k/debug.h
@@ -29,7 +29,7 @@ struct fft_sample_tlv;
 #define TX_STAT_INC(q, c) sc->debug.stats.txstats[q].c++
 #define RESET_STAT_INC(sc, type) sc->debug.stats.reset[type]++
 #define ANT_STAT_INC(i, c) sc->debug.stats.ant_stats[i].c++
-#define ANT_LNA_INC(i, c) sc->debug.stats.ant_stats[i].lna_config_cnt[c]++;
+#define ANT_LNA_INC(i, c) sc->debug.stats.ant_stats[i].lna_recv_cnt[c]++;
 #else
 #define TX_STAT_INC(q, c) do { } while (0)
 #define RESET_STAT_INC(sc, type) do { } while (0)
@@ -252,7 +252,9 @@ struct ath_rx_stats {
 
 struct ath_antenna_stats {
 	u32 recv_cnt;
-	u32 lna_config_cnt[4];
+	u32 rssi_avg;
+	u32 lna_recv_cnt[4];
+	u32 lna_attempt_cnt[4];
 };
 
 struct ath_stats {
@@ -294,10 +296,11 @@ void ath9k_sta_remove_debugfs(struct ieee80211_hw *hw,
 			      struct ieee80211_vif *vif,
 			      struct ieee80211_sta *sta,
 			      struct dentry *dir);
-
 void ath_debug_send_fft_sample(struct ath_softc *sc,
 			       struct fft_sample_tlv *fft_sample);
-
+void ath9k_debug_stat_ant(struct ath_softc *sc,
+			  struct ath_hw_antcomb_conf *div_ant_conf,
+			  int main_rssi_avg, int alt_rssi_avg);
 #else
 
 #define RX_STAT_INC(c) /* NOP */
@@ -310,12 +313,10 @@ static inline int ath9k_init_debug(struct ath_hw *ah)
 static inline void ath9k_deinit_debug(struct ath_softc *sc)
 {
 }
-
 static inline void ath_debug_stat_interrupt(struct ath_softc *sc,
 					    enum ath9k_int status)
 {
 }
-
 static inline void ath_debug_stat_tx(struct ath_softc *sc,
 				     struct ath_buf *bf,
 				     struct ath_tx_status *ts,
@@ -323,11 +324,16 @@ static inline void ath_debug_stat_tx(struct ath_softc *sc,
 				     unsigned int flags)
 {
 }
-
 static inline void ath_debug_stat_rx(struct ath_softc *sc,
 				     struct ath_rx_status *rs)
 {
 }
+static inline void ath9k_debug_stat_ant(struct ath_softc *sc,
+					struct ath_hw_antcomb_conf *div_ant_conf,
+					int main_rssi_avg, int alt_rssi_avg)
+{
+
+}
 
 #endif /* CONFIG_ATH9K_DEBUGFS */
 
-- 
1.8.3.4


^ permalink raw reply related

* Re: [PATCHv5 0/4] add master channel switch announcement support
From: Johannes Berg @ 2013-08-01 15:01 UTC (permalink / raw)
  To: Simon Wunderlich; +Cc: linux-wireless, Mathias Kretschmer, Simon Wunderlich
In-Reply-To: <1373551749-5107-1-git-send-email-siwu@hrz.tu-chemnitz.de>

On Thu, 2013-07-11 at 16:09 +0200, Simon Wunderlich wrote:
> This is the 5th edition of the CSA support patch series. This patchset adds
> generic channel switch support for AP. This is required for DFS operation
> (e.g. Wi-Fi Alliance requires this for 802.11h certification). This will also
> be required for IBSS-DFS later.

Applied 1-3 with some changes (merging 2/3 and small fixes)

johannes


^ permalink raw reply

* [[PATCHv2]rt2800usb: ampdu len] rt2800usb: update aggregation len
From: Sylvain ROGER RIEUNIER @ 2013-08-01 14:42 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, users, Sylvain Roger Rieunier

From: Sylvain Roger Rieunier <sylvain.roger.rieunier@gmail.com>

I tried to read periodically TX_AGG_CNT registers on the rt2800usb driver.
I'had made USB synchronous and asynchronous read. But it's only reduces the
bandwidth.
Does anyone have an idea?


Signed-off-by: Sylvain ROGER RIEUNIER <sylvain.roger.rieunier@gmail.com>
---
 drivers/net/wireless/rt2x00/rt2800lib.c   |   69 ++++++++++++++++++++++
 drivers/net/wireless/rt2x00/rt2800usb.c   |   92 +++++++++++++++++++++++++++++
 drivers/net/wireless/rt2x00/rt2x00.h      |   28 +++++++++
 drivers/net/wireless/rt2x00/rt2x00debug.c |   66 +++++++++++++++++++++
 drivers/net/wireless/rt2x00/rt2x00dev.c   |    2 +
 drivers/net/wireless/rt2x00/rt2x00usb.c   |    2 +
 6 files changed, 259 insertions(+)

diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
index dedc3d4..0db45fb 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -1813,6 +1813,75 @@ void rt2800_config_ant(struct rt2x00_dev *rt2x00dev, struct antenna_setup *ant)
 }
 EXPORT_SYMBOL_GPL(rt2800_config_ant);
 
+void rt2800_update_aggr_stats(struct rt2x00_dev *rt2x00dev)
+{
+	u32 reg;
+	u32 all;
+	int i;
+
+	rt2800_register_read(rt2x00dev,TX_AGG_CNT, &reg);
+	rt2x00dev->aggr_stats.no_aggr =
+		rt2x00_get_field32(reg,TX_AGG_CNT_NON_AGG_TX_COUNT);
+	rt2x00dev->aggr_stats.all_aggr =
+		rt2x00_get_field32(reg,TX_AGG_CNT_AGG_TX_COUNT);
+
+	rt2800_register_read(rt2x00dev,TX_AGG_CNT0, &reg);
+	rt2x00dev->aggr_stats.ampduCount[0] =
+		rt2x00_get_field32(reg,TX_AGG_CNT0_AGG_SIZE_1_COUNT);
+	rt2x00dev->aggr_stats.ampduCount[1] =
+		rt2x00_get_field32(reg,TX_AGG_CNT0_AGG_SIZE_2_COUNT);
+
+	rt2800_register_read(rt2x00dev,TX_AGG_CNT1, &reg);
+	rt2x00dev->aggr_stats.ampduCount[2] =
+		rt2x00_get_field32(reg,TX_AGG_CNT1_AGG_SIZE_3_COUNT);
+	rt2x00dev->aggr_stats.ampduCount[3] =
+		rt2x00_get_field32(reg,TX_AGG_CNT1_AGG_SIZE_4_COUNT);
+
+	rt2800_register_read(rt2x00dev,TX_AGG_CNT2, &reg);
+	rt2x00dev->aggr_stats.ampduCount[4] =
+		rt2x00_get_field32(reg,TX_AGG_CNT2_AGG_SIZE_5_COUNT);
+	rt2x00dev->aggr_stats.ampduCount[5] =
+		rt2x00_get_field32(reg,TX_AGG_CNT2_AGG_SIZE_6_COUNT);
+
+	rt2800_register_read(rt2x00dev,TX_AGG_CNT3, &reg);
+	rt2x00dev->aggr_stats.ampduCount[6] =
+		rt2x00_get_field32(reg,TX_AGG_CNT3_AGG_SIZE_7_COUNT);
+	rt2x00dev->aggr_stats.ampduCount[7] =
+		rt2x00_get_field32(reg,TX_AGG_CNT3_AGG_SIZE_8_COUNT);
+
+	rt2800_register_read(rt2x00dev,TX_AGG_CNT4, &reg);
+	rt2x00dev->aggr_stats.ampduCount[8] =
+		rt2x00_get_field32(reg,TX_AGG_CNT4_AGG_SIZE_9_COUNT);
+	rt2x00dev->aggr_stats.ampduCount[9] =
+		rt2x00_get_field32(reg,TX_AGG_CNT4_AGG_SIZE_10_COUNT);
+
+	rt2800_register_read(rt2x00dev,TX_AGG_CNT5, &reg);
+	rt2x00dev->aggr_stats.ampduCount[10] =
+		rt2x00_get_field32(reg,TX_AGG_CNT5_AGG_SIZE_11_COUNT);
+	rt2x00dev->aggr_stats.ampduCount[11] =
+		rt2x00_get_field32(reg,TX_AGG_CNT5_AGG_SIZE_12_COUNT);
+
+	rt2800_register_read(rt2x00dev,TX_AGG_CNT6, &reg);
+	rt2x00dev->aggr_stats.ampduCount[12] =
+		rt2x00_get_field32(reg,TX_AGG_CNT6_AGG_SIZE_13_COUNT);
+	rt2x00dev->aggr_stats.ampduCount[13] =
+		rt2x00_get_field32(reg,TX_AGG_CNT6_AGG_SIZE_14_COUNT);
+
+	rt2800_register_read(rt2x00dev,TX_AGG_CNT7, &reg);
+	rt2x00dev->aggr_stats.ampduCount[14] =
+		rt2x00_get_field32(reg,TX_AGG_CNT7_AGG_SIZE_15_COUNT);
+	rt2x00dev->aggr_stats.ampduCount[15] =
+		rt2x00_get_field32(reg,TX_AGG_CNT7_AGG_SIZE_16_COUNT);
+
+	all = rt2x00dev->aggr_stats.no_aggr +
+		rt2x00dev->aggr_stats.all_aggr;
+
+	for( i = 0; i < 16 ; i++)
+		rt2x00dev->aggr_stats.ampduRatio[i] =
+			((rt2x00dev->aggr_stats.ampduCount[i] * 100) / all);
+}
+EXPORT_SYMBOL_GPL(rt2800_update_aggr_stats);
+
 static void rt2800_config_lna_gain(struct rt2x00_dev *rt2x00dev,
 				   struct rt2x00lib_conf *libconf)
 {
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c
index fc9efdf..6ca9cdb 100644
--- a/drivers/net/wireless/rt2x00/rt2800usb.c
+++ b/drivers/net/wireless/rt2x00/rt2800usb.c
@@ -225,6 +225,79 @@ static enum hrtimer_restart rt2800usb_tx_sta_fifo_timeout(struct hrtimer *timer)
 	return HRTIMER_NORESTART;
 }
 
+
+
+static bool rt2800usb_tx_agg_cnt_read_completed(struct rt2x00_dev *rt2x00dev,
+					   int urb_status, u32 reg)
+{
+
+	if (urb_status) {
+		WARNING(rt2x00dev, "TX status read failed %d\n", urb_status);
+		return false;
+	}
+
+	if(rt2x00dev->aggr_stats.cnt == 0) {
+		rt2x00dev->aggr_stats.no_aggr =
+			rt2x00_get_field32(reg,TX_AGG_CNT_NON_AGG_TX_COUNT);
+		rt2x00dev->aggr_stats.all_aggr =
+			rt2x00_get_field32(reg,TX_AGG_CNT_AGG_TX_COUNT);
+	} else {
+		unsigned int tmp = (rt2x00dev->aggr_stats.cnt - 1)*2;
+
+		rt2x00dev->aggr_stats.ampduCount[tmp] =
+		rt2x00_get_field32(reg,TX_AGG_CNT0_AGG_SIZE_1_COUNT);
+		rt2x00dev->aggr_stats.ampduCount[tmp+1] =
+		rt2x00_get_field32(reg,TX_AGG_CNT0_AGG_SIZE_2_COUNT);
+	}
+
+	if(rt2x00dev->aggr_stats.cnt == 9) {
+		rt2x00dev->aggr_stats.cnt = 0;
+		clear_bit(TX_AGG_TIMER, &rt2x00dev->aggr_stats.flags);
+	} else {
+		rt2x00dev->aggr_stats.cnt++;
+		/* Read next TX_AGG_CNT register after 1 ms */
+		hrtimer_start(&rt2x00dev->txaggcnt_timer,
+			      ktime_set(0, 1000000), HRTIMER_MODE_REL);
+	}
+
+	 return true;
+}
+
+static enum hrtimer_restart rt2800usb_tx_agg_cnt_timeout(struct hrtimer *timer)
+{
+	struct rt2x00_dev *rt2x00dev =
+	    container_of(timer, struct rt2x00_dev, txaggcnt_timer);
+	unsigned int offset;
+
+	offset = TX_AGG_CNT + rt2x00dev->aggr_stats.cnt*4;
+	rt2x00usb_register_read_async(rt2x00dev,offset,
+				      rt2800usb_tx_agg_cnt_read_completed);
+
+	return HRTIMER_NORESTART;
+}
+
+static void rt2800usb_async_read_tx_agg_cnt(struct rt2x00_dev *rt2x00dev)
+{
+
+	if (test_and_set_bit(TX_AGG_TIMER, &rt2x00dev->aggr_stats.flags))
+		return;
+
+	/* Read TX_AGG_CNT register after 1 ms */
+	hrtimer_start(&rt2x00dev->txaggcnt_timer, ktime_set(0, 1000000),
+		      HRTIMER_MODE_REL);
+}
+
+static void rt2800usb_timer_txagg(unsigned long data)
+{
+	struct rt2x00_dev *rt2x00dev = (struct rt2x00_dev *)data;
+
+	if (!test_bit(TX_AGG_TIMER, &rt2x00dev->aggr_stats.flags))
+		rt2800usb_async_read_tx_agg_cnt(rt2x00dev);
+
+	rt2x00dev->txagg_timer.expires += 5000;
+	add_timer(&rt2x00dev->txagg_timer);
+}
+
 /*
  * Firmware functions
  */
@@ -750,6 +823,7 @@ static int rt2800usb_read_eeprom(struct rt2x00_dev *rt2x00dev)
 static int rt2800usb_probe_hw(struct rt2x00_dev *rt2x00dev)
 {
 	int retval;
+	unsigned long j = jiffies;
 
 	retval = rt2800_probe_hw(rt2x00dev);
 	if (retval)
@@ -765,6 +839,24 @@ static int rt2800usb_probe_hw(struct rt2x00_dev *rt2x00dev)
 	 */
 	PREPARE_WORK(&rt2x00dev->txdone_work, rt2800usb_work_txdone);
 
+	/*
+	 * Set txaggcnt timer function. for usb async read
+	 */
+	rt2x00dev->txaggcnt_timer.function = rt2800usb_tx_agg_cnt_timeout;
+
+	/*
+	 * Set txagg timer function. periodic read
+	 */
+	clear_bit(TX_AGG_TIMER, &rt2x00dev->aggr_stats.flags);
+	rt2x00dev->aggr_stats.cnt = 0;
+	init_timer(&rt2x00dev->txagg_timer);
+	rt2x00dev->txagg_timer.function = rt2800usb_timer_txagg;
+	rt2x00dev->txagg_timer.data = (unsigned long)rt2x00dev;
+
+	j = jiffies;
+	rt2x00dev->txagg_timer.expires = j + 5000;
+	add_timer(&rt2x00dev->txagg_timer);
+
 	return 0;
 }
 
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h
index fe4c572..b6ae9f3 100644
--- a/drivers/net/wireless/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/rt2x00/rt2x00.h
@@ -637,6 +637,7 @@ struct rt2x00lib_ops {
 			struct ieee80211_sta *sta);
 	int (*sta_remove) (struct rt2x00_dev *rt2x00dev,
 			   int wcid);
+	void (*update_aggr_stats) (struct rt2x00_dev *rt2x00dev);
 };
 
 /*
@@ -733,6 +734,24 @@ enum {
 	NUM_IF_COMB,
 };
 
+#define RT2X00_AGGR_CNT_MAX 16
+
+/*
+ * rt2x00 aggregation state flags
+ */
+enum rt2x00_agg_state_flags {
+	TX_AGG_TIMER,
+};
+struct rt2x00_aggr_stats {
+	unsigned long flags;
+	unsigned int cnt;
+	u32 all_aggr;
+	u32 no_aggr;
+	u32 ampduCount[RT2X00_AGGR_CNT_MAX];
+	u32 ampduRatio[RT2X00_AGGR_CNT_MAX];
+};
+
+
 /*
  * rt2x00 device structure.
  */
@@ -764,6 +783,8 @@ struct rt2x00_dev {
 	enum ieee80211_band curr_band;
 	int curr_freq;
 
+	struct rt2x00_aggr_stats aggr_stats;
+
 	/*
 	 * If enabled, the debugfs interface structures
 	 * required for deregistration of debugfs.
@@ -984,6 +1005,13 @@ struct rt2x00_dev {
 	struct hrtimer txstatus_timer;
 
 	/*
+	 * Timer to ensure tx aggregation counter reports are read (rt2800usb).
+	 */
+	struct hrtimer txaggcnt_timer;
+
+	struct timer_list txagg_timer;
+
+	/*
 	 * Tasklet for processing tx status reports (rt2800pci).
 	 */
 	struct tasklet_struct txstatus_tasklet;
diff --git a/drivers/net/wireless/rt2x00/rt2x00debug.c b/drivers/net/wireless/rt2x00/rt2x00debug.c
index fe7a7f6..c41d5a8 100644
--- a/drivers/net/wireless/rt2x00/rt2x00debug.c
+++ b/drivers/net/wireless/rt2x00/rt2x00debug.c
@@ -75,6 +75,7 @@ struct rt2x00debug_intf {
 	 *     - frame dump file
 	 *     - queue stats file
 	 *     - crypto stats file
+	 *     - aggr stats file
 	 */
 	struct dentry *driver_folder;
 	struct dentry *driver_entry;
@@ -96,6 +97,7 @@ struct rt2x00debug_intf {
 	struct dentry *queue_frame_dump_entry;
 	struct dentry *queue_stats_entry;
 	struct dentry *crypto_stats_entry;
+	struct dentry *aggr_stats_entry;
 
 	/*
 	 * The frame dump file only allows a single reader,
@@ -589,6 +591,63 @@ static const struct file_operations rt2x00debug_fop_cap_flags = {
 	.llseek		= default_llseek,
 };
 
+
+static ssize_t rt2x00debug_read_aggr_stats(struct file *file,
+					  char __user *buf,
+					  size_t length,
+					  loff_t *offset)
+{
+	struct rt2x00debug_intf *intf =	file->private_data;
+	struct rt2x00_dev *rt2x00dev = intf->rt2x00dev;
+	size_t size;
+	char *data;
+	char *temp;
+	int i;
+
+	if (*offset)
+		return 0;
+
+	data = kzalloc(17 * MAX_LINE_LENGTH, GFP_KERNEL);
+	if (!data)
+		return 0;
+
+	temp = data;
+	temp += sprintf(temp, "all aggr(%u) no agg(%u) \n",
+		       rt2x00dev->aggr_stats.all_aggr,
+		       rt2x00dev->aggr_stats.no_aggr);
+
+	for (i = 0; i < 15 ; i++) {
+		temp += sprintf(temp, "%u AMPDU cnt(%u), ratio(%u)\n", (i+1),
+		       rt2x00dev->aggr_stats.ampduCount[i],
+		       rt2x00dev->aggr_stats.ampduRatio[i]);
+	}
+
+	temp += sprintf(temp, "16 or up AMPDU cnt(%u), ratio(%u)\n",
+			rt2x00dev->aggr_stats.ampduCount[i],
+			rt2x00dev->aggr_stats.ampduRatio[i]);
+
+	size = strlen(data);
+	size = min(size, length);
+
+	if (copy_to_user(buf, data, size)) {
+		kfree(data);
+		return -EFAULT;
+	}
+
+	kfree(data);
+
+	*offset += size;
+	return size;
+}
+
+static const struct file_operations rt2x00debug_fop_aggr_stats = {
+	.owner		= THIS_MODULE,
+	.read		= rt2x00debug_read_aggr_stats,
+	.open		= rt2x00debug_file_open,
+	.release	= rt2x00debug_file_release,
+	.llseek		= default_llseek,
+};
+
 static struct dentry *rt2x00debug_create_file_driver(const char *name,
 						     struct rt2x00debug_intf
 						     *intf,
@@ -694,6 +753,12 @@ void rt2x00debug_register(struct rt2x00_dev *rt2x00dev)
 	if (IS_ERR(intf->cap_flags) || !intf->cap_flags)
 		goto exit;
 
+	intf->aggr_stats_entry = debugfs_create_file("aggr_stats", S_IRUSR,
+					      intf->driver_folder, intf,
+					      &rt2x00debug_fop_aggr_stats);
+	if (IS_ERR(intf->aggr_stats_entry) || !intf->aggr_stats_entry)
+		goto exit;
+
 	intf->register_folder =
 	    debugfs_create_dir("register", intf->driver_folder);
 	if (IS_ERR(intf->register_folder) || !intf->register_folder)
@@ -794,6 +859,7 @@ void rt2x00debug_deregister(struct rt2x00_dev *rt2x00dev)
 	debugfs_remove(intf->chipset_entry);
 	debugfs_remove(intf->driver_entry);
 	debugfs_remove(intf->driver_folder);
+	debugfs_remove(intf->aggr_stats_entry);
 	kfree(intf->chipset_blob.data);
 	kfree(intf->driver_blob.data);
 	kfree(intf);
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c
index b16521e..935e8b1 100644
--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
@@ -1403,7 +1403,9 @@ void rt2x00lib_remove_dev(struct rt2x00_dev *rt2x00dev)
 	cancel_delayed_work_sync(&rt2x00dev->autowakeup_work);
 	cancel_work_sync(&rt2x00dev->sleep_work);
 	if (rt2x00_is_usb(rt2x00dev)) {
+		hrtimer_cancel(&rt2x00dev->txaggcnt_timer);
 		hrtimer_cancel(&rt2x00dev->txstatus_timer);
+		del_timer(&rt2x00dev->txagg_timer);
 		cancel_work_sync(&rt2x00dev->rxdone_work);
 		cancel_work_sync(&rt2x00dev->txdone_work);
 	}
diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c
index 8828987..0529f69 100644
--- a/drivers/net/wireless/rt2x00/rt2x00usb.c
+++ b/drivers/net/wireless/rt2x00/rt2x00usb.c
@@ -813,6 +813,8 @@ int rt2x00usb_probe(struct usb_interface *usb_intf,
 	INIT_WORK(&rt2x00dev->txdone_work, rt2x00usb_work_txdone);
 	hrtimer_init(&rt2x00dev->txstatus_timer, CLOCK_MONOTONIC,
 		     HRTIMER_MODE_REL);
+	hrtimer_init(&rt2x00dev->txaggcnt_timer, CLOCK_MONOTONIC,
+		     HRTIMER_MODE_REL);
 
 	retval = rt2x00usb_alloc_reg(rt2x00dev);
 	if (retval)
-- 
1.7.10.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