diff options
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-agn.c')
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-agn.c | 1273 |
1 files changed, 407 insertions, 866 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index f46ba2475776..a5637c4aa85d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c | |||
@@ -102,7 +102,7 @@ MODULE_ALIAS("iwl4965"); | |||
102 | * function correctly transitions out of the RXON_ASSOC_MSK state if | 102 | * function correctly transitions out of the RXON_ASSOC_MSK state if |
103 | * a HW tune is required based on the RXON structure changes. | 103 | * a HW tune is required based on the RXON structure changes. |
104 | */ | 104 | */ |
105 | static int iwl_commit_rxon(struct iwl_priv *priv) | 105 | int iwl_commit_rxon(struct iwl_priv *priv) |
106 | { | 106 | { |
107 | /* cast away the const for active_rxon in this function */ | 107 | /* cast away the const for active_rxon in this function */ |
108 | struct iwl_rxon_cmd *active_rxon = (void *)&priv->active_rxon; | 108 | struct iwl_rxon_cmd *active_rxon = (void *)&priv->active_rxon; |
@@ -190,8 +190,7 @@ static int iwl_commit_rxon(struct iwl_priv *priv) | |||
190 | 190 | ||
191 | iwl_clear_stations_table(priv); | 191 | iwl_clear_stations_table(priv); |
192 | 192 | ||
193 | if (!priv->error_recovering) | 193 | priv->start_calib = 0; |
194 | priv->start_calib = 0; | ||
195 | 194 | ||
196 | /* Add the broadcast address so we can send broadcast frames */ | 195 | /* Add the broadcast address so we can send broadcast frames */ |
197 | if (iwl_rxon_add_station(priv, iwl_bcast_addr, 0) == | 196 | if (iwl_rxon_add_station(priv, iwl_bcast_addr, 0) == |
@@ -246,8 +245,9 @@ static int iwl_commit_rxon(struct iwl_priv *priv) | |||
246 | void iwl_update_chain_flags(struct iwl_priv *priv) | 245 | void iwl_update_chain_flags(struct iwl_priv *priv) |
247 | { | 246 | { |
248 | 247 | ||
249 | iwl_set_rxon_chain(priv); | 248 | if (priv->cfg->ops->hcmd->set_rxon_chain) |
250 | iwl_commit_rxon(priv); | 249 | priv->cfg->ops->hcmd->set_rxon_chain(priv); |
250 | iwlcore_commit_rxon(priv); | ||
251 | } | 251 | } |
252 | 252 | ||
253 | static void iwl_clear_free_frames(struct iwl_priv *priv) | 253 | static void iwl_clear_free_frames(struct iwl_priv *priv) |
@@ -503,24 +503,12 @@ int iwl_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv, | |||
503 | int iwl_hw_tx_queue_init(struct iwl_priv *priv, | 503 | int iwl_hw_tx_queue_init(struct iwl_priv *priv, |
504 | struct iwl_tx_queue *txq) | 504 | struct iwl_tx_queue *txq) |
505 | { | 505 | { |
506 | int ret; | ||
507 | unsigned long flags; | ||
508 | int txq_id = txq->q.id; | 506 | int txq_id = txq->q.id; |
509 | 507 | ||
510 | spin_lock_irqsave(&priv->lock, flags); | ||
511 | ret = iwl_grab_nic_access(priv); | ||
512 | if (ret) { | ||
513 | spin_unlock_irqrestore(&priv->lock, flags); | ||
514 | return ret; | ||
515 | } | ||
516 | |||
517 | /* Circular buffer (TFD queue in DRAM) physical base address */ | 508 | /* Circular buffer (TFD queue in DRAM) physical base address */ |
518 | iwl_write_direct32(priv, FH_MEM_CBBC_QUEUE(txq_id), | 509 | iwl_write_direct32(priv, FH_MEM_CBBC_QUEUE(txq_id), |
519 | txq->q.dma_addr >> 8); | 510 | txq->q.dma_addr >> 8); |
520 | 511 | ||
521 | iwl_release_nic_access(priv); | ||
522 | spin_unlock_irqrestore(&priv->lock, flags); | ||
523 | |||
524 | return 0; | 512 | return 0; |
525 | } | 513 | } |
526 | 514 | ||
@@ -531,76 +519,6 @@ int iwl_hw_tx_queue_init(struct iwl_priv *priv, | |||
531 | * | 519 | * |
532 | ******************************************************************************/ | 520 | ******************************************************************************/ |
533 | 521 | ||
534 | static void iwl_ht_conf(struct iwl_priv *priv, | ||
535 | struct ieee80211_bss_conf *bss_conf) | ||
536 | { | ||
537 | struct ieee80211_sta_ht_cap *ht_conf; | ||
538 | struct iwl_ht_info *iwl_conf = &priv->current_ht_config; | ||
539 | struct ieee80211_sta *sta; | ||
540 | |||
541 | IWL_DEBUG_MAC80211(priv, "enter: \n"); | ||
542 | |||
543 | if (!iwl_conf->is_ht) | ||
544 | return; | ||
545 | |||
546 | |||
547 | /* | ||
548 | * It is totally wrong to base global information on something | ||
549 | * that is valid only when associated, alas, this driver works | ||
550 | * that way and I don't know how to fix it. | ||
551 | */ | ||
552 | |||
553 | rcu_read_lock(); | ||
554 | sta = ieee80211_find_sta(priv->hw, priv->bssid); | ||
555 | if (!sta) { | ||
556 | rcu_read_unlock(); | ||
557 | return; | ||
558 | } | ||
559 | ht_conf = &sta->ht_cap; | ||
560 | |||
561 | if (ht_conf->cap & IEEE80211_HT_CAP_SGI_20) | ||
562 | iwl_conf->sgf |= HT_SHORT_GI_20MHZ; | ||
563 | if (ht_conf->cap & IEEE80211_HT_CAP_SGI_40) | ||
564 | iwl_conf->sgf |= HT_SHORT_GI_40MHZ; | ||
565 | |||
566 | iwl_conf->is_green_field = !!(ht_conf->cap & IEEE80211_HT_CAP_GRN_FLD); | ||
567 | iwl_conf->max_amsdu_size = | ||
568 | !!(ht_conf->cap & IEEE80211_HT_CAP_MAX_AMSDU); | ||
569 | |||
570 | iwl_conf->supported_chan_width = | ||
571 | !!(ht_conf->cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40); | ||
572 | |||
573 | /* | ||
574 | * XXX: The HT configuration needs to be moved into iwl_mac_config() | ||
575 | * to be done there correctly. | ||
576 | */ | ||
577 | |||
578 | iwl_conf->extension_chan_offset = IEEE80211_HT_PARAM_CHA_SEC_NONE; | ||
579 | if (conf_is_ht40_minus(&priv->hw->conf)) | ||
580 | iwl_conf->extension_chan_offset = IEEE80211_HT_PARAM_CHA_SEC_BELOW; | ||
581 | else if (conf_is_ht40_plus(&priv->hw->conf)) | ||
582 | iwl_conf->extension_chan_offset = IEEE80211_HT_PARAM_CHA_SEC_ABOVE; | ||
583 | |||
584 | /* If no above or below channel supplied disable FAT channel */ | ||
585 | if (iwl_conf->extension_chan_offset != IEEE80211_HT_PARAM_CHA_SEC_ABOVE && | ||
586 | iwl_conf->extension_chan_offset != IEEE80211_HT_PARAM_CHA_SEC_BELOW) | ||
587 | iwl_conf->supported_chan_width = 0; | ||
588 | |||
589 | iwl_conf->sm_ps = (u8)((ht_conf->cap & IEEE80211_HT_CAP_SM_PS) >> 2); | ||
590 | |||
591 | memcpy(&iwl_conf->mcs, &ht_conf->mcs, 16); | ||
592 | |||
593 | iwl_conf->tx_chan_width = iwl_conf->supported_chan_width != 0; | ||
594 | iwl_conf->ht_protection = | ||
595 | bss_conf->ht.operation_mode & IEEE80211_HT_OP_MODE_PROTECTION; | ||
596 | iwl_conf->non_GF_STA_present = | ||
597 | !!(bss_conf->ht.operation_mode & IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT); | ||
598 | |||
599 | rcu_read_unlock(); | ||
600 | |||
601 | IWL_DEBUG_MAC80211(priv, "leave\n"); | ||
602 | } | ||
603 | |||
604 | #define MAX_UCODE_BEACON_INTERVAL 4096 | 522 | #define MAX_UCODE_BEACON_INTERVAL 4096 |
605 | 523 | ||
606 | static u16 iwl_adjust_beacon_interval(u16 beacon_val) | 524 | static u16 iwl_adjust_beacon_interval(u16 beacon_val) |
@@ -636,7 +554,8 @@ static void iwl_setup_rxon_timing(struct iwl_priv *priv) | |||
636 | beacon_int = iwl_adjust_beacon_interval(priv->beacon_int); | 554 | beacon_int = iwl_adjust_beacon_interval(priv->beacon_int); |
637 | priv->rxon_timing.atim_window = 0; | 555 | priv->rxon_timing.atim_window = 0; |
638 | } else { | 556 | } else { |
639 | beacon_int = iwl_adjust_beacon_interval(conf->beacon_int); | 557 | beacon_int = iwl_adjust_beacon_interval( |
558 | priv->vif->bss_conf.beacon_int); | ||
640 | 559 | ||
641 | /* TODO: we need to get atim_window from upper stack | 560 | /* TODO: we need to get atim_window from upper stack |
642 | * for now we set to 0 */ | 561 | * for now we set to 0 */ |
@@ -657,23 +576,6 @@ static void iwl_setup_rxon_timing(struct iwl_priv *priv) | |||
657 | le16_to_cpu(priv->rxon_timing.atim_window)); | 576 | le16_to_cpu(priv->rxon_timing.atim_window)); |
658 | } | 577 | } |
659 | 578 | ||
660 | static int iwl_set_mode(struct iwl_priv *priv, int mode) | ||
661 | { | ||
662 | iwl_connection_init_rx_config(priv, mode); | ||
663 | iwl_set_rxon_chain(priv); | ||
664 | memcpy(priv->staging_rxon.node_addr, priv->mac_addr, ETH_ALEN); | ||
665 | |||
666 | iwl_clear_stations_table(priv); | ||
667 | |||
668 | /* dont commit rxon if rf-kill is on*/ | ||
669 | if (!iwl_is_ready_rf(priv)) | ||
670 | return -EAGAIN; | ||
671 | |||
672 | iwl_commit_rxon(priv); | ||
673 | |||
674 | return 0; | ||
675 | } | ||
676 | |||
677 | /****************************************************************************** | 579 | /****************************************************************************** |
678 | * | 580 | * |
679 | * Generic RX handler implementations | 581 | * Generic RX handler implementations |
@@ -795,6 +697,7 @@ static void iwl_rx_card_state_notif(struct iwl_priv *priv, | |||
795 | struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; | 697 | struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; |
796 | u32 flags = le32_to_cpu(pkt->u.card_state_notif.flags); | 698 | u32 flags = le32_to_cpu(pkt->u.card_state_notif.flags); |
797 | unsigned long status = priv->status; | 699 | unsigned long status = priv->status; |
700 | unsigned long reg_flags; | ||
798 | 701 | ||
799 | IWL_DEBUG_RF_KILL(priv, "Card state received: HW:%s SW:%s\n", | 702 | IWL_DEBUG_RF_KILL(priv, "Card state received: HW:%s SW:%s\n", |
800 | (flags & HW_CARD_DISABLED) ? "Kill" : "On", | 703 | (flags & HW_CARD_DISABLED) ? "Kill" : "On", |
@@ -806,32 +709,25 @@ static void iwl_rx_card_state_notif(struct iwl_priv *priv, | |||
806 | iwl_write32(priv, CSR_UCODE_DRV_GP1_SET, | 709 | iwl_write32(priv, CSR_UCODE_DRV_GP1_SET, |
807 | CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED); | 710 | CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED); |
808 | 711 | ||
809 | if (!iwl_grab_nic_access(priv)) { | 712 | iwl_write_direct32(priv, HBUS_TARG_MBX_C, |
810 | iwl_write_direct32( | 713 | HBUS_TARG_MBX_C_REG_BIT_CMD_BLOCKED); |
811 | priv, HBUS_TARG_MBX_C, | ||
812 | HBUS_TARG_MBX_C_REG_BIT_CMD_BLOCKED); | ||
813 | |||
814 | iwl_release_nic_access(priv); | ||
815 | } | ||
816 | 714 | ||
817 | if (!(flags & RXON_CARD_DISABLED)) { | 715 | if (!(flags & RXON_CARD_DISABLED)) { |
818 | iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, | 716 | iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, |
819 | CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED); | 717 | CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED); |
820 | if (!iwl_grab_nic_access(priv)) { | 718 | iwl_write_direct32(priv, HBUS_TARG_MBX_C, |
821 | iwl_write_direct32( | ||
822 | priv, HBUS_TARG_MBX_C, | ||
823 | HBUS_TARG_MBX_C_REG_BIT_CMD_BLOCKED); | 719 | HBUS_TARG_MBX_C_REG_BIT_CMD_BLOCKED); |
824 | 720 | ||
825 | iwl_release_nic_access(priv); | ||
826 | } | ||
827 | } | 721 | } |
828 | 722 | ||
829 | if (flags & RF_CARD_DISABLED) { | 723 | if (flags & RF_CARD_DISABLED) { |
830 | iwl_write32(priv, CSR_UCODE_DRV_GP1_SET, | 724 | iwl_write32(priv, CSR_UCODE_DRV_GP1_SET, |
831 | CSR_UCODE_DRV_GP1_REG_BIT_CT_KILL_EXIT); | 725 | CSR_UCODE_DRV_GP1_REG_BIT_CT_KILL_EXIT); |
832 | iwl_read32(priv, CSR_UCODE_DRV_GP1); | 726 | iwl_read32(priv, CSR_UCODE_DRV_GP1); |
727 | spin_lock_irqsave(&priv->reg_lock, reg_flags); | ||
833 | if (!iwl_grab_nic_access(priv)) | 728 | if (!iwl_grab_nic_access(priv)) |
834 | iwl_release_nic_access(priv); | 729 | iwl_release_nic_access(priv); |
730 | spin_unlock_irqrestore(&priv->reg_lock, reg_flags); | ||
835 | } | 731 | } |
836 | } | 732 | } |
837 | 733 | ||
@@ -841,33 +737,19 @@ static void iwl_rx_card_state_notif(struct iwl_priv *priv, | |||
841 | clear_bit(STATUS_RF_KILL_HW, &priv->status); | 737 | clear_bit(STATUS_RF_KILL_HW, &priv->status); |
842 | 738 | ||
843 | 739 | ||
844 | if (flags & SW_CARD_DISABLED) | ||
845 | set_bit(STATUS_RF_KILL_SW, &priv->status); | ||
846 | else | ||
847 | clear_bit(STATUS_RF_KILL_SW, &priv->status); | ||
848 | |||
849 | if (!(flags & RXON_CARD_DISABLED)) | 740 | if (!(flags & RXON_CARD_DISABLED)) |
850 | iwl_scan_cancel(priv); | 741 | iwl_scan_cancel(priv); |
851 | 742 | ||
852 | if ((test_bit(STATUS_RF_KILL_HW, &status) != | 743 | if ((test_bit(STATUS_RF_KILL_HW, &status) != |
853 | test_bit(STATUS_RF_KILL_HW, &priv->status)) || | 744 | test_bit(STATUS_RF_KILL_HW, &priv->status))) |
854 | (test_bit(STATUS_RF_KILL_SW, &status) != | 745 | wiphy_rfkill_set_hw_state(priv->hw->wiphy, |
855 | test_bit(STATUS_RF_KILL_SW, &priv->status))) | 746 | test_bit(STATUS_RF_KILL_HW, &priv->status)); |
856 | queue_work(priv->workqueue, &priv->rf_kill); | ||
857 | else | 747 | else |
858 | wake_up_interruptible(&priv->wait_command_queue); | 748 | wake_up_interruptible(&priv->wait_command_queue); |
859 | } | 749 | } |
860 | 750 | ||
861 | int iwl_set_pwr_src(struct iwl_priv *priv, enum iwl_pwr_src src) | 751 | int iwl_set_pwr_src(struct iwl_priv *priv, enum iwl_pwr_src src) |
862 | { | 752 | { |
863 | int ret; | ||
864 | unsigned long flags; | ||
865 | |||
866 | spin_lock_irqsave(&priv->lock, flags); | ||
867 | ret = iwl_grab_nic_access(priv); | ||
868 | if (ret) | ||
869 | goto err; | ||
870 | |||
871 | if (src == IWL_PWR_SRC_VAUX) { | 753 | if (src == IWL_PWR_SRC_VAUX) { |
872 | if (pci_pme_capable(priv->pci_dev, PCI_D3cold)) | 754 | if (pci_pme_capable(priv->pci_dev, PCI_D3cold)) |
873 | iwl_set_bits_mask_prph(priv, APMG_PS_CTRL_REG, | 755 | iwl_set_bits_mask_prph(priv, APMG_PS_CTRL_REG, |
@@ -879,10 +761,7 @@ int iwl_set_pwr_src(struct iwl_priv *priv, enum iwl_pwr_src src) | |||
879 | ~APMG_PS_CTRL_MSK_PWR_SRC); | 761 | ~APMG_PS_CTRL_MSK_PWR_SRC); |
880 | } | 762 | } |
881 | 763 | ||
882 | iwl_release_nic_access(priv); | 764 | return 0; |
883 | err: | ||
884 | spin_unlock_irqrestore(&priv->lock, flags); | ||
885 | return ret; | ||
886 | } | 765 | } |
887 | 766 | ||
888 | /** | 767 | /** |
@@ -946,6 +825,7 @@ void iwl_rx_handle(struct iwl_priv *priv) | |||
946 | unsigned long flags; | 825 | unsigned long flags; |
947 | u8 fill_rx = 0; | 826 | u8 fill_rx = 0; |
948 | u32 count = 8; | 827 | u32 count = 8; |
828 | int total_empty; | ||
949 | 829 | ||
950 | /* uCode's read index (stored in shared DRAM) indicates the last Rx | 830 | /* uCode's read index (stored in shared DRAM) indicates the last Rx |
951 | * buffer that the driver may process (last buffer filled by ucode). */ | 831 | * buffer that the driver may process (last buffer filled by ucode). */ |
@@ -956,7 +836,12 @@ void iwl_rx_handle(struct iwl_priv *priv) | |||
956 | if (i == r) | 836 | if (i == r) |
957 | IWL_DEBUG_RX(priv, "r = %d, i = %d\n", r, i); | 837 | IWL_DEBUG_RX(priv, "r = %d, i = %d\n", r, i); |
958 | 838 | ||
959 | if (iwl_rx_queue_space(rxq) > (RX_QUEUE_SIZE / 2)) | 839 | /* calculate total frames need to be restock after handling RX */ |
840 | total_empty = r - priv->rxq.write_actual; | ||
841 | if (total_empty < 0) | ||
842 | total_empty += RX_QUEUE_SIZE; | ||
843 | |||
844 | if (total_empty > (RX_QUEUE_SIZE / 2)) | ||
960 | fill_rx = 1; | 845 | fill_rx = 1; |
961 | 846 | ||
962 | while (i != r) { | 847 | while (i != r) { |
@@ -995,6 +880,7 @@ void iwl_rx_handle(struct iwl_priv *priv) | |||
995 | IWL_DEBUG_RX(priv, "r = %d, i = %d, %s, 0x%02x\n", r, | 880 | IWL_DEBUG_RX(priv, "r = %d, i = %d, %s, 0x%02x\n", r, |
996 | i, get_cmd_string(pkt->hdr.cmd), pkt->hdr.cmd); | 881 | i, get_cmd_string(pkt->hdr.cmd), pkt->hdr.cmd); |
997 | priv->rx_handlers[pkt->hdr.cmd] (priv, rxb); | 882 | priv->rx_handlers[pkt->hdr.cmd] (priv, rxb); |
883 | priv->isr_stats.rx_handlers[pkt->hdr.cmd]++; | ||
998 | } else { | 884 | } else { |
999 | /* No handling needed */ | 885 | /* No handling needed */ |
1000 | IWL_DEBUG_RX(priv, | 886 | IWL_DEBUG_RX(priv, |
@@ -1032,7 +918,7 @@ void iwl_rx_handle(struct iwl_priv *priv) | |||
1032 | count++; | 918 | count++; |
1033 | if (count >= 8) { | 919 | if (count >= 8) { |
1034 | priv->rxq.read = i; | 920 | priv->rxq.read = i; |
1035 | iwl_rx_queue_restock(priv); | 921 | iwl_rx_replenish_now(priv); |
1036 | count = 0; | 922 | count = 0; |
1037 | } | 923 | } |
1038 | } | 924 | } |
@@ -1040,7 +926,10 @@ void iwl_rx_handle(struct iwl_priv *priv) | |||
1040 | 926 | ||
1041 | /* Backtrack one entry */ | 927 | /* Backtrack one entry */ |
1042 | priv->rxq.read = i; | 928 | priv->rxq.read = i; |
1043 | iwl_rx_queue_restock(priv); | 929 | if (fill_rx) |
930 | iwl_rx_replenish_now(priv); | ||
931 | else | ||
932 | iwl_rx_queue_restock(priv); | ||
1044 | } | 933 | } |
1045 | 934 | ||
1046 | /* call this function to flush any scheduled tasklet */ | 935 | /* call this function to flush any scheduled tasklet */ |
@@ -1051,24 +940,7 @@ static inline void iwl_synchronize_irq(struct iwl_priv *priv) | |||
1051 | tasklet_kill(&priv->irq_tasklet); | 940 | tasklet_kill(&priv->irq_tasklet); |
1052 | } | 941 | } |
1053 | 942 | ||
1054 | static void iwl_error_recovery(struct iwl_priv *priv) | 943 | static void iwl_irq_tasklet_legacy(struct iwl_priv *priv) |
1055 | { | ||
1056 | unsigned long flags; | ||
1057 | |||
1058 | memcpy(&priv->staging_rxon, &priv->recovery_rxon, | ||
1059 | sizeof(priv->staging_rxon)); | ||
1060 | priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; | ||
1061 | iwl_commit_rxon(priv); | ||
1062 | |||
1063 | iwl_rxon_add_station(priv, priv->bssid, 1); | ||
1064 | |||
1065 | spin_lock_irqsave(&priv->lock, flags); | ||
1066 | priv->assoc_id = le16_to_cpu(priv->staging_rxon.assoc_id); | ||
1067 | priv->error_recovering = 0; | ||
1068 | spin_unlock_irqrestore(&priv->lock, flags); | ||
1069 | } | ||
1070 | |||
1071 | static void iwl_irq_tasklet(struct iwl_priv *priv) | ||
1072 | { | 944 | { |
1073 | u32 inta, handled = 0; | 945 | u32 inta, handled = 0; |
1074 | u32 inta_fh; | 946 | u32 inta_fh; |
@@ -1116,6 +988,7 @@ static void iwl_irq_tasklet(struct iwl_priv *priv) | |||
1116 | /* Tell the device to stop sending interrupts */ | 988 | /* Tell the device to stop sending interrupts */ |
1117 | iwl_disable_interrupts(priv); | 989 | iwl_disable_interrupts(priv); |
1118 | 990 | ||
991 | priv->isr_stats.hw++; | ||
1119 | iwl_irq_handle_error(priv); | 992 | iwl_irq_handle_error(priv); |
1120 | 993 | ||
1121 | handled |= CSR_INT_BIT_HW_ERR; | 994 | handled |= CSR_INT_BIT_HW_ERR; |
@@ -1128,13 +1001,17 @@ static void iwl_irq_tasklet(struct iwl_priv *priv) | |||
1128 | #ifdef CONFIG_IWLWIFI_DEBUG | 1001 | #ifdef CONFIG_IWLWIFI_DEBUG |
1129 | if (priv->debug_level & (IWL_DL_ISR)) { | 1002 | if (priv->debug_level & (IWL_DL_ISR)) { |
1130 | /* NIC fires this, but we don't use it, redundant with WAKEUP */ | 1003 | /* NIC fires this, but we don't use it, redundant with WAKEUP */ |
1131 | if (inta & CSR_INT_BIT_SCD) | 1004 | if (inta & CSR_INT_BIT_SCD) { |
1132 | IWL_DEBUG_ISR(priv, "Scheduler finished to transmit " | 1005 | IWL_DEBUG_ISR(priv, "Scheduler finished to transmit " |
1133 | "the frame/frames.\n"); | 1006 | "the frame/frames.\n"); |
1007 | priv->isr_stats.sch++; | ||
1008 | } | ||
1134 | 1009 | ||
1135 | /* Alive notification via Rx interrupt will do the real work */ | 1010 | /* Alive notification via Rx interrupt will do the real work */ |
1136 | if (inta & CSR_INT_BIT_ALIVE) | 1011 | if (inta & CSR_INT_BIT_ALIVE) { |
1137 | IWL_DEBUG_ISR(priv, "Alive interrupt\n"); | 1012 | IWL_DEBUG_ISR(priv, "Alive interrupt\n"); |
1013 | priv->isr_stats.alive++; | ||
1014 | } | ||
1138 | } | 1015 | } |
1139 | #endif | 1016 | #endif |
1140 | /* Safely ignore these bits for debug checks below */ | 1017 | /* Safely ignore these bits for debug checks below */ |
@@ -1150,6 +1027,8 @@ static void iwl_irq_tasklet(struct iwl_priv *priv) | |||
1150 | IWL_DEBUG_RF_KILL(priv, "RF_KILL bit toggled to %s.\n", | 1027 | IWL_DEBUG_RF_KILL(priv, "RF_KILL bit toggled to %s.\n", |
1151 | hw_rf_kill ? "disable radio" : "enable radio"); | 1028 | hw_rf_kill ? "disable radio" : "enable radio"); |
1152 | 1029 | ||
1030 | priv->isr_stats.rfkill++; | ||
1031 | |||
1153 | /* driver only loads ucode once setting the interface up. | 1032 | /* driver only loads ucode once setting the interface up. |
1154 | * the driver allows loading the ucode even if the radio | 1033 | * the driver allows loading the ucode even if the radio |
1155 | * is killed. Hence update the killswitch state here. The | 1034 | * is killed. Hence update the killswitch state here. The |
@@ -1160,7 +1039,7 @@ static void iwl_irq_tasklet(struct iwl_priv *priv) | |||
1160 | set_bit(STATUS_RF_KILL_HW, &priv->status); | 1039 | set_bit(STATUS_RF_KILL_HW, &priv->status); |
1161 | else | 1040 | else |
1162 | clear_bit(STATUS_RF_KILL_HW, &priv->status); | 1041 | clear_bit(STATUS_RF_KILL_HW, &priv->status); |
1163 | queue_work(priv->workqueue, &priv->rf_kill); | 1042 | wiphy_rfkill_set_hw_state(priv->hw->wiphy, hw_rf_kill); |
1164 | } | 1043 | } |
1165 | 1044 | ||
1166 | handled |= CSR_INT_BIT_RF_KILL; | 1045 | handled |= CSR_INT_BIT_RF_KILL; |
@@ -1169,6 +1048,7 @@ static void iwl_irq_tasklet(struct iwl_priv *priv) | |||
1169 | /* Chip got too hot and stopped itself */ | 1048 | /* Chip got too hot and stopped itself */ |
1170 | if (inta & CSR_INT_BIT_CT_KILL) { | 1049 | if (inta & CSR_INT_BIT_CT_KILL) { |
1171 | IWL_ERR(priv, "Microcode CT kill error detected.\n"); | 1050 | IWL_ERR(priv, "Microcode CT kill error detected.\n"); |
1051 | priv->isr_stats.ctkill++; | ||
1172 | handled |= CSR_INT_BIT_CT_KILL; | 1052 | handled |= CSR_INT_BIT_CT_KILL; |
1173 | } | 1053 | } |
1174 | 1054 | ||
@@ -1176,6 +1056,8 @@ static void iwl_irq_tasklet(struct iwl_priv *priv) | |||
1176 | if (inta & CSR_INT_BIT_SW_ERR) { | 1056 | if (inta & CSR_INT_BIT_SW_ERR) { |
1177 | IWL_ERR(priv, "Microcode SW error detected. " | 1057 | IWL_ERR(priv, "Microcode SW error detected. " |
1178 | " Restarting 0x%X.\n", inta); | 1058 | " Restarting 0x%X.\n", inta); |
1059 | priv->isr_stats.sw++; | ||
1060 | priv->isr_stats.sw_err = inta; | ||
1179 | iwl_irq_handle_error(priv); | 1061 | iwl_irq_handle_error(priv); |
1180 | handled |= CSR_INT_BIT_SW_ERR; | 1062 | handled |= CSR_INT_BIT_SW_ERR; |
1181 | } | 1063 | } |
@@ -1191,6 +1073,8 @@ static void iwl_irq_tasklet(struct iwl_priv *priv) | |||
1191 | iwl_txq_update_write_ptr(priv, &priv->txq[4]); | 1073 | iwl_txq_update_write_ptr(priv, &priv->txq[4]); |
1192 | iwl_txq_update_write_ptr(priv, &priv->txq[5]); | 1074 | iwl_txq_update_write_ptr(priv, &priv->txq[5]); |
1193 | 1075 | ||
1076 | priv->isr_stats.wakeup++; | ||
1077 | |||
1194 | handled |= CSR_INT_BIT_WAKEUP; | 1078 | handled |= CSR_INT_BIT_WAKEUP; |
1195 | } | 1079 | } |
1196 | 1080 | ||
@@ -1199,23 +1083,27 @@ static void iwl_irq_tasklet(struct iwl_priv *priv) | |||
1199 | * notifications from uCode come through here*/ | 1083 | * notifications from uCode come through here*/ |
1200 | if (inta & (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX)) { | 1084 | if (inta & (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX)) { |
1201 | iwl_rx_handle(priv); | 1085 | iwl_rx_handle(priv); |
1086 | priv->isr_stats.rx++; | ||
1202 | handled |= (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX); | 1087 | handled |= (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX); |
1203 | } | 1088 | } |
1204 | 1089 | ||
1205 | if (inta & CSR_INT_BIT_FH_TX) { | 1090 | if (inta & CSR_INT_BIT_FH_TX) { |
1206 | IWL_DEBUG_ISR(priv, "Tx interrupt\n"); | 1091 | IWL_DEBUG_ISR(priv, "Tx interrupt\n"); |
1092 | priv->isr_stats.tx++; | ||
1207 | handled |= CSR_INT_BIT_FH_TX; | 1093 | handled |= CSR_INT_BIT_FH_TX; |
1208 | /* FH finished to write, send event */ | 1094 | /* FH finished to write, send event */ |
1209 | priv->ucode_write_complete = 1; | 1095 | priv->ucode_write_complete = 1; |
1210 | wake_up_interruptible(&priv->wait_command_queue); | 1096 | wake_up_interruptible(&priv->wait_command_queue); |
1211 | } | 1097 | } |
1212 | 1098 | ||
1213 | if (inta & ~handled) | 1099 | if (inta & ~handled) { |
1214 | IWL_ERR(priv, "Unhandled INTA bits 0x%08x\n", inta & ~handled); | 1100 | IWL_ERR(priv, "Unhandled INTA bits 0x%08x\n", inta & ~handled); |
1101 | priv->isr_stats.unhandled++; | ||
1102 | } | ||
1215 | 1103 | ||
1216 | if (inta & ~CSR_INI_SET_MASK) { | 1104 | if (inta & ~(priv->inta_mask)) { |
1217 | IWL_WARN(priv, "Disabled INTA bits 0x%08x were pending\n", | 1105 | IWL_WARN(priv, "Disabled INTA bits 0x%08x were pending\n", |
1218 | inta & ~CSR_INI_SET_MASK); | 1106 | inta & ~priv->inta_mask); |
1219 | IWL_WARN(priv, " with FH_INT = 0x%08x\n", inta_fh); | 1107 | IWL_WARN(priv, " with FH_INT = 0x%08x\n", inta_fh); |
1220 | } | 1108 | } |
1221 | 1109 | ||
@@ -1236,6 +1124,200 @@ static void iwl_irq_tasklet(struct iwl_priv *priv) | |||
1236 | spin_unlock_irqrestore(&priv->lock, flags); | 1124 | spin_unlock_irqrestore(&priv->lock, flags); |
1237 | } | 1125 | } |
1238 | 1126 | ||
1127 | /* tasklet for iwlagn interrupt */ | ||
1128 | static void iwl_irq_tasklet(struct iwl_priv *priv) | ||
1129 | { | ||
1130 | u32 inta = 0; | ||
1131 | u32 handled = 0; | ||
1132 | unsigned long flags; | ||
1133 | #ifdef CONFIG_IWLWIFI_DEBUG | ||
1134 | u32 inta_mask; | ||
1135 | #endif | ||
1136 | |||
1137 | spin_lock_irqsave(&priv->lock, flags); | ||
1138 | |||
1139 | /* Ack/clear/reset pending uCode interrupts. | ||
1140 | * Note: Some bits in CSR_INT are "OR" of bits in CSR_FH_INT_STATUS, | ||
1141 | */ | ||
1142 | iwl_write32(priv, CSR_INT, priv->inta); | ||
1143 | |||
1144 | inta = priv->inta; | ||
1145 | |||
1146 | #ifdef CONFIG_IWLWIFI_DEBUG | ||
1147 | if (priv->debug_level & IWL_DL_ISR) { | ||
1148 | /* just for debug */ | ||
1149 | inta_mask = iwl_read32(priv, CSR_INT_MASK); | ||
1150 | IWL_DEBUG_ISR(priv, "inta 0x%08x, enabled 0x%08x\n ", | ||
1151 | inta, inta_mask); | ||
1152 | } | ||
1153 | #endif | ||
1154 | /* saved interrupt in inta variable now we can reset priv->inta */ | ||
1155 | priv->inta = 0; | ||
1156 | |||
1157 | /* Now service all interrupt bits discovered above. */ | ||
1158 | if (inta & CSR_INT_BIT_HW_ERR) { | ||
1159 | IWL_ERR(priv, "Microcode HW error detected. Restarting.\n"); | ||
1160 | |||
1161 | /* Tell the device to stop sending interrupts */ | ||
1162 | iwl_disable_interrupts(priv); | ||
1163 | |||
1164 | priv->isr_stats.hw++; | ||
1165 | iwl_irq_handle_error(priv); | ||
1166 | |||
1167 | handled |= CSR_INT_BIT_HW_ERR; | ||
1168 | |||
1169 | spin_unlock_irqrestore(&priv->lock, flags); | ||
1170 | |||
1171 | return; | ||
1172 | } | ||
1173 | |||
1174 | #ifdef CONFIG_IWLWIFI_DEBUG | ||
1175 | if (priv->debug_level & (IWL_DL_ISR)) { | ||
1176 | /* NIC fires this, but we don't use it, redundant with WAKEUP */ | ||
1177 | if (inta & CSR_INT_BIT_SCD) { | ||
1178 | IWL_DEBUG_ISR(priv, "Scheduler finished to transmit " | ||
1179 | "the frame/frames.\n"); | ||
1180 | priv->isr_stats.sch++; | ||
1181 | } | ||
1182 | |||
1183 | /* Alive notification via Rx interrupt will do the real work */ | ||
1184 | if (inta & CSR_INT_BIT_ALIVE) { | ||
1185 | IWL_DEBUG_ISR(priv, "Alive interrupt\n"); | ||
1186 | priv->isr_stats.alive++; | ||
1187 | } | ||
1188 | } | ||
1189 | #endif | ||
1190 | /* Safely ignore these bits for debug checks below */ | ||
1191 | inta &= ~(CSR_INT_BIT_SCD | CSR_INT_BIT_ALIVE); | ||
1192 | |||
1193 | /* HW RF KILL switch toggled */ | ||
1194 | if (inta & CSR_INT_BIT_RF_KILL) { | ||
1195 | int hw_rf_kill = 0; | ||
1196 | if (!(iwl_read32(priv, CSR_GP_CNTRL) & | ||
1197 | CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW)) | ||
1198 | hw_rf_kill = 1; | ||
1199 | |||
1200 | IWL_DEBUG_RF_KILL(priv, "RF_KILL bit toggled to %s.\n", | ||
1201 | hw_rf_kill ? "disable radio" : "enable radio"); | ||
1202 | |||
1203 | priv->isr_stats.rfkill++; | ||
1204 | |||
1205 | /* driver only loads ucode once setting the interface up. | ||
1206 | * the driver allows loading the ucode even if the radio | ||
1207 | * is killed. Hence update the killswitch state here. The | ||
1208 | * rfkill handler will care about restarting if needed. | ||
1209 | */ | ||
1210 | if (!test_bit(STATUS_ALIVE, &priv->status)) { | ||
1211 | if (hw_rf_kill) | ||
1212 | set_bit(STATUS_RF_KILL_HW, &priv->status); | ||
1213 | else | ||
1214 | clear_bit(STATUS_RF_KILL_HW, &priv->status); | ||
1215 | wiphy_rfkill_set_hw_state(priv->hw->wiphy, hw_rf_kill); | ||
1216 | } | ||
1217 | |||
1218 | handled |= CSR_INT_BIT_RF_KILL; | ||
1219 | } | ||
1220 | |||
1221 | /* Chip got too hot and stopped itself */ | ||
1222 | if (inta & CSR_INT_BIT_CT_KILL) { | ||
1223 | IWL_ERR(priv, "Microcode CT kill error detected.\n"); | ||
1224 | priv->isr_stats.ctkill++; | ||
1225 | handled |= CSR_INT_BIT_CT_KILL; | ||
1226 | } | ||
1227 | |||
1228 | /* Error detected by uCode */ | ||
1229 | if (inta & CSR_INT_BIT_SW_ERR) { | ||
1230 | IWL_ERR(priv, "Microcode SW error detected. " | ||
1231 | " Restarting 0x%X.\n", inta); | ||
1232 | priv->isr_stats.sw++; | ||
1233 | priv->isr_stats.sw_err = inta; | ||
1234 | iwl_irq_handle_error(priv); | ||
1235 | handled |= CSR_INT_BIT_SW_ERR; | ||
1236 | } | ||
1237 | |||
1238 | /* uCode wakes up after power-down sleep */ | ||
1239 | if (inta & CSR_INT_BIT_WAKEUP) { | ||
1240 | IWL_DEBUG_ISR(priv, "Wakeup interrupt\n"); | ||
1241 | iwl_rx_queue_update_write_ptr(priv, &priv->rxq); | ||
1242 | iwl_txq_update_write_ptr(priv, &priv->txq[0]); | ||
1243 | iwl_txq_update_write_ptr(priv, &priv->txq[1]); | ||
1244 | iwl_txq_update_write_ptr(priv, &priv->txq[2]); | ||
1245 | iwl_txq_update_write_ptr(priv, &priv->txq[3]); | ||
1246 | iwl_txq_update_write_ptr(priv, &priv->txq[4]); | ||
1247 | iwl_txq_update_write_ptr(priv, &priv->txq[5]); | ||
1248 | |||
1249 | priv->isr_stats.wakeup++; | ||
1250 | |||
1251 | handled |= CSR_INT_BIT_WAKEUP; | ||
1252 | } | ||
1253 | |||
1254 | /* All uCode command responses, including Tx command responses, | ||
1255 | * Rx "responses" (frame-received notification), and other | ||
1256 | * notifications from uCode come through here*/ | ||
1257 | if (inta & (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX | | ||
1258 | CSR_INT_BIT_RX_PERIODIC)) { | ||
1259 | IWL_DEBUG_ISR(priv, "Rx interrupt\n"); | ||
1260 | if (inta & (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX)) { | ||
1261 | handled |= (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX); | ||
1262 | iwl_write32(priv, CSR_FH_INT_STATUS, | ||
1263 | CSR49_FH_INT_RX_MASK); | ||
1264 | } | ||
1265 | if (inta & CSR_INT_BIT_RX_PERIODIC) { | ||
1266 | handled |= CSR_INT_BIT_RX_PERIODIC; | ||
1267 | iwl_write32(priv, CSR_INT, CSR_INT_BIT_RX_PERIODIC); | ||
1268 | } | ||
1269 | /* Sending RX interrupt require many steps to be done in the | ||
1270 | * the device: | ||
1271 | * 1- write interrupt to current index in ICT table. | ||
1272 | * 2- dma RX frame. | ||
1273 | * 3- update RX shared data to indicate last write index. | ||
1274 | * 4- send interrupt. | ||
1275 | * This could lead to RX race, driver could receive RX interrupt | ||
1276 | * but the shared data changes does not reflect this. | ||
1277 | * this could lead to RX race, RX periodic will solve this race | ||
1278 | */ | ||
1279 | iwl_write32(priv, CSR_INT_PERIODIC_REG, | ||
1280 | CSR_INT_PERIODIC_DIS); | ||
1281 | iwl_rx_handle(priv); | ||
1282 | /* Only set RX periodic if real RX is received. */ | ||
1283 | if (inta & (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX)) | ||
1284 | iwl_write32(priv, CSR_INT_PERIODIC_REG, | ||
1285 | CSR_INT_PERIODIC_ENA); | ||
1286 | |||
1287 | priv->isr_stats.rx++; | ||
1288 | } | ||
1289 | |||
1290 | if (inta & CSR_INT_BIT_FH_TX) { | ||
1291 | iwl_write32(priv, CSR_FH_INT_STATUS, CSR49_FH_INT_TX_MASK); | ||
1292 | IWL_DEBUG_ISR(priv, "Tx interrupt\n"); | ||
1293 | priv->isr_stats.tx++; | ||
1294 | handled |= CSR_INT_BIT_FH_TX; | ||
1295 | /* FH finished to write, send event */ | ||
1296 | priv->ucode_write_complete = 1; | ||
1297 | wake_up_interruptible(&priv->wait_command_queue); | ||
1298 | } | ||
1299 | |||
1300 | if (inta & ~handled) { | ||
1301 | IWL_ERR(priv, "Unhandled INTA bits 0x%08x\n", inta & ~handled); | ||
1302 | priv->isr_stats.unhandled++; | ||
1303 | } | ||
1304 | |||
1305 | if (inta & ~(priv->inta_mask)) { | ||
1306 | IWL_WARN(priv, "Disabled INTA bits 0x%08x were pending\n", | ||
1307 | inta & ~priv->inta_mask); | ||
1308 | } | ||
1309 | |||
1310 | |||
1311 | /* Re-enable all interrupts */ | ||
1312 | /* only Re-enable if diabled by irq */ | ||
1313 | if (test_bit(STATUS_INT_ENABLED, &priv->status)) | ||
1314 | iwl_enable_interrupts(priv); | ||
1315 | |||
1316 | spin_unlock_irqrestore(&priv->lock, flags); | ||
1317 | |||
1318 | } | ||
1319 | |||
1320 | |||
1239 | /****************************************************************************** | 1321 | /****************************************************************************** |
1240 | * | 1322 | * |
1241 | * uCode download functions | 1323 | * uCode download functions |
@@ -1501,10 +1583,6 @@ static int iwl_read_ucode(struct iwl_priv *priv) | |||
1501 | return ret; | 1583 | return ret; |
1502 | } | 1584 | } |
1503 | 1585 | ||
1504 | /* temporary */ | ||
1505 | static int iwl_mac_beacon_update(struct ieee80211_hw *hw, | ||
1506 | struct sk_buff *skb); | ||
1507 | |||
1508 | /** | 1586 | /** |
1509 | * iwl_alive_start - called after REPLY_ALIVE notification received | 1587 | * iwl_alive_start - called after REPLY_ALIVE notification received |
1510 | * from protocol/runtime uCode (initialization uCode's | 1588 | * from protocol/runtime uCode (initialization uCode's |
@@ -1561,7 +1639,10 @@ static void iwl_alive_start(struct iwl_priv *priv) | |||
1561 | } else { | 1639 | } else { |
1562 | /* Initialize our rx_config data */ | 1640 | /* Initialize our rx_config data */ |
1563 | iwl_connection_init_rx_config(priv, priv->iw_mode); | 1641 | iwl_connection_init_rx_config(priv, priv->iw_mode); |
1564 | iwl_set_rxon_chain(priv); | 1642 | |
1643 | if (priv->cfg->ops->hcmd->set_rxon_chain) | ||
1644 | priv->cfg->ops->hcmd->set_rxon_chain(priv); | ||
1645 | |||
1565 | memcpy(priv->staging_rxon.node_addr, priv->mac_addr, ETH_ALEN); | 1646 | memcpy(priv->staging_rxon.node_addr, priv->mac_addr, ETH_ALEN); |
1566 | } | 1647 | } |
1567 | 1648 | ||
@@ -1571,7 +1652,7 @@ static void iwl_alive_start(struct iwl_priv *priv) | |||
1571 | iwl_reset_run_time_calib(priv); | 1652 | iwl_reset_run_time_calib(priv); |
1572 | 1653 | ||
1573 | /* Configure the adapter for unassociated operation */ | 1654 | /* Configure the adapter for unassociated operation */ |
1574 | iwl_commit_rxon(priv); | 1655 | iwlcore_commit_rxon(priv); |
1575 | 1656 | ||
1576 | /* At this point, the NIC is initialized and operational */ | 1657 | /* At this point, the NIC is initialized and operational */ |
1577 | iwl_rf_kill_ct_config(priv); | 1658 | iwl_rf_kill_ct_config(priv); |
@@ -1582,9 +1663,6 @@ static void iwl_alive_start(struct iwl_priv *priv) | |||
1582 | set_bit(STATUS_READY, &priv->status); | 1663 | set_bit(STATUS_READY, &priv->status); |
1583 | wake_up_interruptible(&priv->wait_command_queue); | 1664 | wake_up_interruptible(&priv->wait_command_queue); |
1584 | 1665 | ||
1585 | if (priv->error_recovering) | ||
1586 | iwl_error_recovery(priv); | ||
1587 | |||
1588 | iwl_power_update_mode(priv, 1); | 1666 | iwl_power_update_mode(priv, 1); |
1589 | 1667 | ||
1590 | /* reassociate for ADHOC mode */ | 1668 | /* reassociate for ADHOC mode */ |
@@ -1642,36 +1720,30 @@ static void __iwl_down(struct iwl_priv *priv) | |||
1642 | ieee80211_stop_queues(priv->hw); | 1720 | ieee80211_stop_queues(priv->hw); |
1643 | 1721 | ||
1644 | /* If we have not previously called iwl_init() then | 1722 | /* If we have not previously called iwl_init() then |
1645 | * clear all bits but the RF Kill and SUSPEND bits and return */ | 1723 | * clear all bits but the RF Kill bit and return */ |
1646 | if (!iwl_is_init(priv)) { | 1724 | if (!iwl_is_init(priv)) { |
1647 | priv->status = test_bit(STATUS_RF_KILL_HW, &priv->status) << | 1725 | priv->status = test_bit(STATUS_RF_KILL_HW, &priv->status) << |
1648 | STATUS_RF_KILL_HW | | 1726 | STATUS_RF_KILL_HW | |
1649 | test_bit(STATUS_RF_KILL_SW, &priv->status) << | ||
1650 | STATUS_RF_KILL_SW | | ||
1651 | test_bit(STATUS_GEO_CONFIGURED, &priv->status) << | 1727 | test_bit(STATUS_GEO_CONFIGURED, &priv->status) << |
1652 | STATUS_GEO_CONFIGURED | | 1728 | STATUS_GEO_CONFIGURED | |
1653 | test_bit(STATUS_IN_SUSPEND, &priv->status) << | ||
1654 | STATUS_IN_SUSPEND | | ||
1655 | test_bit(STATUS_EXIT_PENDING, &priv->status) << | 1729 | test_bit(STATUS_EXIT_PENDING, &priv->status) << |
1656 | STATUS_EXIT_PENDING; | 1730 | STATUS_EXIT_PENDING; |
1657 | goto exit; | 1731 | goto exit; |
1658 | } | 1732 | } |
1659 | 1733 | ||
1660 | /* ...otherwise clear out all the status bits but the RF Kill and | 1734 | /* ...otherwise clear out all the status bits but the RF Kill |
1661 | * SUSPEND bits and continue taking the NIC down. */ | 1735 | * bit and continue taking the NIC down. */ |
1662 | priv->status &= test_bit(STATUS_RF_KILL_HW, &priv->status) << | 1736 | priv->status &= test_bit(STATUS_RF_KILL_HW, &priv->status) << |
1663 | STATUS_RF_KILL_HW | | 1737 | STATUS_RF_KILL_HW | |
1664 | test_bit(STATUS_RF_KILL_SW, &priv->status) << | ||
1665 | STATUS_RF_KILL_SW | | ||
1666 | test_bit(STATUS_GEO_CONFIGURED, &priv->status) << | 1738 | test_bit(STATUS_GEO_CONFIGURED, &priv->status) << |
1667 | STATUS_GEO_CONFIGURED | | 1739 | STATUS_GEO_CONFIGURED | |
1668 | test_bit(STATUS_IN_SUSPEND, &priv->status) << | ||
1669 | STATUS_IN_SUSPEND | | ||
1670 | test_bit(STATUS_FW_ERROR, &priv->status) << | 1740 | test_bit(STATUS_FW_ERROR, &priv->status) << |
1671 | STATUS_FW_ERROR | | 1741 | STATUS_FW_ERROR | |
1672 | test_bit(STATUS_EXIT_PENDING, &priv->status) << | 1742 | test_bit(STATUS_EXIT_PENDING, &priv->status) << |
1673 | STATUS_EXIT_PENDING; | 1743 | STATUS_EXIT_PENDING; |
1674 | 1744 | ||
1745 | /* device going down, Stop using ICT table */ | ||
1746 | iwl_disable_ict(priv); | ||
1675 | spin_lock_irqsave(&priv->lock, flags); | 1747 | spin_lock_irqsave(&priv->lock, flags); |
1676 | iwl_clear_bit(priv, CSR_GP_CNTRL, | 1748 | iwl_clear_bit(priv, CSR_GP_CNTRL, |
1677 | CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); | 1749 | CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); |
@@ -1680,18 +1752,13 @@ static void __iwl_down(struct iwl_priv *priv) | |||
1680 | iwl_txq_ctx_stop(priv); | 1752 | iwl_txq_ctx_stop(priv); |
1681 | iwl_rxq_stop(priv); | 1753 | iwl_rxq_stop(priv); |
1682 | 1754 | ||
1683 | spin_lock_irqsave(&priv->lock, flags); | 1755 | iwl_write_prph(priv, APMG_CLK_DIS_REG, |
1684 | if (!iwl_grab_nic_access(priv)) { | 1756 | APMG_CLK_VAL_DMA_CLK_RQT); |
1685 | iwl_write_prph(priv, APMG_CLK_DIS_REG, | ||
1686 | APMG_CLK_VAL_DMA_CLK_RQT); | ||
1687 | iwl_release_nic_access(priv); | ||
1688 | } | ||
1689 | spin_unlock_irqrestore(&priv->lock, flags); | ||
1690 | 1757 | ||
1691 | udelay(5); | 1758 | udelay(5); |
1692 | 1759 | ||
1693 | /* FIXME: apm_ops.suspend(priv) */ | 1760 | /* FIXME: apm_ops.suspend(priv) */ |
1694 | if (exit_pending || test_bit(STATUS_IN_SUSPEND, &priv->status)) | 1761 | if (exit_pending) |
1695 | priv->cfg->ops->lib->apm_ops.stop(priv); | 1762 | priv->cfg->ops->lib->apm_ops.stop(priv); |
1696 | else | 1763 | else |
1697 | priv->cfg->ops->lib->apm_ops.reset(priv); | 1764 | priv->cfg->ops->lib->apm_ops.reset(priv); |
@@ -1715,6 +1782,49 @@ static void iwl_down(struct iwl_priv *priv) | |||
1715 | iwl_cancel_deferred_work(priv); | 1782 | iwl_cancel_deferred_work(priv); |
1716 | } | 1783 | } |
1717 | 1784 | ||
1785 | #define HW_READY_TIMEOUT (50) | ||
1786 | |||
1787 | static int iwl_set_hw_ready(struct iwl_priv *priv) | ||
1788 | { | ||
1789 | int ret = 0; | ||
1790 | |||
1791 | iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG, | ||
1792 | CSR_HW_IF_CONFIG_REG_BIT_NIC_READY); | ||
1793 | |||
1794 | /* See if we got it */ | ||
1795 | ret = iwl_poll_bit(priv, CSR_HW_IF_CONFIG_REG, | ||
1796 | CSR_HW_IF_CONFIG_REG_BIT_NIC_READY, | ||
1797 | CSR_HW_IF_CONFIG_REG_BIT_NIC_READY, | ||
1798 | HW_READY_TIMEOUT); | ||
1799 | if (ret != -ETIMEDOUT) | ||
1800 | priv->hw_ready = true; | ||
1801 | else | ||
1802 | priv->hw_ready = false; | ||
1803 | |||
1804 | IWL_DEBUG_INFO(priv, "hardware %s\n", | ||
1805 | (priv->hw_ready == 1) ? "ready" : "not ready"); | ||
1806 | return ret; | ||
1807 | } | ||
1808 | |||
1809 | static int iwl_prepare_card_hw(struct iwl_priv *priv) | ||
1810 | { | ||
1811 | int ret = 0; | ||
1812 | |||
1813 | IWL_DEBUG_INFO(priv, "iwl_prepare_card_hw enter \n"); | ||
1814 | |||
1815 | iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG, | ||
1816 | CSR_HW_IF_CONFIG_REG_PREPARE); | ||
1817 | |||
1818 | ret = iwl_poll_bit(priv, CSR_HW_IF_CONFIG_REG, | ||
1819 | ~CSR_HW_IF_CONFIG_REG_BIT_NIC_PREPARE_DONE, | ||
1820 | CSR_HW_IF_CONFIG_REG_BIT_NIC_PREPARE_DONE, 150000); | ||
1821 | |||
1822 | if (ret != -ETIMEDOUT) | ||
1823 | iwl_set_hw_ready(priv); | ||
1824 | |||
1825 | return ret; | ||
1826 | } | ||
1827 | |||
1718 | #define MAX_HW_RESTARTS 5 | 1828 | #define MAX_HW_RESTARTS 5 |
1719 | 1829 | ||
1720 | static int __iwl_up(struct iwl_priv *priv) | 1830 | static int __iwl_up(struct iwl_priv *priv) |
@@ -1732,6 +1842,13 @@ static int __iwl_up(struct iwl_priv *priv) | |||
1732 | return -EIO; | 1842 | return -EIO; |
1733 | } | 1843 | } |
1734 | 1844 | ||
1845 | iwl_prepare_card_hw(priv); | ||
1846 | |||
1847 | if (!priv->hw_ready) { | ||
1848 | IWL_WARN(priv, "Exit HW not ready\n"); | ||
1849 | return -EIO; | ||
1850 | } | ||
1851 | |||
1735 | /* If platform's RF_KILL switch is NOT set to KILL */ | 1852 | /* If platform's RF_KILL switch is NOT set to KILL */ |
1736 | if (iwl_read32(priv, CSR_GP_CNTRL) & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW) | 1853 | if (iwl_read32(priv, CSR_GP_CNTRL) & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW) |
1737 | clear_bit(STATUS_RF_KILL_HW, &priv->status); | 1854 | clear_bit(STATUS_RF_KILL_HW, &priv->status); |
@@ -1739,9 +1856,10 @@ static int __iwl_up(struct iwl_priv *priv) | |||
1739 | set_bit(STATUS_RF_KILL_HW, &priv->status); | 1856 | set_bit(STATUS_RF_KILL_HW, &priv->status); |
1740 | 1857 | ||
1741 | if (iwl_is_rfkill(priv)) { | 1858 | if (iwl_is_rfkill(priv)) { |
1859 | wiphy_rfkill_set_hw_state(priv->hw->wiphy, true); | ||
1860 | |||
1742 | iwl_enable_interrupts(priv); | 1861 | iwl_enable_interrupts(priv); |
1743 | IWL_WARN(priv, "Radio disabled by %s RF Kill switch\n", | 1862 | IWL_WARN(priv, "Radio disabled by HW RF Kill switch\n"); |
1744 | test_bit(STATUS_RF_KILL_HW, &priv->status) ? "HW" : "SW"); | ||
1745 | return 0; | 1863 | return 0; |
1746 | } | 1864 | } |
1747 | 1865 | ||
@@ -1787,9 +1905,6 @@ static int __iwl_up(struct iwl_priv *priv) | |||
1787 | continue; | 1905 | continue; |
1788 | } | 1906 | } |
1789 | 1907 | ||
1790 | /* Clear out the uCode error bit if it is set */ | ||
1791 | clear_bit(STATUS_FW_ERROR, &priv->status); | ||
1792 | |||
1793 | /* start card; "initialize" will load runtime ucode */ | 1908 | /* start card; "initialize" will load runtime ucode */ |
1794 | iwl_nic_start(priv); | 1909 | iwl_nic_start(priv); |
1795 | 1910 | ||
@@ -1836,6 +1951,9 @@ static void iwl_bg_alive_start(struct work_struct *data) | |||
1836 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) | 1951 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) |
1837 | return; | 1952 | return; |
1838 | 1953 | ||
1954 | /* enable dram interrupt */ | ||
1955 | iwl_reset_ict(priv); | ||
1956 | |||
1839 | mutex_lock(&priv->mutex); | 1957 | mutex_lock(&priv->mutex); |
1840 | iwl_alive_start(priv); | 1958 | iwl_alive_start(priv); |
1841 | mutex_unlock(&priv->mutex); | 1959 | mutex_unlock(&priv->mutex); |
@@ -1874,7 +1992,6 @@ static void iwl_bg_up(struct work_struct *data) | |||
1874 | mutex_lock(&priv->mutex); | 1992 | mutex_lock(&priv->mutex); |
1875 | __iwl_up(priv); | 1993 | __iwl_up(priv); |
1876 | mutex_unlock(&priv->mutex); | 1994 | mutex_unlock(&priv->mutex); |
1877 | iwl_rfkill_set_hw_state(priv); | ||
1878 | } | 1995 | } |
1879 | 1996 | ||
1880 | static void iwl_bg_restart(struct work_struct *data) | 1997 | static void iwl_bg_restart(struct work_struct *data) |
@@ -1884,8 +2001,17 @@ static void iwl_bg_restart(struct work_struct *data) | |||
1884 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) | 2001 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) |
1885 | return; | 2002 | return; |
1886 | 2003 | ||
1887 | iwl_down(priv); | 2004 | if (test_and_clear_bit(STATUS_FW_ERROR, &priv->status)) { |
1888 | queue_work(priv->workqueue, &priv->up); | 2005 | mutex_lock(&priv->mutex); |
2006 | priv->vif = NULL; | ||
2007 | priv->is_open = 0; | ||
2008 | mutex_unlock(&priv->mutex); | ||
2009 | iwl_down(priv); | ||
2010 | ieee80211_restart_hw(priv->hw); | ||
2011 | } else { | ||
2012 | iwl_down(priv); | ||
2013 | queue_work(priv->workqueue, &priv->up); | ||
2014 | } | ||
1889 | } | 2015 | } |
1890 | 2016 | ||
1891 | static void iwl_bg_rx_replenish(struct work_struct *data) | 2017 | static void iwl_bg_rx_replenish(struct work_struct *data) |
@@ -1903,7 +2029,7 @@ static void iwl_bg_rx_replenish(struct work_struct *data) | |||
1903 | 2029 | ||
1904 | #define IWL_DELAY_NEXT_SCAN (HZ*2) | 2030 | #define IWL_DELAY_NEXT_SCAN (HZ*2) |
1905 | 2031 | ||
1906 | static void iwl_post_associate(struct iwl_priv *priv) | 2032 | void iwl_post_associate(struct iwl_priv *priv) |
1907 | { | 2033 | { |
1908 | struct ieee80211_conf *conf = NULL; | 2034 | struct ieee80211_conf *conf = NULL; |
1909 | int ret = 0; | 2035 | int ret = 0; |
@@ -1925,13 +2051,12 @@ static void iwl_post_associate(struct iwl_priv *priv) | |||
1925 | if (!priv->vif || !priv->is_open) | 2051 | if (!priv->vif || !priv->is_open) |
1926 | return; | 2052 | return; |
1927 | 2053 | ||
1928 | iwl_power_cancel_timeout(priv); | ||
1929 | iwl_scan_cancel_timeout(priv, 200); | 2054 | iwl_scan_cancel_timeout(priv, 200); |
1930 | 2055 | ||
1931 | conf = ieee80211_get_hw_conf(priv->hw); | 2056 | conf = ieee80211_get_hw_conf(priv->hw); |
1932 | 2057 | ||
1933 | priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; | 2058 | priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; |
1934 | iwl_commit_rxon(priv); | 2059 | iwlcore_commit_rxon(priv); |
1935 | 2060 | ||
1936 | iwl_setup_rxon_timing(priv); | 2061 | iwl_setup_rxon_timing(priv); |
1937 | ret = iwl_send_cmd_pdu(priv, REPLY_RXON_TIMING, | 2062 | ret = iwl_send_cmd_pdu(priv, REPLY_RXON_TIMING, |
@@ -1944,7 +2069,9 @@ static void iwl_post_associate(struct iwl_priv *priv) | |||
1944 | 2069 | ||
1945 | iwl_set_rxon_ht(priv, &priv->current_ht_config); | 2070 | iwl_set_rxon_ht(priv, &priv->current_ht_config); |
1946 | 2071 | ||
1947 | iwl_set_rxon_chain(priv); | 2072 | if (priv->cfg->ops->hcmd->set_rxon_chain) |
2073 | priv->cfg->ops->hcmd->set_rxon_chain(priv); | ||
2074 | |||
1948 | priv->staging_rxon.assoc_id = cpu_to_le16(priv->assoc_id); | 2075 | priv->staging_rxon.assoc_id = cpu_to_le16(priv->assoc_id); |
1949 | 2076 | ||
1950 | IWL_DEBUG_ASSOC(priv, "assoc id %d beacon interval %d\n", | 2077 | IWL_DEBUG_ASSOC(priv, "assoc id %d beacon interval %d\n", |
@@ -1966,7 +2093,7 @@ static void iwl_post_associate(struct iwl_priv *priv) | |||
1966 | 2093 | ||
1967 | } | 2094 | } |
1968 | 2095 | ||
1969 | iwl_commit_rxon(priv); | 2096 | iwlcore_commit_rxon(priv); |
1970 | 2097 | ||
1971 | switch (priv->iw_mode) { | 2098 | switch (priv->iw_mode) { |
1972 | case NL80211_IFTYPE_STATION: | 2099 | case NL80211_IFTYPE_STATION: |
@@ -1999,7 +2126,7 @@ static void iwl_post_associate(struct iwl_priv *priv) | |||
1999 | * If chain noise has already been run, then we need to enable | 2126 | * If chain noise has already been run, then we need to enable |
2000 | * power management here */ | 2127 | * power management here */ |
2001 | if (priv->chain_noise_data.state == IWL_CHAIN_NOISE_DONE) | 2128 | if (priv->chain_noise_data.state == IWL_CHAIN_NOISE_DONE) |
2002 | iwl_power_enable_management(priv); | 2129 | iwl_power_update_mode(priv, 0); |
2003 | 2130 | ||
2004 | /* Enable Rx differential gain and sensitivity calibrations */ | 2131 | /* Enable Rx differential gain and sensitivity calibrations */ |
2005 | iwl_chain_noise_reset(priv); | 2132 | iwl_chain_noise_reset(priv); |
@@ -2042,8 +2169,6 @@ static int iwl_mac_start(struct ieee80211_hw *hw) | |||
2042 | 2169 | ||
2043 | mutex_unlock(&priv->mutex); | 2170 | mutex_unlock(&priv->mutex); |
2044 | 2171 | ||
2045 | iwl_rfkill_set_hw_state(priv); | ||
2046 | |||
2047 | if (ret) | 2172 | if (ret) |
2048 | return ret; | 2173 | return ret; |
2049 | 2174 | ||
@@ -2052,9 +2177,6 @@ static int iwl_mac_start(struct ieee80211_hw *hw) | |||
2052 | 2177 | ||
2053 | IWL_DEBUG_INFO(priv, "Start UP work done.\n"); | 2178 | IWL_DEBUG_INFO(priv, "Start UP work done.\n"); |
2054 | 2179 | ||
2055 | if (test_bit(STATUS_IN_SUSPEND, &priv->status)) | ||
2056 | return 0; | ||
2057 | |||
2058 | /* Wait for START_ALIVE from Run Time ucode. Otherwise callbacks from | 2180 | /* Wait for START_ALIVE from Run Time ucode. Otherwise callbacks from |
2059 | * mac80211 will not be run successfully. */ | 2181 | * mac80211 will not be run successfully. */ |
2060 | ret = wait_event_interruptible_timeout(priv->wait_command_queue, | 2182 | ret = wait_event_interruptible_timeout(priv->wait_command_queue, |
@@ -2080,10 +2202,8 @@ static void iwl_mac_stop(struct ieee80211_hw *hw) | |||
2080 | 2202 | ||
2081 | IWL_DEBUG_MAC80211(priv, "enter\n"); | 2203 | IWL_DEBUG_MAC80211(priv, "enter\n"); |
2082 | 2204 | ||
2083 | if (!priv->is_open) { | 2205 | if (!priv->is_open) |
2084 | IWL_DEBUG_MAC80211(priv, "leave - skip\n"); | ||
2085 | return; | 2206 | return; |
2086 | } | ||
2087 | 2207 | ||
2088 | priv->is_open = 0; | 2208 | priv->is_open = 0; |
2089 | 2209 | ||
@@ -2123,175 +2243,7 @@ static int iwl_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
2123 | return NETDEV_TX_OK; | 2243 | return NETDEV_TX_OK; |
2124 | } | 2244 | } |
2125 | 2245 | ||
2126 | static int iwl_mac_add_interface(struct ieee80211_hw *hw, | 2246 | void iwl_config_ap(struct iwl_priv *priv) |
2127 | struct ieee80211_if_init_conf *conf) | ||
2128 | { | ||
2129 | struct iwl_priv *priv = hw->priv; | ||
2130 | unsigned long flags; | ||
2131 | |||
2132 | IWL_DEBUG_MAC80211(priv, "enter: type %d\n", conf->type); | ||
2133 | |||
2134 | if (priv->vif) { | ||
2135 | IWL_DEBUG_MAC80211(priv, "leave - vif != NULL\n"); | ||
2136 | return -EOPNOTSUPP; | ||
2137 | } | ||
2138 | |||
2139 | spin_lock_irqsave(&priv->lock, flags); | ||
2140 | priv->vif = conf->vif; | ||
2141 | priv->iw_mode = conf->type; | ||
2142 | |||
2143 | spin_unlock_irqrestore(&priv->lock, flags); | ||
2144 | |||
2145 | mutex_lock(&priv->mutex); | ||
2146 | |||
2147 | if (conf->mac_addr) { | ||
2148 | IWL_DEBUG_MAC80211(priv, "Set %pM\n", conf->mac_addr); | ||
2149 | memcpy(priv->mac_addr, conf->mac_addr, ETH_ALEN); | ||
2150 | } | ||
2151 | |||
2152 | if (iwl_set_mode(priv, conf->type) == -EAGAIN) | ||
2153 | /* we are not ready, will run again when ready */ | ||
2154 | set_bit(STATUS_MODE_PENDING, &priv->status); | ||
2155 | |||
2156 | mutex_unlock(&priv->mutex); | ||
2157 | |||
2158 | IWL_DEBUG_MAC80211(priv, "leave\n"); | ||
2159 | return 0; | ||
2160 | } | ||
2161 | |||
2162 | /** | ||
2163 | * iwl_mac_config - mac80211 config callback | ||
2164 | * | ||
2165 | * We ignore conf->flags & IEEE80211_CONF_SHORT_SLOT_TIME since it seems to | ||
2166 | * be set inappropriately and the driver currently sets the hardware up to | ||
2167 | * use it whenever needed. | ||
2168 | */ | ||
2169 | static int iwl_mac_config(struct ieee80211_hw *hw, u32 changed) | ||
2170 | { | ||
2171 | struct iwl_priv *priv = hw->priv; | ||
2172 | const struct iwl_channel_info *ch_info; | ||
2173 | struct ieee80211_conf *conf = &hw->conf; | ||
2174 | unsigned long flags = 0; | ||
2175 | int ret = 0; | ||
2176 | u16 ch; | ||
2177 | int scan_active = 0; | ||
2178 | |||
2179 | mutex_lock(&priv->mutex); | ||
2180 | IWL_DEBUG_MAC80211(priv, "enter to channel %d changed 0x%X\n", | ||
2181 | conf->channel->hw_value, changed); | ||
2182 | |||
2183 | if (unlikely(!priv->cfg->mod_params->disable_hw_scan && | ||
2184 | test_bit(STATUS_SCANNING, &priv->status))) { | ||
2185 | scan_active = 1; | ||
2186 | IWL_DEBUG_MAC80211(priv, "leave - scanning\n"); | ||
2187 | } | ||
2188 | |||
2189 | |||
2190 | /* during scanning mac80211 will delay channel setting until | ||
2191 | * scan finish with changed = 0 | ||
2192 | */ | ||
2193 | if (!changed || (changed & IEEE80211_CONF_CHANGE_CHANNEL)) { | ||
2194 | if (scan_active) | ||
2195 | goto set_ch_out; | ||
2196 | |||
2197 | ch = ieee80211_frequency_to_channel(conf->channel->center_freq); | ||
2198 | ch_info = iwl_get_channel_info(priv, conf->channel->band, ch); | ||
2199 | if (!is_channel_valid(ch_info)) { | ||
2200 | IWL_DEBUG_MAC80211(priv, "leave - invalid channel\n"); | ||
2201 | ret = -EINVAL; | ||
2202 | goto set_ch_out; | ||
2203 | } | ||
2204 | |||
2205 | if (priv->iw_mode == NL80211_IFTYPE_ADHOC && | ||
2206 | !is_channel_ibss(ch_info)) { | ||
2207 | IWL_ERR(priv, "channel %d in band %d not " | ||
2208 | "IBSS channel\n", | ||
2209 | conf->channel->hw_value, conf->channel->band); | ||
2210 | ret = -EINVAL; | ||
2211 | goto set_ch_out; | ||
2212 | } | ||
2213 | |||
2214 | priv->current_ht_config.is_ht = conf_is_ht(conf); | ||
2215 | |||
2216 | spin_lock_irqsave(&priv->lock, flags); | ||
2217 | |||
2218 | |||
2219 | /* if we are switching from ht to 2.4 clear flags | ||
2220 | * from any ht related info since 2.4 does not | ||
2221 | * support ht */ | ||
2222 | if ((le16_to_cpu(priv->staging_rxon.channel) != ch)) | ||
2223 | priv->staging_rxon.flags = 0; | ||
2224 | |||
2225 | iwl_set_rxon_channel(priv, conf->channel); | ||
2226 | |||
2227 | iwl_set_flags_for_band(priv, conf->channel->band); | ||
2228 | spin_unlock_irqrestore(&priv->lock, flags); | ||
2229 | set_ch_out: | ||
2230 | /* The list of supported rates and rate mask can be different | ||
2231 | * for each band; since the band may have changed, reset | ||
2232 | * the rate mask to what mac80211 lists */ | ||
2233 | iwl_set_rate(priv); | ||
2234 | } | ||
2235 | |||
2236 | if (changed & IEEE80211_CONF_CHANGE_PS) { | ||
2237 | if (conf->flags & IEEE80211_CONF_PS) | ||
2238 | ret = iwl_power_set_user_mode(priv, IWL_POWER_INDEX_3); | ||
2239 | else | ||
2240 | ret = iwl_power_set_user_mode(priv, IWL_POWER_MODE_CAM); | ||
2241 | if (ret) | ||
2242 | IWL_DEBUG_MAC80211(priv, "Error setting power level\n"); | ||
2243 | |||
2244 | } | ||
2245 | |||
2246 | if (changed & IEEE80211_CONF_CHANGE_POWER) { | ||
2247 | IWL_DEBUG_MAC80211(priv, "TX Power old=%d new=%d\n", | ||
2248 | priv->tx_power_user_lmt, conf->power_level); | ||
2249 | |||
2250 | iwl_set_tx_power(priv, conf->power_level, false); | ||
2251 | } | ||
2252 | |||
2253 | /* call to ensure that 4965 rx_chain is set properly in monitor mode */ | ||
2254 | iwl_set_rxon_chain(priv); | ||
2255 | |||
2256 | if (changed & IEEE80211_CONF_CHANGE_RADIO_ENABLED) { | ||
2257 | if (conf->radio_enabled && | ||
2258 | iwl_radio_kill_sw_enable_radio(priv)) { | ||
2259 | IWL_DEBUG_MAC80211(priv, "leave - RF-KILL - " | ||
2260 | "waiting for uCode\n"); | ||
2261 | goto out; | ||
2262 | } | ||
2263 | |||
2264 | if (!conf->radio_enabled) | ||
2265 | iwl_radio_kill_sw_disable_radio(priv); | ||
2266 | } | ||
2267 | |||
2268 | if (!conf->radio_enabled) { | ||
2269 | IWL_DEBUG_MAC80211(priv, "leave - radio disabled\n"); | ||
2270 | goto out; | ||
2271 | } | ||
2272 | |||
2273 | if (!iwl_is_ready(priv)) { | ||
2274 | IWL_DEBUG_MAC80211(priv, "leave - not ready\n"); | ||
2275 | goto out; | ||
2276 | } | ||
2277 | |||
2278 | if (scan_active) | ||
2279 | goto out; | ||
2280 | |||
2281 | if (memcmp(&priv->active_rxon, | ||
2282 | &priv->staging_rxon, sizeof(priv->staging_rxon))) | ||
2283 | iwl_commit_rxon(priv); | ||
2284 | else | ||
2285 | IWL_DEBUG_INFO(priv, "No re-sending same RXON configuration.\n"); | ||
2286 | |||
2287 | |||
2288 | out: | ||
2289 | IWL_DEBUG_MAC80211(priv, "leave\n"); | ||
2290 | mutex_unlock(&priv->mutex); | ||
2291 | return ret; | ||
2292 | } | ||
2293 | |||
2294 | static void iwl_config_ap(struct iwl_priv *priv) | ||
2295 | { | 2247 | { |
2296 | int ret = 0; | 2248 | int ret = 0; |
2297 | unsigned long flags; | 2249 | unsigned long flags; |
@@ -2304,7 +2256,7 @@ static void iwl_config_ap(struct iwl_priv *priv) | |||
2304 | 2256 | ||
2305 | /* RXON - unassoc (to set timing command) */ | 2257 | /* RXON - unassoc (to set timing command) */ |
2306 | priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; | 2258 | priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; |
2307 | iwl_commit_rxon(priv); | 2259 | iwlcore_commit_rxon(priv); |
2308 | 2260 | ||
2309 | /* RXON Timing */ | 2261 | /* RXON Timing */ |
2310 | iwl_setup_rxon_timing(priv); | 2262 | iwl_setup_rxon_timing(priv); |
@@ -2314,7 +2266,8 @@ static void iwl_config_ap(struct iwl_priv *priv) | |||
2314 | IWL_WARN(priv, "REPLY_RXON_TIMING failed - " | 2266 | IWL_WARN(priv, "REPLY_RXON_TIMING failed - " |
2315 | "Attempting to continue.\n"); | 2267 | "Attempting to continue.\n"); |
2316 | 2268 | ||
2317 | iwl_set_rxon_chain(priv); | 2269 | if (priv->cfg->ops->hcmd->set_rxon_chain) |
2270 | priv->cfg->ops->hcmd->set_rxon_chain(priv); | ||
2318 | 2271 | ||
2319 | /* FIXME: what should be the assoc_id for AP? */ | 2272 | /* FIXME: what should be the assoc_id for AP? */ |
2320 | priv->staging_rxon.assoc_id = cpu_to_le16(priv->assoc_id); | 2273 | priv->staging_rxon.assoc_id = cpu_to_le16(priv->assoc_id); |
@@ -2340,7 +2293,7 @@ static void iwl_config_ap(struct iwl_priv *priv) | |||
2340 | } | 2293 | } |
2341 | /* restore RXON assoc */ | 2294 | /* restore RXON assoc */ |
2342 | priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK; | 2295 | priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK; |
2343 | iwl_commit_rxon(priv); | 2296 | iwlcore_commit_rxon(priv); |
2344 | spin_lock_irqsave(&priv->lock, flags); | 2297 | spin_lock_irqsave(&priv->lock, flags); |
2345 | iwl_activate_qos(priv, 1); | 2298 | iwl_activate_qos(priv, 1); |
2346 | spin_unlock_irqrestore(&priv->lock, flags); | 2299 | spin_unlock_irqrestore(&priv->lock, flags); |
@@ -2353,194 +2306,6 @@ static void iwl_config_ap(struct iwl_priv *priv) | |||
2353 | * clear sta table, add BCAST sta... */ | 2306 | * clear sta table, add BCAST sta... */ |
2354 | } | 2307 | } |
2355 | 2308 | ||
2356 | |||
2357 | static int iwl_mac_config_interface(struct ieee80211_hw *hw, | ||
2358 | struct ieee80211_vif *vif, | ||
2359 | struct ieee80211_if_conf *conf) | ||
2360 | { | ||
2361 | struct iwl_priv *priv = hw->priv; | ||
2362 | int rc; | ||
2363 | |||
2364 | if (conf == NULL) | ||
2365 | return -EIO; | ||
2366 | |||
2367 | if (priv->vif != vif) { | ||
2368 | IWL_DEBUG_MAC80211(priv, "leave - priv->vif != vif\n"); | ||
2369 | return 0; | ||
2370 | } | ||
2371 | |||
2372 | if (priv->iw_mode == NL80211_IFTYPE_ADHOC && | ||
2373 | conf->changed & IEEE80211_IFCC_BEACON) { | ||
2374 | struct sk_buff *beacon = ieee80211_beacon_get(hw, vif); | ||
2375 | if (!beacon) | ||
2376 | return -ENOMEM; | ||
2377 | mutex_lock(&priv->mutex); | ||
2378 | rc = iwl_mac_beacon_update(hw, beacon); | ||
2379 | mutex_unlock(&priv->mutex); | ||
2380 | if (rc) | ||
2381 | return rc; | ||
2382 | } | ||
2383 | |||
2384 | if (!iwl_is_alive(priv)) | ||
2385 | return -EAGAIN; | ||
2386 | |||
2387 | mutex_lock(&priv->mutex); | ||
2388 | |||
2389 | if (conf->bssid) | ||
2390 | IWL_DEBUG_MAC80211(priv, "bssid: %pM\n", conf->bssid); | ||
2391 | |||
2392 | /* | ||
2393 | * very dubious code was here; the probe filtering flag is never set: | ||
2394 | * | ||
2395 | if (unlikely(test_bit(STATUS_SCANNING, &priv->status)) && | ||
2396 | !(priv->hw->flags & IEEE80211_HW_NO_PROBE_FILTERING)) { | ||
2397 | */ | ||
2398 | |||
2399 | if (priv->iw_mode == NL80211_IFTYPE_AP) { | ||
2400 | if (!conf->bssid) { | ||
2401 | conf->bssid = priv->mac_addr; | ||
2402 | memcpy(priv->bssid, priv->mac_addr, ETH_ALEN); | ||
2403 | IWL_DEBUG_MAC80211(priv, "bssid was set to: %pM\n", | ||
2404 | conf->bssid); | ||
2405 | } | ||
2406 | if (priv->ibss_beacon) | ||
2407 | dev_kfree_skb(priv->ibss_beacon); | ||
2408 | |||
2409 | priv->ibss_beacon = ieee80211_beacon_get(hw, vif); | ||
2410 | } | ||
2411 | |||
2412 | if (iwl_is_rfkill(priv)) | ||
2413 | goto done; | ||
2414 | |||
2415 | if (conf->bssid && !is_zero_ether_addr(conf->bssid) && | ||
2416 | !is_multicast_ether_addr(conf->bssid)) { | ||
2417 | /* If there is currently a HW scan going on in the background | ||
2418 | * then we need to cancel it else the RXON below will fail. */ | ||
2419 | if (iwl_scan_cancel_timeout(priv, 100)) { | ||
2420 | IWL_WARN(priv, "Aborted scan still in progress " | ||
2421 | "after 100ms\n"); | ||
2422 | IWL_DEBUG_MAC80211(priv, "leaving - scan abort failed.\n"); | ||
2423 | mutex_unlock(&priv->mutex); | ||
2424 | return -EAGAIN; | ||
2425 | } | ||
2426 | memcpy(priv->staging_rxon.bssid_addr, conf->bssid, ETH_ALEN); | ||
2427 | |||
2428 | /* TODO: Audit driver for usage of these members and see | ||
2429 | * if mac80211 deprecates them (priv->bssid looks like it | ||
2430 | * shouldn't be there, but I haven't scanned the IBSS code | ||
2431 | * to verify) - jpk */ | ||
2432 | memcpy(priv->bssid, conf->bssid, ETH_ALEN); | ||
2433 | |||
2434 | if (priv->iw_mode == NL80211_IFTYPE_AP) | ||
2435 | iwl_config_ap(priv); | ||
2436 | else { | ||
2437 | rc = iwl_commit_rxon(priv); | ||
2438 | if ((priv->iw_mode == NL80211_IFTYPE_STATION) && rc) | ||
2439 | iwl_rxon_add_station( | ||
2440 | priv, priv->active_rxon.bssid_addr, 1); | ||
2441 | } | ||
2442 | |||
2443 | } else { | ||
2444 | iwl_scan_cancel_timeout(priv, 100); | ||
2445 | priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; | ||
2446 | iwl_commit_rxon(priv); | ||
2447 | } | ||
2448 | |||
2449 | done: | ||
2450 | IWL_DEBUG_MAC80211(priv, "leave\n"); | ||
2451 | mutex_unlock(&priv->mutex); | ||
2452 | |||
2453 | return 0; | ||
2454 | } | ||
2455 | |||
2456 | static void iwl_mac_remove_interface(struct ieee80211_hw *hw, | ||
2457 | struct ieee80211_if_init_conf *conf) | ||
2458 | { | ||
2459 | struct iwl_priv *priv = hw->priv; | ||
2460 | |||
2461 | IWL_DEBUG_MAC80211(priv, "enter\n"); | ||
2462 | |||
2463 | mutex_lock(&priv->mutex); | ||
2464 | |||
2465 | if (iwl_is_ready_rf(priv)) { | ||
2466 | iwl_scan_cancel_timeout(priv, 100); | ||
2467 | priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; | ||
2468 | iwl_commit_rxon(priv); | ||
2469 | } | ||
2470 | if (priv->vif == conf->vif) { | ||
2471 | priv->vif = NULL; | ||
2472 | memset(priv->bssid, 0, ETH_ALEN); | ||
2473 | } | ||
2474 | mutex_unlock(&priv->mutex); | ||
2475 | |||
2476 | IWL_DEBUG_MAC80211(priv, "leave\n"); | ||
2477 | |||
2478 | } | ||
2479 | |||
2480 | #define IWL_DELAY_NEXT_SCAN_AFTER_ASSOC (HZ*6) | ||
2481 | static void iwl_bss_info_changed(struct ieee80211_hw *hw, | ||
2482 | struct ieee80211_vif *vif, | ||
2483 | struct ieee80211_bss_conf *bss_conf, | ||
2484 | u32 changes) | ||
2485 | { | ||
2486 | struct iwl_priv *priv = hw->priv; | ||
2487 | |||
2488 | IWL_DEBUG_MAC80211(priv, "changes = 0x%X\n", changes); | ||
2489 | |||
2490 | if (changes & BSS_CHANGED_ERP_PREAMBLE) { | ||
2491 | IWL_DEBUG_MAC80211(priv, "ERP_PREAMBLE %d\n", | ||
2492 | bss_conf->use_short_preamble); | ||
2493 | if (bss_conf->use_short_preamble) | ||
2494 | priv->staging_rxon.flags |= RXON_FLG_SHORT_PREAMBLE_MSK; | ||
2495 | else | ||
2496 | priv->staging_rxon.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK; | ||
2497 | } | ||
2498 | |||
2499 | if (changes & BSS_CHANGED_ERP_CTS_PROT) { | ||
2500 | IWL_DEBUG_MAC80211(priv, "ERP_CTS %d\n", bss_conf->use_cts_prot); | ||
2501 | if (bss_conf->use_cts_prot && (priv->band != IEEE80211_BAND_5GHZ)) | ||
2502 | priv->staging_rxon.flags |= RXON_FLG_TGG_PROTECT_MSK; | ||
2503 | else | ||
2504 | priv->staging_rxon.flags &= ~RXON_FLG_TGG_PROTECT_MSK; | ||
2505 | } | ||
2506 | |||
2507 | if (changes & BSS_CHANGED_HT) { | ||
2508 | iwl_ht_conf(priv, bss_conf); | ||
2509 | iwl_set_rxon_chain(priv); | ||
2510 | } | ||
2511 | |||
2512 | if (changes & BSS_CHANGED_ASSOC) { | ||
2513 | IWL_DEBUG_MAC80211(priv, "ASSOC %d\n", bss_conf->assoc); | ||
2514 | /* This should never happen as this function should | ||
2515 | * never be called from interrupt context. */ | ||
2516 | if (WARN_ON_ONCE(in_interrupt())) | ||
2517 | return; | ||
2518 | if (bss_conf->assoc) { | ||
2519 | priv->assoc_id = bss_conf->aid; | ||
2520 | priv->beacon_int = bss_conf->beacon_int; | ||
2521 | priv->power_data.dtim_period = bss_conf->dtim_period; | ||
2522 | priv->timestamp = bss_conf->timestamp; | ||
2523 | priv->assoc_capability = bss_conf->assoc_capability; | ||
2524 | |||
2525 | /* we have just associated, don't start scan too early | ||
2526 | * leave time for EAPOL exchange to complete | ||
2527 | */ | ||
2528 | priv->next_scan_jiffies = jiffies + | ||
2529 | IWL_DELAY_NEXT_SCAN_AFTER_ASSOC; | ||
2530 | mutex_lock(&priv->mutex); | ||
2531 | iwl_post_associate(priv); | ||
2532 | mutex_unlock(&priv->mutex); | ||
2533 | } else { | ||
2534 | priv->assoc_id = 0; | ||
2535 | IWL_DEBUG_MAC80211(priv, "DISASSOC %d\n", bss_conf->assoc); | ||
2536 | } | ||
2537 | } else if (changes && iwl_is_associated(priv) && priv->assoc_id) { | ||
2538 | IWL_DEBUG_MAC80211(priv, "Associated Changes %d\n", changes); | ||
2539 | iwl_send_rxon_assoc(priv); | ||
2540 | } | ||
2541 | |||
2542 | } | ||
2543 | |||
2544 | static void iwl_mac_update_tkip_key(struct ieee80211_hw *hw, | 2309 | static void iwl_mac_update_tkip_key(struct ieee80211_hw *hw, |
2545 | struct ieee80211_key_conf *keyconf, const u8 *addr, | 2310 | struct ieee80211_key_conf *keyconf, const u8 *addr, |
2546 | u32 iv32, u16 *phase1key) | 2311 | u32 iv32, u16 *phase1key) |
@@ -2623,49 +2388,6 @@ static int iwl_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | |||
2623 | return ret; | 2388 | return ret; |
2624 | } | 2389 | } |
2625 | 2390 | ||
2626 | static int iwl_mac_conf_tx(struct ieee80211_hw *hw, u16 queue, | ||
2627 | const struct ieee80211_tx_queue_params *params) | ||
2628 | { | ||
2629 | struct iwl_priv *priv = hw->priv; | ||
2630 | unsigned long flags; | ||
2631 | int q; | ||
2632 | |||
2633 | IWL_DEBUG_MAC80211(priv, "enter\n"); | ||
2634 | |||
2635 | if (!iwl_is_ready_rf(priv)) { | ||
2636 | IWL_DEBUG_MAC80211(priv, "leave - RF not ready\n"); | ||
2637 | return -EIO; | ||
2638 | } | ||
2639 | |||
2640 | if (queue >= AC_NUM) { | ||
2641 | IWL_DEBUG_MAC80211(priv, "leave - queue >= AC_NUM %d\n", queue); | ||
2642 | return 0; | ||
2643 | } | ||
2644 | |||
2645 | q = AC_NUM - 1 - queue; | ||
2646 | |||
2647 | spin_lock_irqsave(&priv->lock, flags); | ||
2648 | |||
2649 | priv->qos_data.def_qos_parm.ac[q].cw_min = cpu_to_le16(params->cw_min); | ||
2650 | priv->qos_data.def_qos_parm.ac[q].cw_max = cpu_to_le16(params->cw_max); | ||
2651 | priv->qos_data.def_qos_parm.ac[q].aifsn = params->aifs; | ||
2652 | priv->qos_data.def_qos_parm.ac[q].edca_txop = | ||
2653 | cpu_to_le16((params->txop * 32)); | ||
2654 | |||
2655 | priv->qos_data.def_qos_parm.ac[q].reserved1 = 0; | ||
2656 | priv->qos_data.qos_active = 1; | ||
2657 | |||
2658 | if (priv->iw_mode == NL80211_IFTYPE_AP) | ||
2659 | iwl_activate_qos(priv, 1); | ||
2660 | else if (priv->assoc_id && iwl_is_associated(priv)) | ||
2661 | iwl_activate_qos(priv, 0); | ||
2662 | |||
2663 | spin_unlock_irqrestore(&priv->lock, flags); | ||
2664 | |||
2665 | IWL_DEBUG_MAC80211(priv, "leave\n"); | ||
2666 | return 0; | ||
2667 | } | ||
2668 | |||
2669 | static int iwl_mac_ampdu_action(struct ieee80211_hw *hw, | 2391 | static int iwl_mac_ampdu_action(struct ieee80211_hw *hw, |
2670 | enum ieee80211_ampdu_mlme_action action, | 2392 | enum ieee80211_ampdu_mlme_action action, |
2671 | struct ieee80211_sta *sta, u16 tid, u16 *ssn) | 2393 | struct ieee80211_sta *sta, u16 tid, u16 *ssn) |
@@ -2708,41 +2430,6 @@ static int iwl_mac_ampdu_action(struct ieee80211_hw *hw, | |||
2708 | return 0; | 2430 | return 0; |
2709 | } | 2431 | } |
2710 | 2432 | ||
2711 | static int iwl_mac_get_tx_stats(struct ieee80211_hw *hw, | ||
2712 | struct ieee80211_tx_queue_stats *stats) | ||
2713 | { | ||
2714 | struct iwl_priv *priv = hw->priv; | ||
2715 | int i, avail; | ||
2716 | struct iwl_tx_queue *txq; | ||
2717 | struct iwl_queue *q; | ||
2718 | unsigned long flags; | ||
2719 | |||
2720 | IWL_DEBUG_MAC80211(priv, "enter\n"); | ||
2721 | |||
2722 | if (!iwl_is_ready_rf(priv)) { | ||
2723 | IWL_DEBUG_MAC80211(priv, "leave - RF not ready\n"); | ||
2724 | return -EIO; | ||
2725 | } | ||
2726 | |||
2727 | spin_lock_irqsave(&priv->lock, flags); | ||
2728 | |||
2729 | for (i = 0; i < AC_NUM; i++) { | ||
2730 | txq = &priv->txq[i]; | ||
2731 | q = &txq->q; | ||
2732 | avail = iwl_queue_space(q); | ||
2733 | |||
2734 | stats[i].len = q->n_window - avail; | ||
2735 | stats[i].limit = q->n_window - q->high_mark; | ||
2736 | stats[i].count = q->n_window; | ||
2737 | |||
2738 | } | ||
2739 | spin_unlock_irqrestore(&priv->lock, flags); | ||
2740 | |||
2741 | IWL_DEBUG_MAC80211(priv, "leave\n"); | ||
2742 | |||
2743 | return 0; | ||
2744 | } | ||
2745 | |||
2746 | static int iwl_mac_get_stats(struct ieee80211_hw *hw, | 2433 | static int iwl_mac_get_stats(struct ieee80211_hw *hw, |
2747 | struct ieee80211_low_level_stats *stats) | 2434 | struct ieee80211_low_level_stats *stats) |
2748 | { | 2435 | { |
@@ -2755,120 +2442,6 @@ static int iwl_mac_get_stats(struct ieee80211_hw *hw, | |||
2755 | return 0; | 2442 | return 0; |
2756 | } | 2443 | } |
2757 | 2444 | ||
2758 | static void iwl_mac_reset_tsf(struct ieee80211_hw *hw) | ||
2759 | { | ||
2760 | struct iwl_priv *priv = hw->priv; | ||
2761 | unsigned long flags; | ||
2762 | |||
2763 | mutex_lock(&priv->mutex); | ||
2764 | IWL_DEBUG_MAC80211(priv, "enter\n"); | ||
2765 | |||
2766 | spin_lock_irqsave(&priv->lock, flags); | ||
2767 | memset(&priv->current_ht_config, 0, sizeof(struct iwl_ht_info)); | ||
2768 | spin_unlock_irqrestore(&priv->lock, flags); | ||
2769 | |||
2770 | iwl_reset_qos(priv); | ||
2771 | |||
2772 | spin_lock_irqsave(&priv->lock, flags); | ||
2773 | priv->assoc_id = 0; | ||
2774 | priv->assoc_capability = 0; | ||
2775 | priv->assoc_station_added = 0; | ||
2776 | |||
2777 | /* new association get rid of ibss beacon skb */ | ||
2778 | if (priv->ibss_beacon) | ||
2779 | dev_kfree_skb(priv->ibss_beacon); | ||
2780 | |||
2781 | priv->ibss_beacon = NULL; | ||
2782 | |||
2783 | priv->beacon_int = priv->hw->conf.beacon_int; | ||
2784 | priv->timestamp = 0; | ||
2785 | if ((priv->iw_mode == NL80211_IFTYPE_STATION)) | ||
2786 | priv->beacon_int = 0; | ||
2787 | |||
2788 | spin_unlock_irqrestore(&priv->lock, flags); | ||
2789 | |||
2790 | if (!iwl_is_ready_rf(priv)) { | ||
2791 | IWL_DEBUG_MAC80211(priv, "leave - not ready\n"); | ||
2792 | mutex_unlock(&priv->mutex); | ||
2793 | return; | ||
2794 | } | ||
2795 | |||
2796 | /* we are restarting association process | ||
2797 | * clear RXON_FILTER_ASSOC_MSK bit | ||
2798 | */ | ||
2799 | if (priv->iw_mode != NL80211_IFTYPE_AP) { | ||
2800 | iwl_scan_cancel_timeout(priv, 100); | ||
2801 | priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; | ||
2802 | iwl_commit_rxon(priv); | ||
2803 | } | ||
2804 | |||
2805 | iwl_power_update_mode(priv, 0); | ||
2806 | |||
2807 | /* Per mac80211.h: This is only used in IBSS mode... */ | ||
2808 | if (priv->iw_mode != NL80211_IFTYPE_ADHOC) { | ||
2809 | |||
2810 | /* switch to CAM during association period. | ||
2811 | * the ucode will block any association/authentication | ||
2812 | * frome during assiciation period if it can not hear | ||
2813 | * the AP because of PM. the timer enable PM back is | ||
2814 | * association do not complete | ||
2815 | */ | ||
2816 | if (priv->hw->conf.channel->flags & (IEEE80211_CHAN_PASSIVE_SCAN | | ||
2817 | IEEE80211_CHAN_RADAR)) | ||
2818 | iwl_power_disable_management(priv, 3000); | ||
2819 | |||
2820 | IWL_DEBUG_MAC80211(priv, "leave - not in IBSS\n"); | ||
2821 | mutex_unlock(&priv->mutex); | ||
2822 | return; | ||
2823 | } | ||
2824 | |||
2825 | iwl_set_rate(priv); | ||
2826 | |||
2827 | mutex_unlock(&priv->mutex); | ||
2828 | |||
2829 | IWL_DEBUG_MAC80211(priv, "leave\n"); | ||
2830 | } | ||
2831 | |||
2832 | static int iwl_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb) | ||
2833 | { | ||
2834 | struct iwl_priv *priv = hw->priv; | ||
2835 | unsigned long flags; | ||
2836 | __le64 timestamp; | ||
2837 | |||
2838 | IWL_DEBUG_MAC80211(priv, "enter\n"); | ||
2839 | |||
2840 | if (!iwl_is_ready_rf(priv)) { | ||
2841 | IWL_DEBUG_MAC80211(priv, "leave - RF not ready\n"); | ||
2842 | return -EIO; | ||
2843 | } | ||
2844 | |||
2845 | if (priv->iw_mode != NL80211_IFTYPE_ADHOC) { | ||
2846 | IWL_DEBUG_MAC80211(priv, "leave - not IBSS\n"); | ||
2847 | return -EIO; | ||
2848 | } | ||
2849 | |||
2850 | spin_lock_irqsave(&priv->lock, flags); | ||
2851 | |||
2852 | if (priv->ibss_beacon) | ||
2853 | dev_kfree_skb(priv->ibss_beacon); | ||
2854 | |||
2855 | priv->ibss_beacon = skb; | ||
2856 | |||
2857 | priv->assoc_id = 0; | ||
2858 | timestamp = ((struct ieee80211_mgmt *)skb->data)->u.beacon.timestamp; | ||
2859 | priv->timestamp = le64_to_cpu(timestamp); | ||
2860 | |||
2861 | IWL_DEBUG_MAC80211(priv, "leave\n"); | ||
2862 | spin_unlock_irqrestore(&priv->lock, flags); | ||
2863 | |||
2864 | iwl_reset_qos(priv); | ||
2865 | |||
2866 | iwl_post_associate(priv); | ||
2867 | |||
2868 | |||
2869 | return 0; | ||
2870 | } | ||
2871 | |||
2872 | /***************************************************************************** | 2445 | /***************************************************************************** |
2873 | * | 2446 | * |
2874 | * sysfs attributes | 2447 | * sysfs attributes |
@@ -2888,7 +2461,7 @@ static int iwl_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
2888 | static ssize_t show_debug_level(struct device *d, | 2461 | static ssize_t show_debug_level(struct device *d, |
2889 | struct device_attribute *attr, char *buf) | 2462 | struct device_attribute *attr, char *buf) |
2890 | { | 2463 | { |
2891 | struct iwl_priv *priv = d->driver_data; | 2464 | struct iwl_priv *priv = dev_get_drvdata(d); |
2892 | 2465 | ||
2893 | return sprintf(buf, "0x%08X\n", priv->debug_level); | 2466 | return sprintf(buf, "0x%08X\n", priv->debug_level); |
2894 | } | 2467 | } |
@@ -2896,7 +2469,7 @@ static ssize_t store_debug_level(struct device *d, | |||
2896 | struct device_attribute *attr, | 2469 | struct device_attribute *attr, |
2897 | const char *buf, size_t count) | 2470 | const char *buf, size_t count) |
2898 | { | 2471 | { |
2899 | struct iwl_priv *priv = d->driver_data; | 2472 | struct iwl_priv *priv = dev_get_drvdata(d); |
2900 | unsigned long val; | 2473 | unsigned long val; |
2901 | int ret; | 2474 | int ret; |
2902 | 2475 | ||
@@ -2919,7 +2492,7 @@ static DEVICE_ATTR(debug_level, S_IWUSR | S_IRUGO, | |||
2919 | static ssize_t show_version(struct device *d, | 2492 | static ssize_t show_version(struct device *d, |
2920 | struct device_attribute *attr, char *buf) | 2493 | struct device_attribute *attr, char *buf) |
2921 | { | 2494 | { |
2922 | struct iwl_priv *priv = d->driver_data; | 2495 | struct iwl_priv *priv = dev_get_drvdata(d); |
2923 | struct iwl_alive_resp *palive = &priv->card_alive; | 2496 | struct iwl_alive_resp *palive = &priv->card_alive; |
2924 | ssize_t pos = 0; | 2497 | ssize_t pos = 0; |
2925 | u16 eeprom_ver; | 2498 | u16 eeprom_ver; |
@@ -2936,8 +2509,10 @@ static ssize_t show_version(struct device *d, | |||
2936 | 2509 | ||
2937 | if (priv->eeprom) { | 2510 | if (priv->eeprom) { |
2938 | eeprom_ver = iwl_eeprom_query16(priv, EEPROM_VERSION); | 2511 | eeprom_ver = iwl_eeprom_query16(priv, EEPROM_VERSION); |
2939 | pos += sprintf(buf + pos, "EEPROM version: 0x%x\n", | 2512 | pos += sprintf(buf + pos, "NVM Type: %s, version: 0x%x\n", |
2940 | eeprom_ver); | 2513 | (priv->nvm_device_type == NVM_DEVICE_TYPE_OTP) |
2514 | ? "OTP" : "EEPROM", eeprom_ver); | ||
2515 | |||
2941 | } else { | 2516 | } else { |
2942 | pos += sprintf(buf + pos, "EEPROM not initialzed\n"); | 2517 | pos += sprintf(buf + pos, "EEPROM not initialzed\n"); |
2943 | } | 2518 | } |
@@ -2950,7 +2525,7 @@ static DEVICE_ATTR(version, S_IWUSR | S_IRUGO, show_version, NULL); | |||
2950 | static ssize_t show_temperature(struct device *d, | 2525 | static ssize_t show_temperature(struct device *d, |
2951 | struct device_attribute *attr, char *buf) | 2526 | struct device_attribute *attr, char *buf) |
2952 | { | 2527 | { |
2953 | struct iwl_priv *priv = (struct iwl_priv *)d->driver_data; | 2528 | struct iwl_priv *priv = dev_get_drvdata(d); |
2954 | 2529 | ||
2955 | if (!iwl_is_alive(priv)) | 2530 | if (!iwl_is_alive(priv)) |
2956 | return -EAGAIN; | 2531 | return -EAGAIN; |
@@ -2963,7 +2538,7 @@ static DEVICE_ATTR(temperature, S_IRUGO, show_temperature, NULL); | |||
2963 | static ssize_t show_tx_power(struct device *d, | 2538 | static ssize_t show_tx_power(struct device *d, |
2964 | struct device_attribute *attr, char *buf) | 2539 | struct device_attribute *attr, char *buf) |
2965 | { | 2540 | { |
2966 | struct iwl_priv *priv = (struct iwl_priv *)d->driver_data; | 2541 | struct iwl_priv *priv = dev_get_drvdata(d); |
2967 | 2542 | ||
2968 | if (!iwl_is_ready_rf(priv)) | 2543 | if (!iwl_is_ready_rf(priv)) |
2969 | return sprintf(buf, "off\n"); | 2544 | return sprintf(buf, "off\n"); |
@@ -2975,7 +2550,7 @@ static ssize_t store_tx_power(struct device *d, | |||
2975 | struct device_attribute *attr, | 2550 | struct device_attribute *attr, |
2976 | const char *buf, size_t count) | 2551 | const char *buf, size_t count) |
2977 | { | 2552 | { |
2978 | struct iwl_priv *priv = (struct iwl_priv *)d->driver_data; | 2553 | struct iwl_priv *priv = dev_get_drvdata(d); |
2979 | unsigned long val; | 2554 | unsigned long val; |
2980 | int ret; | 2555 | int ret; |
2981 | 2556 | ||
@@ -2993,7 +2568,7 @@ static DEVICE_ATTR(tx_power, S_IWUSR | S_IRUGO, show_tx_power, store_tx_power); | |||
2993 | static ssize_t show_flags(struct device *d, | 2568 | static ssize_t show_flags(struct device *d, |
2994 | struct device_attribute *attr, char *buf) | 2569 | struct device_attribute *attr, char *buf) |
2995 | { | 2570 | { |
2996 | struct iwl_priv *priv = (struct iwl_priv *)d->driver_data; | 2571 | struct iwl_priv *priv = dev_get_drvdata(d); |
2997 | 2572 | ||
2998 | return sprintf(buf, "0x%04X\n", priv->active_rxon.flags); | 2573 | return sprintf(buf, "0x%04X\n", priv->active_rxon.flags); |
2999 | } | 2574 | } |
@@ -3002,7 +2577,7 @@ static ssize_t store_flags(struct device *d, | |||
3002 | struct device_attribute *attr, | 2577 | struct device_attribute *attr, |
3003 | const char *buf, size_t count) | 2578 | const char *buf, size_t count) |
3004 | { | 2579 | { |
3005 | struct iwl_priv *priv = (struct iwl_priv *)d->driver_data; | 2580 | struct iwl_priv *priv = dev_get_drvdata(d); |
3006 | unsigned long val; | 2581 | unsigned long val; |
3007 | u32 flags; | 2582 | u32 flags; |
3008 | int ret = strict_strtoul(buf, 0, &val); | 2583 | int ret = strict_strtoul(buf, 0, &val); |
@@ -3018,7 +2593,7 @@ static ssize_t store_flags(struct device *d, | |||
3018 | else { | 2593 | else { |
3019 | IWL_DEBUG_INFO(priv, "Commit rxon.flags = 0x%04X\n", flags); | 2594 | IWL_DEBUG_INFO(priv, "Commit rxon.flags = 0x%04X\n", flags); |
3020 | priv->staging_rxon.flags = cpu_to_le32(flags); | 2595 | priv->staging_rxon.flags = cpu_to_le32(flags); |
3021 | iwl_commit_rxon(priv); | 2596 | iwlcore_commit_rxon(priv); |
3022 | } | 2597 | } |
3023 | } | 2598 | } |
3024 | mutex_unlock(&priv->mutex); | 2599 | mutex_unlock(&priv->mutex); |
@@ -3031,7 +2606,7 @@ static DEVICE_ATTR(flags, S_IWUSR | S_IRUGO, show_flags, store_flags); | |||
3031 | static ssize_t show_filter_flags(struct device *d, | 2606 | static ssize_t show_filter_flags(struct device *d, |
3032 | struct device_attribute *attr, char *buf) | 2607 | struct device_attribute *attr, char *buf) |
3033 | { | 2608 | { |
3034 | struct iwl_priv *priv = (struct iwl_priv *)d->driver_data; | 2609 | struct iwl_priv *priv = dev_get_drvdata(d); |
3035 | 2610 | ||
3036 | return sprintf(buf, "0x%04X\n", | 2611 | return sprintf(buf, "0x%04X\n", |
3037 | le32_to_cpu(priv->active_rxon.filter_flags)); | 2612 | le32_to_cpu(priv->active_rxon.filter_flags)); |
@@ -3041,7 +2616,7 @@ static ssize_t store_filter_flags(struct device *d, | |||
3041 | struct device_attribute *attr, | 2616 | struct device_attribute *attr, |
3042 | const char *buf, size_t count) | 2617 | const char *buf, size_t count) |
3043 | { | 2618 | { |
3044 | struct iwl_priv *priv = (struct iwl_priv *)d->driver_data; | 2619 | struct iwl_priv *priv = dev_get_drvdata(d); |
3045 | unsigned long val; | 2620 | unsigned long val; |
3046 | u32 filter_flags; | 2621 | u32 filter_flags; |
3047 | int ret = strict_strtoul(buf, 0, &val); | 2622 | int ret = strict_strtoul(buf, 0, &val); |
@@ -3059,7 +2634,7 @@ static ssize_t store_filter_flags(struct device *d, | |||
3059 | "0x%04X\n", filter_flags); | 2634 | "0x%04X\n", filter_flags); |
3060 | priv->staging_rxon.filter_flags = | 2635 | priv->staging_rxon.filter_flags = |
3061 | cpu_to_le32(filter_flags); | 2636 | cpu_to_le32(filter_flags); |
3062 | iwl_commit_rxon(priv); | 2637 | iwlcore_commit_rxon(priv); |
3063 | } | 2638 | } |
3064 | } | 2639 | } |
3065 | mutex_unlock(&priv->mutex); | 2640 | mutex_unlock(&priv->mutex); |
@@ -3102,32 +2677,37 @@ static ssize_t show_power_level(struct device *d, | |||
3102 | { | 2677 | { |
3103 | struct iwl_priv *priv = dev_get_drvdata(d); | 2678 | struct iwl_priv *priv = dev_get_drvdata(d); |
3104 | int mode = priv->power_data.user_power_setting; | 2679 | int mode = priv->power_data.user_power_setting; |
3105 | int system = priv->power_data.system_power_setting; | ||
3106 | int level = priv->power_data.power_mode; | 2680 | int level = priv->power_data.power_mode; |
3107 | char *p = buf; | 2681 | char *p = buf; |
3108 | 2682 | ||
3109 | switch (system) { | 2683 | p += sprintf(p, "INDEX:%d\t", level); |
3110 | case IWL_POWER_SYS_AUTO: | 2684 | p += sprintf(p, "USER:%d\n", mode); |
3111 | p += sprintf(p, "SYSTEM:auto"); | ||
3112 | break; | ||
3113 | case IWL_POWER_SYS_AC: | ||
3114 | p += sprintf(p, "SYSTEM:ac"); | ||
3115 | break; | ||
3116 | case IWL_POWER_SYS_BATTERY: | ||
3117 | p += sprintf(p, "SYSTEM:battery"); | ||
3118 | break; | ||
3119 | } | ||
3120 | |||
3121 | p += sprintf(p, "\tMODE:%s", (mode < IWL_POWER_AUTO) ? | ||
3122 | "fixed" : "auto"); | ||
3123 | p += sprintf(p, "\tINDEX:%d", level); | ||
3124 | p += sprintf(p, "\n"); | ||
3125 | return p - buf + 1; | 2685 | return p - buf + 1; |
3126 | } | 2686 | } |
3127 | 2687 | ||
3128 | static DEVICE_ATTR(power_level, S_IWUSR | S_IRUSR, show_power_level, | 2688 | static DEVICE_ATTR(power_level, S_IWUSR | S_IRUSR, show_power_level, |
3129 | store_power_level); | 2689 | store_power_level); |
3130 | 2690 | ||
2691 | static ssize_t show_qos(struct device *d, | ||
2692 | struct device_attribute *attr, char *buf) | ||
2693 | { | ||
2694 | struct iwl_priv *priv = dev_get_drvdata(d); | ||
2695 | char *p = buf; | ||
2696 | int q; | ||
2697 | |||
2698 | for (q = 0; q < AC_NUM; q++) { | ||
2699 | p += sprintf(p, "\tcw_min\tcw_max\taifsn\ttxop\n"); | ||
2700 | p += sprintf(p, "AC[%d]\t%u\t%u\t%u\t%u\n", q, | ||
2701 | priv->qos_data.def_qos_parm.ac[q].cw_min, | ||
2702 | priv->qos_data.def_qos_parm.ac[q].cw_max, | ||
2703 | priv->qos_data.def_qos_parm.ac[q].aifsn, | ||
2704 | priv->qos_data.def_qos_parm.ac[q].edca_txop); | ||
2705 | } | ||
2706 | |||
2707 | return p - buf + 1; | ||
2708 | } | ||
2709 | |||
2710 | static DEVICE_ATTR(qos, S_IRUGO, show_qos, NULL); | ||
3131 | 2711 | ||
3132 | static ssize_t show_statistics(struct device *d, | 2712 | static ssize_t show_statistics(struct device *d, |
3133 | struct device_attribute *attr, char *buf) | 2713 | struct device_attribute *attr, char *buf) |
@@ -3183,14 +2763,12 @@ static void iwl_setup_deferred_work(struct iwl_priv *priv) | |||
3183 | INIT_WORK(&priv->up, iwl_bg_up); | 2763 | INIT_WORK(&priv->up, iwl_bg_up); |
3184 | INIT_WORK(&priv->restart, iwl_bg_restart); | 2764 | INIT_WORK(&priv->restart, iwl_bg_restart); |
3185 | INIT_WORK(&priv->rx_replenish, iwl_bg_rx_replenish); | 2765 | INIT_WORK(&priv->rx_replenish, iwl_bg_rx_replenish); |
3186 | INIT_WORK(&priv->rf_kill, iwl_bg_rf_kill); | ||
3187 | INIT_WORK(&priv->beacon_update, iwl_bg_beacon_update); | 2766 | INIT_WORK(&priv->beacon_update, iwl_bg_beacon_update); |
3188 | INIT_WORK(&priv->run_time_calib_work, iwl_bg_run_time_calib_work); | 2767 | INIT_WORK(&priv->run_time_calib_work, iwl_bg_run_time_calib_work); |
3189 | INIT_DELAYED_WORK(&priv->init_alive_start, iwl_bg_init_alive_start); | 2768 | INIT_DELAYED_WORK(&priv->init_alive_start, iwl_bg_init_alive_start); |
3190 | INIT_DELAYED_WORK(&priv->alive_start, iwl_bg_alive_start); | 2769 | INIT_DELAYED_WORK(&priv->alive_start, iwl_bg_alive_start); |
3191 | 2770 | ||
3192 | iwl_setup_scan_deferred_work(priv); | 2771 | iwl_setup_scan_deferred_work(priv); |
3193 | iwl_setup_power_deferred_work(priv); | ||
3194 | 2772 | ||
3195 | if (priv->cfg->ops->lib->setup_deferred_work) | 2773 | if (priv->cfg->ops->lib->setup_deferred_work) |
3196 | priv->cfg->ops->lib->setup_deferred_work(priv); | 2774 | priv->cfg->ops->lib->setup_deferred_work(priv); |
@@ -3199,8 +2777,12 @@ static void iwl_setup_deferred_work(struct iwl_priv *priv) | |||
3199 | priv->statistics_periodic.data = (unsigned long)priv; | 2777 | priv->statistics_periodic.data = (unsigned long)priv; |
3200 | priv->statistics_periodic.function = iwl_bg_statistics_periodic; | 2778 | priv->statistics_periodic.function = iwl_bg_statistics_periodic; |
3201 | 2779 | ||
3202 | tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long)) | 2780 | if (!priv->cfg->use_isr_legacy) |
3203 | iwl_irq_tasklet, (unsigned long)priv); | 2781 | tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long)) |
2782 | iwl_irq_tasklet, (unsigned long)priv); | ||
2783 | else | ||
2784 | tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long)) | ||
2785 | iwl_irq_tasklet_legacy, (unsigned long)priv); | ||
3204 | } | 2786 | } |
3205 | 2787 | ||
3206 | static void iwl_cancel_deferred_work(struct iwl_priv *priv) | 2788 | static void iwl_cancel_deferred_work(struct iwl_priv *priv) |
@@ -3210,7 +2792,6 @@ static void iwl_cancel_deferred_work(struct iwl_priv *priv) | |||
3210 | 2792 | ||
3211 | cancel_delayed_work_sync(&priv->init_alive_start); | 2793 | cancel_delayed_work_sync(&priv->init_alive_start); |
3212 | cancel_delayed_work(&priv->scan_check); | 2794 | cancel_delayed_work(&priv->scan_check); |
3213 | cancel_delayed_work_sync(&priv->set_power_save); | ||
3214 | cancel_delayed_work(&priv->alive_start); | 2795 | cancel_delayed_work(&priv->alive_start); |
3215 | cancel_work_sync(&priv->beacon_update); | 2796 | cancel_work_sync(&priv->beacon_update); |
3216 | del_timer_sync(&priv->statistics_periodic); | 2797 | del_timer_sync(&priv->statistics_periodic); |
@@ -3227,7 +2808,7 @@ static struct attribute *iwl_sysfs_entries[] = { | |||
3227 | &dev_attr_debug_level.attr, | 2808 | &dev_attr_debug_level.attr, |
3228 | #endif | 2809 | #endif |
3229 | &dev_attr_version.attr, | 2810 | &dev_attr_version.attr, |
3230 | 2811 | &dev_attr_qos.attr, | |
3231 | NULL | 2812 | NULL |
3232 | }; | 2813 | }; |
3233 | 2814 | ||
@@ -3243,7 +2824,6 @@ static struct ieee80211_ops iwl_hw_ops = { | |||
3243 | .add_interface = iwl_mac_add_interface, | 2824 | .add_interface = iwl_mac_add_interface, |
3244 | .remove_interface = iwl_mac_remove_interface, | 2825 | .remove_interface = iwl_mac_remove_interface, |
3245 | .config = iwl_mac_config, | 2826 | .config = iwl_mac_config, |
3246 | .config_interface = iwl_mac_config_interface, | ||
3247 | .configure_filter = iwl_configure_filter, | 2827 | .configure_filter = iwl_configure_filter, |
3248 | .set_key = iwl_mac_set_key, | 2828 | .set_key = iwl_mac_set_key, |
3249 | .update_tkip_key = iwl_mac_update_tkip_key, | 2829 | .update_tkip_key = iwl_mac_update_tkip_key, |
@@ -3291,6 +2871,7 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
3291 | IWL_DEBUG_INFO(priv, "*** LOAD DRIVER ***\n"); | 2871 | IWL_DEBUG_INFO(priv, "*** LOAD DRIVER ***\n"); |
3292 | priv->cfg = cfg; | 2872 | priv->cfg = cfg; |
3293 | priv->pci_dev = pdev; | 2873 | priv->pci_dev = pdev; |
2874 | priv->inta_mask = CSR_INI_SET_MASK; | ||
3294 | 2875 | ||
3295 | #ifdef CONFIG_IWLWIFI_DEBUG | 2876 | #ifdef CONFIG_IWLWIFI_DEBUG |
3296 | priv->debug_level = priv->cfg->mod_params->debug; | 2877 | priv->debug_level = priv->cfg->mod_params->debug; |
@@ -3341,6 +2922,10 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
3341 | (unsigned long long) pci_resource_len(pdev, 0)); | 2922 | (unsigned long long) pci_resource_len(pdev, 0)); |
3342 | IWL_DEBUG_INFO(priv, "pci_resource_base = %p\n", priv->hw_base); | 2923 | IWL_DEBUG_INFO(priv, "pci_resource_base = %p\n", priv->hw_base); |
3343 | 2924 | ||
2925 | /* this spin lock will be used in apm_ops.init and EEPROM access | ||
2926 | * we should init now | ||
2927 | */ | ||
2928 | spin_lock_init(&priv->reg_lock); | ||
3344 | iwl_hw_detect(priv); | 2929 | iwl_hw_detect(priv); |
3345 | IWL_INFO(priv, "Detected Intel Wireless WiFi Link %s REV=0x%X\n", | 2930 | IWL_INFO(priv, "Detected Intel Wireless WiFi Link %s REV=0x%X\n", |
3346 | priv->cfg->name, priv->hw_rev); | 2931 | priv->cfg->name, priv->hw_rev); |
@@ -3349,6 +2934,12 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
3349 | * PCI Tx retries from interfering with C3 CPU state */ | 2934 | * PCI Tx retries from interfering with C3 CPU state */ |
3350 | pci_write_config_byte(pdev, PCI_CFG_RETRY_TIMEOUT, 0x00); | 2935 | pci_write_config_byte(pdev, PCI_CFG_RETRY_TIMEOUT, 0x00); |
3351 | 2936 | ||
2937 | iwl_prepare_card_hw(priv); | ||
2938 | if (!priv->hw_ready) { | ||
2939 | IWL_WARN(priv, "Failed, HW not ready\n"); | ||
2940 | goto out_iounmap; | ||
2941 | } | ||
2942 | |||
3352 | /* amp init */ | 2943 | /* amp init */ |
3353 | err = priv->cfg->ops->lib->apm_ops.init(priv); | 2944 | err = priv->cfg->ops->lib->apm_ops.init(priv); |
3354 | if (err < 0) { | 2945 | if (err < 0) { |
@@ -3390,18 +2981,8 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
3390 | goto out_free_eeprom; | 2981 | goto out_free_eeprom; |
3391 | /* At this point both hw and priv are initialized. */ | 2982 | /* At this point both hw and priv are initialized. */ |
3392 | 2983 | ||
3393 | /********************************** | ||
3394 | * 7. Initialize module parameters | ||
3395 | **********************************/ | ||
3396 | |||
3397 | /* Disable radio (SW RF KILL) via parameter when loading driver */ | ||
3398 | if (priv->cfg->mod_params->disable) { | ||
3399 | set_bit(STATUS_RF_KILL_SW, &priv->status); | ||
3400 | IWL_DEBUG_INFO(priv, "Radio disabled.\n"); | ||
3401 | } | ||
3402 | |||
3403 | /******************** | 2984 | /******************** |
3404 | * 8. Setup services | 2985 | * 7. Setup services |
3405 | ********************/ | 2986 | ********************/ |
3406 | spin_lock_irqsave(&priv->lock, flags); | 2987 | spin_lock_irqsave(&priv->lock, flags); |
3407 | iwl_disable_interrupts(priv); | 2988 | iwl_disable_interrupts(priv); |
@@ -3409,8 +2990,9 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
3409 | 2990 | ||
3410 | pci_enable_msi(priv->pci_dev); | 2991 | pci_enable_msi(priv->pci_dev); |
3411 | 2992 | ||
3412 | err = request_irq(priv->pci_dev->irq, iwl_isr, IRQF_SHARED, | 2993 | iwl_alloc_isr_ict(priv); |
3413 | DRV_NAME, priv); | 2994 | err = request_irq(priv->pci_dev->irq, priv->cfg->ops->lib->isr, |
2995 | IRQF_SHARED, DRV_NAME, priv); | ||
3414 | if (err) { | 2996 | if (err) { |
3415 | IWL_ERR(priv, "Error allocating IRQ %d\n", priv->pci_dev->irq); | 2997 | IWL_ERR(priv, "Error allocating IRQ %d\n", priv->pci_dev->irq); |
3416 | goto out_disable_msi; | 2998 | goto out_disable_msi; |
@@ -3425,7 +3007,7 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
3425 | iwl_setup_rx_handlers(priv); | 3007 | iwl_setup_rx_handlers(priv); |
3426 | 3008 | ||
3427 | /********************************** | 3009 | /********************************** |
3428 | * 9. Setup and register mac80211 | 3010 | * 8. Setup and register mac80211 |
3429 | **********************************/ | 3011 | **********************************/ |
3430 | 3012 | ||
3431 | /* enable interrupts if needed: hw bug w/a */ | 3013 | /* enable interrupts if needed: hw bug w/a */ |
@@ -3443,7 +3025,7 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
3443 | 3025 | ||
3444 | err = iwl_dbgfs_register(priv, DRV_NAME); | 3026 | err = iwl_dbgfs_register(priv, DRV_NAME); |
3445 | if (err) | 3027 | if (err) |
3446 | IWL_ERR(priv, "failed to create debugfs files\n"); | 3028 | IWL_ERR(priv, "failed to create debugfs files. Ignoring error: %d\n", err); |
3447 | 3029 | ||
3448 | /* If platform's RF_KILL switch is NOT set to KILL */ | 3030 | /* If platform's RF_KILL switch is NOT set to KILL */ |
3449 | if (iwl_read32(priv, CSR_GP_CNTRL) & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW) | 3031 | if (iwl_read32(priv, CSR_GP_CNTRL) & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW) |
@@ -3451,12 +3033,8 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
3451 | else | 3033 | else |
3452 | set_bit(STATUS_RF_KILL_HW, &priv->status); | 3034 | set_bit(STATUS_RF_KILL_HW, &priv->status); |
3453 | 3035 | ||
3454 | err = iwl_rfkill_init(priv); | 3036 | wiphy_rfkill_set_hw_state(priv->hw->wiphy, |
3455 | if (err) | 3037 | test_bit(STATUS_RF_KILL_HW, &priv->status)); |
3456 | IWL_ERR(priv, "Unable to initialize RFKILL system. " | ||
3457 | "Ignoring error: %d\n", err); | ||
3458 | else | ||
3459 | iwl_rfkill_set_hw_state(priv); | ||
3460 | 3038 | ||
3461 | iwl_power_initialize(priv); | 3039 | iwl_power_initialize(priv); |
3462 | return 0; | 3040 | return 0; |
@@ -3467,6 +3045,7 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
3467 | sysfs_remove_group(&pdev->dev.kobj, &iwl_attribute_group); | 3045 | sysfs_remove_group(&pdev->dev.kobj, &iwl_attribute_group); |
3468 | out_free_irq: | 3046 | out_free_irq: |
3469 | free_irq(priv->pci_dev->irq, priv); | 3047 | free_irq(priv->pci_dev->irq, priv); |
3048 | iwl_free_isr_ict(priv); | ||
3470 | out_disable_msi: | 3049 | out_disable_msi: |
3471 | pci_disable_msi(priv->pci_dev); | 3050 | pci_disable_msi(priv->pci_dev); |
3472 | iwl_uninit_drv(priv); | 3051 | iwl_uninit_drv(priv); |
@@ -3519,7 +3098,6 @@ static void __devexit iwl_pci_remove(struct pci_dev *pdev) | |||
3519 | 3098 | ||
3520 | iwl_synchronize_irq(priv); | 3099 | iwl_synchronize_irq(priv); |
3521 | 3100 | ||
3522 | iwl_rfkill_unregister(priv); | ||
3523 | iwl_dealloc_ucode_pci(priv); | 3101 | iwl_dealloc_ucode_pci(priv); |
3524 | 3102 | ||
3525 | if (priv->rxq.bd) | 3103 | if (priv->rxq.bd) |
@@ -3548,51 +3126,14 @@ static void __devexit iwl_pci_remove(struct pci_dev *pdev) | |||
3548 | 3126 | ||
3549 | iwl_uninit_drv(priv); | 3127 | iwl_uninit_drv(priv); |
3550 | 3128 | ||
3129 | iwl_free_isr_ict(priv); | ||
3130 | |||
3551 | if (priv->ibss_beacon) | 3131 | if (priv->ibss_beacon) |
3552 | dev_kfree_skb(priv->ibss_beacon); | 3132 | dev_kfree_skb(priv->ibss_beacon); |
3553 | 3133 | ||
3554 | ieee80211_free_hw(priv->hw); | 3134 | ieee80211_free_hw(priv->hw); |
3555 | } | 3135 | } |
3556 | 3136 | ||
3557 | #ifdef CONFIG_PM | ||
3558 | |||
3559 | static int iwl_pci_suspend(struct pci_dev *pdev, pm_message_t state) | ||
3560 | { | ||
3561 | struct iwl_priv *priv = pci_get_drvdata(pdev); | ||
3562 | |||
3563 | if (priv->is_open) { | ||
3564 | set_bit(STATUS_IN_SUSPEND, &priv->status); | ||
3565 | iwl_mac_stop(priv->hw); | ||
3566 | priv->is_open = 1; | ||
3567 | } | ||
3568 | |||
3569 | pci_save_state(pdev); | ||
3570 | pci_disable_device(pdev); | ||
3571 | pci_set_power_state(pdev, PCI_D3hot); | ||
3572 | |||
3573 | return 0; | ||
3574 | } | ||
3575 | |||
3576 | static int iwl_pci_resume(struct pci_dev *pdev) | ||
3577 | { | ||
3578 | struct iwl_priv *priv = pci_get_drvdata(pdev); | ||
3579 | int ret; | ||
3580 | |||
3581 | pci_set_power_state(pdev, PCI_D0); | ||
3582 | ret = pci_enable_device(pdev); | ||
3583 | if (ret) | ||
3584 | return ret; | ||
3585 | pci_restore_state(pdev); | ||
3586 | iwl_enable_interrupts(priv); | ||
3587 | |||
3588 | if (priv->is_open) | ||
3589 | iwl_mac_start(priv->hw); | ||
3590 | |||
3591 | clear_bit(STATUS_IN_SUSPEND, &priv->status); | ||
3592 | return 0; | ||
3593 | } | ||
3594 | |||
3595 | #endif /* CONFIG_PM */ | ||
3596 | 3137 | ||
3597 | /***************************************************************************** | 3138 | /***************************************************************************** |
3598 | * | 3139 | * |