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
next prev parent 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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).