iwlagn: enable shadow register
authorWey-Yi Guy <wey-yi.w.guy@intel.com>
Wed, 10 Nov 2010 17:56:50 +0000 (09:56 -0800)
committerJohn W. Linville <linville@tuxdriver.com>
Mon, 15 Nov 2010 18:26:59 +0000 (13:26 -0500)
For 6000 series devices and up, enable automatic update MAC's register
for better power usage in PSP mode

Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
drivers/net/wireless/iwlwifi/iwl-6000.c
drivers/net/wireless/iwlwifi/iwl-agn-lib.c
drivers/net/wireless/iwlwifi/iwl-core.h
drivers/net/wireless/iwlwifi/iwl-csr.h
drivers/net/wireless/iwlwifi/iwl-rx.c
drivers/net/wireless/iwlwifi/iwl-tx.c

index 21ac2817722e64e9c4d991e6d1780ead5d796648..c7ff1bdf42cd02b59ce5f0a8655bcb6867161b5c 100644 (file)
@@ -487,6 +487,7 @@ static struct iwl_base_params iwl6000_base_params = {
        .ucode_tracing = true,
        .sensitivity_calib_by_driver = true,
        .chain_noise_calib_by_driver = true,
+       .shadow_reg_enable = true,
 };
 
 static struct iwl_base_params iwl6050_base_params = {
@@ -510,6 +511,7 @@ static struct iwl_base_params iwl6050_base_params = {
        .ucode_tracing = true,
        .sensitivity_calib_by_driver = true,
        .chain_noise_calib_by_driver = true,
+       .shadow_reg_enable = true,
 };
 static struct iwl_base_params iwl6000_coex_base_params = {
        .eeprom_size = OTP_LOW_IMAGE_SIZE,
@@ -532,6 +534,7 @@ static struct iwl_base_params iwl6000_coex_base_params = {
        .ucode_tracing = true,
        .sensitivity_calib_by_driver = true,
        .chain_noise_calib_by_driver = true,
+       .shadow_reg_enable = true,
 };
 
 static struct iwl_ht_params iwl6000_ht_params = {
index 019d4e7d734818138951f43da130f004cd5ede96..ca3530c4295a2c285118047512c2e743b633bf0f 100644 (file)
@@ -753,6 +753,12 @@ int iwlagn_hw_nic_init(struct iwl_priv *priv)
        } else
                iwlagn_txq_ctx_reset(priv);
 
+       if (priv->cfg->base_params->shadow_reg_enable) {
+               /* enable shadow regs in HW */
+               iwl_set_bit(priv, CSR_MAC_SHADOW_REG_CTRL,
+                       0x800FFFFF);
+       }
+
        set_bit(STATUS_INIT, &priv->status);
 
        return 0;
index 6064bc412e07f5a0830ed5d2cf09f1b1042ecac4..ee8cf240d65d9a1ff6a90c6a8bc1e744bebf1454 100644 (file)
@@ -290,6 +290,7 @@ struct iwl_mod_params {
  *     sensitivity calibration operation
  * @chain_noise_calib_by_driver: driver has the capability to perform
  *     chain noise calibration operation
+ * @shadow_reg_enable: HW shadhow register bit
 */
 struct iwl_base_params {
        int eeprom_size;
@@ -320,6 +321,7 @@ struct iwl_base_params {
        const bool ucode_tracing;
        const bool sensitivity_calib_by_driver;
        const bool chain_noise_calib_by_driver;
+       const bool shadow_reg_enable;
 };
 /*
  * @advanced_bt_coexist: support advanced bt coexist
index 2aa15ab13892541fab426e0dac361e2d3b279adb..b80bf7dff55bda64556ddb63de0c816bdddfe546 100644 (file)
 
 #define CSR_LED_REG             (CSR_BASE+0x094)
 #define CSR_DRAM_INT_TBL_REG   (CSR_BASE+0x0A0)
+#define CSR_MAC_SHADOW_REG_CTRL        (CSR_BASE+0x0A8) /* 6000 and up */
+
 
 /* GIO Chicken Bits (PCI Express bus link power management) */
 #define CSR_GIO_CHICKEN_BITS    (CSR_BASE+0x100)
index baca4cc0073b98cd537de40268c51316d72358f8..87a6fd84d4d25827e7c363638fb31b3b5fbef3c8 100644 (file)
@@ -134,28 +134,37 @@ void iwl_rx_queue_update_write_ptr(struct iwl_priv *priv, struct iwl_rx_queue *q
        if (q->need_update == 0)
                goto exit_unlock;
 
-       /* If power-saving is in use, make sure device is awake */
-       if (test_bit(STATUS_POWER_PMI, &priv->status)) {
-               reg = iwl_read32(priv, CSR_UCODE_DRV_GP1);
-
-               if (reg & CSR_UCODE_DRV_GP1_BIT_MAC_SLEEP) {
-                       IWL_DEBUG_INFO(priv, "Rx queue requesting wakeup, GP1 = 0x%x\n",
-                                     reg);
-                       iwl_set_bit(priv, CSR_GP_CNTRL,
-                                   CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
-                       goto exit_unlock;
-               }
-
-               q->write_actual = (q->write & ~0x7);
-               iwl_write_direct32(priv, rx_wrt_ptr_reg, q->write_actual);
-
-       /* Else device is assumed to be awake */
-       } else {
+       if (priv->cfg->base_params->shadow_reg_enable) {
+               /* shadow register enabled */
                /* Device expects a multiple of 8 */
                q->write_actual = (q->write & ~0x7);
                iwl_write32(priv, rx_wrt_ptr_reg, q->write_actual);
-       }
+       } else {
+               /* If power-saving is in use, make sure device is awake */
+               if (test_bit(STATUS_POWER_PMI, &priv->status)) {
+                       reg = iwl_read32(priv, CSR_UCODE_DRV_GP1);
+
+                       if (reg & CSR_UCODE_DRV_GP1_BIT_MAC_SLEEP) {
+                               IWL_DEBUG_INFO(priv,
+                                       "Rx queue requesting wakeup,"
+                                       " GP1 = 0x%x\n", reg);
+                               iwl_set_bit(priv, CSR_GP_CNTRL,
+                                       CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
+                               goto exit_unlock;
+                       }
 
+                       q->write_actual = (q->write & ~0x7);
+                       iwl_write_direct32(priv, rx_wrt_ptr_reg,
+                                       q->write_actual);
+
+               /* Else device is assumed to be awake */
+               } else {
+                       /* Device expects a multiple of 8 */
+                       q->write_actual = (q->write & ~0x7);
+                       iwl_write_direct32(priv, rx_wrt_ptr_reg,
+                               q->write_actual);
+               }
+       }
        q->need_update = 0;
 
  exit_unlock:
index 7261ee49f282f2c1e3a6d027a2aad2954c9b85a3..feaa3670c6bb62621b39c4b812474f1ac9a86c6f 100644 (file)
@@ -49,30 +49,39 @@ void iwl_txq_update_write_ptr(struct iwl_priv *priv, struct iwl_tx_queue *txq)
        if (txq->need_update == 0)
                return;
 
-       /* if we're trying to save power */
-       if (test_bit(STATUS_POWER_PMI, &priv->status)) {
-               /* wake up nic if it's powered down ...
-                * uCode will wake up, and interrupt us again, so next
-                * time we'll skip this part. */
-               reg = iwl_read32(priv, CSR_UCODE_DRV_GP1);
-
-               if (reg & CSR_UCODE_DRV_GP1_BIT_MAC_SLEEP) {
-                       IWL_DEBUG_INFO(priv, "Tx queue %d requesting wakeup, GP1 = 0x%x\n",
-                                     txq_id, reg);
-                       iwl_set_bit(priv, CSR_GP_CNTRL,
-                                   CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
-                       return;
-               }
-
-               iwl_write_direct32(priv, HBUS_TARG_WRPTR,
-                                    txq->q.write_ptr | (txq_id << 8));
-
-       /* else not in power-save mode, uCode will never sleep when we're
-        * trying to tx (during RFKILL, we're not trying to tx). */
-       } else
+       if (priv->cfg->base_params->shadow_reg_enable) {
+               /* shadow register enabled */
                iwl_write32(priv, HBUS_TARG_WRPTR,
                            txq->q.write_ptr | (txq_id << 8));
+       } else {
+               /* if we're trying to save power */
+               if (test_bit(STATUS_POWER_PMI, &priv->status)) {
+                       /* wake up nic if it's powered down ...
+                        * uCode will wake up, and interrupt us again, so next
+                        * time we'll skip this part. */
+                       reg = iwl_read32(priv, CSR_UCODE_DRV_GP1);
+
+                       if (reg & CSR_UCODE_DRV_GP1_BIT_MAC_SLEEP) {
+                               IWL_DEBUG_INFO(priv,
+                                       "Tx queue %d requesting wakeup,"
+                                       " GP1 = 0x%x\n", txq_id, reg);
+                               iwl_set_bit(priv, CSR_GP_CNTRL,
+                                       CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
+                               return;
+                       }
+
+                       iwl_write_direct32(priv, HBUS_TARG_WRPTR,
+                                    txq->q.write_ptr | (txq_id << 8));
 
+               /*
+                * else not in power-save mode,
+                * uCode will never sleep when we're
+                * trying to tx (during RFKILL, we're not trying to tx).
+                */
+               } else
+                       iwl_write32(priv, HBUS_TARG_WRPTR,
+                                   txq->q.write_ptr | (txq_id << 8));
+       }
        txq->need_update = 0;
 }
 EXPORT_SYMBOL(iwl_txq_update_write_ptr);