Linux wireless drivers development
 help / color / mirror / Atom feed
* [PATCH 12/15] iwlwifi: print warning when sending host command fails
From: Reinette Chatre @ 2009-10-30 21:36 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, ipw3945-devel, Reinette Chatre
In-Reply-To: <1256938578-9638-1-git-send-email-reinette.chatre@intel.com>

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

More information than the "-EIO" return code will be useful here.

Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
---
 drivers/net/wireless/iwlwifi/iwl-tx.c |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c
index 1868093..b1a2de8 100644
--- a/drivers/net/wireless/iwlwifi/iwl-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-tx.c
@@ -980,7 +980,8 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
 	       !(cmd->flags & CMD_SIZE_HUGE));
 
 	if (iwl_is_rfkill(priv) || iwl_is_ctkill(priv)) {
-		IWL_DEBUG_INFO(priv, "Not sending command - RF/CT KILL\n");
+		IWL_WARN(priv, "Not sending command - %s KILL\n",
+			 iwl_is_rfkill(priv) ? "RF" : "CT");
 		return -EIO;
 	}
 
-- 
1.5.6.3


^ permalink raw reply related

* [PATCH 15/15] iwlwifi: add wimax/wifi coexist support for 6x50 series
From: Reinette Chatre @ 2009-10-30 21:36 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, ipw3945-devel, Wey-Yi Guy, Reinette Chatre
In-Reply-To: <1256938578-9638-1-git-send-email-reinette.chatre@intel.com>

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

For 6x50 series, it is wimax/wifi combo device, so driver need to enable
the wimax/wifi co-exist function and send the coexist event priority
table to uCode for operation.

The priority table will be used by uCode to determine what is the proper
action it should take when co-exist with WiMAX.
For example, when WiFi runs a scan, it must own radio exclusively, therefore
will disconnect WiMAX if WiMAX is connected.

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-5000.c     |   12 +---
 drivers/net/wireless/iwlwifi/iwl-6000.c     |    3 +
 drivers/net/wireless/iwlwifi/iwl-commands.h |   92 +++++++++++++++++++++++++++
 drivers/net/wireless/iwlwifi/iwl-core.c     |   59 +++++++++++++++++
 drivers/net/wireless/iwlwifi/iwl-core.h     |    3 +
 5 files changed, 158 insertions(+), 11 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c
index b8ddd70..a97d93d 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-5000.c
@@ -592,16 +592,6 @@ static void iwl5000_tx_queue_set_status(struct iwl_priv *priv,
 		       scd_retry ? "BA" : "AC", txq_id, tx_fifo_id);
 }
 
-static int iwl5000_send_wimax_coex(struct iwl_priv *priv)
-{
-	struct iwl_wimax_coex_cmd coex_cmd;
-
-	memset(&coex_cmd, 0, sizeof(coex_cmd));
-
-	return iwl_send_cmd_pdu(priv, COEX_PRIORITY_TABLE_CMD,
-				sizeof(coex_cmd), &coex_cmd);
-}
-
 int iwl5000_alive_notify(struct iwl_priv *priv)
 {
 	u32 a;
@@ -682,7 +672,7 @@ int iwl5000_alive_notify(struct iwl_priv *priv)
 	spin_unlock_irqrestore(&priv->lock, flags);
 
 
-	iwl5000_send_wimax_coex(priv);
+	iwl_send_wimax_coex(priv);
 
 	iwl5000_set_Xtal_calib(priv);
 	iwl_send_calib_results(priv);
diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c
index a4a8b5e..70e117f 100644
--- a/drivers/net/wireless/iwlwifi/iwl-6000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-6000.c
@@ -491,6 +491,7 @@ struct iwl_cfg iwl6050_2agn_cfg = {
 	.adv_thermal_throttle = true,
 	.support_ct_kill_exit = true,
 	.support_sm_ps = true,
+	.support_wimax_coexist = true,
 };
 
 struct iwl_cfg iwl6050_2abg_cfg = {
@@ -520,6 +521,7 @@ struct iwl_cfg iwl6050_2abg_cfg = {
 	.supports_idle = true,
 	.adv_thermal_throttle = true,
 	.support_ct_kill_exit = true,
+	.support_wimax_coexist = true,
 };
 
 struct iwl_cfg iwl6000_3agn_cfg = {
@@ -581,6 +583,7 @@ struct iwl_cfg iwl6050_3agn_cfg = {
 	.adv_thermal_throttle = true,
 	.support_ct_kill_exit = true,
 	.support_sm_ps = true,
+	.support_wimax_coexist = true,
 };
 
 MODULE_FIRMWARE(IWL6000_MODULE_FIRMWARE(IWL6000_UCODE_API_MAX));
diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h
index 43dd6af..b62c90e 100644
--- a/drivers/net/wireless/iwlwifi/iwl-commands.h
+++ b/drivers/net/wireless/iwlwifi/iwl-commands.h
@@ -3507,6 +3507,98 @@ struct iwl_led_cmd {
  * also used as potential "events" value for both
  * COEX_MEDIUM_NOTIFICATION and COEX_EVENT_CMD
  */
+
+/*
+ * COEX events entry flag masks
+ * RP - Requested Priority
+ * WP - Win Medium Priority: priority assigned when the contention has been won
+ */
+#define COEX_EVT_FLAG_MEDIUM_FREE_NTFY_FLG        (0x1)
+#define COEX_EVT_FLAG_MEDIUM_ACTV_NTFY_FLG        (0x2)
+#define COEX_EVT_FLAG_DELAY_MEDIUM_FREE_NTFY_FLG  (0x4)
+
+#define COEX_CU_UNASSOC_IDLE_RP               4
+#define COEX_CU_UNASSOC_MANUAL_SCAN_RP        4
+#define COEX_CU_UNASSOC_AUTO_SCAN_RP          4
+#define COEX_CU_CALIBRATION_RP                4
+#define COEX_CU_PERIODIC_CALIBRATION_RP       4
+#define COEX_CU_CONNECTION_ESTAB_RP           4
+#define COEX_CU_ASSOCIATED_IDLE_RP            4
+#define COEX_CU_ASSOC_MANUAL_SCAN_RP          4
+#define COEX_CU_ASSOC_AUTO_SCAN_RP            4
+#define COEX_CU_ASSOC_ACTIVE_LEVEL_RP         4
+#define COEX_CU_RF_ON_RP                      6
+#define COEX_CU_RF_OFF_RP                     4
+#define COEX_CU_STAND_ALONE_DEBUG_RP          6
+#define COEX_CU_IPAN_ASSOC_LEVEL_RP           4
+#define COEX_CU_RSRVD1_RP                     4
+#define COEX_CU_RSRVD2_RP                     4
+
+#define COEX_CU_UNASSOC_IDLE_WP               3
+#define COEX_CU_UNASSOC_MANUAL_SCAN_WP        3
+#define COEX_CU_UNASSOC_AUTO_SCAN_WP          3
+#define COEX_CU_CALIBRATION_WP                3
+#define COEX_CU_PERIODIC_CALIBRATION_WP       3
+#define COEX_CU_CONNECTION_ESTAB_WP           3
+#define COEX_CU_ASSOCIATED_IDLE_WP            3
+#define COEX_CU_ASSOC_MANUAL_SCAN_WP          3
+#define COEX_CU_ASSOC_AUTO_SCAN_WP            3
+#define COEX_CU_ASSOC_ACTIVE_LEVEL_WP         3
+#define COEX_CU_RF_ON_WP                      3
+#define COEX_CU_RF_OFF_WP                     3
+#define COEX_CU_STAND_ALONE_DEBUG_WP          6
+#define COEX_CU_IPAN_ASSOC_LEVEL_WP           3
+#define COEX_CU_RSRVD1_WP                     3
+#define COEX_CU_RSRVD2_WP                     3
+
+#define COEX_UNASSOC_IDLE_FLAGS                     0
+#define COEX_UNASSOC_MANUAL_SCAN_FLAGS		\
+	(COEX_EVT_FLAG_MEDIUM_FREE_NTFY_FLG |	\
+	COEX_EVT_FLAG_MEDIUM_ACTV_NTFY_FLG)
+#define COEX_UNASSOC_AUTO_SCAN_FLAGS		\
+	(COEX_EVT_FLAG_MEDIUM_FREE_NTFY_FLG |	\
+	COEX_EVT_FLAG_MEDIUM_ACTV_NTFY_FLG)
+#define COEX_CALIBRATION_FLAGS			\
+	(COEX_EVT_FLAG_MEDIUM_FREE_NTFY_FLG |	\
+	COEX_EVT_FLAG_MEDIUM_ACTV_NTFY_FLG)
+#define COEX_PERIODIC_CALIBRATION_FLAGS             0
+/*
+ * COEX_CONNECTION_ESTAB:
+ * we need DELAY_MEDIUM_FREE_NTFY to let WiMAX disconnect from network.
+ */
+#define COEX_CONNECTION_ESTAB_FLAGS		\
+	(COEX_EVT_FLAG_MEDIUM_FREE_NTFY_FLG |	\
+	COEX_EVT_FLAG_MEDIUM_ACTV_NTFY_FLG |	\
+	COEX_EVT_FLAG_DELAY_MEDIUM_FREE_NTFY_FLG)
+#define COEX_ASSOCIATED_IDLE_FLAGS                  0
+#define COEX_ASSOC_MANUAL_SCAN_FLAGS		\
+	(COEX_EVT_FLAG_MEDIUM_FREE_NTFY_FLG |	\
+	COEX_EVT_FLAG_MEDIUM_ACTV_NTFY_FLG)
+#define COEX_ASSOC_AUTO_SCAN_FLAGS		\
+	(COEX_EVT_FLAG_MEDIUM_FREE_NTFY_FLG |	\
+	 COEX_EVT_FLAG_MEDIUM_ACTV_NTFY_FLG)
+#define COEX_ASSOC_ACTIVE_LEVEL_FLAGS               0
+#define COEX_RF_ON_FLAGS                            0
+#define COEX_RF_OFF_FLAGS                           0
+#define COEX_STAND_ALONE_DEBUG_FLAGS		\
+	(COEX_EVT_FLAG_MEDIUM_FREE_NTFY_FLG |	\
+	 COEX_EVT_FLAG_MEDIUM_ACTV_NTFY_FLG)
+#define COEX_IPAN_ASSOC_LEVEL_FLAGS		\
+	(COEX_EVT_FLAG_MEDIUM_FREE_NTFY_FLG |	\
+	 COEX_EVT_FLAG_MEDIUM_ACTV_NTFY_FLG |	\
+	 COEX_EVT_FLAG_DELAY_MEDIUM_FREE_NTFY_FLG)
+#define COEX_RSRVD1_FLAGS                           0
+#define COEX_RSRVD2_FLAGS                           0
+/*
+ * COEX_CU_RF_ON is the event wrapping all radio ownership.
+ * We need DELAY_MEDIUM_FREE_NTFY to let WiMAX disconnect from network.
+ */
+#define COEX_CU_RF_ON_FLAGS			\
+	(COEX_EVT_FLAG_MEDIUM_FREE_NTFY_FLG |	\
+	 COEX_EVT_FLAG_MEDIUM_ACTV_NTFY_FLG |	\
+	 COEX_EVT_FLAG_DELAY_MEDIUM_FREE_NTFY_FLG)
+
+
 enum {
 	/* un-association part */
 	COEX_UNASSOC_IDLE		= 0,
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index 6a9d593..112181b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -47,6 +47,37 @@ MODULE_VERSION(IWLWIFI_VERSION);
 MODULE_AUTHOR(DRV_COPYRIGHT " " DRV_AUTHOR);
 MODULE_LICENSE("GPL");
 
+static struct iwl_wimax_coex_event_entry cu_priorities[COEX_NUM_OF_EVENTS] = {
+	{COEX_CU_UNASSOC_IDLE_RP, COEX_CU_UNASSOC_IDLE_WP,
+	 0, COEX_UNASSOC_IDLE_FLAGS},
+	{COEX_CU_UNASSOC_MANUAL_SCAN_RP, COEX_CU_UNASSOC_MANUAL_SCAN_WP,
+	 0, COEX_UNASSOC_MANUAL_SCAN_FLAGS},
+	{COEX_CU_UNASSOC_AUTO_SCAN_RP, COEX_CU_UNASSOC_AUTO_SCAN_WP,
+	 0, COEX_UNASSOC_AUTO_SCAN_FLAGS},
+	{COEX_CU_CALIBRATION_RP, COEX_CU_CALIBRATION_WP,
+	 0, COEX_CALIBRATION_FLAGS},
+	{COEX_CU_PERIODIC_CALIBRATION_RP, COEX_CU_PERIODIC_CALIBRATION_WP,
+	 0, COEX_PERIODIC_CALIBRATION_FLAGS},
+	{COEX_CU_CONNECTION_ESTAB_RP, COEX_CU_CONNECTION_ESTAB_WP,
+	 0, COEX_CONNECTION_ESTAB_FLAGS},
+	{COEX_CU_ASSOCIATED_IDLE_RP, COEX_CU_ASSOCIATED_IDLE_WP,
+	 0, COEX_ASSOCIATED_IDLE_FLAGS},
+	{COEX_CU_ASSOC_MANUAL_SCAN_RP, COEX_CU_ASSOC_MANUAL_SCAN_WP,
+	 0, COEX_ASSOC_MANUAL_SCAN_FLAGS},
+	{COEX_CU_ASSOC_AUTO_SCAN_RP, COEX_CU_ASSOC_AUTO_SCAN_WP,
+	 0, COEX_ASSOC_AUTO_SCAN_FLAGS},
+	{COEX_CU_ASSOC_ACTIVE_LEVEL_RP, COEX_CU_ASSOC_ACTIVE_LEVEL_WP,
+	 0, COEX_ASSOC_ACTIVE_LEVEL_FLAGS},
+	{COEX_CU_RF_ON_RP, COEX_CU_RF_ON_WP, 0, COEX_CU_RF_ON_FLAGS},
+	{COEX_CU_RF_OFF_RP, COEX_CU_RF_OFF_WP, 0, COEX_RF_OFF_FLAGS},
+	{COEX_CU_STAND_ALONE_DEBUG_RP, COEX_CU_STAND_ALONE_DEBUG_WP,
+	 0, COEX_STAND_ALONE_DEBUG_FLAGS},
+	{COEX_CU_IPAN_ASSOC_LEVEL_RP, COEX_CU_IPAN_ASSOC_LEVEL_WP,
+	 0, COEX_IPAN_ASSOC_LEVEL_FLAGS},
+	{COEX_CU_RSRVD1_RP, COEX_CU_RSRVD1_WP, 0, COEX_RSRVD1_FLAGS},
+	{COEX_CU_RSRVD2_RP, COEX_CU_RSRVD2_WP, 0, COEX_RSRVD2_FLAGS}
+};
+
 #define IWL_DECLARE_RATE_INFO(r, s, ip, in, rp, rn, pp, np)    \
 	[IWL_RATE_##r##M_INDEX] = { IWL_RATE_##r##M_PLCP,      \
 				    IWL_RATE_SISO_##s##M_PLCP, \
@@ -2866,6 +2897,34 @@ void iwl_free_txq_mem(struct iwl_priv *priv)
 }
 EXPORT_SYMBOL(iwl_free_txq_mem);
 
+int iwl_send_wimax_coex(struct iwl_priv *priv)
+{
+	struct iwl_wimax_coex_cmd uninitialized_var(coex_cmd);
+
+	if (priv->cfg->support_wimax_coexist) {
+		/* UnMask wake up src at associated sleep */
+		coex_cmd.flags |= COEX_FLAGS_ASSOC_WA_UNMASK_MSK;
+
+		/* UnMask wake up src at unassociated sleep */
+		coex_cmd.flags |= COEX_FLAGS_UNASSOC_WA_UNMASK_MSK;
+		memcpy(coex_cmd.sta_prio, cu_priorities,
+			sizeof(struct iwl_wimax_coex_event_entry) *
+			 COEX_NUM_OF_EVENTS);
+
+		/* enabling the coexistence feature */
+		coex_cmd.flags |= COEX_FLAGS_COEX_ENABLE_MSK;
+
+		/* enabling the priorities tables */
+		coex_cmd.flags |= COEX_FLAGS_STA_TABLE_VALID_MSK;
+	} else {
+		/* coexistence is disabled */
+		memset(&coex_cmd, 0, sizeof(coex_cmd));
+	}
+	return iwl_send_cmd_pdu(priv, COEX_PRIORITY_TABLE_CMD,
+				sizeof(coex_cmd), &coex_cmd);
+}
+EXPORT_SYMBOL(iwl_send_wimax_coex);
+
 #ifdef CONFIG_IWLWIFI_DEBUGFS
 
 #define IWL_TRAFFIC_DUMP_SIZE	(IWL_TRAFFIC_ENTRY_SIZE * IWL_TRAFFIC_ENTRIES)
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index d2e47da..9574d8f 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -229,6 +229,7 @@ struct iwl_mod_params {
  * @adv_thermal_throttle: support advance thermal throttle
  * @support_ct_kill_exit: support ct kill exit condition
  * @support_sm_ps: support spatial multiplexing power save
+ * @support_wimax_coexist: support wimax/wifi co-exist
  *
  * We enable the driver to be backward compatible wrt API version. The
  * driver specifies which APIs it supports (with @ucode_api_max being the
@@ -285,6 +286,7 @@ struct iwl_cfg {
 	bool adv_thermal_throttle;
 	bool support_ct_kill_exit;
 	bool support_sm_ps;
+	const bool support_wimax_coexist;
 };
 
 /***************************
@@ -340,6 +342,7 @@ int iwl_alloc_txq_mem(struct iwl_priv *priv);
 void iwl_free_txq_mem(struct iwl_priv *priv);
 void iwlcore_rts_tx_cmd_flag(struct ieee80211_tx_info *info,
 				__le32 *tx_flags);
+int iwl_send_wimax_coex(struct iwl_priv *priv);
 #ifdef CONFIG_IWLWIFI_DEBUGFS
 int iwl_alloc_traffic_mem(struct iwl_priv *priv);
 void iwl_free_traffic_mem(struct iwl_priv *priv);
-- 
1.5.6.3


^ permalink raw reply related

* [PATCH 14/15] iwlwifi: add SM PS support for 6x50 series
From: Reinette Chatre @ 2009-10-30 21:36 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, ipw3945-devel, Wey-Yi Guy, Reinette Chatre
In-Reply-To: <1256938578-9638-1-git-send-email-reinette.chatre@intel.com>

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

Spatial Multiplexing Power Save was disabled to achieve better
throughput while in power save mode by activating all the rx chains all the time.
By doing so, the device power consumption is high.

Enable static/dynamic spatial multiplexing power save if device support
it, which can lower the power consumption without impact throughput.

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-6000.c |    2 +
 drivers/net/wireless/iwlwifi/iwl-agn.c  |    4 ++
 drivers/net/wireless/iwlwifi/iwl-core.c |   48 ++++++++++++++++++++++++------
 drivers/net/wireless/iwlwifi/iwl-core.h |    2 +
 drivers/net/wireless/iwlwifi/iwl-dev.h  |    1 +
 drivers/net/wireless/iwlwifi/iwl-sta.c  |    5 +++
 6 files changed, 52 insertions(+), 10 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c
index 2f841a8..a4a8b5e 100644
--- a/drivers/net/wireless/iwlwifi/iwl-6000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-6000.c
@@ -490,6 +490,7 @@ struct iwl_cfg iwl6050_2agn_cfg = {
 	.supports_idle = true,
 	.adv_thermal_throttle = true,
 	.support_ct_kill_exit = true,
+	.support_sm_ps = true,
 };
 
 struct iwl_cfg iwl6050_2abg_cfg = {
@@ -579,6 +580,7 @@ struct iwl_cfg iwl6050_3agn_cfg = {
 	.supports_idle = true,
 	.adv_thermal_throttle = true,
 	.support_ct_kill_exit = true,
+	.support_sm_ps = true,
 };
 
 MODULE_FIRMWARE(IWL6000_MODULE_FIRMWARE(IWL6000_UCODE_API_MAX));
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index e99b753..2bbd04d 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -3012,6 +3012,10 @@ static int iwl_init_drv(struct iwl_priv *priv)
 	priv->band = IEEE80211_BAND_2GHZ;
 
 	priv->iw_mode = NL80211_IFTYPE_STATION;
+	if (priv->cfg->support_sm_ps)
+		priv->current_ht_config.sm_ps = WLAN_HT_CAP_SM_PS_DYNAMIC;
+	else
+		priv->current_ht_config.sm_ps = WLAN_HT_CAP_SM_PS_DISABLED;
 
 	/* Choose which receivers/antennas to use */
 	if (priv->cfg->ops->hcmd->set_rxon_chain)
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index 96eb476..6a9d593 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -415,8 +415,12 @@ static void iwlcore_init_ht_hw_capab(const struct iwl_priv *priv,
 	if (priv->cfg->ht_greenfield_support)
 		ht_info->cap |= IEEE80211_HT_CAP_GRN_FLD;
 	ht_info->cap |= IEEE80211_HT_CAP_SGI_20;
-	ht_info->cap |= (IEEE80211_HT_CAP_SM_PS &
-			     (WLAN_HT_CAP_SM_PS_DISABLED << 2));
+	if (priv->cfg->support_sm_ps)
+		ht_info->cap |= (IEEE80211_HT_CAP_SM_PS &
+				     (WLAN_HT_CAP_SM_PS_DYNAMIC << 2));
+	else
+		ht_info->cap |= (IEEE80211_HT_CAP_SM_PS &
+				     (WLAN_HT_CAP_SM_PS_DISABLED << 2));
 
 	max_bit_rate = MAX_BIT_RATE_20_MHZ;
 	if (priv->hw_params.ht40_channel & BIT(band)) {
@@ -964,17 +968,35 @@ static int iwl_get_active_rx_chain_count(struct iwl_priv *priv)
 }
 
 /*
- * When we are in power saving, there's no difference between
- * using multiple chains or just a single chain, but due to the
- * lack of SM PS we lose a lot of throughput if we use just a
- * single chain.
- *
- * Therefore, use the active count here (which will use multiple
- * chains unless connected to a legacy AP).
+ * When we are in power saving mode, unless device support spatial
+ * multiplexing power save, use the active count for rx chain count.
  */
 static int iwl_get_idle_rx_chain_count(struct iwl_priv *priv, int active_cnt)
 {
-	return active_cnt;
+	int idle_cnt = active_cnt;
+	bool is_cam = !test_bit(STATUS_POWER_PMI, &priv->status);
+
+	if (priv->cfg->support_sm_ps) {
+		/* # Rx chains when idling and maybe trying to save power */
+		switch (priv->current_ht_config.sm_ps) {
+		case WLAN_HT_CAP_SM_PS_STATIC:
+		case WLAN_HT_CAP_SM_PS_DYNAMIC:
+			idle_cnt = (is_cam) ? IWL_NUM_IDLE_CHAINS_DUAL :
+				IWL_NUM_IDLE_CHAINS_SINGLE;
+			break;
+		case WLAN_HT_CAP_SM_PS_DISABLED:
+			idle_cnt = (is_cam) ? active_cnt :
+				IWL_NUM_IDLE_CHAINS_SINGLE;
+			break;
+		case WLAN_HT_CAP_SM_PS_INVALID:
+		default:
+			IWL_ERR(priv, "invalid sm_ps mode %d\n",
+				priv->current_ht_config.sm_ps);
+			WARN_ON(1);
+			break;
+		}
+	}
+	return idle_cnt;
 }
 
 /* up to 4 chains */
@@ -2258,6 +2280,12 @@ static void iwl_ht_conf(struct iwl_priv *priv,
 					>> IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT;
 			maxstreams += 1;
 
+			ht_conf->sm_ps =
+				(u8)((ht_cap->cap & IEEE80211_HT_CAP_SM_PS)
+				>> 2);
+			IWL_DEBUG_MAC80211(priv, "sm_ps: 0x%x\n",
+				ht_conf->sm_ps);
+
 			if ((ht_cap->mcs.rx_mask[1] == 0) &&
 			    (ht_cap->mcs.rx_mask[2] == 0))
 				ht_conf->single_chain_sufficient = true;
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index ddf0998..d2e47da 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -228,6 +228,7 @@ struct iwl_mod_params {
  * @chain_noise_num_beacons: number of beacons used to compute chain noise
  * @adv_thermal_throttle: support advance thermal throttle
  * @support_ct_kill_exit: support ct kill exit condition
+ * @support_sm_ps: support spatial multiplexing power save
  *
  * We enable the driver to be backward compatible wrt API version. The
  * driver specifies which APIs it supports (with @ucode_api_max being the
@@ -283,6 +284,7 @@ struct iwl_cfg {
 	const bool supports_idle;
 	bool adv_thermal_throttle;
 	bool support_ct_kill_exit;
+	bool support_sm_ps;
 };
 
 /***************************
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index e7ce673..cb2642c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -517,6 +517,7 @@ struct iwl_ht_config {
 	bool is_ht;
 	bool is_40mhz;
 	bool single_chain_sufficient;
+	u8 sm_ps;
 	/* BSS related data */
 	u8 extension_chan_offset;
 	u8 ht_protection;
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c
index ce1ceac..74cc8db 100644
--- a/drivers/net/wireless/iwlwifi/iwl-sta.c
+++ b/drivers/net/wireless/iwlwifi/iwl-sta.c
@@ -182,6 +182,11 @@ static void iwl_set_ht_add_station(struct iwl_priv *priv, u8 index,
 		goto done;
 
 	mimo_ps_mode = (sta_ht_inf->cap & IEEE80211_HT_CAP_SM_PS) >> 2;
+	IWL_DEBUG_ASSOC(priv, "spatial multiplexing power save mode: %s\n",
+			(mimo_ps_mode == WLAN_HT_CAP_SM_PS_STATIC) ?
+			"static" :
+			(mimo_ps_mode == WLAN_HT_CAP_SM_PS_DYNAMIC) ?
+			"dynamic" : "disabled");
 
 	sta_flags = priv->stations[index].sta.station_flags;
 
-- 
1.5.6.3


^ permalink raw reply related

* [PATCH 13/15] iwlwifi: coex API data structure
From: Reinette Chatre @ 2009-10-30 21:36 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, ipw3945-devel, Wey-Yi Guy, Reinette Chatre
In-Reply-To: <1256938578-9638-1-git-send-email-reinette.chatre@intel.com>

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

Add data structure define for COEX_MEDIUM_NOTIFICATION and
COEX_EVENT_CMD host commands.

COEX_MEDIUM_NOTIFICATION is notification from uCode to host to indicate
medium changes. COEX_EVENT_CMD is from host to uCode for coex event
request.

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 |   69 +++++++++++++++++++++++++-
 drivers/net/wireless/iwlwifi/iwl-hcmd.c     |    2 +
 2 files changed, 68 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h
index 954bad6..43dd6af 100644
--- a/drivers/net/wireless/iwlwifi/iwl-commands.h
+++ b/drivers/net/wireless/iwlwifi/iwl-commands.h
@@ -3503,30 +3503,42 @@ struct iwl_led_cmd {
 } __attribute__ ((packed));
 
 /*
- * Coexistence WIFI/WIMAX  Command
- * COEX_PRIORITY_TABLE_CMD = 0x5a
- *
+ * station priority table entries
+ * also used as potential "events" value for both
+ * COEX_MEDIUM_NOTIFICATION and COEX_EVENT_CMD
  */
 enum {
+	/* un-association part */
 	COEX_UNASSOC_IDLE		= 0,
 	COEX_UNASSOC_MANUAL_SCAN	= 1,
 	COEX_UNASSOC_AUTO_SCAN		= 2,
+	/* calibration */
 	COEX_CALIBRATION		= 3,
 	COEX_PERIODIC_CALIBRATION	= 4,
+	/* connection */
 	COEX_CONNECTION_ESTAB		= 5,
+	/* association part */
 	COEX_ASSOCIATED_IDLE		= 6,
 	COEX_ASSOC_MANUAL_SCAN		= 7,
 	COEX_ASSOC_AUTO_SCAN		= 8,
 	COEX_ASSOC_ACTIVE_LEVEL		= 9,
+	/* RF ON/OFF */
 	COEX_RF_ON			= 10,
 	COEX_RF_OFF			= 11,
 	COEX_STAND_ALONE_DEBUG		= 12,
+	/* IPAN */
 	COEX_IPAN_ASSOC_LEVEL		= 13,
+	/* reserved */
 	COEX_RSRVD1			= 14,
 	COEX_RSRVD2			= 15,
 	COEX_NUM_OF_EVENTS		= 16
 };
 
+/*
+ * Coexistence WIFI/WIMAX  Command
+ * COEX_PRIORITY_TABLE_CMD = 0x5a
+ *
+ */
 struct iwl_wimax_coex_event_entry {
 	u8 request_prio;
 	u8 win_medium_prio;
@@ -3551,6 +3563,55 @@ struct iwl_wimax_coex_cmd {
 	struct iwl_wimax_coex_event_entry sta_prio[COEX_NUM_OF_EVENTS];
 } __attribute__ ((packed));
 
+/*
+ * Coexistence MEDIUM NOTIFICATION
+ * COEX_MEDIUM_NOTIFICATION = 0x5b
+ *
+ * notification from uCode to host to indicate medium changes
+ *
+ */
+/*
+ * status field
+ * bit 0 - 2: medium status
+ * bit 3: medium change indication
+ * bit 4 - 31: reserved
+ */
+/* status option values, (0 - 2 bits) */
+#define COEX_MEDIUM_BUSY	(0x0) /* radio belongs to WiMAX */
+#define COEX_MEDIUM_ACTIVE	(0x1) /* radio belongs to WiFi */
+#define COEX_MEDIUM_PRE_RELEASE	(0x2) /* received radio release */
+#define COEX_MEDIUM_MSK		(0x7)
+
+/* send notification status (1 bit) */
+#define COEX_MEDIUM_CHANGED	(0x8)
+#define COEX_MEDIUM_CHANGED_MSK	(0x8)
+#define COEX_MEDIUM_SHIFT	(3)
+
+struct iwl_coex_medium_notification {
+	__le32 status;
+	__le32 events;
+} __attribute__ ((packed));
+
+/*
+ * Coexistence EVENT  Command
+ * COEX_EVENT_CMD = 0x5c
+ *
+ * send from host to uCode for coex event request.
+ */
+/* flags options */
+#define COEX_EVENT_REQUEST_MSK	(0x1)
+
+struct iwl_coex_event_cmd {
+	u8 flags;
+	u8 event;
+	__le16 reserved;
+} __attribute__ ((packed));
+
+struct iwl_coex_event_resp {
+	__le32 status;
+} __attribute__ ((packed));
+
+
 /******************************************************************************
  * (13)
  * Union of all expected notifications/responses:
@@ -3587,6 +3648,8 @@ struct iwl_rx_packet {
 		struct iwl_notif_statistics stats;
 		struct iwl_compressed_ba_resp compressed_ba;
 		struct iwl_missed_beacon_notif missed_beacon;
+		struct iwl_coex_medium_notification coex_medium_notif;
+		struct iwl_coex_event_resp coex_event;
 		__le32 status;
 		u8 raw[0];
 	} u;
diff --git a/drivers/net/wireless/iwlwifi/iwl-hcmd.c b/drivers/net/wireless/iwlwifi/iwl-hcmd.c
index d7ebc5f..ccf50a9 100644
--- a/drivers/net/wireless/iwlwifi/iwl-hcmd.c
+++ b/drivers/net/wireless/iwlwifi/iwl-hcmd.c
@@ -56,6 +56,8 @@ const char *get_cmd_string(u8 cmd)
 		IWL_CMD(REPLY_LEDS_CMD);
 		IWL_CMD(REPLY_TX_LINK_QUALITY_CMD);
 		IWL_CMD(COEX_PRIORITY_TABLE_CMD);
+		IWL_CMD(COEX_MEDIUM_NOTIFICATION);
+		IWL_CMD(COEX_EVENT_CMD);
 		IWL_CMD(RADAR_NOTIFICATION);
 		IWL_CMD(REPLY_QUIET_CMD);
 		IWL_CMD(REPLY_CHANNEL_SWITCH);
-- 
1.5.6.3


^ permalink raw reply related

* [PATCH 11/15] iwlagn: move rate scale initialization to init function
From: Reinette Chatre @ 2009-10-30 21:36 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, ipw3945-devel, Reinette Chatre
In-Reply-To: <1256938578-9638-1-git-send-email-reinette.chatre@intel.com>

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

This fits better in how the callbacks operate (alloc does allocation and
init does initialization). This also helps if we later want to do our own
initialization without relying on the mac80211 allocation.

Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
---
 drivers/net/wireless/iwlwifi/iwl-agn-rs.c |   13 ++++++-------
 1 files changed, 6 insertions(+), 7 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
index 27d4ece..43edd8f 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
@@ -2477,19 +2477,12 @@ static void *rs_alloc_sta(void *priv_rate, struct ieee80211_sta *sta,
 	struct iwl_lq_sta *lq_sta;
 	struct iwl_station_priv *sta_priv = (struct iwl_station_priv *) sta->drv_priv;
 	struct iwl_priv *priv;
-	int i, j;
 
 	priv = (struct iwl_priv *)priv_rate;
 	IWL_DEBUG_RATE(priv, "create station rate scale window\n");
 
 	lq_sta = &sta_priv->lq_sta;
 
-	lq_sta->lq.sta_id = 0xff;
-
-	for (j = 0; j < LQ_SIZE; j++)
-		for (i = 0; i < IWL_RATE_COUNT; i++)
-			rs_rate_scale_clear_window(&lq_sta->lq_info[j].win[i]);
-
 	return lq_sta;
 }
 
@@ -2502,6 +2495,12 @@ static void rs_rate_init(void *priv_r, struct ieee80211_supported_band *sband,
 	struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap;
 	struct iwl_lq_sta *lq_sta = priv_sta;
 
+	lq_sta->lq.sta_id = 0xff;
+
+	for (j = 0; j < LQ_SIZE; j++)
+		for (i = 0; i < IWL_RATE_COUNT; i++)
+			rs_rate_scale_clear_window(&lq_sta->lq_info[j].win[i]);
+
 	lq_sta->flush_timer = 0;
 	lq_sta->supp_rates = sta->supp_rates[sband->band];
 	for (j = 0; j < LQ_SIZE; j++)
-- 
1.5.6.3


^ permalink raw reply related

* [PATCH 10/15] iwl3945: store station rate scale information in mac80211 station structure
From: Reinette Chatre @ 2009-10-30 21:36 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, ipw3945-devel, Reinette Chatre
In-Reply-To: <1256938578-9638-1-git-send-email-reinette.chatre@intel.com>

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

Currently the rate scale information is pointed to from the mac80211
station structure but since that is the only member we might as well make
it part of the structure. Also move the rate scaling initialization to the
init function, no need to do it when we allocate the structure. This fits
with how mac80211 deals with rate scaling information (it always calls init
after allocation) and makes it easier for us to later call initialization
directly.

Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
---
 drivers/net/wireless/iwlwifi/iwl-3945-rs.c |   99 +++++++--------------------
 drivers/net/wireless/iwlwifi/iwl-3945.h    |   35 ++++++++++-
 2 files changed, 60 insertions(+), 74 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-rs.c b/drivers/net/wireless/iwlwifi/iwl-3945-rs.c
index cbb0585..819a81b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945-rs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945-rs.c
@@ -42,38 +42,6 @@
 
 #define RS_NAME "iwl-3945-rs"
 
-struct iwl3945_rate_scale_data {
-	u64 data;
-	s32 success_counter;
-	s32 success_ratio;
-	s32 counter;
-	s32 average_tpt;
-	unsigned long stamp;
-};
-
-struct iwl3945_rs_sta {
-	spinlock_t lock;
-	struct iwl_priv *priv;
-	s32 *expected_tpt;
-	unsigned long last_partial_flush;
-	unsigned long last_flush;
-	u32 flush_time;
-	u32 last_tx_packets;
-	u32 tx_packets;
-	u8 tgg;
-	u8 flush_pending;
-	u8 start_rate;
-	u8 ibss_sta_added;
-	struct timer_list rate_scale_flush;
-	struct iwl3945_rate_scale_data win[IWL_RATE_COUNT_3945];
-#ifdef CONFIG_MAC80211_DEBUGFS
-	struct dentry *rs_sta_dbgfs_stats_table_file;
-#endif
-
-	/* used to be in sta_info */
-	int last_txrate_idx;
-};
-
 static s32 iwl3945_expected_tpt_g[IWL_RATE_COUNT_3945] = {
 	7, 13, 35, 58, 0, 0, 76, 104, 130, 168, 191, 202
 };
@@ -370,6 +338,28 @@ static void rs_rate_init(void *priv_r, struct ieee80211_supported_band *sband,
 
 	IWL_DEBUG_RATE(priv, "enter\n");
 
+	spin_lock_init(&rs_sta->lock);
+
+	rs_sta->priv = priv;
+
+	rs_sta->start_rate = IWL_RATE_INVALID;
+
+	/* default to just 802.11b */
+	rs_sta->expected_tpt = iwl3945_expected_tpt_b;
+
+	rs_sta->last_partial_flush = jiffies;
+	rs_sta->last_flush = jiffies;
+	rs_sta->flush_time = IWL_RATE_FLUSH;
+	rs_sta->last_tx_packets = 0;
+	rs_sta->ibss_sta_added = 0;
+
+	init_timer(&rs_sta->rate_scale_flush);
+	rs_sta->rate_scale_flush.data = (unsigned long)rs_sta;
+	rs_sta->rate_scale_flush.function = &iwl3945_bg_rate_scale_flush;
+
+	for (i = 0; i < IWL_RATE_COUNT_3945; i++)
+		iwl3945_clear_window(&rs_sta->win[i]);
+
 	/* TODO: what is a good starting rate for STA? About middle? Maybe not
 	 * the lowest or the highest rate.. Could consider using RSSI from
 	 * previous packets? Need to have IEEE 802.1X auth succeed immediately
@@ -409,45 +399,11 @@ static void *rs_alloc_sta(void *iwl_priv, struct ieee80211_sta *sta, gfp_t gfp)
 {
 	struct iwl3945_rs_sta *rs_sta;
 	struct iwl3945_sta_priv *psta = (void *) sta->drv_priv;
-	struct iwl_priv *priv = iwl_priv;
-	int i;
-
-	/*
-	 * XXX: If it's using sta->drv_priv anyway, it might
-	 *	as well just put all the information there.
-	 */
+	struct iwl_priv *priv __maybe_unused = iwl_priv;
 
 	IWL_DEBUG_RATE(priv, "enter\n");
 
-	rs_sta = kzalloc(sizeof(struct iwl3945_rs_sta), gfp);
-	if (!rs_sta) {
-		IWL_DEBUG_RATE(priv, "leave: ENOMEM\n");
-		return NULL;
-	}
-
-	psta->rs_sta = rs_sta;
-
-	spin_lock_init(&rs_sta->lock);
-
-	rs_sta->priv = priv;
-
-	rs_sta->start_rate = IWL_RATE_INVALID;
-
-	/* default to just 802.11b */
-	rs_sta->expected_tpt = iwl3945_expected_tpt_b;
-
-	rs_sta->last_partial_flush = jiffies;
-	rs_sta->last_flush = jiffies;
-	rs_sta->flush_time = IWL_RATE_FLUSH;
-	rs_sta->last_tx_packets = 0;
-	rs_sta->ibss_sta_added = 0;
-
-	init_timer(&rs_sta->rate_scale_flush);
-	rs_sta->rate_scale_flush.data = (unsigned long)rs_sta;
-	rs_sta->rate_scale_flush.function = &iwl3945_bg_rate_scale_flush;
-
-	for (i = 0; i < IWL_RATE_COUNT_3945; i++)
-		iwl3945_clear_window(&rs_sta->win[i]);
+	rs_sta = &psta->rs_sta;
 
 	IWL_DEBUG_RATE(priv, "leave\n");
 
@@ -458,14 +414,11 @@ static void rs_free_sta(void *iwl_priv, struct ieee80211_sta *sta,
 			void *priv_sta)
 {
 	struct iwl3945_sta_priv *psta = (void *) sta->drv_priv;
-	struct iwl3945_rs_sta *rs_sta = priv_sta;
+	struct iwl3945_rs_sta *rs_sta = &psta->rs_sta;
 	struct iwl_priv *priv __maybe_unused = rs_sta->priv;
 
-	psta->rs_sta = NULL;
-
 	IWL_DEBUG_RATE(priv, "enter\n");
 	del_timer_sync(&rs_sta->rate_scale_flush);
-	kfree(rs_sta);
 	IWL_DEBUG_RATE(priv, "leave\n");
 }
 
@@ -967,7 +920,7 @@ void iwl3945_rate_scale_init(struct ieee80211_hw *hw, s32 sta_id)
 	}
 
 	psta = (void *) sta->drv_priv;
-	rs_sta = psta->rs_sta;
+	rs_sta = &psta->rs_sta;
 
 	spin_lock_irqsave(&rs_sta->lock, flags);
 
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.h b/drivers/net/wireless/iwlwifi/iwl-3945.h
index ebb999a..2b0d65c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.h
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.h
@@ -74,8 +74,41 @@ extern struct pci_device_id iwl3945_hw_card_ids[];
 /* Module parameters accessible from iwl-*.c */
 extern struct iwl_mod_params iwl3945_mod_params;
 
+struct iwl3945_rate_scale_data {
+	u64 data;
+	s32 success_counter;
+	s32 success_ratio;
+	s32 counter;
+	s32 average_tpt;
+	unsigned long stamp;
+};
+
+struct iwl3945_rs_sta {
+	spinlock_t lock;
+	struct iwl_priv *priv;
+	s32 *expected_tpt;
+	unsigned long last_partial_flush;
+	unsigned long last_flush;
+	u32 flush_time;
+	u32 last_tx_packets;
+	u32 tx_packets;
+	u8 tgg;
+	u8 flush_pending;
+	u8 start_rate;
+	u8 ibss_sta_added;
+	struct timer_list rate_scale_flush;
+	struct iwl3945_rate_scale_data win[IWL_RATE_COUNT_3945];
+#ifdef CONFIG_MAC80211_DEBUGFS
+	struct dentry *rs_sta_dbgfs_stats_table_file;
+#endif
+
+	/* used to be in sta_info */
+	int last_txrate_idx;
+};
+
+
 struct iwl3945_sta_priv {
-	struct iwl3945_rs_sta *rs_sta;
+	struct iwl3945_rs_sta rs_sta;
 };
 
 enum iwl3945_antenna {
-- 
1.5.6.3


^ permalink raw reply related

* [PATCH 08/15] iwlwifi: move iwl_[un]init_drv to iwlagn
From: Reinette Chatre @ 2009-10-30 21:36 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, ipw3945-devel, Reinette Chatre
In-Reply-To: <1256938578-9638-1-git-send-email-reinette.chatre@intel.com>

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

Since iwlagn is the only user of these functions, move it to this module.
This results in a bit more code moving than just these functions since the
functions only used by them are also moved and we need to export the
symbols previously available to them directly.

Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
---
 drivers/net/wireless/iwlwifi/iwl-agn.c   |   90 +++++++++++++++++++++++++++++
 drivers/net/wireless/iwlwifi/iwl-calib.c |    1 +
 drivers/net/wireless/iwlwifi/iwl-core.c  |   93 ------------------------------
 drivers/net/wireless/iwlwifi/iwl-core.h  |    2 -
 drivers/net/wireless/iwlwifi/iwl-scan.c  |    1 +
 5 files changed, 92 insertions(+), 95 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index 3eeffcb..76355cd 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -2973,6 +2973,96 @@ static void iwl_cancel_deferred_work(struct iwl_priv *priv)
 	del_timer_sync(&priv->statistics_periodic);
 }
 
+static void iwl_init_hw_rates(struct iwl_priv *priv,
+			      struct ieee80211_rate *rates)
+{
+	int i;
+
+	for (i = 0; i < IWL_RATE_COUNT_LEGACY; i++) {
+		rates[i].bitrate = iwl_rates[i].ieee * 5;
+		rates[i].hw_value = i; /* Rate scaling will work on indexes */
+		rates[i].hw_value_short = i;
+		rates[i].flags = 0;
+		if ((i >= IWL_FIRST_CCK_RATE) && (i <= IWL_LAST_CCK_RATE)) {
+			/*
+			 * If CCK != 1M then set short preamble rate flag.
+			 */
+			rates[i].flags |=
+				(iwl_rates[i].plcp == IWL_RATE_1M_PLCP) ?
+					0 : IEEE80211_RATE_SHORT_PREAMBLE;
+		}
+	}
+}
+
+static int iwl_init_drv(struct iwl_priv *priv)
+{
+	int ret;
+
+	priv->ibss_beacon = NULL;
+
+	spin_lock_init(&priv->lock);
+	spin_lock_init(&priv->sta_lock);
+	spin_lock_init(&priv->hcmd_lock);
+
+	INIT_LIST_HEAD(&priv->free_frames);
+
+	mutex_init(&priv->mutex);
+
+	/* Clear the driver's (not device's) station table */
+	iwl_clear_stations_table(priv);
+
+	priv->ieee_channels = NULL;
+	priv->ieee_rates = NULL;
+	priv->band = IEEE80211_BAND_2GHZ;
+
+	priv->iw_mode = NL80211_IFTYPE_STATION;
+
+	/* Choose which receivers/antennas to use */
+	if (priv->cfg->ops->hcmd->set_rxon_chain)
+		priv->cfg->ops->hcmd->set_rxon_chain(priv);
+
+	iwl_init_scan_params(priv);
+
+	iwl_reset_qos(priv);
+
+	priv->qos_data.qos_active = 0;
+	priv->qos_data.qos_cap.val = 0;
+
+	priv->rates_mask = IWL_RATES_MASK;
+	/* Set the tx_power_user_lmt to the lowest power level
+	 * this value will get overwritten by channel max power avg
+	 * from eeprom */
+	priv->tx_power_user_lmt = IWL_TX_POWER_TARGET_POWER_MIN;
+
+	ret = iwl_init_channel_map(priv);
+	if (ret) {
+		IWL_ERR(priv, "initializing regulatory failed: %d\n", ret);
+		goto err;
+	}
+
+	ret = iwlcore_init_geos(priv);
+	if (ret) {
+		IWL_ERR(priv, "initializing geos failed: %d\n", ret);
+		goto err_free_channel_map;
+	}
+	iwl_init_hw_rates(priv, priv->ieee_rates);
+
+	return 0;
+
+err_free_channel_map:
+	iwl_free_channel_map(priv);
+err:
+	return ret;
+}
+
+static void iwl_uninit_drv(struct iwl_priv *priv)
+{
+	iwl_calib_free_results(priv);
+	iwlcore_free_geos(priv);
+	iwl_free_channel_map(priv);
+	kfree(priv->scan);
+}
+
 static struct attribute *iwl_sysfs_entries[] = {
 	&dev_attr_flags.attr,
 	&dev_attr_filter_flags.attr,
diff --git a/drivers/net/wireless/iwlwifi/iwl-calib.c b/drivers/net/wireless/iwlwifi/iwl-calib.c
index 1f801eb..d994de7 100644
--- a/drivers/net/wireless/iwlwifi/iwl-calib.c
+++ b/drivers/net/wireless/iwlwifi/iwl-calib.c
@@ -132,6 +132,7 @@ void iwl_calib_free_results(struct iwl_priv *priv)
 		priv->calib_results[i].buf_len = 0;
 	}
 }
+EXPORT_SYMBOL(iwl_calib_free_results);
 
 /*****************************************************************************
  * RUNTIME calibrations framework
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index 2952890..96eb476 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -452,28 +452,6 @@ static void iwlcore_init_ht_hw_capab(const struct iwl_priv *priv,
 	}
 }
 
-static void iwlcore_init_hw_rates(struct iwl_priv *priv,
-			      struct ieee80211_rate *rates)
-{
-	int i;
-
-	for (i = 0; i < IWL_RATE_COUNT_LEGACY; i++) {
-		rates[i].bitrate = iwl_rates[i].ieee * 5;
-		rates[i].hw_value = i; /* Rate scaling will work on indexes */
-		rates[i].hw_value_short = i;
-		rates[i].flags = 0;
-		if ((i >= IWL_FIRST_CCK_RATE) && (i <= IWL_LAST_CCK_RATE)) {
-			/*
-			 * If CCK != 1M then set short preamble rate flag.
-			 */
-			rates[i].flags |=
-				(iwl_rates[i].plcp == IWL_RATE_1M_PLCP) ?
-					0 : IEEE80211_RATE_SHORT_PREAMBLE;
-		}
-	}
-}
-
-
 /**
  * iwlcore_init_geos - Initialize mac80211's geo/channel info based from eeprom
  */
@@ -1572,68 +1550,6 @@ int iwl_set_hw_params(struct iwl_priv *priv)
 }
 EXPORT_SYMBOL(iwl_set_hw_params);
 
-int iwl_init_drv(struct iwl_priv *priv)
-{
-	int ret;
-
-	priv->ibss_beacon = NULL;
-
-	spin_lock_init(&priv->lock);
-	spin_lock_init(&priv->sta_lock);
-	spin_lock_init(&priv->hcmd_lock);
-
-	INIT_LIST_HEAD(&priv->free_frames);
-
-	mutex_init(&priv->mutex);
-
-	/* Clear the driver's (not device's) station table */
-	iwl_clear_stations_table(priv);
-
-	priv->ieee_channels = NULL;
-	priv->ieee_rates = NULL;
-	priv->band = IEEE80211_BAND_2GHZ;
-
-	priv->iw_mode = NL80211_IFTYPE_STATION;
-
-	/* Choose which receivers/antennas to use */
-	if (priv->cfg->ops->hcmd->set_rxon_chain)
-		priv->cfg->ops->hcmd->set_rxon_chain(priv);
-
-	iwl_init_scan_params(priv);
-
-	iwl_reset_qos(priv);
-
-	priv->qos_data.qos_active = 0;
-	priv->qos_data.qos_cap.val = 0;
-
-	priv->rates_mask = IWL_RATES_MASK;
-	/* Set the tx_power_user_lmt to the lowest power level
-	 * this value will get overwritten by channel max power avg
-	 * from eeprom */
-	priv->tx_power_user_lmt = IWL_TX_POWER_TARGET_POWER_MIN;
-
-	ret = iwl_init_channel_map(priv);
-	if (ret) {
-		IWL_ERR(priv, "initializing regulatory failed: %d\n", ret);
-		goto err;
-	}
-
-	ret = iwlcore_init_geos(priv);
-	if (ret) {
-		IWL_ERR(priv, "initializing geos failed: %d\n", ret);
-		goto err_free_channel_map;
-	}
-	iwlcore_init_hw_rates(priv, priv->ieee_rates);
-
-	return 0;
-
-err_free_channel_map:
-	iwl_free_channel_map(priv);
-err:
-	return ret;
-}
-EXPORT_SYMBOL(iwl_init_drv);
-
 int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force)
 {
 	int ret = 0;
@@ -1681,15 +1597,6 @@ int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force)
 }
 EXPORT_SYMBOL(iwl_set_tx_power);
 
-void iwl_uninit_drv(struct iwl_priv *priv)
-{
-	iwl_calib_free_results(priv);
-	iwlcore_free_geos(priv);
-	iwl_free_channel_map(priv);
-	kfree(priv->scan);
-}
-EXPORT_SYMBOL(iwl_uninit_drv);
-
 #define ICT_COUNT (PAGE_SIZE/sizeof(u32))
 
 /* Free dram table */
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index b875dcf..ddf0998 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -316,8 +316,6 @@ void iwl_configure_filter(struct ieee80211_hw *hw,
 			  unsigned int *total_flags, u64 multicast);
 int iwl_hw_nic_init(struct iwl_priv *priv);
 int iwl_set_hw_params(struct iwl_priv *priv);
-int iwl_init_drv(struct iwl_priv *priv);
-void iwl_uninit_drv(struct iwl_priv *priv);
 bool iwl_is_monitor_mode(struct iwl_priv *priv);
 void iwl_post_associate(struct iwl_priv *priv);
 void iwl_bss_info_changed(struct ieee80211_hw *hw,
diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c
index 4fca65a..1eb0d0b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-scan.c
+++ b/drivers/net/wireless/iwlwifi/iwl-scan.c
@@ -401,6 +401,7 @@ void iwl_init_scan_params(struct iwl_priv *priv)
 	if (!priv->scan_tx_ant[IEEE80211_BAND_2GHZ])
 		priv->scan_tx_ant[IEEE80211_BAND_2GHZ] = ant_idx;
 }
+EXPORT_SYMBOL(iwl_init_scan_params);
 
 static int iwl_scan_initiate(struct iwl_priv *priv)
 {
-- 
1.5.6.3


^ permalink raw reply related

* [PATCH 07/15] iwlwifi: unmap memory before use
From: Reinette Chatre @ 2009-10-30 21:36 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, ipw3945-devel, Reinette Chatre
In-Reply-To: <1256938578-9638-1-git-send-email-reinette.chatre@intel.com>

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

Handling responses to driver originated commands include passing the
original command buffer to the caller. At this time it is possible for a
callback to be invoked that is passed this command buffer and thus likely
to access it.

We need to make sure that the memory associated with that buffer is not DMA
mapped at the time.

Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
---
 drivers/net/wireless/iwlwifi/iwl-tx.c |   10 +++++-----
 1 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c
index 2afa003..1868093 100644
--- a/drivers/net/wireless/iwlwifi/iwl-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-tx.c
@@ -1122,11 +1122,6 @@ static void iwl_hcmd_queue_reclaim(struct iwl_priv *priv, int txq_id,
 		return;
 	}
 
-	pci_unmap_single(priv->pci_dev,
-		pci_unmap_addr(&txq->meta[cmd_idx], mapping),
-		pci_unmap_len(&txq->meta[cmd_idx], len),
-		PCI_DMA_BIDIRECTIONAL);
-
 	for (idx = iwl_queue_inc_wrap(idx, q->n_bd); q->read_ptr != idx;
 	     q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd)) {
 
@@ -1174,6 +1169,11 @@ void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
 	cmd = priv->txq[IWL_CMD_QUEUE_NUM].cmd[cmd_index];
 	meta = &priv->txq[IWL_CMD_QUEUE_NUM].meta[cmd_index];
 
+	pci_unmap_single(priv->pci_dev,
+			 pci_unmap_addr(meta, mapping),
+			 pci_unmap_len(meta, len),
+			 PCI_DMA_BIDIRECTIONAL);
+
 	/* Input error checking is done when commands are added to queue. */
 	if (meta->flags & CMD_WANT_SKB) {
 		meta->source->reply_page = (unsigned long)rxb_addr(rxb);
-- 
1.5.6.3


^ permalink raw reply related

* [PATCH 09/15] iwlwifi: split adding broadcast station from others
From: Reinette Chatre @ 2009-10-30 21:36 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, ipw3945-devel, Reinette Chatre
In-Reply-To: <1256938578-9638-1-git-send-email-reinette.chatre@intel.com>

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

In preparation for some station management changes we split the addition of
a broadcast station from the other stations. Later we will rely on mac80211
to direct all management (addition/removal) of all stations except the
broadcast station.

Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
---
 drivers/net/wireless/iwlwifi/iwl-agn.c |    8 +---
 drivers/net/wireless/iwlwifi/iwl-sta.c |   62 ++++++++++++++++++++++++++++++++
 drivers/net/wireless/iwlwifi/iwl-sta.h |    1 +
 3 files changed, 65 insertions(+), 6 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index 76355cd..e99b753 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -191,11 +191,7 @@ int iwl_commit_rxon(struct iwl_priv *priv)
 	priv->start_calib = 0;
 
 	/* Add the broadcast address so we can send broadcast frames */
-	if (iwl_rxon_add_station(priv, iwl_bcast_addr, 0) ==
-						IWL_INVALID_STATION) {
-		IWL_ERR(priv, "Error adding BROADCAST address for transmit.\n");
-		return -EIO;
-	}
+	iwl_add_bcast_station(priv);
 
 	/* If we have set the ASSOC_MSK and we are in BSS mode then
 	 * add the IWL_AP_ID to the station rate table */
@@ -2525,7 +2521,7 @@ void iwl_config_ap(struct iwl_priv *priv)
 		spin_lock_irqsave(&priv->lock, flags);
 		iwl_activate_qos(priv, 1);
 		spin_unlock_irqrestore(&priv->lock, flags);
-		iwl_rxon_add_station(priv, iwl_bcast_addr, 0);
+		iwl_add_bcast_station(priv);
 	}
 	iwl_send_beacon_cmd(priv);
 
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c
index dc74c16..ce1ceac 100644
--- a/drivers/net/wireless/iwlwifi/iwl-sta.c
+++ b/drivers/net/wireless/iwlwifi/iwl-sta.c
@@ -1030,6 +1030,68 @@ int iwl_rxon_add_station(struct iwl_priv *priv, const u8 *addr, bool is_ap)
 EXPORT_SYMBOL(iwl_rxon_add_station);
 
 /**
+ * iwl_sta_init_bcast_lq - Initialize a bcast station's hardware rate table
+ *
+ * NOTE: Run REPLY_ADD_STA command to set up station table entry, before
+ *       calling this function (which runs REPLY_TX_LINK_QUALITY_CMD,
+ *       which requires station table entry to exist).
+ */
+static void iwl_sta_init_bcast_lq(struct iwl_priv *priv)
+{
+	int i, r;
+	struct iwl_link_quality_cmd link_cmd = {
+		.reserved1 = 0,
+	};
+	u32 rate_flags;
+
+	/* Set up the rate scaling to start at selected rate, fall back
+	 * all the way down to 1M in IEEE order, and then spin on 1M */
+	if (priv->band == IEEE80211_BAND_5GHZ)
+		r = IWL_RATE_6M_INDEX;
+	else
+		r = IWL_RATE_1M_INDEX;
+
+	for (i = 0; i < LINK_QUAL_MAX_RETRY_NUM; i++) {
+		rate_flags = 0;
+		if (r >= IWL_FIRST_CCK_RATE && r <= IWL_LAST_CCK_RATE)
+			rate_flags |= RATE_MCS_CCK_MSK;
+
+		rate_flags |= first_antenna(priv->hw_params.valid_tx_ant) <<
+				RATE_MCS_ANT_POS;
+
+		link_cmd.rs_table[i].rate_n_flags =
+			iwl_hw_set_rate_n_flags(iwl_rates[r].plcp, rate_flags);
+		r = iwl_get_prev_ieee_rate(r);
+	}
+
+	link_cmd.general_params.single_stream_ant_msk =
+				first_antenna(priv->hw_params.valid_tx_ant);
+	link_cmd.general_params.dual_stream_ant_msk = 3;
+	link_cmd.agg_params.agg_dis_start_th = LINK_QUAL_AGG_DISABLE_START_DEF;
+	link_cmd.agg_params.agg_time_limit =
+		cpu_to_le16(LINK_QUAL_AGG_TIME_LIMIT_DEF);
+
+	/* Update the rate scaling for control frame Tx to AP */
+	link_cmd.sta_id = priv->hw_params.bcast_sta_id;
+
+	iwl_send_cmd_pdu_async(priv, REPLY_TX_LINK_QUALITY_CMD,
+			       sizeof(link_cmd), &link_cmd, NULL);
+}
+
+
+/**
+ * iwl_add_bcast_station - add broadcast station into station table.
+ */
+void iwl_add_bcast_station(struct iwl_priv *priv)
+{
+	iwl_add_station(priv, iwl_bcast_addr, false, CMD_SYNC, NULL);
+
+	/* Set up default rate scaling table in device's station table */
+	iwl_sta_init_bcast_lq(priv);
+}
+EXPORT_SYMBOL(iwl_add_bcast_station);
+
+/**
  * iwl_get_sta_id - Find station's index within station table
  *
  * If new IBSS station, create new entry in station table
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.h b/drivers/net/wireless/iwlwifi/iwl-sta.h
index 6deebad..1c382de 100644
--- a/drivers/net/wireless/iwlwifi/iwl-sta.h
+++ b/drivers/net/wireless/iwlwifi/iwl-sta.h
@@ -52,6 +52,7 @@ void iwl_update_tkip_key(struct iwl_priv *priv,
 			const u8 *addr, u32 iv32, u16 *phase1key);
 
 int iwl_rxon_add_station(struct iwl_priv *priv, const u8 *addr, bool is_ap);
+void iwl_add_bcast_station(struct iwl_priv *priv);
 int iwl_remove_station(struct iwl_priv *priv, const u8 *addr, bool is_ap);
 void iwl_clear_stations_table(struct iwl_priv *priv);
 int iwl_get_free_ucode_key_index(struct iwl_priv *priv);
-- 
1.5.6.3


^ permalink raw reply related

* [PATCH 05/15] iwlagn: Clarify FH_TX interrupt
From: Reinette Chatre @ 2009-10-30 21:36 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, ipw3945-devel, Ben Cahill, Reinette Chatre
In-Reply-To: <1256938578-9638-1-git-send-email-reinette.chatre@intel.com>

From: Ben Cahill <ben.m.cahill@intel.com>

Add/clarify comments and debug messages for interrupt used only for uCode load

Signed-off-by: Ben Cahill <ben.m.cahill@intel.com>
Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
---
 drivers/net/wireless/iwlwifi/iwl-agn.c |   10 ++++++----
 1 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index a6dce23..f36a7d1 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -1034,11 +1034,12 @@ static void iwl_irq_tasklet_legacy(struct iwl_priv *priv)
 		handled |= (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX);
 	}
 
+	/* This "Tx" DMA channel is used only for loading uCode */
 	if (inta & CSR_INT_BIT_FH_TX) {
-		IWL_DEBUG_ISR(priv, "Tx interrupt\n");
+		IWL_DEBUG_ISR(priv, "uCode load interrupt\n");
 		priv->isr_stats.tx++;
 		handled |= CSR_INT_BIT_FH_TX;
-		/* FH finished to write, send event */
+		/* Wake up uCode load routine, now that load is complete */
 		priv->ucode_write_complete = 1;
 		wake_up_interruptible(&priv->wait_command_queue);
 	}
@@ -1235,12 +1236,13 @@ static void iwl_irq_tasklet(struct iwl_priv *priv)
 		iwl_leds_background(priv);
 	}
 
+	/* This "Tx" DMA channel is used only for loading uCode */
 	if (inta & CSR_INT_BIT_FH_TX) {
 		iwl_write32(priv, CSR_FH_INT_STATUS, CSR49_FH_INT_TX_MASK);
-		IWL_DEBUG_ISR(priv, "Tx interrupt\n");
+		IWL_DEBUG_ISR(priv, "uCode load interrupt\n");
 		priv->isr_stats.tx++;
 		handled |= CSR_INT_BIT_FH_TX;
-		/* FH finished to write, send event */
+		/* Wake up uCode load routine, now that load is complete */
 		priv->ucode_write_complete = 1;
 		wake_up_interruptible(&priv->wait_command_queue);
 	}
-- 
1.5.6.3


^ permalink raw reply related

* [PATCH 04/15] iwlagn: invoke L0S workaround for 6000/1000 series
From: Reinette Chatre @ 2009-10-30 21:36 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, ipw3945-devel, Ben Cahill, Reinette Chatre
In-Reply-To: <1256938578-9638-1-git-send-email-reinette.chatre@intel.com>

From: Ben Cahill <ben.m.cahill@intel.com>

Invoke workaround to avoid instability in L0->L0S->L1 transition on PCIe bus.
Workaround disables L0S state so device moves directly from L0->L1.
Workaround needed on all devices since and including 4965; add to 6000/1000.

Describe bug and workaround better in comments.

Signed-off-by: Ben Cahill <ben.m.cahill@intel.com>
Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
---
 drivers/net/wireless/iwlwifi/iwl-1000.c |    4 ++--
 drivers/net/wireless/iwlwifi/iwl-6000.c |   20 ++++++++++----------
 drivers/net/wireless/iwlwifi/iwl-core.c |    8 ++++++--
 3 files changed, 18 insertions(+), 14 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c
index 3a645e4..1e387b9 100644
--- a/drivers/net/wireless/iwlwifi/iwl-1000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-1000.c
@@ -164,7 +164,7 @@ struct iwl_cfg iwl1000_bgn_cfg = {
 	.valid_tx_ant = ANT_A,
 	.valid_rx_ant = ANT_AB,
 	.pll_cfg_val = CSR50_ANA_PLL_CFG_VAL,
-	.set_l0s = false,
+	.set_l0s = true,
 	.use_bsm = false,
 	.max_ll_items = OTP_MAX_LL_ITEMS_1000,
 	.shadow_ram_support = false,
@@ -190,7 +190,7 @@ struct iwl_cfg iwl1000_bg_cfg = {
 	.valid_tx_ant = ANT_A,
 	.valid_rx_ant = ANT_AB,
 	.pll_cfg_val = CSR50_ANA_PLL_CFG_VAL,
-	.set_l0s = false,
+	.set_l0s = true,
 	.use_bsm = false,
 	.max_ll_items = OTP_MAX_LL_ITEMS_1000,
 	.shadow_ram_support = false,
diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c
index 32466d3..2f841a8 100644
--- a/drivers/net/wireless/iwlwifi/iwl-6000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-6000.c
@@ -299,7 +299,7 @@ struct iwl_cfg iwl6000h_2agn_cfg = {
 	.valid_tx_ant = ANT_AB,
 	.valid_rx_ant = ANT_AB,
 	.pll_cfg_val = 0,
-	.set_l0s = false,
+	.set_l0s = true,
 	.use_bsm = false,
 	.pa_type = IWL_PA_HYBRID,
 	.max_ll_items = OTP_MAX_LL_ITEMS_6x00,
@@ -329,7 +329,7 @@ struct iwl_cfg iwl6000h_2abg_cfg = {
 	.valid_tx_ant = ANT_AB,
 	.valid_rx_ant = ANT_AB,
 	.pll_cfg_val = 0,
-	.set_l0s = false,
+	.set_l0s = true,
 	.use_bsm = false,
 	.pa_type = IWL_PA_HYBRID,
 	.max_ll_items = OTP_MAX_LL_ITEMS_6x00,
@@ -358,7 +358,7 @@ struct iwl_cfg iwl6000h_2bg_cfg = {
 	.valid_tx_ant = ANT_AB,
 	.valid_rx_ant = ANT_AB,
 	.pll_cfg_val = 0,
-	.set_l0s = false,
+	.set_l0s = true,
 	.use_bsm = false,
 	.pa_type = IWL_PA_HYBRID,
 	.max_ll_items = OTP_MAX_LL_ITEMS_6x00,
@@ -390,7 +390,7 @@ struct iwl_cfg iwl6000i_2agn_cfg = {
 	.valid_tx_ant = ANT_BC,
 	.valid_rx_ant = ANT_BC,
 	.pll_cfg_val = 0,
-	.set_l0s = false,
+	.set_l0s = true,
 	.use_bsm = false,
 	.pa_type = IWL_PA_INTERNAL,
 	.max_ll_items = OTP_MAX_LL_ITEMS_6x00,
@@ -420,7 +420,7 @@ struct iwl_cfg iwl6000i_2abg_cfg = {
 	.valid_tx_ant = ANT_BC,
 	.valid_rx_ant = ANT_BC,
 	.pll_cfg_val = 0,
-	.set_l0s = false,
+	.set_l0s = true,
 	.use_bsm = false,
 	.pa_type = IWL_PA_INTERNAL,
 	.max_ll_items = OTP_MAX_LL_ITEMS_6x00,
@@ -449,7 +449,7 @@ struct iwl_cfg iwl6000i_2bg_cfg = {
 	.valid_tx_ant = ANT_BC,
 	.valid_rx_ant = ANT_BC,
 	.pll_cfg_val = 0,
-	.set_l0s = false,
+	.set_l0s = true,
 	.use_bsm = false,
 	.pa_type = IWL_PA_INTERNAL,
 	.max_ll_items = OTP_MAX_LL_ITEMS_6x00,
@@ -478,7 +478,7 @@ struct iwl_cfg iwl6050_2agn_cfg = {
 	.valid_tx_ant = ANT_AB,
 	.valid_rx_ant = ANT_AB,
 	.pll_cfg_val = 0,
-	.set_l0s = false,
+	.set_l0s = true,
 	.use_bsm = false,
 	.pa_type = IWL_PA_SYSTEM,
 	.max_ll_items = OTP_MAX_LL_ITEMS_6x50,
@@ -508,7 +508,7 @@ struct iwl_cfg iwl6050_2abg_cfg = {
 	.valid_tx_ant = ANT_AB,
 	.valid_rx_ant = ANT_AB,
 	.pll_cfg_val = 0,
-	.set_l0s = false,
+	.set_l0s = true,
 	.use_bsm = false,
 	.pa_type = IWL_PA_SYSTEM,
 	.max_ll_items = OTP_MAX_LL_ITEMS_6x50,
@@ -537,7 +537,7 @@ struct iwl_cfg iwl6000_3agn_cfg = {
 	.valid_tx_ant = ANT_ABC,
 	.valid_rx_ant = ANT_ABC,
 	.pll_cfg_val = 0,
-	.set_l0s = false,
+	.set_l0s = true,
 	.use_bsm = false,
 	.pa_type = IWL_PA_SYSTEM,
 	.max_ll_items = OTP_MAX_LL_ITEMS_6x00,
@@ -567,7 +567,7 @@ struct iwl_cfg iwl6050_3agn_cfg = {
 	.valid_tx_ant = ANT_ABC,
 	.valid_rx_ant = ANT_ABC,
 	.pll_cfg_val = 0,
-	.set_l0s = false,
+	.set_l0s = true,
 	.use_bsm = false,
 	.pa_type = IWL_PA_SYSTEM,
 	.max_ll_items = OTP_MAX_LL_ITEMS_6x50,
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index 9e71544..2952890 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -1431,8 +1431,12 @@ int iwl_apm_init(struct iwl_priv *priv)
 				    CSR_HW_IF_CONFIG_REG_BIT_HAP_WAKE_L1A);
 
 	/*
-	 * HW bug W/A - costs negligible power consumption ...
-	 * Check if BIOS (or OS) enabled L1-ASPM on this device
+	 * HW bug W/A for instability in PCIe bus L0->L0S->L1 transition.
+	 * Check if BIOS (or OS) enabled L1-ASPM on this device.
+	 * If so (likely), disable L0S, so device moves directly L0->L1;
+	 *    costs negligible amount of power savings.
+	 * If not (unlikely), enable L0S, so there is at least some
+	 *    power savings, even without L1.
 	 */
 	if (priv->cfg->set_l0s) {
 		lctl = iwl_pcie_link_ctl(priv);
-- 
1.5.6.3


^ permalink raw reply related

* [PATCH 06/15] iwlagn: update write pointers for all tx queues after wakeup
From: Reinette Chatre @ 2009-10-30 21:36 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, ipw3945-devel, Ben Cahill, Reinette Chatre
In-Reply-To: <1256938578-9638-1-git-send-email-reinette.chatre@intel.com>

From: Ben Cahill <ben.m.cahill@intel.com>

Wakeup interrupt has been updating write pointers (indexes, actually) only
for tx queues 0-5.  This is adequate just for 3945, but inadequate for other
devices, all of which have more tx queues.  Now updating all tx/command queues,
so device can be aware of all new tx and host commands enqueued while
device was asleep.

This can potentially improve data traffic bandwidth and/or latency.

Signed-off-by: Ben Cahill <ben.m.cahill@intel.com>
Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
---
 drivers/net/wireless/iwlwifi/iwl-agn.c |   17 ++++++++---------
 1 files changed, 8 insertions(+), 9 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index f36a7d1..3eeffcb 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -891,6 +891,7 @@ static void iwl_irq_tasklet_legacy(struct iwl_priv *priv)
 	u32 inta, handled = 0;
 	u32 inta_fh;
 	unsigned long flags;
+	u32 i;
 #ifdef CONFIG_IWLWIFI_DEBUG
 	u32 inta_mask;
 #endif
@@ -1008,19 +1009,17 @@ static void iwl_irq_tasklet_legacy(struct iwl_priv *priv)
 		handled |= CSR_INT_BIT_SW_ERR;
 	}
 
-	/* uCode wakes up after power-down sleep */
+	/*
+	 * uCode wakes up after power-down sleep.
+	 * Tell device about any new tx or host commands enqueued,
+	 * and about any Rx buffers made available while asleep.
+	 */
 	if (inta & CSR_INT_BIT_WAKEUP) {
 		IWL_DEBUG_ISR(priv, "Wakeup interrupt\n");
 		iwl_rx_queue_update_write_ptr(priv, &priv->rxq);
-		iwl_txq_update_write_ptr(priv, &priv->txq[0]);
-		iwl_txq_update_write_ptr(priv, &priv->txq[1]);
-		iwl_txq_update_write_ptr(priv, &priv->txq[2]);
-		iwl_txq_update_write_ptr(priv, &priv->txq[3]);
-		iwl_txq_update_write_ptr(priv, &priv->txq[4]);
-		iwl_txq_update_write_ptr(priv, &priv->txq[5]);
-
+		for (i = 0; i < priv->hw_params.max_txq_num; i++)
+			iwl_txq_update_write_ptr(priv, &priv->txq[i]);
 		priv->isr_stats.wakeup++;
-
 		handled |= CSR_INT_BIT_WAKEUP;
 	}
 
-- 
1.5.6.3


^ permalink raw reply related

* [PATCH 02/15] iwlwifi: remove unneeded locks from apm_stop() and stop_master()
From: Reinette Chatre @ 2009-10-30 21:36 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, ipw3945-devel, Ben Cahill, Reinette Chatre
In-Reply-To: <1256938578-9638-1-git-send-email-reinette.chatre@intel.com>

From: Ben Cahill <ben.m.cahill@intel.com>

Since priv->reg_lock was added to keep multi-access register manipulation
atomic, priv->lock protection is no longer needed.  Remove this from
iwl_apm_stop_master() and iwl_apm_stop().

Add warning of timeout when polling for busmaster disablement confirmation,
and some comments.

NOTE:  This is needed to enable use of apm_ops.stop() within iwl_eeprom_init();
priv->lock does not get initialized until after this flow.  See patch
"remove power-wasting calls to apm_ops.init()"

Signed-off-by: Ben Cahill <ben.m.cahill@intel.com>
Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
---
 drivers/net/wireless/iwlwifi/iwl-core.c |   26 +++++++++++++-------------
 1 files changed, 13 insertions(+), 13 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index 1949f1a..9e71544 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -1354,39 +1354,39 @@ EXPORT_SYMBOL(iwl_irq_handle_error);
 
 int iwl_apm_stop_master(struct iwl_priv *priv)
 {
-	unsigned long flags;
-
-	spin_lock_irqsave(&priv->lock, flags);
+	int ret = 0;
 
-	/* set stop master bit */
+	/* stop device's busmaster DMA activity */
 	iwl_set_bit(priv, CSR_RESET, CSR_RESET_REG_FLAG_STOP_MASTER);
 
-	iwl_poll_bit(priv, CSR_RESET, CSR_RESET_REG_FLAG_MASTER_DISABLED,
+	ret = iwl_poll_bit(priv, CSR_RESET, CSR_RESET_REG_FLAG_MASTER_DISABLED,
 			CSR_RESET_REG_FLAG_MASTER_DISABLED, 100);
+	if (ret)
+		IWL_WARN(priv, "Master Disable Timed Out, 100 usec\n");
 
-	spin_unlock_irqrestore(&priv->lock, flags);
 	IWL_DEBUG_INFO(priv, "stop master\n");
 
-	return 0;
+	return ret;
 }
 EXPORT_SYMBOL(iwl_apm_stop_master);
 
 void iwl_apm_stop(struct iwl_priv *priv)
 {
-	unsigned long flags;
-
 	IWL_DEBUG_INFO(priv, "Stop card, put in low power state\n");
 
+	/* Stop device's DMA activity */
 	iwl_apm_stop_master(priv);
 
-	spin_lock_irqsave(&priv->lock, flags);
-
+	/* Reset the entire device */
 	iwl_set_bit(priv, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET);
 
 	udelay(10);
-	/* clear "init complete"  move adapter D0A* --> D0U state */
+
+	/*
+	 * Clear "initialization complete" bit to move adapter from
+	 * D0A* (powered-up Active) --> D0U* (Uninitialized) state.
+	 */
 	iwl_clear_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
-	spin_unlock_irqrestore(&priv->lock, flags);
 }
 EXPORT_SYMBOL(iwl_apm_stop);
 
-- 
1.5.6.3


^ permalink raw reply related

* [PATCH 03/15] iwlwifi: remove power-wasting calls to apm_ops.init()
From: Reinette Chatre @ 2009-10-30 21:36 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, ipw3945-devel, Ben Cahill, Reinette Chatre
In-Reply-To: <1256938578-9638-1-git-send-email-reinette.chatre@intel.com>

From: Ben Cahill <ben.m.cahill@intel.com>

To save power, don't run apm_ops.init() until needed at "up" time.

EEPROM (5000 and earlier devices) may be read without running apm_ops.init(),
but OTP reads (6000 and newer devices) require a powered-up chip.
Therefore, remove apm_ops.init() from the general path in XXXX_pci_probe(),
and call it only if device uses OTP.  Once done with OTP read, call
apm_ops.stop() to reset chip and save power until "up" time comes around.

NOTE:  This patch depends on removal of priv->lock from iwl_apm_stop();
lock does not get initialized until later in flow.  See patch
"remove unneeded locks from apm_stop()".

Signed-off-by: Ben Cahill <ben.m.cahill@intel.com>
Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
---
 drivers/net/wireless/iwlwifi/iwl-agn.c      |    6 ------
 drivers/net/wireless/iwlwifi/iwl-eeprom.c   |   11 +++++++++++
 drivers/net/wireless/iwlwifi/iwl3945-base.c |    7 -------
 3 files changed, 11 insertions(+), 13 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index 1f60d64..a6dce23 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -3114,12 +3114,6 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 		goto out_iounmap;
 	}
 
-	/* amp init */
-	err = priv->cfg->ops->lib->apm_ops.init(priv);
-	if (err < 0) {
-		IWL_ERR(priv, "Failed to init APMG\n");
-		goto out_iounmap;
-	}
 	/*****************
 	 * 4. Read EEPROM
 	 *****************/
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-eeprom.c
index 9429cb1..8a0709e 100644
--- a/drivers/net/wireless/iwlwifi/iwl-eeprom.c
+++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.c
@@ -533,6 +533,10 @@ int iwl_eeprom_init(struct iwl_priv *priv)
 		goto err;
 	}
 	if (priv->nvm_device_type == NVM_DEVICE_TYPE_OTP) {
+
+		/* OTP reads require powered-up chip */
+		priv->cfg->ops->lib->apm_ops.init(priv);
+
 		ret = iwl_init_otp_access(priv);
 		if (ret) {
 			IWL_ERR(priv, "Failed to initialize OTP access.\n");
@@ -563,6 +567,13 @@ int iwl_eeprom_init(struct iwl_priv *priv)
 			e[cache_addr / 2] = eeprom_data;
 			cache_addr += sizeof(u16);
 		}
+
+		/*
+		 * Now that OTP reads are complete, reset chip to save
+		 *   power until we load uCode during "up".
+		 */
+		priv->cfg->ops->lib->apm_ops.stop(priv);
+
 	} else {
 		/* eeprom is an array of 16bit values */
 		for (addr = 0; addr < sz; addr += sizeof(u16)) {
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index d63a04d..84dce68 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -4001,13 +4001,6 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
 	 */
 	spin_lock_init(&priv->reg_lock);
 
-	/* amp init */
-	err = priv->cfg->ops->lib->apm_ops.init(priv);
-	if (err < 0) {
-		IWL_DEBUG_INFO(priv, "Failed to init the card\n");
-		goto out_iounmap;
-	}
-
 	/***********************
 	 * 4. Read EEPROM
 	 * ********************/
-- 
1.5.6.3


^ permalink raw reply related

* [PATCH 01/15] iwlwifi: provide firmware version
From: Reinette Chatre @ 2009-10-30 21:36 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, ipw3945-devel, Reinette Chatre
In-Reply-To: <1256938578-9638-1-git-send-email-reinette.chatre@intel.com>

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

By setting the firmware version in wiphy it is possible to obtain this
information via ethtool. Some examples,

	    # ethtool -i wlan1
	    driver: iwlagn
	    version: 2.6.32-rc5-wl-56840-g26d8540
	    firmware-version: 228.57.2.23
	    bus-info: 0000:03:00.0
	    # ethtool -i wlan0
	    driver: iwl3945
	    version: 2.6.32-rc5-wl-56840-g26d8540
	    firmware-version: 15.28.2.8
	    bus-info: 0000:02:00.0

Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
---
 drivers/net/wireless/iwlwifi/iwl-agn.c      |    8 ++++++++
 drivers/net/wireless/iwlwifi/iwl3945-base.c |    8 ++++++++
 2 files changed, 16 insertions(+), 0 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index 06717fc..1f60d64 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -1378,6 +1378,14 @@ static int iwl_read_ucode(struct iwl_priv *priv)
 	       IWL_UCODE_API(priv->ucode_ver),
 	       IWL_UCODE_SERIAL(priv->ucode_ver));
 
+	snprintf(priv->hw->wiphy->fw_version,
+		 sizeof(priv->hw->wiphy->fw_version),
+		 "%u.%u.%u.%u",
+		 IWL_UCODE_MAJOR(priv->ucode_ver),
+		 IWL_UCODE_MINOR(priv->ucode_ver),
+		 IWL_UCODE_API(priv->ucode_ver),
+		 IWL_UCODE_SERIAL(priv->ucode_ver));
+
 	if (build)
 		IWL_DEBUG_INFO(priv, "Build %u\n", build);
 
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index c3b0669..d63a04d 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -2161,6 +2161,14 @@ static int iwl3945_read_ucode(struct iwl_priv *priv)
 		IWL_UCODE_API(priv->ucode_ver),
 		IWL_UCODE_SERIAL(priv->ucode_ver));
 
+	snprintf(priv->hw->wiphy->fw_version,
+		 sizeof(priv->hw->wiphy->fw_version),
+		 "%u.%u.%u.%u",
+		 IWL_UCODE_MAJOR(priv->ucode_ver),
+		 IWL_UCODE_MINOR(priv->ucode_ver),
+		 IWL_UCODE_API(priv->ucode_ver),
+		 IWL_UCODE_SERIAL(priv->ucode_ver));
+
 	IWL_DEBUG_INFO(priv, "f/w package hdr ucode version raw = 0x%x\n",
 		       priv->ucode_ver);
 	IWL_DEBUG_INFO(priv, "f/w package hdr runtime inst size = %u\n",
-- 
1.5.6.3


^ permalink raw reply related

* [PATCH 00/15] iwlwifi updates 10/30/2009
From: Reinette Chatre @ 2009-10-30 21:36 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, ipw3945-devel, Reinette Chatre

Ben M Cahill (5):
  iwlwifi: remove unneeded locks from apm_stop() and stop_master()
  iwlwifi: remove power-wasting calls to apm_ops.init()
  iwlagn: invoke L0S workaround for 6000/1000 series
  iwlagn: Clarify FH_TX interrupt
  iwlagn: update write pointers for all tx queues after wakeup

Reinette Chatre (7):
  iwlwifi: provide firmware version
  iwlwifi: unmap memory before use
  iwlwifi: move iwl_[un]init_drv to iwlagn
  iwlwifi: split adding broadcast station from others
  iwl3945: store station rate scale information in mac80211 station structure
  iwlagn: move rate scale initialization to init function
  iwlwifi: print warning when sending host command fails

Wey-Yi Guy (3):
  iwlwifi: coex API data structure
  iwlwifi: add SM PS support for 6x50 series
  iwlwifi: add wimax/wifi coexist support for 6x50 series

 drivers/net/wireless/iwlwifi/iwl-1000.c     |    4 +-
 drivers/net/wireless/iwlwifi/iwl-3945-rs.c  |   99 +++---------
 drivers/net/wireless/iwlwifi/iwl-3945.h     |   35 ++++-
 drivers/net/wireless/iwlwifi/iwl-5000.c     |   12 +--
 drivers/net/wireless/iwlwifi/iwl-6000.c     |   25 ++--
 drivers/net/wireless/iwlwifi/iwl-agn-rs.c   |   13 +-
 drivers/net/wireless/iwlwifi/iwl-agn.c      |  143 ++++++++++++++---
 drivers/net/wireless/iwlwifi/iwl-calib.c    |    1 +
 drivers/net/wireless/iwlwifi/iwl-commands.h |  161 ++++++++++++++++++-
 drivers/net/wireless/iwlwifi/iwl-core.c     |  234 +++++++++++++--------------
 drivers/net/wireless/iwlwifi/iwl-core.h     |    7 +-
 drivers/net/wireless/iwlwifi/iwl-dev.h      |    1 +
 drivers/net/wireless/iwlwifi/iwl-eeprom.c   |   11 ++
 drivers/net/wireless/iwlwifi/iwl-hcmd.c     |    2 +
 drivers/net/wireless/iwlwifi/iwl-scan.c     |    1 +
 drivers/net/wireless/iwlwifi/iwl-sta.c      |   67 ++++++++
 drivers/net/wireless/iwlwifi/iwl-sta.h      |    1 +
 drivers/net/wireless/iwlwifi/iwl-tx.c       |   13 +-
 drivers/net/wireless/iwlwifi/iwl3945-base.c |   15 +-
 19 files changed, 580 insertions(+), 265 deletions(-)


^ permalink raw reply

* Re: [PATCH] mac80211: make CALL_TXH a statement
From: John W. Linville @ 2009-10-30 20:45 UTC (permalink / raw)
  To: Johannes Berg; +Cc: linux-wireless
In-Reply-To: <1256935427.3555.66.camel@johannes.local>

On Fri, Oct 30, 2009 at 09:43:47PM +0100, Johannes Berg wrote:
> On Fri, 2009-10-30 at 15:11 -0400, John W. Linville wrote:
> > On Thu, Oct 29, 2009 at 08:43:48AM +0100, Johannes Berg wrote:
> > > The multi-line code in this macro wasn't wrapped
> > > in do {} while (0) so we cannot use it in an if()
> > > branch safely in the future -- fix that.
> > > 
> > > Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
> > 
> > do {...} while (0) won't work for that either, right?  You need
> > ({...}) instead if you want to return a value.  Is that what you want?
> 
> No, I just want to be able to do
> 
> if (...)
> 	CALL_TXH(...)

Oh, I see -- I misunderstood you.

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

^ permalink raw reply

* Re: ieee80211_tx_status: headroom too small
From: Johannes Berg @ 2009-10-30 20:59 UTC (permalink / raw)
  To: Nikolai ZHUBR; +Cc: linux-wireless
In-Reply-To: <1094614475.20091030230028@mail.ru>

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

On Fri, 2009-10-30 at 23:00 +0300, Nikolai ZHUBR wrote:
> Hello people,
> 
> I'm using compat-wireless-2009-09-14 with 2.6.25.20 and I have
> recently noticed lots of these in syslog:
> 
> ieee80211_tx_status: headroom too small

What driver are you using?

johannes

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 801 bytes --]

^ permalink raw reply

* Re: pull request: wireless-next-2.6 2009-10-28
From: Jarek Poplawski @ 2009-10-30 20:44 UTC (permalink / raw)
  To: John W. Linville
  Cc: Johannes Berg, Bartlomiej Zolnierkiewicz, Pekka Enberg,
	David Miller, linux-wireless, netdev, linux-kernel
In-Reply-To: <20091030150223.GA2586@tuxdriver.com>

On Fri, Oct 30, 2009 at 11:02:24AM -0400, John W. Linville wrote:
> On Fri, Oct 30, 2009 at 11:06:16AM +0000, Jarek Poplawski wrote:
> 
> > There are various ways to disagree, and ignoring by John questions
> > from a merited developer both in this referenced lkml and current
> > threads looks at least strange (if not offensive) as well.
> 
> Did you read the thread for which Bartlomiej provided a link earlier?
> There were ten responses (only three of them from him) in that thread.
> His comments were not ignored, they were rejected.
> 
> Ever since Bartlomiej decided to tear himself away from
> drivers/staging, he has been nothing but negative -- petty, whining,
> indignat, whatever.  Just what has he done to merit any special
> consideration here?  Why should he have any sort of veto over rt2x00?
> 
> And of all things on which to take a stand -- how dare the rt2x00 guys
> use two header files instead of three?  The nerve of those people!!!
> 
> Ridiculous...

Maybe. Different tastes for sure, so simply no good solution.

Anyway, my point was somewhere else: Davem could be a good example;-)
I simply can't imagine a thread with such concerns left completely
uncommented before merging a patch. It's not about convincing anybody.
Usually you know at least if the concern is dismissed, or valid, but
fixable. (Sometimes you can even read between lines, or explicit, what
he really thinks...)

This discussion is mainly around trying to omit a maintainer with
"higher authority". Of course it's a mortal sin! ...Except, when the
maintainer doesn't seem to respond at all.

BTW, it seems Bartlomiej's main argument in the current thread has
changed to the non-working driver, so ridiculous only if you have a
clue.

Jarek P.

^ permalink raw reply

* Re: [PATCH] mac80211: make CALL_TXH a statement
From: Johannes Berg @ 2009-10-30 20:43 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless
In-Reply-To: <20091030191126.GC2586@tuxdriver.com>

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

On Fri, 2009-10-30 at 15:11 -0400, John W. Linville wrote:
> On Thu, Oct 29, 2009 at 08:43:48AM +0100, Johannes Berg wrote:
> > The multi-line code in this macro wasn't wrapped
> > in do {} while (0) so we cannot use it in an if()
> > branch safely in the future -- fix that.
> > 
> > Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
> 
> do {...} while (0) won't work for that either, right?  You need
> ({...}) instead if you want to return a value.  Is that what you want?

No, I just want to be able to do

if (...)
	CALL_TXH(...)

johannes

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 801 bytes --]

^ permalink raw reply

* Re[2]: ieee80211_tx_status: headroom too small
From: Nikolai ZHUBR @ 2009-10-30 20:49 UTC (permalink / raw)
  To: Luis R. Rodriguez; +Cc: linux-wireless
In-Reply-To: <43e72e890910301303r67fea6b1m3e04b267aceec66b@mail.gmail.com>

Friday, October 30, 2009, 11:03:20 PM, Luis R. Rodriguez wrote:

>> ieee80211_tx_status: headroom too small
>> ieee80211_tx_status: headroom too small
>> ieee80211_tx_status: headroom too small
>>
>> The wireless (access point) works fine, though maybe not very
>> fast. However, this warning somehow bothers me. Is it important?
>> Does it mean something critical? Maybe I should just comment
>> it out in the code? I don't like syslog being filled up this
>> way...

> You're lucky it even worked on 2.6.25.

Yeah but... 2.6.25 is the kernel used in the latest official release
of OpenWRT and in OpenSuse 11.0 as well (which is still their latest
reasonable release, as of now, too)

Ok, I'll probably wait for some updates.

Nikolai ZHUBR

>   Luis



^ permalink raw reply

* Re: ar9170usb from compat-wireless-2009-10-28
From: Larry Finger @ 2009-10-30 20:11 UTC (permalink / raw)
  To: Malte Gell; +Cc: linux-wireless
In-Reply-To: <200910302100.08566.malte.gell@gmx.de>

Malte Gell wrote:
> Hello!
> 
> I use a Fritz! WLAN N stick and the ar9170usb driver, but with compat-wireless 
> from 2009-10-28 I get no USB connection LED burning...
> 
> compat-wireless 2009-09-29 was okay, it has enabled both LEDs. So I wonder, is 
> it safe to use older compat-wireless-2009-09-29?

Does it work? What would be unsafe?

> I use Linux kernel 2.6.32-rc5-git3 on openSUSE 11.1

Is there a reason that you need compat-wireless with 2.6.32-rc5-git3?
Most of the changes in compat-wireless are already in 2.6.32-rc3.

As long as you are using a git kernel, you ought to use git to
download the kernel from Linville's wireless-testing git tree. That
way, you will always have what is in the latest wireless-testing. In
addition, your reports of problems will be for the current state and
you can help with the debugging.


^ permalink raw reply

* Re: (SOLVED) ar9170usb from compat-wireless-2009-10-28
From: Malte Gell @ 2009-10-30 20:10 UTC (permalink / raw)
  To: linux-wireless
In-Reply-To: <200910302100.08566.malte.gell@gmx.de>


Malte Gell <malte.gell@gmx.de> wrote

> Hello!
> 
> I use a Fritz! WLAN N stick and the ar9170usb driver, but with
>  compat-wireless from 2009-10-28 I get no USB connection LED burning...

Forget it! It was a wpa_supplicant issue. Some weird setup, rebooting and now 
everything is fine. Wpa_supplicant tried to started twice, bad setup on my 
machine.

^ permalink raw reply

* Re: ieee80211_tx_status: headroom too small
From: Luis R. Rodriguez @ 2009-10-30 20:03 UTC (permalink / raw)
  To: Nikolai ZHUBR; +Cc: linux-wireless
In-Reply-To: <1094614475.20091030230028@mail.ru>

On Fri, Oct 30, 2009 at 1:00 PM, Nikolai ZHUBR <zhubr@mail.ru> wrote:
> Hello people,
>
> I'm using compat-wireless-2009-09-14 with 2.6.25.20 and I have
> recently noticed lots of these in syslog:
>
> ieee80211_tx_status: headroom too small
> ieee80211_tx_status: headroom too small
> ieee80211_tx_status: headroom too small
>
> The wireless (access point) works fine, though maybe not very
> fast. However, this warning somehow bothers me. Is it important?
> Does it mean something critical? Maybe I should just comment
> it out in the code? I don't like syslog being filled up this
> way...

You're lucky it even worked on 2.6.25.

  Luis

^ permalink raw reply

* ar9170usb from compat-wireless-2009-10-28
From: Malte Gell @ 2009-10-30 20:00 UTC (permalink / raw)
  To: linux-wireless

Hello!

I use a Fritz! WLAN N stick and the ar9170usb driver, but with compat-wireless 
from 2009-10-28 I get no USB connection LED burning...

compat-wireless 2009-09-29 was okay, it has enabled both LEDs. So I wonder, is 
it safe to use older compat-wireless-2009-09-29?

I use Linux kernel 2.6.32-rc5-git3 on openSUSE 11.1

Thanx
Malte

^ 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