Linux wireless drivers development
 help / color / mirror / Atom feed
* [PATCH] ath9k: Fix TX poll work locking
From: Sujith Manoharan @ 2013-08-26  6:17 UTC (permalink / raw)
  To: John Linville; +Cc: linux-wireless

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

There is no need to call ath_txq_unlock_complete() in the
TX poll routine - frame completion is not done here,
so use ath_txq_unlock().

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

diff --git a/drivers/net/wireless/ath/ath9k/link.c b/drivers/net/wireless/ath/ath9k/link.c
index fff5d3c..2f831db 100644
--- a/drivers/net/wireless/ath/ath9k/link.c
+++ b/drivers/net/wireless/ath/ath9k/link.c
@@ -41,7 +41,7 @@ void ath_tx_complete_poll_work(struct work_struct *work)
 				txq->axq_tx_inprogress = true;
 			}
 		}
-		ath_txq_unlock_complete(sc, txq);
+		ath_txq_unlock(sc, txq);
 	}
 
 	if (needreset) {
-- 
1.8.3.4


^ permalink raw reply related

* Re: [PATCH] mac80211: implement STA CSA for drivers using channel contexts
From: Arik Nemtsov @ 2013-08-25 13:14 UTC (permalink / raw)
  To: Johannes Berg; +Cc: linux-wireless@vger.kernel.org
In-Reply-To: <1377266513.14021.37.camel@jlt4.sipsolutions.net>

On Fri, Aug 23, 2013 at 5:01 PM, Johannes Berg
<johannes@sipsolutions.net> wrote:
> On Fri, 2013-08-16 at 23:09 +0300, Arik Nemtsov wrote:
>
>> > Well, it can't. If you look carefully then the old chan_switch op
>> > behaviour is to let the driver switch, not switch in software
>> > afterwards.
>>
>> The right thing for chan_switch drivers would be not to call hw_config()..
>
> chan_switch? or chanctx?

both. the hw_config(channel) is meaningless for chanctx drivers. The
legacy code for op_chan_switch drivers didn't call hw_config() as
well, assuming they'd already get notified internally by their op.

>> The TI driver implements the chan_switch op and uses channel contexts.
>
> Huh, ok, that was a combination I didn't think was going to exist, since
> the chanswitch API doesn't really tell you what channel context etc.
> OTOH, it does give you the vif so you have the chanctx implicitly.

Yep, it's good enough. The driver gets the chandef from the vif.

>
>> Note that with the above, the channel_contexts + software chan-switch
>> drivers will still need the kind of code that I wrote. So it would
>> just lead to replicated code. Or maybe you meant something else?
>
> We have too many possibilities I guess ... I think for MVM I want the
> disconnect, not the channel context change in software. You're taking
> that possibility away, hence my suggestion of a new hardware flag for it
> or so.

I was thinking it's equivalent to to AP case - currently mac80211 is
the dictator and simply changes the chandef once the lower drv
completes the switch.

Anyway IMHO the simplest approach to handle all the legacy stuff +
chanctx it to keep the current patch as is, and add a mac80211 HW flag
to support it, keeping the deauth option as default.
That's what I think you're suggesting?

>
>> Also, where would you put csa_active = true (if at all) for a STA
>> interface? Unlike AP, the trigger here is mac80211 code. So putting it
>> there seemed appropriate.
>
> Yeah, I was really just trying to say that current chanctx drivers need
> not really expect a chanctx to change channel unless they implement CSA,
> but that currently means AP-CSA - basically what I just said above with
> taking away the possibility of doing the deauth instead.

Let's keep the csa_active as I've used it, and just do a deauth when
the csa-support HW flag is not given?

Arik

^ permalink raw reply

* [PATCH] ath9k: Fix ASPM workaround usage
From: Sujith Manoharan @ 2013-08-25 11:00 UTC (permalink / raw)
  To: John Linville; +Cc: linux-wireless

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

The PCIE Workaround register (AR_WA/0x4004) is used to handle
various hardware quirks. For AR9002 chips, AR_WA_D3_L1_DISABLE
is used to prevent the HW from automatically entering L1 state
when D3 is enforced.

AR_WA_D3_L1_DISABLE has to be enabled for a few AR9280 based
cards, mark them based on their PCI subdevice/subvendor IDs
and enforce it in ar9002_hw_configpcipowersave().

Signed-off-by: Sujith Manoharan <c_manoha@qca.qualcomm.com>
---
 drivers/net/wireless/ath/ath9k/ar9002_hw.c | 29 +++++++------------
 drivers/net/wireless/ath/ath9k/ar9003_hw.c |  7 +----
 drivers/net/wireless/ath/ath9k/ath9k.h     |  1 +
 drivers/net/wireless/ath/ath9k/hw.c        |  1 -
 drivers/net/wireless/ath/ath9k/init.c      |  5 ++++
 drivers/net/wireless/ath/ath9k/pci.c       | 46 ++++++++++++++++++++++++++++++
 6 files changed, 64 insertions(+), 25 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/ar9002_hw.c b/drivers/net/wireless/ath/ath9k/ar9002_hw.c
index 8dc2d08..fb61b08 100644
--- a/drivers/net/wireless/ath/ath9k/ar9002_hw.c
+++ b/drivers/net/wireless/ath/ath9k/ar9002_hw.c
@@ -269,13 +269,12 @@ static void ar9002_hw_configpcipowersave(struct ath_hw *ah,
 			if (ah->config.pcie_waen & AR_WA_D3_L1_DISABLE)
 				val |= AR_WA_D3_L1_DISABLE;
 		} else {
-			if (((AR_SREV_9285(ah) ||
-			      AR_SREV_9271(ah) ||
-			      AR_SREV_9287(ah)) &&
-			     (AR9285_WA_DEFAULT & AR_WA_D3_L1_DISABLE)) ||
-			    (AR_SREV_9280(ah) &&
-			     (AR9280_WA_DEFAULT & AR_WA_D3_L1_DISABLE))) {
-				val |= AR_WA_D3_L1_DISABLE;
+			if (AR_SREV_9285(ah) || AR_SREV_9271(ah) || AR_SREV_9287(ah)) {
+				if (AR9285_WA_DEFAULT & AR_WA_D3_L1_DISABLE)
+					val |= AR_WA_D3_L1_DISABLE;
+			} else if (AR_SREV_9280(ah)) {
+				if (AR9280_WA_DEFAULT & AR_WA_D3_L1_DISABLE)
+					val |= AR_WA_D3_L1_DISABLE;
 			}
 		}
 
@@ -297,24 +296,18 @@ static void ar9002_hw_configpcipowersave(struct ath_hw *ah,
 	} else {
 		if (ah->config.pcie_waen) {
 			val = ah->config.pcie_waen;
-			if (!power_off)
-				val &= (~AR_WA_D3_L1_DISABLE);
+			val &= (~AR_WA_D3_L1_DISABLE);
 		} else {
-			if (AR_SREV_9285(ah) ||
-			    AR_SREV_9271(ah) ||
-			    AR_SREV_9287(ah)) {
+			if (AR_SREV_9285(ah) || AR_SREV_9271(ah) || AR_SREV_9287(ah)) {
 				val = AR9285_WA_DEFAULT;
-				if (!power_off)
-					val &= (~AR_WA_D3_L1_DISABLE);
-			}
-			else if (AR_SREV_9280(ah)) {
+				val &= (~AR_WA_D3_L1_DISABLE);
+			} else if (AR_SREV_9280(ah)) {
 				/*
 				 * For AR9280 chips, bit 22 of 0x4004
 				 * needs to be set.
 				 */
 				val = AR9280_WA_DEFAULT;
-				if (!power_off)
-					val &= (~AR_WA_D3_L1_DISABLE);
+				val &= (~AR_WA_D3_L1_DISABLE);
 			} else {
 				val = AR_WA_DEFAULT;
 			}
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_hw.c b/drivers/net/wireless/ath/ath9k/ar9003_hw.c
index 582cddd..608bb48 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_hw.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_hw.c
@@ -763,12 +763,7 @@ static void ar9003_hw_configpcipowersave(struct ath_hw *ah,
 	if (!power_off /* !restore */) {
 		/* set bit 19 to allow forcing of pcie core into L1 state */
 		REG_SET_BIT(ah, AR_PCIE_PM_CTRL, AR_PCIE_PM_CTRL_ENA);
-
-		/* Several PCIe massages to ensure proper behaviour */
-		if (ah->config.pcie_waen)
-			REG_WRITE(ah, AR_WA, ah->config.pcie_waen);
-		else
-			REG_WRITE(ah, AR_WA, ah->WARegVal);
+		REG_WRITE(ah, AR_WA, ah->WARegVal);
 	}
 
 	/*
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index 8519e75..2ee35f6 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -631,6 +631,7 @@ void ath_ant_comb_scan(struct ath_softc *sc, struct ath_rx_status *rs);
 #define ATH9K_PCI_CUS217     0x0004
 #define ATH9K_PCI_WOW        0x0008
 #define ATH9K_PCI_BT_ANT_DIV 0x0010
+#define ATH9K_PCI_D3_L1_WAR  0x0020
 
 /*
  * Default cache line size, in bytes.
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index b3a6891..2670bf6 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -450,7 +450,6 @@ static void ath9k_hw_init_config(struct ath_hw *ah)
 	ah->config.ack_6mb = 0x0;
 	ah->config.cwm_ignore_extcca = 0;
 	ah->config.pcie_clock_req = 0;
-	ah->config.pcie_waen = 0;
 	ah->config.analog_shiftreg = 1;
 
 	for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c
index b897183..9a1f349 100644
--- a/drivers/net/wireless/ath/ath9k/init.c
+++ b/drivers/net/wireless/ath/ath9k/init.c
@@ -551,6 +551,11 @@ static void ath9k_init_platform(struct ath_softc *sc)
 		pCap->hw_caps |= ATH9K_HW_CAP_BT_ANT_DIV;
 		ath_info(common, "Set BT/WLAN RX diversity capability\n");
 	}
+
+	if (sc->driver_data & ATH9K_PCI_D3_L1_WAR) {
+		ah->config.pcie_waen = 0x0040473b;
+		ath_info(common, "Enable WAR for ASPM D3/L1\n");
+	}
 }
 
 static void ath9k_eeprom_request_cb(const struct firmware *eeprom_blob,
diff --git a/drivers/net/wireless/ath/ath9k/pci.c b/drivers/net/wireless/ath/ath9k/pci.c
index e7996a6..d089a7c 100644
--- a/drivers/net/wireless/ath/ath9k/pci.c
+++ b/drivers/net/wireless/ath/ath9k/pci.c
@@ -30,6 +30,52 @@ static DEFINE_PCI_DEVICE_TABLE(ath_pci_id_table) = {
 	{ PCI_VDEVICE(ATHEROS, 0x0029) }, /* PCI   */
 	{ PCI_VDEVICE(ATHEROS, 0x002A) }, /* PCI-E */
 
+	{ PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
+			 0x002A,
+			 PCI_VENDOR_ID_AZWAVE,
+			 0x1C71),
+	  .driver_data = ATH9K_PCI_D3_L1_WAR },
+	{ PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
+			 0x002A,
+			 PCI_VENDOR_ID_FOXCONN,
+			 0xE01F),
+	  .driver_data = ATH9K_PCI_D3_L1_WAR },
+	{ PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
+			 0x002A,
+			 0x11AD, /* LITEON */
+			 0x6632),
+	  .driver_data = ATH9K_PCI_D3_L1_WAR },
+	{ PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
+			 0x002A,
+			 0x11AD, /* LITEON */
+			 0x6642),
+	  .driver_data = ATH9K_PCI_D3_L1_WAR },
+	{ PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
+			 0x002A,
+			 PCI_VENDOR_ID_QMI,
+			 0x0306),
+	  .driver_data = ATH9K_PCI_D3_L1_WAR },
+	{ PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
+			 0x002A,
+			 0x185F, /* WNC */
+			 0x309D),
+	  .driver_data = ATH9K_PCI_D3_L1_WAR },
+	{ PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
+			 0x002A,
+			 0x10CF, /* Fujitsu */
+			 0x147C),
+	  .driver_data = ATH9K_PCI_D3_L1_WAR },
+	{ PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
+			 0x002A,
+			 0x10CF, /* Fujitsu */
+			 0x147D),
+	  .driver_data = ATH9K_PCI_D3_L1_WAR },
+	{ PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
+			 0x002A,
+			 0x10CF, /* Fujitsu */
+			 0x1536),
+	  .driver_data = ATH9K_PCI_D3_L1_WAR },
+
 	/* AR9285 card for Asus */
 	{ PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
 			 0x002B,
-- 
1.8.3.4


^ permalink raw reply related

* [PATCH] ath5k: debugfs: NULL-terminate strings
From: Djalal Harouni @ 2013-08-25 10:50 UTC (permalink / raw)
  To: Jiri Slaby, Nick Kossifidis, John W. Linville, linux-wireless,
	linux-kernel
  Cc: Djalal Harouni

Avoid processing garbage data by NULL terminating the strings.

Signed-off-by: Djalal Harouni <tixxdz@opendz.org>
---
Patch compile tested only.

 drivers/net/wireless/ath/ath5k/debug.c | 24 ++++++++++++++++++------
 1 file changed, 18 insertions(+), 6 deletions(-)

diff --git a/drivers/net/wireless/ath/ath5k/debug.c b/drivers/net/wireless/ath/ath5k/debug.c
index 9d00dab..b8d031a 100644
--- a/drivers/net/wireless/ath/ath5k/debug.c
+++ b/drivers/net/wireless/ath/ath5k/debug.c
@@ -245,9 +245,11 @@ static ssize_t write_file_beacon(struct file *file,
 	struct ath5k_hw *ah = file->private_data;
 	char buf[20];
 
-	if (copy_from_user(buf, userbuf, min(count, sizeof(buf))))
+	count = min_t(size_t, count, sizeof(buf) - 1);
+	if (copy_from_user(buf, userbuf, count))
 		return -EFAULT;
 
+	buf[count] = '\0';
 	if (strncmp(buf, "disable", 7) == 0) {
 		AR5K_REG_DISABLE_BITS(ah, AR5K_BEACON, AR5K_BEACON_ENABLE);
 		pr_info("debugfs disable beacons\n");
@@ -345,9 +347,11 @@ static ssize_t write_file_debug(struct file *file,
 	unsigned int i;
 	char buf[20];
 
-	if (copy_from_user(buf, userbuf, min(count, sizeof(buf))))
+	count = min_t(size_t, count, sizeof(buf) - 1);
+	if (copy_from_user(buf, userbuf, count))
 		return -EFAULT;
 
+	buf[count] = '\0';
 	for (i = 0; i < ARRAY_SIZE(dbg_info); i++) {
 		if (strncmp(buf, dbg_info[i].name,
 					strlen(dbg_info[i].name)) == 0) {
@@ -448,9 +452,11 @@ static ssize_t write_file_antenna(struct file *file,
 	unsigned int i;
 	char buf[20];
 
-	if (copy_from_user(buf, userbuf, min(count, sizeof(buf))))
+	count = min_t(size_t, count, sizeof(buf) - 1);
+	if (copy_from_user(buf, userbuf, count))
 		return -EFAULT;
 
+	buf[count] = '\0';
 	if (strncmp(buf, "diversity", 9) == 0) {
 		ath5k_hw_set_antenna_mode(ah, AR5K_ANTMODE_DEFAULT);
 		pr_info("debug: enable diversity\n");
@@ -619,9 +625,11 @@ static ssize_t write_file_frameerrors(struct file *file,
 	struct ath5k_statistics *st = &ah->stats;
 	char buf[20];
 
-	if (copy_from_user(buf, userbuf, min(count, sizeof(buf))))
+	count = min_t(size_t, count, sizeof(buf) - 1);
+	if (copy_from_user(buf, userbuf, count))
 		return -EFAULT;
 
+	buf[count] = '\0';
 	if (strncmp(buf, "clear", 5) == 0) {
 		st->rxerr_crc = 0;
 		st->rxerr_phy = 0;
@@ -766,9 +774,11 @@ static ssize_t write_file_ani(struct file *file,
 	struct ath5k_hw *ah = file->private_data;
 	char buf[20];
 
-	if (copy_from_user(buf, userbuf, min(count, sizeof(buf))))
+	count = min_t(size_t, count, sizeof(buf) - 1);
+	if (copy_from_user(buf, userbuf, count))
 		return -EFAULT;
 
+	buf[count] = '\0';
 	if (strncmp(buf, "sens-low", 8) == 0) {
 		ath5k_ani_init(ah, ATH5K_ANI_MODE_MANUAL_HIGH);
 	} else if (strncmp(buf, "sens-high", 9) == 0) {
@@ -862,9 +872,11 @@ static ssize_t write_file_queue(struct file *file,
 	struct ath5k_hw *ah = file->private_data;
 	char buf[20];
 
-	if (copy_from_user(buf, userbuf, min(count, sizeof(buf))))
+	count = min_t(size_t, count, sizeof(buf) - 1);
+	if (copy_from_user(buf, userbuf, count))
 		return -EFAULT;
 
+	buf[count] = '\0';
 	if (strncmp(buf, "start", 5) == 0)
 		ieee80211_wake_queues(ah->hw);
 	else if (strncmp(buf, "stop", 4) == 0)
-- 
1.7.11.7


^ permalink raw reply related

* [PATCH] ath9k: Fix ASPM for AR9462
From: Sujith Manoharan @ 2013-08-25  9:13 UTC (permalink / raw)
  To: John Linville; +Cc: linux-wireless

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

If the L1 entrance latency is not calibrated properly
in the EEPROM in WB222 boards, there could be problems
in connectivity. Check and correct the calibrated value
if it doesn't match the optimal value for WB222, 4us.

Signed-off-by: Sujith Manoharan <c_manoha@qca.qualcomm.com>
---
 drivers/net/wireless/ath/ath9k/ar9003_hw.c | 14 ++++++++++++++
 drivers/net/wireless/ath/ath9k/hw.h        |  1 +
 drivers/net/wireless/ath/ath9k/pci.c       | 16 ++++++++++++++++
 3 files changed, 31 insertions(+)

diff --git a/drivers/net/wireless/ath/ath9k/ar9003_hw.c b/drivers/net/wireless/ath/ath9k/ar9003_hw.c
index 738aa7e..582cddd 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_hw.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_hw.c
@@ -745,6 +745,20 @@ static void ar9003_hw_init_mode_gain_regs(struct ath_hw *ah)
 static void ar9003_hw_configpcipowersave(struct ath_hw *ah,
 					 bool power_off)
 {
+	/*
+	 * Increase L1 Entry Latency. Some WB222 boards don't have
+	 * this change in eeprom/OTP.
+	 *
+	 */
+	if (AR_SREV_9462(ah)) {
+		u32 val = ah->config.aspm_l1_fix;
+		if ((val & 0xff000000) == 0x17000000) {
+			val &= 0x00ffffff;
+			val |= 0x27000000;
+			REG_WRITE(ah, 0x570c, val);
+		}
+	}
+
 	/* Nothing to do on restore for 11N */
 	if (!power_off /* !restore */) {
 		/* set bit 19 to allow forcing of pcie core into L1 state */
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index fa543a6..69a907b 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -311,6 +311,7 @@ struct ath9k_ops_config {
 	u16 ani_poll_interval; /* ANI poll interval in ms */
 
 	/* Platform specific config */
+	u32 aspm_l1_fix;
 	u32 xlna_gpio;
 	u32 ant_ctrl_comm2g_switch_enable;
 	bool xatten_margin_cfg;
diff --git a/drivers/net/wireless/ath/ath9k/pci.c b/drivers/net/wireless/ath/ath9k/pci.c
index 3280798..e7996a6 100644
--- a/drivers/net/wireless/ath/ath9k/pci.c
+++ b/drivers/net/wireless/ath/ath9k/pci.c
@@ -314,6 +314,22 @@ static void ath_pci_aspm_init(struct ath_common *common)
 		return;
 	}
 
+	/*
+	 * 0x70c - Ack Frequency Register.
+	 *
+	 * Bits 27:29 - DEFAULT_L1_ENTRANCE_LATENCY.
+	 *
+	 * 000 : 1 us
+	 * 001 : 2 us
+	 * 010 : 4 us
+	 * 011 : 8 us
+	 * 100 : 16 us
+	 * 101 : 32 us
+	 * 110/111 : 64 us
+	 */
+	if (AR_SREV_9462(ah))
+		pci_read_config_dword(pdev, 0x70c, &ah->config.aspm_l1_fix);
+
 	pcie_capability_read_word(parent, PCI_EXP_LNKCTL, &aspm);
 	if (aspm & (PCI_EXP_LNKCTL_ASPM_L0S | PCI_EXP_LNKCTL_ASPM_L1)) {
 		ah->aspm_enabled = true;
-- 
1.8.3.4


^ permalink raw reply related

* RE: [Ilw] Re: iwlwifi micorcode errors and hardware resets problems
From: Grumbach, Emmanuel @ 2013-08-25  8:21 UTC (permalink / raw)
  To: Luca Coelho, Stanislaw Gruszka
  Cc: ilw@linux.intel.com, linux-wireless@vger.kernel.org
In-Reply-To: <1377345177.5589.3.camel@porter.coelho.fi>

PiBPbiBGcmksIDIwMTMtMDgtMjMgYXQgMTE6MDggKzAyMDAsIFN0YW5pc2xhdyBHcnVzemthIHdy
b3RlOg0KPiA+IFdlIGhhdmUgdGhvc2UgYnVnIHJlcG9ydHMgb24gUkggYnVnemlsbGEsIGFuZCB2
YXJpb3VzIG90aGVyIGl3bHdpZmkNCj4gPiBwcm9ibGVtcywgYnV0IHRob3NlIGhhdmUgc29tZSBj
b21tb24gc2NlbmFyaW86DQo+ID4NCj4gPiBodHRwczovL2J1Z3ppbGxhLnJlZGhhdC5jb20vc2hv
d19idWcuY2dpP2lkPTk3OTg3Mw0KPiA+IGh0dHBzOi8vYnVnemlsbGEucmVkaGF0LmNvbS9zaG93
X2J1Zy5jZ2k/aWQ9OTkwNTM2DQo+ID4gaHR0cHM6Ly9idWd6aWxsYS5yZWRoYXQuY29tL3Nob3df
YnVnLmNnaT9pZD05OTQzMjINCj4gPiBodHRwczovL2J1Z3ppbGxhLnJlZGhhdC5jb20vc2hvd19i
dWcuY2dpP2lkPTk5NjUwMg0KPiA+IGh0dHBzOi8vYnVnemlsbGEucmVkaGF0LmNvbS9zaG93X2J1
Zy5jZ2k/aWQ9OTY5NjEwDQo+ID4gaHR0cHM6Ly9idWd6aWxsYS5yZWRoYXQuY29tL3Nob3dfYnVn
LmNnaT9pZD05OTkwNTMNCj4gPg0KPiA+IEZpcnN0IHRoZXJlIGlzIE1pY3JvY29kZSBlcnJvciBv
ciBvdGhlciBmaXJtd2FyZSBwcm9ibGVtLCB3aGF0IG1ha2Ugd2UNCj4gPiBkbyBpd2xfdHJhbnNf
c3RvcF9kZXZpY2UoKSB3aGljaCBzZXQgdHJhbnMtPnN0YXRlIHRvIElXTF9UUkFOU19OT19GVy4N
Cj4gPiBJZiBtYWM4MDIxMSBoYXMgc29tZSBwZW5kaW5nIHdvcmtzL3RpbWVycyBpLmUuIGllZWU4
MDIxMV9zdGFfd29yaygpLA0KPiA+IGl0IGNhbGxzIGRydiBhbmQgd2UgdHJpZ2dlciBvbiBvZiB0
aG9zZSB3YXJuaW5ncw0KPiA+DQo+ID4gICAgICAgICBXQVJOX09OQ0UodHJhbnMtPnN0YXRlICE9
IElXTF9UUkFOU19GV19BTElWRSwNCj4gPiAgICAgICAgICAgICAgICAgICAiJXMgYmFkIHN0YXRl
ID0gJWQiLCBfX2Z1bmNfXywgdHJhbnMtPnN0YXRlKTsNCj4gPg0KPiA+IG9uIHNvbWUgdHJhbnMg
b3BlcmF0aW9uLg0KPiA+DQo+ID4gSSB0aGluayB0aGlzIGNhbiBiZSBmaXhlZCBieSBmaXJzdCBk
byBxdWllc2NlIG9uIG1hYzgwMjExIChmb3IgZXhhbXBsZQ0KPiA+IGJ5IGllZWU4MDIxMV9zdGFf
cXVpZXNjZSgpIHByb2NlZHVyZSwgd2hpY2ggSSByZW1vdmVkIGJ1dCBjYW4gYmUgYWRkZWQNCj4g
PiBiYWNrKSBhbmQgdGhlbiBkbyBpd2xhZ25fcHJlcGFyZV9yZXN0YXJ0KCkgJiBpZWVlODAyMTFf
cmVzdGFydF9odygpLg0KPiA+DQo+ID4gVGhvdWdoIEknbSBub3Qgc3VyZSBpZiBpdCdzIHdvcnRo
IHRvIGRvIHRoaXMgc2luY2UgdGhvc2Ugd2FybmluZ3MgYXJlDQo+ID4gaW5kaWNhdG9yIGZvciBt
YWxmdW5jdGlvbmluZyBpd2x3aWZpIGZpcm13YXJlIChvciBkcml2ZXIgbm90IGNvcnJlY3RseQ0K
PiA+IGNvbW11bmljYXRpbmcgd2l0aCBmaXJtd2FyZSksIHdoaWNoIHdpbGwgYmUgdW5ub3RpY2Vk
IGlmIG5vdCByZXBvcnRlZA0KPiA+IGF1dG9tYXRpY2FsbHkgYnkgdG9vbCBsaWtlIEFCUlQuIEJ1
dCBwZXJoYXBzIHdlIGNvdWxkIGFkZCBXQVJOX09OQ0Ugb24NCj4gPiBNaWNyb2NvZGUgZXJyb3Ig
Y29uZGl0aW9uID8NCj4gDQo+IEkgdGhpbmsgdGhhdCwgaWYgdGhlIHF1aWVzY2UgcmVhbGx5IGhl
bHBzIHdpdGggdGhpcywgd2Ugc2hvdWxkIGRvIGl0Lg0KPiBUaGlzIFdBUk4gaXMgYSBzaWRlLWVm
ZmVjdCBvZiB0aGUgcHJvYmxlbSBhbmQgbm90IHRoZSBwcm9ibGVtIGl0c2VsZi4NCj4gSWYgeW91
IHdhbnQgdG8gY2F0Y2ggdGhlIEZXIHByb2JsZW0sIHRoZXJlIHNob3VsZCBiZSBhIFdBUk4gZWxz
ZXdoZXJlLg0KPiANCj4gSSdtIG5vdCBzYXlpbmcgdGhhdCB0aGlzIFdBUk4gc2hvdWxkIGJlIHJl
bW92ZWQgYW5kIEkgYWxzbyB0aGluayBpdCdzIGEgZ29vZA0KPiBpZGVhIHRvIGNoYW5nZSBpdCB0
byBXQVJOX09OX09OQ0UoKS4gIEkganVzdCB0aGluayB0aGF0LCBpZiB0aGVyZSdzIGFueXRoaW5n
DQo+IHRoZSBkcml2ZXIgY2FuIGRvIHRvIGtlZXAgdGhpbmdzIHJ1bm5pbmcgbmljZWx5LCB3ZSBz
aG91bGQgZG8gaXQuDQo+IA0KPiBJbiBhbnkgY2FzZSwgSSdsbCBsZWF2ZSB0aGlzIGZvciBKb2hh
bm5lcywgRW1tYW51ZWwgb3Igc29tZSBvZiB0aGUgb3RoZXIgZ3V5cw0KPiB3aXRoIG1vcmUgZXhw
ZXJpZW5jZSBpbiBpd2x3aWZpIHRvIGNvbW1lbnQuIDspDQoNCllvdSBnb3QgbXkgQUNLIGhlcmUu
IFdlIGhhdmUgc29tZSBpc3N1ZXMgd2l0aCBmaXJtd2FyZS4gT2J2aW91c2x5LiBCdXQgbW9zdCBv
ZiB0aGUgaXNzdWVzIGFyZSB2ZXJ5IGhhcmQgdG8gZGVidWcuIE1vc3Qgb2YgdGhlbSBJIGFtIHNl
ZWluZyBhcmUgbW9yZSBsaWtlIHRoZSBmaXJtd2FyZSBnZXR0aW5nIHN0dWNrIGV0Yy4uLiAgQWZ0
ZXIgYWxsIHRoaXMgaXMgd2h5IHdlIGhhdmUgYSByZXN0YXJ0IGZsb3csIGZvciB0aGVzZSBpc3N1
ZXMgdGhhdCBkb24ndCBoYXBwZW4gZnJlcXVlbnRseSBidXQgYXJlIHNvbHZhYmxlIGJ5IGEgcmVz
ZXQuIFNpbmNlIHdlIHN0aWxsIHdhbnQgdG8ga25vdyB3aGVuIHRoaXMga2luZCBvZiB0aGluZ3Mg
aGFwcGVuLCBhZGRpbmcgYSBXQVJOX09OX09OQ0Ugc291bmRzIGdvb2QuDQo=

^ permalink raw reply

* mac80211 kernel panic due to invalid cab_queue value with hwsim
From: Jouni Malinen @ 2013-08-24 16:00 UTC (permalink / raw)
  To: Johannes Berg; +Cc: linux-wireless

Something is cab_queue handling is broken (and has been broken for a
while) in mac80211. At least mac80211_hwsim shows this, but I guess it
could happen with some other drivers, too. The error shows up as
group-addressed Data frames from a P2P GO not being transmitted if
CONFIG_MAC80211_VERBOSE_DEBUG is defined and kernel panic if that is not
defined. ieee80211_tx_h_multicast_ps_buf() can assign
IEEE80211_INVAL_HW_QUEUE (0xff) into info->hw_queue in some cases and
that results in the issues in ieee80211_tx_frags where q >=
local->hw.queues check is done only with verbose debugging enabled. If
that check is not there, kernel panic shows up at least in
skb_queue_splice_tail_init() when that invalid hw_queue 0xff value is
used to index the local->pending array.

I'm not sure where cab_queue should be cleared to avoid this, but for
now, I'm using following workaround to avoid the symptoms:


diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 098ae85..41655a4 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -413,8 +413,13 @@ ieee80211_tx_h_multicast_ps_buf(struct ieee80211_tx_data *tx)
 	if (ieee80211_has_order(hdr->frame_control))
 		return TX_CONTINUE;
 
-	if (tx->local->hw.flags & IEEE80211_HW_QUEUE_CONTROL)
-		info->hw_queue = tx->sdata->vif.cab_queue;
+	if (tx->local->hw.flags & IEEE80211_HW_QUEUE_CONTROL) {
+		if (tx->sdata->vif.cab_queue == IEEE80211_INVAL_HW_QUEUE) {
+			printk(KERN_DEBUG "%s:trying to assign invalid cab_queue for skb %p vif.type=%d\n",
+			       __func__, tx->skb, tx->sdata->vif.type);
+		} else
+			info->hw_queue = tx->sdata->vif.cab_queue;
+	}
 
 	/* no stations in PS mode */
 	if (!atomic_read(&ps->num_sta_ps))

-- 
Jouni Malinen                                            PGP id EFC895FA

^ permalink raw reply related

* [PATCH v2] iwlwifi: mvm: make debugfs write() operations write up to count bytes
From: Djalal Harouni @ 2013-08-24 13:35 UTC (permalink / raw)
  To: Johannes Berg, Intel Linux Wireless, John W. Linville,
	Emmanuel Grumbach, linux-wireless, linux-kernel
  Cc: Djalal Harouni

Some debugfs write() operations of the MVM Firmware will ignore the
count argument, and will copy more bytes than what was specified.
Fix this by getting the right count of bytes.

This will honor restrictions put on the number of bytes to write and
avoid strcmp() calls on garbage data.

Signed-off-by: Djalal Harouni <tixxdz@opendz.org>
Cc: "Berg, Johannes" <johannes.berg@intel.com>
---
Patch compile tested only.
v2 Clean patch and use min_t() as noted by Berg Johannes

 drivers/net/wireless/iwlwifi/mvm/debugfs.c | 12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/mvm/debugfs.c b/drivers/net/wireless/iwlwifi/mvm/debugfs.c
index aac81b8..299966a 100644
--- a/drivers/net/wireless/iwlwifi/mvm/debugfs.c
+++ b/drivers/net/wireless/iwlwifi/mvm/debugfs.c
@@ -257,7 +257,8 @@ static ssize_t iwl_dbgfs_power_down_allow_write(struct file *file,
 	if (!mvm->ucode_loaded)
 		return -EIO;
 
-	if (copy_from_user(buf, user_buf, sizeof(buf)))
+	count = min_t(size_t, count, sizeof(buf) - 1);
+	if (copy_from_user(buf, user_buf, count))
 		return -EFAULT;
 
 	if (sscanf(buf, "%d", &allow) != 1)
@@ -281,7 +282,8 @@ static ssize_t iwl_dbgfs_power_down_d3_allow_write(struct file *file,
 	char buf[8] = {};
 	int allow;
 
-	if (copy_from_user(buf, user_buf, sizeof(buf)))
+	count = min_t(size_t, count, sizeof(buf) - 1);
+	if (copy_from_user(buf, user_buf, count))
 		return -EFAULT;
 
 	if (sscanf(buf, "%d", &allow) != 1)
@@ -371,7 +373,8 @@ static ssize_t iwl_dbgfs_pm_params_write(struct file *file,
 	int val;
 	int ret;
 
-	if (copy_from_user(buf, user_buf, sizeof(buf)))
+	count = min_t(size_t, count, sizeof(buf) - 1);
+	if (copy_from_user(buf, user_buf, count))
 		return -EFAULT;
 
 	if (!strncmp("keep_alive=", buf, 11)) {
@@ -968,7 +971,8 @@ static ssize_t iwl_dbgfs_d3_sram_write(struct file *file,
 	char buf[8] = {};
 	int store;
 
-	if (copy_from_user(buf, user_buf, sizeof(buf)))
+	count = min_t(size_t, count, sizeof(buf) - 1);
+	if (copy_from_user(buf, user_buf, count))
 		return -EFAULT;
 
 	if (sscanf(buf, "%d", &store) != 1)
-- 
1.7.11.7


^ permalink raw reply related

* [PATCH 5/5] staging: vt6656: s_vGenerateTxParameter pvRrvTime should never be NULL
From: Malcolm Priestley @ 2013-08-24 12:15 UTC (permalink / raw)
  To: gregkh; +Cc: linux-wireless

If pvRrvTime is NULL the whole structure is NULL, so
remove if statements and consolidate to single return.

Signed-off-by: Malcolm Priestley <tvboxspy@gmail.com>
---
 drivers/staging/vt6656/rxtx.c | 16 +++-------------
 1 file changed, 3 insertions(+), 13 deletions(-)

diff --git a/drivers/staging/vt6656/rxtx.c b/drivers/staging/vt6656/rxtx.c
index 64ce7f0..dd2bfc9 100644
--- a/drivers/staging/vt6656/rxtx.c
+++ b/drivers/staging/vt6656/rxtx.c
@@ -860,6 +860,9 @@ static void s_vGenerateTxParameter(struct vnt_private *pDevice,
         byFBOption = AUTO_FB_1;
     }
 
+	if (!pvRrvTime)
+		return;
+
     if (pDevice->bLongHeader)
         cbMACHdLen = WLAN_HDR_ADDR3_LEN + 6;
 
@@ -867,7 +870,6 @@ static void s_vGenerateTxParameter(struct vnt_private *pDevice,
 
         if (pvRTS != NULL) { //RTS_need
             //Fill RsvTime
-            if (pvRrvTime) {
 		struct vnt_rrv_time_rts *pBuf =
 			(struct vnt_rrv_time_rts *)pvRrvTime;
 		pBuf->wRTSTxRrvTime_aa = s_uGetRTSCTSRsvTime(pDevice, 2,
@@ -881,15 +883,12 @@ static void s_vGenerateTxParameter(struct vnt_private *pDevice,
 		pBuf->wTxRrvTime_b = vnt_rxtx_rsvtime_le16(pDevice,
 			PK_TYPE_11B, cbFrameSize, pDevice->byTopCCKBasicRate,
 				bNeedACK);
-            }
             //Fill RTS
 	    s_vFillRTSHead(pDevice, byPktType, pvRTS, cbFrameSize, bNeedACK,
 				psEthHeader, wCurrentRate, byFBOption);
         }
         else {//RTS_needless, PCF mode
-
             //Fill RsvTime
-            if (pvRrvTime) {
 		struct vnt_rrv_time_cts *pBuf =
 				(struct vnt_rrv_time_cts *)pvRrvTime;
 		pBuf->wTxRrvTime_a = vnt_rxtx_rsvtime_le16(pDevice, byPktType,
@@ -899,7 +898,6 @@ static void s_vGenerateTxParameter(struct vnt_private *pDevice,
 			pDevice->byTopCCKBasicRate, bNeedACK);
 		pBuf->wCTSTxRrvTime_ba = s_uGetRTSCTSRsvTime(pDevice, 3,
 				byPktType, cbFrameSize, wCurrentRate);
-            }
             //Fill CTS
 	    s_vFillCTSHead(pDevice, uDMAIdx, byPktType, pvCTS, cbFrameSize,
 			bNeedACK, wCurrentRate, byFBOption);
@@ -909,52 +907,44 @@ static void s_vGenerateTxParameter(struct vnt_private *pDevice,
 
         if (pvRTS != NULL) {//RTS_need, non PCF mode
             //Fill RsvTime
-            if (pvRrvTime) {
 		struct vnt_rrv_time_ab *pBuf =
 				(struct vnt_rrv_time_ab *)pvRrvTime;
 		pBuf->wRTSTxRrvTime = s_uGetRTSCTSRsvTime(pDevice, 2,
 				byPktType, cbFrameSize, wCurrentRate);
 		pBuf->wTxRrvTime = vnt_rxtx_rsvtime_le16(pDevice, byPktType,
 				cbFrameSize, wCurrentRate, bNeedACK);
-            }
             //Fill RTS
 	    s_vFillRTSHead(pDevice, byPktType, pvRTS, cbFrameSize, bNeedACK,
 			psEthHeader, wCurrentRate, byFBOption);
         }
         else if (pvRTS == NULL) {//RTS_needless, non PCF mode
             //Fill RsvTime
-            if (pvRrvTime) {
 		struct vnt_rrv_time_ab *pBuf =
 				(struct vnt_rrv_time_ab *)pvRrvTime;
 		pBuf->wTxRrvTime = vnt_rxtx_rsvtime_le16(pDevice, PK_TYPE_11A,
 			cbFrameSize, wCurrentRate, bNeedACK);
-            }
         }
     }
     else if (byPktType == PK_TYPE_11B) {
 
         if ((pvRTS != NULL)) {//RTS_need, non PCF mode
             //Fill RsvTime
-            if (pvRrvTime) {
 		struct vnt_rrv_time_ab *pBuf =
 				(struct vnt_rrv_time_ab *)pvRrvTime;
 		pBuf->wRTSTxRrvTime = s_uGetRTSCTSRsvTime(pDevice, 0,
 				byPktType, cbFrameSize, wCurrentRate);
 		pBuf->wTxRrvTime = vnt_rxtx_rsvtime_le16(pDevice, PK_TYPE_11B,
 				cbFrameSize, wCurrentRate, bNeedACK);
-            }
             //Fill RTS
 	    s_vFillRTSHead(pDevice, byPktType, pvRTS, cbFrameSize, bNeedACK,
 			psEthHeader, wCurrentRate, byFBOption);
         }
         else { //RTS_needless, non PCF mode
             //Fill RsvTime
-            if (pvRrvTime) {
 		struct vnt_rrv_time_ab *pBuf =
 				(struct vnt_rrv_time_ab *)pvRrvTime;
 		pBuf->wTxRrvTime = vnt_rxtx_rsvtime_le16(pDevice, PK_TYPE_11B,
 			cbFrameSize, wCurrentRate, bNeedACK);
-            }
         }
     }
     //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"s_vGenerateTxParameter END.\n");
-- 
1.8.1.2


^ permalink raw reply related

* [PATCH 4/5] staging: vt6656: s_vGenerateTxParameter dead code bDisCRC
From: Malcolm Priestley @ 2013-08-24 12:01 UTC (permalink / raw)
  To: gregkh; +Cc: linux-wireless

As result of patch
vt6656: rxtx.c s_vFillCTSHead remove dead code bDisCRC

bDisCRC is unused.

Signed-off-by: Malcolm Priestley <tvboxspy@gmail.com>
---
 drivers/staging/vt6656/rxtx.c | 5 -----
 1 file changed, 5 deletions(-)

diff --git a/drivers/staging/vt6656/rxtx.c b/drivers/staging/vt6656/rxtx.c
index 7b94a77..64ce7f0 100644
--- a/drivers/staging/vt6656/rxtx.c
+++ b/drivers/staging/vt6656/rxtx.c
@@ -846,7 +846,6 @@ static void s_vGenerateTxParameter(struct vnt_private *pDevice,
 {
 	u32 cbMACHdLen = WLAN_HDR_ADDR3_LEN; /* 24 */
 	u16 wFifoCtl;
-	int bDisCRC = false;
 	u8 byFBOption = AUTO_FB_NONE;
 
     //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"s_vGenerateTxParameter...\n");
@@ -854,10 +853,6 @@ static void s_vGenerateTxParameter(struct vnt_private *pDevice,
     pFifoHead->wReserved = wCurrentRate;
     wFifoCtl = pFifoHead->wFIFOCtl;
 
-    if (wFifoCtl & FIFOCTL_CRCDIS) {
-        bDisCRC = true;
-    }
-
     if (wFifoCtl & FIFOCTL_AUTO_FB_0) {
         byFBOption = AUTO_FB_0;
     }
-- 
1.8.1.2


^ permalink raw reply related

* [PATCH 3/5] staging: vt6656: rxtx.c s_vFillCTSHead remove dead code bDisCRC
From: Malcolm Priestley @ 2013-08-24 11:56 UTC (permalink / raw)
  To: gregkh; +Cc: linux-wireless

As result of patch
vt6656: device.h Remove dead code bSoftwareGenCrcErr.

dDiscCRC is unused.

Signed-off-by: Malcolm Priestley <tvboxspy@gmail.com>
---
 drivers/staging/vt6656/rxtx.c | 13 ++++---------
 1 file changed, 4 insertions(+), 9 deletions(-)

diff --git a/drivers/staging/vt6656/rxtx.c b/drivers/staging/vt6656/rxtx.c
index 1b2effc..7b94a77 100644
--- a/drivers/staging/vt6656/rxtx.c
+++ b/drivers/staging/vt6656/rxtx.c
@@ -126,7 +126,7 @@ static u16 s_uGetRTSCTSRsvTime(struct vnt_private *pDevice, u8 byRTSRsvType,
 
 static void s_vFillCTSHead(struct vnt_private *pDevice, u32 uDMAIdx,
 	u8 byPktType, void *pvCTS, u32 cbFrameLength, int bNeedAck,
-	int bDisCRC, u16 wCurrentRate, u8 byFBOption);
+	u16 wCurrentRate, u8 byFBOption);
 
 static void s_vFillRTSHead(struct vnt_private *pDevice, u8 byPktType,
 	void *pvRTS, u32 cbFrameLength, int bNeedAck,
@@ -769,7 +769,7 @@ static void s_vFillRTSHead(struct vnt_private *pDevice, u8 byPktType,
 
 static void s_vFillCTSHead(struct vnt_private *pDevice, u32 uDMAIdx,
 	u8 byPktType, void *pvCTS, u32 cbFrameLength, int bNeedAck,
-	int bDisCRC, u16 wCurrentRate, u8 byFBOption)
+	u16 wCurrentRate, u8 byFBOption)
 {
 	u32 uCTSFrameLen = 14;
 
@@ -777,12 +777,6 @@ static void s_vFillCTSHead(struct vnt_private *pDevice, u32 uDMAIdx,
         return;
     }
 
-    if (bDisCRC) {
-        // When CRCDIS bit is on, H/W forgot to generate FCS for CTS frame,
-        // in this case we need to decrease its length by 4.
-        uCTSFrameLen -= 4;
-    }
-
     if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
 	if (byFBOption != AUTO_FB_NONE) {
 		/* Auto Fall back */
@@ -912,7 +906,8 @@ static void s_vGenerateTxParameter(struct vnt_private *pDevice,
 				byPktType, cbFrameSize, wCurrentRate);
             }
             //Fill CTS
-            s_vFillCTSHead(pDevice, uDMAIdx, byPktType, pvCTS, cbFrameSize, bNeedACK, bDisCRC, wCurrentRate, byFBOption);
+	    s_vFillCTSHead(pDevice, uDMAIdx, byPktType, pvCTS, cbFrameSize,
+			bNeedACK, wCurrentRate, byFBOption);
         }
     }
     else if (byPktType == PK_TYPE_11A) {
-- 
1.8.1.2


^ permalink raw reply related

* Re: iwlwifi micorcode errors and hardware resets problems
From: Luca Coelho @ 2013-08-24 11:52 UTC (permalink / raw)
  To: Stanislaw Gruszka; +Cc: ilw, linux-wireless
In-Reply-To: <20130823090821.GB2632@redhat.com>

On Fri, 2013-08-23 at 11:08 +0200, Stanislaw Gruszka wrote:
> We have those bug reports on RH bugzilla, and various other iwlwifi
> problems, but those have some common scenario:
> 
> https://bugzilla.redhat.com/show_bug.cgi?id=979873
> https://bugzilla.redhat.com/show_bug.cgi?id=990536
> https://bugzilla.redhat.com/show_bug.cgi?id=994322
> https://bugzilla.redhat.com/show_bug.cgi?id=996502
> https://bugzilla.redhat.com/show_bug.cgi?id=969610
> https://bugzilla.redhat.com/show_bug.cgi?id=999053
> 
> First there is Microcode error or other firmware problem, what make we
> do iwl_trans_stop_device() which set trans->state to IWL_TRANS_NO_FW.
> If mac80211 has some pending works/timers i.e. ieee80211_sta_work(),
> it calls drv and we trigger on of those warnings
> 
>         WARN_ONCE(trans->state != IWL_TRANS_FW_ALIVE,
>                   "%s bad state = %d", __func__, trans->state);
> 
> on some trans operation.
> 
> I think this can be fixed by first do quiesce on mac80211 (for example
> by ieee80211_sta_quiesce() procedure, which I removed but can be added
> back) and then do iwlagn_prepare_restart() & ieee80211_restart_hw().
> 
> Though I'm not sure if it's worth to do this since those warnings are
> indicator for malfunctioning iwlwifi firmware (or driver not correctly
> communicating with firmware), which will be unnoticed if not reported
> automatically by tool like ABRT. But perhaps we could add WARN_ONCE on
> Microcode error condition ?

I think that, if the quiesce really helps with this, we should do it.
This WARN is a side-effect of the problem and not the problem itself.
If you want to catch the FW problem, there should be a WARN elsewhere.

I'm not saying that this WARN should be removed and I also think it's a
good idea to change it to WARN_ON_ONCE().  I just think that, if there's
anything the driver can do to keep things running nicely, we should do
it.

In any case, I'll leave this for Johannes, Emmanuel or some of the other
guys with more experience in iwlwifi to comment. ;)

--
Cheers,
Luca.


^ permalink raw reply

* [PATCH 2/5] staging: vt6656: rxtx.c s_vFillRTSHead remove dead bDiscCRC
From: Malcolm Priestley @ 2013-08-24 11:50 UTC (permalink / raw)
  To: gregkh; +Cc: linux-wireless

As result of patch
vt6656: device.h Remove dead code bSoftwareGenCrcErr.

dDiscCRC is unused.

Signed-off-by: Malcolm Priestley <tvboxspy@gmail.com>
---
 drivers/staging/vt6656/rxtx.c | 19 ++++++++-----------
 1 file changed, 8 insertions(+), 11 deletions(-)

diff --git a/drivers/staging/vt6656/rxtx.c b/drivers/staging/vt6656/rxtx.c
index 80741c0..1b2effc 100644
--- a/drivers/staging/vt6656/rxtx.c
+++ b/drivers/staging/vt6656/rxtx.c
@@ -129,7 +129,7 @@ static void s_vFillCTSHead(struct vnt_private *pDevice, u32 uDMAIdx,
 	int bDisCRC, u16 wCurrentRate, u8 byFBOption);
 
 static void s_vFillRTSHead(struct vnt_private *pDevice, u8 byPktType,
-	void *pvRTS, u32 cbFrameLength, int bNeedAck, int bDisCRC,
+	void *pvRTS, u32 cbFrameLength, int bNeedAck,
 	struct ethhdr *psEthHeader, u16 wCurrentRate, u8 byFBOption);
 
 static u16 s_uGetDataDuration(struct vnt_private *pDevice,
@@ -596,7 +596,7 @@ static u32 s_uFillDataHead(struct vnt_private *pDevice,
 }
 
 static void s_vFillRTSHead(struct vnt_private *pDevice, u8 byPktType,
-	void *pvRTS, u32 cbFrameLength, int bNeedAck, int bDisCRC,
+	void *pvRTS, u32 cbFrameLength, int bNeedAck,
 	struct ethhdr *psEthHeader, u16 wCurrentRate, u8 byFBOption)
 {
 	u32 uRTSFrameLen = 20;
@@ -604,12 +604,6 @@ static void s_vFillRTSHead(struct vnt_private *pDevice, u8 byPktType,
     if (pvRTS == NULL)
     	return;
 
-    if (bDisCRC) {
-        // When CRCDIS bit is on, H/W forgot to generate FCS for RTS frame,
-        // in this case we need to decrease its length by 4.
-        uRTSFrameLen -= 4;
-    }
-
     // Note: So far RTSHead doesn't appear in ATIM & Beacom DMA, so we don't need to take them into account.
     //       Otherwise, we need to modified codes for them.
     if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
@@ -900,7 +894,8 @@ static void s_vGenerateTxParameter(struct vnt_private *pDevice,
 				bNeedACK);
             }
             //Fill RTS
-            s_vFillRTSHead(pDevice, byPktType, pvRTS, cbFrameSize, bNeedACK, bDisCRC, psEthHeader, wCurrentRate, byFBOption);
+	    s_vFillRTSHead(pDevice, byPktType, pvRTS, cbFrameSize, bNeedACK,
+				psEthHeader, wCurrentRate, byFBOption);
         }
         else {//RTS_needless, PCF mode
 
@@ -933,7 +928,8 @@ static void s_vGenerateTxParameter(struct vnt_private *pDevice,
 				cbFrameSize, wCurrentRate, bNeedACK);
             }
             //Fill RTS
-            s_vFillRTSHead(pDevice, byPktType, pvRTS, cbFrameSize, bNeedACK, bDisCRC, psEthHeader, wCurrentRate, byFBOption);
+	    s_vFillRTSHead(pDevice, byPktType, pvRTS, cbFrameSize, bNeedACK,
+			psEthHeader, wCurrentRate, byFBOption);
         }
         else if (pvRTS == NULL) {//RTS_needless, non PCF mode
             //Fill RsvTime
@@ -958,7 +954,8 @@ static void s_vGenerateTxParameter(struct vnt_private *pDevice,
 				cbFrameSize, wCurrentRate, bNeedACK);
             }
             //Fill RTS
-            s_vFillRTSHead(pDevice, byPktType, pvRTS, cbFrameSize, bNeedACK, bDisCRC, psEthHeader, wCurrentRate, byFBOption);
+	    s_vFillRTSHead(pDevice, byPktType, pvRTS, cbFrameSize, bNeedACK,
+			psEthHeader, wCurrentRate, byFBOption);
         }
         else { //RTS_needless, non PCF mode
             //Fill RsvTime
-- 
1.8.1.2


^ permalink raw reply related

* [PATCH 1/5] staging: vt6656: device.h Remove dead code bSoftwareGenCrcErr.
From: Malcolm Priestley @ 2013-08-24 11:42 UTC (permalink / raw)
  To: gregkh; +Cc: linux-wireless

Probably an error in earlier firmware is never enabled so remove.

bPacketToWirelessUsb remove dead if/else and variables.

Signed-off-by: Malcolm Priestley <tvboxspy@gmail.com>
---
 drivers/staging/vt6656/device.h |  1 -
 drivers/staging/vt6656/rxtx.c   | 21 +--------------------
 2 files changed, 1 insertion(+), 21 deletions(-)

diff --git a/drivers/staging/vt6656/device.h b/drivers/staging/vt6656/device.h
index 4986910..e8f4b19 100644
--- a/drivers/staging/vt6656/device.h
+++ b/drivers/staging/vt6656/device.h
@@ -596,7 +596,6 @@ struct vnt_private {
 	int bCCK;
 	int bEncryptionEnable;
 	int bLongHeader;
-	int bSoftwareGenCrcErr;
 	int bShortSlotTime;
 	int bProtectMode;
 	int bNonERPPresent;
diff --git a/drivers/staging/vt6656/rxtx.c b/drivers/staging/vt6656/rxtx.c
index 14b7def..80741c0 100644
--- a/drivers/staging/vt6656/rxtx.c
+++ b/drivers/staging/vt6656/rxtx.c
@@ -1003,7 +1003,7 @@ static int s_bPacketToWirelessUsb(struct vnt_private *pDevice, u8 byPktType,
 	void *pvTxDataHd;
 	u8 byFBOption = AUTO_FB_NONE, byFragType;
 	u16 wTxBufSize;
-	u32 dwMICKey0, dwMICKey1, dwMIC_Priority, dwCRC;
+	u32 dwMICKey0, dwMICKey1, dwMIC_Priority;
 	u32 *pdwMIC_L, *pdwMIC_R;
 	int bSoftWEP = false;
 
@@ -1058,10 +1058,6 @@ static int s_bPacketToWirelessUsb(struct vnt_private *pDevice, u8 byPktType,
     if (pDevice->bLongHeader)
         pTxBufHead->wFIFOCtl |= FIFOCTL_LHEAD;
 
-    if (pDevice->bSoftwareGenCrcErr) {
-        pTxBufHead->wFIFOCtl |= FIFOCTL_CRCDIS; // set tx descriptors to NO hardware CRC
-    }
-
     //Set FRAGCTL_MACHDCNT
     if (pDevice->bLongHeader) {
         cbMACHdLen = WLAN_HDR_ADDR3_LEN + 6;
@@ -1386,22 +1382,7 @@ static int s_bPacketToWirelessUsb(struct vnt_private *pDevice, u8 byPktType,
         cbFrameSize -= cbICVlen;
     }
 
-    if (pDevice->bSoftwareGenCrcErr == true) {
-	unsigned int cbLen;
-        u32 * pdwCRC;
-
-        dwCRC = 0xFFFFFFFFL;
-        cbLen = cbFrameSize - cbFCSlen;
-        // calculate CRC, and wrtie CRC value to end of TD
-        dwCRC = CRCdwGetCrc32Ex(pbyMacHdr, cbLen, dwCRC);
-        pdwCRC = (u32 *)(pbyMacHdr + cbLen);
-        // finally, we must invert dwCRC to get the correct answer
-        *pdwCRC = ~dwCRC;
-        // Force Error
-        *pdwCRC -= 1;
-    } else {
         cbFrameSize -= cbFCSlen;
-    }
 
     *pcbHeaderLen = cbHeaderLength;
     *pcbTotalLen = cbHeaderLength + cbFrameSize ;
-- 
1.8.1.2



^ permalink raw reply related

* [PATCH 3/3] mwifiex: drop gratuitous ARP frames
From: Bing Zhao @ 2013-08-23 23:48 UTC (permalink / raw)
  To: linux-wireless
  Cc: John W. Linville, Amitkumar Karwar, Avinash Patil,
	Nishant Sarmukadam, Frank Huang, Bing Zhao
In-Reply-To: <1377301703-8853-1-git-send-email-bzhao@marvell.com>

From: Avinash Patil <patila@marvell.com>

This patch adds support for dropping gratuitous ARP frames which is
requirement for WFA Hotspot2.0.

Hotspot2.0 capability is enabled in driver if extended capabilities
IE from BSS descriptor has 11u interworking enabled.

Signed-off-by: Avinash Patil <patila@marvell.com>
Signed-off-by: Bing Zhao <bzhao@marvell.com>
---
 drivers/net/wireless/mwifiex/11n.c      |  6 ++++
 drivers/net/wireless/mwifiex/cfg80211.c |  1 +
 drivers/net/wireless/mwifiex/decl.h     |  9 ++++++
 drivers/net/wireless/mwifiex/init.c     |  1 +
 drivers/net/wireless/mwifiex/main.h     |  1 +
 drivers/net/wireless/mwifiex/sta_rx.c   | 49 +++++++++++++++++++++++++++++++++
 6 files changed, 67 insertions(+)

diff --git a/drivers/net/wireless/mwifiex/11n.c b/drivers/net/wireless/mwifiex/11n.c
index b579a2e..0b803c0 100644
--- a/drivers/net/wireless/mwifiex/11n.c
+++ b/drivers/net/wireless/mwifiex/11n.c
@@ -399,6 +399,12 @@ mwifiex_cmd_append_11n_tlv(struct mwifiex_private *priv,
 		       bss_desc->bcn_ext_cap + sizeof(struct ieee_types_header),
 		       le16_to_cpu(ext_cap->header.len));
 
+		if (hdr->len > 3 &&
+		    ext_cap->ext_capab[3] & WLAN_EXT_CAPA4_INTERWORKING_ENABLED)
+			priv->hs2_enabled = true;
+		else
+			priv->hs2_enabled = false;
+
 		*buffer += sizeof(struct mwifiex_ie_types_extcap) + hdr->len;
 		ret_len += sizeof(struct mwifiex_ie_types_extcap) + hdr->len;
 	}
diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c
index ca149ae..fbad00a 100644
--- a/drivers/net/wireless/mwifiex/cfg80211.c
+++ b/drivers/net/wireless/mwifiex/cfg80211.c
@@ -1508,6 +1508,7 @@ mwifiex_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev,
 		" reason code %d\n", priv->cfg_bssid, reason_code);
 
 	memset(priv->cfg_bssid, 0, ETH_ALEN);
+	priv->hs2_enabled = false;
 
 	return 0;
 }
diff --git a/drivers/net/wireless/mwifiex/decl.h b/drivers/net/wireless/mwifiex/decl.h
index a599347..5c85d78 100644
--- a/drivers/net/wireless/mwifiex/decl.h
+++ b/drivers/net/wireless/mwifiex/decl.h
@@ -26,6 +26,7 @@
 #include <linux/wait.h>
 #include <linux/timer.h>
 #include <linux/ieee80211.h>
+#include <uapi/linux/if_arp.h>
 #include <net/mac80211.h>
 
 
@@ -152,4 +153,12 @@ struct mwifiex_types_wmm_info {
 	u8 reserved;
 	struct ieee_types_wmm_ac_parameters ac_params[IEEE80211_NUM_ACS];
 } __packed;
+
+struct mwifiex_arp_eth_header {
+	struct arphdr hdr;
+	u8 ar_sha[ETH_ALEN];
+	u8 ar_sip[4];
+	u8 ar_tha[ETH_ALEN];
+	u8 ar_tip[4];
+} __packed;
 #endif /* !_MWIFIEX_DECL_H_ */
diff --git a/drivers/net/wireless/mwifiex/init.c b/drivers/net/wireless/mwifiex/init.c
index e021a58..6499117 100644
--- a/drivers/net/wireless/mwifiex/init.c
+++ b/drivers/net/wireless/mwifiex/init.c
@@ -136,6 +136,7 @@ int mwifiex_init_priv(struct mwifiex_private *priv)
 	priv->csa_chan = 0;
 	priv->csa_expire_time = 0;
 	priv->del_list_idx = 0;
+	priv->hs2_enabled = false;
 
 	return mwifiex_add_bss_prio_tbl(priv);
 }
diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h
index d2e5ccd..7d4d137 100644
--- a/drivers/net/wireless/mwifiex/main.h
+++ b/drivers/net/wireless/mwifiex/main.h
@@ -516,6 +516,7 @@ struct mwifiex_private {
 	u8 csa_chan;
 	unsigned long csa_expire_time;
 	u8 del_list_idx;
+	bool hs2_enabled;
 };
 
 enum mwifiex_ba_status {
diff --git a/drivers/net/wireless/mwifiex/sta_rx.c b/drivers/net/wireless/mwifiex/sta_rx.c
index b5c1095..bb22664 100644
--- a/drivers/net/wireless/mwifiex/sta_rx.c
+++ b/drivers/net/wireless/mwifiex/sta_rx.c
@@ -17,6 +17,8 @@
  * this warranty disclaimer.
  */
 
+#include <uapi/linux/ipv6.h>
+#include <net/ndisc.h>
 #include "decl.h"
 #include "ioctl.h"
 #include "util.h"
@@ -25,6 +27,46 @@
 #include "11n_aggr.h"
 #include "11n_rxreorder.h"
 
+/* This function checks if a frame is IPv4 ARP or IPv6 Neighbour advertisement
+ * frame. If frame has both source and destination mac address as same, this
+ * function drops such gratuitous frames.
+ */
+static bool
+mwifiex_discard_gratuitous_arp(struct mwifiex_private *priv,
+			       struct sk_buff *skb)
+{
+	const struct mwifiex_arp_eth_header *arp;
+	struct ethhdr *eth_hdr;
+	struct ipv6hdr *ipv6;
+	struct icmp6hdr *icmpv6;
+
+	eth_hdr = (struct ethhdr *)skb->data;
+	switch (ntohs(eth_hdr->h_proto)) {
+	case ETH_P_ARP:
+		arp = (void *)(skb->data + sizeof(struct ethhdr));
+		if (arp->hdr.ar_op == htons(ARPOP_REPLY) ||
+		    arp->hdr.ar_op == htons(ARPOP_REQUEST)) {
+			if (!memcmp(arp->ar_sip, arp->ar_tip, 4))
+				return true;
+		}
+		break;
+	case ETH_P_IPV6:
+		ipv6 = (void *)(skb->data + sizeof(struct ethhdr));
+		icmpv6 = (void *)(skb->data + sizeof(struct ethhdr) +
+				  sizeof(struct ipv6hdr));
+		if (NDISC_NEIGHBOUR_ADVERTISEMENT == icmpv6->icmp6_type) {
+			if (!memcmp(&ipv6->saddr, &ipv6->daddr,
+				    sizeof(struct in6_addr)))
+				return true;
+		}
+		break;
+	default:
+		break;
+	}
+
+	return false;
+}
+
 /*
  * This function processes the received packet and forwards it
  * to kernel/upper layer.
@@ -90,6 +132,13 @@ int mwifiex_process_rx_packet(struct mwifiex_private *priv,
 	   either the reconstructed EthII frame or the 802.2/llc/snap frame */
 	skb_pull(skb, hdr_chop);
 
+	if (priv->hs2_enabled &&
+	    mwifiex_discard_gratuitous_arp(priv, skb)) {
+		dev_dbg(priv->adapter->dev, "Bypassed Gratuitous ARP\n");
+		dev_kfree_skb_any(skb);
+		return 0;
+	}
+
 	priv->rxpd_rate = local_rx_pd->rx_rate;
 
 	priv->rxpd_htinfo = local_rx_pd->ht_info;
-- 
1.8.2.3


^ permalink raw reply related

* [PATCH 1/3] mwifiex: fix driver unload problem for usb chipsets
From: Bing Zhao @ 2013-08-23 23:48 UTC (permalink / raw)
  To: linux-wireless
  Cc: John W. Linville, Amitkumar Karwar, Avinash Patil,
	Nishant Sarmukadam, Frank Huang, Bing Zhao

From: Amitkumar Karwar <akarwar@marvell.com>

We have usb_deregister() call in our rmmod routine. deauth,
shutdown etc. commands will be sent to FW later when bus
driver calls disconnect handler.

This mechanism works fine with SDIO and PCIe interfaces, but
there is an issue with USB.

USB bus driver returns all URBs submitted for receiving data
and command response immediately after usb_deregister() with
failure status. Hence we don't send deauth, shutdown etc.
command to firmware.

The problem is fixed by moving code from disconnect handler to
rmmod routine for USB interface.

Signed-off-by: Amitkumar Karwar <akarwar@marvell.com>
Signed-off-by: Bing Zhao <bzhao@marvell.com>
---
 drivers/net/wireless/mwifiex/usb.c | 50 +++++++++++++++++++-------------------
 1 file changed, 25 insertions(+), 25 deletions(-)

diff --git a/drivers/net/wireless/mwifiex/usb.c b/drivers/net/wireless/mwifiex/usb.c
index fca98b5..2472d4b 100644
--- a/drivers/net/wireless/mwifiex/usb.c
+++ b/drivers/net/wireless/mwifiex/usb.c
@@ -24,9 +24,9 @@
 
 static const char usbdriver_name[] = "usb8797";
 
-static u8 user_rmmod;
 static struct mwifiex_if_ops usb_ops;
 static struct semaphore add_remove_card_sem;
+static struct usb_card_rec *usb_card;
 
 static struct usb_device_id mwifiex_usb_table[] = {
 	{USB_DEVICE(USB8797_VID, USB8797_PID_1)},
@@ -350,6 +350,7 @@ static int mwifiex_usb_probe(struct usb_interface *intf,
 
 	card->udev = udev;
 	card->intf = intf;
+	usb_card = card;
 
 	pr_debug("info: bcdUSB=%#x Device Class=%#x SubClass=%#x Protocol=%#x\n",
 		 udev->descriptor.bcdUSB, udev->descriptor.bDeviceClass,
@@ -532,7 +533,6 @@ static void mwifiex_usb_disconnect(struct usb_interface *intf)
 {
 	struct usb_card_rec *card = usb_get_intfdata(intf);
 	struct mwifiex_adapter *adapter;
-	int i;
 
 	if (!card || !card->adapter) {
 		pr_err("%s: card or card->adapter is NULL\n", __func__);
@@ -543,27 +543,6 @@ static void mwifiex_usb_disconnect(struct usb_interface *intf)
 	if (!adapter->priv_num)
 		return;
 
-	/* In case driver is removed when asynchronous FW downloading is
-	 * in progress
-	 */
-	wait_for_completion(&adapter->fw_load);
-
-	if (user_rmmod) {
-#ifdef CONFIG_PM
-		if (adapter->is_suspended)
-			mwifiex_usb_resume(intf);
-#endif
-		for (i = 0; i < adapter->priv_num; i++)
-			if ((GET_BSS_ROLE(adapter->priv[i]) ==
-			     MWIFIEX_BSS_ROLE_STA) &&
-			    adapter->priv[i]->media_connected)
-				mwifiex_deauthenticate(adapter->priv[i], NULL);
-
-		mwifiex_init_shutdown_fw(mwifiex_get_priv(adapter,
-							  MWIFIEX_BSS_ROLE_ANY),
-					 MWIFIEX_FUNC_SHUTDOWN);
-	}
-
 	mwifiex_usb_free(card);
 
 	dev_dbg(adapter->dev, "%s: removing card\n", __func__);
@@ -1032,8 +1011,29 @@ static void mwifiex_usb_cleanup_module(void)
 	if (!down_interruptible(&add_remove_card_sem))
 		up(&add_remove_card_sem);
 
-	/* set the flag as user is removing this module */
-	user_rmmod = 1;
+	if (usb_card) {
+		struct mwifiex_adapter *adapter = usb_card->adapter;
+		int i;
+
+		/* In case driver is removed when asynchronous FW downloading is
+		 * in progress
+		 */
+		wait_for_completion(&adapter->fw_load);
+
+#ifdef CONFIG_PM
+		if (adapter->is_suspended)
+			mwifiex_usb_resume(usb_card->intf);
+#endif
+		for (i = 0; i < adapter->priv_num; i++)
+			if ((GET_BSS_ROLE(adapter->priv[i]) ==
+			     MWIFIEX_BSS_ROLE_STA) &&
+			    adapter->priv[i]->media_connected)
+				mwifiex_deauthenticate(adapter->priv[i], NULL);
+
+		mwifiex_init_shutdown_fw(mwifiex_get_priv(adapter,
+							  MWIFIEX_BSS_ROLE_ANY),
+					 MWIFIEX_FUNC_SHUTDOWN);
+	}
 
 	usb_deregister(&mwifiex_usb_driver);
 }
-- 
1.8.2.3


^ permalink raw reply related

* [PATCH 2/3] mwifiex: fix ext_capab IE structure definition
From: Bing Zhao @ 2013-08-23 23:48 UTC (permalink / raw)
  To: linux-wireless
  Cc: John W. Linville, Amitkumar Karwar, Avinash Patil,
	Nishant Sarmukadam, Frank Huang, Bing Zhao
In-Reply-To: <1377301703-8853-1-git-send-email-bzhao@marvell.com>

From: Avinash Patil <patila@marvell.com>

EXT_CAPAB_IE format involves IEEE header followed by bytestream of
capabilities. Current structure has incorrect member u8 for data;
fix it by defining it as u8[0].

Signed-off-by: Avinash Patil <patila@marvell.com>
Signed-off-by: Bing Zhao <bzhao@marvell.com>
---
 drivers/net/wireless/mwifiex/11n.c | 10 ++++++----
 drivers/net/wireless/mwifiex/fw.h  |  2 +-
 2 files changed, 7 insertions(+), 5 deletions(-)

diff --git a/drivers/net/wireless/mwifiex/11n.c b/drivers/net/wireless/mwifiex/11n.c
index 41e9d25..b579a2e 100644
--- a/drivers/net/wireless/mwifiex/11n.c
+++ b/drivers/net/wireless/mwifiex/11n.c
@@ -292,6 +292,7 @@ mwifiex_cmd_append_11n_tlv(struct mwifiex_private *priv,
 	struct mwifiex_ie_types_extcap *ext_cap;
 	int ret_len = 0;
 	struct ieee80211_supported_band *sband;
+	struct ieee_types_header *hdr;
 	u8 radio_type;
 
 	if (!buffer || !*buffer)
@@ -388,17 +389,18 @@ mwifiex_cmd_append_11n_tlv(struct mwifiex_private *priv,
 	}
 
 	if (bss_desc->bcn_ext_cap) {
+		hdr = (void *)bss_desc->bcn_ext_cap;
 		ext_cap = (struct mwifiex_ie_types_extcap *) *buffer;
 		memset(ext_cap, 0, sizeof(struct mwifiex_ie_types_extcap));
 		ext_cap->header.type = cpu_to_le16(WLAN_EID_EXT_CAPABILITY);
-		ext_cap->header.len = cpu_to_le16(sizeof(ext_cap->ext_cap));
+		ext_cap->header.len = cpu_to_le16(hdr->len);
 
-		memcpy((u8 *)ext_cap + sizeof(struct mwifiex_ie_types_header),
+		memcpy((u8 *)ext_cap->ext_capab,
 		       bss_desc->bcn_ext_cap + sizeof(struct ieee_types_header),
 		       le16_to_cpu(ext_cap->header.len));
 
-		*buffer += sizeof(struct mwifiex_ie_types_extcap);
-		ret_len += sizeof(struct mwifiex_ie_types_extcap);
+		*buffer += sizeof(struct mwifiex_ie_types_extcap) + hdr->len;
+		ret_len += sizeof(struct mwifiex_ie_types_extcap) + hdr->len;
 	}
 
 	return ret_len;
diff --git a/drivers/net/wireless/mwifiex/fw.h b/drivers/net/wireless/mwifiex/fw.h
index c9ad1c0..f80f30b 100644
--- a/drivers/net/wireless/mwifiex/fw.h
+++ b/drivers/net/wireless/mwifiex/fw.h
@@ -1330,7 +1330,7 @@ struct mwifiex_ie_types_2040bssco {
 
 struct mwifiex_ie_types_extcap {
 	struct mwifiex_ie_types_header header;
-	u8 ext_cap;
+	u8 ext_capab[0];
 } __packed;
 
 struct host_cmd_ds_mac_reg_access {
-- 
1.8.2.3


^ permalink raw reply related

* Re: [PATCH v2 13/16] wcn36xx: add wcn36xx.h
From: Joe Perches @ 2013-08-23 23:02 UTC (permalink / raw)
  To: Eugene Krasnikov; +Cc: linux-wireless, wcn36xx
In-Reply-To: <1377248299-21007-14-git-send-email-k.eugene.e@gmail.com>

On Fri, 2013-08-23 at 10:58 +0200, Eugene Krasnikov wrote:
> Adding wcn36xx.h
[]
> +#define wcn36xx_err(fmt, arg...)				\
> +	printk(KERN_ERR pr_fmt("ERROR " fmt), ##arg);
> +
> +#define wcn36xx_warn(fmt, arg...)				\
> +	printk(KERN_WARNING pr_fmt("WARNING " fmt), ##arg)
> +
> +#define wcn36xx_info(fmt, arg...)		\
> +	printk(KERN_INFO pr_fmt(fmt), ##arg)
> +

I these would be better using:

#define wcn36xx_err(fmt, ...)					\
	pr_err("ERROR " fmt, ##__VA_ARGS__)

etc...

> +#define wcn36xx_dbg(mask, fmt, arg...) do {			\
> +	if (debug_mask & mask)					\
> +		printk(KERN_DEBUG pr_fmt(fmt), ##arg);	\
> +} while (0)

And maybe this one using pr_debug so dynamic_debug
can work too.



^ permalink raw reply

* [PATCH 5/5] b43: call PCIe up and down functions
From: Hauke Mehrtens @ 2013-08-23 22:32 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, zajec5, Hauke Mehrtens
In-Reply-To: <1377297154-14525-1-git-send-email-hauke@hauke-m.de>

Tell the PCIe host core when the wifi is activated.

Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
---
 drivers/net/wireless/b43/main.c |   14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
index 0e933bb..ccd24f0a 100644
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -4645,6 +4645,19 @@ static void b43_wireless_core_exit(struct b43_wldev *dev)
 	b43_maskset32(dev, B43_MMIO_MACCTL, ~B43_MACCTL_PSM_RUN,
 		      B43_MACCTL_PSM_JMP0);
 
+	switch (dev->dev->bus_type) {
+#ifdef CONFIG_B43_BCMA
+	case B43_BUS_BCMA:
+		bcma_core_pci_down(dev->dev->bdev->bus);
+		break;
+#endif
+#ifdef CONFIG_B43_SSB
+	case B43_BUS_SSB:
+		/* TODO */
+		break;
+#endif
+	}
+
 	b43_dma_free(dev);
 	b43_pio_free(dev);
 	b43_chip_exit(dev);
@@ -4684,6 +4697,7 @@ static int b43_wireless_core_init(struct b43_wldev *dev)
 	case B43_BUS_BCMA:
 		bcma_core_pci_irq_ctl(&dev->dev->bdev->bus->drv_pci[0],
 				      dev->dev->bdev, true);
+		bcma_core_pci_up(dev->dev->bdev->bus);
 		break;
 #endif
 #ifdef CONFIG_B43_SSB
-- 
1.7.10.4


^ permalink raw reply related

* [PATCH 4/5] bcma: add bcma_core_pci_power_save()
From: Hauke Mehrtens @ 2013-08-23 22:32 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, zajec5, Hauke Mehrtens
In-Reply-To: <1377297154-14525-1-git-send-email-hauke@hauke-m.de>

This enables or disables power saving on the PCIe bus when the wifi is
in operation or not.

Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
---
 drivers/bcma/driver_pci.c            |   36 +++++++++++++++++++++++++++++++---
 include/linux/bcma/bcma_driver_pci.h |   20 +++++++++++++++++++
 2 files changed, 53 insertions(+), 3 deletions(-)

diff --git a/drivers/bcma/driver_pci.c b/drivers/bcma/driver_pci.c
index d51d194..c9fd694 100644
--- a/drivers/bcma/driver_pci.c
+++ b/drivers/bcma/driver_pci.c
@@ -31,7 +31,7 @@ static void bcma_pcie_write(struct bcma_drv_pci *pc, u32 address, u32 data)
 	pcicore_write32(pc, BCMA_CORE_PCI_PCIEIND_DATA, data);
 }
 
-static void bcma_pcie_mdio_set_phy(struct bcma_drv_pci *pc, u8 phy)
+static void bcma_pcie_mdio_set_phy(struct bcma_drv_pci *pc, u16 phy)
 {
 	u32 v;
 	int i;
@@ -55,7 +55,7 @@ static void bcma_pcie_mdio_set_phy(struct bcma_drv_pci *pc, u8 phy)
 	}
 }
 
-static u16 bcma_pcie_mdio_read(struct bcma_drv_pci *pc, u8 device, u8 address)
+static u16 bcma_pcie_mdio_read(struct bcma_drv_pci *pc, u16 device, u8 address)
 {
 	int max_retries = 10;
 	u16 ret = 0;
@@ -98,7 +98,7 @@ static u16 bcma_pcie_mdio_read(struct bcma_drv_pci *pc, u8 device, u8 address)
 	return ret;
 }
 
-static void bcma_pcie_mdio_write(struct bcma_drv_pci *pc, u8 device,
+static void bcma_pcie_mdio_write(struct bcma_drv_pci *pc, u16 device,
 				u8 address, u16 data)
 {
 	int max_retries = 10;
@@ -137,6 +137,13 @@ static void bcma_pcie_mdio_write(struct bcma_drv_pci *pc, u8 device,
 	pcicore_write32(pc, BCMA_CORE_PCI_MDIO_CONTROL, 0);
 }
 
+static u16 bcma_pcie_mdio_writeread(struct bcma_drv_pci *pc, u16 device,
+				    u8 address, u16 data)
+{
+	bcma_pcie_mdio_write(pc, device, address, data);
+	return bcma_pcie_mdio_read(pc, device, address);
+}
+
 /**************************************************
  * Workarounds.
  **************************************************/
@@ -203,6 +210,25 @@ static void bcma_core_pci_config_fixup(struct bcma_drv_pci *pc)
 	}
 }
 
+static void bcma_core_pci_power_save(struct bcma_drv_pci *pc, bool up)
+{
+	u16 data;
+
+	if (pc->core->id.rev >= 15 && pc->core->id.rev <= 20) {
+		data = up ? 0x74 : 0x7C;
+		bcma_pcie_mdio_writeread(pc, BCMA_CORE_PCI_MDIO_BLK1,
+					 BCMA_CORE_PCI_MDIO_BLK1_MGMT1, 0x7F64);
+		bcma_pcie_mdio_writeread(pc, BCMA_CORE_PCI_MDIO_BLK1,
+					 BCMA_CORE_PCI_MDIO_BLK1_MGMT3, data);
+	} else if (pc->core->id.rev >= 21 && pc->core->id.rev <= 22) {
+		data = up ? 0x75 : 0x7D;
+		bcma_pcie_mdio_writeread(pc, BCMA_CORE_PCI_MDIO_BLK1,
+					 BCMA_CORE_PCI_MDIO_BLK1_MGMT1, 0x7E65);
+		bcma_pcie_mdio_writeread(pc, BCMA_CORE_PCI_MDIO_BLK1,
+					 BCMA_CORE_PCI_MDIO_BLK1_MGMT3, data);
+	}
+}
+
 /**************************************************
  * Init.
  **************************************************/
@@ -284,6 +310,8 @@ void bcma_core_pci_up(struct bcma_bus *bus)
 
 	pc = &bus->drv_pci[0];
 
+	bcma_core_pci_power_save(pc, true);
+
 	bcma_core_pci_extend_L1timer(pc, true);
 }
 EXPORT_SYMBOL_GPL(bcma_core_pci_up);
@@ -298,5 +326,7 @@ void bcma_core_pci_down(struct bcma_bus *bus)
 	pc = &bus->drv_pci[0];
 
 	bcma_core_pci_extend_L1timer(pc, false);
+
+	bcma_core_pci_power_save(pc, false);
 }
 EXPORT_SYMBOL_GPL(bcma_core_pci_down);
diff --git a/include/linux/bcma/bcma_driver_pci.h b/include/linux/bcma/bcma_driver_pci.h
index 0234955..d66033f 100644
--- a/include/linux/bcma/bcma_driver_pci.h
+++ b/include/linux/bcma/bcma_driver_pci.h
@@ -181,6 +181,26 @@ struct pci_dev;
 
 #define BCMA_CORE_PCI_CFG_DEVCTRL		0xd8
 
+#define BCMA_CORE_PCI_
+
+/* MDIO devices (SERDES modules) */
+#define BCMA_CORE_PCI_MDIO_IEEE0		0x000
+#define BCMA_CORE_PCI_MDIO_IEEE1		0x001
+#define BCMA_CORE_PCI_MDIO_BLK0			0x800
+#define BCMA_CORE_PCI_MDIO_BLK1			0x801
+#define  BCMA_CORE_PCI_MDIO_BLK1_MGMT0		0x16
+#define  BCMA_CORE_PCI_MDIO_BLK1_MGMT1		0x17
+#define  BCMA_CORE_PCI_MDIO_BLK1_MGMT2		0x18
+#define  BCMA_CORE_PCI_MDIO_BLK1_MGMT3		0x19
+#define  BCMA_CORE_PCI_MDIO_BLK1_MGMT4		0x1A
+#define BCMA_CORE_PCI_MDIO_BLK2			0x802
+#define BCMA_CORE_PCI_MDIO_BLK3			0x803
+#define BCMA_CORE_PCI_MDIO_BLK4			0x804
+#define BCMA_CORE_PCI_MDIO_TXPLL		0x808	/* TXPLL register block idx */
+#define BCMA_CORE_PCI_MDIO_TXCTRL0		0x820
+#define BCMA_CORE_PCI_MDIO_SERDESID		0x831
+#define BCMA_CORE_PCI_MDIO_RXCTRL0		0x840
+
 /* PCIE Root Capability Register bits (Host mode only) */
 #define BCMA_CORE_PCI_RC_CRS_VISIBILITY		0x0001
 
-- 
1.7.10.4


^ permalink raw reply related

* [PATCH 3/5] bcma: do not export bcma_core_pci_extend_L1timer()
From: Hauke Mehrtens @ 2013-08-23 22:32 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, zajec5, Hauke Mehrtens
In-Reply-To: <1377297154-14525-1-git-send-email-hauke@hauke-m.de>

This is not called any more, do not export it.

Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
---
 drivers/bcma/driver_pci.c            |    3 +--
 include/linux/bcma/bcma_driver_pci.h |    1 -
 2 files changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/bcma/driver_pci.c b/drivers/bcma/driver_pci.c
index 6ea817f..d51d194 100644
--- a/drivers/bcma/driver_pci.c
+++ b/drivers/bcma/driver_pci.c
@@ -262,7 +262,7 @@ out:
 }
 EXPORT_SYMBOL_GPL(bcma_core_pci_irq_ctl);
 
-void bcma_core_pci_extend_L1timer(struct bcma_drv_pci *pc, bool extend)
+static void bcma_core_pci_extend_L1timer(struct bcma_drv_pci *pc, bool extend)
 {
 	u32 w;
 
@@ -274,7 +274,6 @@ void bcma_core_pci_extend_L1timer(struct bcma_drv_pci *pc, bool extend)
 	bcma_pcie_write(pc, BCMA_CORE_PCI_DLLP_PMTHRESHREG, w);
 	bcma_pcie_read(pc, BCMA_CORE_PCI_DLLP_PMTHRESHREG);
 }
-EXPORT_SYMBOL_GPL(bcma_core_pci_extend_L1timer);
 
 void bcma_core_pci_up(struct bcma_bus *bus)
 {
diff --git a/include/linux/bcma/bcma_driver_pci.h b/include/linux/bcma/bcma_driver_pci.h
index 27f9ceb..0234955 100644
--- a/include/linux/bcma/bcma_driver_pci.h
+++ b/include/linux/bcma/bcma_driver_pci.h
@@ -220,7 +220,6 @@ struct bcma_drv_pci {
 extern void bcma_core_pci_init(struct bcma_drv_pci *pc);
 extern int bcma_core_pci_irq_ctl(struct bcma_drv_pci *pc,
 				 struct bcma_device *core, bool enable);
-extern void bcma_core_pci_extend_L1timer(struct bcma_drv_pci *pc, bool extend);
 extern void bcma_core_pci_up(struct bcma_bus *bus);
 extern void bcma_core_pci_down(struct bcma_bus *bus);
 
-- 
1.7.10.4


^ permalink raw reply related

* [PATCH 2/5] brcmsmac: use bcma PCIe up and down functions
From: Hauke Mehrtens @ 2013-08-23 22:32 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, zajec5, Hauke Mehrtens, Arend van Spriel
In-Reply-To: <1377297154-14525-1-git-send-email-hauke@hauke-m.de>

replace the calls to bcma_core_pci_extend_L1timer() by calls to the
newly introduced bcma_core_pci_ip() and bcma_core_pci_down()

Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
Cc: Arend van Spriel <arend@broadcom.com>
---
 drivers/net/wireless/brcm80211/brcmsmac/aiutils.c |   21 ---------------------
 drivers/net/wireless/brcm80211/brcmsmac/aiutils.h |    3 ---
 drivers/net/wireless/brcm80211/brcmsmac/main.c    |    8 ++++----
 3 files changed, 4 insertions(+), 28 deletions(-)

diff --git a/drivers/net/wireless/brcm80211/brcmsmac/aiutils.c b/drivers/net/wireless/brcm80211/brcmsmac/aiutils.c
index e4fd1ee..5336597 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/aiutils.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/aiutils.c
@@ -679,27 +679,6 @@ bool ai_clkctl_cc(struct si_pub *sih, enum bcma_clkmode mode)
 	return mode == BCMA_CLKMODE_FAST;
 }
 
-void ai_pci_up(struct si_pub *sih)
-{
-	struct si_info *sii;
-
-	sii = container_of(sih, struct si_info, pub);
-
-	if (sii->icbus->hosttype == BCMA_HOSTTYPE_PCI)
-		bcma_core_pci_extend_L1timer(&sii->icbus->drv_pci[0], true);
-}
-
-/* Unconfigure and/or apply various WARs when going down */
-void ai_pci_down(struct si_pub *sih)
-{
-	struct si_info *sii;
-
-	sii = container_of(sih, struct si_info, pub);
-
-	if (sii->icbus->hosttype == BCMA_HOSTTYPE_PCI)
-		bcma_core_pci_extend_L1timer(&sii->icbus->drv_pci[0], false);
-}
-
 /* Enable BT-COEX & Ex-PA for 4313 */
 void ai_epa_4313war(struct si_pub *sih)
 {
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/aiutils.h b/drivers/net/wireless/brcm80211/brcmsmac/aiutils.h
index 89562c1..a8a267b 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/aiutils.h
+++ b/drivers/net/wireless/brcm80211/brcmsmac/aiutils.h
@@ -183,9 +183,6 @@ extern u16 ai_clkctl_fast_pwrup_delay(struct si_pub *sih);
 extern bool ai_clkctl_cc(struct si_pub *sih, enum bcma_clkmode mode);
 extern bool ai_deviceremoved(struct si_pub *sih);
 
-extern void ai_pci_down(struct si_pub *sih);
-extern void ai_pci_up(struct si_pub *sih);
-
 /* Enable Ex-PA for 4313 */
 extern void ai_epa_4313war(struct si_pub *sih);
 
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/main.c b/drivers/net/wireless/brcm80211/brcmsmac/main.c
index c3c6123..4608e0e 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/main.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c
@@ -4669,7 +4669,7 @@ static int brcms_b_attach(struct brcms_c_info *wlc, struct bcma_device *core,
 	brcms_c_coredisable(wlc_hw);
 
 	/* Match driver "down" state */
-	ai_pci_down(wlc_hw->sih);
+	bcma_core_pci_down(wlc_hw->d11core->bus);
 
 	/* turn off pll and xtal to match driver "down" state */
 	brcms_b_xtal(wlc_hw, OFF);
@@ -5012,12 +5012,12 @@ static int brcms_b_up_prep(struct brcms_hardware *wlc_hw)
 	 */
 	if (brcms_b_radio_read_hwdisabled(wlc_hw)) {
 		/* put SB PCI in down state again */
-		ai_pci_down(wlc_hw->sih);
+		bcma_core_pci_down(wlc_hw->d11core->bus);
 		brcms_b_xtal(wlc_hw, OFF);
 		return -ENOMEDIUM;
 	}
 
-	ai_pci_up(wlc_hw->sih);
+	bcma_core_pci_up(wlc_hw->d11core->bus);
 
 	/* reset the d11 core */
 	brcms_b_corereset(wlc_hw, BRCMS_USE_COREFLAGS);
@@ -5214,7 +5214,7 @@ static int brcms_b_down_finish(struct brcms_hardware *wlc_hw)
 
 		/* turn off primary xtal and pll */
 		if (!wlc_hw->noreset) {
-			ai_pci_down(wlc_hw->sih);
+			bcma_core_pci_down(wlc_hw->d11core->bus);
 			brcms_b_xtal(wlc_hw, OFF);
 		}
 	}
-- 
1.7.10.4


^ permalink raw reply related

* [PATCH 1/5] bcma: add method to power up and down the PCIe core by wifi driver
From: Hauke Mehrtens @ 2013-08-23 22:32 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, zajec5, Hauke Mehrtens

The wifi driver should tell the PCIe core that it is now in operation
so that some workarounds can be applied and the power state is changed.
This should replace the call to bcma_core_pci_extend_L1timer by the
brcmsmac driver.

Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
---
 drivers/bcma/driver_pci.c            |   26 ++++++++++++++++++++++++++
 include/linux/bcma/bcma_driver_pci.h |    3 +++
 2 files changed, 29 insertions(+)

diff --git a/drivers/bcma/driver_pci.c b/drivers/bcma/driver_pci.c
index cf7a476..6ea817f 100644
--- a/drivers/bcma/driver_pci.c
+++ b/drivers/bcma/driver_pci.c
@@ -275,3 +275,29 @@ void bcma_core_pci_extend_L1timer(struct bcma_drv_pci *pc, bool extend)
 	bcma_pcie_read(pc, BCMA_CORE_PCI_DLLP_PMTHRESHREG);
 }
 EXPORT_SYMBOL_GPL(bcma_core_pci_extend_L1timer);
+
+void bcma_core_pci_up(struct bcma_bus *bus)
+{
+	struct bcma_drv_pci *pc;
+
+	if (bus->hosttype != BCMA_HOSTTYPE_PCI)
+		return;
+
+	pc = &bus->drv_pci[0];
+
+	bcma_core_pci_extend_L1timer(pc, true);
+}
+EXPORT_SYMBOL_GPL(bcma_core_pci_up);
+
+void bcma_core_pci_down(struct bcma_bus *bus)
+{
+	struct bcma_drv_pci *pc;
+
+	if (bus->hosttype != BCMA_HOSTTYPE_PCI)
+		return;
+
+	pc = &bus->drv_pci[0];
+
+	bcma_core_pci_extend_L1timer(pc, false);
+}
+EXPORT_SYMBOL_GPL(bcma_core_pci_down);
diff --git a/include/linux/bcma/bcma_driver_pci.h b/include/linux/bcma/bcma_driver_pci.h
index 424760f..27f9ceb 100644
--- a/include/linux/bcma/bcma_driver_pci.h
+++ b/include/linux/bcma/bcma_driver_pci.h
@@ -185,6 +185,7 @@ struct pci_dev;
 #define BCMA_CORE_PCI_RC_CRS_VISIBILITY		0x0001
 
 struct bcma_drv_pci;
+struct bcma_bus;
 
 #ifdef CONFIG_BCMA_DRIVER_PCI_HOSTMODE
 struct bcma_drv_pci_host {
@@ -220,6 +221,8 @@ extern void bcma_core_pci_init(struct bcma_drv_pci *pc);
 extern int bcma_core_pci_irq_ctl(struct bcma_drv_pci *pc,
 				 struct bcma_device *core, bool enable);
 extern void bcma_core_pci_extend_L1timer(struct bcma_drv_pci *pc, bool extend);
+extern void bcma_core_pci_up(struct bcma_bus *bus);
+extern void bcma_core_pci_down(struct bcma_bus *bus);
 
 extern int bcma_core_pci_pcibios_map_irq(const struct pci_dev *dev);
 extern int bcma_core_pci_plat_dev_init(struct pci_dev *dev);
-- 
1.7.10.4


^ permalink raw reply related

* [PATCH] bcma: change max PCI read request size to 128
From: Hauke Mehrtens @ 2013-08-23 21:22 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, zajec5, Hauke Mehrtens

This PCIe controller does not support a max read request size above 128
bytes. The sold card I tested this controller with used 128 as default
value, but some new routers are sold with BCM4331 chips, which have a
default max read request size of 512. This device fails at the first
DMA reqeust whch is bigger than 126 bytes.

This patch changes the max read request size to 128 for every device on
the PCIe link.

Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
---
 drivers/bcma/driver_pci_host.c |    6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/drivers/bcma/driver_pci_host.c b/drivers/bcma/driver_pci_host.c
index 30629a3..c3d7b03 100644
--- a/drivers/bcma/driver_pci_host.c
+++ b/drivers/bcma/driver_pci_host.c
@@ -581,6 +581,7 @@ DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, bcma_core_pci_fixup_addresses);
 int bcma_core_pci_plat_dev_init(struct pci_dev *dev)
 {
 	struct bcma_drv_pci_host *pc_host;
+	int readrq;
 
 	if (dev->bus->ops->read != bcma_core_pci_hostmode_read_config) {
 		/* This is not a device on the PCI-core bridge. */
@@ -595,6 +596,11 @@ int bcma_core_pci_plat_dev_init(struct pci_dev *dev)
 	dev->irq = bcma_core_irq(pc_host->pdev->core);
 	pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
 
+	readrq = pcie_get_readrq(dev);
+	if (readrq > 128) {
+		pr_info("change PCIe max read request size from %i to 128\n", readrq);
+		pcie_set_readrq(dev, 128);
+	}
 	return 0;
 }
 EXPORT_SYMBOL(bcma_core_pci_plat_dev_init);
-- 
1.7.10.4


^ permalink raw reply related

* Re: travelling...
From: Antonio Quartulli @ 2013-08-23 20:16 UTC (permalink / raw)
  To: David Miller, netdev, linux-wireless, netfilter-devel
In-Reply-To: <20130823182943.GE808@order.stressinduktion.org>

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

On Fri, Aug 23, 2013 at 08:29:43PM +0200, Hannes Frederic Sowa wrote:
> On Fri, Aug 23, 2013 at 11:13:08AM -0700, David Miller wrote:
> > 
> > I'm travelling over the weekend so I won't be as responsive as
> > usual.
> > 
> > I just pushed 'net' to Linus and he pulled it in.  I plan to work
> > on my next set of -stable submissions this coming Monday.
> > 
> > If a merge of 'net' into 'net-next' would be useful for someone,
> > now would be a really good time to tell me.
> 
> If it would not take you too much time, it would be nice. I depend on
> a change in net to make another small patch. :)

If possible I'd need that too in order to send a couple of changes to net-next.

Have a nice weekend!


-- 
Antonio Quartulli

..each of us alone is worth nothing..
Ernesto "Che" Guevara

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

^ permalink raw reply


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