diff options
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-3945.c')
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-3945.c | 134 |
1 files changed, 86 insertions, 48 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c index 1071dac99c53..2d6daa88e8c8 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.c +++ b/drivers/net/wireless/iwlwifi/iwl-3945.c | |||
@@ -1077,50 +1077,54 @@ static int iwl3945_txq_ctx_reset(struct iwl_priv *priv) | |||
1077 | return rc; | 1077 | return rc; |
1078 | } | 1078 | } |
1079 | 1079 | ||
1080 | int iwl3945_hw_nic_init(struct iwl_priv *priv) | 1080 | static int iwl3945_apm_init(struct iwl_priv *priv) |
1081 | { | 1081 | { |
1082 | u8 rev_id; | 1082 | int ret = 0; |
1083 | int rc; | ||
1084 | unsigned long flags; | ||
1085 | struct iwl_rx_queue *rxq = &priv->rxq; | ||
1086 | 1083 | ||
1087 | iwl3945_power_init_handle(priv); | 1084 | iwl3945_power_init_handle(priv); |
1088 | 1085 | ||
1089 | spin_lock_irqsave(&priv->lock, flags); | ||
1090 | iwl_set_bit(priv, CSR_ANA_PLL_CFG, CSR39_ANA_PLL_CFG_VAL); | ||
1091 | iwl_set_bit(priv, CSR_GIO_CHICKEN_BITS, | 1086 | iwl_set_bit(priv, CSR_GIO_CHICKEN_BITS, |
1092 | CSR_GIO_CHICKEN_BITS_REG_BIT_L1A_NO_L0S_RX); | 1087 | CSR_GIO_CHICKEN_BITS_REG_BIT_DIS_L0S_EXIT_TIMER); |
1088 | |||
1089 | /* disable L0s without affecting L1 :don't wait for ICH L0s bug W/A) */ | ||
1090 | iwl_set_bit(priv, CSR_GIO_CHICKEN_BITS, | ||
1091 | CSR_GIO_CHICKEN_BITS_REG_BIT_L1A_NO_L0S_RX); | ||
1093 | 1092 | ||
1093 | /* set "initialization complete" bit to move adapter | ||
1094 | * D0U* --> D0A* state */ | ||
1094 | iwl_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE); | 1095 | iwl_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE); |
1095 | rc = iwl_poll_direct_bit(priv, CSR_GP_CNTRL, | 1096 | |
1096 | CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000); | 1097 | iwl_poll_direct_bit(priv, CSR_GP_CNTRL, |
1097 | if (rc < 0) { | 1098 | CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000); |
1098 | spin_unlock_irqrestore(&priv->lock, flags); | 1099 | if (ret < 0) { |
1099 | IWL_DEBUG_INFO("Failed to init the card\n"); | 1100 | IWL_DEBUG_INFO("Failed to init the card\n"); |
1100 | return rc; | 1101 | goto out; |
1101 | } | 1102 | } |
1102 | 1103 | ||
1103 | rc = iwl_grab_nic_access(priv); | 1104 | ret = iwl_grab_nic_access(priv); |
1104 | if (rc) { | 1105 | if (ret) |
1105 | spin_unlock_irqrestore(&priv->lock, flags); | 1106 | goto out; |
1106 | return rc; | 1107 | |
1107 | } | 1108 | /* enable DMA */ |
1108 | iwl_write_prph(priv, APMG_CLK_EN_REG, | 1109 | iwl_write_prph(priv, APMG_CLK_CTRL_REG, APMG_CLK_VAL_DMA_CLK_RQT | |
1109 | APMG_CLK_VAL_DMA_CLK_RQT | | 1110 | APMG_CLK_VAL_BSM_CLK_RQT); |
1110 | APMG_CLK_VAL_BSM_CLK_RQT); | 1111 | |
1111 | udelay(20); | 1112 | udelay(20); |
1113 | |||
1114 | /* disable L1-Active */ | ||
1112 | iwl_set_bits_prph(priv, APMG_PCIDEV_STT_REG, | 1115 | iwl_set_bits_prph(priv, APMG_PCIDEV_STT_REG, |
1113 | APMG_PCIDEV_STT_VAL_L1_ACT_DIS); | 1116 | APMG_PCIDEV_STT_VAL_L1_ACT_DIS); |
1117 | |||
1114 | iwl_release_nic_access(priv); | 1118 | iwl_release_nic_access(priv); |
1115 | spin_unlock_irqrestore(&priv->lock, flags); | 1119 | out: |
1120 | return ret; | ||
1121 | } | ||
1116 | 1122 | ||
1117 | /* Determine HW type */ | 1123 | static void iwl3945_nic_config(struct iwl_priv *priv) |
1118 | rc = pci_read_config_byte(priv->pci_dev, PCI_REVISION_ID, &rev_id); | 1124 | { |
1119 | if (rc) | 1125 | unsigned long flags; |
1120 | return rc; | 1126 | u8 rev_id = 0; |
1121 | IWL_DEBUG_INFO("HW Revision ID = 0x%X\n", rev_id); | ||
1122 | 1127 | ||
1123 | iwl3945_nic_set_pwr_src(priv, 1); | ||
1124 | spin_lock_irqsave(&priv->lock, flags); | 1128 | spin_lock_irqsave(&priv->lock, flags); |
1125 | 1129 | ||
1126 | if (rev_id & PCI_CFG_REV_ID_BIT_RTP) | 1130 | if (rev_id & PCI_CFG_REV_ID_BIT_RTP) |
@@ -1172,6 +1176,27 @@ int iwl3945_hw_nic_init(struct iwl_priv *priv) | |||
1172 | 1176 | ||
1173 | if (priv->eeprom39.sku_cap & EEPROM_SKU_CAP_HW_RF_KILL_ENABLE) | 1177 | if (priv->eeprom39.sku_cap & EEPROM_SKU_CAP_HW_RF_KILL_ENABLE) |
1174 | IWL_DEBUG_RF_KILL("HW RF KILL supported in EEPROM.\n"); | 1178 | IWL_DEBUG_RF_KILL("HW RF KILL supported in EEPROM.\n"); |
1179 | } | ||
1180 | |||
1181 | int iwl3945_hw_nic_init(struct iwl_priv *priv) | ||
1182 | { | ||
1183 | u8 rev_id; | ||
1184 | int rc; | ||
1185 | unsigned long flags; | ||
1186 | struct iwl_rx_queue *rxq = &priv->rxq; | ||
1187 | |||
1188 | spin_lock_irqsave(&priv->lock, flags); | ||
1189 | priv->cfg->ops->lib->apm_ops.init(priv); | ||
1190 | spin_unlock_irqrestore(&priv->lock, flags); | ||
1191 | |||
1192 | /* Determine HW type */ | ||
1193 | rc = pci_read_config_byte(priv->pci_dev, PCI_REVISION_ID, &rev_id); | ||
1194 | if (rc) | ||
1195 | return rc; | ||
1196 | IWL_DEBUG_INFO("HW Revision ID = 0x%X\n", rev_id); | ||
1197 | |||
1198 | iwl3945_nic_set_pwr_src(priv, 1); | ||
1199 | priv->cfg->ops->lib->apm_ops.config(priv); | ||
1175 | 1200 | ||
1176 | /* Allocate the RX queue, or reset if it is already allocated */ | 1201 | /* Allocate the RX queue, or reset if it is already allocated */ |
1177 | if (!rxq->bd) { | 1202 | if (!rxq->bd) { |
@@ -1256,10 +1281,9 @@ void iwl3945_hw_txq_ctx_stop(struct iwl_priv *priv) | |||
1256 | iwl3945_hw_txq_ctx_free(priv); | 1281 | iwl3945_hw_txq_ctx_free(priv); |
1257 | } | 1282 | } |
1258 | 1283 | ||
1259 | int iwl3945_hw_nic_stop_master(struct iwl_priv *priv) | 1284 | static int iwl3945_apm_stop_master(struct iwl_priv *priv) |
1260 | { | 1285 | { |
1261 | int rc = 0; | 1286 | int ret = 0; |
1262 | u32 reg_val; | ||
1263 | unsigned long flags; | 1287 | unsigned long flags; |
1264 | 1288 | ||
1265 | spin_lock_irqsave(&priv->lock, flags); | 1289 | spin_lock_irqsave(&priv->lock, flags); |
@@ -1267,33 +1291,41 @@ int iwl3945_hw_nic_stop_master(struct iwl_priv *priv) | |||
1267 | /* set stop master bit */ | 1291 | /* set stop master bit */ |
1268 | iwl_set_bit(priv, CSR_RESET, CSR_RESET_REG_FLAG_STOP_MASTER); | 1292 | iwl_set_bit(priv, CSR_RESET, CSR_RESET_REG_FLAG_STOP_MASTER); |
1269 | 1293 | ||
1270 | reg_val = iwl_read32(priv, CSR_GP_CNTRL); | 1294 | iwl_poll_direct_bit(priv, CSR_RESET, |
1295 | CSR_RESET_REG_FLAG_MASTER_DISABLED, 100); | ||
1271 | 1296 | ||
1272 | if (CSR_GP_CNTRL_REG_FLAG_MAC_POWER_SAVE == | 1297 | if (ret < 0) |
1273 | (reg_val & CSR_GP_CNTRL_REG_MSK_POWER_SAVE_TYPE)) | 1298 | goto out; |
1274 | IWL_DEBUG_INFO("Card in power save, master is already " | ||
1275 | "stopped\n"); | ||
1276 | else { | ||
1277 | rc = iwl_poll_direct_bit(priv, CSR_RESET, | ||
1278 | CSR_RESET_REG_FLAG_MASTER_DISABLED, 100); | ||
1279 | if (rc < 0) { | ||
1280 | spin_unlock_irqrestore(&priv->lock, flags); | ||
1281 | return rc; | ||
1282 | } | ||
1283 | } | ||
1284 | 1299 | ||
1300 | out: | ||
1285 | spin_unlock_irqrestore(&priv->lock, flags); | 1301 | spin_unlock_irqrestore(&priv->lock, flags); |
1286 | IWL_DEBUG_INFO("stop master\n"); | 1302 | IWL_DEBUG_INFO("stop master\n"); |
1287 | 1303 | ||
1288 | return rc; | 1304 | return ret; |
1305 | } | ||
1306 | |||
1307 | static void iwl3945_apm_stop(struct iwl_priv *priv) | ||
1308 | { | ||
1309 | unsigned long flags; | ||
1310 | |||
1311 | iwl3945_apm_stop_master(priv); | ||
1312 | |||
1313 | spin_lock_irqsave(&priv->lock, flags); | ||
1314 | |||
1315 | iwl_set_bit(priv, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET); | ||
1316 | |||
1317 | udelay(10); | ||
1318 | /* clear "init complete" move adapter D0A* --> D0U state */ | ||
1319 | iwl_clear_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE); | ||
1320 | spin_unlock_irqrestore(&priv->lock, flags); | ||
1289 | } | 1321 | } |
1290 | 1322 | ||
1291 | int iwl3945_hw_nic_reset(struct iwl_priv *priv) | 1323 | int iwl3945_apm_reset(struct iwl_priv *priv) |
1292 | { | 1324 | { |
1293 | int rc; | 1325 | int rc; |
1294 | unsigned long flags; | 1326 | unsigned long flags; |
1295 | 1327 | ||
1296 | iwl3945_hw_nic_stop_master(priv); | 1328 | iwl3945_apm_stop_master(priv); |
1297 | 1329 | ||
1298 | spin_lock_irqsave(&priv->lock, flags); | 1330 | spin_lock_irqsave(&priv->lock, flags); |
1299 | 1331 | ||
@@ -2657,6 +2689,12 @@ static int iwl3945_load_bsm(struct iwl_priv *priv) | |||
2657 | 2689 | ||
2658 | static struct iwl_lib_ops iwl3945_lib = { | 2690 | static struct iwl_lib_ops iwl3945_lib = { |
2659 | .load_ucode = iwl3945_load_bsm, | 2691 | .load_ucode = iwl3945_load_bsm, |
2692 | .apm_ops = { | ||
2693 | .init = iwl3945_apm_init, | ||
2694 | .reset = iwl3945_apm_reset, | ||
2695 | .stop = iwl3945_apm_stop, | ||
2696 | .config = iwl3945_nic_config, | ||
2697 | }, | ||
2660 | }; | 2698 | }; |
2661 | 2699 | ||
2662 | static struct iwl_ops iwl3945_ops = { | 2700 | static struct iwl_ops iwl3945_ops = { |