All of lore.kernel.org
 help / color / mirror / Atom feed
From: Zhu Yi <yi.zhu@intel.com>
To: linville@tuxdriver.com
To: ipwpatch@vger.kernel.org
Cc: linux-wireless@vger.kernel.org, Zhu Yi <yi.zhu@intel.com>,
	Gregory Greenman <gregory.greenman@intel.com>,
	Tomas Winkler <tomas.winkler@intel.com>
Subject: [PATCH 09/17] iwlwifi: EEPROM reading fix
Date: Fri, 27 Jul 2007 17:26:33 +0800	[thread overview]
Message-ID: <11855284183313-git-send-email-yi.zhu@intel.com> (raw)
In-Reply-To: <11855284161716-git-send-email-yi.zhu@intel.com>

This patch fixes EEPROM access. 4965 requires aquiring of EEPROM
semaphore. In addition the timeout on EEPROM read must be longer 10.
This version fixes CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM definition.

Signed-off-by: Gregory Greenman <gregory.greenman@intel.com>
Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
Signed-off-by: Zhu Yi <yi.zhu@intel.com>
---
 drivers/net/wireless/iwl-3945.c |    6 ++++++
 drivers/net/wireless/iwl-3945.h |    1 +
 drivers/net/wireless/iwl-4965.c |   29 +++++++++++++++++++++++++++++
 drivers/net/wireless/iwl-4965.h |    8 ++++++++
 drivers/net/wireless/iwl-base.c |   23 +++++++++++++++--------
 drivers/net/wireless/iwl-hw.h   |    2 +-
 6 files changed, 60 insertions(+), 9 deletions(-)

diff --git a/drivers/net/wireless/iwl-3945.c b/drivers/net/wireless/iwl-3945.c
index af136c8..6c42f53 100644
--- a/drivers/net/wireless/iwl-3945.c
+++ b/drivers/net/wireless/iwl-3945.c
@@ -2295,4 +2295,10 @@ struct pci_device_id iwl_hw_card_ids[] = {
 	{0}
 };
 
+inline int iwl_eeprom_aqcuire_semaphore(struct iwl_priv *priv)
+{
+	_iwl_clear_bit(priv, CSR_EEPROM_GP, CSR_EEPROM_GP_OWNER);
+	return 0;
+}
+
 MODULE_DEVICE_TABLE(pci, iwl_hw_card_ids);
diff --git a/drivers/net/wireless/iwl-3945.h b/drivers/net/wireless/iwl-3945.h
index 4f43702..d134a4b 100644
--- a/drivers/net/wireless/iwl-3945.h
+++ b/drivers/net/wireless/iwl-3945.h
@@ -47,6 +47,7 @@ static inline u8 iwl3945_sync_sta(struct iwl_priv *priv, int sta_id,
 /*
  * Forward declare iwl-3945.c functions for iwl-base.c
  */
+extern int iwl_eeprom_aqcuire_semaphore(struct iwl_priv *priv);
 extern int iwl3945_get_antenna_flags(const struct iwl_priv *priv);
 extern int iwl3945_init_hw_rate_table(struct iwl_priv *priv);
 extern void iwl3945_reg_txpower_periodic(struct iwl_priv *priv);
diff --git a/drivers/net/wireless/iwl-4965.c b/drivers/net/wireless/iwl-4965.c
index 5586b4c..a333204 100644
--- a/drivers/net/wireless/iwl-4965.c
+++ b/drivers/net/wireless/iwl-4965.c
@@ -4763,4 +4763,33 @@ struct pci_device_id iwl_hw_card_ids[] = {
 	{0}
 };
 
+int iwl_eeprom_aqcuire_semaphore(struct iwl_priv *priv)
+{
+	u16 count;
+	int rc;
+
+	for (count = 0; count < EEPROM_SEM_RETRY_LIMIT; count++) {
+		iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG,
+			CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM);
+		rc = iwl_poll_bit(priv, CSR_HW_IF_CONFIG_REG,
+					CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM,
+					CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM,
+					EEPROM_SEM_TIMEOUT);
+		if (rc >= 0) {
+			IWL_DEBUG_IO("Aqcuired semaphore after %d tries.\n",
+				count+1);
+			return rc;
+		}
+	}
+
+	return rc;
+}
+
+inline void iwl_eeprom_release_semaphore(struct iwl_priv *priv)
+{
+	iwl_clear_bit(priv, CSR_HW_IF_CONFIG_REG,
+		CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM);
+}
+
+
 MODULE_DEVICE_TABLE(pci, iwl_hw_card_ids);
diff --git a/drivers/net/wireless/iwl-4965.h b/drivers/net/wireless/iwl-4965.h
index 1f832e7..9e4a663 100644
--- a/drivers/net/wireless/iwl-4965.h
+++ b/drivers/net/wireless/iwl-4965.h
@@ -34,6 +34,8 @@ struct sta_ht_info;
  * In non IWL == 4965 builds, these must build to nothing in order to allow
  * the common code to not have several #if IWL == XXXX / #endif blocks
  */
+static inline void iwl_eeprom_release_semaphore(struct iwl_priv *priv) {}
+
 static inline void iwl4965_add_station(struct iwl_priv *priv, const u8 * addr,
 				       int is_ap) {}
 static inline void iwl4965_set_rxon_ht(struct iwl_priv *priv,
@@ -69,6 +71,9 @@ static inline void iwl4965_rf_kill_ct_config(struct iwl_priv *priv) {}
 /*
  * Forward declare iwl-4965.c functions for iwl-base.c
  */
+extern int iwl_eeprom_aqcuire_semaphore(struct iwl_priv *priv);
+extern void iwl_eeprom_release_semaphore(struct iwl_priv *priv);
+
 extern int iwl4965_tx_queue_update_wr_ptr(struct iwl_priv *priv,
 					  struct iwl_tx_queue *txq,
 					  u16 byte_cnt);
@@ -355,5 +360,8 @@ struct iwl_chain_noise_data {
 #define RATE_MCS_SGI_POS 13
 #define RATE_MCS_SGI_MSK 0x2000
 
+#define	EEPROM_SEM_TIMEOUT 10
+#define EEPROM_SEM_RETRY_LIMIT 1000
+
 #endif				/* IWL == 4965 */
 #endif				/* __iwl_4965_h__ */
diff --git a/drivers/net/wireless/iwl-base.c b/drivers/net/wireless/iwl-base.c
index 1adcdbe..92c21d1 100644
--- a/drivers/net/wireless/iwl-base.c
+++ b/drivers/net/wireless/iwl-base.c
@@ -1549,35 +1549,42 @@ int iwl_eeprom_init(struct iwl_priv *priv)
 		IWL_ERROR("EEPROM not found, EEPROM_GP=0x%08x", gp);
 		return -ENOENT;
 	}
-#if IWL == 3945
-	_iwl_clear_bit(priv, CSR_EEPROM_GP, CSR_EEPROM_GP_OWNER);
-#endif
+
+	rc = iwl_eeprom_aqcuire_semaphore(priv);
+	if (rc < 0) {
+		IWL_ERROR("Failed to aqcuire EEPROM semaphore.\n");
+		return -ENOENT;
+	}
 
 	for (addr = 0, r = 0; addr < sz; addr += 2) {
 		_iwl_write32(priv, CSR_EEPROM_REG, addr << 1);
 		_iwl_clear_bit(priv, CSR_EEPROM_REG, 0x00000002);
 		rc = _iwl_grab_restricted_access(priv);
 		if (rc)
-			return rc;
+			goto done;
 
-		for (to = 0; to < 10; to++) {
+		for (to = 0; to < 50; to++) {
 			r = _iwl_read_restricted(priv, CSR_EEPROM_REG);
 			if (r & 1)
 				break;
-			udelay(5);
+			udelay(10);
 		}
 
 		_iwl_release_restricted_access(priv);
 
 		if (!(r & 1)) {
 			IWL_ERROR("Time out reading EEPROM[%d]", addr);
-			return -ETIMEDOUT;
+			rc = -ETIMEDOUT;
+			goto done;
 		}
 
 		e[addr / 2] = le16_to_cpu(r >> 16);
 	}
+	rc = 0;
 
-	return 0;
+done:
+	iwl_eeprom_release_semaphore(priv);
+	return rc;
 }
 
 /******************************************************************************
diff --git a/drivers/net/wireless/iwl-hw.h b/drivers/net/wireless/iwl-hw.h
index 49ad71b..7512fc7 100644
--- a/drivers/net/wireless/iwl-hw.h
+++ b/drivers/net/wireless/iwl-hw.h
@@ -893,6 +893,7 @@ struct statistics {
 #define CSR_HW_IF_CONFIG_REG_BIT_BOARD_TYPE         (0x00000800)
 #define CSR_HW_IF_CONFIG_REG_BITS_SILICON_TYPE_A    (0x00000000)
 #define CSR_HW_IF_CONFIG_REG_BITS_SILICON_TYPE_B    (0x00001000)
+#define CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM	    (0x00200000)
 
 #define CSR_UCODE_DRV_GP1_BIT_MAC_SLEEP             (0x00000001)
 #define CSR_UCODE_SW_BIT_RFKILL                     (0x00000002)
@@ -907,7 +908,6 @@ struct statistics {
 
 #define PCI_CFG_PMC_PME_FROM_D3COLD_SUPPORT         (0x80000000)
 
-
 /* interrupt flags in INTA, set by uCode or hardware (e.g. dma),
  * acknowledged (reset) by host writing "1" to flagged bits. */
 #define BIT_INT_FH_RX        (1<<31) /* Rx DMA, cmd responses, FH_INT[17:16] */
-- 
1.5.2

  reply	other threads:[~2007-07-27  9:29 UTC|newest]

Thread overview: 21+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <11855284012123-git-send-email-yi.zhu@intel.com>
2007-07-27  9:26 ` [PATCH 01/17] iwlwifi: provide frequency to radiotap monitor not channel index Zhu Yi
2007-07-27  9:26   ` [PATCH 02/17] iwlwifi: Calculate and report noise level while associated Zhu Yi
2007-07-27  9:26     ` [PATCH 03/17] iwlwifi: modify station fix Zhu Yi
2007-07-27  9:26       ` [PATCH 04/17] iwlwifi: cleanup tx queue allocation Zhu Yi
2007-07-27  9:26         ` [PATCH 05/17] iwlwifi: rxon filter_flags endianity fix Zhu Yi
2007-07-27  9:26           ` [PATCH 06/17] iwlwifi: rename base.c to iwl-base.c Zhu Yi
2007-07-27  9:26             ` [PATCH 07/17] iwilwifi: removed unused constant Zhu Yi
2007-07-27  9:26               ` [PATCH 08/17] iwlwifi: QoS control endianity fixes Zhu Yi
2007-07-27  9:26                 ` Zhu Yi [this message]
2007-07-27  9:26                   ` [PATCH 10/17] iwlwifi: endianity cleaning of iwl_print_rx_config_cmd Zhu Yi
2007-07-27  9:26                     ` [PATCH 11/17] iwlwifi: endianity cleanup for QoS host command Zhu Yi
2007-07-27  9:26                       ` [PATCH 12/17] iwlwifi: endianity cleanup for power table " Zhu Yi
2007-07-27  9:26                         ` [PATCH 13/17] iwlwifi: fix 11n on 2.4 channel Zhu Yi
2007-07-27  9:26                           ` [PATCH 14/17] iwlwifi: fix channel switch assert Zhu Yi
2007-07-27  9:26                             ` [PATCH 15/17] iwlwifi: fix scaing watchdog time out Zhu Yi
2007-07-27  9:26                               ` [PATCH 16/17] iwlwifi: Add uCode/driver compatibility version number Zhu Yi
2007-07-27  9:26                                 ` [PATCH 17/17] iwlwifi: update version stamp to 0.1.5 Zhu Yi
2007-07-27 11:22                   ` [PATCH 09/17] iwlwifi: EEPROM reading fix Michael Buesch
2007-07-27 22:24                     ` Tomas Winkler
2007-07-27 22:32                       ` Michael Buesch
2007-07-27  9:30 ` [PATCH 00/17] iwlwifi driver updated to version 0.1.5 Zhu Yi

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=11855284183313-git-send-email-yi.zhu@intel.com \
    --to=yi.zhu@intel.com \
    --cc=gregory.greenman@intel.com \
    --cc=linux-wireless@vger.kernel.org \
    --cc=linville@tuxdriver.com \
    --cc=tomas.winkler@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.