aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-agn-lib.c')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-lib.c124
1 files changed, 112 insertions, 12 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
index e741128842bb..8e79653aed9a 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
@@ -483,8 +483,6 @@ void iwlagn_rx_handler_setup(struct iwl_priv *priv)
483 /* init calibration handlers */ 483 /* init calibration handlers */
484 priv->rx_handlers[CALIBRATION_RES_NOTIFICATION] = 484 priv->rx_handlers[CALIBRATION_RES_NOTIFICATION] =
485 iwlagn_rx_calib_result; 485 iwlagn_rx_calib_result;
486 priv->rx_handlers[CALIBRATION_COMPLETE_NOTIFICATION] =
487 iwlagn_rx_calib_complete;
488 priv->rx_handlers[REPLY_TX] = iwlagn_rx_reply_tx; 486 priv->rx_handlers[REPLY_TX] = iwlagn_rx_reply_tx;
489 487
490 /* set up notification wait support */ 488 /* set up notification wait support */
@@ -667,7 +665,7 @@ int iwlagn_rx_init(struct iwl_priv *priv, struct iwl_rx_queue *rxq)
667 665
668 rb_timeout = RX_RB_TIMEOUT; 666 rb_timeout = RX_RB_TIMEOUT;
669 667
670 if (priv->cfg->mod_params->amsdu_size_8K) 668 if (iwlagn_mod_params.amsdu_size_8K)
671 rb_size = FH_RCSR_RX_CONFIG_REG_VAL_RB_SIZE_8K; 669 rb_size = FH_RCSR_RX_CONFIG_REG_VAL_RB_SIZE_8K;
672 else 670 else
673 rb_size = FH_RCSR_RX_CONFIG_REG_VAL_RB_SIZE_4K; 671 rb_size = FH_RCSR_RX_CONFIG_REG_VAL_RB_SIZE_4K;
@@ -1296,9 +1294,17 @@ int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
1296 * mean we never reach it, but at the same time work around 1294 * mean we never reach it, but at the same time work around
1297 * the aforementioned issue. Thus use IWL_GOOD_CRC_TH_NEVER 1295 * the aforementioned issue. Thus use IWL_GOOD_CRC_TH_NEVER
1298 * here instead of IWL_GOOD_CRC_TH_DISABLED. 1296 * here instead of IWL_GOOD_CRC_TH_DISABLED.
1297 *
1298 * This was fixed in later versions along with some other
1299 * scan changes, and the threshold behaves as a flag in those
1300 * versions.
1299 */ 1301 */
1300 scan->good_CRC_th = is_active ? IWL_GOOD_CRC_TH_DEFAULT : 1302 if (priv->new_scan_threshold_behaviour)
1301 IWL_GOOD_CRC_TH_NEVER; 1303 scan->good_CRC_th = is_active ? IWL_GOOD_CRC_TH_DEFAULT :
1304 IWL_GOOD_CRC_TH_DISABLED;
1305 else
1306 scan->good_CRC_th = is_active ? IWL_GOOD_CRC_TH_DEFAULT :
1307 IWL_GOOD_CRC_TH_NEVER;
1302 1308
1303 band = priv->scan_band; 1309 band = priv->scan_band;
1304 1310
@@ -2256,34 +2262,44 @@ int iwl_dump_fh(struct iwl_priv *priv, char **buf, bool display)
2256/* notification wait support */ 2262/* notification wait support */
2257void iwlagn_init_notification_wait(struct iwl_priv *priv, 2263void iwlagn_init_notification_wait(struct iwl_priv *priv,
2258 struct iwl_notification_wait *wait_entry, 2264 struct iwl_notification_wait *wait_entry,
2265 u8 cmd,
2259 void (*fn)(struct iwl_priv *priv, 2266 void (*fn)(struct iwl_priv *priv,
2260 struct iwl_rx_packet *pkt), 2267 struct iwl_rx_packet *pkt,
2261 u8 cmd) 2268 void *data),
2269 void *fn_data)
2262{ 2270{
2263 wait_entry->fn = fn; 2271 wait_entry->fn = fn;
2272 wait_entry->fn_data = fn_data;
2264 wait_entry->cmd = cmd; 2273 wait_entry->cmd = cmd;
2265 wait_entry->triggered = false; 2274 wait_entry->triggered = false;
2275 wait_entry->aborted = false;
2266 2276
2267 spin_lock_bh(&priv->_agn.notif_wait_lock); 2277 spin_lock_bh(&priv->_agn.notif_wait_lock);
2268 list_add(&wait_entry->list, &priv->_agn.notif_waits); 2278 list_add(&wait_entry->list, &priv->_agn.notif_waits);
2269 spin_unlock_bh(&priv->_agn.notif_wait_lock); 2279 spin_unlock_bh(&priv->_agn.notif_wait_lock);
2270} 2280}
2271 2281
2272signed long iwlagn_wait_notification(struct iwl_priv *priv, 2282int iwlagn_wait_notification(struct iwl_priv *priv,
2273 struct iwl_notification_wait *wait_entry, 2283 struct iwl_notification_wait *wait_entry,
2274 unsigned long timeout) 2284 unsigned long timeout)
2275{ 2285{
2276 int ret; 2286 int ret;
2277 2287
2278 ret = wait_event_timeout(priv->_agn.notif_waitq, 2288 ret = wait_event_timeout(priv->_agn.notif_waitq,
2279 wait_entry->triggered, 2289 wait_entry->triggered || wait_entry->aborted,
2280 timeout); 2290 timeout);
2281 2291
2282 spin_lock_bh(&priv->_agn.notif_wait_lock); 2292 spin_lock_bh(&priv->_agn.notif_wait_lock);
2283 list_del(&wait_entry->list); 2293 list_del(&wait_entry->list);
2284 spin_unlock_bh(&priv->_agn.notif_wait_lock); 2294 spin_unlock_bh(&priv->_agn.notif_wait_lock);
2285 2295
2286 return ret; 2296 if (wait_entry->aborted)
2297 return -EIO;
2298
2299 /* return value is always >= 0 */
2300 if (ret <= 0)
2301 return -ETIMEDOUT;
2302 return 0;
2287} 2303}
2288 2304
2289void iwlagn_remove_notification(struct iwl_priv *priv, 2305void iwlagn_remove_notification(struct iwl_priv *priv,
@@ -2293,3 +2309,87 @@ void iwlagn_remove_notification(struct iwl_priv *priv,
2293 list_del(&wait_entry->list); 2309 list_del(&wait_entry->list);
2294 spin_unlock_bh(&priv->_agn.notif_wait_lock); 2310 spin_unlock_bh(&priv->_agn.notif_wait_lock);
2295} 2311}
2312
2313int iwlagn_start_device(struct iwl_priv *priv)
2314{
2315 int ret;
2316
2317 if (iwl_prepare_card_hw(priv)) {
2318 IWL_WARN(priv, "Exit HW not ready\n");
2319 return -EIO;
2320 }
2321
2322 /* If platform's RF_KILL switch is NOT set to KILL */
2323 if (iwl_read32(priv, CSR_GP_CNTRL) & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW)
2324 clear_bit(STATUS_RF_KILL_HW, &priv->status);
2325 else
2326 set_bit(STATUS_RF_KILL_HW, &priv->status);
2327
2328 if (iwl_is_rfkill(priv)) {
2329 wiphy_rfkill_set_hw_state(priv->hw->wiphy, true);
2330 iwl_enable_interrupts(priv);
2331 return -ERFKILL;
2332 }
2333
2334 iwl_write32(priv, CSR_INT, 0xFFFFFFFF);
2335
2336 ret = iwlagn_hw_nic_init(priv);
2337 if (ret) {
2338 IWL_ERR(priv, "Unable to init nic\n");
2339 return ret;
2340 }
2341
2342 /* make sure rfkill handshake bits are cleared */
2343 iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
2344 iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR,
2345 CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED);
2346
2347 /* clear (again), then enable host interrupts */
2348 iwl_write32(priv, CSR_INT, 0xFFFFFFFF);
2349 iwl_enable_interrupts(priv);
2350
2351 /* really make sure rfkill handshake bits are cleared */
2352 iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
2353 iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
2354
2355 return 0;
2356}
2357
2358void iwlagn_stop_device(struct iwl_priv *priv)
2359{
2360 unsigned long flags;
2361
2362 /* stop and reset the on-board processor */
2363 iwl_write32(priv, CSR_RESET, CSR_RESET_REG_FLAG_NEVO_RESET);
2364
2365 /* tell the device to stop sending interrupts */
2366 spin_lock_irqsave(&priv->lock, flags);
2367 iwl_disable_interrupts(priv);
2368 spin_unlock_irqrestore(&priv->lock, flags);
2369 iwl_synchronize_irq(priv);
2370
2371 /* device going down, Stop using ICT table */
2372 iwl_disable_ict(priv);
2373
2374 /*
2375 * If a HW restart happens during firmware loading,
2376 * then the firmware loading might call this function
2377 * and later it might be called again due to the
2378 * restart. So don't process again if the device is
2379 * already dead.
2380 */
2381 if (test_bit(STATUS_DEVICE_ENABLED, &priv->status)) {
2382 iwlagn_txq_ctx_stop(priv);
2383 iwlagn_rxq_stop(priv);
2384
2385 /* Power-down device's busmaster DMA clocks */
2386 iwl_write_prph(priv, APMG_CLK_DIS_REG, APMG_CLK_VAL_DMA_CLK_RQT);
2387 udelay(5);
2388 }
2389
2390 /* Make sure (redundant) we've released our request to stay awake */
2391 iwl_clear_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
2392
2393 /* Stop the device, and put it in low power state */
2394 iwl_apm_stop(priv);
2395}