diff options
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-agn.c')
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-agn.c | 582 |
1 files changed, 314 insertions, 268 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index c1cfd9952e52..581dc9f10273 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c | |||
@@ -59,6 +59,7 @@ | |||
59 | #include "iwl-sta.h" | 59 | #include "iwl-sta.h" |
60 | #include "iwl-agn-calib.h" | 60 | #include "iwl-agn-calib.h" |
61 | #include "iwl-agn.h" | 61 | #include "iwl-agn.h" |
62 | #include "iwl-agn-led.h" | ||
62 | 63 | ||
63 | 64 | ||
64 | /****************************************************************************** | 65 | /****************************************************************************** |
@@ -85,7 +86,6 @@ MODULE_DESCRIPTION(DRV_DESCRIPTION); | |||
85 | MODULE_VERSION(DRV_VERSION); | 86 | MODULE_VERSION(DRV_VERSION); |
86 | MODULE_AUTHOR(DRV_COPYRIGHT " " DRV_AUTHOR); | 87 | MODULE_AUTHOR(DRV_COPYRIGHT " " DRV_AUTHOR); |
87 | MODULE_LICENSE("GPL"); | 88 | MODULE_LICENSE("GPL"); |
88 | MODULE_ALIAS("iwl4965"); | ||
89 | 89 | ||
90 | static int iwlagn_ant_coupling; | 90 | static int iwlagn_ant_coupling; |
91 | static bool iwlagn_bt_ch_announce = 1; | 91 | static bool iwlagn_bt_ch_announce = 1; |
@@ -424,47 +424,6 @@ int iwl_hw_tx_queue_init(struct iwl_priv *priv, | |||
424 | return 0; | 424 | return 0; |
425 | } | 425 | } |
426 | 426 | ||
427 | /****************************************************************************** | ||
428 | * | ||
429 | * Generic RX handler implementations | ||
430 | * | ||
431 | ******************************************************************************/ | ||
432 | static void iwl_rx_reply_alive(struct iwl_priv *priv, | ||
433 | struct iwl_rx_mem_buffer *rxb) | ||
434 | { | ||
435 | struct iwl_rx_packet *pkt = rxb_addr(rxb); | ||
436 | struct iwl_alive_resp *palive; | ||
437 | struct delayed_work *pwork; | ||
438 | |||
439 | palive = &pkt->u.alive_frame; | ||
440 | |||
441 | IWL_DEBUG_INFO(priv, "Alive ucode status 0x%08X revision " | ||
442 | "0x%01X 0x%01X\n", | ||
443 | palive->is_valid, palive->ver_type, | ||
444 | palive->ver_subtype); | ||
445 | |||
446 | if (palive->ver_subtype == INITIALIZE_SUBTYPE) { | ||
447 | IWL_DEBUG_INFO(priv, "Initialization Alive received.\n"); | ||
448 | memcpy(&priv->card_alive_init, | ||
449 | &pkt->u.alive_frame, | ||
450 | sizeof(struct iwl_init_alive_resp)); | ||
451 | pwork = &priv->init_alive_start; | ||
452 | } else { | ||
453 | IWL_DEBUG_INFO(priv, "Runtime Alive received.\n"); | ||
454 | memcpy(&priv->card_alive, &pkt->u.alive_frame, | ||
455 | sizeof(struct iwl_alive_resp)); | ||
456 | pwork = &priv->alive_start; | ||
457 | } | ||
458 | |||
459 | /* We delay the ALIVE response by 5ms to | ||
460 | * give the HW RF Kill time to activate... */ | ||
461 | if (palive->is_valid == UCODE_VALID_OK) | ||
462 | queue_delayed_work(priv->workqueue, pwork, | ||
463 | msecs_to_jiffies(5)); | ||
464 | else | ||
465 | IWL_WARN(priv, "uCode did not respond OK.\n"); | ||
466 | } | ||
467 | |||
468 | static void iwl_bg_beacon_update(struct work_struct *work) | 427 | static void iwl_bg_beacon_update(struct work_struct *work) |
469 | { | 428 | { |
470 | struct iwl_priv *priv = | 429 | struct iwl_priv *priv = |
@@ -699,83 +658,6 @@ static void iwl_bg_ucode_trace(unsigned long data) | |||
699 | } | 658 | } |
700 | } | 659 | } |
701 | 660 | ||
702 | static void iwl_rx_beacon_notif(struct iwl_priv *priv, | ||
703 | struct iwl_rx_mem_buffer *rxb) | ||
704 | { | ||
705 | struct iwl_rx_packet *pkt = rxb_addr(rxb); | ||
706 | struct iwl4965_beacon_notif *beacon = | ||
707 | (struct iwl4965_beacon_notif *)pkt->u.raw; | ||
708 | #ifdef CONFIG_IWLWIFI_DEBUG | ||
709 | u8 rate = iwl_hw_get_rate(beacon->beacon_notify_hdr.rate_n_flags); | ||
710 | |||
711 | IWL_DEBUG_RX(priv, "beacon status %x retries %d iss %d " | ||
712 | "tsf %d %d rate %d\n", | ||
713 | le32_to_cpu(beacon->beacon_notify_hdr.u.status) & TX_STATUS_MSK, | ||
714 | beacon->beacon_notify_hdr.failure_frame, | ||
715 | le32_to_cpu(beacon->ibss_mgr_status), | ||
716 | le32_to_cpu(beacon->high_tsf), | ||
717 | le32_to_cpu(beacon->low_tsf), rate); | ||
718 | #endif | ||
719 | |||
720 | priv->ibss_manager = le32_to_cpu(beacon->ibss_mgr_status); | ||
721 | |||
722 | if (!test_bit(STATUS_EXIT_PENDING, &priv->status)) | ||
723 | queue_work(priv->workqueue, &priv->beacon_update); | ||
724 | } | ||
725 | |||
726 | /* Handle notification from uCode that card's power state is changing | ||
727 | * due to software, hardware, or critical temperature RFKILL */ | ||
728 | static void iwl_rx_card_state_notif(struct iwl_priv *priv, | ||
729 | struct iwl_rx_mem_buffer *rxb) | ||
730 | { | ||
731 | struct iwl_rx_packet *pkt = rxb_addr(rxb); | ||
732 | u32 flags = le32_to_cpu(pkt->u.card_state_notif.flags); | ||
733 | unsigned long status = priv->status; | ||
734 | |||
735 | IWL_DEBUG_RF_KILL(priv, "Card state received: HW:%s SW:%s CT:%s\n", | ||
736 | (flags & HW_CARD_DISABLED) ? "Kill" : "On", | ||
737 | (flags & SW_CARD_DISABLED) ? "Kill" : "On", | ||
738 | (flags & CT_CARD_DISABLED) ? | ||
739 | "Reached" : "Not reached"); | ||
740 | |||
741 | if (flags & (SW_CARD_DISABLED | HW_CARD_DISABLED | | ||
742 | CT_CARD_DISABLED)) { | ||
743 | |||
744 | iwl_write32(priv, CSR_UCODE_DRV_GP1_SET, | ||
745 | CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED); | ||
746 | |||
747 | iwl_write_direct32(priv, HBUS_TARG_MBX_C, | ||
748 | HBUS_TARG_MBX_C_REG_BIT_CMD_BLOCKED); | ||
749 | |||
750 | if (!(flags & RXON_CARD_DISABLED)) { | ||
751 | iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, | ||
752 | CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED); | ||
753 | iwl_write_direct32(priv, HBUS_TARG_MBX_C, | ||
754 | HBUS_TARG_MBX_C_REG_BIT_CMD_BLOCKED); | ||
755 | } | ||
756 | if (flags & CT_CARD_DISABLED) | ||
757 | iwl_tt_enter_ct_kill(priv); | ||
758 | } | ||
759 | if (!(flags & CT_CARD_DISABLED)) | ||
760 | iwl_tt_exit_ct_kill(priv); | ||
761 | |||
762 | if (flags & HW_CARD_DISABLED) | ||
763 | set_bit(STATUS_RF_KILL_HW, &priv->status); | ||
764 | else | ||
765 | clear_bit(STATUS_RF_KILL_HW, &priv->status); | ||
766 | |||
767 | |||
768 | if (!(flags & RXON_CARD_DISABLED)) | ||
769 | iwl_scan_cancel(priv); | ||
770 | |||
771 | if ((test_bit(STATUS_RF_KILL_HW, &status) != | ||
772 | test_bit(STATUS_RF_KILL_HW, &priv->status))) | ||
773 | wiphy_rfkill_set_hw_state(priv->hw->wiphy, | ||
774 | test_bit(STATUS_RF_KILL_HW, &priv->status)); | ||
775 | else | ||
776 | wake_up_interruptible(&priv->wait_command_queue); | ||
777 | } | ||
778 | |||
779 | static void iwl_bg_tx_flush(struct work_struct *work) | 661 | static void iwl_bg_tx_flush(struct work_struct *work) |
780 | { | 662 | { |
781 | struct iwl_priv *priv = | 663 | struct iwl_priv *priv = |
@@ -795,58 +677,13 @@ static void iwl_bg_tx_flush(struct work_struct *work) | |||
795 | } | 677 | } |
796 | 678 | ||
797 | /** | 679 | /** |
798 | * iwl_setup_rx_handlers - Initialize Rx handler callbacks | ||
799 | * | ||
800 | * Setup the RX handlers for each of the reply types sent from the uCode | ||
801 | * to the host. | ||
802 | * | ||
803 | * This function chains into the hardware specific files for them to setup | ||
804 | * any hardware specific handlers as well. | ||
805 | */ | ||
806 | static void iwl_setup_rx_handlers(struct iwl_priv *priv) | ||
807 | { | ||
808 | priv->rx_handlers[REPLY_ALIVE] = iwl_rx_reply_alive; | ||
809 | priv->rx_handlers[REPLY_ERROR] = iwl_rx_reply_error; | ||
810 | priv->rx_handlers[CHANNEL_SWITCH_NOTIFICATION] = iwl_rx_csa; | ||
811 | priv->rx_handlers[SPECTRUM_MEASURE_NOTIFICATION] = | ||
812 | iwl_rx_spectrum_measure_notif; | ||
813 | priv->rx_handlers[PM_SLEEP_NOTIFICATION] = iwl_rx_pm_sleep_notif; | ||
814 | priv->rx_handlers[PM_DEBUG_STATISTIC_NOTIFIC] = | ||
815 | iwl_rx_pm_debug_statistics_notif; | ||
816 | priv->rx_handlers[BEACON_NOTIFICATION] = iwl_rx_beacon_notif; | ||
817 | |||
818 | /* | ||
819 | * The same handler is used for both the REPLY to a discrete | ||
820 | * statistics request from the host as well as for the periodic | ||
821 | * statistics notifications (after received beacons) from the uCode. | ||
822 | */ | ||
823 | priv->rx_handlers[REPLY_STATISTICS_CMD] = iwl_reply_statistics; | ||
824 | priv->rx_handlers[STATISTICS_NOTIFICATION] = iwl_rx_statistics; | ||
825 | |||
826 | iwl_setup_rx_scan_handlers(priv); | ||
827 | |||
828 | /* status change handler */ | ||
829 | priv->rx_handlers[CARD_STATE_NOTIFICATION] = iwl_rx_card_state_notif; | ||
830 | |||
831 | priv->rx_handlers[MISSED_BEACONS_NOTIFICATION] = | ||
832 | iwl_rx_missed_beacon_notif; | ||
833 | /* Rx handlers */ | ||
834 | priv->rx_handlers[REPLY_RX_PHY_CMD] = iwlagn_rx_reply_rx_phy; | ||
835 | priv->rx_handlers[REPLY_RX_MPDU_CMD] = iwlagn_rx_reply_rx; | ||
836 | /* block ack */ | ||
837 | priv->rx_handlers[REPLY_COMPRESSED_BA] = iwlagn_rx_reply_compressed_ba; | ||
838 | /* Set up hardware specific Rx handlers */ | ||
839 | priv->cfg->ops->lib->rx_handler_setup(priv); | ||
840 | } | ||
841 | |||
842 | /** | ||
843 | * iwl_rx_handle - Main entry function for receiving responses from uCode | 680 | * iwl_rx_handle - Main entry function for receiving responses from uCode |
844 | * | 681 | * |
845 | * Uses the priv->rx_handlers callback function array to invoke | 682 | * Uses the priv->rx_handlers callback function array to invoke |
846 | * the appropriate handlers, including command responses, | 683 | * the appropriate handlers, including command responses, |
847 | * frame-received notifications, and other notifications. | 684 | * frame-received notifications, and other notifications. |
848 | */ | 685 | */ |
849 | void iwl_rx_handle(struct iwl_priv *priv) | 686 | static void iwl_rx_handle(struct iwl_priv *priv) |
850 | { | 687 | { |
851 | struct iwl_rx_mem_buffer *rxb; | 688 | struct iwl_rx_mem_buffer *rxb; |
852 | struct iwl_rx_packet *pkt; | 689 | struct iwl_rx_packet *pkt; |
@@ -910,6 +747,27 @@ void iwl_rx_handle(struct iwl_priv *priv) | |||
910 | (pkt->hdr.cmd != STATISTICS_NOTIFICATION) && | 747 | (pkt->hdr.cmd != STATISTICS_NOTIFICATION) && |
911 | (pkt->hdr.cmd != REPLY_TX); | 748 | (pkt->hdr.cmd != REPLY_TX); |
912 | 749 | ||
750 | /* | ||
751 | * Do the notification wait before RX handlers so | ||
752 | * even if the RX handler consumes the RXB we have | ||
753 | * access to it in the notification wait entry. | ||
754 | */ | ||
755 | if (!list_empty(&priv->_agn.notif_waits)) { | ||
756 | struct iwl_notification_wait *w; | ||
757 | |||
758 | spin_lock(&priv->_agn.notif_wait_lock); | ||
759 | list_for_each_entry(w, &priv->_agn.notif_waits, list) { | ||
760 | if (w->cmd == pkt->hdr.cmd) { | ||
761 | w->triggered = true; | ||
762 | if (w->fn) | ||
763 | w->fn(priv, pkt); | ||
764 | } | ||
765 | } | ||
766 | spin_unlock(&priv->_agn.notif_wait_lock); | ||
767 | |||
768 | wake_up_all(&priv->_agn.notif_waitq); | ||
769 | } | ||
770 | |||
913 | /* Based on type of command response or notification, | 771 | /* Based on type of command response or notification, |
914 | * handle those that need handling via function in | 772 | * handle those that need handling via function in |
915 | * rx_handlers table. See iwl_setup_rx_handlers() */ | 773 | * rx_handlers table. See iwl_setup_rx_handlers() */ |
@@ -1379,66 +1237,6 @@ static void iwl_irq_tasklet(struct iwl_priv *priv) | |||
1379 | iwl_enable_rfkill_int(priv); | 1237 | iwl_enable_rfkill_int(priv); |
1380 | } | 1238 | } |
1381 | 1239 | ||
1382 | /* the threshold ratio of actual_ack_cnt to expected_ack_cnt in percent */ | ||
1383 | #define ACK_CNT_RATIO (50) | ||
1384 | #define BA_TIMEOUT_CNT (5) | ||
1385 | #define BA_TIMEOUT_MAX (16) | ||
1386 | |||
1387 | /** | ||
1388 | * iwl_good_ack_health - checks for ACK count ratios, BA timeout retries. | ||
1389 | * | ||
1390 | * When the ACK count ratio is 0 and aggregated BA timeout retries exceeding | ||
1391 | * the BA_TIMEOUT_MAX, reload firmware and bring system back to normal | ||
1392 | * operation state. | ||
1393 | */ | ||
1394 | bool iwl_good_ack_health(struct iwl_priv *priv, | ||
1395 | struct iwl_rx_packet *pkt) | ||
1396 | { | ||
1397 | bool rc = true; | ||
1398 | int actual_ack_cnt_delta, expected_ack_cnt_delta; | ||
1399 | int ba_timeout_delta; | ||
1400 | |||
1401 | actual_ack_cnt_delta = | ||
1402 | le32_to_cpu(pkt->u.stats.tx.actual_ack_cnt) - | ||
1403 | le32_to_cpu(priv->_agn.statistics.tx.actual_ack_cnt); | ||
1404 | expected_ack_cnt_delta = | ||
1405 | le32_to_cpu(pkt->u.stats.tx.expected_ack_cnt) - | ||
1406 | le32_to_cpu(priv->_agn.statistics.tx.expected_ack_cnt); | ||
1407 | ba_timeout_delta = | ||
1408 | le32_to_cpu(pkt->u.stats.tx.agg.ba_timeout) - | ||
1409 | le32_to_cpu(priv->_agn.statistics.tx.agg.ba_timeout); | ||
1410 | if ((priv->_agn.agg_tids_count > 0) && | ||
1411 | (expected_ack_cnt_delta > 0) && | ||
1412 | (((actual_ack_cnt_delta * 100) / expected_ack_cnt_delta) | ||
1413 | < ACK_CNT_RATIO) && | ||
1414 | (ba_timeout_delta > BA_TIMEOUT_CNT)) { | ||
1415 | IWL_DEBUG_RADIO(priv, "actual_ack_cnt delta = %d," | ||
1416 | " expected_ack_cnt = %d\n", | ||
1417 | actual_ack_cnt_delta, expected_ack_cnt_delta); | ||
1418 | |||
1419 | #ifdef CONFIG_IWLWIFI_DEBUGFS | ||
1420 | /* | ||
1421 | * This is ifdef'ed on DEBUGFS because otherwise the | ||
1422 | * statistics aren't available. If DEBUGFS is set but | ||
1423 | * DEBUG is not, these will just compile out. | ||
1424 | */ | ||
1425 | IWL_DEBUG_RADIO(priv, "rx_detected_cnt delta = %d\n", | ||
1426 | priv->_agn.delta_statistics.tx.rx_detected_cnt); | ||
1427 | IWL_DEBUG_RADIO(priv, | ||
1428 | "ack_or_ba_timeout_collision delta = %d\n", | ||
1429 | priv->_agn.delta_statistics.tx. | ||
1430 | ack_or_ba_timeout_collision); | ||
1431 | #endif | ||
1432 | IWL_DEBUG_RADIO(priv, "agg ba_timeout delta = %d\n", | ||
1433 | ba_timeout_delta); | ||
1434 | if (!actual_ack_cnt_delta && | ||
1435 | (ba_timeout_delta >= BA_TIMEOUT_MAX)) | ||
1436 | rc = false; | ||
1437 | } | ||
1438 | return rc; | ||
1439 | } | ||
1440 | |||
1441 | |||
1442 | /***************************************************************************** | 1240 | /***************************************************************************** |
1443 | * | 1241 | * |
1444 | * sysfs attributes | 1242 | * sysfs attributes |
@@ -2632,13 +2430,6 @@ static void iwl_alive_start(struct iwl_priv *priv) | |||
2632 | 2430 | ||
2633 | IWL_DEBUG_INFO(priv, "Runtime Alive received.\n"); | 2431 | IWL_DEBUG_INFO(priv, "Runtime Alive received.\n"); |
2634 | 2432 | ||
2635 | if (priv->card_alive.is_valid != UCODE_VALID_OK) { | ||
2636 | /* We had an error bringing up the hardware, so take it | ||
2637 | * all the way back down so we can try again */ | ||
2638 | IWL_DEBUG_INFO(priv, "Alive failed.\n"); | ||
2639 | goto restart; | ||
2640 | } | ||
2641 | |||
2642 | /* Initialize uCode has loaded Runtime uCode ... verify inst image. | 2433 | /* Initialize uCode has loaded Runtime uCode ... verify inst image. |
2643 | * This is a paranoid check, because we would not have gotten the | 2434 | * This is a paranoid check, because we would not have gotten the |
2644 | * "runtime" alive if code weren't properly loaded. */ | 2435 | * "runtime" alive if code weren't properly loaded. */ |
@@ -2710,9 +2501,11 @@ static void iwl_alive_start(struct iwl_priv *priv) | |||
2710 | priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx); | 2501 | priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx); |
2711 | } | 2502 | } |
2712 | 2503 | ||
2713 | if (priv->cfg->bt_params && | 2504 | if (!priv->cfg->bt_params || (priv->cfg->bt_params && |
2714 | !priv->cfg->bt_params->advanced_bt_coexist) { | 2505 | !priv->cfg->bt_params->advanced_bt_coexist)) { |
2715 | /* Configure Bluetooth device coexistence support */ | 2506 | /* |
2507 | * default is 2-wire BT coexexistence support | ||
2508 | */ | ||
2716 | priv->cfg->ops->hcmd->send_bt_config(priv); | 2509 | priv->cfg->ops->hcmd->send_bt_config(priv); |
2717 | } | 2510 | } |
2718 | 2511 | ||
@@ -2726,8 +2519,6 @@ static void iwl_alive_start(struct iwl_priv *priv) | |||
2726 | /* At this point, the NIC is initialized and operational */ | 2519 | /* At this point, the NIC is initialized and operational */ |
2727 | iwl_rf_kill_ct_config(priv); | 2520 | iwl_rf_kill_ct_config(priv); |
2728 | 2521 | ||
2729 | iwl_leds_init(priv); | ||
2730 | |||
2731 | IWL_DEBUG_INFO(priv, "ALIVE processing complete.\n"); | 2522 | IWL_DEBUG_INFO(priv, "ALIVE processing complete.\n"); |
2732 | wake_up_interruptible(&priv->wait_command_queue); | 2523 | wake_up_interruptible(&priv->wait_command_queue); |
2733 | 2524 | ||
@@ -2769,7 +2560,6 @@ static void __iwl_down(struct iwl_priv *priv) | |||
2769 | priv->cfg->bt_params->bt_init_traffic_load; | 2560 | priv->cfg->bt_params->bt_init_traffic_load; |
2770 | else | 2561 | else |
2771 | priv->bt_traffic_load = 0; | 2562 | priv->bt_traffic_load = 0; |
2772 | priv->bt_sco_active = false; | ||
2773 | priv->bt_full_concurrent = false; | 2563 | priv->bt_full_concurrent = false; |
2774 | priv->bt_ci_compliance = 0; | 2564 | priv->bt_ci_compliance = 0; |
2775 | 2565 | ||
@@ -3063,8 +2853,7 @@ static void iwl_bg_run_time_calib_work(struct work_struct *work) | |||
3063 | } | 2853 | } |
3064 | 2854 | ||
3065 | if (priv->start_calib) { | 2855 | if (priv->start_calib) { |
3066 | if (priv->cfg->bt_params && | 2856 | if (iwl_bt_statistics(priv)) { |
3067 | priv->cfg->bt_params->bt_statistics) { | ||
3068 | iwl_chain_noise_calibration(priv, | 2857 | iwl_chain_noise_calibration(priv, |
3069 | (void *)&priv->_agn.statistics_bt); | 2858 | (void *)&priv->_agn.statistics_bt); |
3070 | iwl_sensitivity_calibration(priv, | 2859 | iwl_sensitivity_calibration(priv, |
@@ -3089,7 +2878,7 @@ static void iwl_bg_restart(struct work_struct *data) | |||
3089 | 2878 | ||
3090 | if (test_and_clear_bit(STATUS_FW_ERROR, &priv->status)) { | 2879 | if (test_and_clear_bit(STATUS_FW_ERROR, &priv->status)) { |
3091 | struct iwl_rxon_context *ctx; | 2880 | struct iwl_rxon_context *ctx; |
3092 | bool bt_sco, bt_full_concurrent; | 2881 | bool bt_full_concurrent; |
3093 | u8 bt_ci_compliance; | 2882 | u8 bt_ci_compliance; |
3094 | u8 bt_load; | 2883 | u8 bt_load; |
3095 | u8 bt_status; | 2884 | u8 bt_status; |
@@ -3108,7 +2897,6 @@ static void iwl_bg_restart(struct work_struct *data) | |||
3108 | * re-configure the hw when we reconfigure the BT | 2897 | * re-configure the hw when we reconfigure the BT |
3109 | * command. | 2898 | * command. |
3110 | */ | 2899 | */ |
3111 | bt_sco = priv->bt_sco_active; | ||
3112 | bt_full_concurrent = priv->bt_full_concurrent; | 2900 | bt_full_concurrent = priv->bt_full_concurrent; |
3113 | bt_ci_compliance = priv->bt_ci_compliance; | 2901 | bt_ci_compliance = priv->bt_ci_compliance; |
3114 | bt_load = priv->bt_traffic_load; | 2902 | bt_load = priv->bt_traffic_load; |
@@ -3116,7 +2904,6 @@ static void iwl_bg_restart(struct work_struct *data) | |||
3116 | 2904 | ||
3117 | __iwl_down(priv); | 2905 | __iwl_down(priv); |
3118 | 2906 | ||
3119 | priv->bt_sco_active = bt_sco; | ||
3120 | priv->bt_full_concurrent = bt_full_concurrent; | 2907 | priv->bt_full_concurrent = bt_full_concurrent; |
3121 | priv->bt_ci_compliance = bt_ci_compliance; | 2908 | priv->bt_ci_compliance = bt_ci_compliance; |
3122 | priv->bt_traffic_load = bt_load; | 2909 | priv->bt_traffic_load = bt_load; |
@@ -3150,6 +2937,91 @@ static void iwl_bg_rx_replenish(struct work_struct *data) | |||
3150 | mutex_unlock(&priv->mutex); | 2937 | mutex_unlock(&priv->mutex); |
3151 | } | 2938 | } |
3152 | 2939 | ||
2940 | static int iwl_mac_offchannel_tx(struct ieee80211_hw *hw, struct sk_buff *skb, | ||
2941 | struct ieee80211_channel *chan, | ||
2942 | enum nl80211_channel_type channel_type, | ||
2943 | unsigned int wait) | ||
2944 | { | ||
2945 | struct iwl_priv *priv = hw->priv; | ||
2946 | int ret; | ||
2947 | |||
2948 | /* Not supported if we don't have PAN */ | ||
2949 | if (!(priv->valid_contexts & BIT(IWL_RXON_CTX_PAN))) { | ||
2950 | ret = -EOPNOTSUPP; | ||
2951 | goto free; | ||
2952 | } | ||
2953 | |||
2954 | /* Not supported on pre-P2P firmware */ | ||
2955 | if (!(priv->contexts[IWL_RXON_CTX_PAN].interface_modes & | ||
2956 | BIT(NL80211_IFTYPE_P2P_CLIENT))) { | ||
2957 | ret = -EOPNOTSUPP; | ||
2958 | goto free; | ||
2959 | } | ||
2960 | |||
2961 | mutex_lock(&priv->mutex); | ||
2962 | |||
2963 | if (!priv->contexts[IWL_RXON_CTX_PAN].is_active) { | ||
2964 | /* | ||
2965 | * If the PAN context is free, use the normal | ||
2966 | * way of doing remain-on-channel offload + TX. | ||
2967 | */ | ||
2968 | ret = 1; | ||
2969 | goto out; | ||
2970 | } | ||
2971 | |||
2972 | /* TODO: queue up if scanning? */ | ||
2973 | if (test_bit(STATUS_SCANNING, &priv->status) || | ||
2974 | priv->_agn.offchan_tx_skb) { | ||
2975 | ret = -EBUSY; | ||
2976 | goto out; | ||
2977 | } | ||
2978 | |||
2979 | /* | ||
2980 | * max_scan_ie_len doesn't include the blank SSID or the header, | ||
2981 | * so need to add that again here. | ||
2982 | */ | ||
2983 | if (skb->len > hw->wiphy->max_scan_ie_len + 24 + 2) { | ||
2984 | ret = -ENOBUFS; | ||
2985 | goto out; | ||
2986 | } | ||
2987 | |||
2988 | priv->_agn.offchan_tx_skb = skb; | ||
2989 | priv->_agn.offchan_tx_timeout = wait; | ||
2990 | priv->_agn.offchan_tx_chan = chan; | ||
2991 | |||
2992 | ret = iwl_scan_initiate(priv, priv->contexts[IWL_RXON_CTX_PAN].vif, | ||
2993 | IWL_SCAN_OFFCH_TX, chan->band); | ||
2994 | if (ret) | ||
2995 | priv->_agn.offchan_tx_skb = NULL; | ||
2996 | out: | ||
2997 | mutex_unlock(&priv->mutex); | ||
2998 | free: | ||
2999 | if (ret < 0) | ||
3000 | kfree_skb(skb); | ||
3001 | |||
3002 | return ret; | ||
3003 | } | ||
3004 | |||
3005 | static int iwl_mac_offchannel_tx_cancel_wait(struct ieee80211_hw *hw) | ||
3006 | { | ||
3007 | struct iwl_priv *priv = hw->priv; | ||
3008 | int ret; | ||
3009 | |||
3010 | mutex_lock(&priv->mutex); | ||
3011 | |||
3012 | if (!priv->_agn.offchan_tx_skb) | ||
3013 | return -EINVAL; | ||
3014 | |||
3015 | priv->_agn.offchan_tx_skb = NULL; | ||
3016 | |||
3017 | ret = iwl_scan_cancel_timeout(priv, 200); | ||
3018 | if (ret) | ||
3019 | ret = -EIO; | ||
3020 | mutex_unlock(&priv->mutex); | ||
3021 | |||
3022 | return ret; | ||
3023 | } | ||
3024 | |||
3153 | /***************************************************************************** | 3025 | /***************************************************************************** |
3154 | * | 3026 | * |
3155 | * mac80211 entry point functions | 3027 | * mac80211 entry point functions |
@@ -3178,6 +3050,8 @@ static int iwl_mac_setup_register(struct iwl_priv *priv, | |||
3178 | IEEE80211_HW_SPECTRUM_MGMT | | 3050 | IEEE80211_HW_SPECTRUM_MGMT | |
3179 | IEEE80211_HW_REPORTS_TX_ACK_STATUS; | 3051 | IEEE80211_HW_REPORTS_TX_ACK_STATUS; |
3180 | 3052 | ||
3053 | hw->max_tx_aggregation_subframes = LINK_QUAL_AGG_FRAME_LIMIT_DEF; | ||
3054 | |||
3181 | if (!priv->cfg->base_params->broken_powersave) | 3055 | if (!priv->cfg->base_params->broken_powersave) |
3182 | hw->flags |= IEEE80211_HW_SUPPORTS_PS | | 3056 | hw->flags |= IEEE80211_HW_SUPPORTS_PS | |
3183 | IEEE80211_HW_SUPPORTS_DYNAMIC_PS; | 3057 | IEEE80211_HW_SUPPORTS_DYNAMIC_PS; |
@@ -3194,8 +3068,11 @@ static int iwl_mac_setup_register(struct iwl_priv *priv, | |||
3194 | hw->wiphy->interface_modes |= ctx->exclusive_interface_modes; | 3068 | hw->wiphy->interface_modes |= ctx->exclusive_interface_modes; |
3195 | } | 3069 | } |
3196 | 3070 | ||
3071 | hw->wiphy->max_remain_on_channel_duration = 1000; | ||
3072 | |||
3197 | hw->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY | | 3073 | hw->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY | |
3198 | WIPHY_FLAG_DISABLE_BEACON_HINTS; | 3074 | WIPHY_FLAG_DISABLE_BEACON_HINTS | |
3075 | WIPHY_FLAG_IBSS_RSN; | ||
3199 | 3076 | ||
3200 | /* | 3077 | /* |
3201 | * For now, disable PS by default because it affects | 3078 | * For now, disable PS by default because it affects |
@@ -3219,6 +3096,8 @@ static int iwl_mac_setup_register(struct iwl_priv *priv, | |||
3219 | priv->hw->wiphy->bands[IEEE80211_BAND_5GHZ] = | 3096 | priv->hw->wiphy->bands[IEEE80211_BAND_5GHZ] = |
3220 | &priv->bands[IEEE80211_BAND_5GHZ]; | 3097 | &priv->bands[IEEE80211_BAND_5GHZ]; |
3221 | 3098 | ||
3099 | iwl_leds_init(priv); | ||
3100 | |||
3222 | ret = ieee80211_register_hw(priv->hw); | 3101 | ret = ieee80211_register_hw(priv->hw); |
3223 | if (ret) { | 3102 | if (ret) { |
3224 | IWL_ERR(priv, "Failed to register hw (error %d)\n", ret); | 3103 | IWL_ERR(priv, "Failed to register hw (error %d)\n", ret); |
@@ -3263,7 +3142,7 @@ int iwlagn_mac_start(struct ieee80211_hw *hw) | |||
3263 | } | 3142 | } |
3264 | } | 3143 | } |
3265 | 3144 | ||
3266 | iwl_led_start(priv); | 3145 | iwlagn_led_enable(priv); |
3267 | 3146 | ||
3268 | out: | 3147 | out: |
3269 | priv->is_open = 1; | 3148 | priv->is_open = 1; |
@@ -3294,7 +3173,7 @@ void iwlagn_mac_stop(struct ieee80211_hw *hw) | |||
3294 | IWL_DEBUG_MAC80211(priv, "leave\n"); | 3173 | IWL_DEBUG_MAC80211(priv, "leave\n"); |
3295 | } | 3174 | } |
3296 | 3175 | ||
3297 | int iwlagn_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb) | 3176 | void iwlagn_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb) |
3298 | { | 3177 | { |
3299 | struct iwl_priv *priv = hw->priv; | 3178 | struct iwl_priv *priv = hw->priv; |
3300 | 3179 | ||
@@ -3307,7 +3186,6 @@ int iwlagn_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
3307 | dev_kfree_skb_any(skb); | 3186 | dev_kfree_skb_any(skb); |
3308 | 3187 | ||
3309 | IWL_DEBUG_MACDUMP(priv, "leave\n"); | 3188 | IWL_DEBUG_MACDUMP(priv, "leave\n"); |
3310 | return NETDEV_TX_OK; | ||
3311 | } | 3189 | } |
3312 | 3190 | ||
3313 | void iwlagn_mac_update_tkip_key(struct ieee80211_hw *hw, | 3191 | void iwlagn_mac_update_tkip_key(struct ieee80211_hw *hw, |
@@ -3345,6 +3223,14 @@ int iwlagn_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | |||
3345 | return -EOPNOTSUPP; | 3223 | return -EOPNOTSUPP; |
3346 | } | 3224 | } |
3347 | 3225 | ||
3226 | /* | ||
3227 | * To support IBSS RSN, don't program group keys in IBSS, the | ||
3228 | * hardware will then not attempt to decrypt the frames. | ||
3229 | */ | ||
3230 | if (vif->type == NL80211_IFTYPE_ADHOC && | ||
3231 | !(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) | ||
3232 | return -EOPNOTSUPP; | ||
3233 | |||
3348 | sta_id = iwl_sta_id_or_broadcast(priv, vif_priv->ctx, sta); | 3234 | sta_id = iwl_sta_id_or_broadcast(priv, vif_priv->ctx, sta); |
3349 | if (sta_id == IWL_INVALID_STATION) | 3235 | if (sta_id == IWL_INVALID_STATION) |
3350 | return -EINVAL; | 3236 | return -EINVAL; |
@@ -3399,10 +3285,12 @@ int iwlagn_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | |||
3399 | int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw, | 3285 | int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw, |
3400 | struct ieee80211_vif *vif, | 3286 | struct ieee80211_vif *vif, |
3401 | enum ieee80211_ampdu_mlme_action action, | 3287 | enum ieee80211_ampdu_mlme_action action, |
3402 | struct ieee80211_sta *sta, u16 tid, u16 *ssn) | 3288 | struct ieee80211_sta *sta, u16 tid, u16 *ssn, |
3289 | u8 buf_size) | ||
3403 | { | 3290 | { |
3404 | struct iwl_priv *priv = hw->priv; | 3291 | struct iwl_priv *priv = hw->priv; |
3405 | int ret = -EINVAL; | 3292 | int ret = -EINVAL; |
3293 | struct iwl_station_priv *sta_priv = (void *) sta->drv_priv; | ||
3406 | 3294 | ||
3407 | IWL_DEBUG_HT(priv, "A-MPDU action on addr %pM tid %d\n", | 3295 | IWL_DEBUG_HT(priv, "A-MPDU action on addr %pM tid %d\n", |
3408 | sta->addr, tid); | 3296 | sta->addr, tid); |
@@ -3457,11 +3345,28 @@ int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw, | |||
3457 | } | 3345 | } |
3458 | break; | 3346 | break; |
3459 | case IEEE80211_AMPDU_TX_OPERATIONAL: | 3347 | case IEEE80211_AMPDU_TX_OPERATIONAL: |
3348 | /* | ||
3349 | * If the limit is 0, then it wasn't initialised yet, | ||
3350 | * use the default. We can do that since we take the | ||
3351 | * minimum below, and we don't want to go above our | ||
3352 | * default due to hardware restrictions. | ||
3353 | */ | ||
3354 | if (sta_priv->max_agg_bufsize == 0) | ||
3355 | sta_priv->max_agg_bufsize = | ||
3356 | LINK_QUAL_AGG_FRAME_LIMIT_DEF; | ||
3357 | |||
3358 | /* | ||
3359 | * Even though in theory the peer could have different | ||
3360 | * aggregation reorder buffer sizes for different sessions, | ||
3361 | * our ucode doesn't allow for that and has a global limit | ||
3362 | * for each station. Therefore, use the minimum of all the | ||
3363 | * aggregation sessions and our default value. | ||
3364 | */ | ||
3365 | sta_priv->max_agg_bufsize = | ||
3366 | min(sta_priv->max_agg_bufsize, buf_size); | ||
3367 | |||
3460 | if (priv->cfg->ht_params && | 3368 | if (priv->cfg->ht_params && |
3461 | priv->cfg->ht_params->use_rts_for_aggregation) { | 3369 | priv->cfg->ht_params->use_rts_for_aggregation) { |
3462 | struct iwl_station_priv *sta_priv = | ||
3463 | (void *) sta->drv_priv; | ||
3464 | |||
3465 | /* | 3370 | /* |
3466 | * switch to RTS/CTS if it is the prefer protection | 3371 | * switch to RTS/CTS if it is the prefer protection |
3467 | * method for HT traffic | 3372 | * method for HT traffic |
@@ -3469,9 +3374,13 @@ int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw, | |||
3469 | 3374 | ||
3470 | sta_priv->lq_sta.lq.general_params.flags |= | 3375 | sta_priv->lq_sta.lq.general_params.flags |= |
3471 | LINK_QUAL_FLAGS_SET_STA_TLC_RTS_MSK; | 3376 | LINK_QUAL_FLAGS_SET_STA_TLC_RTS_MSK; |
3472 | iwl_send_lq_cmd(priv, iwl_rxon_ctx_from_vif(vif), | ||
3473 | &sta_priv->lq_sta.lq, CMD_ASYNC, false); | ||
3474 | } | 3377 | } |
3378 | |||
3379 | sta_priv->lq_sta.lq.agg_params.agg_frame_cnt_limit = | ||
3380 | sta_priv->max_agg_bufsize; | ||
3381 | |||
3382 | iwl_send_lq_cmd(priv, iwl_rxon_ctx_from_vif(vif), | ||
3383 | &sta_priv->lq_sta.lq, CMD_ASYNC, false); | ||
3475 | ret = 0; | 3384 | ret = 0; |
3476 | break; | 3385 | break; |
3477 | } | 3386 | } |
@@ -3709,6 +3618,95 @@ done: | |||
3709 | IWL_DEBUG_MAC80211(priv, "leave\n"); | 3618 | IWL_DEBUG_MAC80211(priv, "leave\n"); |
3710 | } | 3619 | } |
3711 | 3620 | ||
3621 | static void iwlagn_disable_roc(struct iwl_priv *priv) | ||
3622 | { | ||
3623 | struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_PAN]; | ||
3624 | struct ieee80211_channel *chan = ACCESS_ONCE(priv->hw->conf.channel); | ||
3625 | |||
3626 | lockdep_assert_held(&priv->mutex); | ||
3627 | |||
3628 | if (!ctx->is_active) | ||
3629 | return; | ||
3630 | |||
3631 | ctx->staging.dev_type = RXON_DEV_TYPE_2STA; | ||
3632 | ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK; | ||
3633 | iwl_set_rxon_channel(priv, chan, ctx); | ||
3634 | iwl_set_flags_for_band(priv, ctx, chan->band, NULL); | ||
3635 | |||
3636 | priv->_agn.hw_roc_channel = NULL; | ||
3637 | |||
3638 | iwlcore_commit_rxon(priv, ctx); | ||
3639 | |||
3640 | ctx->is_active = false; | ||
3641 | } | ||
3642 | |||
3643 | static void iwlagn_bg_roc_done(struct work_struct *work) | ||
3644 | { | ||
3645 | struct iwl_priv *priv = container_of(work, struct iwl_priv, | ||
3646 | _agn.hw_roc_work.work); | ||
3647 | |||
3648 | mutex_lock(&priv->mutex); | ||
3649 | ieee80211_remain_on_channel_expired(priv->hw); | ||
3650 | iwlagn_disable_roc(priv); | ||
3651 | mutex_unlock(&priv->mutex); | ||
3652 | } | ||
3653 | |||
3654 | static int iwl_mac_remain_on_channel(struct ieee80211_hw *hw, | ||
3655 | struct ieee80211_channel *channel, | ||
3656 | enum nl80211_channel_type channel_type, | ||
3657 | int duration) | ||
3658 | { | ||
3659 | struct iwl_priv *priv = hw->priv; | ||
3660 | int err = 0; | ||
3661 | |||
3662 | if (!(priv->valid_contexts & BIT(IWL_RXON_CTX_PAN))) | ||
3663 | return -EOPNOTSUPP; | ||
3664 | |||
3665 | if (!(priv->contexts[IWL_RXON_CTX_PAN].interface_modes & | ||
3666 | BIT(NL80211_IFTYPE_P2P_CLIENT))) | ||
3667 | return -EOPNOTSUPP; | ||
3668 | |||
3669 | mutex_lock(&priv->mutex); | ||
3670 | |||
3671 | if (priv->contexts[IWL_RXON_CTX_PAN].is_active || | ||
3672 | test_bit(STATUS_SCAN_HW, &priv->status)) { | ||
3673 | err = -EBUSY; | ||
3674 | goto out; | ||
3675 | } | ||
3676 | |||
3677 | priv->contexts[IWL_RXON_CTX_PAN].is_active = true; | ||
3678 | priv->_agn.hw_roc_channel = channel; | ||
3679 | priv->_agn.hw_roc_chantype = channel_type; | ||
3680 | priv->_agn.hw_roc_duration = DIV_ROUND_UP(duration * 1000, 1024); | ||
3681 | iwlcore_commit_rxon(priv, &priv->contexts[IWL_RXON_CTX_PAN]); | ||
3682 | queue_delayed_work(priv->workqueue, &priv->_agn.hw_roc_work, | ||
3683 | msecs_to_jiffies(duration + 20)); | ||
3684 | |||
3685 | msleep(IWL_MIN_SLOT_TIME); /* TU is almost ms */ | ||
3686 | ieee80211_ready_on_channel(priv->hw); | ||
3687 | |||
3688 | out: | ||
3689 | mutex_unlock(&priv->mutex); | ||
3690 | |||
3691 | return err; | ||
3692 | } | ||
3693 | |||
3694 | static int iwl_mac_cancel_remain_on_channel(struct ieee80211_hw *hw) | ||
3695 | { | ||
3696 | struct iwl_priv *priv = hw->priv; | ||
3697 | |||
3698 | if (!(priv->valid_contexts & BIT(IWL_RXON_CTX_PAN))) | ||
3699 | return -EOPNOTSUPP; | ||
3700 | |||
3701 | cancel_delayed_work_sync(&priv->_agn.hw_roc_work); | ||
3702 | |||
3703 | mutex_lock(&priv->mutex); | ||
3704 | iwlagn_disable_roc(priv); | ||
3705 | mutex_unlock(&priv->mutex); | ||
3706 | |||
3707 | return 0; | ||
3708 | } | ||
3709 | |||
3712 | /***************************************************************************** | 3710 | /***************************************************************************** |
3713 | * | 3711 | * |
3714 | * driver setup and teardown | 3712 | * driver setup and teardown |
@@ -3730,6 +3728,7 @@ static void iwl_setup_deferred_work(struct iwl_priv *priv) | |||
3730 | INIT_WORK(&priv->bt_runtime_config, iwl_bg_bt_runtime_config); | 3728 | INIT_WORK(&priv->bt_runtime_config, iwl_bg_bt_runtime_config); |
3731 | INIT_DELAYED_WORK(&priv->init_alive_start, iwl_bg_init_alive_start); | 3729 | INIT_DELAYED_WORK(&priv->init_alive_start, iwl_bg_init_alive_start); |
3732 | INIT_DELAYED_WORK(&priv->alive_start, iwl_bg_alive_start); | 3730 | INIT_DELAYED_WORK(&priv->alive_start, iwl_bg_alive_start); |
3731 | INIT_DELAYED_WORK(&priv->_agn.hw_roc_work, iwlagn_bg_roc_done); | ||
3733 | 3732 | ||
3734 | iwl_setup_scan_deferred_work(priv); | 3733 | iwl_setup_scan_deferred_work(priv); |
3735 | 3734 | ||
@@ -3823,6 +3822,8 @@ static int iwl_init_drv(struct iwl_priv *priv) | |||
3823 | priv->force_reset[IWL_FW_RESET].reset_duration = | 3822 | priv->force_reset[IWL_FW_RESET].reset_duration = |
3824 | IWL_DELAY_NEXT_FORCE_FW_RELOAD; | 3823 | IWL_DELAY_NEXT_FORCE_FW_RELOAD; |
3825 | 3824 | ||
3825 | priv->rx_statistics_jiffies = jiffies; | ||
3826 | |||
3826 | /* Choose which receivers/antennas to use */ | 3827 | /* Choose which receivers/antennas to use */ |
3827 | if (priv->cfg->ops->hcmd->set_rxon_chain) | 3828 | if (priv->cfg->ops->hcmd->set_rxon_chain) |
3828 | priv->cfg->ops->hcmd->set_rxon_chain(priv, | 3829 | priv->cfg->ops->hcmd->set_rxon_chain(priv, |
@@ -3876,7 +3877,6 @@ static void iwl_uninit_drv(struct iwl_priv *priv) | |||
3876 | kfree(priv->scan_cmd); | 3877 | kfree(priv->scan_cmd); |
3877 | } | 3878 | } |
3878 | 3879 | ||
3879 | #ifdef CONFIG_IWL5000 | ||
3880 | struct ieee80211_ops iwlagn_hw_ops = { | 3880 | struct ieee80211_ops iwlagn_hw_ops = { |
3881 | .tx = iwlagn_mac_tx, | 3881 | .tx = iwlagn_mac_tx, |
3882 | .start = iwlagn_mac_start, | 3882 | .start = iwlagn_mac_start, |
@@ -3898,14 +3898,17 @@ struct ieee80211_ops iwlagn_hw_ops = { | |||
3898 | .channel_switch = iwlagn_mac_channel_switch, | 3898 | .channel_switch = iwlagn_mac_channel_switch, |
3899 | .flush = iwlagn_mac_flush, | 3899 | .flush = iwlagn_mac_flush, |
3900 | .tx_last_beacon = iwl_mac_tx_last_beacon, | 3900 | .tx_last_beacon = iwl_mac_tx_last_beacon, |
3901 | .remain_on_channel = iwl_mac_remain_on_channel, | ||
3902 | .cancel_remain_on_channel = iwl_mac_cancel_remain_on_channel, | ||
3903 | .offchannel_tx = iwl_mac_offchannel_tx, | ||
3904 | .offchannel_tx_cancel_wait = iwl_mac_offchannel_tx_cancel_wait, | ||
3901 | }; | 3905 | }; |
3902 | #endif | ||
3903 | 3906 | ||
3904 | static void iwl_hw_detect(struct iwl_priv *priv) | 3907 | static void iwl_hw_detect(struct iwl_priv *priv) |
3905 | { | 3908 | { |
3906 | priv->hw_rev = _iwl_read32(priv, CSR_HW_REV); | 3909 | priv->hw_rev = _iwl_read32(priv, CSR_HW_REV); |
3907 | priv->hw_wa_rev = _iwl_read32(priv, CSR_HW_REV_WA_REG); | 3910 | priv->hw_wa_rev = _iwl_read32(priv, CSR_HW_REV_WA_REG); |
3908 | pci_read_config_byte(priv->pci_dev, PCI_REVISION_ID, &priv->rev_id); | 3911 | priv->rev_id = priv->pci_dev->revision; |
3909 | IWL_DEBUG_INFO(priv, "HW Revision ID = 0x%X\n", priv->rev_id); | 3912 | IWL_DEBUG_INFO(priv, "HW Revision ID = 0x%X\n", priv->rev_id); |
3910 | } | 3913 | } |
3911 | 3914 | ||
@@ -3967,12 +3970,7 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
3967 | if (cfg->mod_params->disable_hw_scan) { | 3970 | if (cfg->mod_params->disable_hw_scan) { |
3968 | dev_printk(KERN_DEBUG, &(pdev->dev), | 3971 | dev_printk(KERN_DEBUG, &(pdev->dev), |
3969 | "sw scan support is deprecated\n"); | 3972 | "sw scan support is deprecated\n"); |
3970 | #ifdef CONFIG_IWL5000 | ||
3971 | iwlagn_hw_ops.hw_scan = NULL; | 3973 | iwlagn_hw_ops.hw_scan = NULL; |
3972 | #endif | ||
3973 | #ifdef CONFIG_IWL4965 | ||
3974 | iwl4965_hw_ops.hw_scan = NULL; | ||
3975 | #endif | ||
3976 | } | 3974 | } |
3977 | 3975 | ||
3978 | hw = iwl_alloc_all(cfg); | 3976 | hw = iwl_alloc_all(cfg); |
@@ -4025,6 +4023,10 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
4025 | priv->contexts[IWL_RXON_CTX_PAN].mcast_queue = IWL_IPAN_MCAST_QUEUE; | 4023 | priv->contexts[IWL_RXON_CTX_PAN].mcast_queue = IWL_IPAN_MCAST_QUEUE; |
4026 | priv->contexts[IWL_RXON_CTX_PAN].interface_modes = | 4024 | priv->contexts[IWL_RXON_CTX_PAN].interface_modes = |
4027 | BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_AP); | 4025 | BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_AP); |
4026 | #ifdef CONFIG_IWL_P2P | ||
4027 | priv->contexts[IWL_RXON_CTX_PAN].interface_modes |= | ||
4028 | BIT(NL80211_IFTYPE_P2P_CLIENT) | BIT(NL80211_IFTYPE_P2P_GO); | ||
4029 | #endif | ||
4028 | priv->contexts[IWL_RXON_CTX_PAN].ap_devtype = RXON_DEV_TYPE_CP; | 4030 | priv->contexts[IWL_RXON_CTX_PAN].ap_devtype = RXON_DEV_TYPE_CP; |
4029 | priv->contexts[IWL_RXON_CTX_PAN].station_devtype = RXON_DEV_TYPE_2STA; | 4031 | priv->contexts[IWL_RXON_CTX_PAN].station_devtype = RXON_DEV_TYPE_2STA; |
4030 | priv->contexts[IWL_RXON_CTX_PAN].unused_devtype = RXON_DEV_TYPE_P2P; | 4032 | priv->contexts[IWL_RXON_CTX_PAN].unused_devtype = RXON_DEV_TYPE_P2P; |
@@ -4272,6 +4274,9 @@ static void __devexit iwl_pci_remove(struct pci_dev *pdev) | |||
4272 | * we need to set STATUS_EXIT_PENDING bit. | 4274 | * we need to set STATUS_EXIT_PENDING bit. |
4273 | */ | 4275 | */ |
4274 | set_bit(STATUS_EXIT_PENDING, &priv->status); | 4276 | set_bit(STATUS_EXIT_PENDING, &priv->status); |
4277 | |||
4278 | iwl_leds_exit(priv); | ||
4279 | |||
4275 | if (priv->mac80211_registered) { | 4280 | if (priv->mac80211_registered) { |
4276 | ieee80211_unregister_hw(priv->hw); | 4281 | ieee80211_unregister_hw(priv->hw); |
4277 | priv->mac80211_registered = 0; | 4282 | priv->mac80211_registered = 0; |
@@ -4344,12 +4349,6 @@ static void __devexit iwl_pci_remove(struct pci_dev *pdev) | |||
4344 | 4349 | ||
4345 | /* Hardware specific file defines the PCI IDs table for that hardware module */ | 4350 | /* Hardware specific file defines the PCI IDs table for that hardware module */ |
4346 | static DEFINE_PCI_DEVICE_TABLE(iwl_hw_card_ids) = { | 4351 | static DEFINE_PCI_DEVICE_TABLE(iwl_hw_card_ids) = { |
4347 | #ifdef CONFIG_IWL4965 | ||
4348 | {IWL_PCI_DEVICE(0x4229, PCI_ANY_ID, iwl4965_agn_cfg)}, | ||
4349 | {IWL_PCI_DEVICE(0x4230, PCI_ANY_ID, iwl4965_agn_cfg)}, | ||
4350 | #endif /* CONFIG_IWL4965 */ | ||
4351 | #ifdef CONFIG_IWL5000 | ||
4352 | /* 5100 Series WiFi */ | ||
4353 | {IWL_PCI_DEVICE(0x4232, 0x1201, iwl5100_agn_cfg)}, /* Mini Card */ | 4352 | {IWL_PCI_DEVICE(0x4232, 0x1201, iwl5100_agn_cfg)}, /* Mini Card */ |
4354 | {IWL_PCI_DEVICE(0x4232, 0x1301, iwl5100_agn_cfg)}, /* Half Mini Card */ | 4353 | {IWL_PCI_DEVICE(0x4232, 0x1301, iwl5100_agn_cfg)}, /* Half Mini Card */ |
4355 | {IWL_PCI_DEVICE(0x4232, 0x1204, iwl5100_agn_cfg)}, /* Mini Card */ | 4354 | {IWL_PCI_DEVICE(0x4232, 0x1204, iwl5100_agn_cfg)}, /* Mini Card */ |
@@ -4492,7 +4491,48 @@ static DEFINE_PCI_DEVICE_TABLE(iwl_hw_card_ids) = { | |||
4492 | {IWL_PCI_DEVICE(0x0896, 0x5025, iwl130_bgn_cfg)}, | 4491 | {IWL_PCI_DEVICE(0x0896, 0x5025, iwl130_bgn_cfg)}, |
4493 | {IWL_PCI_DEVICE(0x0896, 0x5027, iwl130_bg_cfg)}, | 4492 | {IWL_PCI_DEVICE(0x0896, 0x5027, iwl130_bg_cfg)}, |
4494 | 4493 | ||
4495 | #endif /* CONFIG_IWL5000 */ | 4494 | /* 2x00 Series */ |
4495 | {IWL_PCI_DEVICE(0x0890, 0x4022, iwl2000_2bgn_cfg)}, | ||
4496 | {IWL_PCI_DEVICE(0x0891, 0x4222, iwl2000_2bgn_cfg)}, | ||
4497 | {IWL_PCI_DEVICE(0x0890, 0x4422, iwl2000_2bgn_cfg)}, | ||
4498 | {IWL_PCI_DEVICE(0x0890, 0x4026, iwl2000_2bg_cfg)}, | ||
4499 | {IWL_PCI_DEVICE(0x0891, 0x4226, iwl2000_2bg_cfg)}, | ||
4500 | {IWL_PCI_DEVICE(0x0890, 0x4426, iwl2000_2bg_cfg)}, | ||
4501 | |||
4502 | /* 2x30 Series */ | ||
4503 | {IWL_PCI_DEVICE(0x0887, 0x4062, iwl2030_2bgn_cfg)}, | ||
4504 | {IWL_PCI_DEVICE(0x0888, 0x4262, iwl2030_2bgn_cfg)}, | ||
4505 | {IWL_PCI_DEVICE(0x0887, 0x4462, iwl2030_2bgn_cfg)}, | ||
4506 | {IWL_PCI_DEVICE(0x0887, 0x4066, iwl2030_2bg_cfg)}, | ||
4507 | {IWL_PCI_DEVICE(0x0888, 0x4266, iwl2030_2bg_cfg)}, | ||
4508 | {IWL_PCI_DEVICE(0x0887, 0x4466, iwl2030_2bg_cfg)}, | ||
4509 | |||
4510 | /* 6x35 Series */ | ||
4511 | {IWL_PCI_DEVICE(0x088E, 0x4060, iwl6035_2agn_cfg)}, | ||
4512 | {IWL_PCI_DEVICE(0x088F, 0x4260, iwl6035_2agn_cfg)}, | ||
4513 | {IWL_PCI_DEVICE(0x088E, 0x4460, iwl6035_2agn_cfg)}, | ||
4514 | {IWL_PCI_DEVICE(0x088E, 0x4064, iwl6035_2abg_cfg)}, | ||
4515 | {IWL_PCI_DEVICE(0x088F, 0x4264, iwl6035_2abg_cfg)}, | ||
4516 | {IWL_PCI_DEVICE(0x088E, 0x4464, iwl6035_2abg_cfg)}, | ||
4517 | {IWL_PCI_DEVICE(0x088E, 0x4066, iwl6035_2bg_cfg)}, | ||
4518 | {IWL_PCI_DEVICE(0x088F, 0x4266, iwl6035_2bg_cfg)}, | ||
4519 | {IWL_PCI_DEVICE(0x088E, 0x4466, iwl6035_2bg_cfg)}, | ||
4520 | |||
4521 | /* 200 Series */ | ||
4522 | {IWL_PCI_DEVICE(0x0894, 0x0022, iwl200_bgn_cfg)}, | ||
4523 | {IWL_PCI_DEVICE(0x0895, 0x0222, iwl200_bgn_cfg)}, | ||
4524 | {IWL_PCI_DEVICE(0x0894, 0x0422, iwl200_bgn_cfg)}, | ||
4525 | {IWL_PCI_DEVICE(0x0894, 0x0026, iwl200_bg_cfg)}, | ||
4526 | {IWL_PCI_DEVICE(0x0895, 0x0226, iwl200_bg_cfg)}, | ||
4527 | {IWL_PCI_DEVICE(0x0894, 0x0426, iwl200_bg_cfg)}, | ||
4528 | |||
4529 | /* 230 Series */ | ||
4530 | {IWL_PCI_DEVICE(0x0892, 0x0062, iwl230_bgn_cfg)}, | ||
4531 | {IWL_PCI_DEVICE(0x0893, 0x0262, iwl230_bgn_cfg)}, | ||
4532 | {IWL_PCI_DEVICE(0x0892, 0x0462, iwl230_bgn_cfg)}, | ||
4533 | {IWL_PCI_DEVICE(0x0892, 0x0066, iwl230_bg_cfg)}, | ||
4534 | {IWL_PCI_DEVICE(0x0893, 0x0266, iwl230_bg_cfg)}, | ||
4535 | {IWL_PCI_DEVICE(0x0892, 0x0466, iwl230_bg_cfg)}, | ||
4496 | 4536 | ||
4497 | {0} | 4537 | {0} |
4498 | }; | 4538 | }; |
@@ -4592,3 +4632,9 @@ MODULE_PARM_DESC(antenna_coupling, | |||
4592 | module_param_named(bt_ch_inhibition, iwlagn_bt_ch_announce, bool, S_IRUGO); | 4632 | module_param_named(bt_ch_inhibition, iwlagn_bt_ch_announce, bool, S_IRUGO); |
4593 | MODULE_PARM_DESC(bt_ch_inhibition, | 4633 | MODULE_PARM_DESC(bt_ch_inhibition, |
4594 | "Disable BT channel inhibition (default: enable)"); | 4634 | "Disable BT channel inhibition (default: enable)"); |
4635 | |||
4636 | module_param_named(plcp_check, iwlagn_mod_params.plcp_check, bool, S_IRUGO); | ||
4637 | MODULE_PARM_DESC(plcp_check, "Check plcp health (default: 1 [enabled])"); | ||
4638 | |||
4639 | module_param_named(ack_check, iwlagn_mod_params.ack_check, bool, S_IRUGO); | ||
4640 | MODULE_PARM_DESC(ack_check, "Check ack health (default: 0 [disabled])"); | ||