iwlagn: co-exist with AMT
authorMohamed Abbas <mohamed.abbas@intel.com>
Fri, 22 May 2009 18:01:54 +0000 (11:01 -0700)
committerJohn W. Linville <linville@tuxdriver.com>
Fri, 22 May 2009 18:06:09 +0000 (14:06 -0400)
Enable using iwlwifi driver in AMT system.

Signed-off-by: Mohamed Abbas <mohamed.abbas@intel.com>
Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
drivers/net/wireless/iwlwifi/iwl-agn.c
drivers/net/wireless/iwlwifi/iwl-csr.h
drivers/net/wireless/iwlwifi/iwl-dev.h

index 889574d852b87e3cc08f1d1569543f16f1c95d22..0a5507cbeb3f779fb8c9b04883fd1c30b22f418f 100644 (file)
@@ -1792,6 +1792,49 @@ static void iwl_down(struct iwl_priv *priv)
        iwl_cancel_deferred_work(priv);
 }
 
+#define HW_READY_TIMEOUT (50)
+
+static int iwl_set_hw_ready(struct iwl_priv *priv)
+{
+       int ret = 0;
+
+       iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG,
+               CSR_HW_IF_CONFIG_REG_BIT_NIC_READY);
+
+       /* See if we got it */
+       ret = iwl_poll_bit(priv, CSR_HW_IF_CONFIG_REG,
+                               CSR_HW_IF_CONFIG_REG_BIT_NIC_READY,
+                               CSR_HW_IF_CONFIG_REG_BIT_NIC_READY,
+                               HW_READY_TIMEOUT);
+       if (ret != -ETIMEDOUT)
+               priv->hw_ready = true;
+       else
+               priv->hw_ready = false;
+
+       IWL_DEBUG_INFO(priv, "hardware %s\n",
+                     (priv->hw_ready == 1) ? "ready" : "not ready");
+       return ret;
+}
+
+static int iwl_prepare_card_hw(struct iwl_priv *priv)
+{
+       int ret = 0;
+
+       IWL_DEBUG_INFO(priv, "iwl_prepare_card_hw enter \n");
+
+       iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG,
+                       CSR_HW_IF_CONFIG_REG_PREPARE);
+
+       ret = iwl_poll_bit(priv, CSR_HW_IF_CONFIG_REG,
+                       ~CSR_HW_IF_CONFIG_REG_BIT_NIC_PREPARE_DONE,
+                       CSR_HW_IF_CONFIG_REG_BIT_NIC_PREPARE_DONE, 150000);
+
+       if (ret != -ETIMEDOUT)
+               iwl_set_hw_ready(priv);
+
+       return ret;
+}
+
 #define MAX_HW_RESTARTS 5
 
 static int __iwl_up(struct iwl_priv *priv)
@@ -1809,6 +1852,13 @@ static int __iwl_up(struct iwl_priv *priv)
                return -EIO;
        }
 
+       iwl_prepare_card_hw(priv);
+
+       if (!priv->hw_ready) {
+               IWL_WARN(priv, "Exit HW not ready\n");
+               return -EIO;
+       }
+
        /* If platform's RF_KILL switch is NOT set to KILL */
        if (iwl_read32(priv, CSR_GP_CNTRL) & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW)
                clear_bit(STATUS_RF_KILL_HW, &priv->status);
@@ -2896,6 +2946,12 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
         * PCI Tx retries from interfering with C3 CPU state */
        pci_write_config_byte(pdev, PCI_CFG_RETRY_TIMEOUT, 0x00);
 
+       iwl_prepare_card_hw(priv);
+       if (!priv->hw_ready) {
+               IWL_WARN(priv, "Failed, HW not ready\n");
+               goto out_iounmap;
+       }
+
        /* amp init */
        err = priv->cfg->ops->lib->apm_ops.init(priv);
        if (err < 0) {
index e2fafb82868494f7a611166cb9c2f0444d99d840..f03dae1b2f367eefb6dccddf2d612384566cca42 100644 (file)
 
 #define CSR_HW_IF_CONFIG_REG_BIT_HAP_WAKE_L1A          (0x00080000)
 #define CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM                (0x00200000)
-#define CSR_HW_IF_CONFIG_REG_BIT_PCI_OWN_SEM           (0x00400000)
-#define CSR_HW_IF_CONFIG_REG_BIT_ME_OWN                        (0x02000000)
-#define CSR_HW_IF_CONFIG_REG_BIT_WAKE_ME               (0x08000000)
+#define CSR_HW_IF_CONFIG_REG_BIT_NIC_READY             (0x00400000)
+#define CSR_HW_IF_CONFIG_REG_BIT_NIC_PREPARE_DONE      (0x02000000)
+#define CSR_HW_IF_CONFIG_REG_PREPARE                   (0x08000000)
 
 #define CSR_INT_PERIODIC_DIS                   (0x00)
 #define CSR_INT_PERIODIC_ENA                   (0xFF)
index f9a3fd6a023ad2644d15e11989a80837306a2c16..2dafc26fb6a83a3e75eba661e5bc02f7a9541995 100644 (file)
@@ -1113,7 +1113,7 @@ struct iwl_priv {
        u32 disable_tx_power_cal;
        struct work_struct run_time_calib_work;
        struct timer_list statistics_periodic;
-
+       bool hw_ready;
        /*For 3945*/
 #define IWL_DEFAULT_TX_POWER 0x0F