Linux wireless drivers development
 help / color / mirror / Atom feed
* ath9k doesn't clean up virtual wifis on rmmod, and crashes.
From: Ben Greear @ 2010-07-03  6:26 UTC (permalink / raw)
  To: linux-wireless

It seems to me that in 2.6.34, there is no code to clean up
virtual wiphys in ath9k on rmmod.  Also, ath9k mailing list
is returning error about mis-configured DNS server.

This is with un-modified ath9k driver and is repeatable
every time on my system (crash is often different, but
it always crashes very quickly).

[root@atom ~]# echo add=5 > /debug/ath9k/phy1/wiphy
-bash: /debug/ath9k/phy1/wiphy: No such file or directory
[root@atom ~]# echo add=5 > /debug/ath9k/phy0/wiphy
Jul  2 23:22:19 atom kernel: phy1: Selected rate control algorithm 'ath9k_rate_control'
[root@atom ~]# Jul  2 23:22:19 atom kernel: ADDRCONF(NETDEV_UP): wlan1: link is not ready
rmmod ath9k
Jul  2 23:22:24 atom kernel: ath9k 0000:05:00.0: PCI INT A disabled
Jul  2 23:22:24 atom kernel: ath9k: Driver unloaded
[root@atom ~]# BUG: spinlock bad magic on CPU#1, iw/2877
  lock: f8a476c0, .magic: 00000000, .owner: <none>/-1, .owner_cpu: 0
Pid: 2877, comm: iw Not tainted 2.6.34 #7
Call Trace:
  [<c0730e34>] ? printk+0xf/0x13
  [<c05710d6>] spin_bug+0x7b/0x86
  [<c0440b76>] ? delayed_work_timer_fn+0x0/0x30
  [<c0571171>] do_raw_spin_lock+0x1e/0x125
  [<c042f91e>] ? scheduler_tick+0xd6/0x1c9
  [<c0440b76>] ? delayed_work_timer_fn+0x0/0x30
  [<c0732a6d>] _raw_spin_lock_irqsave+0x1b/0x20
  [<c0440b59>] __queue_work+0x12/0x2f
  [<c0440b76>] ? delayed_work_timer_fn+0x0/0x30
  [<c0440ba4>] delayed_work_timer_fn+0x2e/0x30

I'm new to hacking on this driver..but would love to test
patches, and if someone wants to suggest a good point in
the code to remove the virtual phys, I'll make the attempt.

Thanks,
Ben

-- 
Ben Greear <greearb@candelatech.com>
Candela Technologies Inc  http://www.candelatech.com

^ permalink raw reply

* Re: [PATCH 6/6] ath9k: fix false positives in the baseband hang check
From: Björn Smedman @ 2010-07-03  0:53 UTC (permalink / raw)
  To: Felix Fietkau; +Cc: linux-wireless, linville, lrodriguez
In-Reply-To: <1278022192-83277-6-git-send-email-nbd@openwrt.org>

On Fri, Jul 2, 2010 at 12:09 AM, Felix Fietkau <nbd@openwrt.org> wrote:
> ath9k_hw_check_alive() occasionally returns false, as the hardware
> is still processing data in a specific state. Fix this issue by
> repeating the test a few times with longer delay inbetween attempts.
> This gets rid of excessive hardware resets that appear frequently on
> some AR9132 based devices, but could also happen on AR9280.
>
> Signed-off-by: Felix Fietkau <nbd@openwrt.org>
> Reported-by: Björn Smedman <bjorn.smedman@venatech.se>
> Cc: stable@kernel.org

Tested-by: Björn Smedman <bjorn.smedman@venatech.se>

No false positives.

By the way, ath9k has never felt so solid on AR9100 as after this
patch series. Huge thanx, especially for the initvals update! :)

/Björn

^ permalink raw reply

* Re: [PATCH 2.6.34] mac80211: Fix auth retries if AP sends temporary deauth
From: Paul Stewart @ 2010-07-02 19:57 UTC (permalink / raw)
  To: Johannes Berg; +Cc: linux-wireless, Michael Wu, Jiri Benc, John W. Linville
In-Reply-To: <1278094401.15412.27.camel@jlt3.sipsolutions.net>

Sure enough, your patch works well.  The end effect is correct, in
that despite the reception of the DEAUTH, we are successfully able to
process a successful auth response on the second try.  Do I take it
that this change will make it upstream since this is the case?  Have a
happy wedding, and no git merge until after the ceremony! :-)

--
Paul

On Fri, Jul 2, 2010 at 11:13 AM, Johannes Berg
<johannes@sipsolutions.net> wrote:
> On Fri, 2010-07-02 at 11:09 -0700, Paul Stewart wrote:
> Can you try the patch below instead of yours? I'll explain it a bit more
> later, but my church wedding ceremony is tomorrow :)
>
> johannes
>
> --- wireless-testing.orig/net/wireless/mlme.c   2010-07-02 20:12:19.000000000 +0200
> +++ wireless-testing/net/wireless/mlme.c        2010-07-02 20:12:43.000000000 +0200
> @@ -44,10 +44,10 @@ void cfg80211_send_rx_auth(struct net_de
>                }
>        }
>
> -       WARN_ON(!done);
> -
> -       nl80211_send_rx_auth(rdev, dev, buf, len, GFP_KERNEL);
> -       cfg80211_sme_rx_auth(dev, buf, len);
> +       if (done) {
> +               nl80211_send_rx_auth(rdev, dev, buf, len, GFP_KERNEL);
> +               cfg80211_sme_rx_auth(dev, buf, len);
> +       }
>
>        wdev_unlock(wdev);
>  }
>
>
>

^ permalink raw reply

* Compat-wireless release for 2010-07-02 is baked
From: Compat-wireless cronjob account @ 2010-07-02 19:03 UTC (permalink / raw)
  To: linux-wireless

>From git://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next
   a348d8b..c48fe0c  history    -> origin/history
 + fb4cbff...4985a03 master     -> origin/master  (forced update)
   984bc96..9fbd7f9  stable     -> origin/stable
 * [new tag]         next-20100702 -> next-20100702
cat: /var/opt/compat/compat-wireless-2.6/compat_version: No such file or directory
cat: compat_base_tree: No such file or directory
cat: compat_base_tree_version: No such file or directory
cat: compat_version: No such file or directory
cat: /var/opt/compat/compat-wireless-2.6/compat_version: No such file or directory
scripts/Makefile.clean:17: /var/opt/compat/compat-wireless-2.6/drivers/net/wireless/hostap/Makefile: No such file or directory
make[4]: *** No rule to make target `/var/opt/compat/compat-wireless-2.6/drivers/net/wireless/hostap/Makefile'.  Stop.
make[3]: *** [/var/opt/compat/compat-wireless-2.6/drivers/net/wireless/hostap] Error 2
make[2]: *** [/var/opt/compat/compat-wireless-2.6/drivers/net/wireless] Error 2
make[1]: *** [_clean_/var/opt/compat/compat-wireless-2.6] Error 2
make: *** [clean] Error 2
/usr/bin/sha1sum: *.tar.bz2: No such file or directory

compat-wireless code metrics

    494455 - Total upstream lines of code being pulled

^ permalink raw reply

* [PATCH 8/8] iwlwifi: adding enhance sensitivity table entries
From: Wey-Yi Guy @ 2010-07-02 18:45 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, ipw3945-devel, Wey-Yi Guy
In-Reply-To: <1278096340-2546-1-git-send-email-wey-yi.w.guy@intel.com>

From: Wey-Yi Guy <wey-yi.w.guy@intel.com>

For newer devices (6000g2a and 6000g2b), the sensitivity table send to
uCode require additional table entries to help sensitivity calibration.

All the additional entries has fix data for now, but do expect the value
will be change in the future when device become more stable.

Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
---
 drivers/net/wireless/iwlwifi/iwl-agn-calib.c |  133 ++++++++++++++++++++------
 drivers/net/wireless/iwlwifi/iwl-agn.c       |    6 +
 drivers/net/wireless/iwlwifi/iwl-commands.h  |   43 ++++++++
 drivers/net/wireless/iwlwifi/iwl-dev.h       |    3 +
 4 files changed, 157 insertions(+), 28 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-calib.c b/drivers/net/wireless/iwlwifi/iwl-agn-calib.c
index eb052b0..90033e8 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-calib.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-calib.c
@@ -409,46 +409,34 @@ static int iwl_sens_auto_corr_ofdm(struct iwl_priv *priv,
 	return 0;
 }
 
-/* Prepare a SENSITIVITY_CMD, send to uCode if values have changed */
-static int iwl_sensitivity_write(struct iwl_priv *priv)
+static void iwl_prepare_legacy_sensitivity_tbl(struct iwl_priv *priv,
+				struct iwl_sensitivity_data *data,
+				__le16 *tbl)
 {
-	struct iwl_sensitivity_cmd cmd ;
-	struct iwl_sensitivity_data *data = NULL;
-	struct iwl_host_cmd cmd_out = {
-		.id = SENSITIVITY_CMD,
-		.len = sizeof(struct iwl_sensitivity_cmd),
-		.flags = CMD_ASYNC,
-		.data = &cmd,
-	};
-
-	data = &(priv->sensitivity_data);
-
-	memset(&cmd, 0, sizeof(cmd));
-
-	cmd.table[HD_AUTO_CORR32_X4_TH_ADD_MIN_INDEX] =
+	tbl[HD_AUTO_CORR32_X4_TH_ADD_MIN_INDEX] =
 				cpu_to_le16((u16)data->auto_corr_ofdm);
-	cmd.table[HD_AUTO_CORR32_X4_TH_ADD_MIN_MRC_INDEX] =
+	tbl[HD_AUTO_CORR32_X4_TH_ADD_MIN_MRC_INDEX] =
 				cpu_to_le16((u16)data->auto_corr_ofdm_mrc);
-	cmd.table[HD_AUTO_CORR32_X1_TH_ADD_MIN_INDEX] =
+	tbl[HD_AUTO_CORR32_X1_TH_ADD_MIN_INDEX] =
 				cpu_to_le16((u16)data->auto_corr_ofdm_x1);
-	cmd.table[HD_AUTO_CORR32_X1_TH_ADD_MIN_MRC_INDEX] =
+	tbl[HD_AUTO_CORR32_X1_TH_ADD_MIN_MRC_INDEX] =
 				cpu_to_le16((u16)data->auto_corr_ofdm_mrc_x1);
 
-	cmd.table[HD_AUTO_CORR40_X4_TH_ADD_MIN_INDEX] =
+	tbl[HD_AUTO_CORR40_X4_TH_ADD_MIN_INDEX] =
 				cpu_to_le16((u16)data->auto_corr_cck);
-	cmd.table[HD_AUTO_CORR40_X4_TH_ADD_MIN_MRC_INDEX] =
+	tbl[HD_AUTO_CORR40_X4_TH_ADD_MIN_MRC_INDEX] =
 				cpu_to_le16((u16)data->auto_corr_cck_mrc);
 
-	cmd.table[HD_MIN_ENERGY_CCK_DET_INDEX] =
+	tbl[HD_MIN_ENERGY_CCK_DET_INDEX] =
 				cpu_to_le16((u16)data->nrg_th_cck);
-	cmd.table[HD_MIN_ENERGY_OFDM_DET_INDEX] =
+	tbl[HD_MIN_ENERGY_OFDM_DET_INDEX] =
 				cpu_to_le16((u16)data->nrg_th_ofdm);
 
-	cmd.table[HD_BARKER_CORR_TH_ADD_MIN_INDEX] =
+	tbl[HD_BARKER_CORR_TH_ADD_MIN_INDEX] =
 				cpu_to_le16(data->barker_corr_th_min);
-	cmd.table[HD_BARKER_CORR_TH_ADD_MIN_MRC_INDEX] =
+	tbl[HD_BARKER_CORR_TH_ADD_MIN_MRC_INDEX] =
 				cpu_to_le16(data->barker_corr_th_min_mrc);
-	cmd.table[HD_OFDM_ENERGY_TH_IN_INDEX] =
+	tbl[HD_OFDM_ENERGY_TH_IN_INDEX] =
 				cpu_to_le16(data->nrg_th_cca);
 
 	IWL_DEBUG_CALIB(priv, "ofdm: ac %u mrc %u x1 %u mrc_x1 %u thresh %u\n",
@@ -459,6 +447,25 @@ static int iwl_sensitivity_write(struct iwl_priv *priv)
 	IWL_DEBUG_CALIB(priv, "cck: ac %u mrc %u thresh %u\n",
 			data->auto_corr_cck, data->auto_corr_cck_mrc,
 			data->nrg_th_cck);
+}
+
+/* Prepare a SENSITIVITY_CMD, send to uCode if values have changed */
+static int iwl_sensitivity_write(struct iwl_priv *priv)
+{
+	struct iwl_sensitivity_cmd cmd;
+	struct iwl_sensitivity_data *data = NULL;
+	struct iwl_host_cmd cmd_out = {
+		.id = SENSITIVITY_CMD,
+		.len = sizeof(struct iwl_sensitivity_cmd),
+		.flags = CMD_ASYNC,
+		.data = &cmd,
+	};
+
+	data = &(priv->sensitivity_data);
+
+	memset(&cmd, 0, sizeof(cmd));
+
+	iwl_prepare_legacy_sensitivity_tbl(priv, data, &cmd.table[0]);
 
 	/* Update uCode's "work" table, and copy it to DSP */
 	cmd.control = SENSITIVITY_CMD_CONTROL_WORK_TABLE;
@@ -477,6 +484,70 @@ static int iwl_sensitivity_write(struct iwl_priv *priv)
 	return iwl_send_cmd(priv, &cmd_out);
 }
 
+/* Prepare a SENSITIVITY_CMD, send to uCode if values have changed */
+static int iwl_enhance_sensitivity_write(struct iwl_priv *priv)
+{
+	struct iwl_enhance_sensitivity_cmd cmd;
+	struct iwl_sensitivity_data *data = NULL;
+	struct iwl_host_cmd cmd_out = {
+		.id = SENSITIVITY_CMD,
+		.len = sizeof(struct iwl_enhance_sensitivity_cmd),
+		.flags = CMD_ASYNC,
+		.data = &cmd,
+	};
+
+	data = &(priv->sensitivity_data);
+
+	memset(&cmd, 0, sizeof(cmd));
+
+	iwl_prepare_legacy_sensitivity_tbl(priv, data, &cmd.enhance_table[0]);
+
+	cmd.enhance_table[HD_INA_NON_SQUARE_DET_OFDM_INDEX] =
+		HD_INA_NON_SQUARE_DET_OFDM_DATA;
+	cmd.enhance_table[HD_INA_NON_SQUARE_DET_CCK_INDEX] =
+		HD_INA_NON_SQUARE_DET_CCK_DATA;
+	cmd.enhance_table[HD_CORR_11_INSTEAD_OF_CORR_9_EN_INDEX] =
+		HD_CORR_11_INSTEAD_OF_CORR_9_EN_DATA;
+	cmd.enhance_table[HD_OFDM_NON_SQUARE_DET_SLOPE_MRC_INDEX] =
+		HD_OFDM_NON_SQUARE_DET_SLOPE_MRC_DATA;
+	cmd.enhance_table[HD_OFDM_NON_SQUARE_DET_INTERCEPT_MRC_INDEX] =
+		HD_OFDM_NON_SQUARE_DET_INTERCEPT_MRC_DATA;
+	cmd.enhance_table[HD_OFDM_NON_SQUARE_DET_SLOPE_INDEX] =
+		HD_OFDM_NON_SQUARE_DET_SLOPE_DATA;
+	cmd.enhance_table[HD_OFDM_NON_SQUARE_DET_INTERCEPT_INDEX] =
+		HD_OFDM_NON_SQUARE_DET_INTERCEPT_DATA;
+	cmd.enhance_table[HD_CCK_NON_SQUARE_DET_SLOPE_MRC_INDEX] =
+		HD_CCK_NON_SQUARE_DET_SLOPE_MRC_DATA;
+	cmd.enhance_table[HD_CCK_NON_SQUARE_DET_INTERCEPT_MRC_INDEX] =
+		HD_CCK_NON_SQUARE_DET_INTERCEPT_MRC_DATA;
+	cmd.enhance_table[HD_CCK_NON_SQUARE_DET_SLOPE_INDEX] =
+		HD_CCK_NON_SQUARE_DET_SLOPE_DATA;
+	cmd.enhance_table[HD_CCK_NON_SQUARE_DET_INTERCEPT_INDEX] =
+		HD_CCK_NON_SQUARE_DET_INTERCEPT_DATA;
+
+	/* Update uCode's "work" table, and copy it to DSP */
+	cmd.control = SENSITIVITY_CMD_CONTROL_WORK_TABLE;
+
+	/* Don't send command to uCode if nothing has changed */
+	if (!memcmp(&cmd.enhance_table[0], &(priv->sensitivity_tbl[0]),
+		    sizeof(u16)*HD_TABLE_SIZE) &&
+	    !memcmp(&cmd.enhance_table[HD_INA_NON_SQUARE_DET_OFDM_INDEX],
+		    &(priv->enhance_sensitivity_tbl[0]),
+		    sizeof(u16)*ENHANCE_HD_TABLE_ENTRIES)) {
+		IWL_DEBUG_CALIB(priv, "No change in SENSITIVITY_CMD\n");
+		return 0;
+	}
+
+	/* Copy table for comparison next time */
+	memcpy(&(priv->sensitivity_tbl[0]), &(cmd.enhance_table[0]),
+	       sizeof(u16)*HD_TABLE_SIZE);
+	memcpy(&(priv->enhance_sensitivity_tbl[0]),
+	       &(cmd.enhance_table[HD_INA_NON_SQUARE_DET_OFDM_INDEX]),
+	       sizeof(u16)*ENHANCE_HD_TABLE_ENTRIES);
+
+	return iwl_send_cmd(priv, &cmd_out);
+}
+
 void iwl_init_sensitivity(struct iwl_priv *priv)
 {
 	int ret = 0;
@@ -527,7 +598,10 @@ void iwl_init_sensitivity(struct iwl_priv *priv)
 	data->last_bad_plcp_cnt_cck = 0;
 	data->last_fa_cnt_cck = 0;
 
-	ret |= iwl_sensitivity_write(priv);
+	if (priv->enhance_sensitivity_table)
+		ret |= iwl_enhance_sensitivity_write(priv);
+	else
+		ret |= iwl_sensitivity_write(priv);
 	IWL_DEBUG_CALIB(priv, "<<return 0x%X\n", ret);
 }
 
@@ -633,7 +707,10 @@ void iwl_sensitivity_calibration(struct iwl_priv *priv,
 
 	iwl_sens_auto_corr_ofdm(priv, norm_fa_ofdm, rx_enable_time);
 	iwl_sens_energy_cck(priv, norm_fa_cck, rx_enable_time, &statis);
-	iwl_sensitivity_write(priv);
+	if (priv->enhance_sensitivity_table)
+		iwl_enhance_sensitivity_write(priv);
+	else
+		iwl_sensitivity_write(priv);
 }
 
 static inline u8 find_first_chain(u8 mask)
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index 60af542..66c83b2 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -1961,6 +1961,12 @@ static int iwlagn_load_firmware(struct iwl_priv *priv,
 				pieces->inst_errlog_ptr =
 					le32_to_cpup((__le32 *)tlv_data);
 			break;
+		case IWL_UCODE_TLV_ENHANCE_SENS_TBL:
+			if (tlv_len)
+				ret = -EINVAL;
+			else
+				priv->enhance_sensitivity_table = true;
+			break;
 		default:
 			IWL_WARN(priv, "unknown TLV: %d\n", tlv_type);
 			break;
diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h
index d887b57..a587999 100644
--- a/drivers/net/wireless/iwlwifi/iwl-commands.h
+++ b/drivers/net/wireless/iwlwifi/iwl-commands.h
@@ -3490,6 +3490,41 @@ struct iwl_missed_beacon_notif {
 #define HD_AUTO_CORR40_X4_TH_ADD_MIN_INDEX          (9)
 #define HD_OFDM_ENERGY_TH_IN_INDEX                  (10)
 
+/*
+ * Additional table entries in enhance SENSITIVITY_CMD
+ */
+#define HD_INA_NON_SQUARE_DET_OFDM_INDEX		(11)
+#define HD_INA_NON_SQUARE_DET_CCK_INDEX			(12)
+#define HD_CORR_11_INSTEAD_OF_CORR_9_EN_INDEX		(13)
+#define HD_OFDM_NON_SQUARE_DET_SLOPE_MRC_INDEX		(14)
+#define HD_OFDM_NON_SQUARE_DET_INTERCEPT_MRC_INDEX	(15)
+#define HD_OFDM_NON_SQUARE_DET_SLOPE_INDEX		(16)
+#define HD_OFDM_NON_SQUARE_DET_INTERCEPT_INDEX		(17)
+#define HD_CCK_NON_SQUARE_DET_SLOPE_MRC_INDEX		(18)
+#define HD_CCK_NON_SQUARE_DET_INTERCEPT_MRC_INDEX	(19)
+#define HD_CCK_NON_SQUARE_DET_SLOPE_INDEX		(20)
+#define HD_CCK_NON_SQUARE_DET_INTERCEPT_INDEX		(21)
+#define HD_RESERVED					(22)
+
+/* number of entries for enhanced tbl */
+#define ENHANCE_HD_TABLE_SIZE  (23)
+
+/* number of additional entries for enhanced tbl */
+#define ENHANCE_HD_TABLE_ENTRIES  (ENHANCE_HD_TABLE_SIZE - HD_TABLE_SIZE)
+
+#define HD_INA_NON_SQUARE_DET_OFDM_DATA			cpu_to_le16(0)
+#define HD_INA_NON_SQUARE_DET_CCK_DATA			cpu_to_le16(0)
+#define HD_CORR_11_INSTEAD_OF_CORR_9_EN_DATA		cpu_to_le16(0)
+#define HD_OFDM_NON_SQUARE_DET_SLOPE_MRC_DATA		cpu_to_le16(668)
+#define HD_OFDM_NON_SQUARE_DET_INTERCEPT_MRC_DATA	cpu_to_le16(4)
+#define HD_OFDM_NON_SQUARE_DET_SLOPE_DATA		cpu_to_le16(486)
+#define HD_OFDM_NON_SQUARE_DET_INTERCEPT_DATA		cpu_to_le16(37)
+#define HD_CCK_NON_SQUARE_DET_SLOPE_MRC_DATA		cpu_to_le16(853)
+#define HD_CCK_NON_SQUARE_DET_INTERCEPT_MRC_DATA	cpu_to_le16(4)
+#define HD_CCK_NON_SQUARE_DET_SLOPE_DATA		cpu_to_le16(476)
+#define HD_CCK_NON_SQUARE_DET_INTERCEPT_DATA		cpu_to_le16(99)
+
+
 /* Control field in struct iwl_sensitivity_cmd */
 #define SENSITIVITY_CMD_CONTROL_DEFAULT_TABLE	cpu_to_le16(0)
 #define SENSITIVITY_CMD_CONTROL_WORK_TABLE	cpu_to_le16(1)
@@ -3506,6 +3541,14 @@ struct iwl_sensitivity_cmd {
 	__le16 table[HD_TABLE_SIZE];	/* use HD_* as index */
 } __attribute__ ((packed));
 
+/*
+ *
+ */
+struct iwl_enhance_sensitivity_cmd {
+	__le16 control;			/* always use "1" */
+	__le16 enhance_table[ENHANCE_HD_TABLE_SIZE];	/* use HD_* as index */
+} __attribute__ ((packed));
+
 
 /**
  * REPLY_PHY_CALIBRATION_CMD = 0xb0 (command, has simple generic response)
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index c637376..dff1b17 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -570,6 +570,7 @@ enum iwl_ucode_tlv_type {
 	IWL_UCODE_TLV_INIT_EVTLOG_PTR	= 11,
 	IWL_UCODE_TLV_INIT_EVTLOG_SIZE	= 12,
 	IWL_UCODE_TLV_INIT_ERRLOG_PTR	= 13,
+	IWL_UCODE_TLV_ENHANCE_SENS_TBL	= 14,
 };
 
 struct iwl_ucode_tlv {
@@ -1193,7 +1194,9 @@ struct iwl_priv {
 	u8 start_calib;
 	struct iwl_sensitivity_data sensitivity_data;
 	struct iwl_chain_noise_data chain_noise_data;
+	bool enhance_sensitivity_table;
 	__le16 sensitivity_tbl[HD_TABLE_SIZE];
+	__le16 enhance_sensitivity_tbl[ENHANCE_HD_TABLE_ENTRIES];
 
 	struct iwl_ht_config current_ht_config;
 
-- 
1.7.0.4


^ permalink raw reply related

* [PATCH 6/8] iwlwifi: debugfs file for txfifo command testing
From: Wey-Yi Guy @ 2010-07-02 18:45 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, ipw3945-devel, Wey-Yi Guy, Reinette Chatre
In-Reply-To: <1278096340-2546-1-git-send-email-wey-yi.w.guy@intel.com>

From: Wey-Yi Guy <wey-yi.w.guy@intel.com>

Add debugfs file for REPLY_TXFIFO_FLUSH host command testing.

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

diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
index 48f8908..088a2c1 100644
--- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
@@ -1495,6 +1495,30 @@ static ssize_t iwl_dbgfs_force_reset_write(struct file *file,
 	return ret ? ret : count;
 }
 
+static ssize_t iwl_dbgfs_txfifo_flush_write(struct file *file,
+					const char __user *user_buf,
+					size_t count, loff_t *ppos) {
+
+	struct iwl_priv *priv = file->private_data;
+	char buf[8];
+	int buf_size;
+	int flush;
+
+	memset(buf, 0, sizeof(buf));
+	buf_size = min(count, sizeof(buf) -  1);
+	if (copy_from_user(buf, user_buf, buf_size))
+		return -EFAULT;
+	if (sscanf(buf, "%d", &flush) != 1)
+		return -EINVAL;
+
+	if (iwl_is_rfkill(priv))
+		return -EFAULT;
+
+	priv->cfg->ops->lib->dev_txfifo_flush(priv, IWL_DROP_ALL);
+
+	return count;
+}
+
 DEBUGFS_READ_FILE_OPS(rx_statistics);
 DEBUGFS_READ_FILE_OPS(tx_statistics);
 DEBUGFS_READ_WRITE_FILE_OPS(traffic_log);
@@ -1516,6 +1540,7 @@ DEBUGFS_READ_WRITE_FILE_OPS(plcp_delta);
 DEBUGFS_READ_WRITE_FILE_OPS(force_reset);
 DEBUGFS_READ_FILE_OPS(rxon_flags);
 DEBUGFS_READ_FILE_OPS(rxon_filter_flags);
+DEBUGFS_WRITE_FILE_OPS(txfifo_flush);
 
 /*
  * Create the debugfs files and directories
@@ -1574,6 +1599,8 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name)
 	DEBUGFS_ADD_FILE(ucode_rx_stats, dir_debug, S_IRUSR);
 	DEBUGFS_ADD_FILE(ucode_tx_stats, dir_debug, S_IRUSR);
 	DEBUGFS_ADD_FILE(ucode_general_stats, dir_debug, S_IRUSR);
+	if (priv->cfg->ops->lib->dev_txfifo_flush)
+		DEBUGFS_ADD_FILE(txfifo_flush, dir_debug, S_IWUSR);
 
 	if (priv->cfg->sensitivity_calib_by_driver)
 		DEBUGFS_ADD_FILE(sensitivity, dir_debug, S_IRUSR);
-- 
1.7.0.4


^ permalink raw reply related

* [PATCH 7/8] iwlwifi: generic parameter define for _agn device
From: Wey-Yi Guy @ 2010-07-02 18:45 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, ipw3945-devel, Wey-Yi Guy, Reinette Chatre
In-Reply-To: <1278096340-2546-1-git-send-email-wey-yi.w.guy@intel.com>

From: Wey-Yi Guy <wey-yi.w.guy@intel.com>

Code clean up to change name from having 5000 as part of name which easy
to confuse and think it is for 5000 series devices to more
generic _agn name since it is being used by multiple _agn devices.

No functional changes.

Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
---
 drivers/net/wireless/iwlwifi/iwl-1000.c     |    4 ++--
 drivers/net/wireless/iwlwifi/iwl-5000.c     |    8 ++++----
 drivers/net/wireless/iwlwifi/iwl-6000.c     |    4 ++--
 drivers/net/wireless/iwlwifi/iwl-commands.h |    4 ++--
 4 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c
index 96a4888..c281d07 100644
--- a/drivers/net/wireless/iwlwifi/iwl-1000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-1000.c
@@ -129,8 +129,8 @@ static int iwl1000_hw_set_hw_params(struct iwl_priv *priv)
 			priv->cfg->num_of_queues *
 			sizeof(struct iwlagn_scd_bc_tbl);
 	priv->hw_params.tfd_size = sizeof(struct iwl_tfd);
-	priv->hw_params.max_stations = IWL5000_STATION_COUNT;
-	priv->hw_params.bcast_sta_id = IWL5000_BROADCAST_ID;
+	priv->hw_params.max_stations = IWLAGN_STATION_COUNT;
+	priv->hw_params.bcast_sta_id = IWLAGN_BROADCAST_ID;
 
 	priv->hw_params.max_data_size = IWLAGN_RTC_DATA_SIZE;
 	priv->hw_params.max_inst_size = IWLAGN_RTC_INST_SIZE;
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c
index 648d53b..7d89d99 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-5000.c
@@ -179,8 +179,8 @@ static int iwl5000_hw_set_hw_params(struct iwl_priv *priv)
 			priv->cfg->num_of_queues *
 			sizeof(struct iwlagn_scd_bc_tbl);
 	priv->hw_params.tfd_size = sizeof(struct iwl_tfd);
-	priv->hw_params.max_stations = IWL5000_STATION_COUNT;
-	priv->hw_params.bcast_sta_id = IWL5000_BROADCAST_ID;
+	priv->hw_params.max_stations = IWLAGN_STATION_COUNT;
+	priv->hw_params.bcast_sta_id = IWLAGN_BROADCAST_ID;
 
 	priv->hw_params.max_data_size = IWLAGN_RTC_DATA_SIZE;
 	priv->hw_params.max_inst_size = IWLAGN_RTC_INST_SIZE;
@@ -226,8 +226,8 @@ static int iwl5150_hw_set_hw_params(struct iwl_priv *priv)
 			priv->cfg->num_of_queues *
 			sizeof(struct iwlagn_scd_bc_tbl);
 	priv->hw_params.tfd_size = sizeof(struct iwl_tfd);
-	priv->hw_params.max_stations = IWL5000_STATION_COUNT;
-	priv->hw_params.bcast_sta_id = IWL5000_BROADCAST_ID;
+	priv->hw_params.max_stations = IWLAGN_STATION_COUNT;
+	priv->hw_params.bcast_sta_id = IWLAGN_BROADCAST_ID;
 
 	priv->hw_params.max_data_size = IWLAGN_RTC_DATA_SIZE;
 	priv->hw_params.max_inst_size = IWLAGN_RTC_INST_SIZE;
diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c
index 79ba7ad..59681c5 100644
--- a/drivers/net/wireless/iwlwifi/iwl-6000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-6000.c
@@ -160,8 +160,8 @@ static int iwl6000_hw_set_hw_params(struct iwl_priv *priv)
 			priv->cfg->num_of_queues *
 			sizeof(struct iwlagn_scd_bc_tbl);
 	priv->hw_params.tfd_size = sizeof(struct iwl_tfd);
-	priv->hw_params.max_stations = IWL5000_STATION_COUNT;
-	priv->hw_params.bcast_sta_id = IWL5000_BROADCAST_ID;
+	priv->hw_params.max_stations = IWLAGN_STATION_COUNT;
+	priv->hw_params.bcast_sta_id = IWLAGN_BROADCAST_ID;
 
 	priv->hw_params.max_data_size = IWL60_RTC_DATA_SIZE;
 	priv->hw_params.max_inst_size = IWL60_RTC_INST_SIZE;
diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h
index 0844955..d887b57 100644
--- a/drivers/net/wireless/iwlwifi/iwl-commands.h
+++ b/drivers/net/wireless/iwlwifi/iwl-commands.h
@@ -958,8 +958,8 @@ struct iwl_qosparam_cmd {
 #define IWL3945_STATION_COUNT	25
 #define IWL4965_BROADCAST_ID	31
 #define	IWL4965_STATION_COUNT	32
-#define IWL5000_BROADCAST_ID	15
-#define	IWL5000_STATION_COUNT	16
+#define IWLAGN_BROADCAST_ID	15
+#define	IWLAGN_STATION_COUNT	16
 
 #define	IWL_STATION_COUNT	32 	/* MAX(3945,4965)*/
 #define	IWL_INVALID_STATION 	255
-- 
1.7.0.4


^ permalink raw reply related

* [PATCH 5/8] iwlwifi: add support for device tx flush request
From: Wey-Yi Guy @ 2010-07-02 18:45 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, ipw3945-devel, Wey-Yi Guy, Reinette Chatre
In-Reply-To: <1278096340-2546-1-git-send-email-wey-yi.w.guy@intel.com>

From: Wey-Yi Guy <wey-yi.w.guy@intel.com>

"Flush" request can come from two different sources, it can either from
mac80211, or from device when the operation is needed. Here
adding the support for device issue "flush" request.

When receive tx complete with status is TX_STATUS_FAIL_RFKILL_FLUSH,
issue REPLY_TXFIFO_FLUSH command to uCode to flush out all the tx frames
in queues.

In this condition, since mac80211 has no knowledge of "flush" operation,
driver need to stop all the tx queues and wait for the operation
completed before wake up the queues for frames transmission.

Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
---
 drivers/net/wireless/iwlwifi/iwl-1000.c    |    1 +
 drivers/net/wireless/iwlwifi/iwl-5000.c    |    2 ++
 drivers/net/wireless/iwlwifi/iwl-6000.c    |    1 +
 drivers/net/wireless/iwlwifi/iwl-agn-lib.c |   19 ++++++++++++++++++-
 drivers/net/wireless/iwlwifi/iwl-agn.c     |   19 +++++++++++++++++++
 drivers/net/wireless/iwlwifi/iwl-agn.h     |    1 +
 drivers/net/wireless/iwlwifi/iwl-core.h    |    1 +
 drivers/net/wireless/iwlwifi/iwl-dev.h     |    1 +
 8 files changed, 44 insertions(+), 1 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c
index 00808ee..96a4888 100644
--- a/drivers/net/wireless/iwlwifi/iwl-1000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-1000.c
@@ -227,6 +227,7 @@ static struct iwl_lib_ops iwl1000_lib = {
 	.check_plcp_health = iwl_good_plcp_health,
 	.check_ack_health = iwl_good_ack_health,
 	.txfifo_flush = iwlagn_txfifo_flush,
+	.dev_txfifo_flush = iwlagn_dev_txfifo_flush,
 };
 
 static const struct iwl_ops iwl1000_ops = {
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c
index 1182498..648d53b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-5000.c
@@ -403,6 +403,7 @@ static struct iwl_lib_ops iwl5000_lib = {
 	.check_plcp_health = iwl_good_plcp_health,
 	.check_ack_health = iwl_good_ack_health,
 	.txfifo_flush = iwlagn_txfifo_flush,
+	.dev_txfifo_flush = iwlagn_dev_txfifo_flush,
 };
 
 static struct iwl_lib_ops iwl5150_lib = {
@@ -467,6 +468,7 @@ static struct iwl_lib_ops iwl5150_lib = {
 	.check_plcp_health = iwl_good_plcp_health,
 	.check_ack_health = iwl_good_ack_health,
 	.txfifo_flush = iwlagn_txfifo_flush,
+	.dev_txfifo_flush = iwlagn_dev_txfifo_flush,
 };
 
 static const struct iwl_ops iwl5000_ops = {
diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c
index e1959fb..79ba7ad 100644
--- a/drivers/net/wireless/iwlwifi/iwl-6000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-6000.c
@@ -328,6 +328,7 @@ static struct iwl_lib_ops iwl6000_lib = {
 	.check_plcp_health = iwl_good_plcp_health,
 	.check_ack_health = iwl_good_ack_health,
 	.txfifo_flush = iwlagn_txfifo_flush,
+	.dev_txfifo_flush = iwlagn_dev_txfifo_flush,
 };
 
 static const struct iwl_ops iwl6000_ops = {
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
index 95666e5..74623e0 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
@@ -205,7 +205,9 @@ void iwl_check_abort_status(struct iwl_priv *priv,
 			    u8 frame_count, u32 status)
 {
 	if (frame_count == 1 && status == TX_STATUS_FAIL_RFKILL_FLUSH) {
-		IWL_ERR(priv, "TODO: Implement Tx flush command!!!\n");
+		IWL_ERR(priv, "Tx flush command to flush out all frames\n");
+		if (!test_bit(STATUS_EXIT_PENDING, &priv->status))
+			queue_work(priv->workqueue, &priv->tx_flush);
 	}
 }
 
@@ -1498,3 +1500,18 @@ int iwlagn_txfifo_flush(struct iwl_priv *priv, u16 flush_control)
 
 	return iwl_send_cmd(priv, &cmd);
 }
+
+void iwlagn_dev_txfifo_flush(struct iwl_priv *priv, u16 flush_control)
+{
+	mutex_lock(&priv->mutex);
+	ieee80211_stop_queues(priv->hw);
+	if (priv->cfg->ops->lib->txfifo_flush(priv, IWL_DROP_ALL)) {
+		IWL_ERR(priv, "flush request fail\n");
+		goto done;
+	}
+	IWL_DEBUG_INFO(priv, "wait transmit/flush all frames\n");
+	iwlagn_wait_tx_queue_empty(priv);
+done:
+	ieee80211_wake_queues(priv->hw);
+	mutex_unlock(&priv->mutex);
+}
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index c735a39..60af542 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -859,6 +859,24 @@ int iwl_set_pwr_src(struct iwl_priv *priv, enum iwl_pwr_src src)
 	return 0;
 }
 
+static void iwl_bg_tx_flush(struct work_struct *work)
+{
+	struct iwl_priv *priv =
+		container_of(work, struct iwl_priv, tx_flush);
+
+	if (test_bit(STATUS_EXIT_PENDING, &priv->status))
+		return;
+
+	/* do nothing if rf-kill is on */
+	if (!iwl_is_ready_rf(priv))
+		return;
+
+	if (priv->cfg->ops->lib->txfifo_flush) {
+		IWL_DEBUG_INFO(priv, "device request: flush all tx frames\n");
+		iwlagn_dev_txfifo_flush(priv, IWL_DROP_ALL);
+	}
+}
+
 /**
  * iwl_setup_rx_handlers - Initialize Rx handler callbacks
  *
@@ -3693,6 +3711,7 @@ static void iwl_setup_deferred_work(struct iwl_priv *priv)
 	INIT_WORK(&priv->rx_replenish, iwl_bg_rx_replenish);
 	INIT_WORK(&priv->beacon_update, iwl_bg_beacon_update);
 	INIT_WORK(&priv->run_time_calib_work, iwl_bg_run_time_calib_work);
+	INIT_WORK(&priv->tx_flush, iwl_bg_tx_flush);
 	INIT_DELAYED_WORK(&priv->init_alive_start, iwl_bg_init_alive_start);
 	INIT_DELAYED_WORK(&priv->alive_start, iwl_bg_alive_start);
 
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h
index 0298642..5c46b2c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.h
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.h
@@ -149,6 +149,7 @@ int iwlagn_rx_init(struct iwl_priv *priv, struct iwl_rx_queue *rxq);
 int iwlagn_hw_nic_init(struct iwl_priv *priv);
 int iwlagn_wait_tx_queue_empty(struct iwl_priv *priv);
 int iwlagn_txfifo_flush(struct iwl_priv *priv, u16 flush_control);
+void iwlagn_dev_txfifo_flush(struct iwl_priv *priv, u16 flush_control);
 
 /* rx */
 void iwlagn_rx_queue_restock(struct iwl_priv *priv);
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index db315b0..fcbba3d 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -206,6 +206,7 @@ struct iwl_lib_ops {
 	bool (*check_ack_health)(struct iwl_priv *priv,
 					struct iwl_rx_packet *pkt);
 	int (*txfifo_flush)(struct iwl_priv *priv, u16 flush_control);
+	void (*dev_txfifo_flush)(struct iwl_priv *priv, u16 flush_control);
 
 	struct iwl_debugfs_ops debugfs_ops;
 };
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index df07a14..c637376 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -1345,6 +1345,7 @@ struct iwl_priv {
 	struct work_struct ct_enter;
 	struct work_struct ct_exit;
 	struct work_struct start_internal_scan;
+	struct work_struct tx_flush;
 
 	struct tasklet_struct irq_tasklet;
 
-- 
1.7.0.4


^ permalink raw reply related

* [PATCH 3/8] iwlwifi: tx fifo queue flush command
From: Wey-Yi Guy @ 2010-07-02 18:45 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, ipw3945-devel, Wey-Yi Guy, Reinette Chatre
In-Reply-To: <1278096340-2546-1-git-send-email-wey-yi.w.guy@intel.com>

From: Wey-Yi Guy <wey-yi.w.guy@intel.com>

Add host command and structure for tx fifo queue flush

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

diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h
index a304f77..b28cb4f 100644
--- a/drivers/net/wireless/iwlwifi/iwl-commands.h
+++ b/drivers/net/wireless/iwlwifi/iwl-commands.h
@@ -97,6 +97,7 @@ enum {
 	REPLY_ADD_STA = 0x18,
 	REPLY_REMOVE_STA = 0x19,
 	REPLY_REMOVE_ALL_STA = 0x1a,	/* not used */
+	REPLY_TXFIFO_FLUSH = 0x1e,
 
 	/* Security */
 	REPLY_WEPKEY = 0x20,
@@ -1209,6 +1210,39 @@ struct iwl_rem_sta_cmd {
 	u8 reserved2[2];
 } __attribute__ ((packed));
 
+#define IWL_TX_FIFO_BK_MSK		cpu_to_le32(BIT(0))
+#define IWL_TX_FIFO_BE_MSK		cpu_to_le32(BIT(1))
+#define IWL_TX_FIFO_VI_MSK		cpu_to_le32(BIT(2))
+#define IWL_TX_FIFO_VO_MSK		cpu_to_le32(BIT(3))
+#define IWL_AGG_TX_QUEUE_MSK		cpu_to_le32(0xffc00)
+
+/*
+ * REPLY_TXFIFO_FLUSH = 0x1e(command and response)
+ *
+ * When using full FIFO flush this command checks the scheduler HW block WR/RD
+ * pointers to check if all the frames were transferred by DMA into the
+ * relevant TX FIFO queue. Only when the DMA is finished and the queue is
+ * empty the command can finish.
+ * This command is used to flush the TXFIFO from transmit commands, it may
+ * operate on single or multiple queues, the command queue can't be flushed by
+ * this command. The command response is returned when all the queue flush
+ * operations are done. Each TX command flushed return response with the FLUSH
+ * status set in the TX response status. When FIFO flush operation is used,
+ * the flush operation ends when both the scheduler DMA done and TXFIFO empty
+ * are set.
+ *
+ * @fifo_control: bit mask for which queues to flush
+ * @flush_control: flush controls
+ *	0: Dump single MSDU
+ *	1: Dump multiple MSDU according to PS, INVALID STA, TTL, TID disable.
+ *	2: Dump all FIFO
+ */
+struct iwl_txfifo_flush_cmd {
+	__le32 fifo_control;
+	__le16 flush_control;
+	__le16 reserved;
+} __attribute__ ((packed));
+
 /*
  * REPLY_WEP_KEY = 0x20
  */
diff --git a/drivers/net/wireless/iwlwifi/iwl-hcmd.c b/drivers/net/wireless/iwlwifi/iwl-hcmd.c
index 51f89e7..258d059 100644
--- a/drivers/net/wireless/iwlwifi/iwl-hcmd.c
+++ b/drivers/net/wireless/iwlwifi/iwl-hcmd.c
@@ -49,6 +49,7 @@ const char *get_cmd_string(u8 cmd)
 		IWL_CMD(REPLY_ADD_STA);
 		IWL_CMD(REPLY_REMOVE_STA);
 		IWL_CMD(REPLY_REMOVE_ALL_STA);
+		IWL_CMD(REPLY_TXFIFO_FLUSH);
 		IWL_CMD(REPLY_WEPKEY);
 		IWL_CMD(REPLY_3945_RX);
 		IWL_CMD(REPLY_TX);
-- 
1.7.0.4


^ permalink raw reply related

* [PATCH 4/8] iwlwifi: add mac80211 flush callback support
From: Wey-Yi Guy @ 2010-07-02 18:45 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, ipw3945-devel, Wey-Yi Guy, Reinette Chatre
In-Reply-To: <1278096340-2546-1-git-send-email-wey-yi.w.guy@intel.com>

From: Wey-Yi Guy <wey-yi.w.guy@intel.com>

Adding flush callback support in the driver. Two type of flush can be
issued by mac80211:
1. drop = true: frame drop is ok, issue REPLY_TXFIFO_FLUSH host command
to uCode to drop all the frames in tx fifo queues; then return the
control back to mac80211
2. drop = false: wait for either all the frames in tx fifo queues been
transmitted, or timeout; then return the control back to mac80211

If the flush request coming from mac80211, mac80211 will make sure there
are no additional frames push down to driver before flush operation is
completed.

Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
---
 drivers/net/wireless/iwlwifi/iwl-1000.c     |    1 +
 drivers/net/wireless/iwlwifi/iwl-5000.c     |    2 +
 drivers/net/wireless/iwlwifi/iwl-6000.c     |    1 +
 drivers/net/wireless/iwlwifi/iwl-agn-lib.c  |   63 +++++++++++++++++++++++++++
 drivers/net/wireless/iwlwifi/iwl-agn.c      |   39 ++++++++++++++++
 drivers/net/wireless/iwlwifi/iwl-agn.h      |    2 +
 drivers/net/wireless/iwlwifi/iwl-commands.h |    4 ++
 drivers/net/wireless/iwlwifi/iwl-core.h     |    2 +
 8 files changed, 114 insertions(+), 0 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c
index 1daf159..00808ee 100644
--- a/drivers/net/wireless/iwlwifi/iwl-1000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-1000.c
@@ -226,6 +226,7 @@ static struct iwl_lib_ops iwl1000_lib = {
 	.recover_from_tx_stall = iwl_bg_monitor_recover,
 	.check_plcp_health = iwl_good_plcp_health,
 	.check_ack_health = iwl_good_ack_health,
+	.txfifo_flush = iwlagn_txfifo_flush,
 };
 
 static const struct iwl_ops iwl1000_ops = {
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c
index b8f3e20..1182498 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-5000.c
@@ -402,6 +402,7 @@ static struct iwl_lib_ops iwl5000_lib = {
 	.recover_from_tx_stall = iwl_bg_monitor_recover,
 	.check_plcp_health = iwl_good_plcp_health,
 	.check_ack_health = iwl_good_ack_health,
+	.txfifo_flush = iwlagn_txfifo_flush,
 };
 
 static struct iwl_lib_ops iwl5150_lib = {
@@ -465,6 +466,7 @@ static struct iwl_lib_ops iwl5150_lib = {
 	.recover_from_tx_stall = iwl_bg_monitor_recover,
 	.check_plcp_health = iwl_good_plcp_health,
 	.check_ack_health = iwl_good_ack_health,
+	.txfifo_flush = iwlagn_txfifo_flush,
 };
 
 static const struct iwl_ops iwl5000_ops = {
diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c
index 8577664..e1959fb 100644
--- a/drivers/net/wireless/iwlwifi/iwl-6000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-6000.c
@@ -327,6 +327,7 @@ static struct iwl_lib_ops iwl6000_lib = {
 	.recover_from_tx_stall = iwl_bg_monitor_recover,
 	.check_plcp_health = iwl_good_plcp_health,
 	.check_ack_health = iwl_good_ack_health,
+	.txfifo_flush = iwlagn_txfifo_flush,
 };
 
 static const struct iwl_ops iwl6000_ops = {
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
index 5f1e7d8..95666e5 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
@@ -1435,3 +1435,66 @@ void iwl_free_tfds_in_queue(struct iwl_priv *priv,
 		priv->stations[sta_id].tid[tid].tfds_in_queue = 0;
 	}
 }
+
+#define IWL_FLUSH_WAIT_MS	2000
+
+int iwlagn_wait_tx_queue_empty(struct iwl_priv *priv)
+{
+	struct iwl_tx_queue *txq;
+	struct iwl_queue *q;
+	int cnt;
+	unsigned long now = jiffies;
+	int ret = 0;
+
+	/* waiting for all the tx frames complete might take a while */
+	for (cnt = 0; cnt < priv->hw_params.max_txq_num; cnt++) {
+		if (cnt == IWL_CMD_QUEUE_NUM)
+			continue;
+		txq = &priv->txq[cnt];
+		q = &txq->q;
+		while (q->read_ptr != q->write_ptr && !time_after(jiffies,
+		       now + msecs_to_jiffies(IWL_FLUSH_WAIT_MS)))
+				msleep(1);
+
+		if (q->read_ptr != q->write_ptr) {
+			IWL_ERR(priv, "fail to flush all tx fifo queues\n");
+			ret = -ETIMEDOUT;
+			break;
+		}
+	}
+	return ret;
+}
+
+#define IWL_TX_QUEUE_MSK	0xfffff
+
+/**
+ * iwlagn_txfifo_flush: send REPLY_TXFIFO_FLUSH command to uCode
+ *
+ * pre-requirements:
+ *  1. acquire mutex before calling
+ *  2. make sure rf is on and not in exit state
+ */
+int iwlagn_txfifo_flush(struct iwl_priv *priv, u16 flush_control)
+{
+	struct iwl_txfifo_flush_cmd flush_cmd;
+	struct iwl_host_cmd cmd = {
+		.id = REPLY_TXFIFO_FLUSH,
+		.len = sizeof(struct iwl_txfifo_flush_cmd),
+		.flags = CMD_SYNC,
+		.data = &flush_cmd,
+	};
+
+	might_sleep();
+
+	memset(&flush_cmd, 0, sizeof(flush_cmd));
+	flush_cmd.fifo_control = IWL_TX_FIFO_VO_MSK | IWL_TX_FIFO_VI_MSK |
+				 IWL_TX_FIFO_BE_MSK | IWL_TX_FIFO_BK_MSK;
+	if (priv->cfg->sku & IWL_SKU_N)
+		flush_cmd.fifo_control |= IWL_AGG_TX_QUEUE_MSK;
+
+	IWL_DEBUG_INFO(priv, "fifo queue control: 0X%x\n",
+		       flush_cmd.fifo_control);
+	flush_cmd.flush_control = cpu_to_le16(flush_control);
+
+	return iwl_send_cmd(priv, &cmd);
+}
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index 22c0149..c735a39 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -3639,6 +3639,44 @@ out_exit:
 	IWL_DEBUG_MAC80211(priv, "leave\n");
 }
 
+static void iwl_mac_flush(struct ieee80211_hw *hw, bool drop)
+{
+	struct iwl_priv *priv = hw->priv;
+
+	mutex_lock(&priv->mutex);
+	IWL_DEBUG_MAC80211(priv, "enter\n");
+
+	/* do not support "flush" */
+	if (!priv->cfg->ops->lib->txfifo_flush)
+		goto done;
+
+	if (test_bit(STATUS_EXIT_PENDING, &priv->status)) {
+		IWL_DEBUG_TX(priv, "Aborting flush due to device shutdown\n");
+		goto done;
+	}
+	if (iwl_is_rfkill(priv)) {
+		IWL_DEBUG_TX(priv, "Aborting flush due to RF Kill\n");
+		goto done;
+	}
+
+	/*
+	 * mac80211 will not push any more frames for transmit
+	 * until the flush is completed
+	 */
+	if (drop) {
+		IWL_DEBUG_MAC80211(priv, "send flush command\n");
+		if (priv->cfg->ops->lib->txfifo_flush(priv, IWL_DROP_ALL)) {
+			IWL_ERR(priv, "flush request fail\n");
+			goto done;
+		}
+	}
+	IWL_DEBUG_MAC80211(priv, "wait transmit/flush all frames\n");
+	iwlagn_wait_tx_queue_empty(priv);
+done:
+	mutex_unlock(&priv->mutex);
+	IWL_DEBUG_MAC80211(priv, "leave\n");
+}
+
 /*****************************************************************************
  *
  * driver setup and teardown
@@ -3812,6 +3850,7 @@ static struct ieee80211_ops iwl_hw_ops = {
 	.sta_add = iwlagn_mac_sta_add,
 	.sta_remove = iwl_mac_sta_remove,
 	.channel_switch = iwl_mac_channel_switch,
+	.flush = iwl_mac_flush,
 };
 
 static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h
index be9d298..0298642 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.h
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.h
@@ -147,6 +147,8 @@ const u8 *iwlagn_eeprom_query_addr(const struct iwl_priv *priv,
 void iwlagn_rx_queue_reset(struct iwl_priv *priv, struct iwl_rx_queue *rxq);
 int iwlagn_rx_init(struct iwl_priv *priv, struct iwl_rx_queue *rxq);
 int iwlagn_hw_nic_init(struct iwl_priv *priv);
+int iwlagn_wait_tx_queue_empty(struct iwl_priv *priv);
+int iwlagn_txfifo_flush(struct iwl_priv *priv, u16 flush_control);
 
 /* rx */
 void iwlagn_rx_queue_restock(struct iwl_priv *priv);
diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h
index b28cb4f..0844955 100644
--- a/drivers/net/wireless/iwlwifi/iwl-commands.h
+++ b/drivers/net/wireless/iwlwifi/iwl-commands.h
@@ -1216,6 +1216,10 @@ struct iwl_rem_sta_cmd {
 #define IWL_TX_FIFO_VO_MSK		cpu_to_le32(BIT(3))
 #define IWL_AGG_TX_QUEUE_MSK		cpu_to_le32(0xffc00)
 
+#define IWL_DROP_SINGLE		0
+#define IWL_DROP_SELECTED	1
+#define IWL_DROP_ALL		2
+
 /*
  * REPLY_TXFIFO_FLUSH = 0x1e(command and response)
  *
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index bfa3456..db315b0 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -205,6 +205,8 @@ struct iwl_lib_ops {
 	/* check for ack health */
 	bool (*check_ack_health)(struct iwl_priv *priv,
 					struct iwl_rx_packet *pkt);
+	int (*txfifo_flush)(struct iwl_priv *priv, u16 flush_control);
+
 	struct iwl_debugfs_ops debugfs_ops;
 };
 
-- 
1.7.0.4


^ permalink raw reply related

* [PATCH 2/8] iwlwifi: add debug print for parsing firmware TLV
From: Wey-Yi Guy @ 2010-07-02 18:45 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, ipw3945-devel, Wey-Yi Guy, Reinette Chatre
In-Reply-To: <1278096340-2546-1-git-send-email-wey-yi.w.guy@intel.com>

From: Wey-Yi Guy <wey-yi.w.guy@intel.com>

When parsing TLV during loading firmware, if encounter any TLV error,
log the error message to help debugging.

Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
---
 drivers/net/wireless/iwlwifi/iwl-agn.c |  101 ++++++++++++++++++++------------
 1 files changed, 63 insertions(+), 38 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index 3368cfd..22c0149 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -1806,12 +1806,21 @@ static int iwlagn_load_firmware(struct iwl_priv *priv,
 	const u8 *data;
 	int wanted_alternative = iwlagn_wanted_ucode_alternative, tmp;
 	u64 alternatives;
+	u32 tlv_len;
+	enum iwl_ucode_tlv_type tlv_type;
+	const u8 *tlv_data;
+	int ret = 0;
 
-	if (len < sizeof(*ucode))
+	if (len < sizeof(*ucode)) {
+		IWL_ERR(priv, "uCode has invalid length: %zd\n", len);
 		return -EINVAL;
+	}
 
-	if (ucode->magic != cpu_to_le32(IWL_TLV_UCODE_MAGIC))
+	if (ucode->magic != cpu_to_le32(IWL_TLV_UCODE_MAGIC)) {
+		IWL_ERR(priv, "invalid uCode magic: 0X%x\n",
+			le32_to_cpu(ucode->magic));
 		return -EINVAL;
+	}
 
 	/*
 	 * Check which alternatives are present, and "downgrade"
@@ -1836,11 +1845,9 @@ static int iwlagn_load_firmware(struct iwl_priv *priv,
 
 	len -= sizeof(*ucode);
 
-	while (len >= sizeof(*tlv)) {
-		u32 tlv_len;
-		enum iwl_ucode_tlv_type tlv_type;
+	while (len >= sizeof(*tlv) && !ret) {
 		u16 tlv_alt;
-		const u8 *tlv_data;
+		u32 fixed_tlv_size = 4;
 
 		len -= sizeof(*tlv);
 		tlv = (void *)data;
@@ -1850,8 +1857,11 @@ static int iwlagn_load_firmware(struct iwl_priv *priv,
 		tlv_alt = le16_to_cpu(tlv->alternative);
 		tlv_data = tlv->data;
 
-		if (len < tlv_len)
+		if (len < tlv_len) {
+			IWL_ERR(priv, "invalid TLV len: %zd/%u\n",
+				len, tlv_len);
 			return -EINVAL;
+		}
 		len -= ALIGN(tlv_len, 4);
 		data += sizeof(*tlv) + ALIGN(tlv_len, 4);
 
@@ -1885,56 +1895,71 @@ static int iwlagn_load_firmware(struct iwl_priv *priv,
 			pieces->boot_size = tlv_len;
 			break;
 		case IWL_UCODE_TLV_PROBE_MAX_LEN:
-			if (tlv_len != 4)
-				return -EINVAL;
-			capa->max_probe_length =
-				le32_to_cpup((__le32 *)tlv_data);
+			if (tlv_len != fixed_tlv_size)
+				ret = -EINVAL;
+			else
+				capa->max_probe_length =
+					le32_to_cpup((__le32 *)tlv_data);
 			break;
 		case IWL_UCODE_TLV_INIT_EVTLOG_PTR:
-			if (tlv_len != 4)
-				return -EINVAL;
-			pieces->init_evtlog_ptr =
-				le32_to_cpup((__le32 *)tlv_data);
+			if (tlv_len != fixed_tlv_size)
+				ret = -EINVAL;
+			else
+				pieces->init_evtlog_ptr =
+					le32_to_cpup((__le32 *)tlv_data);
 			break;
 		case IWL_UCODE_TLV_INIT_EVTLOG_SIZE:
-			if (tlv_len != 4)
-				return -EINVAL;
-			pieces->init_evtlog_size =
-				le32_to_cpup((__le32 *)tlv_data);
+			if (tlv_len != fixed_tlv_size)
+				ret = -EINVAL;
+			else
+				pieces->init_evtlog_size =
+					le32_to_cpup((__le32 *)tlv_data);
 			break;
 		case IWL_UCODE_TLV_INIT_ERRLOG_PTR:
-			if (tlv_len != 4)
-				return -EINVAL;
-			pieces->init_errlog_ptr =
-				le32_to_cpup((__le32 *)tlv_data);
+			if (tlv_len != fixed_tlv_size)
+				ret = -EINVAL;
+			else
+				pieces->init_errlog_ptr =
+					le32_to_cpup((__le32 *)tlv_data);
 			break;
 		case IWL_UCODE_TLV_RUNT_EVTLOG_PTR:
-			if (tlv_len != 4)
-				return -EINVAL;
-			pieces->inst_evtlog_ptr =
-				le32_to_cpup((__le32 *)tlv_data);
+			if (tlv_len != fixed_tlv_size)
+				ret = -EINVAL;
+			else
+				pieces->inst_evtlog_ptr =
+					le32_to_cpup((__le32 *)tlv_data);
 			break;
 		case IWL_UCODE_TLV_RUNT_EVTLOG_SIZE:
-			if (tlv_len != 4)
-				return -EINVAL;
-			pieces->inst_evtlog_size =
-				le32_to_cpup((__le32 *)tlv_data);
+			if (tlv_len != fixed_tlv_size)
+				ret = -EINVAL;
+			else
+				pieces->inst_evtlog_size =
+					le32_to_cpup((__le32 *)tlv_data);
 			break;
 		case IWL_UCODE_TLV_RUNT_ERRLOG_PTR:
-			if (tlv_len != 4)
-				return -EINVAL;
-			pieces->inst_errlog_ptr =
-				le32_to_cpup((__le32 *)tlv_data);
+			if (tlv_len != fixed_tlv_size)
+				ret = -EINVAL;
+			else
+				pieces->inst_errlog_ptr =
+					le32_to_cpup((__le32 *)tlv_data);
 			break;
 		default:
+			IWL_WARN(priv, "unknown TLV: %d\n", tlv_type);
 			break;
 		}
 	}
 
-	if (len)
-		return -EINVAL;
+	if (len) {
+		IWL_ERR(priv, "invalid TLV after parsing: %zd\n", len);
+		iwl_print_hex_dump(priv, IWL_DL_FW, (u8 *)data, len);
+		ret = -EINVAL;
+	} else if (ret) {
+		IWL_ERR(priv, "TLV %d has invalid size: %u\n",
+			tlv_type, tlv_len);
+		iwl_print_hex_dump(priv, IWL_DL_FW, (u8 *)tlv_data, tlv_len);
+	}
 
-	return 0;
+	return ret;
 }
 
 /**
-- 
1.7.0.4


^ permalink raw reply related

* [PATCH 1/8] iwlwifi: fix fw_restart module parameter
From: Wey-Yi Guy @ 2010-07-02 18:45 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, ipw3945-devel, Wey-Yi Guy, Reinette Chatre
In-Reply-To: <1278096340-2546-1-git-send-email-wey-yi.w.guy@intel.com>

From: Wey-Yi Guy <wey-yi.w.guy@intel.com>

fw_restart module parameter was broken by the recent check for stuck
queue patch, driver check the fx_restart module parameter
before reload the firmware; but the stuck queue timer kick in after
firmware error and reload the firmware even fw_restart=0. In this case,
driver should not reload the firmware, it is important to help debugging
uCode error.

The only case we can ignore the module parameter is when user request
firmware reload from debugfs, which can bypass the checking and perform
firmware reload all the time.

Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
---
 drivers/net/wireless/iwlwifi/iwl-core.c    |   31 ++++++++++++++++++++-------
 drivers/net/wireless/iwlwifi/iwl-core.h    |    2 +-
 drivers/net/wireless/iwlwifi/iwl-debugfs.c |    2 +-
 drivers/net/wireless/iwlwifi/iwl-rx.c      |    4 +-
 4 files changed, 27 insertions(+), 12 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index a56fb46..f73eb08 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -2627,7 +2627,7 @@ static void iwl_force_rf_reset(struct iwl_priv *priv)
 }
 
 
-int iwl_force_reset(struct iwl_priv *priv, int mode)
+int iwl_force_reset(struct iwl_priv *priv, int mode, bool external)
 {
 	struct iwl_force_reset *force_reset;
 
@@ -2640,12 +2640,14 @@ int iwl_force_reset(struct iwl_priv *priv, int mode)
 	}
 	force_reset = &priv->force_reset[mode];
 	force_reset->reset_request_count++;
-	if (force_reset->last_force_reset_jiffies &&
-	    time_after(force_reset->last_force_reset_jiffies +
-	    force_reset->reset_duration, jiffies)) {
-		IWL_DEBUG_INFO(priv, "force reset rejected\n");
-		force_reset->reset_reject_count++;
-		return -EAGAIN;
+	if (!external) {
+		if (force_reset->last_force_reset_jiffies &&
+		    time_after(force_reset->last_force_reset_jiffies +
+		    force_reset->reset_duration, jiffies)) {
+			IWL_DEBUG_INFO(priv, "force reset rejected\n");
+			force_reset->reset_reject_count++;
+			return -EAGAIN;
+		}
 	}
 	force_reset->reset_success_count++;
 	force_reset->last_force_reset_jiffies = jiffies;
@@ -2655,6 +2657,19 @@ int iwl_force_reset(struct iwl_priv *priv, int mode)
 		iwl_force_rf_reset(priv);
 		break;
 	case IWL_FW_RESET:
+		/*
+		 * if the request is from external(ex: debugfs),
+		 * then always perform the request in regardless the module
+		 * parameter setting
+		 * if the request is from internal (uCode error or driver
+		 * detect failure), then fw_restart module parameter
+		 * need to be check before performing firmware reload
+		 */
+		if (!external && !priv->cfg->mod_params->restart_fw) {
+			IWL_DEBUG_INFO(priv, "Cancel firmware reload based on "
+				       "module parameter setting\n");
+			break;
+		}
 		IWL_ERR(priv, "On demand firmware reload\n");
 		/* Set the FW error flag -- cleared on iwl_down */
 		set_bit(STATUS_FW_ERROR, &priv->status);
@@ -2713,7 +2728,7 @@ static int iwl_check_stuck_queue(struct iwl_priv *priv, int cnt)
 					"queue %d stuck %d time. Fw reload.\n",
 					q->id, q->repeat_same_read_ptr);
 				q->repeat_same_read_ptr = 0;
-				iwl_force_reset(priv, IWL_FW_RESET);
+				iwl_force_reset(priv, IWL_FW_RESET, false);
 			} else {
 				q->repeat_same_read_ptr++;
 				IWL_DEBUG_RADIO(priv,
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index 15930e0..bfa3456 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -525,7 +525,7 @@ int iwl_mac_hw_scan(struct ieee80211_hw *hw,
 		    struct cfg80211_scan_request *req);
 void iwl_bg_start_internal_scan(struct work_struct *work);
 void iwl_internal_short_hw_scan(struct iwl_priv *priv);
-int iwl_force_reset(struct iwl_priv *priv, int mode);
+int iwl_force_reset(struct iwl_priv *priv, int mode, bool external);
 u16 iwl_fill_probe_req(struct iwl_priv *priv, struct ieee80211_mgmt *frame,
 		       const u8 *ta, const u8 *ie, int ie_len, int left);
 void iwl_setup_rx_scan_handlers(struct iwl_priv *priv);
diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
index 7d9ffc1..48f8908 100644
--- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
@@ -1487,7 +1487,7 @@ static ssize_t iwl_dbgfs_force_reset_write(struct file *file,
 	switch (reset) {
 	case IWL_RF_RESET:
 	case IWL_FW_RESET:
-		ret = iwl_force_reset(priv, reset);
+		ret = iwl_force_reset(priv, reset, true);
 		break;
 	default:
 		return -EINVAL;
diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c
index b437f31..79773e3 100644
--- a/drivers/net/wireless/iwlwifi/iwl-rx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-rx.c
@@ -238,7 +238,7 @@ void iwl_recover_from_statistics(struct iwl_priv *priv,
 				 */
 				IWL_ERR(priv, "low ack count detected, "
 					"restart firmware\n");
-				if (!iwl_force_reset(priv, IWL_FW_RESET))
+				if (!iwl_force_reset(priv, IWL_FW_RESET, false))
 					return;
 			}
 		}
@@ -249,7 +249,7 @@ void iwl_recover_from_statistics(struct iwl_priv *priv,
 				 * high plcp error detected
 				 * reset Radio
 				 */
-				iwl_force_reset(priv, IWL_RF_RESET);
+				iwl_force_reset(priv, IWL_RF_RESET, false);
 			}
 		}
 	}
-- 
1.7.0.4


^ permalink raw reply related

* [PATCH 0/8] iwlwifi update for 2.6.36
From: Wey-Yi Guy @ 2010-07-02 18:45 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, ipw3945-devel, Wey-Yi Guy

We add support for tx fifo flush command
We also add new supporting sensitivity information for upcoming devices
"fw_restart" module parameter was broken by earlier firmware restart
patch; here we re-enable this module parameter.

Wey-Yi Guy (8):
  iwlwifi: fix fw_restart module parameter
  iwlwifi: add debug print for parsing firmware TLV
  iwlwifi: tx fifo queue flush command
  iwlwifi: add mac80211 flush callback support
  iwlwifi: add support for device tx flush request
  iwlwifi: debugfs file for txfifo command testing
  iwlwifi: generic parameter define for _agn device
  iwlwifi: adding enhance sensitivity table entries

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

 drivers/net/wireless/iwlwifi/iwl-1000.c      |    6 +-
 drivers/net/wireless/iwlwifi/iwl-5000.c      |   12 ++-
 drivers/net/wireless/iwlwifi/iwl-6000.c      |    6 +-
 drivers/net/wireless/iwlwifi/iwl-agn-calib.c |  133 ++++++++++++++++-----
 drivers/net/wireless/iwlwifi/iwl-agn-lib.c   |   82 +++++++++++++-
 drivers/net/wireless/iwlwifi/iwl-agn.c       |  165 ++++++++++++++++++++------
 drivers/net/wireless/iwlwifi/iwl-agn.h       |    3 +
 drivers/net/wireless/iwlwifi/iwl-commands.h  |   85 +++++++++++++-
 drivers/net/wireless/iwlwifi/iwl-core.c      |   31 ++++--
 drivers/net/wireless/iwlwifi/iwl-core.h      |    5 +-
 drivers/net/wireless/iwlwifi/iwl-debugfs.c   |   29 +++++-
 drivers/net/wireless/iwlwifi/iwl-dev.h       |    4 +
 drivers/net/wireless/iwlwifi/iwl-hcmd.c      |    1 +
 drivers/net/wireless/iwlwifi/iwl-rx.c        |    4 +-
 14 files changed, 477 insertions(+), 89 deletions(-)


^ permalink raw reply

* [PATCH wireless-2.6] iwlwifi: remove key information during device restart
From: Wey-Yi Guy @ 2010-07-02 18:45 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, ipw3945-devel, Reinette Chatre

From: Reinette Chatre <reinette.chatre@intel.com>

When there is a firmware error or the firmware is reloaded for some other
reason we currently clear all station information, including keys
associated with them. A problem is that we do not clear some other
information regarding keys that are not stored in the station structs.

The consequence of this is that when the device is reconfigured after the
firmware reload we can, among other things, run out of key indices.

This fixes:
https://bugzilla.kernel.org/show_bug.cgi?id=16232
http://bugzilla.intellinuxwireless.org/show_bug.cgi?id=2221

Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
Reviewed-by: Johannes Berg <johannes.berg@intel.com>
---
this patch is also available from wireless-2.6 branch on
 git://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi-2.6.git

 drivers/net/wireless/iwlwifi/iwl-sta.h |   11 +++++++++++
 1 files changed, 11 insertions(+), 0 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.h b/drivers/net/wireless/iwlwifi/iwl-sta.h
index c2a453a..dc43ebd 100644
--- a/drivers/net/wireless/iwlwifi/iwl-sta.h
+++ b/drivers/net/wireless/iwlwifi/iwl-sta.h
@@ -97,6 +97,17 @@ static inline void iwl_clear_driver_stations(struct iwl_priv *priv)
 	spin_lock_irqsave(&priv->sta_lock, flags);
 	memset(priv->stations, 0, sizeof(priv->stations));
 	priv->num_stations = 0;
+
+	/*
+	 * Remove all key information that is not stored as part of station
+	 * information since mac80211 may not have had a
+	 * chance to remove all the keys. When device is reconfigured by
+	 * mac80211 after an error all keys will be reconfigured.
+	 */
+	priv->ucode_key_table = 0;
+	priv->key_mapping_key = 0;
+	memset(priv->wep_keys, 0, sizeof(priv->wep_keys));
+
 	spin_unlock_irqrestore(&priv->sta_lock, flags);
 }
 
-- 
1.7.0.4


^ permalink raw reply related

* Re: Enabling channels 12,13
From: Jaroslav Fojtik @ 2010-07-02 18:27 UTC (permalink / raw)
  To: linux-wireless; +Cc: Paul Fertser
In-Reply-To: <20100702173625.GD974@home.pavel.comp>

[-- Attachment #1: Mail message body --]
[-- Type: text/plain, Size: 1983 bytes --]

Dear Paul Fertser,

thank you for a hint.

But unfortunatelly this patch (attached) does not work for me.
May be for multiple devices? Who knows.

Band 1:
                Frequencies:
                        * 2412 MHz [1] (20.0 dBm)
                        * 2417 MHz [2] (20.0 dBm)
                        * 2422 MHz [3] (20.0 dBm)
                        * 2427 MHz [4] (20.0 dBm)
                        * 2432 MHz [5] (20.0 dBm)
                        * 2437 MHz [6] (20.0 dBm)
                        * 2442 MHz [7] (20.0 dBm)
                        * 2447 MHz [8] (20.0 dBm)
                        * 2452 MHz [9] (20.0 dBm)
                        * 2457 MHz [10] (20.0 dBm)
                        * 2462 MHz [11] (20.0 dBm)
                        * 2467 MHz [12] (disabled)
                        * 2472 MHz [13] (disabled)
                        * 2484 MHz [14] (disabled)



[    4.464183] ath5k 0000:02:08.0: PCI INT A -> GSI 17 (level, low) -> IRQ 17
[    4.464328] ath5k 0000:02:08.0: registered as 'phy0'
[    5.059773] ath5k phy0: DANGER! You're overriding EEPROM-defined regulatory domain.
[    5.059837] ath5k phy0: Your card was not certified to operate on the domain you choosed.
[    5.059902] ath5k phy0: This might result in a violation of your local regulatory rules.
--
[    5.122197] ath5k 0000:02:0a.0: PCI INT A -> GSI 19 (level, low) -> IRQ 19
[    5.122338] ath5k 0000:02:0a.0: registered as 'phy1'
[    5.587528] ath5k phy1: DANGER! You're overriding EEPROM-defined regulatory domain.
[    5.587593] ath5k phy1: Your card was not certified to operate on the domain you choosed.
[    5.588358] ath5k phy1: This might result in a violation of your local regulatory rules.

> Please see this for reference:
> http://forum.aircrack-ng.org/index.php?topic=6822.15
> 
> You can also try "pentoo" gentoo overlay.

regards
   Jara


> 
> HTH
> -- 
> Be free, use free (http://www.gnu.org/philosophy/free-sw.html) software!
> mailto:fercerpav@gmail.com



[-- Attachment #2: ath5k_regdomain_override.patch --]
[-- Type: Application/Octet-stream, Size: 1481 bytes --]

PaulFertser> Get _your_ country code from regd.h, add 32768 and supply as a parameter.
fercerpav@gmail.com
--- linux-2.6.32-gentoo-r1-orig/drivers/net/wireless/ath/ath5k/base.c	2009-12-03 06:51:21.000000000 +0300
+++ linux-2.6.32-gentoo-r1/drivers/net/wireless/ath/ath5k/base.c	2010-01-16 00:02:51.000000000 +0300
@@ -68,6 +68,11 @@
 module_param_named(all_channels, modparam_all_channels, bool, S_IRUGO);
 MODULE_PARM_DESC(all_channels, "Expose all channels the device can use.");
 
+static int modparam_override_eeprom_regdomain = -1;
+module_param_named(override_eeprom_regdomain, 
+			modparam_override_eeprom_regdomain, int, S_IRUGO);
+MODULE_PARM_DESC(override_eeprom_regdomain, "Override regdomain hardcoded in EEPROM with this value (DANGEROUS).");
+
 
 /******************\
 * Internal defines *
@@ -572,6 +577,15 @@
 		goto err_irq;
 	}
 
+	if (modparam_override_eeprom_regdomain != -1) {
+		ATH5K_ERR(sc, "DANGER! You're overriding EEPROM-defined regulatory domain.\n");
+		ATH5K_ERR(sc, "Your card was not certified to operate on the domain you choosed.\n");
+		ATH5K_ERR(sc, "This might result in a violation of your local regulatory rules.\n");
+		ATH5K_ERR(sc, "Do not ever do that unless you really know what you do!\n");
+		sc->ah->ah_capabilities.cap_eeprom.ee_regdomain =
+			modparam_override_eeprom_regdomain;
+	}
+
 	/* set up multi-rate retry capabilities */
 	if (sc->ah->ah_version == AR5K_AR5212) {
 		hw->max_rates = 4;


^ permalink raw reply

* Re: rt2x00 & mac80211: correct usage of ieee80211_beacon_get_tim?
From: Helmut Schaa @ 2010-07-02 18:20 UTC (permalink / raw)
  To: Johannes Berg; +Cc: linux-wireless, Ivo van Doorn, Gertjan van Wingerde
In-Reply-To: <1278093964.15412.24.camel@jlt3.sipsolutions.net>

Am Freitag 02 Juli 2010 schrieb Johannes Berg:
> On Fri, 2010-07-02 at 19:59 +0200, Helmut Schaa wrote:
> 
> > > unless your
> > > device itself is capable of generating the TIM IE _right before_ the
> > > beacon gets transmitted.
> > 
> > Agreed. At least on rt2800 we can use the pre tbtt interrupt to update the
> > beacon just before it is sent out.
> 
> Careful though. You don't know how far in advance it is triggered (or
> maybe you do) or if the time will be sufficient to generate and upload
> the beacon to the device. You could even hit lock contention I think.

Yeah, the delay is configurable. And yes, we cannot be 100% sure but
I already did some tests and on my MIPS board anything >1ms was
enough to generate + upload a new beacon to the device. And we can still
increase that to a safe default of maybe 5ms or so.

Helmut

^ permalink raw reply

* Re: [PATCH 2.6.34] mac80211: Fix auth retries if AP sends temporary deauth
From: Johannes Berg @ 2010-07-02 18:13 UTC (permalink / raw)
  To: Paul Stewart; +Cc: linux-wireless, Michael Wu, Jiri Benc, John W. Linville
In-Reply-To: <AANLkTikfegnc1gAwIUiZKaMeDoUYOFqK8eSc6_3wUggm@mail.gmail.com>

On Fri, 2010-07-02 at 11:09 -0700, Paul Stewart wrote:
> It may be a weird patch, but probably just because I'm still wrapping
> my head around how things work.  

Sure.

> The problem is ultimately the call to
> __cfg80211_send_deauth() in wireless/mlme.c that is triggered by
> reception of the DEAUTH.  

Is it? I thought it was without double underscore from another code
path?

> That function removes wdev->auth_bsses[i],

No, the BSS can't be in auth_bsses yet. I think the problem is more
complex, and wpa_supplicant itself will remove it from auth_bsses
because the kernel erroneously told it we got deauthenticated.

> which is needed in order for an auth to succeed.  The code path that
> gets us there is:
> 
>     mac80211/rx.c: ieee80211_rx_h_mgmt()
>     mac80211/mlme.c: ieee80211_sta_rx_mgmt()
>     ...then through the queued work and...
>     ieee80211_sta_rx_queued_mgmt()
> 
> At the bottom of the latter function, outside of the block that checks
> for our authentication state, we call cfg80211_send_deauth() in
> response to IEEE80211_STYPE_DEAUTH, which quite arguably should never
> be called if we're authenticated.  The only time this issue touches
> cfg80211 is that final call to send_deauth() which I believe is done
> in error.  I think the fix should be in mac80211 somewhere.
> 
> I didn't find a way to tell where we were in the authentication proces
> from within ieee80211_sta_rx_queued_mgmt(), so I swallowed the packet
> much earlier in the process from within ieee80211_work_rx_mgmt(),
> which has access to that state, and can indeed claim packets for
> itself it it believes it knows best what to do with them.
> 
> I hope this clears up my thinking on this.  I'd be happy to change the
> patch in whatever way makes sense.

Can you try the patch below instead of yours? I'll explain it a bit more
later, but my church wedding ceremony is tomorrow :)

johannes

--- wireless-testing.orig/net/wireless/mlme.c	2010-07-02 20:12:19.000000000 +0200
+++ wireless-testing/net/wireless/mlme.c	2010-07-02 20:12:43.000000000 +0200
@@ -44,10 +44,10 @@ void cfg80211_send_rx_auth(struct net_de
 		}
 	}
 
-	WARN_ON(!done);
-
-	nl80211_send_rx_auth(rdev, dev, buf, len, GFP_KERNEL);
-	cfg80211_sme_rx_auth(dev, buf, len);
+	if (done) {
+		nl80211_send_rx_auth(rdev, dev, buf, len, GFP_KERNEL);
+		cfg80211_sme_rx_auth(dev, buf, len);
+	}
 
 	wdev_unlock(wdev);
 }



^ permalink raw reply

* Re: [PATCH 2.6.34] mac80211: Fix auth retries if AP sends temporary deauth
From: Paul Stewart @ 2010-07-02 18:09 UTC (permalink / raw)
  To: Johannes Berg; +Cc: linux-wireless, Michael Wu, Jiri Benc, John W. Linville
In-Reply-To: <1278091743.15412.17.camel@jlt3.sipsolutions.net>

It may be a weird patch, but probably just because I'm still wrapping
my head around how things work.  The problem is ultimately the call to
__cfg80211_send_deauth() in wireless/mlme.c that is triggered by
reception of the DEAUTH.  That function removes wdev->auth_bsses[i],
which is needed in order for an auth to succeed.  The code path that
gets us there is:

    mac80211/rx.c: ieee80211_rx_h_mgmt()
    mac80211/mlme.c: ieee80211_sta_rx_mgmt()
    ...then through the queued work and...
    ieee80211_sta_rx_queued_mgmt()

At the bottom of the latter function, outside of the block that checks
for our authentication state, we call cfg80211_send_deauth() in
response to IEEE80211_STYPE_DEAUTH, which quite arguably should never
be called if we're authenticated.  The only time this issue touches
cfg80211 is that final call to send_deauth() which I believe is done
in error.  I think the fix should be in mac80211 somewhere.

I didn't find a way to tell where we were in the authentication proces
from within ieee80211_sta_rx_queued_mgmt(), so I swallowed the packet
much earlier in the process from within ieee80211_work_rx_mgmt(),
which has access to that state, and can indeed claim packets for
itself it it believes it knows best what to do with them.

I hope this clears up my thinking on this.  I'd be happy to change the
patch in whatever way makes sense.

--
Paul

On Fri, Jul 2, 2010 at 10:29 AM, Johannes Berg
<johannes@sipsolutions.net> wrote:
> On Thu, 2010-07-01 at 10:21 -0700, Paul Stewart wrote:
>> @@ -1030,6 +1030,25 @@ ieee80211_rx_result
>> ieee80211_work_rx_mgmt(struct ieee80211_sub_if_data *sdata,
>>                       skb_queue_tail(&local->work_skb_queue, skb);
>>                       ieee80211_queue_work(&local->hw, &local->work_work);
>>                       return RX_QUEUED;
>> +             case IEEE80211_STYPE_DEAUTH:
>> +                     /*
>> +                      * If we get sent a DEAUTH while we are
>> +                      * actively trying to authenticate to this
>> +                      * station, we shoot ourselves in the foot if
>> +                      * we fall through using RX_CONTINUE and allow
>> +                      * the bss context to disappear
>> +                      * (ieee80211_sta_rx_mgmt()).  This is
>> +                      * especially true if the reason for the
>> +                      * DEAUTH was a negative but temporary direct
>> +                      * response to an AUTH attempt. Let the retry
>> +                      * mechanism run its course instead.
>> +                      */
>> +                        reason_code = le16_to_cpu(mgmt->u.deauth.reason_code);
>> +                     if (wk->type == IEEE80211_WORK_AUTH &&
>> +                            reason_code == WLAN_REASON_PREV_AUTH_NOT_VALID) {
>> +                             return RX_DROP_MONITOR;
>> +                     }
>> +                     break;
>
> Ok, wow, I finally understand this patch, but is it weird!! You're
> modifying work.c to avoid having the mlme.c code send this frame to
> cfg80211? That's really confusing.
>
> The real reason for this is that we send up the deauth frame even when
> we're not even authenticated. This happens in mlme.c. Therefore, we
> should improve the logic in ieee80211_sta_rx_queued_mgmt() to make sure
> it only triggers when we're authenticated with the BSS?
>
> Alternatively, since cfg80211 tracks this, it would be easier to modify
> cfg80211_send_rx_auth() to not send the event to userspace in the !done
> case I guess.
>
> johannes
>
>

^ permalink raw reply

* Re: rt2x00 & mac80211: correct usage of ieee80211_beacon_get_tim?
From: Johannes Berg @ 2010-07-02 18:06 UTC (permalink / raw)
  To: Helmut Schaa; +Cc: linux-wireless, Ivo van Doorn, Gertjan van Wingerde
In-Reply-To: <201007021959.45704.helmut.schaa@googlemail.com>

On Fri, 2010-07-02 at 19:59 +0200, Helmut Schaa wrote:

> > unless your
> > device itself is capable of generating the TIM IE _right before_ the
> > beacon gets transmitted.
> 
> Agreed. At least on rt2800 we can use the pre tbtt interrupt to update the
> beacon just before it is sent out.

Careful though. You don't know how far in advance it is triggered (or
maybe you do) or if the time will be sufficient to generate and upload
the beacon to the device. You could even hit lock contention I think.

johannes


^ permalink raw reply

* Re: rt2x00 & mac80211: correct usage of ieee80211_beacon_get_tim?
From: Helmut Schaa @ 2010-07-02 17:59 UTC (permalink / raw)
  To: Johannes Berg; +Cc: linux-wireless, Ivo van Doorn, Gertjan van Wingerde
In-Reply-To: <1278090770.15412.4.camel@jlt3.sipsolutions.net>

Am Freitag 02 Juli 2010 schrieb Johannes Berg:
> On Sun, 2010-06-27 at 21:00 +0200, Helmut Schaa wrote:
> 
> > rt2x00 pulls every beacon. But not directly _prior_ to transmission as the 
> > hw lacks an interrupt for that. Instead the next beacon gets pulled _after_
> > the beacondone interrupt (which is obviously triggered directly after the
> > beacon was sent). So, all TIM changes that happen during the next beacon
> > interval won't be included in the next beacon. Hence, rt2x00 also implements
> > the set_tim callback and updates the beacon through these as well.
> > 
> > This gives us a correct TIM but as I explained earlier breaks the DTIM
> > count (and thus bc/mc buffering which is done in mac80211 fot rt2x00).
> > 
> > One possible option to fix this in rt2x00 would be to delay the beacon
> > update (as it is already put on a workqueue we could simply replace it by
> > a delayed work) by beaconinterval - 10ms or something. But I'm not how
> > accurate that would be (and of course remove the set_tim callback).
> 
> Well, after a beacon is before a beacon.

Yes ;)

> I think iwlwifi also pulls the
> next beacon after the previous one was sent. That just means you get a
> potential higher delay, 

Agreed.

> but otherwise it doesn't really matter that
> much. You'll never be able to close the race fully anyway,

No, but I'd like to get as close as possible. The idea with the delayed
work was intended to reduce the latency as good as we can.

> unless your
> device itself is capable of generating the TIM IE _right before_ the
> beacon gets transmitted.

Agreed. At least on rt2800 we can use the pre tbtt interrupt to update the
beacon just before it is sent out.

> Therefore, with standard beacon intervals of 100 TU, I don't think it
> matters all that much whether it's before or after?

Yeah, maybe that's just fine. I guess I'll just drop the set_tim callback
from all rt2x00 pci variants and implement the pre tbtt interrupt on rt2800.

Thanks,
Helmut

^ permalink raw reply

* How to enable channels 12,13?
From: Jaroslav Fojtik @ 2010-07-02 17:33 UTC (permalink / raw)
  To: linux-wireless

Dears,

My device ignores channels 12,13, but they are allowed in our country.
Is it possible to shut down defective regdomain policy?

The proper regdomain is already set:
[    5.809776] ath5k 0000:02:0a.0: registered as 'phy1'
[    6.276736] ath: EEPROM regdomain: 0x36
.....
[    5.152196] ath5k 0000:02:08.0: registered as 'phy0'
[    5.749710] ath: EEPROM regdomain: 0x36
.....
[    6.278376] ath5k phy1: Atheros AR5213A chip found (MAC: 0x59, PHY: 0x43)
[    6.278440] ath5k phy1: RF5112B multiband radio found (0x36)
[    6.278539] ath5k 0000:02:0b.0: PCI INT A -> GSI 16 (level, low) -> IRQ 16
[    6.278679] ath5k 0000:02:0b.0: registered as 'phy2'
[    6.745533] ath: EEPROM regdomain: 0x36
[    6.745538] ath: EEPROM indicates we should expect a direct regpair map
[    6.745547] ath: Country alpha2 being used: CZ
[    6.745553] ath: Regpair used: 0x36
[    6.745661] cfg80211: Calling CRDA for country: CZ


Strange ???

root@dvouramenna:~# iw reg get
country 00:
        (2402 - 2472 @ 40), (6, 20)
        (2457 - 2482 @ 20), (6, 20), PASSIVE-SCAN, NO-IBSS
        (2474 - 2494 @ 20), (6, 20), NO-OFDM, PASSIVE-SCAN, NO-IBSS
        (5170 - 5250 @ 40), (6, 20), PASSIVE-SCAN, NO-IBSS
        (5735 - 5835 @ 40), (6, 20), PASSIVE-SCAN, NO-IBSS

Hmmm?? What is it:

root@dvouramenna:~# iw reg set CZ
root@dvouramenna:~# iw reg get
country 00:
        (2402 - 2472 @ 40), (6, 20)
        (2457 - 2482 @ 20), (6, 20), PASSIVE-SCAN, NO-IBSS
        (2474 - 2494 @ 20), (6, 20), NO-OFDM, PASSIVE-SCAN, NO-IBSS
        (5170 - 5250 @ 40), (6, 20), PASSIVE-SCAN, NO-IBSS
        (5735 - 5835 @ 40), (6, 20), PASSIVE-SCAN, NO-IBSS


Even attempt of rewriting regdomain shows that a device has proper 
domain in EEPROM:

root@dvouramenna:~#ath_info -g 1:0 -w 0xfdee0000 regdomain 36
......................................
new GPIO CR 00000303 DO 00000001 DI 00000007
           regdomain (0x00bf) := 0x0036
WARNING: The write function may easy brick your device or
violate state regulation on frequency usage.
Proceed on your own risk!
Shall I write the above value(s)? (y/n)  y
pair 0: skipped, value already there
restoring GPIO CR 303 -> 3


But channels are somehow blocked from unknown reason.

regards
   Jara

iw list:

Wiphy phy1
        Band 1:
                Frequencies:
                        * 2412 MHz [1] (20.0 dBm)
                        * 2417 MHz [2] (20.0 dBm)
                        * 2422 MHz [3] (20.0 dBm)
                        * 2427 MHz [4] (20.0 dBm)
                        * 2432 MHz [5] (20.0 dBm)
                        * 2437 MHz [6] (20.0 dBm)
                        * 2442 MHz [7] (20.0 dBm)
                        * 2447 MHz [8] (20.0 dBm)
                        * 2452 MHz [9] (20.0 dBm)
                        * 2457 MHz [10] (20.0 dBm)
                        * 2462 MHz [11] (20.0 dBm)
                        * 2467 MHz [12] (disabled)
                        * 2472 MHz [13] (disabled)
                        * 2484 MHz [14] (disabled)
                Bitrates (non-HT):
                        * 1.0 Mbps
                        * 2.0 Mbps (short preamble supported)
                        * 5.5 Mbps (short preamble supported)
                        * 11.0 Mbps (short preamble supported)
                        * 6.0 Mbps
                        * 9.0 Mbps
                        * 12.0 Mbps
                        * 18.0 Mbps
                        * 24.0 Mbps
                        * 36.0 Mbps
                        * 48.0 Mbps
                        * 54.0 Mbps
        Band 2:
                Frequencies:
                        * 5180 MHz [36] (30.0 dBm)
                        * 5200 MHz [40] (30.0 dBm) (passive scanning, no IBSS)
                        * 5220 MHz [44] (30.0 dBm) (passive scanning, no IBSS)
                        * 5240 MHz [48] (30.0 dBm) (passive scanning, no IBSS)
                        * 5260 MHz [52] (30.0 dBm) (passive scanning, no IBSS, radar 
detection)
                        * 5280 MHz [56] (30.0 dBm) (passive scanning, no IBSS, radar 
detection)
                        * 5300 MHz [60] (30.0 dBm) (passive scanning, no IBSS, radar 
detection)
                        * 5320 MHz [64] (30.0 dBm) (passive scanning, no IBSS, radar 
detection)
                        * 5500 MHz [100] (disabled)
                        * 5520 MHz [104] (disabled)
                        * 5540 MHz [108] (disabled)
                        * 5560 MHz [112] (disabled)
                        * 5580 MHz [116] (disabled)
                        * 5600 MHz [120] (disabled)
                        * 5620 MHz [124] (disabled)
                        * 5640 MHz [128] (disabled)
                        * 5660 MHz [132] (disabled)
                        * 5680 MHz [136] (disabled)
                        * 5700 MHz [140] (disabled)
                        * 5745 MHz [149] (30.0 dBm) (passive scanning, no IBSS)
                        * 5765 MHz [153] (30.0 dBm) (passive scanning, no IBSS)
                        * 5785 MHz [157] (30.0 dBm) (passive scanning, no IBSS)
                        * 5805 MHz [161] (30.0 dBm) (passive scanning, no IBSS)
                        * 5825 MHz [165] (30.0 dBm) (passive scanning, no IBSS)
                Bitrates (non-HT):
                        * 6.0 Mbps
                        * 9.0 Mbps
                        * 12.0 Mbps
                        * 18.0 Mbps
                        * 24.0 Mbps
                        * 36.0 Mbps
                        * 48.0 Mbps
                        * 54.0 Mbps
        max # scan SSIDs: 4
        Supported interface modes:
                 * IBSS
                 * managed
                 * AP
                 * AP/VLAN
                 * monitor
                 * mesh point
        Supported commands:
                 * new_interface
                 * set_interface
                 * new_key
                 * new_beacon
                 * new_station
                 * new_mpath
                 * set_mesh_params
                 * set_bss
                 * authenticate
                 * associate
                 * deauthenticate
                 * disassociate
                 * join_ibss
                 * Unknown command (55)
                 * Unknown command (57)
                 * Unknown command (59)
                 * set_wiphy_netns
                 * Unknown command (65)
                 * connect
                 * disconnect
Wiphy phy0
        Band 1:
                Frequencies:
                        * 2412 MHz [1] (20.0 dBm)
                        * 2417 MHz [2] (20.0 dBm)
                        * 2422 MHz [3] (20.0 dBm)
                        * 2427 MHz [4] (20.0 dBm)
                        * 2432 MHz [5] (20.0 dBm)
                        * 2437 MHz [6] (20.0 dBm)
                        * 2442 MHz [7] (20.0 dBm)
                        * 2447 MHz [8] (20.0 dBm)
                        * 2452 MHz [9] (20.0 dBm)
                        * 2457 MHz [10] (20.0 dBm)
                        * 2462 MHz [11] (20.0 dBm)
                        * 2467 MHz [12] (disabled)
                        * 2472 MHz [13] (disabled)
                        * 2484 MHz [14] (disabled)
                Bitrates (non-HT):
                        * 1.0 Mbps
                        * 2.0 Mbps (short preamble supported)
                        * 5.5 Mbps (short preamble supported)
                        * 11.0 Mbps (short preamble supported)
                        * 6.0 Mbps
                        * 9.0 Mbps
                        * 12.0 Mbps
                        * 18.0 Mbps
                        * 24.0 Mbps
                        * 36.0 Mbps
                        * 48.0 Mbps
                        * 54.0 Mbps
        max # scan SSIDs: 4
        Supported interface modes:
                 * IBSS
                 * managed
                 * AP
                 * AP/VLAN
                 * monitor
                 * mesh point
        Supported commands:
                 * new_interface
                 * set_interface
                 * new_key
                 * new_beacon
                 * new_station
                 * new_mpath
                 * set_mesh_params
                 * set_bss
                 * authenticate
                 * associate
                 * deauthenticate
                 * disassociate
                 * join_ibss
                 * Unknown command (55)
                 * Unknown command (57)
                 * Unknown command (59)
                 * set_wiphy_netns
                 * Unknown command (65)
                 * connect
                 * disconnect
root@dvouramenna:~#


^ permalink raw reply

* Re: [PATCH 2.6.34] mac80211: Fix auth retries if AP sends temporary deauth
From: Johannes Berg @ 2010-07-02 17:29 UTC (permalink / raw)
  To: Paul Stewart; +Cc: linux-wireless, Michael Wu, Jiri Benc, John W. Linville
In-Reply-To: <AANLkTilV1t1737ciSPyyETeBEcN_QXsYxgEwpZIIucR2@mail.gmail.com>

On Thu, 2010-07-01 at 10:21 -0700, Paul Stewart wrote:
> @@ -1030,6 +1030,25 @@ ieee80211_rx_result
> ieee80211_work_rx_mgmt(struct ieee80211_sub_if_data *sdata,
>  			skb_queue_tail(&local->work_skb_queue, skb);
>  			ieee80211_queue_work(&local->hw, &local->work_work);
>  			return RX_QUEUED;
> +		case IEEE80211_STYPE_DEAUTH:
> +			/*
> +			 * If we get sent a DEAUTH while we are
> +			 * actively trying to authenticate to this
> +			 * station, we shoot ourselves in the foot if
> +			 * we fall through using RX_CONTINUE and allow
> +			 * the bss context to disappear
> +			 * (ieee80211_sta_rx_mgmt()).  This is
> +			 * especially true if the reason for the
> +			 * DEAUTH was a negative but temporary direct
> +			 * response to an AUTH attempt. Let the retry
> +			 * mechanism run its course instead.
> +			 */
> +                        reason_code = le16_to_cpu(mgmt->u.deauth.reason_code);
> +			if (wk->type == IEEE80211_WORK_AUTH &&
> +                            reason_code == WLAN_REASON_PREV_AUTH_NOT_VALID) {
> +				return RX_DROP_MONITOR;
> +			}
> +			break;

Ok, wow, I finally understand this patch, but is it weird!! You're
modifying work.c to avoid having the mlme.c code send this frame to
cfg80211? That's really confusing.

The real reason for this is that we send up the deauth frame even when
we're not even authenticated. This happens in mlme.c. Therefore, we
should improve the logic in ieee80211_sta_rx_queued_mgmt() to make sure
it only triggers when we're authenticated with the BSS?

Alternatively, since cfg80211 tracks this, it would be easier to modify
cfg80211_send_rx_auth() to not send the event to userspace in the !done
case I guess.

johannes


^ permalink raw reply

* Re: [PATCH 2.6.34] mac80211: Fix auth retries if AP sends temporary deauth
From: Johannes Berg @ 2010-07-02 17:21 UTC (permalink / raw)
  To: Paul Stewart; +Cc: linux-wireless, Michael Wu, Jiri Benc, John W. Linville
In-Reply-To: <AANLkTilV1t1737ciSPyyETeBEcN_QXsYxgEwpZIIucR2@mail.gmail.com>

On Thu, 2010-07-01 at 10:21 -0700, Paul Stewart wrote:
> This bypasses destruction of BSS state if a temporary DEAUTH packet is
> received while performing an AUTH.  This will allow the retry mechanism
> (which runs regardless of this patch) to succeed, since we do not remove
> the BSS state which is required to complete authentication on the client
> side in cfg80211_send_rx_auth().
> 
> The specific case handled here is "Previous authentication no longer
> valid", which is usually generated by an AP if the AP still has saved
> state of the STA being authenticated.  Usually a retry will be successful.

You don't usually send patches to stable, you send them to the current
tree with a cc stable tag, and then they get picked up.

I'm going to look at the problem now, I'm still not really convinced by
this.

johannes


^ permalink raw reply

* Re: rt2x00 & mac80211: correct usage of ieee80211_beacon_get_tim?
From: Johannes Berg @ 2010-07-02 17:12 UTC (permalink / raw)
  To: Helmut Schaa; +Cc: linux-wireless, Ivo van Doorn, Gertjan van Wingerde
In-Reply-To: <201006272100.22216.helmut.schaa@googlemail.com>

On Sun, 2010-06-27 at 21:00 +0200, Helmut Schaa wrote:

> rt2x00 pulls every beacon. But not directly _prior_ to transmission as the 
> hw lacks an interrupt for that. Instead the next beacon gets pulled _after_
> the beacondone interrupt (which is obviously triggered directly after the
> beacon was sent). So, all TIM changes that happen during the next beacon
> interval won't be included in the next beacon. Hence, rt2x00 also implements
> the set_tim callback and updates the beacon through these as well.
> 
> This gives us a correct TIM but as I explained earlier breaks the DTIM
> count (and thus bc/mc buffering which is done in mac80211 fot rt2x00).
> 
> One possible option to fix this in rt2x00 would be to delay the beacon
> update (as it is already put on a workqueue we could simply replace it by
> a delayed work) by beaconinterval - 10ms or something. But I'm not how
> accurate that would be (and of course remove the set_tim callback).

Well, after a beacon is before a beacon. I think iwlwifi also pulls the
next beacon after the previous one was sent. That just means you get a
potential higher delay, but otherwise it doesn't really matter that
much. You'll never be able to close the race fully anyway, unless your
device itself is capable of generating the TIM IE _right before_ the
beacon gets transmitted.

Therefore, with standard beacon intervals of 100 TU, I don't think it
matters all that much whether it's before or after?

johannes


^ permalink raw reply

* Re: Question on 'iw reg get/set'
From: John W. Linville @ 2010-07-02 16:48 UTC (permalink / raw)
  To: Ben Greear; +Cc: linux-wireless
In-Reply-To: <4C2E170E.6040207@candelatech.com>

On Fri, Jul 02, 2010 at 09:42:54AM -0700, Ben Greear wrote:
> On 07/02/2010 07:12 AM, John W. Linville wrote:

> >The ath9k driver is setting its own regulatory restrictions based on
> >its EEPROM.  Setting the domain from userland can only further restrict
> >the regulatory settings.  The '98' value represents a synthesized
> >regulatory domain, based on the intersection of the available source
> >of regulatory information (which can include the EEPROM, the userland
> >setting, and a country IE from your AP).
> 
> Is there any way to get/set these raw settings (like, whatever it has in EEPROM)?
> 
> I expect we may ship some of these systems overseas, and would like the flexibility
> to set the country-code for testing purposes, if nothing else.

I'll leave it to the Atheros guys to address this.

> Is there any documentation as to what '98' really means, or do we just ignore that
> value and look at the info printed out after that?

'98' pretty much means "look at the info" :-)

-- 
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


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