diff options
Diffstat (limited to 'drivers/net/wireless/iwlwifi')
29 files changed, 1800 insertions, 1236 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c index 679a67ff76eb..3a645e485dda 100644 --- a/drivers/net/wireless/iwlwifi/iwl-1000.c +++ b/drivers/net/wireless/iwlwifi/iwl-1000.c | |||
@@ -110,8 +110,7 @@ static struct iwl_lib_ops iwl1000_lib = { | |||
110 | .send_tx_power = iwl5000_send_tx_power, | 110 | .send_tx_power = iwl5000_send_tx_power, |
111 | .update_chain_flags = iwl_update_chain_flags, | 111 | .update_chain_flags = iwl_update_chain_flags, |
112 | .apm_ops = { | 112 | .apm_ops = { |
113 | .init = iwl5000_apm_init, | 113 | .init = iwl_apm_init, |
114 | .reset = iwl5000_apm_reset, | ||
115 | .stop = iwl_apm_stop, | 114 | .stop = iwl_apm_stop, |
116 | .config = iwl1000_nic_config, | 115 | .config = iwl1000_nic_config, |
117 | .set_pwr_src = iwl_set_pwr_src, | 116 | .set_pwr_src = iwl_set_pwr_src, |
@@ -159,15 +158,20 @@ struct iwl_cfg iwl1000_bgn_cfg = { | |||
159 | .eeprom_size = OTP_LOW_IMAGE_SIZE, | 158 | .eeprom_size = OTP_LOW_IMAGE_SIZE, |
160 | .eeprom_ver = EEPROM_1000_EEPROM_VERSION, | 159 | .eeprom_ver = EEPROM_1000_EEPROM_VERSION, |
161 | .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, | 160 | .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, |
161 | .num_of_queues = IWL50_NUM_QUEUES, | ||
162 | .num_of_ampdu_queues = IWL50_NUM_AMPDU_QUEUES, | ||
162 | .mod_params = &iwl50_mod_params, | 163 | .mod_params = &iwl50_mod_params, |
163 | .valid_tx_ant = ANT_A, | 164 | .valid_tx_ant = ANT_A, |
164 | .valid_rx_ant = ANT_AB, | 165 | .valid_rx_ant = ANT_AB, |
165 | .need_pll_cfg = true, | 166 | .pll_cfg_val = CSR50_ANA_PLL_CFG_VAL, |
167 | .set_l0s = false, | ||
168 | .use_bsm = false, | ||
166 | .max_ll_items = OTP_MAX_LL_ITEMS_1000, | 169 | .max_ll_items = OTP_MAX_LL_ITEMS_1000, |
167 | .shadow_ram_support = false, | 170 | .shadow_ram_support = false, |
168 | .ht_greenfield_support = true, | 171 | .ht_greenfield_support = true, |
169 | .led_compensation = 51, | 172 | .led_compensation = 51, |
170 | .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, | 173 | .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, |
174 | .support_ct_kill_exit = true, | ||
171 | }; | 175 | }; |
172 | 176 | ||
173 | struct iwl_cfg iwl1000_bg_cfg = { | 177 | struct iwl_cfg iwl1000_bg_cfg = { |
@@ -180,15 +184,20 @@ struct iwl_cfg iwl1000_bg_cfg = { | |||
180 | .eeprom_size = OTP_LOW_IMAGE_SIZE, | 184 | .eeprom_size = OTP_LOW_IMAGE_SIZE, |
181 | .eeprom_ver = EEPROM_1000_EEPROM_VERSION, | 185 | .eeprom_ver = EEPROM_1000_EEPROM_VERSION, |
182 | .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, | 186 | .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, |
187 | .num_of_queues = IWL50_NUM_QUEUES, | ||
188 | .num_of_ampdu_queues = IWL50_NUM_AMPDU_QUEUES, | ||
183 | .mod_params = &iwl50_mod_params, | 189 | .mod_params = &iwl50_mod_params, |
184 | .valid_tx_ant = ANT_A, | 190 | .valid_tx_ant = ANT_A, |
185 | .valid_rx_ant = ANT_AB, | 191 | .valid_rx_ant = ANT_AB, |
186 | .need_pll_cfg = true, | 192 | .pll_cfg_val = CSR50_ANA_PLL_CFG_VAL, |
193 | .set_l0s = false, | ||
194 | .use_bsm = false, | ||
187 | .max_ll_items = OTP_MAX_LL_ITEMS_1000, | 195 | .max_ll_items = OTP_MAX_LL_ITEMS_1000, |
188 | .shadow_ram_support = false, | 196 | .shadow_ram_support = false, |
189 | .ht_greenfield_support = true, | 197 | .ht_greenfield_support = true, |
190 | .led_compensation = 51, | 198 | .led_compensation = 51, |
191 | .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, | 199 | .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, |
200 | .support_ct_kill_exit = true, | ||
192 | }; | 201 | }; |
193 | 202 | ||
194 | MODULE_FIRMWARE(IWL1000_MODULE_FIRMWARE(IWL1000_UCODE_API_MAX)); | 203 | MODULE_FIRMWARE(IWL1000_MODULE_FIRMWARE(IWL1000_UCODE_API_MAX)); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-hw.h b/drivers/net/wireless/iwlwifi/iwl-3945-hw.h index 16772780c5b0..6fd10d443ba3 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945-hw.h +++ b/drivers/net/wireless/iwlwifi/iwl-3945-hw.h | |||
@@ -71,12 +71,6 @@ | |||
71 | 71 | ||
72 | #include "iwl-eeprom.h" | 72 | #include "iwl-eeprom.h" |
73 | 73 | ||
74 | /* | ||
75 | * uCode queue management definitions ... | ||
76 | * Queue #4 is the command queue for 3945 and 4965. | ||
77 | */ | ||
78 | #define IWL_CMD_QUEUE_NUM 4 | ||
79 | |||
80 | /* Time constants */ | 74 | /* Time constants */ |
81 | #define SHORT_SLOT_TIME 9 | 75 | #define SHORT_SLOT_TIME 9 |
82 | #define LONG_SLOT_TIME 20 | 76 | #define LONG_SLOT_TIME 20 |
@@ -254,12 +248,6 @@ struct iwl3945_eeprom { | |||
254 | #define TFD_CTL_PAD_SET(n) (n << 28) | 248 | #define TFD_CTL_PAD_SET(n) (n << 28) |
255 | #define TFD_CTL_PAD_GET(ctl) (ctl >> 28) | 249 | #define TFD_CTL_PAD_GET(ctl) (ctl >> 28) |
256 | 250 | ||
257 | /* | ||
258 | * RX related structures and functions | ||
259 | */ | ||
260 | #define RX_FREE_BUFFERS 64 | ||
261 | #define RX_LOW_WATERMARK 8 | ||
262 | |||
263 | /* Sizes and addresses for instruction and data memory (SRAM) in | 251 | /* Sizes and addresses for instruction and data memory (SRAM) in |
264 | * 3945's embedded processor. Driver access is via HBUS_TARG_MEM_* regs. */ | 252 | * 3945's embedded processor. Driver access is via HBUS_TARG_MEM_* regs. */ |
265 | #define IWL39_RTC_INST_LOWER_BOUND (0x000000) | 253 | #define IWL39_RTC_INST_LOWER_BOUND (0x000000) |
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c index 4115672e2338..09a7bd2c0be4 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.c +++ b/drivers/net/wireless/iwlwifi/iwl-3945.c | |||
@@ -293,7 +293,7 @@ static void iwl3945_tx_queue_reclaim(struct iwl_priv *priv, | |||
293 | static void iwl3945_rx_reply_tx(struct iwl_priv *priv, | 293 | static void iwl3945_rx_reply_tx(struct iwl_priv *priv, |
294 | struct iwl_rx_mem_buffer *rxb) | 294 | struct iwl_rx_mem_buffer *rxb) |
295 | { | 295 | { |
296 | struct iwl_rx_packet *pkt = (void *)rxb->skb->data; | 296 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
297 | u16 sequence = le16_to_cpu(pkt->hdr.sequence); | 297 | u16 sequence = le16_to_cpu(pkt->hdr.sequence); |
298 | int txq_id = SEQ_TO_QUEUE(sequence); | 298 | int txq_id = SEQ_TO_QUEUE(sequence); |
299 | int index = SEQ_TO_INDEX(sequence); | 299 | int index = SEQ_TO_INDEX(sequence); |
@@ -353,16 +353,12 @@ static void iwl3945_rx_reply_tx(struct iwl_priv *priv, | |||
353 | void iwl3945_hw_rx_statistics(struct iwl_priv *priv, | 353 | void iwl3945_hw_rx_statistics(struct iwl_priv *priv, |
354 | struct iwl_rx_mem_buffer *rxb) | 354 | struct iwl_rx_mem_buffer *rxb) |
355 | { | 355 | { |
356 | struct iwl_rx_packet *pkt = (void *)rxb->skb->data; | 356 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
357 | IWL_DEBUG_RX(priv, "Statistics notification received (%d vs %d).\n", | 357 | IWL_DEBUG_RX(priv, "Statistics notification received (%d vs %d).\n", |
358 | (int)sizeof(struct iwl3945_notif_statistics), | 358 | (int)sizeof(struct iwl3945_notif_statistics), |
359 | le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK); | 359 | le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK); |
360 | 360 | ||
361 | memcpy(&priv->statistics_39, pkt->u.raw, sizeof(priv->statistics_39)); | 361 | memcpy(&priv->statistics_39, pkt->u.raw, sizeof(priv->statistics_39)); |
362 | |||
363 | iwl_leds_background(priv); | ||
364 | |||
365 | priv->last_statistics_time = jiffies; | ||
366 | } | 362 | } |
367 | 363 | ||
368 | /****************************************************************************** | 364 | /****************************************************************************** |
@@ -545,14 +541,18 @@ static void iwl3945_pass_packet_to_mac80211(struct iwl_priv *priv, | |||
545 | struct iwl_rx_mem_buffer *rxb, | 541 | struct iwl_rx_mem_buffer *rxb, |
546 | struct ieee80211_rx_status *stats) | 542 | struct ieee80211_rx_status *stats) |
547 | { | 543 | { |
548 | struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; | 544 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
549 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)IWL_RX_DATA(pkt); | 545 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)IWL_RX_DATA(pkt); |
550 | struct iwl3945_rx_frame_hdr *rx_hdr = IWL_RX_HDR(pkt); | 546 | struct iwl3945_rx_frame_hdr *rx_hdr = IWL_RX_HDR(pkt); |
551 | struct iwl3945_rx_frame_end *rx_end = IWL_RX_END(pkt); | 547 | struct iwl3945_rx_frame_end *rx_end = IWL_RX_END(pkt); |
552 | short len = le16_to_cpu(rx_hdr->len); | 548 | u16 len = le16_to_cpu(rx_hdr->len); |
549 | struct sk_buff *skb; | ||
550 | int ret; | ||
551 | __le16 fc = hdr->frame_control; | ||
553 | 552 | ||
554 | /* We received data from the HW, so stop the watchdog */ | 553 | /* We received data from the HW, so stop the watchdog */ |
555 | if (unlikely((len + IWL39_RX_FRAME_SIZE) > skb_tailroom(rxb->skb))) { | 554 | if (unlikely(len + IWL39_RX_FRAME_SIZE > |
555 | PAGE_SIZE << priv->hw_params.rx_page_order)) { | ||
556 | IWL_DEBUG_DROP(priv, "Corruption detected!\n"); | 556 | IWL_DEBUG_DROP(priv, "Corruption detected!\n"); |
557 | return; | 557 | return; |
558 | } | 558 | } |
@@ -564,20 +564,49 @@ static void iwl3945_pass_packet_to_mac80211(struct iwl_priv *priv, | |||
564 | return; | 564 | return; |
565 | } | 565 | } |
566 | 566 | ||
567 | skb_reserve(rxb->skb, (void *)rx_hdr->payload - (void *)pkt); | 567 | skb = alloc_skb(IWL_LINK_HDR_MAX, GFP_ATOMIC); |
568 | /* Set the size of the skb to the size of the frame */ | 568 | if (!skb) { |
569 | skb_put(rxb->skb, le16_to_cpu(rx_hdr->len)); | 569 | IWL_ERR(priv, "alloc_skb failed\n"); |
570 | return; | ||
571 | } | ||
570 | 572 | ||
571 | if (!iwl3945_mod_params.sw_crypto) | 573 | if (!iwl3945_mod_params.sw_crypto) |
572 | iwl_set_decrypted_flag(priv, | 574 | iwl_set_decrypted_flag(priv, |
573 | (struct ieee80211_hdr *)rxb->skb->data, | 575 | (struct ieee80211_hdr *)rxb_addr(rxb), |
574 | le32_to_cpu(rx_end->status), stats); | 576 | le32_to_cpu(rx_end->status), stats); |
575 | 577 | ||
576 | iwl_update_stats(priv, false, hdr->frame_control, len); | 578 | skb_add_rx_frag(skb, 0, rxb->page, |
579 | (void *)rx_hdr->payload - (void *)pkt, len); | ||
580 | |||
581 | /* mac80211 currently doesn't support paged SKB. Convert it to | ||
582 | * linear SKB for management frame and data frame requires | ||
583 | * software decryption or software defragementation. */ | ||
584 | if (ieee80211_is_mgmt(fc) || | ||
585 | ieee80211_has_protected(fc) || | ||
586 | ieee80211_has_morefrags(fc) || | ||
587 | le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG) | ||
588 | ret = skb_linearize(skb); | ||
589 | else | ||
590 | ret = __pskb_pull_tail(skb, min_t(u16, IWL_LINK_HDR_MAX, len)) ? | ||
591 | 0 : -ENOMEM; | ||
592 | |||
593 | if (ret) { | ||
594 | kfree_skb(skb); | ||
595 | goto out; | ||
596 | } | ||
597 | |||
598 | /* | ||
599 | * XXX: We cannot touch the page and its virtual memory (pkt) after | ||
600 | * here. It might have already been freed by the above skb change. | ||
601 | */ | ||
602 | |||
603 | iwl_update_stats(priv, false, fc, len); | ||
604 | memcpy(IEEE80211_SKB_RXCB(skb), stats, sizeof(*stats)); | ||
577 | 605 | ||
578 | memcpy(IEEE80211_SKB_RXCB(rxb->skb), stats, sizeof(*stats)); | 606 | ieee80211_rx(priv->hw, skb); |
579 | ieee80211_rx_irqsafe(priv->hw, rxb->skb); | 607 | out: |
580 | rxb->skb = NULL; | 608 | priv->alloc_rxb_page--; |
609 | rxb->page = NULL; | ||
581 | } | 610 | } |
582 | 611 | ||
583 | #define IWL_DELAY_NEXT_SCAN_AFTER_ASSOC (HZ*6) | 612 | #define IWL_DELAY_NEXT_SCAN_AFTER_ASSOC (HZ*6) |
@@ -587,7 +616,7 @@ static void iwl3945_rx_reply_rx(struct iwl_priv *priv, | |||
587 | { | 616 | { |
588 | struct ieee80211_hdr *header; | 617 | struct ieee80211_hdr *header; |
589 | struct ieee80211_rx_status rx_status; | 618 | struct ieee80211_rx_status rx_status; |
590 | struct iwl_rx_packet *pkt = (void *)rxb->skb->data; | 619 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
591 | struct iwl3945_rx_frame_stats *rx_stats = IWL_RX_STATS(pkt); | 620 | struct iwl3945_rx_frame_stats *rx_stats = IWL_RX_STATS(pkt); |
592 | struct iwl3945_rx_frame_hdr *rx_hdr = IWL_RX_HDR(pkt); | 621 | struct iwl3945_rx_frame_hdr *rx_hdr = IWL_RX_HDR(pkt); |
593 | struct iwl3945_rx_frame_end *rx_end = IWL_RX_END(pkt); | 622 | struct iwl3945_rx_frame_end *rx_end = IWL_RX_END(pkt); |
@@ -787,29 +816,31 @@ void iwl3945_hw_build_tx_cmd_rate(struct iwl_priv *priv, | |||
787 | u8 data_retry_limit; | 816 | u8 data_retry_limit; |
788 | __le32 tx_flags; | 817 | __le32 tx_flags; |
789 | __le16 fc = hdr->frame_control; | 818 | __le16 fc = hdr->frame_control; |
790 | struct iwl3945_tx_cmd *tx = (struct iwl3945_tx_cmd *)cmd->cmd.payload; | 819 | struct iwl3945_tx_cmd *tx_cmd = (struct iwl3945_tx_cmd *)cmd->cmd.payload; |
791 | 820 | ||
792 | rate = iwl3945_rates[rate_index].plcp; | 821 | rate = iwl3945_rates[rate_index].plcp; |
793 | tx_flags = tx->tx_flags; | 822 | tx_flags = tx_cmd->tx_flags; |
794 | 823 | ||
795 | /* We need to figure out how to get the sta->supp_rates while | 824 | /* We need to figure out how to get the sta->supp_rates while |
796 | * in this running context */ | 825 | * in this running context */ |
797 | rate_mask = IWL_RATES_MASK; | 826 | rate_mask = IWL_RATES_MASK; |
798 | 827 | ||
828 | |||
829 | /* Set retry limit on DATA packets and Probe Responses*/ | ||
830 | if (ieee80211_is_probe_resp(fc)) | ||
831 | data_retry_limit = 3; | ||
832 | else | ||
833 | data_retry_limit = IWL_DEFAULT_TX_RETRY; | ||
834 | tx_cmd->data_retry_limit = data_retry_limit; | ||
835 | |||
799 | if (tx_id >= IWL_CMD_QUEUE_NUM) | 836 | if (tx_id >= IWL_CMD_QUEUE_NUM) |
800 | rts_retry_limit = 3; | 837 | rts_retry_limit = 3; |
801 | else | 838 | else |
802 | rts_retry_limit = 7; | 839 | rts_retry_limit = 7; |
803 | 840 | ||
804 | if (ieee80211_is_probe_resp(fc)) { | 841 | if (data_retry_limit < rts_retry_limit) |
805 | data_retry_limit = 3; | 842 | rts_retry_limit = data_retry_limit; |
806 | if (data_retry_limit < rts_retry_limit) | 843 | tx_cmd->rts_retry_limit = rts_retry_limit; |
807 | rts_retry_limit = data_retry_limit; | ||
808 | } else | ||
809 | data_retry_limit = IWL_DEFAULT_TX_RETRY; | ||
810 | |||
811 | if (priv->data_retry_limit != -1) | ||
812 | data_retry_limit = priv->data_retry_limit; | ||
813 | 844 | ||
814 | if (ieee80211_is_mgmt(fc)) { | 845 | if (ieee80211_is_mgmt(fc)) { |
815 | switch (fc & cpu_to_le16(IEEE80211_FCTL_STYPE)) { | 846 | switch (fc & cpu_to_le16(IEEE80211_FCTL_STYPE)) { |
@@ -827,22 +858,20 @@ void iwl3945_hw_build_tx_cmd_rate(struct iwl_priv *priv, | |||
827 | } | 858 | } |
828 | } | 859 | } |
829 | 860 | ||
830 | tx->rts_retry_limit = rts_retry_limit; | 861 | tx_cmd->rate = rate; |
831 | tx->data_retry_limit = data_retry_limit; | 862 | tx_cmd->tx_flags = tx_flags; |
832 | tx->rate = rate; | ||
833 | tx->tx_flags = tx_flags; | ||
834 | 863 | ||
835 | /* OFDM */ | 864 | /* OFDM */ |
836 | tx->supp_rates[0] = | 865 | tx_cmd->supp_rates[0] = |
837 | ((rate_mask & IWL_OFDM_RATES_MASK) >> IWL_FIRST_OFDM_RATE) & 0xFF; | 866 | ((rate_mask & IWL_OFDM_RATES_MASK) >> IWL_FIRST_OFDM_RATE) & 0xFF; |
838 | 867 | ||
839 | /* CCK */ | 868 | /* CCK */ |
840 | tx->supp_rates[1] = (rate_mask & 0xF); | 869 | tx_cmd->supp_rates[1] = (rate_mask & 0xF); |
841 | 870 | ||
842 | IWL_DEBUG_RATE(priv, "Tx sta id: %d, rate: %d (plcp), flags: 0x%4X " | 871 | IWL_DEBUG_RATE(priv, "Tx sta id: %d, rate: %d (plcp), flags: 0x%4X " |
843 | "cck/ofdm mask: 0x%x/0x%x\n", sta_id, | 872 | "cck/ofdm mask: 0x%x/0x%x\n", sta_id, |
844 | tx->rate, le32_to_cpu(tx->tx_flags), | 873 | tx_cmd->rate, le32_to_cpu(tx_cmd->tx_flags), |
845 | tx->supp_rates[1], tx->supp_rates[0]); | 874 | tx_cmd->supp_rates[1], tx_cmd->supp_rates[0]); |
846 | } | 875 | } |
847 | 876 | ||
848 | u8 iwl3945_sync_sta(struct iwl_priv *priv, int sta_id, u16 tx_rate, u8 flags) | 877 | u8 iwl3945_sync_sta(struct iwl_priv *priv, int sta_id, u16 tx_rate, u8 flags) |
@@ -958,6 +987,11 @@ static int iwl3945_txq_ctx_reset(struct iwl_priv *priv) | |||
958 | 987 | ||
959 | iwl3945_hw_txq_ctx_free(priv); | 988 | iwl3945_hw_txq_ctx_free(priv); |
960 | 989 | ||
990 | /* allocate tx queue structure */ | ||
991 | rc = iwl_alloc_txq_mem(priv); | ||
992 | if (rc) | ||
993 | return rc; | ||
994 | |||
961 | /* Tx CMD queue */ | 995 | /* Tx CMD queue */ |
962 | rc = iwl3945_tx_reset(priv); | 996 | rc = iwl3945_tx_reset(priv); |
963 | if (rc) | 997 | if (rc) |
@@ -982,42 +1016,25 @@ static int iwl3945_txq_ctx_reset(struct iwl_priv *priv) | |||
982 | return rc; | 1016 | return rc; |
983 | } | 1017 | } |
984 | 1018 | ||
1019 | |||
1020 | /* | ||
1021 | * Start up 3945's basic functionality after it has been reset | ||
1022 | * (e.g. after platform boot, or shutdown via iwl_apm_stop()) | ||
1023 | * NOTE: This does not load uCode nor start the embedded processor | ||
1024 | */ | ||
985 | static int iwl3945_apm_init(struct iwl_priv *priv) | 1025 | static int iwl3945_apm_init(struct iwl_priv *priv) |
986 | { | 1026 | { |
987 | int ret; | 1027 | int ret = iwl_apm_init(priv); |
988 | |||
989 | iwl_power_initialize(priv); | ||
990 | 1028 | ||
991 | iwl_set_bit(priv, CSR_GIO_CHICKEN_BITS, | 1029 | /* Clear APMG (NIC's internal power management) interrupts */ |
992 | CSR_GIO_CHICKEN_BITS_REG_BIT_DIS_L0S_EXIT_TIMER); | 1030 | iwl_write_prph(priv, APMG_RTC_INT_MSK_REG, 0x0); |
993 | 1031 | iwl_write_prph(priv, APMG_RTC_INT_STT_REG, 0xFFFFFFFF); | |
994 | /* disable L0s without affecting L1 :don't wait for ICH L0s bug W/A) */ | ||
995 | iwl_set_bit(priv, CSR_GIO_CHICKEN_BITS, | ||
996 | CSR_GIO_CHICKEN_BITS_REG_BIT_L1A_NO_L0S_RX); | ||
997 | |||
998 | /* set "initialization complete" bit to move adapter | ||
999 | * D0U* --> D0A* state */ | ||
1000 | iwl_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE); | ||
1001 | |||
1002 | ret = iwl_poll_bit(priv, CSR_GP_CNTRL, | ||
1003 | CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, | ||
1004 | CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000); | ||
1005 | if (ret < 0) { | ||
1006 | IWL_DEBUG_INFO(priv, "Failed to init the card\n"); | ||
1007 | goto out; | ||
1008 | } | ||
1009 | |||
1010 | /* enable DMA */ | ||
1011 | iwl_write_prph(priv, APMG_CLK_CTRL_REG, APMG_CLK_VAL_DMA_CLK_RQT | | ||
1012 | APMG_CLK_VAL_BSM_CLK_RQT); | ||
1013 | |||
1014 | udelay(20); | ||
1015 | 1032 | ||
1016 | /* disable L1-Active */ | 1033 | /* Reset radio chip */ |
1017 | iwl_set_bits_prph(priv, APMG_PCIDEV_STT_REG, | 1034 | iwl_set_bits_prph(priv, APMG_PS_CTRL_REG, APMG_PS_CTRL_VAL_RESET_REQ); |
1018 | APMG_PCIDEV_STT_VAL_L1_ACT_DIS); | 1035 | udelay(5); |
1036 | iwl_clear_bits_prph(priv, APMG_PS_CTRL_REG, APMG_PS_CTRL_VAL_RESET_REQ); | ||
1019 | 1037 | ||
1020 | out: | ||
1021 | return ret; | 1038 | return ret; |
1022 | } | 1039 | } |
1023 | 1040 | ||
@@ -1142,12 +1159,16 @@ void iwl3945_hw_txq_ctx_free(struct iwl_priv *priv) | |||
1142 | int txq_id; | 1159 | int txq_id; |
1143 | 1160 | ||
1144 | /* Tx queues */ | 1161 | /* Tx queues */ |
1145 | for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++) | 1162 | if (priv->txq) |
1146 | if (txq_id == IWL_CMD_QUEUE_NUM) | 1163 | for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; |
1147 | iwl_cmd_queue_free(priv); | 1164 | txq_id++) |
1148 | else | 1165 | if (txq_id == IWL_CMD_QUEUE_NUM) |
1149 | iwl_tx_queue_free(priv, txq_id); | 1166 | iwl_cmd_queue_free(priv); |
1167 | else | ||
1168 | iwl_tx_queue_free(priv, txq_id); | ||
1150 | 1169 | ||
1170 | /* free tx queue structure */ | ||
1171 | iwl_free_txq_mem(priv); | ||
1151 | } | 1172 | } |
1152 | 1173 | ||
1153 | void iwl3945_hw_txq_ctx_stop(struct iwl_priv *priv) | 1174 | void iwl3945_hw_txq_ctx_stop(struct iwl_priv *priv) |
@@ -1156,6 +1177,7 @@ void iwl3945_hw_txq_ctx_stop(struct iwl_priv *priv) | |||
1156 | 1177 | ||
1157 | /* stop SCD */ | 1178 | /* stop SCD */ |
1158 | iwl_write_prph(priv, ALM_SCD_MODE_REG, 0); | 1179 | iwl_write_prph(priv, ALM_SCD_MODE_REG, 0); |
1180 | iwl_write_prph(priv, ALM_SCD_TXFACT_REG, 0); | ||
1159 | 1181 | ||
1160 | /* reset TFD queues */ | 1182 | /* reset TFD queues */ |
1161 | for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++) { | 1183 | for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++) { |
@@ -1168,47 +1190,6 @@ void iwl3945_hw_txq_ctx_stop(struct iwl_priv *priv) | |||
1168 | iwl3945_hw_txq_ctx_free(priv); | 1190 | iwl3945_hw_txq_ctx_free(priv); |
1169 | } | 1191 | } |
1170 | 1192 | ||
1171 | static int iwl3945_apm_reset(struct iwl_priv *priv) | ||
1172 | { | ||
1173 | iwl_apm_stop_master(priv); | ||
1174 | |||
1175 | |||
1176 | iwl_set_bit(priv, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET); | ||
1177 | udelay(10); | ||
1178 | |||
1179 | iwl_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE); | ||
1180 | |||
1181 | iwl_poll_bit(priv, CSR_GP_CNTRL, | ||
1182 | CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, | ||
1183 | CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000); | ||
1184 | |||
1185 | iwl_write_prph(priv, APMG_CLK_CTRL_REG, | ||
1186 | APMG_CLK_VAL_BSM_CLK_RQT); | ||
1187 | |||
1188 | iwl_write_prph(priv, APMG_RTC_INT_MSK_REG, 0x0); | ||
1189 | iwl_write_prph(priv, APMG_RTC_INT_STT_REG, | ||
1190 | 0xFFFFFFFF); | ||
1191 | |||
1192 | /* enable DMA */ | ||
1193 | iwl_write_prph(priv, APMG_CLK_EN_REG, | ||
1194 | APMG_CLK_VAL_DMA_CLK_RQT | | ||
1195 | APMG_CLK_VAL_BSM_CLK_RQT); | ||
1196 | udelay(10); | ||
1197 | |||
1198 | iwl_set_bits_prph(priv, APMG_PS_CTRL_REG, | ||
1199 | APMG_PS_CTRL_VAL_RESET_REQ); | ||
1200 | udelay(5); | ||
1201 | iwl_clear_bits_prph(priv, APMG_PS_CTRL_REG, | ||
1202 | APMG_PS_CTRL_VAL_RESET_REQ); | ||
1203 | |||
1204 | /* Clear the 'host command active' bit... */ | ||
1205 | clear_bit(STATUS_HCMD_ACTIVE, &priv->status); | ||
1206 | |||
1207 | wake_up_interruptible(&priv->wait_command_queue); | ||
1208 | |||
1209 | return 0; | ||
1210 | } | ||
1211 | |||
1212 | /** | 1193 | /** |
1213 | * iwl3945_hw_reg_adjust_power_by_temp | 1194 | * iwl3945_hw_reg_adjust_power_by_temp |
1214 | * return index delta into power gain settings table | 1195 | * return index delta into power gain settings table |
@@ -1817,7 +1798,7 @@ int iwl3945_hw_reg_set_txpower(struct iwl_priv *priv, s8 power) | |||
1817 | static int iwl3945_send_rxon_assoc(struct iwl_priv *priv) | 1798 | static int iwl3945_send_rxon_assoc(struct iwl_priv *priv) |
1818 | { | 1799 | { |
1819 | int rc = 0; | 1800 | int rc = 0; |
1820 | struct iwl_rx_packet *res = NULL; | 1801 | struct iwl_rx_packet *pkt; |
1821 | struct iwl3945_rxon_assoc_cmd rxon_assoc; | 1802 | struct iwl3945_rxon_assoc_cmd rxon_assoc; |
1822 | struct iwl_host_cmd cmd = { | 1803 | struct iwl_host_cmd cmd = { |
1823 | .id = REPLY_RXON_ASSOC, | 1804 | .id = REPLY_RXON_ASSOC, |
@@ -1846,14 +1827,14 @@ static int iwl3945_send_rxon_assoc(struct iwl_priv *priv) | |||
1846 | if (rc) | 1827 | if (rc) |
1847 | return rc; | 1828 | return rc; |
1848 | 1829 | ||
1849 | res = (struct iwl_rx_packet *)cmd.reply_skb->data; | 1830 | pkt = (struct iwl_rx_packet *)cmd.reply_page; |
1850 | if (res->hdr.flags & IWL_CMD_FAILED_MSK) { | 1831 | if (pkt->hdr.flags & IWL_CMD_FAILED_MSK) { |
1851 | IWL_ERR(priv, "Bad return from REPLY_RXON_ASSOC command\n"); | 1832 | IWL_ERR(priv, "Bad return from REPLY_RXON_ASSOC command\n"); |
1852 | rc = -EIO; | 1833 | rc = -EIO; |
1853 | } | 1834 | } |
1854 | 1835 | ||
1855 | priv->alloc_rxb_skb--; | 1836 | priv->alloc_rxb_page--; |
1856 | dev_kfree_skb_any(cmd.reply_skb); | 1837 | free_pages(cmd.reply_page, priv->hw_params.rx_page_order); |
1857 | 1838 | ||
1858 | return rc; | 1839 | return rc; |
1859 | } | 1840 | } |
@@ -2001,12 +1982,6 @@ static int iwl3945_commit_rxon(struct iwl_priv *priv) | |||
2001 | return 0; | 1982 | return 0; |
2002 | } | 1983 | } |
2003 | 1984 | ||
2004 | /* will add 3945 channel switch cmd handling later */ | ||
2005 | int iwl3945_hw_channel_switch(struct iwl_priv *priv, u16 channel) | ||
2006 | { | ||
2007 | return 0; | ||
2008 | } | ||
2009 | |||
2010 | /** | 1985 | /** |
2011 | * iwl3945_reg_txpower_periodic - called when time to check our temperature. | 1986 | * iwl3945_reg_txpower_periodic - called when time to check our temperature. |
2012 | * | 1987 | * |
@@ -2516,11 +2491,10 @@ int iwl3945_hw_set_hw_params(struct iwl_priv *priv) | |||
2516 | } | 2491 | } |
2517 | 2492 | ||
2518 | /* Assign number of Usable TX queues */ | 2493 | /* Assign number of Usable TX queues */ |
2519 | priv->hw_params.max_txq_num = IWL39_NUM_QUEUES; | 2494 | priv->hw_params.max_txq_num = priv->cfg->num_of_queues; |
2520 | 2495 | ||
2521 | priv->hw_params.tfd_size = sizeof(struct iwl3945_tfd); | 2496 | priv->hw_params.tfd_size = sizeof(struct iwl3945_tfd); |
2522 | priv->hw_params.rx_buf_size = IWL_RX_BUF_SIZE_3K; | 2497 | priv->hw_params.rx_page_order = get_order(IWL_RX_BUF_SIZE_3K); |
2523 | priv->hw_params.max_pkt_size = 2342; | ||
2524 | priv->hw_params.max_rxq_size = RX_QUEUE_SIZE; | 2498 | priv->hw_params.max_rxq_size = RX_QUEUE_SIZE; |
2525 | priv->hw_params.max_rxq_log = RX_QUEUE_SIZE_LOG; | 2499 | priv->hw_params.max_rxq_log = RX_QUEUE_SIZE_LOG; |
2526 | priv->hw_params.max_stations = IWL3945_STATION_COUNT; | 2500 | priv->hw_params.max_stations = IWL3945_STATION_COUNT; |
@@ -2803,7 +2777,6 @@ static struct iwl_lib_ops iwl3945_lib = { | |||
2803 | .dump_nic_error_log = iwl3945_dump_nic_error_log, | 2777 | .dump_nic_error_log = iwl3945_dump_nic_error_log, |
2804 | .apm_ops = { | 2778 | .apm_ops = { |
2805 | .init = iwl3945_apm_init, | 2779 | .init = iwl3945_apm_init, |
2806 | .reset = iwl3945_apm_reset, | ||
2807 | .stop = iwl_apm_stop, | 2780 | .stop = iwl_apm_stop, |
2808 | .config = iwl3945_nic_config, | 2781 | .config = iwl3945_nic_config, |
2809 | .set_pwr_src = iwl3945_set_pwr_src, | 2782 | .set_pwr_src = iwl3945_set_pwr_src, |
@@ -2833,6 +2806,7 @@ static struct iwl_lib_ops iwl3945_lib = { | |||
2833 | static struct iwl_hcmd_utils_ops iwl3945_hcmd_utils = { | 2806 | static struct iwl_hcmd_utils_ops iwl3945_hcmd_utils = { |
2834 | .get_hcmd_size = iwl3945_get_hcmd_size, | 2807 | .get_hcmd_size = iwl3945_get_hcmd_size, |
2835 | .build_addsta_hcmd = iwl3945_build_addsta_hcmd, | 2808 | .build_addsta_hcmd = iwl3945_build_addsta_hcmd, |
2809 | .rts_tx_cmd_flag = iwlcore_rts_tx_cmd_flag, | ||
2836 | }; | 2810 | }; |
2837 | 2811 | ||
2838 | static struct iwl_ops iwl3945_ops = { | 2812 | static struct iwl_ops iwl3945_ops = { |
@@ -2852,7 +2826,11 @@ static struct iwl_cfg iwl3945_bg_cfg = { | |||
2852 | .eeprom_size = IWL3945_EEPROM_IMG_SIZE, | 2826 | .eeprom_size = IWL3945_EEPROM_IMG_SIZE, |
2853 | .eeprom_ver = EEPROM_3945_EEPROM_VERSION, | 2827 | .eeprom_ver = EEPROM_3945_EEPROM_VERSION, |
2854 | .ops = &iwl3945_ops, | 2828 | .ops = &iwl3945_ops, |
2829 | .num_of_queues = IWL39_NUM_QUEUES, | ||
2855 | .mod_params = &iwl3945_mod_params, | 2830 | .mod_params = &iwl3945_mod_params, |
2831 | .pll_cfg_val = CSR39_ANA_PLL_CFG_VAL, | ||
2832 | .set_l0s = false, | ||
2833 | .use_bsm = true, | ||
2856 | .use_isr_legacy = true, | 2834 | .use_isr_legacy = true, |
2857 | .ht_greenfield_support = false, | 2835 | .ht_greenfield_support = false, |
2858 | .led_compensation = 64, | 2836 | .led_compensation = 64, |
@@ -2867,6 +2845,7 @@ static struct iwl_cfg iwl3945_abg_cfg = { | |||
2867 | .eeprom_size = IWL3945_EEPROM_IMG_SIZE, | 2845 | .eeprom_size = IWL3945_EEPROM_IMG_SIZE, |
2868 | .eeprom_ver = EEPROM_3945_EEPROM_VERSION, | 2846 | .eeprom_ver = EEPROM_3945_EEPROM_VERSION, |
2869 | .ops = &iwl3945_ops, | 2847 | .ops = &iwl3945_ops, |
2848 | .num_of_queues = IWL39_NUM_QUEUES, | ||
2870 | .mod_params = &iwl3945_mod_params, | 2849 | .mod_params = &iwl3945_mod_params, |
2871 | .use_isr_legacy = true, | 2850 | .use_isr_legacy = true, |
2872 | .ht_greenfield_support = false, | 2851 | .ht_greenfield_support = false, |
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.h b/drivers/net/wireless/iwlwifi/iwl-3945.h index f3907c1079f5..ebb999a51b58 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.h +++ b/drivers/net/wireless/iwlwifi/iwl-3945.h | |||
@@ -130,12 +130,6 @@ struct iwl3945_frame { | |||
130 | #define SN_TO_SEQ(ssn) (((ssn) << 4) & IEEE80211_SCTL_SEQ) | 130 | #define SN_TO_SEQ(ssn) (((ssn) << 4) & IEEE80211_SCTL_SEQ) |
131 | #define MAX_SN ((IEEE80211_SCTL_SEQ) >> 4) | 131 | #define MAX_SN ((IEEE80211_SCTL_SEQ) >> 4) |
132 | 132 | ||
133 | /* | ||
134 | * RX related structures and functions | ||
135 | */ | ||
136 | #define RX_FREE_BUFFERS 64 | ||
137 | #define RX_LOW_WATERMARK 8 | ||
138 | |||
139 | #define SUP_RATE_11A_MAX_NUM_CHANNELS 8 | 133 | #define SUP_RATE_11A_MAX_NUM_CHANNELS 8 |
140 | #define SUP_RATE_11B_MAX_NUM_CHANNELS 4 | 134 | #define SUP_RATE_11B_MAX_NUM_CHANNELS 4 |
141 | #define SUP_RATE_11G_MAX_NUM_CHANNELS 12 | 135 | #define SUP_RATE_11G_MAX_NUM_CHANNELS 12 |
@@ -280,8 +274,6 @@ extern void iwl3945_config_ap(struct iwl_priv *priv); | |||
280 | */ | 274 | */ |
281 | extern u8 iwl3945_hw_find_station(struct iwl_priv *priv, const u8 *bssid); | 275 | extern u8 iwl3945_hw_find_station(struct iwl_priv *priv, const u8 *bssid); |
282 | 276 | ||
283 | extern int iwl3945_hw_channel_switch(struct iwl_priv *priv, u16 channel); | ||
284 | |||
285 | /* | 277 | /* |
286 | * Forward declare iwl-3945.c functions for iwl-base.c | 278 | * Forward declare iwl-3945.c functions for iwl-base.c |
287 | */ | 279 | */ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965-hw.h b/drivers/net/wireless/iwlwifi/iwl-4965-hw.h index b34322a32458..c606366b582c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965-hw.h +++ b/drivers/net/wireless/iwlwifi/iwl-4965-hw.h | |||
@@ -76,12 +76,9 @@ | |||
76 | 76 | ||
77 | /* | 77 | /* |
78 | * uCode queue management definitions ... | 78 | * uCode queue management definitions ... |
79 | * Queue #4 is the command queue for 3945 and 4965; map it to Tx FIFO chnl 4. | ||
80 | * The first queue used for block-ack aggregation is #7 (4965 only). | 79 | * The first queue used for block-ack aggregation is #7 (4965 only). |
81 | * All block-ack aggregation queues should map to Tx DMA/FIFO channel 7. | 80 | * All block-ack aggregation queues should map to Tx DMA/FIFO channel 7. |
82 | */ | 81 | */ |
83 | #define IWL_CMD_QUEUE_NUM 4 | ||
84 | #define IWL_CMD_FIFO_NUM 4 | ||
85 | #define IWL49_FIRST_AMPDU_QUEUE 7 | 82 | #define IWL49_FIRST_AMPDU_QUEUE 7 |
86 | 83 | ||
87 | /* Time constants */ | 84 | /* Time constants */ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c index f8eed9a4abc1..1ff465ad40d8 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965.c +++ b/drivers/net/wireless/iwlwifi/iwl-4965.c | |||
@@ -62,8 +62,6 @@ static int iwl4965_hw_get_temperature(struct iwl_priv *priv); | |||
62 | 62 | ||
63 | /* module parameters */ | 63 | /* module parameters */ |
64 | static struct iwl_mod_params iwl4965_mod_params = { | 64 | static struct iwl_mod_params iwl4965_mod_params = { |
65 | .num_of_queues = IWL49_NUM_QUEUES, | ||
66 | .num_of_ampdu_queues = IWL49_NUM_AMPDU_QUEUES, | ||
67 | .amsdu_size_8K = 1, | 65 | .amsdu_size_8K = 1, |
68 | .restart_fw = 1, | 66 | .restart_fw = 1, |
69 | /* the rest are 0 by default */ | 67 | /* the rest are 0 by default */ |
@@ -319,64 +317,13 @@ static void iwl4965_txq_set_sched(struct iwl_priv *priv, u32 mask) | |||
319 | iwl_write_prph(priv, IWL49_SCD_TXFACT, mask); | 317 | iwl_write_prph(priv, IWL49_SCD_TXFACT, mask); |
320 | } | 318 | } |
321 | 319 | ||
322 | static int iwl4965_apm_init(struct iwl_priv *priv) | ||
323 | { | ||
324 | int ret = 0; | ||
325 | |||
326 | iwl_set_bit(priv, CSR_GIO_CHICKEN_BITS, | ||
327 | CSR_GIO_CHICKEN_BITS_REG_BIT_DIS_L0S_EXIT_TIMER); | ||
328 | |||
329 | /* disable L0s without affecting L1 :don't wait for ICH L0s bug W/A) */ | ||
330 | iwl_set_bit(priv, CSR_GIO_CHICKEN_BITS, | ||
331 | CSR_GIO_CHICKEN_BITS_REG_BIT_L1A_NO_L0S_RX); | ||
332 | |||
333 | /* set "initialization complete" bit to move adapter | ||
334 | * D0U* --> D0A* state */ | ||
335 | iwl_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE); | ||
336 | |||
337 | /* wait for clock stabilization */ | ||
338 | ret = iwl_poll_bit(priv, CSR_GP_CNTRL, | ||
339 | CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, | ||
340 | CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000); | ||
341 | if (ret < 0) { | ||
342 | IWL_DEBUG_INFO(priv, "Failed to init the card\n"); | ||
343 | goto out; | ||
344 | } | ||
345 | |||
346 | /* enable DMA */ | ||
347 | iwl_write_prph(priv, APMG_CLK_CTRL_REG, APMG_CLK_VAL_DMA_CLK_RQT | | ||
348 | APMG_CLK_VAL_BSM_CLK_RQT); | ||
349 | |||
350 | udelay(20); | ||
351 | |||
352 | /* disable L1-Active */ | ||
353 | iwl_set_bits_prph(priv, APMG_PCIDEV_STT_REG, | ||
354 | APMG_PCIDEV_STT_VAL_L1_ACT_DIS); | ||
355 | |||
356 | out: | ||
357 | return ret; | ||
358 | } | ||
359 | |||
360 | |||
361 | static void iwl4965_nic_config(struct iwl_priv *priv) | 320 | static void iwl4965_nic_config(struct iwl_priv *priv) |
362 | { | 321 | { |
363 | unsigned long flags; | 322 | unsigned long flags; |
364 | u16 radio_cfg; | 323 | u16 radio_cfg; |
365 | u16 lctl; | ||
366 | 324 | ||
367 | spin_lock_irqsave(&priv->lock, flags); | 325 | spin_lock_irqsave(&priv->lock, flags); |
368 | 326 | ||
369 | lctl = iwl_pcie_link_ctl(priv); | ||
370 | |||
371 | /* HW bug W/A - negligible power consumption */ | ||
372 | /* L1-ASPM is enabled by BIOS */ | ||
373 | if ((lctl & PCI_CFG_LINK_CTRL_VAL_L1_EN) == PCI_CFG_LINK_CTRL_VAL_L1_EN) | ||
374 | /* L1-ASPM enabled: disable L0S */ | ||
375 | iwl_set_bit(priv, CSR_GIO_REG, CSR_GIO_REG_VAL_L0S_ENABLED); | ||
376 | else | ||
377 | /* L1-ASPM disabled: enable L0S */ | ||
378 | iwl_clear_bit(priv, CSR_GIO_REG, CSR_GIO_REG_VAL_L0S_ENABLED); | ||
379 | |||
380 | radio_cfg = iwl_eeprom_query16(priv, EEPROM_RADIO_CONFIG); | 327 | radio_cfg = iwl_eeprom_query16(priv, EEPROM_RADIO_CONFIG); |
381 | 328 | ||
382 | /* write radio config values to register */ | 329 | /* write radio config values to register */ |
@@ -397,46 +344,6 @@ static void iwl4965_nic_config(struct iwl_priv *priv) | |||
397 | spin_unlock_irqrestore(&priv->lock, flags); | 344 | spin_unlock_irqrestore(&priv->lock, flags); |
398 | } | 345 | } |
399 | 346 | ||
400 | static int iwl4965_apm_reset(struct iwl_priv *priv) | ||
401 | { | ||
402 | int ret = 0; | ||
403 | |||
404 | iwl_apm_stop_master(priv); | ||
405 | |||
406 | |||
407 | iwl_set_bit(priv, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET); | ||
408 | |||
409 | udelay(10); | ||
410 | |||
411 | /* FIXME: put here L1A -L0S w/a */ | ||
412 | |||
413 | iwl_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE); | ||
414 | |||
415 | ret = iwl_poll_bit(priv, CSR_GP_CNTRL, | ||
416 | CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, | ||
417 | CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000); | ||
418 | if (ret < 0) | ||
419 | goto out; | ||
420 | |||
421 | udelay(10); | ||
422 | |||
423 | /* Enable DMA and BSM Clock */ | ||
424 | iwl_write_prph(priv, APMG_CLK_EN_REG, APMG_CLK_VAL_DMA_CLK_RQT | | ||
425 | APMG_CLK_VAL_BSM_CLK_RQT); | ||
426 | |||
427 | udelay(10); | ||
428 | |||
429 | /* disable L1A */ | ||
430 | iwl_set_bits_prph(priv, APMG_PCIDEV_STT_REG, | ||
431 | APMG_PCIDEV_STT_VAL_L1_ACT_DIS); | ||
432 | |||
433 | clear_bit(STATUS_HCMD_ACTIVE, &priv->status); | ||
434 | wake_up_interruptible(&priv->wait_command_queue); | ||
435 | |||
436 | out: | ||
437 | return ret; | ||
438 | } | ||
439 | |||
440 | /* Reset differential Rx gains in NIC to prepare for chain noise calibration. | 347 | /* Reset differential Rx gains in NIC to prepare for chain noise calibration. |
441 | * Called after every association, but this runs only once! | 348 | * Called after every association, but this runs only once! |
442 | * ... once chain noise is calibrated the first time, it's good forever. */ | 349 | * ... once chain noise is calibrated the first time, it's good forever. */ |
@@ -526,18 +433,6 @@ static void iwl4965_gain_computation(struct iwl_priv *priv, | |||
526 | data->beacon_count = 0; | 433 | data->beacon_count = 0; |
527 | } | 434 | } |
528 | 435 | ||
529 | static void iwl4965_rts_tx_cmd_flag(struct ieee80211_tx_info *info, | ||
530 | __le32 *tx_flags) | ||
531 | { | ||
532 | if (info->control.rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS) { | ||
533 | *tx_flags |= TX_CMD_FLG_RTS_MSK; | ||
534 | *tx_flags &= ~TX_CMD_FLG_CTS_MSK; | ||
535 | } else if (info->control.rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT) { | ||
536 | *tx_flags &= ~TX_CMD_FLG_RTS_MSK; | ||
537 | *tx_flags |= TX_CMD_FLG_CTS_MSK; | ||
538 | } | ||
539 | } | ||
540 | |||
541 | static void iwl4965_bg_txpower_work(struct work_struct *work) | 436 | static void iwl4965_bg_txpower_work(struct work_struct *work) |
542 | { | 437 | { |
543 | struct iwl_priv *priv = container_of(work, struct iwl_priv, | 438 | struct iwl_priv *priv = container_of(work, struct iwl_priv, |
@@ -718,6 +613,10 @@ static struct iwl_sensitivity_ranges iwl4965_sensitivity = { | |||
718 | 613 | ||
719 | .nrg_th_cck = 100, | 614 | .nrg_th_cck = 100, |
720 | .nrg_th_ofdm = 100, | 615 | .nrg_th_ofdm = 100, |
616 | |||
617 | .barker_corr_th_min = 190, | ||
618 | .barker_corr_th_min_mrc = 390, | ||
619 | .nrg_th_cca = 62, | ||
721 | }; | 620 | }; |
722 | 621 | ||
723 | static void iwl4965_set_ct_threshold(struct iwl_priv *priv) | 622 | static void iwl4965_set_ct_threshold(struct iwl_priv *priv) |
@@ -734,19 +633,16 @@ static void iwl4965_set_ct_threshold(struct iwl_priv *priv) | |||
734 | */ | 633 | */ |
735 | static int iwl4965_hw_set_hw_params(struct iwl_priv *priv) | 634 | static int iwl4965_hw_set_hw_params(struct iwl_priv *priv) |
736 | { | 635 | { |
636 | if (priv->cfg->mod_params->num_of_queues >= IWL_MIN_NUM_QUEUES && | ||
637 | priv->cfg->mod_params->num_of_queues <= IWL49_NUM_QUEUES) | ||
638 | priv->cfg->num_of_queues = | ||
639 | priv->cfg->mod_params->num_of_queues; | ||
737 | 640 | ||
738 | if ((priv->cfg->mod_params->num_of_queues > IWL49_NUM_QUEUES) || | 641 | priv->hw_params.max_txq_num = priv->cfg->num_of_queues; |
739 | (priv->cfg->mod_params->num_of_queues < IWL_MIN_NUM_QUEUES)) { | ||
740 | IWL_ERR(priv, | ||
741 | "invalid queues_num, should be between %d and %d\n", | ||
742 | IWL_MIN_NUM_QUEUES, IWL49_NUM_QUEUES); | ||
743 | return -EINVAL; | ||
744 | } | ||
745 | |||
746 | priv->hw_params.max_txq_num = priv->cfg->mod_params->num_of_queues; | ||
747 | priv->hw_params.dma_chnl_num = FH49_TCSR_CHNL_NUM; | 642 | priv->hw_params.dma_chnl_num = FH49_TCSR_CHNL_NUM; |
748 | priv->hw_params.scd_bc_tbls_size = | 643 | priv->hw_params.scd_bc_tbls_size = |
749 | IWL49_NUM_QUEUES * sizeof(struct iwl4965_scd_bc_tbl); | 644 | priv->cfg->num_of_queues * |
645 | sizeof(struct iwl4965_scd_bc_tbl); | ||
750 | priv->hw_params.tfd_size = sizeof(struct iwl_tfd); | 646 | priv->hw_params.tfd_size = sizeof(struct iwl_tfd); |
751 | priv->hw_params.max_stations = IWL4965_STATION_COUNT; | 647 | priv->hw_params.max_stations = IWL4965_STATION_COUNT; |
752 | priv->hw_params.bcast_sta_id = IWL4965_BROADCAST_ID; | 648 | priv->hw_params.bcast_sta_id = IWL4965_BROADCAST_ID; |
@@ -757,10 +653,10 @@ static int iwl4965_hw_set_hw_params(struct iwl_priv *priv) | |||
757 | 653 | ||
758 | priv->hw_params.rx_wrt_ptr_reg = FH_RSCSR_CHNL0_WPTR; | 654 | priv->hw_params.rx_wrt_ptr_reg = FH_RSCSR_CHNL0_WPTR; |
759 | 655 | ||
760 | priv->hw_params.tx_chains_num = 2; | 656 | priv->hw_params.tx_chains_num = num_of_ant(priv->cfg->valid_tx_ant); |
761 | priv->hw_params.rx_chains_num = 2; | 657 | priv->hw_params.rx_chains_num = num_of_ant(priv->cfg->valid_rx_ant); |
762 | priv->hw_params.valid_tx_ant = ANT_A | ANT_B; | 658 | priv->hw_params.valid_tx_ant = priv->cfg->valid_tx_ant; |
763 | priv->hw_params.valid_rx_ant = ANT_A | ANT_B; | 659 | priv->hw_params.valid_rx_ant = priv->cfg->valid_rx_ant; |
764 | if (priv->cfg->ops->lib->temp_ops.set_ct_kill) | 660 | if (priv->cfg->ops->lib->temp_ops.set_ct_kill) |
765 | priv->cfg->ops->lib->temp_ops.set_ct_kill(priv); | 661 | priv->cfg->ops->lib->temp_ops.set_ct_kill(priv); |
766 | 662 | ||
@@ -1537,14 +1433,13 @@ static int iwl4965_send_rxon_assoc(struct iwl_priv *priv) | |||
1537 | return ret; | 1433 | return ret; |
1538 | } | 1434 | } |
1539 | 1435 | ||
1540 | #ifdef IEEE80211_CONF_CHANNEL_SWITCH | ||
1541 | static int iwl4965_hw_channel_switch(struct iwl_priv *priv, u16 channel) | 1436 | static int iwl4965_hw_channel_switch(struct iwl_priv *priv, u16 channel) |
1542 | { | 1437 | { |
1543 | int rc; | 1438 | int rc; |
1544 | u8 band = 0; | 1439 | u8 band = 0; |
1545 | bool is_ht40 = false; | 1440 | bool is_ht40 = false; |
1546 | u8 ctrl_chan_high = 0; | 1441 | u8 ctrl_chan_high = 0; |
1547 | struct iwl4965_channel_switch_cmd cmd = { 0 }; | 1442 | struct iwl4965_channel_switch_cmd cmd; |
1548 | const struct iwl_channel_info *ch_info; | 1443 | const struct iwl_channel_info *ch_info; |
1549 | 1444 | ||
1550 | band = priv->band == IEEE80211_BAND_2GHZ; | 1445 | band = priv->band == IEEE80211_BAND_2GHZ; |
@@ -1565,8 +1460,11 @@ static int iwl4965_hw_channel_switch(struct iwl_priv *priv, u16 channel) | |||
1565 | cmd.switch_time = cpu_to_le32(priv->ucode_beacon_time); | 1460 | cmd.switch_time = cpu_to_le32(priv->ucode_beacon_time); |
1566 | if (ch_info) | 1461 | if (ch_info) |
1567 | cmd.expect_beacon = is_channel_radar(ch_info); | 1462 | cmd.expect_beacon = is_channel_radar(ch_info); |
1568 | else | 1463 | else { |
1569 | cmd.expect_beacon = 1; | 1464 | IWL_ERR(priv, "invalid channel switch from %u to %u\n", |
1465 | priv->active_rxon.channel, channel); | ||
1466 | return -EFAULT; | ||
1467 | } | ||
1570 | 1468 | ||
1571 | rc = iwl4965_fill_txpower_tbl(priv, band, channel, is_ht40, | 1469 | rc = iwl4965_fill_txpower_tbl(priv, band, channel, is_ht40, |
1572 | ctrl_chan_high, &cmd.tx_power); | 1470 | ctrl_chan_high, &cmd.tx_power); |
@@ -1578,7 +1476,6 @@ static int iwl4965_hw_channel_switch(struct iwl_priv *priv, u16 channel) | |||
1578 | rc = iwl_send_cmd_pdu(priv, REPLY_CHANNEL_SWITCH, sizeof(cmd), &cmd); | 1476 | rc = iwl_send_cmd_pdu(priv, REPLY_CHANNEL_SWITCH, sizeof(cmd), &cmd); |
1579 | return rc; | 1477 | return rc; |
1580 | } | 1478 | } |
1581 | #endif | ||
1582 | 1479 | ||
1583 | /** | 1480 | /** |
1584 | * iwl4965_txq_update_byte_cnt_tbl - Set up entry in Tx byte-count array | 1481 | * iwl4965_txq_update_byte_cnt_tbl - Set up entry in Tx byte-count array |
@@ -1775,11 +1672,13 @@ static int iwl4965_txq_agg_disable(struct iwl_priv *priv, u16 txq_id, | |||
1775 | u16 ssn_idx, u8 tx_fifo) | 1672 | u16 ssn_idx, u8 tx_fifo) |
1776 | { | 1673 | { |
1777 | if ((IWL49_FIRST_AMPDU_QUEUE > txq_id) || | 1674 | if ((IWL49_FIRST_AMPDU_QUEUE > txq_id) || |
1778 | (IWL49_FIRST_AMPDU_QUEUE + IWL49_NUM_AMPDU_QUEUES <= txq_id)) { | 1675 | (IWL49_FIRST_AMPDU_QUEUE + priv->cfg->num_of_ampdu_queues |
1676 | <= txq_id)) { | ||
1779 | IWL_WARN(priv, | 1677 | IWL_WARN(priv, |
1780 | "queue number out of range: %d, must be %d to %d\n", | 1678 | "queue number out of range: %d, must be %d to %d\n", |
1781 | txq_id, IWL49_FIRST_AMPDU_QUEUE, | 1679 | txq_id, IWL49_FIRST_AMPDU_QUEUE, |
1782 | IWL49_FIRST_AMPDU_QUEUE + IWL49_NUM_AMPDU_QUEUES - 1); | 1680 | IWL49_FIRST_AMPDU_QUEUE + |
1681 | priv->cfg->num_of_ampdu_queues - 1); | ||
1783 | return -EINVAL; | 1682 | return -EINVAL; |
1784 | } | 1683 | } |
1785 | 1684 | ||
@@ -1840,11 +1739,13 @@ static int iwl4965_txq_agg_enable(struct iwl_priv *priv, int txq_id, | |||
1840 | u16 ra_tid; | 1739 | u16 ra_tid; |
1841 | 1740 | ||
1842 | if ((IWL49_FIRST_AMPDU_QUEUE > txq_id) || | 1741 | if ((IWL49_FIRST_AMPDU_QUEUE > txq_id) || |
1843 | (IWL49_FIRST_AMPDU_QUEUE + IWL49_NUM_AMPDU_QUEUES <= txq_id)) { | 1742 | (IWL49_FIRST_AMPDU_QUEUE + priv->cfg->num_of_ampdu_queues |
1743 | <= txq_id)) { | ||
1844 | IWL_WARN(priv, | 1744 | IWL_WARN(priv, |
1845 | "queue number out of range: %d, must be %d to %d\n", | 1745 | "queue number out of range: %d, must be %d to %d\n", |
1846 | txq_id, IWL49_FIRST_AMPDU_QUEUE, | 1746 | txq_id, IWL49_FIRST_AMPDU_QUEUE, |
1847 | IWL49_FIRST_AMPDU_QUEUE + IWL49_NUM_AMPDU_QUEUES - 1); | 1747 | IWL49_FIRST_AMPDU_QUEUE + |
1748 | priv->cfg->num_of_ampdu_queues - 1); | ||
1848 | return -EINVAL; | 1749 | return -EINVAL; |
1849 | } | 1750 | } |
1850 | 1751 | ||
@@ -2048,7 +1949,7 @@ static int iwl4965_tx_status_reply_tx(struct iwl_priv *priv, | |||
2048 | static void iwl4965_rx_reply_tx(struct iwl_priv *priv, | 1949 | static void iwl4965_rx_reply_tx(struct iwl_priv *priv, |
2049 | struct iwl_rx_mem_buffer *rxb) | 1950 | struct iwl_rx_mem_buffer *rxb) |
2050 | { | 1951 | { |
2051 | struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; | 1952 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
2052 | u16 sequence = le16_to_cpu(pkt->hdr.sequence); | 1953 | u16 sequence = le16_to_cpu(pkt->hdr.sequence); |
2053 | int txq_id = SEQ_TO_QUEUE(sequence); | 1954 | int txq_id = SEQ_TO_QUEUE(sequence); |
2054 | int index = SEQ_TO_INDEX(sequence); | 1955 | int index = SEQ_TO_INDEX(sequence); |
@@ -2249,7 +2150,7 @@ static struct iwl_hcmd_utils_ops iwl4965_hcmd_utils = { | |||
2249 | .build_addsta_hcmd = iwl4965_build_addsta_hcmd, | 2150 | .build_addsta_hcmd = iwl4965_build_addsta_hcmd, |
2250 | .chain_noise_reset = iwl4965_chain_noise_reset, | 2151 | .chain_noise_reset = iwl4965_chain_noise_reset, |
2251 | .gain_computation = iwl4965_gain_computation, | 2152 | .gain_computation = iwl4965_gain_computation, |
2252 | .rts_tx_cmd_flag = iwl4965_rts_tx_cmd_flag, | 2153 | .rts_tx_cmd_flag = iwlcore_rts_tx_cmd_flag, |
2253 | .calc_rssi = iwl4965_calc_rssi, | 2154 | .calc_rssi = iwl4965_calc_rssi, |
2254 | }; | 2155 | }; |
2255 | 2156 | ||
@@ -2271,9 +2172,9 @@ static struct iwl_lib_ops iwl4965_lib = { | |||
2271 | .load_ucode = iwl4965_load_bsm, | 2172 | .load_ucode = iwl4965_load_bsm, |
2272 | .dump_nic_event_log = iwl_dump_nic_event_log, | 2173 | .dump_nic_event_log = iwl_dump_nic_event_log, |
2273 | .dump_nic_error_log = iwl_dump_nic_error_log, | 2174 | .dump_nic_error_log = iwl_dump_nic_error_log, |
2175 | .set_channel_switch = iwl4965_hw_channel_switch, | ||
2274 | .apm_ops = { | 2176 | .apm_ops = { |
2275 | .init = iwl4965_apm_init, | 2177 | .init = iwl_apm_init, |
2276 | .reset = iwl4965_apm_reset, | ||
2277 | .stop = iwl_apm_stop, | 2178 | .stop = iwl_apm_stop, |
2278 | .config = iwl4965_nic_config, | 2179 | .config = iwl4965_nic_config, |
2279 | .set_pwr_src = iwl_set_pwr_src, | 2180 | .set_pwr_src = iwl_set_pwr_src, |
@@ -2323,7 +2224,14 @@ struct iwl_cfg iwl4965_agn_cfg = { | |||
2323 | .eeprom_ver = EEPROM_4965_EEPROM_VERSION, | 2224 | .eeprom_ver = EEPROM_4965_EEPROM_VERSION, |
2324 | .eeprom_calib_ver = EEPROM_4965_TX_POWER_VERSION, | 2225 | .eeprom_calib_ver = EEPROM_4965_TX_POWER_VERSION, |
2325 | .ops = &iwl4965_ops, | 2226 | .ops = &iwl4965_ops, |
2227 | .num_of_queues = IWL49_NUM_QUEUES, | ||
2228 | .num_of_ampdu_queues = IWL49_NUM_AMPDU_QUEUES, | ||
2326 | .mod_params = &iwl4965_mod_params, | 2229 | .mod_params = &iwl4965_mod_params, |
2230 | .valid_tx_ant = ANT_AB, | ||
2231 | .valid_rx_ant = ANT_AB, | ||
2232 | .pll_cfg_val = 0, | ||
2233 | .set_l0s = true, | ||
2234 | .use_bsm = true, | ||
2327 | .use_isr_legacy = true, | 2235 | .use_isr_legacy = true, |
2328 | .ht_greenfield_support = false, | 2236 | .ht_greenfield_support = false, |
2329 | .broken_powersave = true, | 2237 | .broken_powersave = true, |
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index 8cc3d50e7f59..d256fecc6cda 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c | |||
@@ -72,115 +72,14 @@ static const u16 iwl5000_default_queue_to_tx_fifo[] = { | |||
72 | IWL_TX_FIFO_HCCA_2 | 72 | IWL_TX_FIFO_HCCA_2 |
73 | }; | 73 | }; |
74 | 74 | ||
75 | int iwl5000_apm_init(struct iwl_priv *priv) | ||
76 | { | ||
77 | int ret = 0; | ||
78 | |||
79 | iwl_set_bit(priv, CSR_GIO_CHICKEN_BITS, | ||
80 | CSR_GIO_CHICKEN_BITS_REG_BIT_DIS_L0S_EXIT_TIMER); | ||
81 | |||
82 | /* disable L0s without affecting L1 :don't wait for ICH L0s bug W/A) */ | ||
83 | iwl_set_bit(priv, CSR_GIO_CHICKEN_BITS, | ||
84 | CSR_GIO_CHICKEN_BITS_REG_BIT_L1A_NO_L0S_RX); | ||
85 | |||
86 | /* Set FH wait threshold to maximum (HW error during stress W/A) */ | ||
87 | iwl_set_bit(priv, CSR_DBG_HPET_MEM_REG, CSR_DBG_HPET_MEM_REG_VAL); | ||
88 | |||
89 | /* enable HAP INTA to move device L1a -> L0s */ | ||
90 | iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG, | ||
91 | CSR_HW_IF_CONFIG_REG_BIT_HAP_WAKE_L1A); | ||
92 | |||
93 | if (priv->cfg->need_pll_cfg) | ||
94 | iwl_set_bit(priv, CSR_ANA_PLL_CFG, CSR50_ANA_PLL_CFG_VAL); | ||
95 | |||
96 | /* set "initialization complete" bit to move adapter | ||
97 | * D0U* --> D0A* state */ | ||
98 | iwl_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE); | ||
99 | |||
100 | /* wait for clock stabilization */ | ||
101 | ret = iwl_poll_bit(priv, CSR_GP_CNTRL, | ||
102 | CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, | ||
103 | CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000); | ||
104 | if (ret < 0) { | ||
105 | IWL_DEBUG_INFO(priv, "Failed to init the card\n"); | ||
106 | return ret; | ||
107 | } | ||
108 | |||
109 | /* enable DMA */ | ||
110 | iwl_write_prph(priv, APMG_CLK_EN_REG, APMG_CLK_VAL_DMA_CLK_RQT); | ||
111 | |||
112 | udelay(20); | ||
113 | |||
114 | /* disable L1-Active */ | ||
115 | iwl_set_bits_prph(priv, APMG_PCIDEV_STT_REG, | ||
116 | APMG_PCIDEV_STT_VAL_L1_ACT_DIS); | ||
117 | |||
118 | return ret; | ||
119 | } | ||
120 | |||
121 | int iwl5000_apm_reset(struct iwl_priv *priv) | ||
122 | { | ||
123 | int ret = 0; | ||
124 | |||
125 | iwl_apm_stop_master(priv); | ||
126 | |||
127 | iwl_set_bit(priv, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET); | ||
128 | |||
129 | udelay(10); | ||
130 | |||
131 | |||
132 | /* FIXME: put here L1A -L0S w/a */ | ||
133 | |||
134 | if (priv->cfg->need_pll_cfg) | ||
135 | iwl_set_bit(priv, CSR_ANA_PLL_CFG, CSR50_ANA_PLL_CFG_VAL); | ||
136 | |||
137 | /* set "initialization complete" bit to move adapter | ||
138 | * D0U* --> D0A* state */ | ||
139 | iwl_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE); | ||
140 | |||
141 | /* wait for clock stabilization */ | ||
142 | ret = iwl_poll_bit(priv, CSR_GP_CNTRL, | ||
143 | CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, | ||
144 | CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000); | ||
145 | if (ret < 0) { | ||
146 | IWL_DEBUG_INFO(priv, "Failed to init the card\n"); | ||
147 | goto out; | ||
148 | } | ||
149 | |||
150 | /* enable DMA */ | ||
151 | iwl_write_prph(priv, APMG_CLK_EN_REG, APMG_CLK_VAL_DMA_CLK_RQT); | ||
152 | |||
153 | udelay(20); | ||
154 | |||
155 | /* disable L1-Active */ | ||
156 | iwl_set_bits_prph(priv, APMG_PCIDEV_STT_REG, | ||
157 | APMG_PCIDEV_STT_VAL_L1_ACT_DIS); | ||
158 | out: | ||
159 | |||
160 | return ret; | ||
161 | } | ||
162 | |||
163 | |||
164 | /* NIC configuration for 5000 series */ | 75 | /* NIC configuration for 5000 series */ |
165 | void iwl5000_nic_config(struct iwl_priv *priv) | 76 | void iwl5000_nic_config(struct iwl_priv *priv) |
166 | { | 77 | { |
167 | unsigned long flags; | 78 | unsigned long flags; |
168 | u16 radio_cfg; | 79 | u16 radio_cfg; |
169 | u16 lctl; | ||
170 | 80 | ||
171 | spin_lock_irqsave(&priv->lock, flags); | 81 | spin_lock_irqsave(&priv->lock, flags); |
172 | 82 | ||
173 | lctl = iwl_pcie_link_ctl(priv); | ||
174 | |||
175 | /* HW bug W/A */ | ||
176 | /* L1-ASPM is enabled by BIOS */ | ||
177 | if ((lctl & PCI_CFG_LINK_CTRL_VAL_L1_EN) == PCI_CFG_LINK_CTRL_VAL_L1_EN) | ||
178 | /* L1-APSM enabled: disable L0S */ | ||
179 | iwl_set_bit(priv, CSR_GIO_REG, CSR_GIO_REG_VAL_L0S_ENABLED); | ||
180 | else | ||
181 | /* L1-ASPM disabled: enable L0S */ | ||
182 | iwl_clear_bit(priv, CSR_GIO_REG, CSR_GIO_REG_VAL_L0S_ENABLED); | ||
183 | |||
184 | radio_cfg = iwl_eeprom_query16(priv, EEPROM_RADIO_CONFIG); | 83 | radio_cfg = iwl_eeprom_query16(priv, EEPROM_RADIO_CONFIG); |
185 | 84 | ||
186 | /* write radio config values to register */ | 85 | /* write radio config values to register */ |
@@ -279,7 +178,7 @@ static void iwl5000_gain_computation(struct iwl_priv *priv, | |||
279 | data->delta_gain_code[i] = 0; | 178 | data->delta_gain_code[i] = 0; |
280 | continue; | 179 | continue; |
281 | } | 180 | } |
282 | delta_g = (1000 * ((s32)average_noise[0] - | 181 | delta_g = (1000 * ((s32)average_noise[default_chain] - |
283 | (s32)average_noise[i])) / 1500; | 182 | (s32)average_noise[i])) / 1500; |
284 | /* bound gain by 2 bits value max, 3rd bit is sign */ | 183 | /* bound gain by 2 bits value max, 3rd bit is sign */ |
285 | data->delta_gain_code[i] = | 184 | data->delta_gain_code[i] = |
@@ -372,6 +271,10 @@ static struct iwl_sensitivity_ranges iwl5000_sensitivity = { | |||
372 | .auto_corr_max_cck_mrc = 400, | 271 | .auto_corr_max_cck_mrc = 400, |
373 | .nrg_th_cck = 95, | 272 | .nrg_th_cck = 95, |
374 | .nrg_th_ofdm = 95, | 273 | .nrg_th_ofdm = 95, |
274 | |||
275 | .barker_corr_th_min = 190, | ||
276 | .barker_corr_th_min_mrc = 390, | ||
277 | .nrg_th_cca = 62, | ||
375 | }; | 278 | }; |
376 | 279 | ||
377 | static struct iwl_sensitivity_ranges iwl5150_sensitivity = { | 280 | static struct iwl_sensitivity_ranges iwl5150_sensitivity = { |
@@ -394,6 +297,10 @@ static struct iwl_sensitivity_ranges iwl5150_sensitivity = { | |||
394 | .auto_corr_max_cck_mrc = 400, | 297 | .auto_corr_max_cck_mrc = 400, |
395 | .nrg_th_cck = 95, | 298 | .nrg_th_cck = 95, |
396 | .nrg_th_ofdm = 95, | 299 | .nrg_th_ofdm = 95, |
300 | |||
301 | .barker_corr_th_min = 190, | ||
302 | .barker_corr_th_min_mrc = 390, | ||
303 | .nrg_th_cca = 62, | ||
397 | }; | 304 | }; |
398 | 305 | ||
399 | const u8 *iwl5000_eeprom_query_addr(const struct iwl_priv *priv, | 306 | const u8 *iwl5000_eeprom_query_addr(const struct iwl_priv *priv, |
@@ -458,7 +365,7 @@ static int iwl5000_send_calib_cfg(struct iwl_priv *priv) | |||
458 | static void iwl5000_rx_calib_result(struct iwl_priv *priv, | 365 | static void iwl5000_rx_calib_result(struct iwl_priv *priv, |
459 | struct iwl_rx_mem_buffer *rxb) | 366 | struct iwl_rx_mem_buffer *rxb) |
460 | { | 367 | { |
461 | struct iwl_rx_packet *pkt = (void *)rxb->skb->data; | 368 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
462 | struct iwl_calib_hdr *hdr = (struct iwl_calib_hdr *)pkt->u.raw; | 369 | struct iwl_calib_hdr *hdr = (struct iwl_calib_hdr *)pkt->u.raw; |
463 | int len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK; | 370 | int len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK; |
464 | int index; | 371 | int index; |
@@ -784,18 +691,16 @@ int iwl5000_alive_notify(struct iwl_priv *priv) | |||
784 | 691 | ||
785 | int iwl5000_hw_set_hw_params(struct iwl_priv *priv) | 692 | int iwl5000_hw_set_hw_params(struct iwl_priv *priv) |
786 | { | 693 | { |
787 | if ((priv->cfg->mod_params->num_of_queues > IWL50_NUM_QUEUES) || | 694 | if (priv->cfg->mod_params->num_of_queues >= IWL_MIN_NUM_QUEUES && |
788 | (priv->cfg->mod_params->num_of_queues < IWL_MIN_NUM_QUEUES)) { | 695 | priv->cfg->mod_params->num_of_queues <= IWL50_NUM_QUEUES) |
789 | IWL_ERR(priv, | 696 | priv->cfg->num_of_queues = |
790 | "invalid queues_num, should be between %d and %d\n", | 697 | priv->cfg->mod_params->num_of_queues; |
791 | IWL_MIN_NUM_QUEUES, IWL50_NUM_QUEUES); | ||
792 | return -EINVAL; | ||
793 | } | ||
794 | 698 | ||
795 | priv->hw_params.max_txq_num = priv->cfg->mod_params->num_of_queues; | 699 | priv->hw_params.max_txq_num = priv->cfg->num_of_queues; |
796 | priv->hw_params.dma_chnl_num = FH50_TCSR_CHNL_NUM; | 700 | priv->hw_params.dma_chnl_num = FH50_TCSR_CHNL_NUM; |
797 | priv->hw_params.scd_bc_tbls_size = | 701 | priv->hw_params.scd_bc_tbls_size = |
798 | IWL50_NUM_QUEUES * sizeof(struct iwl5000_scd_bc_tbl); | 702 | priv->cfg->num_of_queues * |
703 | sizeof(struct iwl5000_scd_bc_tbl); | ||
799 | priv->hw_params.tfd_size = sizeof(struct iwl_tfd); | 704 | priv->hw_params.tfd_size = sizeof(struct iwl_tfd); |
800 | priv->hw_params.max_stations = IWL5000_STATION_COUNT; | 705 | priv->hw_params.max_stations = IWL5000_STATION_COUNT; |
801 | priv->hw_params.bcast_sta_id = IWL5000_BROADCAST_ID; | 706 | priv->hw_params.bcast_sta_id = IWL5000_BROADCAST_ID; |
@@ -947,11 +852,13 @@ int iwl5000_txq_agg_enable(struct iwl_priv *priv, int txq_id, | |||
947 | u16 ra_tid; | 852 | u16 ra_tid; |
948 | 853 | ||
949 | if ((IWL50_FIRST_AMPDU_QUEUE > txq_id) || | 854 | if ((IWL50_FIRST_AMPDU_QUEUE > txq_id) || |
950 | (IWL50_FIRST_AMPDU_QUEUE + IWL50_NUM_AMPDU_QUEUES <= txq_id)) { | 855 | (IWL50_FIRST_AMPDU_QUEUE + priv->cfg->num_of_ampdu_queues |
856 | <= txq_id)) { | ||
951 | IWL_WARN(priv, | 857 | IWL_WARN(priv, |
952 | "queue number out of range: %d, must be %d to %d\n", | 858 | "queue number out of range: %d, must be %d to %d\n", |
953 | txq_id, IWL50_FIRST_AMPDU_QUEUE, | 859 | txq_id, IWL50_FIRST_AMPDU_QUEUE, |
954 | IWL50_FIRST_AMPDU_QUEUE + IWL50_NUM_AMPDU_QUEUES - 1); | 860 | IWL50_FIRST_AMPDU_QUEUE + |
861 | priv->cfg->num_of_ampdu_queues - 1); | ||
955 | return -EINVAL; | 862 | return -EINVAL; |
956 | } | 863 | } |
957 | 864 | ||
@@ -1005,11 +912,13 @@ int iwl5000_txq_agg_disable(struct iwl_priv *priv, u16 txq_id, | |||
1005 | u16 ssn_idx, u8 tx_fifo) | 912 | u16 ssn_idx, u8 tx_fifo) |
1006 | { | 913 | { |
1007 | if ((IWL50_FIRST_AMPDU_QUEUE > txq_id) || | 914 | if ((IWL50_FIRST_AMPDU_QUEUE > txq_id) || |
1008 | (IWL50_FIRST_AMPDU_QUEUE + IWL50_NUM_AMPDU_QUEUES <= txq_id)) { | 915 | (IWL50_FIRST_AMPDU_QUEUE + priv->cfg->num_of_ampdu_queues |
916 | <= txq_id)) { | ||
1009 | IWL_ERR(priv, | 917 | IWL_ERR(priv, |
1010 | "queue number out of range: %d, must be %d to %d\n", | 918 | "queue number out of range: %d, must be %d to %d\n", |
1011 | txq_id, IWL50_FIRST_AMPDU_QUEUE, | 919 | txq_id, IWL50_FIRST_AMPDU_QUEUE, |
1012 | IWL50_FIRST_AMPDU_QUEUE + IWL50_NUM_AMPDU_QUEUES - 1); | 920 | IWL50_FIRST_AMPDU_QUEUE + |
921 | priv->cfg->num_of_ampdu_queues - 1); | ||
1013 | return -EINVAL; | 922 | return -EINVAL; |
1014 | } | 923 | } |
1015 | 924 | ||
@@ -1176,7 +1085,7 @@ static int iwl5000_tx_status_reply_tx(struct iwl_priv *priv, | |||
1176 | static void iwl5000_rx_reply_tx(struct iwl_priv *priv, | 1085 | static void iwl5000_rx_reply_tx(struct iwl_priv *priv, |
1177 | struct iwl_rx_mem_buffer *rxb) | 1086 | struct iwl_rx_mem_buffer *rxb) |
1178 | { | 1087 | { |
1179 | struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; | 1088 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
1180 | u16 sequence = le16_to_cpu(pkt->hdr.sequence); | 1089 | u16 sequence = le16_to_cpu(pkt->hdr.sequence); |
1181 | int txq_id = SEQ_TO_QUEUE(sequence); | 1090 | int txq_id = SEQ_TO_QUEUE(sequence); |
1182 | int index = SEQ_TO_INDEX(sequence); | 1091 | int index = SEQ_TO_INDEX(sequence); |
@@ -1473,6 +1382,36 @@ IWL5000_UCODE_GET(init_size); | |||
1473 | IWL5000_UCODE_GET(init_data_size); | 1382 | IWL5000_UCODE_GET(init_data_size); |
1474 | IWL5000_UCODE_GET(boot_size); | 1383 | IWL5000_UCODE_GET(boot_size); |
1475 | 1384 | ||
1385 | static int iwl5000_hw_channel_switch(struct iwl_priv *priv, u16 channel) | ||
1386 | { | ||
1387 | struct iwl5000_channel_switch_cmd cmd; | ||
1388 | const struct iwl_channel_info *ch_info; | ||
1389 | struct iwl_host_cmd hcmd = { | ||
1390 | .id = REPLY_CHANNEL_SWITCH, | ||
1391 | .len = sizeof(cmd), | ||
1392 | .flags = CMD_SIZE_HUGE, | ||
1393 | .data = &cmd, | ||
1394 | }; | ||
1395 | |||
1396 | IWL_DEBUG_11H(priv, "channel switch from %d to %d\n", | ||
1397 | priv->active_rxon.channel, channel); | ||
1398 | cmd.band = priv->band == IEEE80211_BAND_2GHZ; | ||
1399 | cmd.channel = cpu_to_le16(channel); | ||
1400 | cmd.rxon_flags = priv->active_rxon.flags; | ||
1401 | cmd.rxon_filter_flags = priv->active_rxon.filter_flags; | ||
1402 | cmd.switch_time = cpu_to_le32(priv->ucode_beacon_time); | ||
1403 | ch_info = iwl_get_channel_info(priv, priv->band, channel); | ||
1404 | if (ch_info) | ||
1405 | cmd.expect_beacon = is_channel_radar(ch_info); | ||
1406 | else { | ||
1407 | IWL_ERR(priv, "invalid channel switch from %u to %u\n", | ||
1408 | priv->active_rxon.channel, channel); | ||
1409 | return -EFAULT; | ||
1410 | } | ||
1411 | |||
1412 | return iwl_send_cmd_sync(priv, &hcmd); | ||
1413 | } | ||
1414 | |||
1476 | struct iwl_hcmd_ops iwl5000_hcmd = { | 1415 | struct iwl_hcmd_ops iwl5000_hcmd = { |
1477 | .rxon_assoc = iwl5000_send_rxon_assoc, | 1416 | .rxon_assoc = iwl5000_send_rxon_assoc, |
1478 | .commit_rxon = iwl_commit_rxon, | 1417 | .commit_rxon = iwl_commit_rxon, |
@@ -1520,9 +1459,9 @@ struct iwl_lib_ops iwl5000_lib = { | |||
1520 | .alive_notify = iwl5000_alive_notify, | 1459 | .alive_notify = iwl5000_alive_notify, |
1521 | .send_tx_power = iwl5000_send_tx_power, | 1460 | .send_tx_power = iwl5000_send_tx_power, |
1522 | .update_chain_flags = iwl_update_chain_flags, | 1461 | .update_chain_flags = iwl_update_chain_flags, |
1462 | .set_channel_switch = iwl5000_hw_channel_switch, | ||
1523 | .apm_ops = { | 1463 | .apm_ops = { |
1524 | .init = iwl5000_apm_init, | 1464 | .init = iwl_apm_init, |
1525 | .reset = iwl5000_apm_reset, | ||
1526 | .stop = iwl_apm_stop, | 1465 | .stop = iwl_apm_stop, |
1527 | .config = iwl5000_nic_config, | 1466 | .config = iwl5000_nic_config, |
1528 | .set_pwr_src = iwl_set_pwr_src, | 1467 | .set_pwr_src = iwl_set_pwr_src, |
@@ -1572,9 +1511,9 @@ static struct iwl_lib_ops iwl5150_lib = { | |||
1572 | .alive_notify = iwl5000_alive_notify, | 1511 | .alive_notify = iwl5000_alive_notify, |
1573 | .send_tx_power = iwl5000_send_tx_power, | 1512 | .send_tx_power = iwl5000_send_tx_power, |
1574 | .update_chain_flags = iwl_update_chain_flags, | 1513 | .update_chain_flags = iwl_update_chain_flags, |
1514 | .set_channel_switch = iwl5000_hw_channel_switch, | ||
1575 | .apm_ops = { | 1515 | .apm_ops = { |
1576 | .init = iwl5000_apm_init, | 1516 | .init = iwl_apm_init, |
1577 | .reset = iwl5000_apm_reset, | ||
1578 | .stop = iwl_apm_stop, | 1517 | .stop = iwl_apm_stop, |
1579 | .config = iwl5000_nic_config, | 1518 | .config = iwl5000_nic_config, |
1580 | .set_pwr_src = iwl_set_pwr_src, | 1519 | .set_pwr_src = iwl_set_pwr_src, |
@@ -1621,8 +1560,6 @@ static struct iwl_ops iwl5150_ops = { | |||
1621 | }; | 1560 | }; |
1622 | 1561 | ||
1623 | struct iwl_mod_params iwl50_mod_params = { | 1562 | struct iwl_mod_params iwl50_mod_params = { |
1624 | .num_of_queues = IWL50_NUM_QUEUES, | ||
1625 | .num_of_ampdu_queues = IWL50_NUM_AMPDU_QUEUES, | ||
1626 | .amsdu_size_8K = 1, | 1563 | .amsdu_size_8K = 1, |
1627 | .restart_fw = 1, | 1564 | .restart_fw = 1, |
1628 | /* the rest are 0 by default */ | 1565 | /* the rest are 0 by default */ |
@@ -1639,10 +1576,14 @@ struct iwl_cfg iwl5300_agn_cfg = { | |||
1639 | .eeprom_size = IWL_5000_EEPROM_IMG_SIZE, | 1576 | .eeprom_size = IWL_5000_EEPROM_IMG_SIZE, |
1640 | .eeprom_ver = EEPROM_5000_EEPROM_VERSION, | 1577 | .eeprom_ver = EEPROM_5000_EEPROM_VERSION, |
1641 | .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, | 1578 | .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, |
1579 | .num_of_queues = IWL50_NUM_QUEUES, | ||
1580 | .num_of_ampdu_queues = IWL50_NUM_AMPDU_QUEUES, | ||
1642 | .mod_params = &iwl50_mod_params, | 1581 | .mod_params = &iwl50_mod_params, |
1643 | .valid_tx_ant = ANT_ABC, | 1582 | .valid_tx_ant = ANT_ABC, |
1644 | .valid_rx_ant = ANT_ABC, | 1583 | .valid_rx_ant = ANT_ABC, |
1645 | .need_pll_cfg = true, | 1584 | .pll_cfg_val = CSR50_ANA_PLL_CFG_VAL, |
1585 | .set_l0s = true, | ||
1586 | .use_bsm = false, | ||
1646 | .ht_greenfield_support = true, | 1587 | .ht_greenfield_support = true, |
1647 | .led_compensation = 51, | 1588 | .led_compensation = 51, |
1648 | .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, | 1589 | .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, |
@@ -1658,10 +1599,14 @@ struct iwl_cfg iwl5100_bg_cfg = { | |||
1658 | .eeprom_size = IWL_5000_EEPROM_IMG_SIZE, | 1599 | .eeprom_size = IWL_5000_EEPROM_IMG_SIZE, |
1659 | .eeprom_ver = EEPROM_5000_EEPROM_VERSION, | 1600 | .eeprom_ver = EEPROM_5000_EEPROM_VERSION, |
1660 | .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, | 1601 | .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, |
1602 | .num_of_queues = IWL50_NUM_QUEUES, | ||
1603 | .num_of_ampdu_queues = IWL50_NUM_AMPDU_QUEUES, | ||
1661 | .mod_params = &iwl50_mod_params, | 1604 | .mod_params = &iwl50_mod_params, |
1662 | .valid_tx_ant = ANT_B, | 1605 | .valid_tx_ant = ANT_B, |
1663 | .valid_rx_ant = ANT_AB, | 1606 | .valid_rx_ant = ANT_AB, |
1664 | .need_pll_cfg = true, | 1607 | .pll_cfg_val = CSR50_ANA_PLL_CFG_VAL, |
1608 | .set_l0s = true, | ||
1609 | .use_bsm = false, | ||
1665 | .ht_greenfield_support = true, | 1610 | .ht_greenfield_support = true, |
1666 | .led_compensation = 51, | 1611 | .led_compensation = 51, |
1667 | .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, | 1612 | .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, |
@@ -1677,10 +1622,14 @@ struct iwl_cfg iwl5100_abg_cfg = { | |||
1677 | .eeprom_size = IWL_5000_EEPROM_IMG_SIZE, | 1622 | .eeprom_size = IWL_5000_EEPROM_IMG_SIZE, |
1678 | .eeprom_ver = EEPROM_5000_EEPROM_VERSION, | 1623 | .eeprom_ver = EEPROM_5000_EEPROM_VERSION, |
1679 | .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, | 1624 | .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, |
1625 | .num_of_queues = IWL50_NUM_QUEUES, | ||
1626 | .num_of_ampdu_queues = IWL50_NUM_AMPDU_QUEUES, | ||
1680 | .mod_params = &iwl50_mod_params, | 1627 | .mod_params = &iwl50_mod_params, |
1681 | .valid_tx_ant = ANT_B, | 1628 | .valid_tx_ant = ANT_B, |
1682 | .valid_rx_ant = ANT_AB, | 1629 | .valid_rx_ant = ANT_AB, |
1683 | .need_pll_cfg = true, | 1630 | .pll_cfg_val = CSR50_ANA_PLL_CFG_VAL, |
1631 | .set_l0s = true, | ||
1632 | .use_bsm = false, | ||
1684 | .ht_greenfield_support = true, | 1633 | .ht_greenfield_support = true, |
1685 | .led_compensation = 51, | 1634 | .led_compensation = 51, |
1686 | .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, | 1635 | .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, |
@@ -1696,10 +1645,14 @@ struct iwl_cfg iwl5100_agn_cfg = { | |||
1696 | .eeprom_size = IWL_5000_EEPROM_IMG_SIZE, | 1645 | .eeprom_size = IWL_5000_EEPROM_IMG_SIZE, |
1697 | .eeprom_ver = EEPROM_5000_EEPROM_VERSION, | 1646 | .eeprom_ver = EEPROM_5000_EEPROM_VERSION, |
1698 | .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, | 1647 | .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, |
1648 | .num_of_queues = IWL50_NUM_QUEUES, | ||
1649 | .num_of_ampdu_queues = IWL50_NUM_AMPDU_QUEUES, | ||
1699 | .mod_params = &iwl50_mod_params, | 1650 | .mod_params = &iwl50_mod_params, |
1700 | .valid_tx_ant = ANT_B, | 1651 | .valid_tx_ant = ANT_B, |
1701 | .valid_rx_ant = ANT_AB, | 1652 | .valid_rx_ant = ANT_AB, |
1702 | .need_pll_cfg = true, | 1653 | .pll_cfg_val = CSR50_ANA_PLL_CFG_VAL, |
1654 | .set_l0s = true, | ||
1655 | .use_bsm = false, | ||
1703 | .ht_greenfield_support = true, | 1656 | .ht_greenfield_support = true, |
1704 | .led_compensation = 51, | 1657 | .led_compensation = 51, |
1705 | .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, | 1658 | .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, |
@@ -1715,10 +1668,14 @@ struct iwl_cfg iwl5350_agn_cfg = { | |||
1715 | .eeprom_size = IWL_5000_EEPROM_IMG_SIZE, | 1668 | .eeprom_size = IWL_5000_EEPROM_IMG_SIZE, |
1716 | .eeprom_ver = EEPROM_5050_EEPROM_VERSION, | 1669 | .eeprom_ver = EEPROM_5050_EEPROM_VERSION, |
1717 | .eeprom_calib_ver = EEPROM_5050_TX_POWER_VERSION, | 1670 | .eeprom_calib_ver = EEPROM_5050_TX_POWER_VERSION, |
1671 | .num_of_queues = IWL50_NUM_QUEUES, | ||
1672 | .num_of_ampdu_queues = IWL50_NUM_AMPDU_QUEUES, | ||
1718 | .mod_params = &iwl50_mod_params, | 1673 | .mod_params = &iwl50_mod_params, |
1719 | .valid_tx_ant = ANT_ABC, | 1674 | .valid_tx_ant = ANT_ABC, |
1720 | .valid_rx_ant = ANT_ABC, | 1675 | .valid_rx_ant = ANT_ABC, |
1721 | .need_pll_cfg = true, | 1676 | .pll_cfg_val = CSR50_ANA_PLL_CFG_VAL, |
1677 | .set_l0s = true, | ||
1678 | .use_bsm = false, | ||
1722 | .ht_greenfield_support = true, | 1679 | .ht_greenfield_support = true, |
1723 | .led_compensation = 51, | 1680 | .led_compensation = 51, |
1724 | .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, | 1681 | .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, |
@@ -1734,10 +1691,14 @@ struct iwl_cfg iwl5150_agn_cfg = { | |||
1734 | .eeprom_size = IWL_5000_EEPROM_IMG_SIZE, | 1691 | .eeprom_size = IWL_5000_EEPROM_IMG_SIZE, |
1735 | .eeprom_ver = EEPROM_5050_EEPROM_VERSION, | 1692 | .eeprom_ver = EEPROM_5050_EEPROM_VERSION, |
1736 | .eeprom_calib_ver = EEPROM_5050_TX_POWER_VERSION, | 1693 | .eeprom_calib_ver = EEPROM_5050_TX_POWER_VERSION, |
1694 | .num_of_queues = IWL50_NUM_QUEUES, | ||
1695 | .num_of_ampdu_queues = IWL50_NUM_AMPDU_QUEUES, | ||
1737 | .mod_params = &iwl50_mod_params, | 1696 | .mod_params = &iwl50_mod_params, |
1738 | .valid_tx_ant = ANT_A, | 1697 | .valid_tx_ant = ANT_A, |
1739 | .valid_rx_ant = ANT_AB, | 1698 | .valid_rx_ant = ANT_AB, |
1740 | .need_pll_cfg = true, | 1699 | .pll_cfg_val = CSR50_ANA_PLL_CFG_VAL, |
1700 | .set_l0s = true, | ||
1701 | .use_bsm = false, | ||
1741 | .ht_greenfield_support = true, | 1702 | .ht_greenfield_support = true, |
1742 | .led_compensation = 51, | 1703 | .led_compensation = 51, |
1743 | .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, | 1704 | .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, |
diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index d1f0b0b4ad0c..32466d38d1ae 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c | |||
@@ -52,8 +52,8 @@ | |||
52 | #define IWL6050_UCODE_API_MAX 4 | 52 | #define IWL6050_UCODE_API_MAX 4 |
53 | 53 | ||
54 | /* Lowest firmware API version supported */ | 54 | /* Lowest firmware API version supported */ |
55 | #define IWL6000_UCODE_API_MIN 1 | 55 | #define IWL6000_UCODE_API_MIN 4 |
56 | #define IWL6050_UCODE_API_MIN 1 | 56 | #define IWL6050_UCODE_API_MIN 4 |
57 | 57 | ||
58 | #define IWL6000_FW_PRE "iwlwifi-6000-" | 58 | #define IWL6000_FW_PRE "iwlwifi-6000-" |
59 | #define _IWL6000_MODULE_FIRMWARE(api) IWL6000_FW_PRE #api ".ucode" | 59 | #define _IWL6000_MODULE_FIRMWARE(api) IWL6000_FW_PRE #api ".ucode" |
@@ -121,22 +121,24 @@ static struct iwl_sensitivity_ranges iwl6000_sensitivity = { | |||
121 | .auto_corr_max_cck_mrc = 310, | 121 | .auto_corr_max_cck_mrc = 310, |
122 | .nrg_th_cck = 97, | 122 | .nrg_th_cck = 97, |
123 | .nrg_th_ofdm = 100, | 123 | .nrg_th_ofdm = 100, |
124 | |||
125 | .barker_corr_th_min = 190, | ||
126 | .barker_corr_th_min_mrc = 390, | ||
127 | .nrg_th_cca = 62, | ||
124 | }; | 128 | }; |
125 | 129 | ||
126 | static int iwl6000_hw_set_hw_params(struct iwl_priv *priv) | 130 | static int iwl6000_hw_set_hw_params(struct iwl_priv *priv) |
127 | { | 131 | { |
128 | if ((priv->cfg->mod_params->num_of_queues > IWL50_NUM_QUEUES) || | 132 | if (priv->cfg->mod_params->num_of_queues >= IWL_MIN_NUM_QUEUES && |
129 | (priv->cfg->mod_params->num_of_queues < IWL_MIN_NUM_QUEUES)) { | 133 | priv->cfg->mod_params->num_of_queues <= IWL50_NUM_QUEUES) |
130 | IWL_ERR(priv, | 134 | priv->cfg->num_of_queues = |
131 | "invalid queues_num, should be between %d and %d\n", | 135 | priv->cfg->mod_params->num_of_queues; |
132 | IWL_MIN_NUM_QUEUES, IWL50_NUM_QUEUES); | ||
133 | return -EINVAL; | ||
134 | } | ||
135 | 136 | ||
136 | priv->hw_params.max_txq_num = priv->cfg->mod_params->num_of_queues; | 137 | priv->hw_params.max_txq_num = priv->cfg->num_of_queues; |
137 | priv->hw_params.dma_chnl_num = FH50_TCSR_CHNL_NUM; | 138 | priv->hw_params.dma_chnl_num = FH50_TCSR_CHNL_NUM; |
138 | priv->hw_params.scd_bc_tbls_size = | 139 | priv->hw_params.scd_bc_tbls_size = |
139 | IWL50_NUM_QUEUES * sizeof(struct iwl5000_scd_bc_tbl); | 140 | priv->cfg->num_of_queues * |
141 | sizeof(struct iwl5000_scd_bc_tbl); | ||
140 | priv->hw_params.tfd_size = sizeof(struct iwl_tfd); | 142 | priv->hw_params.tfd_size = sizeof(struct iwl_tfd); |
141 | priv->hw_params.max_stations = IWL5000_STATION_COUNT; | 143 | priv->hw_params.max_stations = IWL5000_STATION_COUNT; |
142 | priv->hw_params.bcast_sta_id = IWL5000_BROADCAST_ID; | 144 | priv->hw_params.bcast_sta_id = IWL5000_BROADCAST_ID; |
@@ -170,6 +172,37 @@ static int iwl6000_hw_set_hw_params(struct iwl_priv *priv) | |||
170 | return 0; | 172 | return 0; |
171 | } | 173 | } |
172 | 174 | ||
175 | static int iwl6000_hw_channel_switch(struct iwl_priv *priv, u16 channel) | ||
176 | { | ||
177 | struct iwl6000_channel_switch_cmd cmd; | ||
178 | const struct iwl_channel_info *ch_info; | ||
179 | struct iwl_host_cmd hcmd = { | ||
180 | .id = REPLY_CHANNEL_SWITCH, | ||
181 | .len = sizeof(cmd), | ||
182 | .flags = CMD_SIZE_HUGE, | ||
183 | .data = &cmd, | ||
184 | }; | ||
185 | |||
186 | IWL_DEBUG_11H(priv, "channel switch from %d to %d\n", | ||
187 | priv->active_rxon.channel, channel); | ||
188 | |||
189 | cmd.band = priv->band == IEEE80211_BAND_2GHZ; | ||
190 | cmd.channel = cpu_to_le16(channel); | ||
191 | cmd.rxon_flags = priv->active_rxon.flags; | ||
192 | cmd.rxon_filter_flags = priv->active_rxon.filter_flags; | ||
193 | cmd.switch_time = cpu_to_le32(priv->ucode_beacon_time); | ||
194 | ch_info = iwl_get_channel_info(priv, priv->band, channel); | ||
195 | if (ch_info) | ||
196 | cmd.expect_beacon = is_channel_radar(ch_info); | ||
197 | else { | ||
198 | IWL_ERR(priv, "invalid channel switch from %u to %u\n", | ||
199 | priv->active_rxon.channel, channel); | ||
200 | return -EFAULT; | ||
201 | } | ||
202 | |||
203 | return iwl_send_cmd_sync(priv, &hcmd); | ||
204 | } | ||
205 | |||
173 | static struct iwl_lib_ops iwl6000_lib = { | 206 | static struct iwl_lib_ops iwl6000_lib = { |
174 | .set_hw_params = iwl6000_hw_set_hw_params, | 207 | .set_hw_params = iwl6000_hw_set_hw_params, |
175 | .txq_update_byte_cnt_tbl = iwl5000_txq_update_byte_cnt_tbl, | 208 | .txq_update_byte_cnt_tbl = iwl5000_txq_update_byte_cnt_tbl, |
@@ -190,9 +223,9 @@ static struct iwl_lib_ops iwl6000_lib = { | |||
190 | .alive_notify = iwl5000_alive_notify, | 223 | .alive_notify = iwl5000_alive_notify, |
191 | .send_tx_power = iwl5000_send_tx_power, | 224 | .send_tx_power = iwl5000_send_tx_power, |
192 | .update_chain_flags = iwl_update_chain_flags, | 225 | .update_chain_flags = iwl_update_chain_flags, |
226 | .set_channel_switch = iwl6000_hw_channel_switch, | ||
193 | .apm_ops = { | 227 | .apm_ops = { |
194 | .init = iwl5000_apm_init, | 228 | .init = iwl_apm_init, |
195 | .reset = iwl5000_apm_reset, | ||
196 | .stop = iwl_apm_stop, | 229 | .stop = iwl_apm_stop, |
197 | .config = iwl6000_nic_config, | 230 | .config = iwl6000_nic_config, |
198 | .set_pwr_src = iwl_set_pwr_src, | 231 | .set_pwr_src = iwl_set_pwr_src, |
@@ -231,6 +264,21 @@ static struct iwl_ops iwl6000_ops = { | |||
231 | .led = &iwlagn_led_ops, | 264 | .led = &iwlagn_led_ops, |
232 | }; | 265 | }; |
233 | 266 | ||
267 | static struct iwl_hcmd_utils_ops iwl6050_hcmd_utils = { | ||
268 | .get_hcmd_size = iwl5000_get_hcmd_size, | ||
269 | .build_addsta_hcmd = iwl5000_build_addsta_hcmd, | ||
270 | .rts_tx_cmd_flag = iwl5000_rts_tx_cmd_flag, | ||
271 | .calc_rssi = iwl5000_calc_rssi, | ||
272 | }; | ||
273 | |||
274 | static struct iwl_ops iwl6050_ops = { | ||
275 | .ucode = &iwl5000_ucode, | ||
276 | .lib = &iwl6000_lib, | ||
277 | .hcmd = &iwl5000_hcmd, | ||
278 | .utils = &iwl6050_hcmd_utils, | ||
279 | .led = &iwlagn_led_ops, | ||
280 | }; | ||
281 | |||
234 | 282 | ||
235 | /* | 283 | /* |
236 | * "h": Hybrid configuration, use both internal and external Power Amplifier | 284 | * "h": Hybrid configuration, use both internal and external Power Amplifier |
@@ -245,10 +293,14 @@ struct iwl_cfg iwl6000h_2agn_cfg = { | |||
245 | .eeprom_size = OTP_LOW_IMAGE_SIZE, | 293 | .eeprom_size = OTP_LOW_IMAGE_SIZE, |
246 | .eeprom_ver = EEPROM_6000_EEPROM_VERSION, | 294 | .eeprom_ver = EEPROM_6000_EEPROM_VERSION, |
247 | .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, | 295 | .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, |
296 | .num_of_queues = IWL50_NUM_QUEUES, | ||
297 | .num_of_ampdu_queues = IWL50_NUM_AMPDU_QUEUES, | ||
248 | .mod_params = &iwl50_mod_params, | 298 | .mod_params = &iwl50_mod_params, |
249 | .valid_tx_ant = ANT_AB, | 299 | .valid_tx_ant = ANT_AB, |
250 | .valid_rx_ant = ANT_AB, | 300 | .valid_rx_ant = ANT_AB, |
251 | .need_pll_cfg = false, | 301 | .pll_cfg_val = 0, |
302 | .set_l0s = false, | ||
303 | .use_bsm = false, | ||
252 | .pa_type = IWL_PA_HYBRID, | 304 | .pa_type = IWL_PA_HYBRID, |
253 | .max_ll_items = OTP_MAX_LL_ITEMS_6x00, | 305 | .max_ll_items = OTP_MAX_LL_ITEMS_6x00, |
254 | .shadow_ram_support = true, | 306 | .shadow_ram_support = true, |
@@ -257,6 +309,8 @@ struct iwl_cfg iwl6000h_2agn_cfg = { | |||
257 | .use_rts_for_ht = true, /* use rts/cts protection */ | 309 | .use_rts_for_ht = true, /* use rts/cts protection */ |
258 | .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, | 310 | .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, |
259 | .supports_idle = true, | 311 | .supports_idle = true, |
312 | .adv_thermal_throttle = true, | ||
313 | .support_ct_kill_exit = true, | ||
260 | }; | 314 | }; |
261 | 315 | ||
262 | struct iwl_cfg iwl6000h_2abg_cfg = { | 316 | struct iwl_cfg iwl6000h_2abg_cfg = { |
@@ -269,10 +323,14 @@ struct iwl_cfg iwl6000h_2abg_cfg = { | |||
269 | .eeprom_size = OTP_LOW_IMAGE_SIZE, | 323 | .eeprom_size = OTP_LOW_IMAGE_SIZE, |
270 | .eeprom_ver = EEPROM_6000_EEPROM_VERSION, | 324 | .eeprom_ver = EEPROM_6000_EEPROM_VERSION, |
271 | .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, | 325 | .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, |
326 | .num_of_queues = IWL50_NUM_QUEUES, | ||
327 | .num_of_ampdu_queues = IWL50_NUM_AMPDU_QUEUES, | ||
272 | .mod_params = &iwl50_mod_params, | 328 | .mod_params = &iwl50_mod_params, |
273 | .valid_tx_ant = ANT_AB, | 329 | .valid_tx_ant = ANT_AB, |
274 | .valid_rx_ant = ANT_AB, | 330 | .valid_rx_ant = ANT_AB, |
275 | .need_pll_cfg = false, | 331 | .pll_cfg_val = 0, |
332 | .set_l0s = false, | ||
333 | .use_bsm = false, | ||
276 | .pa_type = IWL_PA_HYBRID, | 334 | .pa_type = IWL_PA_HYBRID, |
277 | .max_ll_items = OTP_MAX_LL_ITEMS_6x00, | 335 | .max_ll_items = OTP_MAX_LL_ITEMS_6x00, |
278 | .shadow_ram_support = true, | 336 | .shadow_ram_support = true, |
@@ -280,6 +338,8 @@ struct iwl_cfg iwl6000h_2abg_cfg = { | |||
280 | .led_compensation = 51, | 338 | .led_compensation = 51, |
281 | .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, | 339 | .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, |
282 | .supports_idle = true, | 340 | .supports_idle = true, |
341 | .adv_thermal_throttle = true, | ||
342 | .support_ct_kill_exit = true, | ||
283 | }; | 343 | }; |
284 | 344 | ||
285 | struct iwl_cfg iwl6000h_2bg_cfg = { | 345 | struct iwl_cfg iwl6000h_2bg_cfg = { |
@@ -292,10 +352,14 @@ struct iwl_cfg iwl6000h_2bg_cfg = { | |||
292 | .eeprom_size = OTP_LOW_IMAGE_SIZE, | 352 | .eeprom_size = OTP_LOW_IMAGE_SIZE, |
293 | .eeprom_ver = EEPROM_6000_EEPROM_VERSION, | 353 | .eeprom_ver = EEPROM_6000_EEPROM_VERSION, |
294 | .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, | 354 | .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, |
355 | .num_of_queues = IWL50_NUM_QUEUES, | ||
356 | .num_of_ampdu_queues = IWL50_NUM_AMPDU_QUEUES, | ||
295 | .mod_params = &iwl50_mod_params, | 357 | .mod_params = &iwl50_mod_params, |
296 | .valid_tx_ant = ANT_AB, | 358 | .valid_tx_ant = ANT_AB, |
297 | .valid_rx_ant = ANT_AB, | 359 | .valid_rx_ant = ANT_AB, |
298 | .need_pll_cfg = false, | 360 | .pll_cfg_val = 0, |
361 | .set_l0s = false, | ||
362 | .use_bsm = false, | ||
299 | .pa_type = IWL_PA_HYBRID, | 363 | .pa_type = IWL_PA_HYBRID, |
300 | .max_ll_items = OTP_MAX_LL_ITEMS_6x00, | 364 | .max_ll_items = OTP_MAX_LL_ITEMS_6x00, |
301 | .shadow_ram_support = true, | 365 | .shadow_ram_support = true, |
@@ -303,6 +367,8 @@ struct iwl_cfg iwl6000h_2bg_cfg = { | |||
303 | .led_compensation = 51, | 367 | .led_compensation = 51, |
304 | .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, | 368 | .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, |
305 | .supports_idle = true, | 369 | .supports_idle = true, |
370 | .adv_thermal_throttle = true, | ||
371 | .support_ct_kill_exit = true, | ||
306 | }; | 372 | }; |
307 | 373 | ||
308 | /* | 374 | /* |
@@ -318,10 +384,14 @@ struct iwl_cfg iwl6000i_2agn_cfg = { | |||
318 | .eeprom_size = OTP_LOW_IMAGE_SIZE, | 384 | .eeprom_size = OTP_LOW_IMAGE_SIZE, |
319 | .eeprom_ver = EEPROM_6000_EEPROM_VERSION, | 385 | .eeprom_ver = EEPROM_6000_EEPROM_VERSION, |
320 | .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, | 386 | .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, |
387 | .num_of_queues = IWL50_NUM_QUEUES, | ||
388 | .num_of_ampdu_queues = IWL50_NUM_AMPDU_QUEUES, | ||
321 | .mod_params = &iwl50_mod_params, | 389 | .mod_params = &iwl50_mod_params, |
322 | .valid_tx_ant = ANT_BC, | 390 | .valid_tx_ant = ANT_BC, |
323 | .valid_rx_ant = ANT_BC, | 391 | .valid_rx_ant = ANT_BC, |
324 | .need_pll_cfg = false, | 392 | .pll_cfg_val = 0, |
393 | .set_l0s = false, | ||
394 | .use_bsm = false, | ||
325 | .pa_type = IWL_PA_INTERNAL, | 395 | .pa_type = IWL_PA_INTERNAL, |
326 | .max_ll_items = OTP_MAX_LL_ITEMS_6x00, | 396 | .max_ll_items = OTP_MAX_LL_ITEMS_6x00, |
327 | .shadow_ram_support = true, | 397 | .shadow_ram_support = true, |
@@ -330,6 +400,8 @@ struct iwl_cfg iwl6000i_2agn_cfg = { | |||
330 | .use_rts_for_ht = true, /* use rts/cts protection */ | 400 | .use_rts_for_ht = true, /* use rts/cts protection */ |
331 | .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, | 401 | .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, |
332 | .supports_idle = true, | 402 | .supports_idle = true, |
403 | .adv_thermal_throttle = true, | ||
404 | .support_ct_kill_exit = true, | ||
333 | }; | 405 | }; |
334 | 406 | ||
335 | struct iwl_cfg iwl6000i_2abg_cfg = { | 407 | struct iwl_cfg iwl6000i_2abg_cfg = { |
@@ -342,10 +414,14 @@ struct iwl_cfg iwl6000i_2abg_cfg = { | |||
342 | .eeprom_size = OTP_LOW_IMAGE_SIZE, | 414 | .eeprom_size = OTP_LOW_IMAGE_SIZE, |
343 | .eeprom_ver = EEPROM_6000_EEPROM_VERSION, | 415 | .eeprom_ver = EEPROM_6000_EEPROM_VERSION, |
344 | .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, | 416 | .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, |
417 | .num_of_queues = IWL50_NUM_QUEUES, | ||
418 | .num_of_ampdu_queues = IWL50_NUM_AMPDU_QUEUES, | ||
345 | .mod_params = &iwl50_mod_params, | 419 | .mod_params = &iwl50_mod_params, |
346 | .valid_tx_ant = ANT_BC, | 420 | .valid_tx_ant = ANT_BC, |
347 | .valid_rx_ant = ANT_BC, | 421 | .valid_rx_ant = ANT_BC, |
348 | .need_pll_cfg = false, | 422 | .pll_cfg_val = 0, |
423 | .set_l0s = false, | ||
424 | .use_bsm = false, | ||
349 | .pa_type = IWL_PA_INTERNAL, | 425 | .pa_type = IWL_PA_INTERNAL, |
350 | .max_ll_items = OTP_MAX_LL_ITEMS_6x00, | 426 | .max_ll_items = OTP_MAX_LL_ITEMS_6x00, |
351 | .shadow_ram_support = true, | 427 | .shadow_ram_support = true, |
@@ -353,6 +429,8 @@ struct iwl_cfg iwl6000i_2abg_cfg = { | |||
353 | .led_compensation = 51, | 429 | .led_compensation = 51, |
354 | .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, | 430 | .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, |
355 | .supports_idle = true, | 431 | .supports_idle = true, |
432 | .adv_thermal_throttle = true, | ||
433 | .support_ct_kill_exit = true, | ||
356 | }; | 434 | }; |
357 | 435 | ||
358 | struct iwl_cfg iwl6000i_2bg_cfg = { | 436 | struct iwl_cfg iwl6000i_2bg_cfg = { |
@@ -365,10 +443,14 @@ struct iwl_cfg iwl6000i_2bg_cfg = { | |||
365 | .eeprom_size = OTP_LOW_IMAGE_SIZE, | 443 | .eeprom_size = OTP_LOW_IMAGE_SIZE, |
366 | .eeprom_ver = EEPROM_6000_EEPROM_VERSION, | 444 | .eeprom_ver = EEPROM_6000_EEPROM_VERSION, |
367 | .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, | 445 | .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, |
446 | .num_of_queues = IWL50_NUM_QUEUES, | ||
447 | .num_of_ampdu_queues = IWL50_NUM_AMPDU_QUEUES, | ||
368 | .mod_params = &iwl50_mod_params, | 448 | .mod_params = &iwl50_mod_params, |
369 | .valid_tx_ant = ANT_BC, | 449 | .valid_tx_ant = ANT_BC, |
370 | .valid_rx_ant = ANT_BC, | 450 | .valid_rx_ant = ANT_BC, |
371 | .need_pll_cfg = false, | 451 | .pll_cfg_val = 0, |
452 | .set_l0s = false, | ||
453 | .use_bsm = false, | ||
372 | .pa_type = IWL_PA_INTERNAL, | 454 | .pa_type = IWL_PA_INTERNAL, |
373 | .max_ll_items = OTP_MAX_LL_ITEMS_6x00, | 455 | .max_ll_items = OTP_MAX_LL_ITEMS_6x00, |
374 | .shadow_ram_support = true, | 456 | .shadow_ram_support = true, |
@@ -376,6 +458,8 @@ struct iwl_cfg iwl6000i_2bg_cfg = { | |||
376 | .led_compensation = 51, | 458 | .led_compensation = 51, |
377 | .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, | 459 | .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, |
378 | .supports_idle = true, | 460 | .supports_idle = true, |
461 | .adv_thermal_throttle = true, | ||
462 | .support_ct_kill_exit = true, | ||
379 | }; | 463 | }; |
380 | 464 | ||
381 | struct iwl_cfg iwl6050_2agn_cfg = { | 465 | struct iwl_cfg iwl6050_2agn_cfg = { |
@@ -384,22 +468,28 @@ struct iwl_cfg iwl6050_2agn_cfg = { | |||
384 | .ucode_api_max = IWL6050_UCODE_API_MAX, | 468 | .ucode_api_max = IWL6050_UCODE_API_MAX, |
385 | .ucode_api_min = IWL6050_UCODE_API_MIN, | 469 | .ucode_api_min = IWL6050_UCODE_API_MIN, |
386 | .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N, | 470 | .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N, |
387 | .ops = &iwl6000_ops, | 471 | .ops = &iwl6050_ops, |
388 | .eeprom_size = OTP_LOW_IMAGE_SIZE, | 472 | .eeprom_size = OTP_LOW_IMAGE_SIZE, |
389 | .eeprom_ver = EEPROM_6000_EEPROM_VERSION, | 473 | .eeprom_ver = EEPROM_6050_EEPROM_VERSION, |
390 | .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, | 474 | .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, |
475 | .num_of_queues = IWL50_NUM_QUEUES, | ||
476 | .num_of_ampdu_queues = IWL50_NUM_AMPDU_QUEUES, | ||
391 | .mod_params = &iwl50_mod_params, | 477 | .mod_params = &iwl50_mod_params, |
392 | .valid_tx_ant = ANT_AB, | 478 | .valid_tx_ant = ANT_AB, |
393 | .valid_rx_ant = ANT_AB, | 479 | .valid_rx_ant = ANT_AB, |
394 | .need_pll_cfg = false, | 480 | .pll_cfg_val = 0, |
481 | .set_l0s = false, | ||
482 | .use_bsm = false, | ||
395 | .pa_type = IWL_PA_SYSTEM, | 483 | .pa_type = IWL_PA_SYSTEM, |
396 | .max_ll_items = OTP_MAX_LL_ITEMS_6x00, | 484 | .max_ll_items = OTP_MAX_LL_ITEMS_6x50, |
397 | .shadow_ram_support = true, | 485 | .shadow_ram_support = true, |
398 | .ht_greenfield_support = true, | 486 | .ht_greenfield_support = true, |
399 | .led_compensation = 51, | 487 | .led_compensation = 51, |
400 | .use_rts_for_ht = true, /* use rts/cts protection */ | 488 | .use_rts_for_ht = true, /* use rts/cts protection */ |
401 | .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, | 489 | .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, |
402 | .supports_idle = true, | 490 | .supports_idle = true, |
491 | .adv_thermal_throttle = true, | ||
492 | .support_ct_kill_exit = true, | ||
403 | }; | 493 | }; |
404 | 494 | ||
405 | struct iwl_cfg iwl6050_2abg_cfg = { | 495 | struct iwl_cfg iwl6050_2abg_cfg = { |
@@ -408,21 +498,27 @@ struct iwl_cfg iwl6050_2abg_cfg = { | |||
408 | .ucode_api_max = IWL6050_UCODE_API_MAX, | 498 | .ucode_api_max = IWL6050_UCODE_API_MAX, |
409 | .ucode_api_min = IWL6050_UCODE_API_MIN, | 499 | .ucode_api_min = IWL6050_UCODE_API_MIN, |
410 | .sku = IWL_SKU_A|IWL_SKU_G, | 500 | .sku = IWL_SKU_A|IWL_SKU_G, |
411 | .ops = &iwl6000_ops, | 501 | .ops = &iwl6050_ops, |
412 | .eeprom_size = OTP_LOW_IMAGE_SIZE, | 502 | .eeprom_size = OTP_LOW_IMAGE_SIZE, |
413 | .eeprom_ver = EEPROM_6000_EEPROM_VERSION, | 503 | .eeprom_ver = EEPROM_6050_EEPROM_VERSION, |
414 | .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, | 504 | .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, |
505 | .num_of_queues = IWL50_NUM_QUEUES, | ||
506 | .num_of_ampdu_queues = IWL50_NUM_AMPDU_QUEUES, | ||
415 | .mod_params = &iwl50_mod_params, | 507 | .mod_params = &iwl50_mod_params, |
416 | .valid_tx_ant = ANT_AB, | 508 | .valid_tx_ant = ANT_AB, |
417 | .valid_rx_ant = ANT_AB, | 509 | .valid_rx_ant = ANT_AB, |
418 | .need_pll_cfg = false, | 510 | .pll_cfg_val = 0, |
511 | .set_l0s = false, | ||
512 | .use_bsm = false, | ||
419 | .pa_type = IWL_PA_SYSTEM, | 513 | .pa_type = IWL_PA_SYSTEM, |
420 | .max_ll_items = OTP_MAX_LL_ITEMS_6x00, | 514 | .max_ll_items = OTP_MAX_LL_ITEMS_6x50, |
421 | .shadow_ram_support = true, | 515 | .shadow_ram_support = true, |
422 | .ht_greenfield_support = true, | 516 | .ht_greenfield_support = true, |
423 | .led_compensation = 51, | 517 | .led_compensation = 51, |
424 | .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, | 518 | .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, |
425 | .supports_idle = true, | 519 | .supports_idle = true, |
520 | .adv_thermal_throttle = true, | ||
521 | .support_ct_kill_exit = true, | ||
426 | }; | 522 | }; |
427 | 523 | ||
428 | struct iwl_cfg iwl6000_3agn_cfg = { | 524 | struct iwl_cfg iwl6000_3agn_cfg = { |
@@ -435,10 +531,14 @@ struct iwl_cfg iwl6000_3agn_cfg = { | |||
435 | .eeprom_size = OTP_LOW_IMAGE_SIZE, | 531 | .eeprom_size = OTP_LOW_IMAGE_SIZE, |
436 | .eeprom_ver = EEPROM_6000_EEPROM_VERSION, | 532 | .eeprom_ver = EEPROM_6000_EEPROM_VERSION, |
437 | .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, | 533 | .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, |
534 | .num_of_queues = IWL50_NUM_QUEUES, | ||
535 | .num_of_ampdu_queues = IWL50_NUM_AMPDU_QUEUES, | ||
438 | .mod_params = &iwl50_mod_params, | 536 | .mod_params = &iwl50_mod_params, |
439 | .valid_tx_ant = ANT_ABC, | 537 | .valid_tx_ant = ANT_ABC, |
440 | .valid_rx_ant = ANT_ABC, | 538 | .valid_rx_ant = ANT_ABC, |
441 | .need_pll_cfg = false, | 539 | .pll_cfg_val = 0, |
540 | .set_l0s = false, | ||
541 | .use_bsm = false, | ||
442 | .pa_type = IWL_PA_SYSTEM, | 542 | .pa_type = IWL_PA_SYSTEM, |
443 | .max_ll_items = OTP_MAX_LL_ITEMS_6x00, | 543 | .max_ll_items = OTP_MAX_LL_ITEMS_6x00, |
444 | .shadow_ram_support = true, | 544 | .shadow_ram_support = true, |
@@ -447,6 +547,8 @@ struct iwl_cfg iwl6000_3agn_cfg = { | |||
447 | .use_rts_for_ht = true, /* use rts/cts protection */ | 547 | .use_rts_for_ht = true, /* use rts/cts protection */ |
448 | .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, | 548 | .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, |
449 | .supports_idle = true, | 549 | .supports_idle = true, |
550 | .adv_thermal_throttle = true, | ||
551 | .support_ct_kill_exit = true, | ||
450 | }; | 552 | }; |
451 | 553 | ||
452 | struct iwl_cfg iwl6050_3agn_cfg = { | 554 | struct iwl_cfg iwl6050_3agn_cfg = { |
@@ -455,22 +557,28 @@ struct iwl_cfg iwl6050_3agn_cfg = { | |||
455 | .ucode_api_max = IWL6050_UCODE_API_MAX, | 557 | .ucode_api_max = IWL6050_UCODE_API_MAX, |
456 | .ucode_api_min = IWL6050_UCODE_API_MIN, | 558 | .ucode_api_min = IWL6050_UCODE_API_MIN, |
457 | .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N, | 559 | .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N, |
458 | .ops = &iwl6000_ops, | 560 | .ops = &iwl6050_ops, |
459 | .eeprom_size = OTP_LOW_IMAGE_SIZE, | 561 | .eeprom_size = OTP_LOW_IMAGE_SIZE, |
460 | .eeprom_ver = EEPROM_6000_EEPROM_VERSION, | 562 | .eeprom_ver = EEPROM_6050_EEPROM_VERSION, |
461 | .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, | 563 | .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, |
564 | .num_of_queues = IWL50_NUM_QUEUES, | ||
565 | .num_of_ampdu_queues = IWL50_NUM_AMPDU_QUEUES, | ||
462 | .mod_params = &iwl50_mod_params, | 566 | .mod_params = &iwl50_mod_params, |
463 | .valid_tx_ant = ANT_ABC, | 567 | .valid_tx_ant = ANT_ABC, |
464 | .valid_rx_ant = ANT_ABC, | 568 | .valid_rx_ant = ANT_ABC, |
465 | .need_pll_cfg = false, | 569 | .pll_cfg_val = 0, |
570 | .set_l0s = false, | ||
571 | .use_bsm = false, | ||
466 | .pa_type = IWL_PA_SYSTEM, | 572 | .pa_type = IWL_PA_SYSTEM, |
467 | .max_ll_items = OTP_MAX_LL_ITEMS_6x00, | 573 | .max_ll_items = OTP_MAX_LL_ITEMS_6x50, |
468 | .shadow_ram_support = true, | 574 | .shadow_ram_support = true, |
469 | .ht_greenfield_support = true, | 575 | .ht_greenfield_support = true, |
470 | .led_compensation = 51, | 576 | .led_compensation = 51, |
471 | .use_rts_for_ht = true, /* use rts/cts protection */ | 577 | .use_rts_for_ht = true, /* use rts/cts protection */ |
472 | .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, | 578 | .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, |
473 | .supports_idle = true, | 579 | .supports_idle = true, |
580 | .adv_thermal_throttle = true, | ||
581 | .support_ct_kill_exit = true, | ||
474 | }; | 582 | }; |
475 | 583 | ||
476 | MODULE_FIRMWARE(IWL6000_MODULE_FIRMWARE(IWL6000_UCODE_API_MAX)); | 584 | MODULE_FIRMWARE(IWL6000_MODULE_FIRMWARE(IWL6000_UCODE_API_MAX)); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c index a07be29cc5e5..27d4ece4d467 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c | |||
@@ -75,106 +75,6 @@ static const u8 ant_toggle_lookup[] = { | |||
75 | /*ANT_ABC -> */ ANT_ABC, | 75 | /*ANT_ABC -> */ ANT_ABC, |
76 | }; | 76 | }; |
77 | 77 | ||
78 | /** | ||
79 | * struct iwl_rate_scale_data -- tx success history for one rate | ||
80 | */ | ||
81 | struct iwl_rate_scale_data { | ||
82 | u64 data; /* bitmap of successful frames */ | ||
83 | s32 success_counter; /* number of frames successful */ | ||
84 | s32 success_ratio; /* per-cent * 128 */ | ||
85 | s32 counter; /* number of frames attempted */ | ||
86 | s32 average_tpt; /* success ratio * expected throughput */ | ||
87 | unsigned long stamp; | ||
88 | }; | ||
89 | |||
90 | /** | ||
91 | * struct iwl_scale_tbl_info -- tx params and success history for all rates | ||
92 | * | ||
93 | * There are two of these in struct iwl_lq_sta, | ||
94 | * one for "active", and one for "search". | ||
95 | */ | ||
96 | struct iwl_scale_tbl_info { | ||
97 | enum iwl_table_type lq_type; | ||
98 | u8 ant_type; | ||
99 | u8 is_SGI; /* 1 = short guard interval */ | ||
100 | u8 is_ht40; /* 1 = 40 MHz channel width */ | ||
101 | u8 is_dup; /* 1 = duplicated data streams */ | ||
102 | u8 action; /* change modulation; IWL_[LEGACY/SISO/MIMO]_SWITCH_* */ | ||
103 | u8 max_search; /* maximun number of tables we can search */ | ||
104 | s32 *expected_tpt; /* throughput metrics; expected_tpt_G, etc. */ | ||
105 | u32 current_rate; /* rate_n_flags, uCode API format */ | ||
106 | struct iwl_rate_scale_data win[IWL_RATE_COUNT]; /* rate histories */ | ||
107 | }; | ||
108 | |||
109 | struct iwl_traffic_load { | ||
110 | unsigned long time_stamp; /* age of the oldest statistics */ | ||
111 | u32 packet_count[TID_QUEUE_MAX_SIZE]; /* packet count in this time | ||
112 | * slice */ | ||
113 | u32 total; /* total num of packets during the | ||
114 | * last TID_MAX_TIME_DIFF */ | ||
115 | u8 queue_count; /* number of queues that has | ||
116 | * been used since the last cleanup */ | ||
117 | u8 head; /* start of the circular buffer */ | ||
118 | }; | ||
119 | |||
120 | /** | ||
121 | * struct iwl_lq_sta -- driver's rate scaling private structure | ||
122 | * | ||
123 | * Pointer to this gets passed back and forth between driver and mac80211. | ||
124 | */ | ||
125 | struct iwl_lq_sta { | ||
126 | u8 active_tbl; /* index of active table, range 0-1 */ | ||
127 | u8 enable_counter; /* indicates HT mode */ | ||
128 | u8 stay_in_tbl; /* 1: disallow, 0: allow search for new mode */ | ||
129 | u8 search_better_tbl; /* 1: currently trying alternate mode */ | ||
130 | s32 last_tpt; | ||
131 | |||
132 | /* The following determine when to search for a new mode */ | ||
133 | u32 table_count_limit; | ||
134 | u32 max_failure_limit; /* # failed frames before new search */ | ||
135 | u32 max_success_limit; /* # successful frames before new search */ | ||
136 | u32 table_count; | ||
137 | u32 total_failed; /* total failed frames, any/all rates */ | ||
138 | u32 total_success; /* total successful frames, any/all rates */ | ||
139 | u64 flush_timer; /* time staying in mode before new search */ | ||
140 | |||
141 | u8 action_counter; /* # mode-switch actions tried */ | ||
142 | u8 is_green; | ||
143 | u8 is_dup; | ||
144 | enum ieee80211_band band; | ||
145 | u8 ibss_sta_added; | ||
146 | |||
147 | /* The following are bitmaps of rates; IWL_RATE_6M_MASK, etc. */ | ||
148 | u32 supp_rates; | ||
149 | u16 active_legacy_rate; | ||
150 | u16 active_siso_rate; | ||
151 | u16 active_mimo2_rate; | ||
152 | u16 active_mimo3_rate; | ||
153 | u16 active_rate_basic; | ||
154 | s8 max_rate_idx; /* Max rate set by user */ | ||
155 | u8 missed_rate_counter; | ||
156 | |||
157 | struct iwl_link_quality_cmd lq; | ||
158 | struct iwl_scale_tbl_info lq_info[LQ_SIZE]; /* "active", "search" */ | ||
159 | struct iwl_traffic_load load[TID_MAX_LOAD_COUNT]; | ||
160 | u8 tx_agg_tid_en; | ||
161 | #ifdef CONFIG_MAC80211_DEBUGFS | ||
162 | struct dentry *rs_sta_dbgfs_scale_table_file; | ||
163 | struct dentry *rs_sta_dbgfs_stats_table_file; | ||
164 | struct dentry *rs_sta_dbgfs_rate_scale_data_file; | ||
165 | struct dentry *rs_sta_dbgfs_tx_agg_tid_en_file; | ||
166 | u32 dbg_fixed_rate; | ||
167 | #endif | ||
168 | struct iwl_priv *drv; | ||
169 | |||
170 | /* used to be in sta_info */ | ||
171 | int last_txrate_idx; | ||
172 | /* last tx rate_n_flags */ | ||
173 | u32 last_rate_n_flags; | ||
174 | /* packets destined for this STA are aggregated */ | ||
175 | u8 is_agg; | ||
176 | }; | ||
177 | |||
178 | static void rs_rate_scale_perform(struct iwl_priv *priv, | 78 | static void rs_rate_scale_perform(struct iwl_priv *priv, |
179 | struct sk_buff *skb, | 79 | struct sk_buff *skb, |
180 | struct ieee80211_sta *sta, | 80 | struct ieee80211_sta *sta, |
@@ -2575,19 +2475,17 @@ static void *rs_alloc_sta(void *priv_rate, struct ieee80211_sta *sta, | |||
2575 | gfp_t gfp) | 2475 | gfp_t gfp) |
2576 | { | 2476 | { |
2577 | struct iwl_lq_sta *lq_sta; | 2477 | struct iwl_lq_sta *lq_sta; |
2478 | struct iwl_station_priv *sta_priv = (struct iwl_station_priv *) sta->drv_priv; | ||
2578 | struct iwl_priv *priv; | 2479 | struct iwl_priv *priv; |
2579 | int i, j; | 2480 | int i, j; |
2580 | 2481 | ||
2581 | priv = (struct iwl_priv *)priv_rate; | 2482 | priv = (struct iwl_priv *)priv_rate; |
2582 | IWL_DEBUG_RATE(priv, "create station rate scale window\n"); | 2483 | IWL_DEBUG_RATE(priv, "create station rate scale window\n"); |
2583 | 2484 | ||
2584 | lq_sta = kzalloc(sizeof(struct iwl_lq_sta), gfp); | 2485 | lq_sta = &sta_priv->lq_sta; |
2585 | 2486 | ||
2586 | if (lq_sta == NULL) | ||
2587 | return NULL; | ||
2588 | lq_sta->lq.sta_id = 0xff; | 2487 | lq_sta->lq.sta_id = 0xff; |
2589 | 2488 | ||
2590 | |||
2591 | for (j = 0; j < LQ_SIZE; j++) | 2489 | for (j = 0; j < LQ_SIZE; j++) |
2592 | for (i = 0; i < IWL_RATE_COUNT; i++) | 2490 | for (i = 0; i < IWL_RATE_COUNT; i++) |
2593 | rs_rate_scale_clear_window(&lq_sta->lq_info[j].win[i]); | 2491 | rs_rate_scale_clear_window(&lq_sta->lq_info[j].win[i]); |
@@ -2819,11 +2717,9 @@ static void rs_free(void *priv_rate) | |||
2819 | static void rs_free_sta(void *priv_r, struct ieee80211_sta *sta, | 2717 | static void rs_free_sta(void *priv_r, struct ieee80211_sta *sta, |
2820 | void *priv_sta) | 2718 | void *priv_sta) |
2821 | { | 2719 | { |
2822 | struct iwl_lq_sta *lq_sta = priv_sta; | ||
2823 | struct iwl_priv *priv __maybe_unused = priv_r; | 2720 | struct iwl_priv *priv __maybe_unused = priv_r; |
2824 | 2721 | ||
2825 | IWL_DEBUG_RATE(priv, "enter\n"); | 2722 | IWL_DEBUG_RATE(priv, "enter\n"); |
2826 | kfree(lq_sta); | ||
2827 | IWL_DEBUG_RATE(priv, "leave\n"); | 2723 | IWL_DEBUG_RATE(priv, "leave\n"); |
2828 | } | 2724 | } |
2829 | 2725 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.h b/drivers/net/wireless/iwlwifi/iwl-agn-rs.h index 9fac530cfb7e..affc0c5a2f2c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.h | |||
@@ -54,6 +54,7 @@ struct iwl3945_rate_info { | |||
54 | u8 prev_table_rs; /* prev in rate table cmd */ | 54 | u8 prev_table_rs; /* prev in rate table cmd */ |
55 | }; | 55 | }; |
56 | 56 | ||
57 | |||
57 | /* | 58 | /* |
58 | * These serve as indexes into | 59 | * These serve as indexes into |
59 | * struct iwl_rate_info iwl_rates[IWL_RATE_COUNT]; | 60 | * struct iwl_rate_info iwl_rates[IWL_RATE_COUNT]; |
@@ -335,6 +336,106 @@ struct iwl_rate_mcs_info { | |||
335 | char mcs[IWL_MAX_MCS_DISPLAY_SIZE]; | 336 | char mcs[IWL_MAX_MCS_DISPLAY_SIZE]; |
336 | }; | 337 | }; |
337 | 338 | ||
339 | /** | ||
340 | * struct iwl_rate_scale_data -- tx success history for one rate | ||
341 | */ | ||
342 | struct iwl_rate_scale_data { | ||
343 | u64 data; /* bitmap of successful frames */ | ||
344 | s32 success_counter; /* number of frames successful */ | ||
345 | s32 success_ratio; /* per-cent * 128 */ | ||
346 | s32 counter; /* number of frames attempted */ | ||
347 | s32 average_tpt; /* success ratio * expected throughput */ | ||
348 | unsigned long stamp; | ||
349 | }; | ||
350 | |||
351 | /** | ||
352 | * struct iwl_scale_tbl_info -- tx params and success history for all rates | ||
353 | * | ||
354 | * There are two of these in struct iwl_lq_sta, | ||
355 | * one for "active", and one for "search". | ||
356 | */ | ||
357 | struct iwl_scale_tbl_info { | ||
358 | enum iwl_table_type lq_type; | ||
359 | u8 ant_type; | ||
360 | u8 is_SGI; /* 1 = short guard interval */ | ||
361 | u8 is_ht40; /* 1 = 40 MHz channel width */ | ||
362 | u8 is_dup; /* 1 = duplicated data streams */ | ||
363 | u8 action; /* change modulation; IWL_[LEGACY/SISO/MIMO]_SWITCH_* */ | ||
364 | u8 max_search; /* maximun number of tables we can search */ | ||
365 | s32 *expected_tpt; /* throughput metrics; expected_tpt_G, etc. */ | ||
366 | u32 current_rate; /* rate_n_flags, uCode API format */ | ||
367 | struct iwl_rate_scale_data win[IWL_RATE_COUNT]; /* rate histories */ | ||
368 | }; | ||
369 | |||
370 | struct iwl_traffic_load { | ||
371 | unsigned long time_stamp; /* age of the oldest statistics */ | ||
372 | u32 packet_count[TID_QUEUE_MAX_SIZE]; /* packet count in this time | ||
373 | * slice */ | ||
374 | u32 total; /* total num of packets during the | ||
375 | * last TID_MAX_TIME_DIFF */ | ||
376 | u8 queue_count; /* number of queues that has | ||
377 | * been used since the last cleanup */ | ||
378 | u8 head; /* start of the circular buffer */ | ||
379 | }; | ||
380 | |||
381 | /** | ||
382 | * struct iwl_lq_sta -- driver's rate scaling private structure | ||
383 | * | ||
384 | * Pointer to this gets passed back and forth between driver and mac80211. | ||
385 | */ | ||
386 | struct iwl_lq_sta { | ||
387 | u8 active_tbl; /* index of active table, range 0-1 */ | ||
388 | u8 enable_counter; /* indicates HT mode */ | ||
389 | u8 stay_in_tbl; /* 1: disallow, 0: allow search for new mode */ | ||
390 | u8 search_better_tbl; /* 1: currently trying alternate mode */ | ||
391 | s32 last_tpt; | ||
392 | |||
393 | /* The following determine when to search for a new mode */ | ||
394 | u32 table_count_limit; | ||
395 | u32 max_failure_limit; /* # failed frames before new search */ | ||
396 | u32 max_success_limit; /* # successful frames before new search */ | ||
397 | u32 table_count; | ||
398 | u32 total_failed; /* total failed frames, any/all rates */ | ||
399 | u32 total_success; /* total successful frames, any/all rates */ | ||
400 | u64 flush_timer; /* time staying in mode before new search */ | ||
401 | |||
402 | u8 action_counter; /* # mode-switch actions tried */ | ||
403 | u8 is_green; | ||
404 | u8 is_dup; | ||
405 | enum ieee80211_band band; | ||
406 | u8 ibss_sta_added; | ||
407 | |||
408 | /* The following are bitmaps of rates; IWL_RATE_6M_MASK, etc. */ | ||
409 | u32 supp_rates; | ||
410 | u16 active_legacy_rate; | ||
411 | u16 active_siso_rate; | ||
412 | u16 active_mimo2_rate; | ||
413 | u16 active_mimo3_rate; | ||
414 | u16 active_rate_basic; | ||
415 | s8 max_rate_idx; /* Max rate set by user */ | ||
416 | u8 missed_rate_counter; | ||
417 | |||
418 | struct iwl_link_quality_cmd lq; | ||
419 | struct iwl_scale_tbl_info lq_info[LQ_SIZE]; /* "active", "search" */ | ||
420 | struct iwl_traffic_load load[TID_MAX_LOAD_COUNT]; | ||
421 | u8 tx_agg_tid_en; | ||
422 | #ifdef CONFIG_MAC80211_DEBUGFS | ||
423 | struct dentry *rs_sta_dbgfs_scale_table_file; | ||
424 | struct dentry *rs_sta_dbgfs_stats_table_file; | ||
425 | struct dentry *rs_sta_dbgfs_rate_scale_data_file; | ||
426 | struct dentry *rs_sta_dbgfs_tx_agg_tid_en_file; | ||
427 | u32 dbg_fixed_rate; | ||
428 | #endif | ||
429 | struct iwl_priv *drv; | ||
430 | |||
431 | /* used to be in sta_info */ | ||
432 | int last_txrate_idx; | ||
433 | /* last tx rate_n_flags */ | ||
434 | u32 last_rate_n_flags; | ||
435 | /* packets destined for this STA are aggregated */ | ||
436 | u8 is_agg; | ||
437 | }; | ||
438 | |||
338 | static inline u8 num_of_ant(u8 mask) | 439 | static inline u8 num_of_ant(u8 mask) |
339 | { | 440 | { |
340 | return !!((mask) & ANT_A) + | 441 | return !!((mask) & ANT_A) + |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 8d7bc38fe005..fa1672e99e4b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c | |||
@@ -524,7 +524,7 @@ int iwl_hw_tx_queue_init(struct iwl_priv *priv, | |||
524 | static void iwl_rx_reply_alive(struct iwl_priv *priv, | 524 | static void iwl_rx_reply_alive(struct iwl_priv *priv, |
525 | struct iwl_rx_mem_buffer *rxb) | 525 | struct iwl_rx_mem_buffer *rxb) |
526 | { | 526 | { |
527 | struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; | 527 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
528 | struct iwl_alive_resp *palive; | 528 | struct iwl_alive_resp *palive; |
529 | struct delayed_work *pwork; | 529 | struct delayed_work *pwork; |
530 | 530 | ||
@@ -610,7 +610,7 @@ static void iwl_rx_beacon_notif(struct iwl_priv *priv, | |||
610 | struct iwl_rx_mem_buffer *rxb) | 610 | struct iwl_rx_mem_buffer *rxb) |
611 | { | 611 | { |
612 | #ifdef CONFIG_IWLWIFI_DEBUG | 612 | #ifdef CONFIG_IWLWIFI_DEBUG |
613 | struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; | 613 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
614 | struct iwl4965_beacon_notif *beacon = | 614 | struct iwl4965_beacon_notif *beacon = |
615 | (struct iwl4965_beacon_notif *)pkt->u.raw; | 615 | (struct iwl4965_beacon_notif *)pkt->u.raw; |
616 | u8 rate = iwl_hw_get_rate(beacon->beacon_notify_hdr.rate_n_flags); | 616 | u8 rate = iwl_hw_get_rate(beacon->beacon_notify_hdr.rate_n_flags); |
@@ -634,7 +634,7 @@ static void iwl_rx_beacon_notif(struct iwl_priv *priv, | |||
634 | static void iwl_rx_card_state_notif(struct iwl_priv *priv, | 634 | static void iwl_rx_card_state_notif(struct iwl_priv *priv, |
635 | struct iwl_rx_mem_buffer *rxb) | 635 | struct iwl_rx_mem_buffer *rxb) |
636 | { | 636 | { |
637 | struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; | 637 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
638 | u32 flags = le32_to_cpu(pkt->u.card_state_notif.flags); | 638 | u32 flags = le32_to_cpu(pkt->u.card_state_notif.flags); |
639 | unsigned long status = priv->status; | 639 | unsigned long status = priv->status; |
640 | 640 | ||
@@ -769,7 +769,7 @@ void iwl_rx_handle(struct iwl_priv *priv) | |||
769 | IWL_DEBUG_RX(priv, "r = %d, i = %d\n", r, i); | 769 | IWL_DEBUG_RX(priv, "r = %d, i = %d\n", r, i); |
770 | 770 | ||
771 | /* calculate total frames need to be restock after handling RX */ | 771 | /* calculate total frames need to be restock after handling RX */ |
772 | total_empty = r - priv->rxq.write_actual; | 772 | total_empty = r - rxq->write_actual; |
773 | if (total_empty < 0) | 773 | if (total_empty < 0) |
774 | total_empty += RX_QUEUE_SIZE; | 774 | total_empty += RX_QUEUE_SIZE; |
775 | 775 | ||
@@ -786,10 +786,10 @@ void iwl_rx_handle(struct iwl_priv *priv) | |||
786 | 786 | ||
787 | rxq->queue[i] = NULL; | 787 | rxq->queue[i] = NULL; |
788 | 788 | ||
789 | pci_unmap_single(priv->pci_dev, rxb->real_dma_addr, | 789 | pci_unmap_page(priv->pci_dev, rxb->page_dma, |
790 | priv->hw_params.rx_buf_size + 256, | 790 | PAGE_SIZE << priv->hw_params.rx_page_order, |
791 | PCI_DMA_FROMDEVICE); | 791 | PCI_DMA_FROMDEVICE); |
792 | pkt = (struct iwl_rx_packet *)rxb->skb->data; | 792 | pkt = rxb_addr(rxb); |
793 | 793 | ||
794 | trace_iwlwifi_dev_rx(priv, pkt, | 794 | trace_iwlwifi_dev_rx(priv, pkt, |
795 | le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK); | 795 | le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK); |
@@ -814,8 +814,8 @@ void iwl_rx_handle(struct iwl_priv *priv) | |||
814 | if (priv->rx_handlers[pkt->hdr.cmd]) { | 814 | if (priv->rx_handlers[pkt->hdr.cmd]) { |
815 | IWL_DEBUG_RX(priv, "r = %d, i = %d, %s, 0x%02x\n", r, | 815 | IWL_DEBUG_RX(priv, "r = %d, i = %d, %s, 0x%02x\n", r, |
816 | i, get_cmd_string(pkt->hdr.cmd), pkt->hdr.cmd); | 816 | i, get_cmd_string(pkt->hdr.cmd), pkt->hdr.cmd); |
817 | priv->rx_handlers[pkt->hdr.cmd] (priv, rxb); | ||
818 | priv->isr_stats.rx_handlers[pkt->hdr.cmd]++; | 817 | priv->isr_stats.rx_handlers[pkt->hdr.cmd]++; |
818 | priv->rx_handlers[pkt->hdr.cmd] (priv, rxb); | ||
819 | } else { | 819 | } else { |
820 | /* No handling needed */ | 820 | /* No handling needed */ |
821 | IWL_DEBUG_RX(priv, | 821 | IWL_DEBUG_RX(priv, |
@@ -824,35 +824,45 @@ void iwl_rx_handle(struct iwl_priv *priv) | |||
824 | pkt->hdr.cmd); | 824 | pkt->hdr.cmd); |
825 | } | 825 | } |
826 | 826 | ||
827 | /* | ||
828 | * XXX: After here, we should always check rxb->page | ||
829 | * against NULL before touching it or its virtual | ||
830 | * memory (pkt). Because some rx_handler might have | ||
831 | * already taken or freed the pages. | ||
832 | */ | ||
833 | |||
827 | if (reclaim) { | 834 | if (reclaim) { |
828 | /* Invoke any callbacks, transfer the skb to caller, and | 835 | /* Invoke any callbacks, transfer the buffer to caller, |
829 | * fire off the (possibly) blocking iwl_send_cmd() | 836 | * and fire off the (possibly) blocking iwl_send_cmd() |
830 | * as we reclaim the driver command queue */ | 837 | * as we reclaim the driver command queue */ |
831 | if (rxb && rxb->skb) | 838 | if (rxb->page) |
832 | iwl_tx_cmd_complete(priv, rxb); | 839 | iwl_tx_cmd_complete(priv, rxb); |
833 | else | 840 | else |
834 | IWL_WARN(priv, "Claim null rxb?\n"); | 841 | IWL_WARN(priv, "Claim null rxb?\n"); |
835 | } | 842 | } |
836 | 843 | ||
837 | /* For now we just don't re-use anything. We can tweak this | 844 | /* Reuse the page if possible. For notification packets and |
838 | * later to try and re-use notification packets and SKBs that | 845 | * SKBs that fail to Rx correctly, add them back into the |
839 | * fail to Rx correctly */ | 846 | * rx_free list for reuse later. */ |
840 | if (rxb->skb != NULL) { | ||
841 | priv->alloc_rxb_skb--; | ||
842 | dev_kfree_skb_any(rxb->skb); | ||
843 | rxb->skb = NULL; | ||
844 | } | ||
845 | |||
846 | spin_lock_irqsave(&rxq->lock, flags); | 847 | spin_lock_irqsave(&rxq->lock, flags); |
847 | list_add_tail(&rxb->list, &priv->rxq.rx_used); | 848 | if (rxb->page != NULL) { |
849 | rxb->page_dma = pci_map_page(priv->pci_dev, rxb->page, | ||
850 | 0, PAGE_SIZE << priv->hw_params.rx_page_order, | ||
851 | PCI_DMA_FROMDEVICE); | ||
852 | list_add_tail(&rxb->list, &rxq->rx_free); | ||
853 | rxq->free_count++; | ||
854 | } else | ||
855 | list_add_tail(&rxb->list, &rxq->rx_used); | ||
856 | |||
848 | spin_unlock_irqrestore(&rxq->lock, flags); | 857 | spin_unlock_irqrestore(&rxq->lock, flags); |
858 | |||
849 | i = (i + 1) & RX_QUEUE_MASK; | 859 | i = (i + 1) & RX_QUEUE_MASK; |
850 | /* If there are a lot of unused frames, | 860 | /* If there are a lot of unused frames, |
851 | * restock the Rx queue so ucode wont assert. */ | 861 | * restock the Rx queue so ucode wont assert. */ |
852 | if (fill_rx) { | 862 | if (fill_rx) { |
853 | count++; | 863 | count++; |
854 | if (count >= 8) { | 864 | if (count >= 8) { |
855 | priv->rxq.read = i; | 865 | rxq->read = i; |
856 | iwl_rx_replenish_now(priv); | 866 | iwl_rx_replenish_now(priv); |
857 | count = 0; | 867 | count = 0; |
858 | } | 868 | } |
@@ -860,7 +870,7 @@ void iwl_rx_handle(struct iwl_priv *priv) | |||
860 | } | 870 | } |
861 | 871 | ||
862 | /* Backtrack one entry */ | 872 | /* Backtrack one entry */ |
863 | priv->rxq.read = i; | 873 | rxq->read = i; |
864 | if (fill_rx) | 874 | if (fill_rx) |
865 | iwl_rx_replenish_now(priv); | 875 | iwl_rx_replenish_now(priv); |
866 | else | 876 | else |
@@ -907,6 +917,8 @@ static void iwl_irq_tasklet_legacy(struct iwl_priv *priv) | |||
907 | } | 917 | } |
908 | #endif | 918 | #endif |
909 | 919 | ||
920 | spin_unlock_irqrestore(&priv->lock, flags); | ||
921 | |||
910 | /* Since CSR_INT and CSR_FH_INT_STATUS reads and clears are not | 922 | /* Since CSR_INT and CSR_FH_INT_STATUS reads and clears are not |
911 | * atomic, make sure that inta covers all the interrupts that | 923 | * atomic, make sure that inta covers all the interrupts that |
912 | * we've discovered, even if FH interrupt came in just after | 924 | * we've discovered, even if FH interrupt came in just after |
@@ -928,8 +940,6 @@ static void iwl_irq_tasklet_legacy(struct iwl_priv *priv) | |||
928 | 940 | ||
929 | handled |= CSR_INT_BIT_HW_ERR; | 941 | handled |= CSR_INT_BIT_HW_ERR; |
930 | 942 | ||
931 | spin_unlock_irqrestore(&priv->lock, flags); | ||
932 | |||
933 | return; | 943 | return; |
934 | } | 944 | } |
935 | 945 | ||
@@ -1019,6 +1029,7 @@ static void iwl_irq_tasklet_legacy(struct iwl_priv *priv) | |||
1019 | if (inta & (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX)) { | 1029 | if (inta & (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX)) { |
1020 | iwl_rx_handle(priv); | 1030 | iwl_rx_handle(priv); |
1021 | priv->isr_stats.rx++; | 1031 | priv->isr_stats.rx++; |
1032 | iwl_leds_background(priv); | ||
1022 | handled |= (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX); | 1033 | handled |= (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX); |
1023 | } | 1034 | } |
1024 | 1035 | ||
@@ -1056,7 +1067,6 @@ static void iwl_irq_tasklet_legacy(struct iwl_priv *priv) | |||
1056 | "flags 0x%08lx\n", inta, inta_mask, inta_fh, flags); | 1067 | "flags 0x%08lx\n", inta, inta_mask, inta_fh, flags); |
1057 | } | 1068 | } |
1058 | #endif | 1069 | #endif |
1059 | spin_unlock_irqrestore(&priv->lock, flags); | ||
1060 | } | 1070 | } |
1061 | 1071 | ||
1062 | /* tasklet for iwlagn interrupt */ | 1072 | /* tasklet for iwlagn interrupt */ |
@@ -1086,6 +1096,9 @@ static void iwl_irq_tasklet(struct iwl_priv *priv) | |||
1086 | inta, inta_mask); | 1096 | inta, inta_mask); |
1087 | } | 1097 | } |
1088 | #endif | 1098 | #endif |
1099 | |||
1100 | spin_unlock_irqrestore(&priv->lock, flags); | ||
1101 | |||
1089 | /* saved interrupt in inta variable now we can reset priv->inta */ | 1102 | /* saved interrupt in inta variable now we can reset priv->inta */ |
1090 | priv->inta = 0; | 1103 | priv->inta = 0; |
1091 | 1104 | ||
@@ -1101,8 +1114,6 @@ static void iwl_irq_tasklet(struct iwl_priv *priv) | |||
1101 | 1114 | ||
1102 | handled |= CSR_INT_BIT_HW_ERR; | 1115 | handled |= CSR_INT_BIT_HW_ERR; |
1103 | 1116 | ||
1104 | spin_unlock_irqrestore(&priv->lock, flags); | ||
1105 | |||
1106 | return; | 1117 | return; |
1107 | } | 1118 | } |
1108 | 1119 | ||
@@ -1220,6 +1231,7 @@ static void iwl_irq_tasklet(struct iwl_priv *priv) | |||
1220 | CSR_INT_PERIODIC_ENA); | 1231 | CSR_INT_PERIODIC_ENA); |
1221 | 1232 | ||
1222 | priv->isr_stats.rx++; | 1233 | priv->isr_stats.rx++; |
1234 | iwl_leds_background(priv); | ||
1223 | } | 1235 | } |
1224 | 1236 | ||
1225 | if (inta & CSR_INT_BIT_FH_TX) { | 1237 | if (inta & CSR_INT_BIT_FH_TX) { |
@@ -1242,14 +1254,10 @@ static void iwl_irq_tasklet(struct iwl_priv *priv) | |||
1242 | inta & ~priv->inta_mask); | 1254 | inta & ~priv->inta_mask); |
1243 | } | 1255 | } |
1244 | 1256 | ||
1245 | |||
1246 | /* Re-enable all interrupts */ | 1257 | /* Re-enable all interrupts */ |
1247 | /* only Re-enable if diabled by irq */ | 1258 | /* only Re-enable if diabled by irq */ |
1248 | if (test_bit(STATUS_INT_ENABLED, &priv->status)) | 1259 | if (test_bit(STATUS_INT_ENABLED, &priv->status)) |
1249 | iwl_enable_interrupts(priv); | 1260 | iwl_enable_interrupts(priv); |
1250 | |||
1251 | spin_unlock_irqrestore(&priv->lock, flags); | ||
1252 | |||
1253 | } | 1261 | } |
1254 | 1262 | ||
1255 | 1263 | ||
@@ -1899,11 +1907,9 @@ static void __iwl_down(struct iwl_priv *priv) | |||
1899 | 1907 | ||
1900 | udelay(5); | 1908 | udelay(5); |
1901 | 1909 | ||
1902 | /* FIXME: apm_ops.suspend(priv) */ | 1910 | /* Stop the device, and put it in low power state */ |
1903 | if (exit_pending) | 1911 | priv->cfg->ops->lib->apm_ops.stop(priv); |
1904 | priv->cfg->ops->lib->apm_ops.stop(priv); | 1912 | |
1905 | else | ||
1906 | priv->cfg->ops->lib->apm_ops.reset(priv); | ||
1907 | exit: | 1913 | exit: |
1908 | memset(&priv->card_alive, 0, sizeof(struct iwl_alive_resp)); | 1914 | memset(&priv->card_alive, 0, sizeof(struct iwl_alive_resp)); |
1909 | 1915 | ||
@@ -2290,6 +2296,69 @@ void iwl_post_associate(struct iwl_priv *priv) | |||
2290 | 2296 | ||
2291 | #define UCODE_READY_TIMEOUT (4 * HZ) | 2297 | #define UCODE_READY_TIMEOUT (4 * HZ) |
2292 | 2298 | ||
2299 | /* | ||
2300 | * Not a mac80211 entry point function, but it fits in with all the | ||
2301 | * other mac80211 functions grouped here. | ||
2302 | */ | ||
2303 | static int iwl_setup_mac(struct iwl_priv *priv) | ||
2304 | { | ||
2305 | int ret; | ||
2306 | struct ieee80211_hw *hw = priv->hw; | ||
2307 | hw->rate_control_algorithm = "iwl-agn-rs"; | ||
2308 | |||
2309 | /* Tell mac80211 our characteristics */ | ||
2310 | hw->flags = IEEE80211_HW_SIGNAL_DBM | | ||
2311 | IEEE80211_HW_NOISE_DBM | | ||
2312 | IEEE80211_HW_AMPDU_AGGREGATION | | ||
2313 | IEEE80211_HW_SPECTRUM_MGMT; | ||
2314 | |||
2315 | if (!priv->cfg->broken_powersave) | ||
2316 | hw->flags |= IEEE80211_HW_SUPPORTS_PS | | ||
2317 | IEEE80211_HW_SUPPORTS_DYNAMIC_PS; | ||
2318 | |||
2319 | hw->sta_data_size = sizeof(struct iwl_station_priv); | ||
2320 | hw->wiphy->interface_modes = | ||
2321 | BIT(NL80211_IFTYPE_STATION) | | ||
2322 | BIT(NL80211_IFTYPE_ADHOC); | ||
2323 | |||
2324 | hw->wiphy->custom_regulatory = true; | ||
2325 | |||
2326 | /* Firmware does not support this */ | ||
2327 | hw->wiphy->disable_beacon_hints = true; | ||
2328 | |||
2329 | /* | ||
2330 | * For now, disable PS by default because it affects | ||
2331 | * RX performance significantly. | ||
2332 | */ | ||
2333 | hw->wiphy->ps_default = false; | ||
2334 | |||
2335 | hw->wiphy->max_scan_ssids = PROBE_OPTION_MAX; | ||
2336 | /* we create the 802.11 header and a zero-length SSID element */ | ||
2337 | hw->wiphy->max_scan_ie_len = IWL_MAX_PROBE_REQUEST - 24 - 2; | ||
2338 | |||
2339 | /* Default value; 4 EDCA QOS priorities */ | ||
2340 | hw->queues = 4; | ||
2341 | |||
2342 | hw->max_listen_interval = IWL_CONN_MAX_LISTEN_INTERVAL; | ||
2343 | |||
2344 | if (priv->bands[IEEE80211_BAND_2GHZ].n_channels) | ||
2345 | priv->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = | ||
2346 | &priv->bands[IEEE80211_BAND_2GHZ]; | ||
2347 | if (priv->bands[IEEE80211_BAND_5GHZ].n_channels) | ||
2348 | priv->hw->wiphy->bands[IEEE80211_BAND_5GHZ] = | ||
2349 | &priv->bands[IEEE80211_BAND_5GHZ]; | ||
2350 | |||
2351 | ret = ieee80211_register_hw(priv->hw); | ||
2352 | if (ret) { | ||
2353 | IWL_ERR(priv, "Failed to register hw (error %d)\n", ret); | ||
2354 | return ret; | ||
2355 | } | ||
2356 | priv->mac80211_registered = 1; | ||
2357 | |||
2358 | return 0; | ||
2359 | } | ||
2360 | |||
2361 | |||
2293 | static int iwl_mac_start(struct ieee80211_hw *hw) | 2362 | static int iwl_mac_start(struct ieee80211_hw *hw) |
2294 | { | 2363 | { |
2295 | struct iwl_priv *priv = hw->priv; | 2364 | struct iwl_priv *priv = hw->priv; |
@@ -3187,6 +3256,15 @@ static void __devexit iwl_pci_remove(struct pci_dev *pdev) | |||
3187 | iwl_down(priv); | 3256 | iwl_down(priv); |
3188 | } | 3257 | } |
3189 | 3258 | ||
3259 | /* | ||
3260 | * Make sure device is reset to low power before unloading driver. | ||
3261 | * This may be redundant with iwl_down(), but there are paths to | ||
3262 | * run iwl_down() without calling apm_ops.stop(), and there are | ||
3263 | * paths to avoid running iwl_down() at all before leaving driver. | ||
3264 | * This (inexpensive) call *makes sure* device is reset. | ||
3265 | */ | ||
3266 | priv->cfg->ops->lib->apm_ops.stop(priv); | ||
3267 | |||
3190 | iwl_tt_exit(priv); | 3268 | iwl_tt_exit(priv); |
3191 | 3269 | ||
3192 | /* make sure we flush any pending irq or | 3270 | /* make sure we flush any pending irq or |
diff --git a/drivers/net/wireless/iwlwifi/iwl-calib.c b/drivers/net/wireless/iwlwifi/iwl-calib.c index 69a80d7c2e44..1f801eb9fbff 100644 --- a/drivers/net/wireless/iwlwifi/iwl-calib.c +++ b/drivers/net/wireless/iwlwifi/iwl-calib.c | |||
@@ -447,11 +447,11 @@ static int iwl_sensitivity_write(struct iwl_priv *priv) | |||
447 | cpu_to_le16((u16)data->nrg_th_ofdm); | 447 | cpu_to_le16((u16)data->nrg_th_ofdm); |
448 | 448 | ||
449 | cmd.table[HD_BARKER_CORR_TH_ADD_MIN_INDEX] = | 449 | cmd.table[HD_BARKER_CORR_TH_ADD_MIN_INDEX] = |
450 | cpu_to_le16(190); | 450 | cpu_to_le16(data->barker_corr_th_min); |
451 | cmd.table[HD_BARKER_CORR_TH_ADD_MIN_MRC_INDEX] = | 451 | cmd.table[HD_BARKER_CORR_TH_ADD_MIN_MRC_INDEX] = |
452 | cpu_to_le16(390); | 452 | cpu_to_le16(data->barker_corr_th_min_mrc); |
453 | cmd.table[HD_OFDM_ENERGY_TH_IN_INDEX] = | 453 | cmd.table[HD_OFDM_ENERGY_TH_IN_INDEX] = |
454 | cpu_to_le16(62); | 454 | cpu_to_le16(data->nrg_th_cca); |
455 | 455 | ||
456 | IWL_DEBUG_CALIB(priv, "ofdm: ac %u mrc %u x1 %u mrc_x1 %u thresh %u\n", | 456 | IWL_DEBUG_CALIB(priv, "ofdm: ac %u mrc %u x1 %u mrc_x1 %u thresh %u\n", |
457 | data->auto_corr_ofdm, data->auto_corr_ofdm_mrc, | 457 | data->auto_corr_ofdm, data->auto_corr_ofdm_mrc, |
@@ -524,6 +524,9 @@ void iwl_init_sensitivity(struct iwl_priv *priv) | |||
524 | data->auto_corr_cck_mrc = ranges->auto_corr_min_cck_mrc; | 524 | data->auto_corr_cck_mrc = ranges->auto_corr_min_cck_mrc; |
525 | data->nrg_th_cck = ranges->nrg_th_cck; | 525 | data->nrg_th_cck = ranges->nrg_th_cck; |
526 | data->nrg_th_ofdm = ranges->nrg_th_ofdm; | 526 | data->nrg_th_ofdm = ranges->nrg_th_ofdm; |
527 | data->barker_corr_th_min = ranges->barker_corr_th_min; | ||
528 | data->barker_corr_th_min_mrc = ranges->barker_corr_th_min_mrc; | ||
529 | data->nrg_th_cca = ranges->nrg_th_cca; | ||
527 | 530 | ||
528 | data->last_bad_plcp_cnt_ofdm = 0; | 531 | data->last_bad_plcp_cnt_ofdm = 0; |
529 | data->last_fa_cnt_ofdm = 0; | 532 | data->last_fa_cnt_ofdm = 0; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h index ba3e4c837d87..954bad60355d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-commands.h +++ b/drivers/net/wireless/iwlwifi/iwl-commands.h | |||
@@ -109,11 +109,12 @@ enum { | |||
109 | REPLY_TX_LINK_QUALITY_CMD = 0x4e, /* 4965 only */ | 109 | REPLY_TX_LINK_QUALITY_CMD = 0x4e, /* 4965 only */ |
110 | 110 | ||
111 | /* WiMAX coexistence */ | 111 | /* WiMAX coexistence */ |
112 | COEX_PRIORITY_TABLE_CMD = 0x5a, /*5000 only */ | 112 | COEX_PRIORITY_TABLE_CMD = 0x5a, /* for 5000 series and up */ |
113 | COEX_MEDIUM_NOTIFICATION = 0x5b, | 113 | COEX_MEDIUM_NOTIFICATION = 0x5b, |
114 | COEX_EVENT_CMD = 0x5c, | 114 | COEX_EVENT_CMD = 0x5c, |
115 | 115 | ||
116 | /* Calibration */ | 116 | /* Calibration */ |
117 | TEMPERATURE_NOTIFICATION = 0x62, | ||
117 | CALIBRATION_CFG_CMD = 0x65, | 118 | CALIBRATION_CFG_CMD = 0x65, |
118 | CALIBRATION_RES_NOTIFICATION = 0x66, | 119 | CALIBRATION_RES_NOTIFICATION = 0x66, |
119 | CALIBRATION_COMPLETE_NOTIFICATION = 0x67, | 120 | CALIBRATION_COMPLETE_NOTIFICATION = 0x67, |
@@ -353,6 +354,9 @@ struct iwl3945_power_per_rate { | |||
353 | #define POWER_TABLE_NUM_HT_OFDM_ENTRIES 32 | 354 | #define POWER_TABLE_NUM_HT_OFDM_ENTRIES 32 |
354 | #define POWER_TABLE_CCK_ENTRY 32 | 355 | #define POWER_TABLE_CCK_ENTRY 32 |
355 | 356 | ||
357 | #define IWL_PWR_NUM_HT_OFDM_ENTRIES 24 | ||
358 | #define IWL_PWR_CCK_ENTRIES 2 | ||
359 | |||
356 | /** | 360 | /** |
357 | * union iwl4965_tx_power_dual_stream | 361 | * union iwl4965_tx_power_dual_stream |
358 | * | 362 | * |
@@ -803,7 +807,7 @@ struct iwl3945_channel_switch_cmd { | |||
803 | struct iwl3945_power_per_rate power[IWL_MAX_RATES]; | 807 | struct iwl3945_power_per_rate power[IWL_MAX_RATES]; |
804 | } __attribute__ ((packed)); | 808 | } __attribute__ ((packed)); |
805 | 809 | ||
806 | struct iwl_channel_switch_cmd { | 810 | struct iwl4965_channel_switch_cmd { |
807 | u8 band; | 811 | u8 band; |
808 | u8 expect_beacon; | 812 | u8 expect_beacon; |
809 | __le16 channel; | 813 | __le16 channel; |
@@ -813,6 +817,48 @@ struct iwl_channel_switch_cmd { | |||
813 | struct iwl4965_tx_power_db tx_power; | 817 | struct iwl4965_tx_power_db tx_power; |
814 | } __attribute__ ((packed)); | 818 | } __attribute__ ((packed)); |
815 | 819 | ||
820 | /** | ||
821 | * struct iwl5000_channel_switch_cmd | ||
822 | * @band: 0- 5.2GHz, 1- 2.4GHz | ||
823 | * @expect_beacon: 0- resume transmits after channel switch | ||
824 | * 1- wait for beacon to resume transmits | ||
825 | * @channel: new channel number | ||
826 | * @rxon_flags: Rx on flags | ||
827 | * @rxon_filter_flags: filtering parameters | ||
828 | * @switch_time: switch time in extended beacon format | ||
829 | * @reserved: reserved bytes | ||
830 | */ | ||
831 | struct iwl5000_channel_switch_cmd { | ||
832 | u8 band; | ||
833 | u8 expect_beacon; | ||
834 | __le16 channel; | ||
835 | __le32 rxon_flags; | ||
836 | __le32 rxon_filter_flags; | ||
837 | __le32 switch_time; | ||
838 | __le32 reserved[2][IWL_PWR_NUM_HT_OFDM_ENTRIES + IWL_PWR_CCK_ENTRIES]; | ||
839 | } __attribute__ ((packed)); | ||
840 | |||
841 | /** | ||
842 | * struct iwl6000_channel_switch_cmd | ||
843 | * @band: 0- 5.2GHz, 1- 2.4GHz | ||
844 | * @expect_beacon: 0- resume transmits after channel switch | ||
845 | * 1- wait for beacon to resume transmits | ||
846 | * @channel: new channel number | ||
847 | * @rxon_flags: Rx on flags | ||
848 | * @rxon_filter_flags: filtering parameters | ||
849 | * @switch_time: switch time in extended beacon format | ||
850 | * @reserved: reserved bytes | ||
851 | */ | ||
852 | struct iwl6000_channel_switch_cmd { | ||
853 | u8 band; | ||
854 | u8 expect_beacon; | ||
855 | __le16 channel; | ||
856 | __le32 rxon_flags; | ||
857 | __le32 rxon_filter_flags; | ||
858 | __le32 switch_time; | ||
859 | __le32 reserved[3][IWL_PWR_NUM_HT_OFDM_ENTRIES + IWL_PWR_CCK_ENTRIES]; | ||
860 | } __attribute__ ((packed)); | ||
861 | |||
816 | /* | 862 | /* |
817 | * CHANNEL_SWITCH_NOTIFICATION = 0x73 (notification only, not a command) | 863 | * CHANNEL_SWITCH_NOTIFICATION = 0x73 (notification only, not a command) |
818 | */ | 864 | */ |
@@ -2172,6 +2218,19 @@ struct iwl_link_quality_cmd { | |||
2172 | __le32 reserved2; | 2218 | __le32 reserved2; |
2173 | } __attribute__ ((packed)); | 2219 | } __attribute__ ((packed)); |
2174 | 2220 | ||
2221 | #define BT_COEX_DISABLE (0x0) | ||
2222 | #define BT_COEX_MODE_2W (0x1) | ||
2223 | #define BT_COEX_MODE_3W (0x2) | ||
2224 | #define BT_COEX_MODE_4W (0x3) | ||
2225 | |||
2226 | #define BT_LEAD_TIME_MIN (0x0) | ||
2227 | #define BT_LEAD_TIME_DEF (0x1E) | ||
2228 | #define BT_LEAD_TIME_MAX (0xFF) | ||
2229 | |||
2230 | #define BT_MAX_KILL_MIN (0x1) | ||
2231 | #define BT_MAX_KILL_DEF (0x5) | ||
2232 | #define BT_MAX_KILL_MAX (0xFF) | ||
2233 | |||
2175 | /* | 2234 | /* |
2176 | * REPLY_BT_CONFIG = 0x9b (command, has simple generic response) | 2235 | * REPLY_BT_CONFIG = 0x9b (command, has simple generic response) |
2177 | * | 2236 | * |
@@ -3247,12 +3306,6 @@ struct iwl_missed_beacon_notif { | |||
3247 | * Lower values mean higher energy; this means making sure that the value | 3306 | * Lower values mean higher energy; this means making sure that the value |
3248 | * in HD_MIN_ENERGY_CCK_DET_INDEX is at or *above* "Max cck energy". | 3307 | * in HD_MIN_ENERGY_CCK_DET_INDEX is at or *above* "Max cck energy". |
3249 | * | 3308 | * |
3250 | * Driver should set the following entries to fixed values: | ||
3251 | * | ||
3252 | * HD_MIN_ENERGY_OFDM_DET_INDEX 100 | ||
3253 | * HD_BARKER_CORR_TH_ADD_MIN_INDEX 190 | ||
3254 | * HD_BARKER_CORR_TH_ADD_MIN_MRC_INDEX 390 | ||
3255 | * HD_OFDM_ENERGY_TH_IN_INDEX 62 | ||
3256 | */ | 3309 | */ |
3257 | 3310 | ||
3258 | /* | 3311 | /* |
@@ -3505,6 +3558,16 @@ struct iwl_wimax_coex_cmd { | |||
3505 | *****************************************************************************/ | 3558 | *****************************************************************************/ |
3506 | 3559 | ||
3507 | struct iwl_rx_packet { | 3560 | struct iwl_rx_packet { |
3561 | /* | ||
3562 | * The first 4 bytes of the RX frame header contain both the RX frame | ||
3563 | * size and some flags. | ||
3564 | * Bit fields: | ||
3565 | * 31: flag flush RB request | ||
3566 | * 30: flag ignore TC (terminal counter) request | ||
3567 | * 29: flag fast IRQ request | ||
3568 | * 28-14: Reserved | ||
3569 | * 13-00: RX frame size | ||
3570 | */ | ||
3508 | __le32 len_n_flags; | 3571 | __le32 len_n_flags; |
3509 | struct iwl_cmd_header hdr; | 3572 | struct iwl_cmd_header hdr; |
3510 | union { | 3573 | union { |
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index dc7fd87bed98..d2b56baf98fb 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c | |||
@@ -604,6 +604,23 @@ void iwlcore_free_geos(struct iwl_priv *priv) | |||
604 | } | 604 | } |
605 | EXPORT_SYMBOL(iwlcore_free_geos); | 605 | EXPORT_SYMBOL(iwlcore_free_geos); |
606 | 606 | ||
607 | /* | ||
608 | * iwlcore_rts_tx_cmd_flag: Set rts/cts. 3945 and 4965 only share this | ||
609 | * function. | ||
610 | */ | ||
611 | void iwlcore_rts_tx_cmd_flag(struct ieee80211_tx_info *info, | ||
612 | __le32 *tx_flags) | ||
613 | { | ||
614 | if (info->control.rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS) { | ||
615 | *tx_flags |= TX_CMD_FLG_RTS_MSK; | ||
616 | *tx_flags &= ~TX_CMD_FLG_CTS_MSK; | ||
617 | } else if (info->control.rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT) { | ||
618 | *tx_flags &= ~TX_CMD_FLG_RTS_MSK; | ||
619 | *tx_flags |= TX_CMD_FLG_CTS_MSK; | ||
620 | } | ||
621 | } | ||
622 | EXPORT_SYMBOL(iwlcore_rts_tx_cmd_flag); | ||
623 | |||
607 | static bool is_single_rx_stream(struct iwl_priv *priv) | 624 | static bool is_single_rx_stream(struct iwl_priv *priv) |
608 | { | 625 | { |
609 | return !priv->current_ht_config.is_ht || | 626 | return !priv->current_ht_config.is_ht || |
@@ -1264,13 +1281,18 @@ static void iwl_set_rate(struct iwl_priv *priv) | |||
1264 | 1281 | ||
1265 | void iwl_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) | 1282 | void iwl_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) |
1266 | { | 1283 | { |
1267 | struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; | 1284 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
1268 | struct iwl_rxon_cmd *rxon = (void *)&priv->active_rxon; | 1285 | struct iwl_rxon_cmd *rxon = (void *)&priv->active_rxon; |
1269 | struct iwl_csa_notification *csa = &(pkt->u.csa_notif); | 1286 | struct iwl_csa_notification *csa = &(pkt->u.csa_notif); |
1270 | IWL_DEBUG_11H(priv, "CSA notif: channel %d, status %d\n", | 1287 | |
1271 | le16_to_cpu(csa->channel), le32_to_cpu(csa->status)); | 1288 | if (!le32_to_cpu(csa->status)) { |
1272 | rxon->channel = csa->channel; | 1289 | rxon->channel = csa->channel; |
1273 | priv->staging_rxon.channel = csa->channel; | 1290 | priv->staging_rxon.channel = csa->channel; |
1291 | IWL_DEBUG_11H(priv, "CSA notif: channel %d\n", | ||
1292 | le16_to_cpu(csa->channel)); | ||
1293 | } else | ||
1294 | IWL_ERR(priv, "CSA notif (fail) : channel %d\n", | ||
1295 | le16_to_cpu(csa->channel)); | ||
1274 | } | 1296 | } |
1275 | EXPORT_SYMBOL(iwl_rx_csa); | 1297 | EXPORT_SYMBOL(iwl_rx_csa); |
1276 | 1298 | ||
@@ -1352,6 +1374,8 @@ void iwl_apm_stop(struct iwl_priv *priv) | |||
1352 | { | 1374 | { |
1353 | unsigned long flags; | 1375 | unsigned long flags; |
1354 | 1376 | ||
1377 | IWL_DEBUG_INFO(priv, "Stop card, put in low power state\n"); | ||
1378 | |||
1355 | iwl_apm_stop_master(priv); | 1379 | iwl_apm_stop_master(priv); |
1356 | 1380 | ||
1357 | spin_lock_irqsave(&priv->lock, flags); | 1381 | spin_lock_irqsave(&priv->lock, flags); |
@@ -1365,6 +1389,118 @@ void iwl_apm_stop(struct iwl_priv *priv) | |||
1365 | } | 1389 | } |
1366 | EXPORT_SYMBOL(iwl_apm_stop); | 1390 | EXPORT_SYMBOL(iwl_apm_stop); |
1367 | 1391 | ||
1392 | |||
1393 | /* | ||
1394 | * Start up NIC's basic functionality after it has been reset | ||
1395 | * (e.g. after platform boot, or shutdown via iwl_apm_stop()) | ||
1396 | * NOTE: This does not load uCode nor start the embedded processor | ||
1397 | */ | ||
1398 | int iwl_apm_init(struct iwl_priv *priv) | ||
1399 | { | ||
1400 | int ret = 0; | ||
1401 | u16 lctl; | ||
1402 | |||
1403 | IWL_DEBUG_INFO(priv, "Init card's basic functions\n"); | ||
1404 | |||
1405 | /* | ||
1406 | * Use "set_bit" below rather than "write", to preserve any hardware | ||
1407 | * bits already set by default after reset. | ||
1408 | */ | ||
1409 | |||
1410 | /* Disable L0S exit timer (platform NMI Work/Around) */ | ||
1411 | iwl_set_bit(priv, CSR_GIO_CHICKEN_BITS, | ||
1412 | CSR_GIO_CHICKEN_BITS_REG_BIT_DIS_L0S_EXIT_TIMER); | ||
1413 | |||
1414 | /* | ||
1415 | * Disable L0s without affecting L1; | ||
1416 | * don't wait for ICH L0s (ICH bug W/A) | ||
1417 | */ | ||
1418 | iwl_set_bit(priv, CSR_GIO_CHICKEN_BITS, | ||
1419 | CSR_GIO_CHICKEN_BITS_REG_BIT_L1A_NO_L0S_RX); | ||
1420 | |||
1421 | /* Set FH wait threshold to maximum (HW error during stress W/A) */ | ||
1422 | iwl_set_bit(priv, CSR_DBG_HPET_MEM_REG, CSR_DBG_HPET_MEM_REG_VAL); | ||
1423 | |||
1424 | /* | ||
1425 | * Enable HAP INTA (interrupt from management bus) to | ||
1426 | * wake device's PCI Express link L1a -> L0s | ||
1427 | * NOTE: This is no-op for 3945 (non-existant bit) | ||
1428 | */ | ||
1429 | iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG, | ||
1430 | CSR_HW_IF_CONFIG_REG_BIT_HAP_WAKE_L1A); | ||
1431 | |||
1432 | /* | ||
1433 | * HW bug W/A - costs negligible power consumption ... | ||
1434 | * Check if BIOS (or OS) enabled L1-ASPM on this device | ||
1435 | */ | ||
1436 | if (priv->cfg->set_l0s) { | ||
1437 | lctl = iwl_pcie_link_ctl(priv); | ||
1438 | if ((lctl & PCI_CFG_LINK_CTRL_VAL_L1_EN) == | ||
1439 | PCI_CFG_LINK_CTRL_VAL_L1_EN) { | ||
1440 | /* L1-ASPM enabled; disable(!) L0S */ | ||
1441 | iwl_set_bit(priv, CSR_GIO_REG, | ||
1442 | CSR_GIO_REG_VAL_L0S_ENABLED); | ||
1443 | IWL_DEBUG_POWER(priv, "L1 Enabled; Disabling L0S\n"); | ||
1444 | } else { | ||
1445 | /* L1-ASPM disabled; enable(!) L0S */ | ||
1446 | iwl_clear_bit(priv, CSR_GIO_REG, | ||
1447 | CSR_GIO_REG_VAL_L0S_ENABLED); | ||
1448 | IWL_DEBUG_POWER(priv, "L1 Disabled; Enabling L0S\n"); | ||
1449 | } | ||
1450 | } | ||
1451 | |||
1452 | /* Configure analog phase-lock-loop before activating to D0A */ | ||
1453 | if (priv->cfg->pll_cfg_val) | ||
1454 | iwl_set_bit(priv, CSR_ANA_PLL_CFG, priv->cfg->pll_cfg_val); | ||
1455 | |||
1456 | /* | ||
1457 | * Set "initialization complete" bit to move adapter from | ||
1458 | * D0U* --> D0A* (powered-up active) state. | ||
1459 | */ | ||
1460 | iwl_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE); | ||
1461 | |||
1462 | /* | ||
1463 | * Wait for clock stabilization; once stabilized, access to | ||
1464 | * device-internal resources is supported, e.g. iwl_write_prph() | ||
1465 | * and accesses to uCode SRAM. | ||
1466 | */ | ||
1467 | ret = iwl_poll_bit(priv, CSR_GP_CNTRL, | ||
1468 | CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, | ||
1469 | CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000); | ||
1470 | if (ret < 0) { | ||
1471 | IWL_DEBUG_INFO(priv, "Failed to init the card\n"); | ||
1472 | goto out; | ||
1473 | } | ||
1474 | |||
1475 | /* | ||
1476 | * Enable DMA and BSM (if used) clocks, wait for them to stabilize. | ||
1477 | * BSM (Boostrap State Machine) is only in 3945 and 4965; | ||
1478 | * later devices (i.e. 5000 and later) have non-volatile SRAM, | ||
1479 | * and don't need BSM to restore data after power-saving sleep. | ||
1480 | * | ||
1481 | * Write to "CLK_EN_REG"; "1" bits enable clocks, while "0" bits | ||
1482 | * do not disable clocks. This preserves any hardware bits already | ||
1483 | * set by default in "CLK_CTRL_REG" after reset. | ||
1484 | */ | ||
1485 | if (priv->cfg->use_bsm) | ||
1486 | iwl_write_prph(priv, APMG_CLK_EN_REG, | ||
1487 | APMG_CLK_VAL_DMA_CLK_RQT | APMG_CLK_VAL_BSM_CLK_RQT); | ||
1488 | else | ||
1489 | iwl_write_prph(priv, APMG_CLK_EN_REG, | ||
1490 | APMG_CLK_VAL_DMA_CLK_RQT); | ||
1491 | udelay(20); | ||
1492 | |||
1493 | /* Disable L1-Active */ | ||
1494 | iwl_set_bits_prph(priv, APMG_PCIDEV_STT_REG, | ||
1495 | APMG_PCIDEV_STT_VAL_L1_ACT_DIS); | ||
1496 | |||
1497 | out: | ||
1498 | return ret; | ||
1499 | } | ||
1500 | EXPORT_SYMBOL(iwl_apm_init); | ||
1501 | |||
1502 | |||
1503 | |||
1368 | void iwl_configure_filter(struct ieee80211_hw *hw, | 1504 | void iwl_configure_filter(struct ieee80211_hw *hw, |
1369 | unsigned int changed_flags, | 1505 | unsigned int changed_flags, |
1370 | unsigned int *total_flags, | 1506 | unsigned int *total_flags, |
@@ -1412,73 +1548,14 @@ void iwl_configure_filter(struct ieee80211_hw *hw, | |||
1412 | } | 1548 | } |
1413 | EXPORT_SYMBOL(iwl_configure_filter); | 1549 | EXPORT_SYMBOL(iwl_configure_filter); |
1414 | 1550 | ||
1415 | int iwl_setup_mac(struct iwl_priv *priv) | ||
1416 | { | ||
1417 | int ret; | ||
1418 | struct ieee80211_hw *hw = priv->hw; | ||
1419 | hw->rate_control_algorithm = "iwl-agn-rs"; | ||
1420 | |||
1421 | /* Tell mac80211 our characteristics */ | ||
1422 | hw->flags = IEEE80211_HW_SIGNAL_DBM | | ||
1423 | IEEE80211_HW_NOISE_DBM | | ||
1424 | IEEE80211_HW_AMPDU_AGGREGATION | | ||
1425 | IEEE80211_HW_SPECTRUM_MGMT; | ||
1426 | |||
1427 | if (!priv->cfg->broken_powersave) | ||
1428 | hw->flags |= IEEE80211_HW_SUPPORTS_PS | | ||
1429 | IEEE80211_HW_SUPPORTS_DYNAMIC_PS; | ||
1430 | |||
1431 | hw->wiphy->interface_modes = | ||
1432 | BIT(NL80211_IFTYPE_STATION) | | ||
1433 | BIT(NL80211_IFTYPE_ADHOC); | ||
1434 | |||
1435 | hw->wiphy->custom_regulatory = true; | ||
1436 | |||
1437 | /* Firmware does not support this */ | ||
1438 | hw->wiphy->disable_beacon_hints = true; | ||
1439 | |||
1440 | /* | ||
1441 | * For now, disable PS by default because it affects | ||
1442 | * RX performance significantly. | ||
1443 | */ | ||
1444 | hw->wiphy->ps_default = false; | ||
1445 | |||
1446 | hw->wiphy->max_scan_ssids = PROBE_OPTION_MAX; | ||
1447 | /* we create the 802.11 header and a zero-length SSID element */ | ||
1448 | hw->wiphy->max_scan_ie_len = IWL_MAX_PROBE_REQUEST - 24 - 2; | ||
1449 | |||
1450 | /* Default value; 4 EDCA QOS priorities */ | ||
1451 | hw->queues = 4; | ||
1452 | |||
1453 | hw->max_listen_interval = IWL_CONN_MAX_LISTEN_INTERVAL; | ||
1454 | |||
1455 | if (priv->bands[IEEE80211_BAND_2GHZ].n_channels) | ||
1456 | priv->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = | ||
1457 | &priv->bands[IEEE80211_BAND_2GHZ]; | ||
1458 | if (priv->bands[IEEE80211_BAND_5GHZ].n_channels) | ||
1459 | priv->hw->wiphy->bands[IEEE80211_BAND_5GHZ] = | ||
1460 | &priv->bands[IEEE80211_BAND_5GHZ]; | ||
1461 | |||
1462 | ret = ieee80211_register_hw(priv->hw); | ||
1463 | if (ret) { | ||
1464 | IWL_ERR(priv, "Failed to register hw (error %d)\n", ret); | ||
1465 | return ret; | ||
1466 | } | ||
1467 | priv->mac80211_registered = 1; | ||
1468 | |||
1469 | return 0; | ||
1470 | } | ||
1471 | EXPORT_SYMBOL(iwl_setup_mac); | ||
1472 | |||
1473 | int iwl_set_hw_params(struct iwl_priv *priv) | 1551 | int iwl_set_hw_params(struct iwl_priv *priv) |
1474 | { | 1552 | { |
1475 | priv->hw_params.max_rxq_size = RX_QUEUE_SIZE; | 1553 | priv->hw_params.max_rxq_size = RX_QUEUE_SIZE; |
1476 | priv->hw_params.max_rxq_log = RX_QUEUE_SIZE_LOG; | 1554 | priv->hw_params.max_rxq_log = RX_QUEUE_SIZE_LOG; |
1477 | if (priv->cfg->mod_params->amsdu_size_8K) | 1555 | if (priv->cfg->mod_params->amsdu_size_8K) |
1478 | priv->hw_params.rx_buf_size = IWL_RX_BUF_SIZE_8K; | 1556 | priv->hw_params.rx_page_order = get_order(IWL_RX_BUF_SIZE_8K); |
1479 | else | 1557 | else |
1480 | priv->hw_params.rx_buf_size = IWL_RX_BUF_SIZE_4K; | 1558 | priv->hw_params.rx_page_order = get_order(IWL_RX_BUF_SIZE_4K); |
1481 | priv->hw_params.max_pkt_size = priv->hw_params.rx_buf_size - 256; | ||
1482 | 1559 | ||
1483 | priv->hw_params.max_beacon_itrvl = IWL_MAX_UCODE_BEACON_INTERVAL; | 1560 | priv->hw_params.max_beacon_itrvl = IWL_MAX_UCODE_BEACON_INTERVAL; |
1484 | 1561 | ||
@@ -1507,7 +1584,6 @@ int iwl_init_drv(struct iwl_priv *priv) | |||
1507 | /* Clear the driver's (not device's) station table */ | 1584 | /* Clear the driver's (not device's) station table */ |
1508 | iwl_clear_stations_table(priv); | 1585 | iwl_clear_stations_table(priv); |
1509 | 1586 | ||
1510 | priv->data_retry_limit = -1; | ||
1511 | priv->ieee_channels = NULL; | 1587 | priv->ieee_channels = NULL; |
1512 | priv->ieee_rates = NULL; | 1588 | priv->ieee_rates = NULL; |
1513 | priv->band = IEEE80211_BAND_2GHZ; | 1589 | priv->band = IEEE80211_BAND_2GHZ; |
@@ -1932,9 +2008,9 @@ EXPORT_SYMBOL(iwl_isr_legacy); | |||
1932 | int iwl_send_bt_config(struct iwl_priv *priv) | 2008 | int iwl_send_bt_config(struct iwl_priv *priv) |
1933 | { | 2009 | { |
1934 | struct iwl_bt_cmd bt_cmd = { | 2010 | struct iwl_bt_cmd bt_cmd = { |
1935 | .flags = 3, | 2011 | .flags = BT_COEX_MODE_4W, |
1936 | .lead_time = 0xAA, | 2012 | .lead_time = BT_LEAD_TIME_DEF, |
1937 | .max_kill = 1, | 2013 | .max_kill = BT_MAX_KILL_DEF, |
1938 | .kill_ack_mask = 0, | 2014 | .kill_ack_mask = 0, |
1939 | .kill_cts_mask = 0, | 2015 | .kill_cts_mask = 0, |
1940 | }; | 2016 | }; |
@@ -2094,10 +2170,7 @@ void iwl_rf_kill_ct_config(struct iwl_priv *priv) | |||
2094 | spin_unlock_irqrestore(&priv->lock, flags); | 2170 | spin_unlock_irqrestore(&priv->lock, flags); |
2095 | priv->thermal_throttle.ct_kill_toggle = false; | 2171 | priv->thermal_throttle.ct_kill_toggle = false; |
2096 | 2172 | ||
2097 | switch (priv->hw_rev & CSR_HW_REV_TYPE_MSK) { | 2173 | if (priv->cfg->support_ct_kill_exit) { |
2098 | case CSR_HW_REV_TYPE_1000: | ||
2099 | case CSR_HW_REV_TYPE_6x00: | ||
2100 | case CSR_HW_REV_TYPE_6x50: | ||
2101 | adv_cmd.critical_temperature_enter = | 2174 | adv_cmd.critical_temperature_enter = |
2102 | cpu_to_le32(priv->hw_params.ct_kill_threshold); | 2175 | cpu_to_le32(priv->hw_params.ct_kill_threshold); |
2103 | adv_cmd.critical_temperature_exit = | 2176 | adv_cmd.critical_temperature_exit = |
@@ -2114,8 +2187,7 @@ void iwl_rf_kill_ct_config(struct iwl_priv *priv) | |||
2114 | "exit is %d\n", | 2187 | "exit is %d\n", |
2115 | priv->hw_params.ct_kill_threshold, | 2188 | priv->hw_params.ct_kill_threshold, |
2116 | priv->hw_params.ct_kill_exit_threshold); | 2189 | priv->hw_params.ct_kill_exit_threshold); |
2117 | break; | 2190 | } else { |
2118 | default: | ||
2119 | cmd.critical_temperature_R = | 2191 | cmd.critical_temperature_R = |
2120 | cpu_to_le32(priv->hw_params.ct_kill_threshold); | 2192 | cpu_to_le32(priv->hw_params.ct_kill_threshold); |
2121 | 2193 | ||
@@ -2128,7 +2200,6 @@ void iwl_rf_kill_ct_config(struct iwl_priv *priv) | |||
2128 | "succeeded, " | 2200 | "succeeded, " |
2129 | "critical temperature is %d\n", | 2201 | "critical temperature is %d\n", |
2130 | priv->hw_params.ct_kill_threshold); | 2202 | priv->hw_params.ct_kill_threshold); |
2131 | break; | ||
2132 | } | 2203 | } |
2133 | } | 2204 | } |
2134 | EXPORT_SYMBOL(iwl_rf_kill_ct_config); | 2205 | EXPORT_SYMBOL(iwl_rf_kill_ct_config); |
@@ -2160,7 +2231,7 @@ void iwl_rx_pm_sleep_notif(struct iwl_priv *priv, | |||
2160 | struct iwl_rx_mem_buffer *rxb) | 2231 | struct iwl_rx_mem_buffer *rxb) |
2161 | { | 2232 | { |
2162 | #ifdef CONFIG_IWLWIFI_DEBUG | 2233 | #ifdef CONFIG_IWLWIFI_DEBUG |
2163 | struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; | 2234 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
2164 | struct iwl_sleep_notification *sleep = &(pkt->u.sleep_notif); | 2235 | struct iwl_sleep_notification *sleep = &(pkt->u.sleep_notif); |
2165 | IWL_DEBUG_RX(priv, "sleep mode: %d, src: %d\n", | 2236 | IWL_DEBUG_RX(priv, "sleep mode: %d, src: %d\n", |
2166 | sleep->pm_sleep_mode, sleep->pm_wakeup_src); | 2237 | sleep->pm_sleep_mode, sleep->pm_wakeup_src); |
@@ -2171,7 +2242,7 @@ EXPORT_SYMBOL(iwl_rx_pm_sleep_notif); | |||
2171 | void iwl_rx_pm_debug_statistics_notif(struct iwl_priv *priv, | 2242 | void iwl_rx_pm_debug_statistics_notif(struct iwl_priv *priv, |
2172 | struct iwl_rx_mem_buffer *rxb) | 2243 | struct iwl_rx_mem_buffer *rxb) |
2173 | { | 2244 | { |
2174 | struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; | 2245 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
2175 | u32 len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK; | 2246 | u32 len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK; |
2176 | IWL_DEBUG_RADIO(priv, "Dumping %d bytes of unhandled " | 2247 | IWL_DEBUG_RADIO(priv, "Dumping %d bytes of unhandled " |
2177 | "notification for %s:\n", len, | 2248 | "notification for %s:\n", len, |
@@ -2183,7 +2254,7 @@ EXPORT_SYMBOL(iwl_rx_pm_debug_statistics_notif); | |||
2183 | void iwl_rx_reply_error(struct iwl_priv *priv, | 2254 | void iwl_rx_reply_error(struct iwl_priv *priv, |
2184 | struct iwl_rx_mem_buffer *rxb) | 2255 | struct iwl_rx_mem_buffer *rxb) |
2185 | { | 2256 | { |
2186 | struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; | 2257 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
2187 | 2258 | ||
2188 | IWL_ERR(priv, "Error Reply type 0x%08X cmd %s (0x%02X) " | 2259 | IWL_ERR(priv, "Error Reply type 0x%08X cmd %s (0x%02X) " |
2189 | "seq 0x%04X ser 0x%08X\n", | 2260 | "seq 0x%04X ser 0x%08X\n", |
@@ -2648,6 +2719,14 @@ int iwl_mac_config(struct ieee80211_hw *hw, u32 changed) | |||
2648 | goto set_ch_out; | 2719 | goto set_ch_out; |
2649 | } | 2720 | } |
2650 | 2721 | ||
2722 | if (iwl_is_associated(priv) && | ||
2723 | (le16_to_cpu(priv->active_rxon.channel) != ch) && | ||
2724 | priv->cfg->ops->lib->set_channel_switch) { | ||
2725 | ret = priv->cfg->ops->lib->set_channel_switch(priv, | ||
2726 | ch); | ||
2727 | goto out; | ||
2728 | } | ||
2729 | |||
2651 | spin_lock_irqsave(&priv->lock, flags); | 2730 | spin_lock_irqsave(&priv->lock, flags); |
2652 | 2731 | ||
2653 | /* Configure HT40 channels */ | 2732 | /* Configure HT40 channels */ |
@@ -2826,6 +2905,27 @@ void iwl_mac_reset_tsf(struct ieee80211_hw *hw) | |||
2826 | } | 2905 | } |
2827 | EXPORT_SYMBOL(iwl_mac_reset_tsf); | 2906 | EXPORT_SYMBOL(iwl_mac_reset_tsf); |
2828 | 2907 | ||
2908 | int iwl_alloc_txq_mem(struct iwl_priv *priv) | ||
2909 | { | ||
2910 | if (!priv->txq) | ||
2911 | priv->txq = kzalloc( | ||
2912 | sizeof(struct iwl_tx_queue) * priv->cfg->num_of_queues, | ||
2913 | GFP_KERNEL); | ||
2914 | if (!priv->txq) { | ||
2915 | IWL_ERR(priv, "Not enough memory for txq \n"); | ||
2916 | return -ENOMEM; | ||
2917 | } | ||
2918 | return 0; | ||
2919 | } | ||
2920 | EXPORT_SYMBOL(iwl_alloc_txq_mem); | ||
2921 | |||
2922 | void iwl_free_txq_mem(struct iwl_priv *priv) | ||
2923 | { | ||
2924 | kfree(priv->txq); | ||
2925 | priv->txq = NULL; | ||
2926 | } | ||
2927 | EXPORT_SYMBOL(iwl_free_txq_mem); | ||
2928 | |||
2829 | #ifdef CONFIG_IWLWIFI_DEBUGFS | 2929 | #ifdef CONFIG_IWLWIFI_DEBUGFS |
2830 | 2930 | ||
2831 | #define IWL_TRAFFIC_DUMP_SIZE (IWL_TRAFFIC_ENTRY_SIZE * IWL_TRAFFIC_ENTRIES) | 2931 | #define IWL_TRAFFIC_DUMP_SIZE (IWL_TRAFFIC_ENTRY_SIZE * IWL_TRAFFIC_ENTRIES) |
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 6688b6944200..b875dcfca2d6 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h | |||
@@ -109,7 +109,6 @@ struct iwl_hcmd_utils_ops { | |||
109 | 109 | ||
110 | struct iwl_apm_ops { | 110 | struct iwl_apm_ops { |
111 | int (*init)(struct iwl_priv *priv); | 111 | int (*init)(struct iwl_priv *priv); |
112 | int (*reset)(struct iwl_priv *priv); | ||
113 | void (*stop)(struct iwl_priv *priv); | 112 | void (*stop)(struct iwl_priv *priv); |
114 | void (*config)(struct iwl_priv *priv); | 113 | void (*config)(struct iwl_priv *priv); |
115 | int (*set_pwr_src)(struct iwl_priv *priv, enum iwl_pwr_src src); | 114 | int (*set_pwr_src)(struct iwl_priv *priv, enum iwl_pwr_src src); |
@@ -170,6 +169,7 @@ struct iwl_lib_ops { | |||
170 | int (*load_ucode)(struct iwl_priv *priv); | 169 | int (*load_ucode)(struct iwl_priv *priv); |
171 | void (*dump_nic_event_log)(struct iwl_priv *priv); | 170 | void (*dump_nic_event_log)(struct iwl_priv *priv); |
172 | void (*dump_nic_error_log)(struct iwl_priv *priv); | 171 | void (*dump_nic_error_log)(struct iwl_priv *priv); |
172 | int (*set_channel_switch)(struct iwl_priv *priv, u16 channel); | ||
173 | /* power management */ | 173 | /* power management */ |
174 | struct iwl_apm_ops apm_ops; | 174 | struct iwl_apm_ops apm_ops; |
175 | 175 | ||
@@ -205,7 +205,6 @@ struct iwl_mod_params { | |||
205 | int sw_crypto; /* def: 0 = using hardware encryption */ | 205 | int sw_crypto; /* def: 0 = using hardware encryption */ |
206 | int disable_hw_scan; /* def: 0 = use h/w scan */ | 206 | int disable_hw_scan; /* def: 0 = use h/w scan */ |
207 | int num_of_queues; /* def: HW dependent */ | 207 | int num_of_queues; /* def: HW dependent */ |
208 | int num_of_ampdu_queues;/* def: HW dependent */ | ||
209 | int disable_11n; /* def: 0 = 11n capabilities enabled */ | 208 | int disable_11n; /* def: 0 = 11n capabilities enabled */ |
210 | int amsdu_size_8K; /* def: 1 = enable 8K amsdu size */ | 209 | int amsdu_size_8K; /* def: 1 = enable 8K amsdu size */ |
211 | int antenna; /* def: 0 = both antennas (use diversity) */ | 210 | int antenna; /* def: 0 = both antennas (use diversity) */ |
@@ -227,6 +226,8 @@ struct iwl_mod_params { | |||
227 | * The detail algorithm is described in iwl-led.c | 226 | * The detail algorithm is described in iwl-led.c |
228 | * @use_rts_for_ht: use rts/cts protection for HT traffic | 227 | * @use_rts_for_ht: use rts/cts protection for HT traffic |
229 | * @chain_noise_num_beacons: number of beacons used to compute chain noise | 228 | * @chain_noise_num_beacons: number of beacons used to compute chain noise |
229 | * @adv_thermal_throttle: support advance thermal throttle | ||
230 | * @support_ct_kill_exit: support ct kill exit condition | ||
230 | * | 231 | * |
231 | * We enable the driver to be backward compatible wrt API version. The | 232 | * We enable the driver to be backward compatible wrt API version. The |
232 | * driver specifies which APIs it supports (with @ucode_api_max being the | 233 | * driver specifies which APIs it supports (with @ucode_api_max being the |
@@ -258,11 +259,18 @@ struct iwl_cfg { | |||
258 | int eeprom_size; | 259 | int eeprom_size; |
259 | u16 eeprom_ver; | 260 | u16 eeprom_ver; |
260 | u16 eeprom_calib_ver; | 261 | u16 eeprom_calib_ver; |
262 | int num_of_queues; /* def: HW dependent */ | ||
263 | int num_of_ampdu_queues;/* def: HW dependent */ | ||
261 | const struct iwl_ops *ops; | 264 | const struct iwl_ops *ops; |
262 | const struct iwl_mod_params *mod_params; | 265 | const struct iwl_mod_params *mod_params; |
263 | u8 valid_tx_ant; | 266 | u8 valid_tx_ant; |
264 | u8 valid_rx_ant; | 267 | u8 valid_rx_ant; |
265 | bool need_pll_cfg; | 268 | |
269 | /* for iwl_apm_init() */ | ||
270 | u32 pll_cfg_val; | ||
271 | bool set_l0s; | ||
272 | bool use_bsm; | ||
273 | |||
266 | bool use_isr_legacy; | 274 | bool use_isr_legacy; |
267 | enum iwl_pa_type pa_type; | 275 | enum iwl_pa_type pa_type; |
268 | const u16 max_ll_items; | 276 | const u16 max_ll_items; |
@@ -273,6 +281,8 @@ struct iwl_cfg { | |||
273 | bool use_rts_for_ht; | 281 | bool use_rts_for_ht; |
274 | int chain_noise_num_beacons; | 282 | int chain_noise_num_beacons; |
275 | const bool supports_idle; | 283 | const bool supports_idle; |
284 | bool adv_thermal_throttle; | ||
285 | bool support_ct_kill_exit; | ||
276 | }; | 286 | }; |
277 | 287 | ||
278 | /*************************** | 288 | /*************************** |
@@ -305,7 +315,6 @@ void iwl_configure_filter(struct ieee80211_hw *hw, | |||
305 | unsigned int changed_flags, | 315 | unsigned int changed_flags, |
306 | unsigned int *total_flags, u64 multicast); | 316 | unsigned int *total_flags, u64 multicast); |
307 | int iwl_hw_nic_init(struct iwl_priv *priv); | 317 | int iwl_hw_nic_init(struct iwl_priv *priv); |
308 | int iwl_setup_mac(struct iwl_priv *priv); | ||
309 | int iwl_set_hw_params(struct iwl_priv *priv); | 318 | int iwl_set_hw_params(struct iwl_priv *priv); |
310 | int iwl_init_drv(struct iwl_priv *priv); | 319 | int iwl_init_drv(struct iwl_priv *priv); |
311 | void iwl_uninit_drv(struct iwl_priv *priv); | 320 | void iwl_uninit_drv(struct iwl_priv *priv); |
@@ -327,6 +336,10 @@ void iwl_config_ap(struct iwl_priv *priv); | |||
327 | int iwl_mac_get_tx_stats(struct ieee80211_hw *hw, | 336 | int iwl_mac_get_tx_stats(struct ieee80211_hw *hw, |
328 | struct ieee80211_tx_queue_stats *stats); | 337 | struct ieee80211_tx_queue_stats *stats); |
329 | void iwl_mac_reset_tsf(struct ieee80211_hw *hw); | 338 | void iwl_mac_reset_tsf(struct ieee80211_hw *hw); |
339 | int iwl_alloc_txq_mem(struct iwl_priv *priv); | ||
340 | void iwl_free_txq_mem(struct iwl_priv *priv); | ||
341 | void iwlcore_rts_tx_cmd_flag(struct ieee80211_tx_info *info, | ||
342 | __le32 *tx_flags); | ||
330 | #ifdef CONFIG_IWLWIFI_DEBUGFS | 343 | #ifdef CONFIG_IWLWIFI_DEBUGFS |
331 | int iwl_alloc_traffic_mem(struct iwl_priv *priv); | 344 | int iwl_alloc_traffic_mem(struct iwl_priv *priv); |
332 | void iwl_free_traffic_mem(struct iwl_priv *priv); | 345 | void iwl_free_traffic_mem(struct iwl_priv *priv); |
@@ -527,7 +540,7 @@ int iwl_send_cmd_pdu_async(struct iwl_priv *priv, u8 id, u16 len, | |||
527 | const void *data, | 540 | const void *data, |
528 | void (*callback)(struct iwl_priv *priv, | 541 | void (*callback)(struct iwl_priv *priv, |
529 | struct iwl_device_cmd *cmd, | 542 | struct iwl_device_cmd *cmd, |
530 | struct sk_buff *skb)); | 543 | struct iwl_rx_packet *pkt)); |
531 | 544 | ||
532 | int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd); | 545 | int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd); |
533 | 546 | ||
@@ -660,6 +673,7 @@ void iwl_rx_reply_compressed_ba(struct iwl_priv *priv, | |||
660 | struct iwl_rx_mem_buffer *rxb); | 673 | struct iwl_rx_mem_buffer *rxb); |
661 | void iwl_apm_stop(struct iwl_priv *priv); | 674 | void iwl_apm_stop(struct iwl_priv *priv); |
662 | int iwl_apm_stop_master(struct iwl_priv *priv); | 675 | int iwl_apm_stop_master(struct iwl_priv *priv); |
676 | int iwl_apm_init(struct iwl_priv *priv); | ||
663 | 677 | ||
664 | void iwl_setup_rxon_timing(struct iwl_priv *priv); | 678 | void iwl_setup_rxon_timing(struct iwl_priv *priv); |
665 | static inline int iwl_send_rxon_assoc(struct iwl_priv *priv) | 679 | static inline int iwl_send_rxon_assoc(struct iwl_priv *priv) |
diff --git a/drivers/net/wireless/iwlwifi/iwl-csr.h b/drivers/net/wireless/iwlwifi/iwl-csr.h index 8f183e0fa512..b6ed5a3147a1 100644 --- a/drivers/net/wireless/iwlwifi/iwl-csr.h +++ b/drivers/net/wireless/iwlwifi/iwl-csr.h | |||
@@ -109,8 +109,9 @@ | |||
109 | * Bit fields: | 109 | * Bit fields: |
110 | * 3-2: 0 = A, 1 = B, 2 = C, 3 = D step | 110 | * 3-2: 0 = A, 1 = B, 2 = C, 3 = D step |
111 | */ | 111 | */ |
112 | #define CSR_HW_REV_WA_REG (CSR_BASE+0x22C) | 112 | #define CSR_HW_REV_WA_REG (CSR_BASE+0x22C) |
113 | #define CSR_DBG_HPET_MEM_REG (CSR_BASE+0x240) | 113 | #define CSR_DBG_HPET_MEM_REG (CSR_BASE+0x240) |
114 | #define CSR_DBG_LINK_PWR_MGMT_REG (CSR_BASE+0x250) | ||
114 | 115 | ||
115 | /* Bits for CSR_HW_IF_CONFIG_REG */ | 116 | /* Bits for CSR_HW_IF_CONFIG_REG */ |
116 | #define CSR49_HW_IF_CONFIG_REG_BIT_4965_R (0x00000010) | 117 | #define CSR49_HW_IF_CONFIG_REG_BIT_4965_R (0x00000010) |
@@ -195,6 +196,7 @@ | |||
195 | #define CSR_RESET_REG_FLAG_SW_RESET (0x00000080) | 196 | #define CSR_RESET_REG_FLAG_SW_RESET (0x00000080) |
196 | #define CSR_RESET_REG_FLAG_MASTER_DISABLED (0x00000100) | 197 | #define CSR_RESET_REG_FLAG_MASTER_DISABLED (0x00000100) |
197 | #define CSR_RESET_REG_FLAG_STOP_MASTER (0x00000200) | 198 | #define CSR_RESET_REG_FLAG_STOP_MASTER (0x00000200) |
199 | #define CSR_RESET_LINK_PWR_MGMT_DISABLED (0x80000000) | ||
198 | 200 | ||
199 | /* GP (general purpose) CONTROL */ | 201 | /* GP (general purpose) CONTROL */ |
200 | #define CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY (0x00000001) | 202 | #define CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY (0x00000001) |
@@ -235,6 +237,11 @@ | |||
235 | #define CSR_OTP_GP_REG_OTP_ACCESS_MODE (0x00020000) /* 0 - absolute, 1 - relative */ | 237 | #define CSR_OTP_GP_REG_OTP_ACCESS_MODE (0x00020000) /* 0 - absolute, 1 - relative */ |
236 | #define CSR_OTP_GP_REG_ECC_CORR_STATUS_MSK (0x00100000) /* bit 20 */ | 238 | #define CSR_OTP_GP_REG_ECC_CORR_STATUS_MSK (0x00100000) /* bit 20 */ |
237 | #define CSR_OTP_GP_REG_ECC_UNCORR_STATUS_MSK (0x00200000) /* bit 21 */ | 239 | #define CSR_OTP_GP_REG_ECC_UNCORR_STATUS_MSK (0x00200000) /* bit 21 */ |
240 | #define CSR_GP_REG_POWER_SAVE_STATUS_MSK (0x03000000) /* bit 24/25 */ | ||
241 | #define CSR_GP_REG_NO_POWER_SAVE (0x00000000) | ||
242 | #define CSR_GP_REG_MAC_POWER_SAVE (0x01000000) | ||
243 | #define CSR_GP_REG_PHY_POWER_SAVE (0x02000000) | ||
244 | #define CSR_GP_REG_POWER_SAVE_ERROR (0x03000000) | ||
238 | 245 | ||
239 | /* EEPROM signature */ | 246 | /* EEPROM signature */ |
240 | #define CSR_EEPROM_GP_BAD_SIGNATURE_BOTH_EEP_AND_OTP (0x00000000) | 247 | #define CSR_EEPROM_GP_BAD_SIGNATURE_BOTH_EEP_AND_OTP (0x00000000) |
diff --git a/drivers/net/wireless/iwlwifi/iwl-debug.h b/drivers/net/wireless/iwlwifi/iwl-debug.h index b9ca475cc61c..96c92eab692a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debug.h +++ b/drivers/net/wireless/iwlwifi/iwl-debug.h | |||
@@ -106,6 +106,7 @@ struct iwl_debugfs { | |||
106 | struct dentry *file_sensitivity; | 106 | struct dentry *file_sensitivity; |
107 | struct dentry *file_chain_noise; | 107 | struct dentry *file_chain_noise; |
108 | struct dentry *file_tx_power; | 108 | struct dentry *file_tx_power; |
109 | struct dentry *file_power_save_status; | ||
109 | } dbgfs_debug_files; | 110 | } dbgfs_debug_files; |
110 | u32 sram_offset; | 111 | u32 sram_offset; |
111 | u32 sram_len; | 112 | u32 sram_len; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c index 1794b9c4e6ac..8784911fd56e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c +++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c | |||
@@ -801,15 +801,20 @@ static ssize_t iwl_dbgfs_sleep_level_override_write(struct file *file, | |||
801 | * valid here. However, let's not confuse them and present | 801 | * valid here. However, let's not confuse them and present |
802 | * IWL_POWER_INDEX_1 as "1", not "0". | 802 | * IWL_POWER_INDEX_1 as "1", not "0". |
803 | */ | 803 | */ |
804 | if (value > 0) | 804 | if (value == 0) |
805 | return -EINVAL; | ||
806 | else if (value > 0) | ||
805 | value -= 1; | 807 | value -= 1; |
806 | 808 | ||
807 | if (value != -1 && (value < 0 || value >= IWL_POWER_NUM)) | 809 | if (value != -1 && (value < 0 || value >= IWL_POWER_NUM)) |
808 | return -EINVAL; | 810 | return -EINVAL; |
809 | 811 | ||
812 | if (!iwl_is_ready_rf(priv)) | ||
813 | return -EAGAIN; | ||
814 | |||
810 | priv->power_data.debug_sleep_level_override = value; | 815 | priv->power_data.debug_sleep_level_override = value; |
811 | 816 | ||
812 | iwl_power_update_mode(priv, false); | 817 | iwl_power_update_mode(priv, true); |
813 | 818 | ||
814 | return count; | 819 | return count; |
815 | } | 820 | } |
@@ -882,10 +887,14 @@ static ssize_t iwl_dbgfs_traffic_log_read(struct file *file, | |||
882 | struct iwl_rx_queue *rxq = &priv->rxq; | 887 | struct iwl_rx_queue *rxq = &priv->rxq; |
883 | char *buf; | 888 | char *buf; |
884 | int bufsz = ((IWL_TRAFFIC_ENTRIES * IWL_TRAFFIC_ENTRY_SIZE * 64) * 2) + | 889 | int bufsz = ((IWL_TRAFFIC_ENTRIES * IWL_TRAFFIC_ENTRY_SIZE * 64) * 2) + |
885 | (IWL_MAX_NUM_QUEUES * 32 * 8) + 400; | 890 | (priv->cfg->num_of_queues * 32 * 8) + 400; |
886 | const u8 *ptr; | 891 | const u8 *ptr; |
887 | ssize_t ret; | 892 | ssize_t ret; |
888 | 893 | ||
894 | if (!priv->txq) { | ||
895 | IWL_ERR(priv, "txq not ready\n"); | ||
896 | return -EAGAIN; | ||
897 | } | ||
889 | buf = kzalloc(bufsz, GFP_KERNEL); | 898 | buf = kzalloc(bufsz, GFP_KERNEL); |
890 | if (!buf) { | 899 | if (!buf) { |
891 | IWL_ERR(priv, "Can not allocate buffer\n"); | 900 | IWL_ERR(priv, "Can not allocate buffer\n"); |
@@ -977,8 +986,12 @@ static ssize_t iwl_dbgfs_tx_queue_read(struct file *file, | |||
977 | int pos = 0; | 986 | int pos = 0; |
978 | int cnt; | 987 | int cnt; |
979 | int ret; | 988 | int ret; |
980 | const size_t bufsz = sizeof(char) * 60 * IWL_MAX_NUM_QUEUES; | 989 | const size_t bufsz = sizeof(char) * 60 * priv->cfg->num_of_queues; |
981 | 990 | ||
991 | if (!priv->txq) { | ||
992 | IWL_ERR(priv, "txq not ready\n"); | ||
993 | return -EAGAIN; | ||
994 | } | ||
982 | buf = kzalloc(bufsz, GFP_KERNEL); | 995 | buf = kzalloc(bufsz, GFP_KERNEL); |
983 | if (!buf) | 996 | if (!buf) |
984 | return -ENOMEM; | 997 | return -ENOMEM; |
@@ -1069,10 +1082,10 @@ static ssize_t iwl_dbgfs_ucode_rx_stats_read(struct file *file, | |||
1069 | sizeof(struct statistics_rx_non_phy) * 20 + | 1082 | sizeof(struct statistics_rx_non_phy) * 20 + |
1070 | sizeof(struct statistics_rx_ht_phy) * 20 + 400; | 1083 | sizeof(struct statistics_rx_ht_phy) * 20 + 400; |
1071 | ssize_t ret; | 1084 | ssize_t ret; |
1072 | struct statistics_rx_phy *ofdm; | 1085 | struct statistics_rx_phy *ofdm, *accum_ofdm; |
1073 | struct statistics_rx_phy *cck; | 1086 | struct statistics_rx_phy *cck, *accum_cck; |
1074 | struct statistics_rx_non_phy *general; | 1087 | struct statistics_rx_non_phy *general, *accum_general; |
1075 | struct statistics_rx_ht_phy *ht; | 1088 | struct statistics_rx_ht_phy *ht, *accum_ht; |
1076 | 1089 | ||
1077 | if (!iwl_is_alive(priv)) | 1090 | if (!iwl_is_alive(priv)) |
1078 | return -EAGAIN; | 1091 | return -EAGAIN; |
@@ -1101,155 +1114,268 @@ static ssize_t iwl_dbgfs_ucode_rx_stats_read(struct file *file, | |||
1101 | cck = &priv->statistics.rx.cck; | 1114 | cck = &priv->statistics.rx.cck; |
1102 | general = &priv->statistics.rx.general; | 1115 | general = &priv->statistics.rx.general; |
1103 | ht = &priv->statistics.rx.ofdm_ht; | 1116 | ht = &priv->statistics.rx.ofdm_ht; |
1117 | accum_ofdm = &priv->accum_statistics.rx.ofdm; | ||
1118 | accum_cck = &priv->accum_statistics.rx.cck; | ||
1119 | accum_general = &priv->accum_statistics.rx.general; | ||
1120 | accum_ht = &priv->accum_statistics.rx.ofdm_ht; | ||
1104 | pos += iwl_dbgfs_statistics_flag(priv, buf, bufsz); | 1121 | pos += iwl_dbgfs_statistics_flag(priv, buf, bufsz); |
1105 | pos += scnprintf(buf + pos, bufsz - pos, "Statistics_Rx - OFDM:\n"); | 1122 | pos += scnprintf(buf + pos, bufsz - pos, "Statistics_Rx - OFDM:\n"); |
1106 | pos += scnprintf(buf + pos, bufsz - pos, "ina_cnt: %u\n", | 1123 | pos += scnprintf(buf + pos, bufsz - pos, |
1107 | le32_to_cpu(ofdm->ina_cnt)); | 1124 | "\t\t\tcurrent\t\t\taccumulative\n"); |
1108 | pos += scnprintf(buf + pos, bufsz - pos, "fina_cnt: %u\n", | 1125 | pos += scnprintf(buf + pos, bufsz - pos, "ina_cnt:\t\t%u\t\t\t%u\n", |
1109 | le32_to_cpu(ofdm->fina_cnt)); | 1126 | le32_to_cpu(ofdm->ina_cnt), accum_ofdm->ina_cnt); |
1110 | pos += scnprintf(buf + pos, bufsz - pos, "plcp_err: %u\n", | 1127 | pos += scnprintf(buf + pos, bufsz - pos, "fina_cnt:\t\t%u\t\t\t%u\n", |
1111 | le32_to_cpu(ofdm->plcp_err)); | 1128 | le32_to_cpu(ofdm->fina_cnt), accum_ofdm->fina_cnt); |
1112 | pos += scnprintf(buf + pos, bufsz - pos, "crc32_err: %u\n", | 1129 | pos += scnprintf(buf + pos, bufsz - pos, "plcp_err:\t\t%u\t\t\t%u\n", |
1113 | le32_to_cpu(ofdm->crc32_err)); | 1130 | le32_to_cpu(ofdm->plcp_err), accum_ofdm->plcp_err); |
1114 | pos += scnprintf(buf + pos, bufsz - pos, "overrun_err: %u\n", | 1131 | pos += scnprintf(buf + pos, bufsz - pos, "crc32_err:\t\t%u\t\t\t%u\n", |
1115 | le32_to_cpu(ofdm->overrun_err)); | 1132 | le32_to_cpu(ofdm->crc32_err), accum_ofdm->crc32_err); |
1116 | pos += scnprintf(buf + pos, bufsz - pos, "early_overrun_err: %u\n", | 1133 | pos += scnprintf(buf + pos, bufsz - pos, |
1117 | le32_to_cpu(ofdm->early_overrun_err)); | 1134 | "overrun_err:\t\t%u\t\t\t%u\n", |
1118 | pos += scnprintf(buf + pos, bufsz - pos, "crc32_good: %u\n", | 1135 | le32_to_cpu(ofdm->overrun_err), |
1119 | le32_to_cpu(ofdm->crc32_good)); | 1136 | accum_ofdm->overrun_err); |
1120 | pos += scnprintf(buf + pos, bufsz - pos, "false_alarm_cnt: %u\n", | 1137 | pos += scnprintf(buf + pos, bufsz - pos, |
1121 | le32_to_cpu(ofdm->false_alarm_cnt)); | 1138 | "early_overrun_err:\t%u\t\t\t%u\n", |
1122 | pos += scnprintf(buf + pos, bufsz - pos, "fina_sync_err_cnt: %u\n", | 1139 | le32_to_cpu(ofdm->early_overrun_err), |
1123 | le32_to_cpu(ofdm->fina_sync_err_cnt)); | 1140 | accum_ofdm->early_overrun_err); |
1124 | pos += scnprintf(buf + pos, bufsz - pos, "sfd_timeout: %u\n", | 1141 | pos += scnprintf(buf + pos, bufsz - pos, "crc32_good:\t\t%u\t\t\t%u\n", |
1125 | le32_to_cpu(ofdm->sfd_timeout)); | 1142 | le32_to_cpu(ofdm->crc32_good), |
1126 | pos += scnprintf(buf + pos, bufsz - pos, "fina_timeout: %u\n", | 1143 | accum_ofdm->crc32_good); |
1127 | le32_to_cpu(ofdm->fina_timeout)); | 1144 | pos += scnprintf(buf + pos, bufsz - pos, |
1128 | pos += scnprintf(buf + pos, bufsz - pos, "unresponded_rts: %u\n", | 1145 | "false_alarm_cnt:\t%u\t\t\t%u\n", |
1129 | le32_to_cpu(ofdm->unresponded_rts)); | 1146 | le32_to_cpu(ofdm->false_alarm_cnt), |
1130 | pos += scnprintf(buf + pos, bufsz - pos, | 1147 | accum_ofdm->false_alarm_cnt); |
1131 | "rxe_frame_limit_overrun: %u\n", | 1148 | pos += scnprintf(buf + pos, bufsz - pos, |
1132 | le32_to_cpu(ofdm->rxe_frame_limit_overrun)); | 1149 | "fina_sync_err_cnt:\t%u\t\t\t%u\n", |
1133 | pos += scnprintf(buf + pos, bufsz - pos, "sent_ack_cnt: %u\n", | 1150 | le32_to_cpu(ofdm->fina_sync_err_cnt), |
1134 | le32_to_cpu(ofdm->sent_ack_cnt)); | 1151 | accum_ofdm->fina_sync_err_cnt); |
1135 | pos += scnprintf(buf + pos, bufsz - pos, "sent_cts_cnt: %u\n", | 1152 | pos += scnprintf(buf + pos, bufsz - pos, |
1136 | le32_to_cpu(ofdm->sent_cts_cnt)); | 1153 | "sfd_timeout:\t\t%u\t\t\t%u\n", |
1137 | pos += scnprintf(buf + pos, bufsz - pos, "sent_ba_rsp_cnt: %u\n", | 1154 | le32_to_cpu(ofdm->sfd_timeout), |
1138 | le32_to_cpu(ofdm->sent_ba_rsp_cnt)); | 1155 | accum_ofdm->sfd_timeout); |
1139 | pos += scnprintf(buf + pos, bufsz - pos, "dsp_self_kill: %u\n", | 1156 | pos += scnprintf(buf + pos, bufsz - pos, |
1140 | le32_to_cpu(ofdm->dsp_self_kill)); | 1157 | "fina_timeout:\t\t%u\t\t\t%u\n", |
1141 | pos += scnprintf(buf + pos, bufsz - pos, "mh_format_err: %u\n", | 1158 | le32_to_cpu(ofdm->fina_timeout), |
1142 | le32_to_cpu(ofdm->mh_format_err)); | 1159 | accum_ofdm->fina_timeout); |
1143 | pos += scnprintf(buf + pos, bufsz - pos, "re_acq_main_rssi_sum: %u\n", | 1160 | pos += scnprintf(buf + pos, bufsz - pos, |
1144 | le32_to_cpu(ofdm->re_acq_main_rssi_sum)); | 1161 | "unresponded_rts:\t%u\t\t\t%u\n", |
1162 | le32_to_cpu(ofdm->unresponded_rts), | ||
1163 | accum_ofdm->unresponded_rts); | ||
1164 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1165 | "rxe_frame_lmt_ovrun:\t%u\t\t\t%u\n", | ||
1166 | le32_to_cpu(ofdm->rxe_frame_limit_overrun), | ||
1167 | accum_ofdm->rxe_frame_limit_overrun); | ||
1168 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1169 | "sent_ack_cnt:\t\t%u\t\t\t%u\n", | ||
1170 | le32_to_cpu(ofdm->sent_ack_cnt), | ||
1171 | accum_ofdm->sent_ack_cnt); | ||
1172 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1173 | "sent_cts_cnt:\t\t%u\t\t\t%u\n", | ||
1174 | le32_to_cpu(ofdm->sent_cts_cnt), | ||
1175 | accum_ofdm->sent_cts_cnt); | ||
1176 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1177 | "sent_ba_rsp_cnt:\t%u\t\t\t%u\n", | ||
1178 | le32_to_cpu(ofdm->sent_ba_rsp_cnt), | ||
1179 | accum_ofdm->sent_ba_rsp_cnt); | ||
1180 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1181 | "dsp_self_kill:\t\t%u\t\t\t%u\n", | ||
1182 | le32_to_cpu(ofdm->dsp_self_kill), | ||
1183 | accum_ofdm->dsp_self_kill); | ||
1184 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1185 | "mh_format_err:\t\t%u\t\t\t%u\n", | ||
1186 | le32_to_cpu(ofdm->mh_format_err), | ||
1187 | accum_ofdm->mh_format_err); | ||
1188 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1189 | "re_acq_main_rssi_sum:\t%u\t\t\t%u\n", | ||
1190 | le32_to_cpu(ofdm->re_acq_main_rssi_sum), | ||
1191 | accum_ofdm->re_acq_main_rssi_sum); | ||
1145 | 1192 | ||
1146 | pos += scnprintf(buf + pos, bufsz - pos, "Statistics_Rx - CCK:\n"); | 1193 | pos += scnprintf(buf + pos, bufsz - pos, "Statistics_Rx - CCK:\n"); |
1147 | pos += scnprintf(buf + pos, bufsz - pos, "ina_cnt: %u\n", | 1194 | pos += scnprintf(buf + pos, bufsz - pos, |
1148 | le32_to_cpu(cck->ina_cnt)); | 1195 | "\t\t\tcurrent\t\t\taccumulative\n"); |
1149 | pos += scnprintf(buf + pos, bufsz - pos, "fina_cnt: %u\n", | 1196 | pos += scnprintf(buf + pos, bufsz - pos, "ina_cnt:\t\t%u\t\t\t%u\n", |
1150 | le32_to_cpu(cck->fina_cnt)); | 1197 | le32_to_cpu(cck->ina_cnt), accum_cck->ina_cnt); |
1151 | pos += scnprintf(buf + pos, bufsz - pos, "plcp_err: %u\n", | 1198 | pos += scnprintf(buf + pos, bufsz - pos, "fina_cnt:\t\t%u\t\t\t%u\n", |
1152 | le32_to_cpu(cck->plcp_err)); | 1199 | le32_to_cpu(cck->fina_cnt), accum_cck->fina_cnt); |
1153 | pos += scnprintf(buf + pos, bufsz - pos, "crc32_err: %u\n", | 1200 | pos += scnprintf(buf + pos, bufsz - pos, "plcp_err:\t\t%u\t\t\t%u\n", |
1154 | le32_to_cpu(cck->crc32_err)); | 1201 | le32_to_cpu(cck->plcp_err), accum_cck->plcp_err); |
1155 | pos += scnprintf(buf + pos, bufsz - pos, "overrun_err: %u\n", | 1202 | pos += scnprintf(buf + pos, bufsz - pos, "crc32_err:\t\t%u\t\t\t%u\n", |
1156 | le32_to_cpu(cck->overrun_err)); | 1203 | le32_to_cpu(cck->crc32_err), accum_cck->crc32_err); |
1157 | pos += scnprintf(buf + pos, bufsz - pos, "early_overrun_err: %u\n", | 1204 | pos += scnprintf(buf + pos, bufsz - pos, |
1158 | le32_to_cpu(cck->early_overrun_err)); | 1205 | "overrun_err:\t\t%u\t\t\t%u\n", |
1159 | pos += scnprintf(buf + pos, bufsz - pos, "crc32_good: %u\n", | 1206 | le32_to_cpu(cck->overrun_err), |
1160 | le32_to_cpu(cck->crc32_good)); | 1207 | accum_cck->overrun_err); |
1161 | pos += scnprintf(buf + pos, bufsz - pos, "false_alarm_cnt: %u\n", | 1208 | pos += scnprintf(buf + pos, bufsz - pos, |
1162 | le32_to_cpu(cck->false_alarm_cnt)); | 1209 | "early_overrun_err:\t%u\t\t\t%u\n", |
1163 | pos += scnprintf(buf + pos, bufsz - pos, "fina_sync_err_cnt: %u\n", | 1210 | le32_to_cpu(cck->early_overrun_err), |
1164 | le32_to_cpu(cck->fina_sync_err_cnt)); | 1211 | accum_cck->early_overrun_err); |
1165 | pos += scnprintf(buf + pos, bufsz - pos, "sfd_timeout: %u\n", | 1212 | pos += scnprintf(buf + pos, bufsz - pos, "crc32_good:\t\t%u\t\t\t%u\n", |
1166 | le32_to_cpu(cck->sfd_timeout)); | 1213 | le32_to_cpu(cck->crc32_good), accum_cck->crc32_good); |
1167 | pos += scnprintf(buf + pos, bufsz - pos, "fina_timeout: %u\n", | 1214 | pos += scnprintf(buf + pos, bufsz - pos, |
1168 | le32_to_cpu(cck->fina_timeout)); | 1215 | "false_alarm_cnt:\t%u\t\t\t%u\n", |
1169 | pos += scnprintf(buf + pos, bufsz - pos, "unresponded_rts: %u\n", | 1216 | le32_to_cpu(cck->false_alarm_cnt), |
1170 | le32_to_cpu(cck->unresponded_rts)); | 1217 | accum_cck->false_alarm_cnt); |
1171 | pos += scnprintf(buf + pos, bufsz - pos, | 1218 | pos += scnprintf(buf + pos, bufsz - pos, |
1172 | "rxe_frame_limit_overrun: %u\n", | 1219 | "fina_sync_err_cnt:\t%u\t\t\t%u\n", |
1173 | le32_to_cpu(cck->rxe_frame_limit_overrun)); | 1220 | le32_to_cpu(cck->fina_sync_err_cnt), |
1174 | pos += scnprintf(buf + pos, bufsz - pos, "sent_ack_cnt: %u\n", | 1221 | accum_cck->fina_sync_err_cnt); |
1175 | le32_to_cpu(cck->sent_ack_cnt)); | 1222 | pos += scnprintf(buf + pos, bufsz - pos, |
1176 | pos += scnprintf(buf + pos, bufsz - pos, "sent_cts_cnt: %u\n", | 1223 | "sfd_timeout:\t\t%u\t\t\t%u\n", |
1177 | le32_to_cpu(cck->sent_cts_cnt)); | 1224 | le32_to_cpu(cck->sfd_timeout), |
1178 | pos += scnprintf(buf + pos, bufsz - pos, "sent_ba_rsp_cnt: %u\n", | 1225 | accum_cck->sfd_timeout); |
1179 | le32_to_cpu(cck->sent_ba_rsp_cnt)); | 1226 | pos += scnprintf(buf + pos, bufsz - pos, |
1180 | pos += scnprintf(buf + pos, bufsz - pos, "dsp_self_kill: %u\n", | 1227 | "fina_timeout:\t\t%u\t\t\t%u\n", |
1181 | le32_to_cpu(cck->dsp_self_kill)); | 1228 | le32_to_cpu(cck->fina_timeout), |
1182 | pos += scnprintf(buf + pos, bufsz - pos, "mh_format_err: %u\n", | 1229 | accum_cck->fina_timeout); |
1183 | le32_to_cpu(cck->mh_format_err)); | 1230 | pos += scnprintf(buf + pos, bufsz - pos, |
1184 | pos += scnprintf(buf + pos, bufsz - pos, "re_acq_main_rssi_sum: %u\n", | 1231 | "unresponded_rts:\t%u\t\t\t%u\n", |
1185 | le32_to_cpu(cck->re_acq_main_rssi_sum)); | 1232 | le32_to_cpu(cck->unresponded_rts), |
1233 | accum_cck->unresponded_rts); | ||
1234 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1235 | "rxe_frame_lmt_ovrun:\t%u\t\t\t%u\n", | ||
1236 | le32_to_cpu(cck->rxe_frame_limit_overrun), | ||
1237 | accum_cck->rxe_frame_limit_overrun); | ||
1238 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1239 | "sent_ack_cnt:\t\t%u\t\t\t%u\n", | ||
1240 | le32_to_cpu(cck->sent_ack_cnt), | ||
1241 | accum_cck->sent_ack_cnt); | ||
1242 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1243 | "sent_cts_cnt:\t\t%u\t\t\t%u\n", | ||
1244 | le32_to_cpu(cck->sent_cts_cnt), | ||
1245 | accum_cck->sent_cts_cnt); | ||
1246 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1247 | "sent_ba_rsp_cnt:\t%u\t\t\t%u\n", | ||
1248 | le32_to_cpu(cck->sent_ba_rsp_cnt), | ||
1249 | accum_cck->sent_ba_rsp_cnt); | ||
1250 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1251 | "dsp_self_kill:\t\t%u\t\t\t%u\n", | ||
1252 | le32_to_cpu(cck->dsp_self_kill), | ||
1253 | accum_cck->dsp_self_kill); | ||
1254 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1255 | "mh_format_err:\t\t%u\t\t\t%u\n", | ||
1256 | le32_to_cpu(cck->mh_format_err), | ||
1257 | accum_cck->mh_format_err); | ||
1258 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1259 | "re_acq_main_rssi_sum:\t%u\t\t\t%u\n", | ||
1260 | le32_to_cpu(cck->re_acq_main_rssi_sum), | ||
1261 | accum_cck->re_acq_main_rssi_sum); | ||
1186 | 1262 | ||
1187 | pos += scnprintf(buf + pos, bufsz - pos, "Statistics_Rx - GENERAL:\n"); | 1263 | pos += scnprintf(buf + pos, bufsz - pos, "Statistics_Rx - GENERAL:\n"); |
1188 | pos += scnprintf(buf + pos, bufsz - pos, "bogus_cts: %u\n", | 1264 | pos += scnprintf(buf + pos, bufsz - pos, |
1189 | le32_to_cpu(general->bogus_cts)); | 1265 | "\t\t\tcurrent\t\t\taccumulative\n"); |
1190 | pos += scnprintf(buf + pos, bufsz - pos, "bogus_ack: %u\n", | 1266 | pos += scnprintf(buf + pos, bufsz - pos, "bogus_cts:\t\t%u\t\t\t%u\n", |
1191 | le32_to_cpu(general->bogus_ack)); | 1267 | le32_to_cpu(general->bogus_cts), |
1192 | pos += scnprintf(buf + pos, bufsz - pos, "non_bssid_frames: %u\n", | 1268 | accum_general->bogus_cts); |
1193 | le32_to_cpu(general->non_bssid_frames)); | 1269 | pos += scnprintf(buf + pos, bufsz - pos, "bogus_ack:\t\t%u\t\t\t%u\n", |
1194 | pos += scnprintf(buf + pos, bufsz - pos, "filtered_frames: %u\n", | 1270 | le32_to_cpu(general->bogus_ack), |
1195 | le32_to_cpu(general->filtered_frames)); | 1271 | accum_general->bogus_ack); |
1196 | pos += scnprintf(buf + pos, bufsz - pos, "non_channel_beacons: %u\n", | 1272 | pos += scnprintf(buf + pos, bufsz - pos, |
1197 | le32_to_cpu(general->non_channel_beacons)); | 1273 | "non_bssid_frames:\t%u\t\t\t%u\n", |
1198 | pos += scnprintf(buf + pos, bufsz - pos, "channel_beacons: %u\n", | 1274 | le32_to_cpu(general->non_bssid_frames), |
1199 | le32_to_cpu(general->channel_beacons)); | 1275 | accum_general->non_bssid_frames); |
1200 | pos += scnprintf(buf + pos, bufsz - pos, "num_missed_bcon: %u\n", | 1276 | pos += scnprintf(buf + pos, bufsz - pos, |
1201 | le32_to_cpu(general->num_missed_bcon)); | 1277 | "filtered_frames:\t%u\t\t\t%u\n", |
1202 | pos += scnprintf(buf + pos, bufsz - pos, | 1278 | le32_to_cpu(general->filtered_frames), |
1203 | "adc_rx_saturation_time: %u\n", | 1279 | accum_general->filtered_frames); |
1204 | le32_to_cpu(general->adc_rx_saturation_time)); | 1280 | pos += scnprintf(buf + pos, bufsz - pos, |
1205 | pos += scnprintf(buf + pos, bufsz - pos, | 1281 | "non_channel_beacons:\t%u\t\t\t%u\n", |
1206 | "ina_detection_search_time: %u\n", | 1282 | le32_to_cpu(general->non_channel_beacons), |
1207 | le32_to_cpu(general->ina_detection_search_time)); | 1283 | accum_general->non_channel_beacons); |
1208 | pos += scnprintf(buf + pos, bufsz - pos, "beacon_silence_rssi_a: %u\n", | 1284 | pos += scnprintf(buf + pos, bufsz - pos, |
1209 | le32_to_cpu(general->beacon_silence_rssi_a)); | 1285 | "channel_beacons:\t%u\t\t\t%u\n", |
1210 | pos += scnprintf(buf + pos, bufsz - pos, "beacon_silence_rssi_b: %u\n", | 1286 | le32_to_cpu(general->channel_beacons), |
1211 | le32_to_cpu(general->beacon_silence_rssi_b)); | 1287 | accum_general->channel_beacons); |
1212 | pos += scnprintf(buf + pos, bufsz - pos, "beacon_silence_rssi_c: %u\n", | 1288 | pos += scnprintf(buf + pos, bufsz - pos, |
1213 | le32_to_cpu(general->beacon_silence_rssi_c)); | 1289 | "num_missed_bcon:\t%u\t\t\t%u\n", |
1214 | pos += scnprintf(buf + pos, bufsz - pos, | 1290 | le32_to_cpu(general->num_missed_bcon), |
1215 | "interference_data_flag: %u\n", | 1291 | accum_general->num_missed_bcon); |
1216 | le32_to_cpu(general->interference_data_flag)); | 1292 | pos += scnprintf(buf + pos, bufsz - pos, |
1217 | pos += scnprintf(buf + pos, bufsz - pos, "channel_load: %u\n", | 1293 | "adc_rx_saturation_time:\t%u\t\t\t%u\n", |
1218 | le32_to_cpu(general->channel_load)); | 1294 | le32_to_cpu(general->adc_rx_saturation_time), |
1219 | pos += scnprintf(buf + pos, bufsz - pos, "dsp_false_alarms: %u\n", | 1295 | accum_general->adc_rx_saturation_time); |
1220 | le32_to_cpu(general->dsp_false_alarms)); | 1296 | pos += scnprintf(buf + pos, bufsz - pos, |
1221 | pos += scnprintf(buf + pos, bufsz - pos, "beacon_rssi_a: %u\n", | 1297 | "ina_detect_search_tm:\t%u\t\t\t%u\n", |
1222 | le32_to_cpu(general->beacon_rssi_a)); | 1298 | le32_to_cpu(general->ina_detection_search_time), |
1223 | pos += scnprintf(buf + pos, bufsz - pos, "beacon_rssi_b: %u\n", | 1299 | accum_general->ina_detection_search_time); |
1224 | le32_to_cpu(general->beacon_rssi_b)); | 1300 | pos += scnprintf(buf + pos, bufsz - pos, |
1225 | pos += scnprintf(buf + pos, bufsz - pos, "beacon_rssi_c: %u\n", | 1301 | "beacon_silence_rssi_a:\t%u\t\t\t%u\n", |
1226 | le32_to_cpu(general->beacon_rssi_c)); | 1302 | le32_to_cpu(general->beacon_silence_rssi_a), |
1227 | pos += scnprintf(buf + pos, bufsz - pos, "beacon_energy_a: %u\n", | 1303 | accum_general->beacon_silence_rssi_a); |
1228 | le32_to_cpu(general->beacon_energy_a)); | 1304 | pos += scnprintf(buf + pos, bufsz - pos, |
1229 | pos += scnprintf(buf + pos, bufsz - pos, "beacon_energy_b: %u\n", | 1305 | "beacon_silence_rssi_b:\t%u\t\t\t%u\n", |
1230 | le32_to_cpu(general->beacon_energy_b)); | 1306 | le32_to_cpu(general->beacon_silence_rssi_b), |
1231 | pos += scnprintf(buf + pos, bufsz - pos, "beacon_energy_c: %u\n", | 1307 | accum_general->beacon_silence_rssi_b); |
1232 | le32_to_cpu(general->beacon_energy_c)); | 1308 | pos += scnprintf(buf + pos, bufsz - pos, |
1309 | "beacon_silence_rssi_c:\t%u\t\t\t%u\n", | ||
1310 | le32_to_cpu(general->beacon_silence_rssi_c), | ||
1311 | accum_general->beacon_silence_rssi_c); | ||
1312 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1313 | "interference_data_flag:\t%u\t\t\t%u\n", | ||
1314 | le32_to_cpu(general->interference_data_flag), | ||
1315 | accum_general->interference_data_flag); | ||
1316 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1317 | "channel_load:\t\t%u\t\t\t%u\n", | ||
1318 | le32_to_cpu(general->channel_load), | ||
1319 | accum_general->channel_load); | ||
1320 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1321 | "dsp_false_alarms:\t%u\t\t\t%u\n", | ||
1322 | le32_to_cpu(general->dsp_false_alarms), | ||
1323 | accum_general->dsp_false_alarms); | ||
1324 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1325 | "beacon_rssi_a:\t\t%u\t\t\t%u\n", | ||
1326 | le32_to_cpu(general->beacon_rssi_a), | ||
1327 | accum_general->beacon_rssi_a); | ||
1328 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1329 | "beacon_rssi_b:\t\t%u\t\t\t%u\n", | ||
1330 | le32_to_cpu(general->beacon_rssi_b), | ||
1331 | accum_general->beacon_rssi_b); | ||
1332 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1333 | "beacon_rssi_c:\t\t%u\t\t\t%u\n", | ||
1334 | le32_to_cpu(general->beacon_rssi_c), | ||
1335 | accum_general->beacon_rssi_c); | ||
1336 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1337 | "beacon_energy_a:\t%u\t\t\t%u\n", | ||
1338 | le32_to_cpu(general->beacon_energy_a), | ||
1339 | accum_general->beacon_energy_a); | ||
1340 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1341 | "beacon_energy_b:\t%u\t\t\t%u\n", | ||
1342 | le32_to_cpu(general->beacon_energy_b), | ||
1343 | accum_general->beacon_energy_b); | ||
1344 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1345 | "beacon_energy_c:\t%u\t\t\t%u\n", | ||
1346 | le32_to_cpu(general->beacon_energy_c), | ||
1347 | accum_general->beacon_energy_c); | ||
1233 | 1348 | ||
1234 | pos += scnprintf(buf + pos, bufsz - pos, "Statistics_Rx - OFDM_HT:\n"); | 1349 | pos += scnprintf(buf + pos, bufsz - pos, "Statistics_Rx - OFDM_HT:\n"); |
1235 | pos += scnprintf(buf + pos, bufsz - pos, "plcp_err: %u\n", | 1350 | pos += scnprintf(buf + pos, bufsz - pos, |
1236 | le32_to_cpu(ht->plcp_err)); | 1351 | "\t\t\tcurrent\t\t\taccumulative\n"); |
1237 | pos += scnprintf(buf + pos, bufsz - pos, "overrun_err: %u\n", | 1352 | pos += scnprintf(buf + pos, bufsz - pos, "plcp_err:\t\t%u\t\t\t%u\n", |
1238 | le32_to_cpu(ht->overrun_err)); | 1353 | le32_to_cpu(ht->plcp_err), accum_ht->plcp_err); |
1239 | pos += scnprintf(buf + pos, bufsz - pos, "early_overrun_err: %u\n", | 1354 | pos += scnprintf(buf + pos, bufsz - pos, |
1240 | le32_to_cpu(ht->early_overrun_err)); | 1355 | "overrun_err:\t\t%u\t\t\t%u\n", |
1241 | pos += scnprintf(buf + pos, bufsz - pos, "crc32_good: %u\n", | 1356 | le32_to_cpu(ht->overrun_err), accum_ht->overrun_err); |
1242 | le32_to_cpu(ht->crc32_good)); | 1357 | pos += scnprintf(buf + pos, bufsz - pos, |
1243 | pos += scnprintf(buf + pos, bufsz - pos, "crc32_err: %u\n", | 1358 | "early_overrun_err:\t%u\t\t\t%u\n", |
1244 | le32_to_cpu(ht->crc32_err)); | 1359 | le32_to_cpu(ht->early_overrun_err), |
1245 | pos += scnprintf(buf + pos, bufsz - pos, "mh_format_err: %u\n", | 1360 | accum_ht->early_overrun_err); |
1246 | le32_to_cpu(ht->mh_format_err)); | 1361 | pos += scnprintf(buf + pos, bufsz - pos, "crc32_good:\t\t%u\t\t\t%u\n", |
1247 | pos += scnprintf(buf + pos, bufsz - pos, "agg_crc32_good: %u\n", | 1362 | le32_to_cpu(ht->crc32_good), accum_ht->crc32_good); |
1248 | le32_to_cpu(ht->agg_crc32_good)); | 1363 | pos += scnprintf(buf + pos, bufsz - pos, "crc32_err:\t\t%u\t\t\t%u\n", |
1249 | pos += scnprintf(buf + pos, bufsz - pos, "agg_mpdu_cnt: %u\n", | 1364 | le32_to_cpu(ht->crc32_err), accum_ht->crc32_err); |
1250 | le32_to_cpu(ht->agg_mpdu_cnt)); | 1365 | pos += scnprintf(buf + pos, bufsz - pos, |
1251 | pos += scnprintf(buf + pos, bufsz - pos, "agg_cnt: %u\n", | 1366 | "mh_format_err:\t\t%u\t\t\t%u\n", |
1252 | le32_to_cpu(ht->agg_cnt)); | 1367 | le32_to_cpu(ht->mh_format_err), |
1368 | accum_ht->mh_format_err); | ||
1369 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1370 | "agg_crc32_good:\t\t%u\t\t\t%u\n", | ||
1371 | le32_to_cpu(ht->agg_crc32_good), | ||
1372 | accum_ht->agg_crc32_good); | ||
1373 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1374 | "agg_mpdu_cnt:\t\t%u\t\t\t%u\n", | ||
1375 | le32_to_cpu(ht->agg_mpdu_cnt), | ||
1376 | accum_ht->agg_mpdu_cnt); | ||
1377 | pos += scnprintf(buf + pos, bufsz - pos, "agg_cnt:\t\t%u\t\t\t%u\n", | ||
1378 | le32_to_cpu(ht->agg_cnt), accum_ht->agg_cnt); | ||
1253 | 1379 | ||
1254 | ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); | 1380 | ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); |
1255 | kfree(buf); | 1381 | kfree(buf); |
@@ -1265,7 +1391,7 @@ static ssize_t iwl_dbgfs_ucode_tx_stats_read(struct file *file, | |||
1265 | char *buf; | 1391 | char *buf; |
1266 | int bufsz = (sizeof(struct statistics_tx) * 24) + 250; | 1392 | int bufsz = (sizeof(struct statistics_tx) * 24) + 250; |
1267 | ssize_t ret; | 1393 | ssize_t ret; |
1268 | struct statistics_tx *tx; | 1394 | struct statistics_tx *tx, *accum_tx; |
1269 | 1395 | ||
1270 | if (!iwl_is_alive(priv)) | 1396 | if (!iwl_is_alive(priv)) |
1271 | return -EAGAIN; | 1397 | return -EAGAIN; |
@@ -1291,62 +1417,107 @@ static ssize_t iwl_dbgfs_ucode_tx_stats_read(struct file *file, | |||
1291 | * might not reflect the current uCode activity | 1417 | * might not reflect the current uCode activity |
1292 | */ | 1418 | */ |
1293 | tx = &priv->statistics.tx; | 1419 | tx = &priv->statistics.tx; |
1420 | accum_tx = &priv->accum_statistics.tx; | ||
1294 | pos += iwl_dbgfs_statistics_flag(priv, buf, bufsz); | 1421 | pos += iwl_dbgfs_statistics_flag(priv, buf, bufsz); |
1295 | pos += scnprintf(buf + pos, bufsz - pos, "Statistics_Tx:\n"); | 1422 | pos += scnprintf(buf + pos, bufsz - pos, "Statistics_Tx:\n"); |
1296 | pos += scnprintf(buf + pos, bufsz - pos, "preamble: %u\n", | 1423 | pos += scnprintf(buf + pos, bufsz - pos, |
1297 | le32_to_cpu(tx->preamble_cnt)); | 1424 | "\t\t\tcurrent\t\t\taccumulative\n"); |
1298 | pos += scnprintf(buf + pos, bufsz - pos, "rx_detected_cnt: %u\n", | 1425 | pos += scnprintf(buf + pos, bufsz - pos, "preamble:\t\t\t%u\t\t\t%u\n", |
1299 | le32_to_cpu(tx->rx_detected_cnt)); | 1426 | le32_to_cpu(tx->preamble_cnt), |
1300 | pos += scnprintf(buf + pos, bufsz - pos, "bt_prio_defer_cnt: %u\n", | 1427 | accum_tx->preamble_cnt); |
1301 | le32_to_cpu(tx->bt_prio_defer_cnt)); | 1428 | pos += scnprintf(buf + pos, bufsz - pos, |
1302 | pos += scnprintf(buf + pos, bufsz - pos, "bt_prio_kill_cnt: %u\n", | 1429 | "rx_detected_cnt:\t\t%u\t\t\t%u\n", |
1303 | le32_to_cpu(tx->bt_prio_kill_cnt)); | 1430 | le32_to_cpu(tx->rx_detected_cnt), |
1304 | pos += scnprintf(buf + pos, bufsz - pos, "few_bytes_cnt: %u\n", | 1431 | accum_tx->rx_detected_cnt); |
1305 | le32_to_cpu(tx->few_bytes_cnt)); | 1432 | pos += scnprintf(buf + pos, bufsz - pos, |
1306 | pos += scnprintf(buf + pos, bufsz - pos, "cts_timeout: %u\n", | 1433 | "bt_prio_defer_cnt:\t\t%u\t\t\t%u\n", |
1307 | le32_to_cpu(tx->cts_timeout)); | 1434 | le32_to_cpu(tx->bt_prio_defer_cnt), |
1308 | pos += scnprintf(buf + pos, bufsz - pos, "ack_timeout: %u\n", | 1435 | accum_tx->bt_prio_defer_cnt); |
1309 | le32_to_cpu(tx->ack_timeout)); | 1436 | pos += scnprintf(buf + pos, bufsz - pos, |
1310 | pos += scnprintf(buf + pos, bufsz - pos, "expected_ack_cnt: %u\n", | 1437 | "bt_prio_kill_cnt:\t\t%u\t\t\t%u\n", |
1311 | le32_to_cpu(tx->expected_ack_cnt)); | 1438 | le32_to_cpu(tx->bt_prio_kill_cnt), |
1312 | pos += scnprintf(buf + pos, bufsz - pos, "actual_ack_cnt: %u\n", | 1439 | accum_tx->bt_prio_kill_cnt); |
1313 | le32_to_cpu(tx->actual_ack_cnt)); | 1440 | pos += scnprintf(buf + pos, bufsz - pos, |
1314 | pos += scnprintf(buf + pos, bufsz - pos, "dump_msdu_cnt: %u\n", | 1441 | "few_bytes_cnt:\t\t\t%u\t\t\t%u\n", |
1315 | le32_to_cpu(tx->dump_msdu_cnt)); | 1442 | le32_to_cpu(tx->few_bytes_cnt), |
1316 | pos += scnprintf(buf + pos, bufsz - pos, | 1443 | accum_tx->few_bytes_cnt); |
1317 | "burst_abort_next_frame_mismatch_cnt: %u\n", | 1444 | pos += scnprintf(buf + pos, bufsz - pos, |
1318 | le32_to_cpu(tx->burst_abort_next_frame_mismatch_cnt)); | 1445 | "cts_timeout:\t\t\t%u\t\t\t%u\n", |
1319 | pos += scnprintf(buf + pos, bufsz - pos, | 1446 | le32_to_cpu(tx->cts_timeout), accum_tx->cts_timeout); |
1320 | "burst_abort_missing_next_frame_cnt: %u\n", | 1447 | pos += scnprintf(buf + pos, bufsz - pos, |
1321 | le32_to_cpu(tx->burst_abort_missing_next_frame_cnt)); | 1448 | "ack_timeout:\t\t\t%u\t\t\t%u\n", |
1322 | pos += scnprintf(buf + pos, bufsz - pos, "cts_timeout_collision: %u\n", | 1449 | le32_to_cpu(tx->ack_timeout), |
1323 | le32_to_cpu(tx->cts_timeout_collision)); | 1450 | accum_tx->ack_timeout); |
1324 | pos += scnprintf(buf + pos, bufsz - pos, | 1451 | pos += scnprintf(buf + pos, bufsz - pos, |
1325 | "ack_or_ba_timeout_collision: %u\n", | 1452 | "expected_ack_cnt:\t\t%u\t\t\t%u\n", |
1326 | le32_to_cpu(tx->ack_or_ba_timeout_collision)); | 1453 | le32_to_cpu(tx->expected_ack_cnt), |
1327 | pos += scnprintf(buf + pos, bufsz - pos, "agg ba_timeout: %u\n", | 1454 | accum_tx->expected_ack_cnt); |
1328 | le32_to_cpu(tx->agg.ba_timeout)); | 1455 | pos += scnprintf(buf + pos, bufsz - pos, |
1329 | pos += scnprintf(buf + pos, bufsz - pos, | 1456 | "actual_ack_cnt:\t\t\t%u\t\t\t%u\n", |
1330 | "agg ba_reschedule_frames: %u\n", | 1457 | le32_to_cpu(tx->actual_ack_cnt), |
1331 | le32_to_cpu(tx->agg.ba_reschedule_frames)); | 1458 | accum_tx->actual_ack_cnt); |
1332 | pos += scnprintf(buf + pos, bufsz - pos, | 1459 | pos += scnprintf(buf + pos, bufsz - pos, |
1333 | "agg scd_query_agg_frame_cnt: %u\n", | 1460 | "dump_msdu_cnt:\t\t\t%u\t\t\t%u\n", |
1334 | le32_to_cpu(tx->agg.scd_query_agg_frame_cnt)); | 1461 | le32_to_cpu(tx->dump_msdu_cnt), |
1335 | pos += scnprintf(buf + pos, bufsz - pos, "agg scd_query_no_agg: %u\n", | 1462 | accum_tx->dump_msdu_cnt); |
1336 | le32_to_cpu(tx->agg.scd_query_no_agg)); | 1463 | pos += scnprintf(buf + pos, bufsz - pos, |
1337 | pos += scnprintf(buf + pos, bufsz - pos, "agg scd_query_agg: %u\n", | 1464 | "abort_nxt_frame_mismatch:" |
1338 | le32_to_cpu(tx->agg.scd_query_agg)); | 1465 | "\t%u\t\t\t%u\n", |
1339 | pos += scnprintf(buf + pos, bufsz - pos, | 1466 | le32_to_cpu(tx->burst_abort_next_frame_mismatch_cnt), |
1340 | "agg scd_query_mismatch: %u\n", | 1467 | accum_tx->burst_abort_next_frame_mismatch_cnt); |
1341 | le32_to_cpu(tx->agg.scd_query_mismatch)); | 1468 | pos += scnprintf(buf + pos, bufsz - pos, |
1342 | pos += scnprintf(buf + pos, bufsz - pos, "agg frame_not_ready: %u\n", | 1469 | "abort_missing_nxt_frame:" |
1343 | le32_to_cpu(tx->agg.frame_not_ready)); | 1470 | "\t%u\t\t\t%u\n", |
1344 | pos += scnprintf(buf + pos, bufsz - pos, "agg underrun: %u\n", | 1471 | le32_to_cpu(tx->burst_abort_missing_next_frame_cnt), |
1345 | le32_to_cpu(tx->agg.underrun)); | 1472 | accum_tx->burst_abort_missing_next_frame_cnt); |
1346 | pos += scnprintf(buf + pos, bufsz - pos, "agg bt_prio_kill: %u\n", | 1473 | pos += scnprintf(buf + pos, bufsz - pos, |
1347 | le32_to_cpu(tx->agg.bt_prio_kill)); | 1474 | "cts_timeout_collision:\t\t%u\t\t\t%u\n", |
1348 | pos += scnprintf(buf + pos, bufsz - pos, "agg rx_ba_rsp_cnt: %u\n", | 1475 | le32_to_cpu(tx->cts_timeout_collision), |
1349 | le32_to_cpu(tx->agg.rx_ba_rsp_cnt)); | 1476 | accum_tx->cts_timeout_collision); |
1477 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1478 | "ack_ba_timeout_collision:\t%u\t\t\t%u\n", | ||
1479 | le32_to_cpu(tx->ack_or_ba_timeout_collision), | ||
1480 | accum_tx->ack_or_ba_timeout_collision); | ||
1481 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1482 | "agg ba_timeout:\t\t\t%u\t\t\t%u\n", | ||
1483 | le32_to_cpu(tx->agg.ba_timeout), | ||
1484 | accum_tx->agg.ba_timeout); | ||
1485 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1486 | "agg ba_resched_frames:\t\t%u\t\t\t%u\n", | ||
1487 | le32_to_cpu(tx->agg.ba_reschedule_frames), | ||
1488 | accum_tx->agg.ba_reschedule_frames); | ||
1489 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1490 | "agg scd_query_agg_frame:\t%u\t\t\t%u\n", | ||
1491 | le32_to_cpu(tx->agg.scd_query_agg_frame_cnt), | ||
1492 | accum_tx->agg.scd_query_agg_frame_cnt); | ||
1493 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1494 | "agg scd_query_no_agg:\t\t%u\t\t\t%u\n", | ||
1495 | le32_to_cpu(tx->agg.scd_query_no_agg), | ||
1496 | accum_tx->agg.scd_query_no_agg); | ||
1497 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1498 | "agg scd_query_agg:\t\t%u\t\t\t%u\n", | ||
1499 | le32_to_cpu(tx->agg.scd_query_agg), | ||
1500 | accum_tx->agg.scd_query_agg); | ||
1501 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1502 | "agg scd_query_mismatch:\t\t%u\t\t\t%u\n", | ||
1503 | le32_to_cpu(tx->agg.scd_query_mismatch), | ||
1504 | accum_tx->agg.scd_query_mismatch); | ||
1505 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1506 | "agg frame_not_ready:\t\t%u\t\t\t%u\n", | ||
1507 | le32_to_cpu(tx->agg.frame_not_ready), | ||
1508 | accum_tx->agg.frame_not_ready); | ||
1509 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1510 | "agg underrun:\t\t\t%u\t\t\t%u\n", | ||
1511 | le32_to_cpu(tx->agg.underrun), | ||
1512 | accum_tx->agg.underrun); | ||
1513 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1514 | "agg bt_prio_kill:\t\t%u\t\t\t%u\n", | ||
1515 | le32_to_cpu(tx->agg.bt_prio_kill), | ||
1516 | accum_tx->agg.bt_prio_kill); | ||
1517 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1518 | "agg rx_ba_rsp_cnt:\t\t%u\t\t\t%u\n", | ||
1519 | le32_to_cpu(tx->agg.rx_ba_rsp_cnt), | ||
1520 | accum_tx->agg.rx_ba_rsp_cnt); | ||
1350 | 1521 | ||
1351 | ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); | 1522 | ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); |
1352 | kfree(buf); | 1523 | kfree(buf); |
@@ -1362,9 +1533,9 @@ static ssize_t iwl_dbgfs_ucode_general_stats_read(struct file *file, | |||
1362 | char *buf; | 1533 | char *buf; |
1363 | int bufsz = sizeof(struct statistics_general) * 4 + 250; | 1534 | int bufsz = sizeof(struct statistics_general) * 4 + 250; |
1364 | ssize_t ret; | 1535 | ssize_t ret; |
1365 | struct statistics_general *general; | 1536 | struct statistics_general *general, *accum_general; |
1366 | struct statistics_dbg *dbg; | 1537 | struct statistics_dbg *dbg, *accum_dbg; |
1367 | struct statistics_div *div; | 1538 | struct statistics_div *div, *accum_div; |
1368 | 1539 | ||
1369 | if (!iwl_is_alive(priv)) | 1540 | if (!iwl_is_alive(priv)) |
1370 | return -EAGAIN; | 1541 | return -EAGAIN; |
@@ -1392,34 +1563,53 @@ static ssize_t iwl_dbgfs_ucode_general_stats_read(struct file *file, | |||
1392 | general = &priv->statistics.general; | 1563 | general = &priv->statistics.general; |
1393 | dbg = &priv->statistics.general.dbg; | 1564 | dbg = &priv->statistics.general.dbg; |
1394 | div = &priv->statistics.general.div; | 1565 | div = &priv->statistics.general.div; |
1566 | accum_general = &priv->accum_statistics.general; | ||
1567 | accum_dbg = &priv->accum_statistics.general.dbg; | ||
1568 | accum_div = &priv->accum_statistics.general.div; | ||
1395 | pos += iwl_dbgfs_statistics_flag(priv, buf, bufsz); | 1569 | pos += iwl_dbgfs_statistics_flag(priv, buf, bufsz); |
1396 | pos += scnprintf(buf + pos, bufsz - pos, "Statistics_General:\n"); | 1570 | pos += scnprintf(buf + pos, bufsz - pos, "Statistics_General:\n"); |
1397 | pos += scnprintf(buf + pos, bufsz - pos, "temperature: %u\n", | 1571 | pos += scnprintf(buf + pos, bufsz - pos, |
1572 | "\t\t\tcurrent\t\t\taccumulative\n"); | ||
1573 | pos += scnprintf(buf + pos, bufsz - pos, "temperature:\t\t\t%u\n", | ||
1398 | le32_to_cpu(general->temperature)); | 1574 | le32_to_cpu(general->temperature)); |
1399 | pos += scnprintf(buf + pos, bufsz - pos, "temperature_m: %u\n", | 1575 | pos += scnprintf(buf + pos, bufsz - pos, "temperature_m:\t\t\t%u\n", |
1400 | le32_to_cpu(general->temperature_m)); | 1576 | le32_to_cpu(general->temperature_m)); |
1401 | pos += scnprintf(buf + pos, bufsz - pos, "burst_check: %u\n", | 1577 | pos += scnprintf(buf + pos, bufsz - pos, |
1402 | le32_to_cpu(dbg->burst_check)); | 1578 | "burst_check:\t\t\t%u\t\t\t%u\n", |
1403 | pos += scnprintf(buf + pos, bufsz - pos, "burst_count: %u\n", | 1579 | le32_to_cpu(dbg->burst_check), |
1404 | le32_to_cpu(dbg->burst_count)); | 1580 | accum_dbg->burst_check); |
1405 | pos += scnprintf(buf + pos, bufsz - pos, "sleep_time: %u\n", | 1581 | pos += scnprintf(buf + pos, bufsz - pos, |
1406 | le32_to_cpu(general->sleep_time)); | 1582 | "burst_count:\t\t\t%u\t\t\t%u\n", |
1407 | pos += scnprintf(buf + pos, bufsz - pos, "slots_out: %u\n", | 1583 | le32_to_cpu(dbg->burst_count), |
1408 | le32_to_cpu(general->slots_out)); | 1584 | accum_dbg->burst_count); |
1409 | pos += scnprintf(buf + pos, bufsz - pos, "slots_idle: %u\n", | 1585 | pos += scnprintf(buf + pos, bufsz - pos, |
1410 | le32_to_cpu(general->slots_idle)); | 1586 | "sleep_time:\t\t\t%u\t\t\t%u\n", |
1411 | pos += scnprintf(buf + pos, bufsz - pos, "ttl_timestamp: %u\n", | 1587 | le32_to_cpu(general->sleep_time), |
1588 | accum_general->sleep_time); | ||
1589 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1590 | "slots_out:\t\t\t%u\t\t\t%u\n", | ||
1591 | le32_to_cpu(general->slots_out), | ||
1592 | accum_general->slots_out); | ||
1593 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1594 | "slots_idle:\t\t\t%u\t\t\t%u\n", | ||
1595 | le32_to_cpu(general->slots_idle), | ||
1596 | accum_general->slots_idle); | ||
1597 | pos += scnprintf(buf + pos, bufsz - pos, "ttl_timestamp:\t\t\t%u\n", | ||
1412 | le32_to_cpu(general->ttl_timestamp)); | 1598 | le32_to_cpu(general->ttl_timestamp)); |
1413 | pos += scnprintf(buf + pos, bufsz - pos, "tx_on_a: %u\n", | 1599 | pos += scnprintf(buf + pos, bufsz - pos, "tx_on_a:\t\t\t%u\t\t\t%u\n", |
1414 | le32_to_cpu(div->tx_on_a)); | 1600 | le32_to_cpu(div->tx_on_a), accum_div->tx_on_a); |
1415 | pos += scnprintf(buf + pos, bufsz - pos, "tx_on_b: %u\n", | 1601 | pos += scnprintf(buf + pos, bufsz - pos, "tx_on_b:\t\t\t%u\t\t\t%u\n", |
1416 | le32_to_cpu(div->tx_on_b)); | 1602 | le32_to_cpu(div->tx_on_b), accum_div->tx_on_b); |
1417 | pos += scnprintf(buf + pos, bufsz - pos, "exec_time: %u\n", | 1603 | pos += scnprintf(buf + pos, bufsz - pos, |
1418 | le32_to_cpu(div->exec_time)); | 1604 | "exec_time:\t\t\t%u\t\t\t%u\n", |
1419 | pos += scnprintf(buf + pos, bufsz - pos, "probe_time: %u\n", | 1605 | le32_to_cpu(div->exec_time), accum_div->exec_time); |
1420 | le32_to_cpu(div->probe_time)); | 1606 | pos += scnprintf(buf + pos, bufsz - pos, |
1421 | pos += scnprintf(buf + pos, bufsz - pos, "rx_enable_counter: %u\n", | 1607 | "probe_time:\t\t\t%u\t\t\t%u\n", |
1422 | le32_to_cpu(general->rx_enable_counter)); | 1608 | le32_to_cpu(div->probe_time), accum_div->probe_time); |
1609 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1610 | "rx_enable_counter:\t\t%u\t\t\t%u\n", | ||
1611 | le32_to_cpu(general->rx_enable_counter), | ||
1612 | accum_general->rx_enable_counter); | ||
1423 | ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); | 1613 | ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); |
1424 | kfree(buf); | 1614 | kfree(buf); |
1425 | return ret; | 1615 | return ret; |
@@ -1615,6 +1805,29 @@ static ssize_t iwl_dbgfs_tx_power_read(struct file *file, | |||
1615 | return simple_read_from_buffer(user_buf, count, ppos, buf, pos); | 1805 | return simple_read_from_buffer(user_buf, count, ppos, buf, pos); |
1616 | } | 1806 | } |
1617 | 1807 | ||
1808 | static ssize_t iwl_dbgfs_power_save_status_read(struct file *file, | ||
1809 | char __user *user_buf, | ||
1810 | size_t count, loff_t *ppos) | ||
1811 | { | ||
1812 | struct iwl_priv *priv = (struct iwl_priv *)file->private_data; | ||
1813 | char buf[60]; | ||
1814 | int pos = 0; | ||
1815 | const size_t bufsz = sizeof(buf); | ||
1816 | u32 pwrsave_status; | ||
1817 | |||
1818 | pwrsave_status = iwl_read32(priv, CSR_GP_CNTRL) & | ||
1819 | CSR_GP_REG_POWER_SAVE_STATUS_MSK; | ||
1820 | |||
1821 | pos += scnprintf(buf + pos, bufsz - pos, "Power Save Status: "); | ||
1822 | pos += scnprintf(buf + pos, bufsz - pos, "%s\n", | ||
1823 | (pwrsave_status == CSR_GP_REG_NO_POWER_SAVE) ? "none" : | ||
1824 | (pwrsave_status == CSR_GP_REG_MAC_POWER_SAVE) ? "MAC" : | ||
1825 | (pwrsave_status == CSR_GP_REG_PHY_POWER_SAVE) ? "PHY" : | ||
1826 | "error"); | ||
1827 | |||
1828 | return simple_read_from_buffer(user_buf, count, ppos, buf, pos); | ||
1829 | } | ||
1830 | |||
1618 | DEBUGFS_READ_WRITE_FILE_OPS(rx_statistics); | 1831 | DEBUGFS_READ_WRITE_FILE_OPS(rx_statistics); |
1619 | DEBUGFS_READ_WRITE_FILE_OPS(tx_statistics); | 1832 | DEBUGFS_READ_WRITE_FILE_OPS(tx_statistics); |
1620 | DEBUGFS_READ_WRITE_FILE_OPS(traffic_log); | 1833 | DEBUGFS_READ_WRITE_FILE_OPS(traffic_log); |
@@ -1626,6 +1839,7 @@ DEBUGFS_READ_FILE_OPS(ucode_general_stats); | |||
1626 | DEBUGFS_READ_FILE_OPS(sensitivity); | 1839 | DEBUGFS_READ_FILE_OPS(sensitivity); |
1627 | DEBUGFS_READ_FILE_OPS(chain_noise); | 1840 | DEBUGFS_READ_FILE_OPS(chain_noise); |
1628 | DEBUGFS_READ_FILE_OPS(tx_power); | 1841 | DEBUGFS_READ_FILE_OPS(tx_power); |
1842 | DEBUGFS_READ_FILE_OPS(power_save_status); | ||
1629 | 1843 | ||
1630 | /* | 1844 | /* |
1631 | * Create the debugfs files and directories | 1845 | * Create the debugfs files and directories |
@@ -1673,6 +1887,7 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name) | |||
1673 | DEBUGFS_ADD_FILE(rx_queue, debug); | 1887 | DEBUGFS_ADD_FILE(rx_queue, debug); |
1674 | DEBUGFS_ADD_FILE(tx_queue, debug); | 1888 | DEBUGFS_ADD_FILE(tx_queue, debug); |
1675 | DEBUGFS_ADD_FILE(tx_power, debug); | 1889 | DEBUGFS_ADD_FILE(tx_power, debug); |
1890 | DEBUGFS_ADD_FILE(power_save_status, debug); | ||
1676 | if ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) != CSR_HW_REV_TYPE_3945) { | 1891 | if ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) != CSR_HW_REV_TYPE_3945) { |
1677 | DEBUGFS_ADD_FILE(ucode_rx_stats, debug); | 1892 | DEBUGFS_ADD_FILE(ucode_rx_stats, debug); |
1678 | DEBUGFS_ADD_FILE(ucode_tx_stats, debug); | 1893 | DEBUGFS_ADD_FILE(ucode_tx_stats, debug); |
@@ -1725,6 +1940,7 @@ void iwl_dbgfs_unregister(struct iwl_priv *priv) | |||
1725 | DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.file_rx_queue); | 1940 | DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.file_rx_queue); |
1726 | DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.file_tx_queue); | 1941 | DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.file_tx_queue); |
1727 | DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.file_tx_power); | 1942 | DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.file_tx_power); |
1943 | DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.file_power_save_status); | ||
1728 | if ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) != CSR_HW_REV_TYPE_3945) { | 1944 | if ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) != CSR_HW_REV_TYPE_3945) { |
1729 | DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files. | 1945 | DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files. |
1730 | file_ucode_rx_stats); | 1946 | file_ucode_rx_stats); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 72946c144be7..e7ce67387662 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h | |||
@@ -85,8 +85,6 @@ extern void iwl5000_rts_tx_cmd_flag(struct ieee80211_tx_info *info, | |||
85 | __le32 *tx_flags); | 85 | __le32 *tx_flags); |
86 | extern int iwl5000_calc_rssi(struct iwl_priv *priv, | 86 | extern int iwl5000_calc_rssi(struct iwl_priv *priv, |
87 | struct iwl_rx_phy_res *rx_resp); | 87 | struct iwl_rx_phy_res *rx_resp); |
88 | extern int iwl5000_apm_init(struct iwl_priv *priv); | ||
89 | extern int iwl5000_apm_reset(struct iwl_priv *priv); | ||
90 | extern void iwl5000_nic_config(struct iwl_priv *priv); | 88 | extern void iwl5000_nic_config(struct iwl_priv *priv); |
91 | extern u16 iwl5000_eeprom_calib_version(struct iwl_priv *priv); | 89 | extern u16 iwl5000_eeprom_calib_version(struct iwl_priv *priv); |
92 | extern const u8 *iwl5000_eeprom_query_addr(const struct iwl_priv *priv, | 90 | extern const u8 *iwl5000_eeprom_query_addr(const struct iwl_priv *priv, |
@@ -147,12 +145,13 @@ extern void iwl5000_temperature(struct iwl_priv *priv); | |||
147 | #define DEFAULT_LONG_RETRY_LIMIT 4U | 145 | #define DEFAULT_LONG_RETRY_LIMIT 4U |
148 | 146 | ||
149 | struct iwl_rx_mem_buffer { | 147 | struct iwl_rx_mem_buffer { |
150 | dma_addr_t real_dma_addr; | 148 | dma_addr_t page_dma; |
151 | dma_addr_t aligned_dma_addr; | 149 | struct page *page; |
152 | struct sk_buff *skb; | ||
153 | struct list_head list; | 150 | struct list_head list; |
154 | }; | 151 | }; |
155 | 152 | ||
153 | #define rxb_addr(r) page_address(r->page) | ||
154 | |||
156 | /* defined below */ | 155 | /* defined below */ |
157 | struct iwl_device_cmd; | 156 | struct iwl_device_cmd; |
158 | 157 | ||
@@ -168,7 +167,7 @@ struct iwl_cmd_meta { | |||
168 | */ | 167 | */ |
169 | void (*callback)(struct iwl_priv *priv, | 168 | void (*callback)(struct iwl_priv *priv, |
170 | struct iwl_device_cmd *cmd, | 169 | struct iwl_device_cmd *cmd, |
171 | struct sk_buff *skb); | 170 | struct iwl_rx_packet *pkt); |
172 | 171 | ||
173 | /* The CMD_SIZE_HUGE flag bit indicates that the command | 172 | /* The CMD_SIZE_HUGE flag bit indicates that the command |
174 | * structure is stored at the end of the shared queue memory. */ | 173 | * structure is stored at the end of the shared queue memory. */ |
@@ -324,6 +323,12 @@ struct iwl_channel_info { | |||
324 | * queue, 2 (unused) HCCA queues, and 4 HT queues (one for each AC) */ | 323 | * queue, 2 (unused) HCCA queues, and 4 HT queues (one for each AC) */ |
325 | #define IWL_MIN_NUM_QUEUES 10 | 324 | #define IWL_MIN_NUM_QUEUES 10 |
326 | 325 | ||
326 | /* | ||
327 | * uCode queue management definitions ... | ||
328 | * Queue #4 is the command queue for 3945/4965/5x00/1000/6x00. | ||
329 | */ | ||
330 | #define IWL_CMD_QUEUE_NUM 4 | ||
331 | |||
327 | /* Power management (not Tx power) structures */ | 332 | /* Power management (not Tx power) structures */ |
328 | 333 | ||
329 | enum iwl_pwr_src { | 334 | enum iwl_pwr_src { |
@@ -359,7 +364,14 @@ enum { | |||
359 | CMD_WANT_SKB = (1 << 2), | 364 | CMD_WANT_SKB = (1 << 2), |
360 | }; | 365 | }; |
361 | 366 | ||
362 | #define IWL_CMD_MAX_PAYLOAD 320 | 367 | #define DEF_CMD_PAYLOAD_SIZE 320 |
368 | |||
369 | /* | ||
370 | * IWL_LINK_HDR_MAX should include ieee80211_hdr, radiotap header, | ||
371 | * SNAP header and alignment. It should also be big enough for 802.11 | ||
372 | * control frames. | ||
373 | */ | ||
374 | #define IWL_LINK_HDR_MAX 64 | ||
363 | 375 | ||
364 | /** | 376 | /** |
365 | * struct iwl_device_cmd | 377 | * struct iwl_device_cmd |
@@ -376,7 +388,8 @@ struct iwl_device_cmd { | |||
376 | u16 val16; | 388 | u16 val16; |
377 | u32 val32; | 389 | u32 val32; |
378 | struct iwl_tx_cmd tx; | 390 | struct iwl_tx_cmd tx; |
379 | u8 payload[IWL_CMD_MAX_PAYLOAD]; | 391 | struct iwl6000_channel_switch_cmd chswitch; |
392 | u8 payload[DEF_CMD_PAYLOAD_SIZE]; | ||
380 | } __attribute__ ((packed)) cmd; | 393 | } __attribute__ ((packed)) cmd; |
381 | } __attribute__ ((packed)); | 394 | } __attribute__ ((packed)); |
382 | 395 | ||
@@ -385,21 +398,15 @@ struct iwl_device_cmd { | |||
385 | 398 | ||
386 | struct iwl_host_cmd { | 399 | struct iwl_host_cmd { |
387 | const void *data; | 400 | const void *data; |
388 | struct sk_buff *reply_skb; | 401 | unsigned long reply_page; |
389 | void (*callback)(struct iwl_priv *priv, | 402 | void (*callback)(struct iwl_priv *priv, |
390 | struct iwl_device_cmd *cmd, | 403 | struct iwl_device_cmd *cmd, |
391 | struct sk_buff *skb); | 404 | struct iwl_rx_packet *pkt); |
392 | u32 flags; | 405 | u32 flags; |
393 | u16 len; | 406 | u16 len; |
394 | u8 id; | 407 | u8 id; |
395 | }; | 408 | }; |
396 | 409 | ||
397 | /* | ||
398 | * RX related structures and functions | ||
399 | */ | ||
400 | #define RX_FREE_BUFFERS 64 | ||
401 | #define RX_LOW_WATERMARK 8 | ||
402 | |||
403 | #define SUP_RATE_11A_MAX_NUM_CHANNELS 8 | 410 | #define SUP_RATE_11A_MAX_NUM_CHANNELS 8 |
404 | #define SUP_RATE_11B_MAX_NUM_CHANNELS 4 | 411 | #define SUP_RATE_11B_MAX_NUM_CHANNELS 4 |
405 | #define SUP_RATE_11G_MAX_NUM_CHANNELS 12 | 412 | #define SUP_RATE_11G_MAX_NUM_CHANNELS 12 |
@@ -563,6 +570,19 @@ struct iwl_station_entry { | |||
563 | struct iwl_hw_key keyinfo; | 570 | struct iwl_hw_key keyinfo; |
564 | }; | 571 | }; |
565 | 572 | ||
573 | /* | ||
574 | * iwl_station_priv: Driver's private station information | ||
575 | * | ||
576 | * When mac80211 creates a station it reserves some space (hw->sta_data_size) | ||
577 | * in the structure for use by driver. This structure is places in that | ||
578 | * space. | ||
579 | * | ||
580 | * At the moment use it for the station's rate scaling information. | ||
581 | */ | ||
582 | struct iwl_station_priv { | ||
583 | struct iwl_lq_sta lq_sta; | ||
584 | }; | ||
585 | |||
566 | /* one for each uCode image (inst/data, boot/init/runtime) */ | 586 | /* one for each uCode image (inst/data, boot/init/runtime) */ |
567 | struct fw_desc { | 587 | struct fw_desc { |
568 | void *v_addr; /* access by driver */ | 588 | void *v_addr; /* access by driver */ |
@@ -624,6 +644,10 @@ struct iwl_sensitivity_ranges { | |||
624 | u16 auto_corr_max_cck_mrc; | 644 | u16 auto_corr_max_cck_mrc; |
625 | u16 auto_corr_min_cck; | 645 | u16 auto_corr_min_cck; |
626 | u16 auto_corr_min_cck_mrc; | 646 | u16 auto_corr_min_cck_mrc; |
647 | |||
648 | u16 barker_corr_th_min; | ||
649 | u16 barker_corr_th_min_mrc; | ||
650 | u16 nrg_th_cca; | ||
627 | }; | 651 | }; |
628 | 652 | ||
629 | 653 | ||
@@ -641,7 +665,7 @@ struct iwl_sensitivity_ranges { | |||
641 | * @valid_tx/rx_ant: usable antennas | 665 | * @valid_tx/rx_ant: usable antennas |
642 | * @max_rxq_size: Max # Rx frames in Rx queue (must be power-of-2) | 666 | * @max_rxq_size: Max # Rx frames in Rx queue (must be power-of-2) |
643 | * @max_rxq_log: Log-base-2 of max_rxq_size | 667 | * @max_rxq_log: Log-base-2 of max_rxq_size |
644 | * @rx_buf_size: Rx buffer size | 668 | * @rx_page_order: Rx buffer page order |
645 | * @rx_wrt_ptr_reg: FH{39}_RSCSR_CHNL0_WPTR | 669 | * @rx_wrt_ptr_reg: FH{39}_RSCSR_CHNL0_WPTR |
646 | * @max_stations: | 670 | * @max_stations: |
647 | * @bcast_sta_id: | 671 | * @bcast_sta_id: |
@@ -664,9 +688,8 @@ struct iwl_hw_params { | |||
664 | u8 valid_rx_ant; | 688 | u8 valid_rx_ant; |
665 | u16 max_rxq_size; | 689 | u16 max_rxq_size; |
666 | u16 max_rxq_log; | 690 | u16 max_rxq_log; |
667 | u32 rx_buf_size; | 691 | u32 rx_page_order; |
668 | u32 rx_wrt_ptr_reg; | 692 | u32 rx_wrt_ptr_reg; |
669 | u32 max_pkt_size; | ||
670 | u8 max_stations; | 693 | u8 max_stations; |
671 | u8 bcast_sta_id; | 694 | u8 bcast_sta_id; |
672 | u8 ht40_channel; | 695 | u8 ht40_channel; |
@@ -713,7 +736,11 @@ static inline int iwl_queue_used(const struct iwl_queue *q, int i) | |||
713 | 736 | ||
714 | static inline u8 get_cmd_index(struct iwl_queue *q, u32 index, int is_huge) | 737 | static inline u8 get_cmd_index(struct iwl_queue *q, u32 index, int is_huge) |
715 | { | 738 | { |
716 | /* This is for scan command, the big buffer at end of command array */ | 739 | /* |
740 | * This is for init calibration result and scan command which | ||
741 | * required buffer > TFD_MAX_PAYLOAD_SIZE, | ||
742 | * the big buffer at end of command array | ||
743 | */ | ||
717 | if (is_huge) | 744 | if (is_huge) |
718 | return q->n_window; /* must be power of 2 */ | 745 | return q->n_window; /* must be power of 2 */ |
719 | 746 | ||
@@ -845,6 +872,10 @@ struct iwl_sensitivity_data { | |||
845 | s32 nrg_auto_corr_silence_diff; | 872 | s32 nrg_auto_corr_silence_diff; |
846 | u32 num_in_cck_no_fa; | 873 | u32 num_in_cck_no_fa; |
847 | u32 nrg_th_ofdm; | 874 | u32 nrg_th_ofdm; |
875 | |||
876 | u16 barker_corr_th_min; | ||
877 | u16 barker_corr_th_min_mrc; | ||
878 | u16 nrg_th_cca; | ||
848 | }; | 879 | }; |
849 | 880 | ||
850 | /* Chain noise (differential Rx gain) calib data */ | 881 | /* Chain noise (differential Rx gain) calib data */ |
@@ -961,8 +992,6 @@ struct traffic_stats { | |||
961 | }; | 992 | }; |
962 | #endif | 993 | #endif |
963 | 994 | ||
964 | #define IWL_MAX_NUM_QUEUES 20 /* FIXME: do dynamic allocation */ | ||
965 | |||
966 | struct iwl_priv { | 995 | struct iwl_priv { |
967 | 996 | ||
968 | /* ieee device used by generic ieee processing code */ | 997 | /* ieee device used by generic ieee processing code */ |
@@ -976,7 +1005,7 @@ struct iwl_priv { | |||
976 | int frames_count; | 1005 | int frames_count; |
977 | 1006 | ||
978 | enum ieee80211_band band; | 1007 | enum ieee80211_band band; |
979 | int alloc_rxb_skb; | 1008 | int alloc_rxb_page; |
980 | 1009 | ||
981 | void (*rx_handlers[REPLY_MAX])(struct iwl_priv *priv, | 1010 | void (*rx_handlers[REPLY_MAX])(struct iwl_priv *priv, |
982 | struct iwl_rx_mem_buffer *rxb); | 1011 | struct iwl_rx_mem_buffer *rxb); |
@@ -1081,7 +1110,6 @@ struct iwl_priv { | |||
1081 | u8 last_phy_res[100]; | 1110 | u8 last_phy_res[100]; |
1082 | 1111 | ||
1083 | /* Rate scaling data */ | 1112 | /* Rate scaling data */ |
1084 | s8 data_retry_limit; | ||
1085 | u8 retry_rate; | 1113 | u8 retry_rate; |
1086 | 1114 | ||
1087 | wait_queue_head_t wait_command_queue; | 1115 | wait_queue_head_t wait_command_queue; |
@@ -1090,7 +1118,7 @@ struct iwl_priv { | |||
1090 | 1118 | ||
1091 | /* Rx and Tx DMA processing queues */ | 1119 | /* Rx and Tx DMA processing queues */ |
1092 | struct iwl_rx_queue rxq; | 1120 | struct iwl_rx_queue rxq; |
1093 | struct iwl_tx_queue txq[IWL_MAX_NUM_QUEUES]; | 1121 | struct iwl_tx_queue *txq; |
1094 | unsigned long txq_ctx_active_msk; | 1122 | unsigned long txq_ctx_active_msk; |
1095 | struct iwl_dma_ptr kw; /* keep warm address */ | 1123 | struct iwl_dma_ptr kw; /* keep warm address */ |
1096 | struct iwl_dma_ptr scd_bc_tbls; | 1124 | struct iwl_dma_ptr scd_bc_tbls; |
@@ -1113,7 +1141,9 @@ struct iwl_priv { | |||
1113 | struct iwl_tt_mgmt thermal_throttle; | 1141 | struct iwl_tt_mgmt thermal_throttle; |
1114 | 1142 | ||
1115 | struct iwl_notif_statistics statistics; | 1143 | struct iwl_notif_statistics statistics; |
1116 | unsigned long last_statistics_time; | 1144 | #ifdef CONFIG_IWLWIFI_DEBUG |
1145 | struct iwl_notif_statistics accum_statistics; | ||
1146 | #endif | ||
1117 | 1147 | ||
1118 | /* context information */ | 1148 | /* context information */ |
1119 | u16 rates_mask; | 1149 | u16 rates_mask; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-eeprom.c index 2e8c40576d22..9429cb1c69bd 100644 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom.c +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.c | |||
@@ -358,6 +358,14 @@ static int iwl_init_otp_access(struct iwl_priv *priv) | |||
358 | udelay(5); | 358 | udelay(5); |
359 | iwl_clear_bits_prph(priv, APMG_PS_CTRL_REG, | 359 | iwl_clear_bits_prph(priv, APMG_PS_CTRL_REG, |
360 | APMG_PS_CTRL_VAL_RESET_REQ); | 360 | APMG_PS_CTRL_VAL_RESET_REQ); |
361 | |||
362 | /* | ||
363 | * CSR auto clock gate disable bit - | ||
364 | * this is only applicable for HW with OTP shadow RAM | ||
365 | */ | ||
366 | if (priv->cfg->shadow_ram_support) | ||
367 | iwl_set_bit(priv, CSR_DBG_LINK_PWR_MGMT_REG, | ||
368 | CSR_RESET_LINK_PWR_MGMT_DISABLED); | ||
361 | } | 369 | } |
362 | return ret; | 370 | return ret; |
363 | } | 371 | } |
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.h b/drivers/net/wireless/iwlwifi/iwl-eeprom.h index b363c96fd6c6..5ba5a4e9e49a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom.h +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.h | |||
@@ -261,9 +261,12 @@ struct iwl_eeprom_enhanced_txpwr { | |||
261 | /* 1000 Specific */ | 261 | /* 1000 Specific */ |
262 | #define EEPROM_1000_EEPROM_VERSION (0x15C) | 262 | #define EEPROM_1000_EEPROM_VERSION (0x15C) |
263 | 263 | ||
264 | /* 60x0 Specific */ | 264 | /* 6x00 Specific */ |
265 | #define EEPROM_6000_EEPROM_VERSION (0x434) | 265 | #define EEPROM_6000_EEPROM_VERSION (0x434) |
266 | 266 | ||
267 | /* 6x50 Specific */ | ||
268 | #define EEPROM_6050_EEPROM_VERSION (0x532) | ||
269 | |||
267 | /* OTP */ | 270 | /* OTP */ |
268 | /* lower blocks contain EEPROM image and calibration data */ | 271 | /* lower blocks contain EEPROM image and calibration data */ |
269 | #define OTP_LOW_IMAGE_SIZE (2 * 512 * sizeof(u16)) /* 2 KB */ | 272 | #define OTP_LOW_IMAGE_SIZE (2 * 512 * sizeof(u16)) /* 2 KB */ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-hcmd.c b/drivers/net/wireless/iwlwifi/iwl-hcmd.c index 532c8d6cd8da..f2a60dc4109f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-hcmd.c +++ b/drivers/net/wireless/iwlwifi/iwl-hcmd.c | |||
@@ -92,6 +92,8 @@ const char *get_cmd_string(u8 cmd) | |||
92 | IWL_CMD(CALIBRATION_RES_NOTIFICATION); | 92 | IWL_CMD(CALIBRATION_RES_NOTIFICATION); |
93 | IWL_CMD(CALIBRATION_COMPLETE_NOTIFICATION); | 93 | IWL_CMD(CALIBRATION_COMPLETE_NOTIFICATION); |
94 | IWL_CMD(REPLY_TX_POWER_DBM_CMD); | 94 | IWL_CMD(REPLY_TX_POWER_DBM_CMD); |
95 | IWL_CMD(TEMPERATURE_NOTIFICATION); | ||
96 | IWL_CMD(TX_ANT_CONFIGURATION_CMD); | ||
95 | default: | 97 | default: |
96 | return "UNKNOWN"; | 98 | return "UNKNOWN"; |
97 | 99 | ||
@@ -103,17 +105,8 @@ EXPORT_SYMBOL(get_cmd_string); | |||
103 | 105 | ||
104 | static void iwl_generic_cmd_callback(struct iwl_priv *priv, | 106 | static void iwl_generic_cmd_callback(struct iwl_priv *priv, |
105 | struct iwl_device_cmd *cmd, | 107 | struct iwl_device_cmd *cmd, |
106 | struct sk_buff *skb) | 108 | struct iwl_rx_packet *pkt) |
107 | { | 109 | { |
108 | struct iwl_rx_packet *pkt = NULL; | ||
109 | |||
110 | if (!skb) { | ||
111 | IWL_ERR(priv, "Error: Response NULL in %s.\n", | ||
112 | get_cmd_string(cmd->hdr.cmd)); | ||
113 | return; | ||
114 | } | ||
115 | |||
116 | pkt = (struct iwl_rx_packet *)skb->data; | ||
117 | if (pkt->hdr.flags & IWL_CMD_FAILED_MSK) { | 110 | if (pkt->hdr.flags & IWL_CMD_FAILED_MSK) { |
118 | IWL_ERR(priv, "Bad return from %s (0x%08X)\n", | 111 | IWL_ERR(priv, "Bad return from %s (0x%08X)\n", |
119 | get_cmd_string(cmd->hdr.cmd), pkt->hdr.flags); | 112 | get_cmd_string(cmd->hdr.cmd), pkt->hdr.flags); |
@@ -215,7 +208,7 @@ int iwl_send_cmd_sync(struct iwl_priv *priv, struct iwl_host_cmd *cmd) | |||
215 | ret = -EIO; | 208 | ret = -EIO; |
216 | goto fail; | 209 | goto fail; |
217 | } | 210 | } |
218 | if ((cmd->flags & CMD_WANT_SKB) && !cmd->reply_skb) { | 211 | if ((cmd->flags & CMD_WANT_SKB) && !cmd->reply_page) { |
219 | IWL_ERR(priv, "Error: Response NULL in '%s'\n", | 212 | IWL_ERR(priv, "Error: Response NULL in '%s'\n", |
220 | get_cmd_string(cmd->id)); | 213 | get_cmd_string(cmd->id)); |
221 | ret = -EIO; | 214 | ret = -EIO; |
@@ -237,9 +230,9 @@ cancel: | |||
237 | ~CMD_WANT_SKB; | 230 | ~CMD_WANT_SKB; |
238 | } | 231 | } |
239 | fail: | 232 | fail: |
240 | if (cmd->reply_skb) { | 233 | if (cmd->reply_page) { |
241 | dev_kfree_skb_any(cmd->reply_skb); | 234 | free_pages(cmd->reply_page, priv->hw_params.rx_page_order); |
242 | cmd->reply_skb = NULL; | 235 | cmd->reply_page = 0; |
243 | } | 236 | } |
244 | out: | 237 | out: |
245 | clear_bit(STATUS_HCMD_SYNC_ACTIVE, &priv->status); | 238 | clear_bit(STATUS_HCMD_SYNC_ACTIVE, &priv->status); |
@@ -272,7 +265,7 @@ int iwl_send_cmd_pdu_async(struct iwl_priv *priv, | |||
272 | u8 id, u16 len, const void *data, | 265 | u8 id, u16 len, const void *data, |
273 | void (*callback)(struct iwl_priv *priv, | 266 | void (*callback)(struct iwl_priv *priv, |
274 | struct iwl_device_cmd *cmd, | 267 | struct iwl_device_cmd *cmd, |
275 | struct sk_buff *skb)) | 268 | struct iwl_rx_packet *pkt)) |
276 | { | 269 | { |
277 | struct iwl_host_cmd cmd = { | 270 | struct iwl_host_cmd cmd = { |
278 | .id = id, | 271 | .id = id, |
diff --git a/drivers/net/wireless/iwlwifi/iwl-power.c b/drivers/net/wireless/iwlwifi/iwl-power.c index 9c6b14952061..9bce2c1625e3 100644 --- a/drivers/net/wireless/iwlwifi/iwl-power.c +++ b/drivers/net/wireless/iwlwifi/iwl-power.c | |||
@@ -66,7 +66,7 @@ MODULE_PARM_DESC(no_sleep_autoadjust, | |||
66 | 66 | ||
67 | struct iwl_power_vec_entry { | 67 | struct iwl_power_vec_entry { |
68 | struct iwl_powertable_cmd cmd; | 68 | struct iwl_powertable_cmd cmd; |
69 | u8 no_dtim; | 69 | u8 no_dtim; /* number of skip dtim */ |
70 | }; | 70 | }; |
71 | 71 | ||
72 | #define IWL_DTIM_RANGE_0_MAX 2 | 72 | #define IWL_DTIM_RANGE_0_MAX 2 |
@@ -83,8 +83,9 @@ struct iwl_power_vec_entry { | |||
83 | cpu_to_le32(X4)} | 83 | cpu_to_le32(X4)} |
84 | /* default power management (not Tx power) table values */ | 84 | /* default power management (not Tx power) table values */ |
85 | /* for DTIM period 0 through IWL_DTIM_RANGE_0_MAX */ | 85 | /* for DTIM period 0 through IWL_DTIM_RANGE_0_MAX */ |
86 | /* DTIM 0 - 2 */ | ||
86 | static const struct iwl_power_vec_entry range_0[IWL_POWER_NUM] = { | 87 | static const struct iwl_power_vec_entry range_0[IWL_POWER_NUM] = { |
87 | {{SLP, SLP_TOUT(200), SLP_TOUT(500), SLP_VEC(1, 2, 2, 2, 0xFF)}, 0}, | 88 | {{SLP, SLP_TOUT(200), SLP_TOUT(500), SLP_VEC(1, 1, 2, 2, 0xFF)}, 0}, |
88 | {{SLP, SLP_TOUT(200), SLP_TOUT(300), SLP_VEC(1, 2, 2, 2, 0xFF)}, 0}, | 89 | {{SLP, SLP_TOUT(200), SLP_TOUT(300), SLP_VEC(1, 2, 2, 2, 0xFF)}, 0}, |
89 | {{SLP, SLP_TOUT(50), SLP_TOUT(100), SLP_VEC(2, 2, 2, 2, 0xFF)}, 0}, | 90 | {{SLP, SLP_TOUT(50), SLP_TOUT(100), SLP_VEC(2, 2, 2, 2, 0xFF)}, 0}, |
90 | {{SLP, SLP_TOUT(50), SLP_TOUT(25), SLP_VEC(2, 2, 4, 4, 0xFF)}, 1}, | 91 | {{SLP, SLP_TOUT(50), SLP_TOUT(25), SLP_VEC(2, 2, 4, 4, 0xFF)}, 1}, |
@@ -93,15 +94,17 @@ static const struct iwl_power_vec_entry range_0[IWL_POWER_NUM] = { | |||
93 | 94 | ||
94 | 95 | ||
95 | /* for DTIM period IWL_DTIM_RANGE_0_MAX + 1 through IWL_DTIM_RANGE_1_MAX */ | 96 | /* for DTIM period IWL_DTIM_RANGE_0_MAX + 1 through IWL_DTIM_RANGE_1_MAX */ |
97 | /* DTIM 3 - 10 */ | ||
96 | static const struct iwl_power_vec_entry range_1[IWL_POWER_NUM] = { | 98 | static const struct iwl_power_vec_entry range_1[IWL_POWER_NUM] = { |
97 | {{SLP, SLP_TOUT(200), SLP_TOUT(500), SLP_VEC(1, 2, 3, 4, 4)}, 0}, | 99 | {{SLP, SLP_TOUT(200), SLP_TOUT(500), SLP_VEC(1, 2, 3, 4, 4)}, 0}, |
98 | {{SLP, SLP_TOUT(200), SLP_TOUT(300), SLP_VEC(1, 2, 3, 4, 7)}, 0}, | 100 | {{SLP, SLP_TOUT(200), SLP_TOUT(300), SLP_VEC(1, 2, 3, 4, 7)}, 0}, |
99 | {{SLP, SLP_TOUT(50), SLP_TOUT(100), SLP_VEC(2, 4, 6, 7, 9)}, 0}, | 101 | {{SLP, SLP_TOUT(50), SLP_TOUT(100), SLP_VEC(2, 4, 6, 7, 9)}, 0}, |
100 | {{SLP, SLP_TOUT(50), SLP_TOUT(25), SLP_VEC(2, 4, 6, 9, 10)}, 1}, | 102 | {{SLP, SLP_TOUT(50), SLP_TOUT(25), SLP_VEC(2, 4, 6, 9, 10)}, 1}, |
101 | {{SLP, SLP_TOUT(25), SLP_TOUT(25), SLP_VEC(2, 4, 7, 10, 10)}, 2} | 103 | {{SLP, SLP_TOUT(25), SLP_TOUT(25), SLP_VEC(2, 4, 6, 10, 10)}, 2} |
102 | }; | 104 | }; |
103 | 105 | ||
104 | /* for DTIM period > IWL_DTIM_RANGE_1_MAX */ | 106 | /* for DTIM period > IWL_DTIM_RANGE_1_MAX */ |
107 | /* DTIM 11 - */ | ||
105 | static const struct iwl_power_vec_entry range_2[IWL_POWER_NUM] = { | 108 | static const struct iwl_power_vec_entry range_2[IWL_POWER_NUM] = { |
106 | {{SLP, SLP_TOUT(200), SLP_TOUT(500), SLP_VEC(1, 2, 3, 4, 0xFF)}, 0}, | 109 | {{SLP, SLP_TOUT(200), SLP_TOUT(500), SLP_VEC(1, 2, 3, 4, 0xFF)}, 0}, |
107 | {{SLP, SLP_TOUT(200), SLP_TOUT(300), SLP_VEC(2, 4, 6, 7, 0xFF)}, 0}, | 110 | {{SLP, SLP_TOUT(200), SLP_TOUT(300), SLP_VEC(2, 4, 6, 7, 0xFF)}, 0}, |
@@ -115,13 +118,15 @@ static void iwl_static_sleep_cmd(struct iwl_priv *priv, | |||
115 | enum iwl_power_level lvl, int period) | 118 | enum iwl_power_level lvl, int period) |
116 | { | 119 | { |
117 | const struct iwl_power_vec_entry *table; | 120 | const struct iwl_power_vec_entry *table; |
118 | int max_sleep, i; | 121 | int max_sleep[IWL_POWER_VEC_SIZE] = { 0 }; |
119 | bool skip; | 122 | int i; |
123 | u8 skip; | ||
124 | u32 slp_itrvl; | ||
120 | 125 | ||
121 | table = range_2; | 126 | table = range_2; |
122 | if (period < IWL_DTIM_RANGE_1_MAX) | 127 | if (period <= IWL_DTIM_RANGE_1_MAX) |
123 | table = range_1; | 128 | table = range_1; |
124 | if (period < IWL_DTIM_RANGE_0_MAX) | 129 | if (period <= IWL_DTIM_RANGE_0_MAX) |
125 | table = range_0; | 130 | table = range_0; |
126 | 131 | ||
127 | BUG_ON(lvl < 0 || lvl >= IWL_POWER_NUM); | 132 | BUG_ON(lvl < 0 || lvl >= IWL_POWER_NUM); |
@@ -129,34 +134,60 @@ static void iwl_static_sleep_cmd(struct iwl_priv *priv, | |||
129 | *cmd = table[lvl].cmd; | 134 | *cmd = table[lvl].cmd; |
130 | 135 | ||
131 | if (period == 0) { | 136 | if (period == 0) { |
132 | skip = false; | 137 | skip = 0; |
133 | period = 1; | 138 | period = 1; |
139 | for (i = 0; i < IWL_POWER_VEC_SIZE; i++) | ||
140 | max_sleep[i] = 1; | ||
141 | |||
134 | } else { | 142 | } else { |
135 | skip = !!table[lvl].no_dtim; | 143 | skip = table[lvl].no_dtim; |
144 | for (i = 0; i < IWL_POWER_VEC_SIZE; i++) | ||
145 | max_sleep[i] = le32_to_cpu(cmd->sleep_interval[i]); | ||
146 | max_sleep[IWL_POWER_VEC_SIZE - 1] = skip + 1; | ||
136 | } | 147 | } |
137 | 148 | ||
138 | if (skip) { | 149 | slp_itrvl = le32_to_cpu(cmd->sleep_interval[IWL_POWER_VEC_SIZE - 1]); |
139 | __le32 slp_itrvl = cmd->sleep_interval[IWL_POWER_VEC_SIZE - 1]; | 150 | /* figure out the listen interval based on dtim period and skip */ |
140 | max_sleep = le32_to_cpu(slp_itrvl); | 151 | if (slp_itrvl == 0xFF) |
141 | if (max_sleep == 0xFF) | 152 | cmd->sleep_interval[IWL_POWER_VEC_SIZE - 1] = |
142 | max_sleep = period * (skip + 1); | 153 | cpu_to_le32(period * (skip + 1)); |
143 | else if (max_sleep > period) | 154 | |
144 | max_sleep = (le32_to_cpu(slp_itrvl) / period) * period; | 155 | slp_itrvl = le32_to_cpu(cmd->sleep_interval[IWL_POWER_VEC_SIZE - 1]); |
156 | if (slp_itrvl > period) | ||
157 | cmd->sleep_interval[IWL_POWER_VEC_SIZE - 1] = | ||
158 | cpu_to_le32((slp_itrvl / period) * period); | ||
159 | |||
160 | if (skip) | ||
145 | cmd->flags |= IWL_POWER_SLEEP_OVER_DTIM_MSK; | 161 | cmd->flags |= IWL_POWER_SLEEP_OVER_DTIM_MSK; |
146 | } else { | 162 | else |
147 | max_sleep = period; | ||
148 | cmd->flags &= ~IWL_POWER_SLEEP_OVER_DTIM_MSK; | 163 | cmd->flags &= ~IWL_POWER_SLEEP_OVER_DTIM_MSK; |
149 | } | ||
150 | 164 | ||
151 | for (i = 0; i < IWL_POWER_VEC_SIZE; i++) | 165 | slp_itrvl = le32_to_cpu(cmd->sleep_interval[IWL_POWER_VEC_SIZE - 1]); |
152 | if (le32_to_cpu(cmd->sleep_interval[i]) > max_sleep) | 166 | if (slp_itrvl > IWL_CONN_MAX_LISTEN_INTERVAL) |
153 | cmd->sleep_interval[i] = cpu_to_le32(max_sleep); | 167 | cmd->sleep_interval[IWL_POWER_VEC_SIZE - 1] = |
168 | cpu_to_le32(IWL_CONN_MAX_LISTEN_INTERVAL); | ||
169 | |||
170 | /* enforce max sleep interval */ | ||
171 | for (i = IWL_POWER_VEC_SIZE - 1; i >= 0 ; i--) { | ||
172 | if (le32_to_cpu(cmd->sleep_interval[i]) > | ||
173 | (max_sleep[i] * period)) | ||
174 | cmd->sleep_interval[i] = | ||
175 | cpu_to_le32(max_sleep[i] * period); | ||
176 | if (i != (IWL_POWER_VEC_SIZE - 1)) { | ||
177 | if (le32_to_cpu(cmd->sleep_interval[i]) > | ||
178 | le32_to_cpu(cmd->sleep_interval[i+1])) | ||
179 | cmd->sleep_interval[i] = | ||
180 | cmd->sleep_interval[i+1]; | ||
181 | } | ||
182 | } | ||
154 | 183 | ||
155 | if (priv->power_data.pci_pm) | 184 | if (priv->power_data.pci_pm) |
156 | cmd->flags |= IWL_POWER_PCI_PM_MSK; | 185 | cmd->flags |= IWL_POWER_PCI_PM_MSK; |
157 | else | 186 | else |
158 | cmd->flags &= ~IWL_POWER_PCI_PM_MSK; | 187 | cmd->flags &= ~IWL_POWER_PCI_PM_MSK; |
159 | 188 | ||
189 | IWL_DEBUG_POWER(priv, "numSkipDtim = %u, dtimPeriod = %d\n", | ||
190 | skip, period); | ||
160 | IWL_DEBUG_POWER(priv, "Sleep command for index %d\n", lvl + 1); | 191 | IWL_DEBUG_POWER(priv, "Sleep command for index %d\n", lvl + 1); |
161 | } | 192 | } |
162 | 193 | ||
@@ -862,9 +893,7 @@ void iwl_tt_initialize(struct iwl_priv *priv) | |||
862 | INIT_WORK(&priv->ct_enter, iwl_bg_ct_enter); | 893 | INIT_WORK(&priv->ct_enter, iwl_bg_ct_enter); |
863 | INIT_WORK(&priv->ct_exit, iwl_bg_ct_exit); | 894 | INIT_WORK(&priv->ct_exit, iwl_bg_ct_exit); |
864 | 895 | ||
865 | switch (priv->hw_rev & CSR_HW_REV_TYPE_MSK) { | 896 | if (priv->cfg->adv_thermal_throttle) { |
866 | case CSR_HW_REV_TYPE_6x00: | ||
867 | case CSR_HW_REV_TYPE_6x50: | ||
868 | IWL_DEBUG_POWER(priv, "Advanced Thermal Throttling\n"); | 897 | IWL_DEBUG_POWER(priv, "Advanced Thermal Throttling\n"); |
869 | tt->restriction = kzalloc(sizeof(struct iwl_tt_restriction) * | 898 | tt->restriction = kzalloc(sizeof(struct iwl_tt_restriction) * |
870 | IWL_TI_STATE_MAX, GFP_KERNEL); | 899 | IWL_TI_STATE_MAX, GFP_KERNEL); |
@@ -897,11 +926,9 @@ void iwl_tt_initialize(struct iwl_priv *priv) | |||
897 | &restriction_range[0], size); | 926 | &restriction_range[0], size); |
898 | priv->thermal_throttle.advanced_tt = true; | 927 | priv->thermal_throttle.advanced_tt = true; |
899 | } | 928 | } |
900 | break; | 929 | } else { |
901 | default: | ||
902 | IWL_DEBUG_POWER(priv, "Legacy Thermal Throttling\n"); | 930 | IWL_DEBUG_POWER(priv, "Legacy Thermal Throttling\n"); |
903 | priv->thermal_throttle.advanced_tt = false; | 931 | priv->thermal_throttle.advanced_tt = false; |
904 | break; | ||
905 | } | 932 | } |
906 | } | 933 | } |
907 | EXPORT_SYMBOL(iwl_tt_initialize); | 934 | EXPORT_SYMBOL(iwl_tt_initialize); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c index 493626bcd3ec..e5339c9ad13e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-rx.c | |||
@@ -200,7 +200,7 @@ int iwl_rx_queue_restock(struct iwl_priv *priv) | |||
200 | list_del(element); | 200 | list_del(element); |
201 | 201 | ||
202 | /* Point to Rx buffer via next RBD in circular buffer */ | 202 | /* Point to Rx buffer via next RBD in circular buffer */ |
203 | rxq->bd[rxq->write] = iwl_dma_addr2rbd_ptr(priv, rxb->aligned_dma_addr); | 203 | rxq->bd[rxq->write] = iwl_dma_addr2rbd_ptr(priv, rxb->page_dma); |
204 | rxq->queue[rxq->write] = rxb; | 204 | rxq->queue[rxq->write] = rxb; |
205 | rxq->write = (rxq->write + 1) & RX_QUEUE_MASK; | 205 | rxq->write = (rxq->write + 1) & RX_QUEUE_MASK; |
206 | rxq->free_count--; | 206 | rxq->free_count--; |
@@ -239,8 +239,9 @@ void iwl_rx_allocate(struct iwl_priv *priv, gfp_t priority) | |||
239 | struct iwl_rx_queue *rxq = &priv->rxq; | 239 | struct iwl_rx_queue *rxq = &priv->rxq; |
240 | struct list_head *element; | 240 | struct list_head *element; |
241 | struct iwl_rx_mem_buffer *rxb; | 241 | struct iwl_rx_mem_buffer *rxb; |
242 | struct sk_buff *skb; | 242 | struct page *page; |
243 | unsigned long flags; | 243 | unsigned long flags; |
244 | gfp_t gfp_mask = priority; | ||
244 | 245 | ||
245 | while (1) { | 246 | while (1) { |
246 | spin_lock_irqsave(&rxq->lock, flags); | 247 | spin_lock_irqsave(&rxq->lock, flags); |
@@ -251,30 +252,35 @@ void iwl_rx_allocate(struct iwl_priv *priv, gfp_t priority) | |||
251 | spin_unlock_irqrestore(&rxq->lock, flags); | 252 | spin_unlock_irqrestore(&rxq->lock, flags); |
252 | 253 | ||
253 | if (rxq->free_count > RX_LOW_WATERMARK) | 254 | if (rxq->free_count > RX_LOW_WATERMARK) |
254 | priority |= __GFP_NOWARN; | 255 | gfp_mask |= __GFP_NOWARN; |
255 | /* Alloc a new receive buffer */ | 256 | |
256 | skb = alloc_skb(priv->hw_params.rx_buf_size + 256, | 257 | if (priv->hw_params.rx_page_order > 0) |
257 | priority); | 258 | gfp_mask |= __GFP_COMP; |
258 | 259 | ||
259 | if (!skb) { | 260 | /* Alloc a new receive buffer */ |
261 | page = alloc_pages(gfp_mask, priv->hw_params.rx_page_order); | ||
262 | if (!page) { | ||
260 | if (net_ratelimit()) | 263 | if (net_ratelimit()) |
261 | IWL_DEBUG_INFO(priv, "Failed to allocate SKB buffer.\n"); | 264 | IWL_DEBUG_INFO(priv, "alloc_pages failed, " |
265 | "order: %d\n", | ||
266 | priv->hw_params.rx_page_order); | ||
267 | |||
262 | if ((rxq->free_count <= RX_LOW_WATERMARK) && | 268 | if ((rxq->free_count <= RX_LOW_WATERMARK) && |
263 | net_ratelimit()) | 269 | net_ratelimit()) |
264 | IWL_CRIT(priv, "Failed to allocate SKB buffer with %s. Only %u free buffers remaining.\n", | 270 | IWL_CRIT(priv, "Failed to alloc_pages with %s. Only %u free buffers remaining.\n", |
265 | priority == GFP_ATOMIC ? "GFP_ATOMIC" : "GFP_KERNEL", | 271 | priority == GFP_ATOMIC ? "GFP_ATOMIC" : "GFP_KERNEL", |
266 | rxq->free_count); | 272 | rxq->free_count); |
267 | /* We don't reschedule replenish work here -- we will | 273 | /* We don't reschedule replenish work here -- we will |
268 | * call the restock method and if it still needs | 274 | * call the restock method and if it still needs |
269 | * more buffers it will schedule replenish */ | 275 | * more buffers it will schedule replenish */ |
270 | break; | 276 | return; |
271 | } | 277 | } |
272 | 278 | ||
273 | spin_lock_irqsave(&rxq->lock, flags); | 279 | spin_lock_irqsave(&rxq->lock, flags); |
274 | 280 | ||
275 | if (list_empty(&rxq->rx_used)) { | 281 | if (list_empty(&rxq->rx_used)) { |
276 | spin_unlock_irqrestore(&rxq->lock, flags); | 282 | spin_unlock_irqrestore(&rxq->lock, flags); |
277 | dev_kfree_skb_any(skb); | 283 | __free_pages(page, priv->hw_params.rx_page_order); |
278 | return; | 284 | return; |
279 | } | 285 | } |
280 | element = rxq->rx_used.next; | 286 | element = rxq->rx_used.next; |
@@ -283,24 +289,21 @@ void iwl_rx_allocate(struct iwl_priv *priv, gfp_t priority) | |||
283 | 289 | ||
284 | spin_unlock_irqrestore(&rxq->lock, flags); | 290 | spin_unlock_irqrestore(&rxq->lock, flags); |
285 | 291 | ||
286 | rxb->skb = skb; | 292 | rxb->page = page; |
287 | /* Get physical address of RB/SKB */ | 293 | /* Get physical address of the RB */ |
288 | rxb->real_dma_addr = pci_map_single( | 294 | rxb->page_dma = pci_map_page(priv->pci_dev, page, 0, |
289 | priv->pci_dev, | 295 | PAGE_SIZE << priv->hw_params.rx_page_order, |
290 | rxb->skb->data, | 296 | PCI_DMA_FROMDEVICE); |
291 | priv->hw_params.rx_buf_size + 256, | ||
292 | PCI_DMA_FROMDEVICE); | ||
293 | /* dma address must be no more than 36 bits */ | 297 | /* dma address must be no more than 36 bits */ |
294 | BUG_ON(rxb->real_dma_addr & ~DMA_BIT_MASK(36)); | 298 | BUG_ON(rxb->page_dma & ~DMA_BIT_MASK(36)); |
295 | /* and also 256 byte aligned! */ | 299 | /* and also 256 byte aligned! */ |
296 | rxb->aligned_dma_addr = ALIGN(rxb->real_dma_addr, 256); | 300 | BUG_ON(rxb->page_dma & DMA_BIT_MASK(8)); |
297 | skb_reserve(rxb->skb, rxb->aligned_dma_addr - rxb->real_dma_addr); | ||
298 | 301 | ||
299 | spin_lock_irqsave(&rxq->lock, flags); | 302 | spin_lock_irqsave(&rxq->lock, flags); |
300 | 303 | ||
301 | list_add_tail(&rxb->list, &rxq->rx_free); | 304 | list_add_tail(&rxb->list, &rxq->rx_free); |
302 | rxq->free_count++; | 305 | rxq->free_count++; |
303 | priv->alloc_rxb_skb++; | 306 | priv->alloc_rxb_page++; |
304 | 307 | ||
305 | spin_unlock_irqrestore(&rxq->lock, flags); | 308 | spin_unlock_irqrestore(&rxq->lock, flags); |
306 | } | 309 | } |
@@ -336,12 +339,14 @@ void iwl_rx_queue_free(struct iwl_priv *priv, struct iwl_rx_queue *rxq) | |||
336 | { | 339 | { |
337 | int i; | 340 | int i; |
338 | for (i = 0; i < RX_QUEUE_SIZE + RX_FREE_BUFFERS; i++) { | 341 | for (i = 0; i < RX_QUEUE_SIZE + RX_FREE_BUFFERS; i++) { |
339 | if (rxq->pool[i].skb != NULL) { | 342 | if (rxq->pool[i].page != NULL) { |
340 | pci_unmap_single(priv->pci_dev, | 343 | pci_unmap_page(priv->pci_dev, rxq->pool[i].page_dma, |
341 | rxq->pool[i].real_dma_addr, | 344 | PAGE_SIZE << priv->hw_params.rx_page_order, |
342 | priv->hw_params.rx_buf_size + 256, | 345 | PCI_DMA_FROMDEVICE); |
343 | PCI_DMA_FROMDEVICE); | 346 | __free_pages(rxq->pool[i].page, |
344 | dev_kfree_skb(rxq->pool[i].skb); | 347 | priv->hw_params.rx_page_order); |
348 | rxq->pool[i].page = NULL; | ||
349 | priv->alloc_rxb_page--; | ||
345 | } | 350 | } |
346 | } | 351 | } |
347 | 352 | ||
@@ -405,14 +410,14 @@ void iwl_rx_queue_reset(struct iwl_priv *priv, struct iwl_rx_queue *rxq) | |||
405 | for (i = 0; i < RX_FREE_BUFFERS + RX_QUEUE_SIZE; i++) { | 410 | for (i = 0; i < RX_FREE_BUFFERS + RX_QUEUE_SIZE; i++) { |
406 | /* In the reset function, these buffers may have been allocated | 411 | /* In the reset function, these buffers may have been allocated |
407 | * to an SKB, so we need to unmap and free potential storage */ | 412 | * to an SKB, so we need to unmap and free potential storage */ |
408 | if (rxq->pool[i].skb != NULL) { | 413 | if (rxq->pool[i].page != NULL) { |
409 | pci_unmap_single(priv->pci_dev, | 414 | pci_unmap_page(priv->pci_dev, rxq->pool[i].page_dma, |
410 | rxq->pool[i].real_dma_addr, | 415 | PAGE_SIZE << priv->hw_params.rx_page_order, |
411 | priv->hw_params.rx_buf_size + 256, | 416 | PCI_DMA_FROMDEVICE); |
412 | PCI_DMA_FROMDEVICE); | 417 | priv->alloc_rxb_page--; |
413 | priv->alloc_rxb_skb--; | 418 | __free_pages(rxq->pool[i].page, |
414 | dev_kfree_skb(rxq->pool[i].skb); | 419 | priv->hw_params.rx_page_order); |
415 | rxq->pool[i].skb = NULL; | 420 | rxq->pool[i].page = NULL; |
416 | } | 421 | } |
417 | list_add_tail(&rxq->pool[i].list, &rxq->rx_used); | 422 | list_add_tail(&rxq->pool[i].list, &rxq->rx_used); |
418 | } | 423 | } |
@@ -491,7 +496,7 @@ void iwl_rx_missed_beacon_notif(struct iwl_priv *priv, | |||
491 | struct iwl_rx_mem_buffer *rxb) | 496 | struct iwl_rx_mem_buffer *rxb) |
492 | 497 | ||
493 | { | 498 | { |
494 | struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; | 499 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
495 | struct iwl_missed_beacon_notif *missed_beacon; | 500 | struct iwl_missed_beacon_notif *missed_beacon; |
496 | 501 | ||
497 | missed_beacon = &pkt->u.missed_beacon; | 502 | missed_beacon = &pkt->u.missed_beacon; |
@@ -548,13 +553,51 @@ static void iwl_rx_calc_noise(struct iwl_priv *priv) | |||
548 | priv->last_rx_noise); | 553 | priv->last_rx_noise); |
549 | } | 554 | } |
550 | 555 | ||
556 | #ifdef CONFIG_IWLWIFI_DEBUG | ||
557 | /* | ||
558 | * based on the assumption of all statistics counter are in DWORD | ||
559 | * FIXME: This function is for debugging, do not deal with | ||
560 | * the case of counters roll-over. | ||
561 | */ | ||
562 | static void iwl_accumulative_statistics(struct iwl_priv *priv, | ||
563 | __le32 *stats) | ||
564 | { | ||
565 | int i; | ||
566 | __le32 *prev_stats; | ||
567 | u32 *accum_stats; | ||
568 | |||
569 | prev_stats = (__le32 *)&priv->statistics; | ||
570 | accum_stats = (u32 *)&priv->accum_statistics; | ||
571 | |||
572 | for (i = sizeof(__le32); i < sizeof(struct iwl_notif_statistics); | ||
573 | i += sizeof(__le32), stats++, prev_stats++, accum_stats++) | ||
574 | if (le32_to_cpu(*stats) > le32_to_cpu(*prev_stats)) | ||
575 | *accum_stats += (le32_to_cpu(*stats) - | ||
576 | le32_to_cpu(*prev_stats)); | ||
577 | |||
578 | /* reset accumulative statistics for "no-counter" type statistics */ | ||
579 | priv->accum_statistics.general.temperature = | ||
580 | priv->statistics.general.temperature; | ||
581 | priv->accum_statistics.general.temperature_m = | ||
582 | priv->statistics.general.temperature_m; | ||
583 | priv->accum_statistics.general.ttl_timestamp = | ||
584 | priv->statistics.general.ttl_timestamp; | ||
585 | priv->accum_statistics.tx.tx_power.ant_a = | ||
586 | priv->statistics.tx.tx_power.ant_a; | ||
587 | priv->accum_statistics.tx.tx_power.ant_b = | ||
588 | priv->statistics.tx.tx_power.ant_b; | ||
589 | priv->accum_statistics.tx.tx_power.ant_c = | ||
590 | priv->statistics.tx.tx_power.ant_c; | ||
591 | } | ||
592 | #endif | ||
593 | |||
551 | #define REG_RECALIB_PERIOD (60) | 594 | #define REG_RECALIB_PERIOD (60) |
552 | 595 | ||
553 | void iwl_rx_statistics(struct iwl_priv *priv, | 596 | void iwl_rx_statistics(struct iwl_priv *priv, |
554 | struct iwl_rx_mem_buffer *rxb) | 597 | struct iwl_rx_mem_buffer *rxb) |
555 | { | 598 | { |
556 | int change; | 599 | int change; |
557 | struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; | 600 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
558 | 601 | ||
559 | IWL_DEBUG_RX(priv, "Statistics notification received (%d vs %d).\n", | 602 | IWL_DEBUG_RX(priv, "Statistics notification received (%d vs %d).\n", |
560 | (int)sizeof(priv->statistics), | 603 | (int)sizeof(priv->statistics), |
@@ -566,6 +609,9 @@ void iwl_rx_statistics(struct iwl_priv *priv, | |||
566 | STATISTICS_REPLY_FLG_HT40_MODE_MSK) != | 609 | STATISTICS_REPLY_FLG_HT40_MODE_MSK) != |
567 | (pkt->u.stats.flag & STATISTICS_REPLY_FLG_HT40_MODE_MSK))); | 610 | (pkt->u.stats.flag & STATISTICS_REPLY_FLG_HT40_MODE_MSK))); |
568 | 611 | ||
612 | #ifdef CONFIG_IWLWIFI_DEBUG | ||
613 | iwl_accumulative_statistics(priv, (__le32 *)&pkt->u.stats); | ||
614 | #endif | ||
569 | memcpy(&priv->statistics, &pkt->u.stats, sizeof(priv->statistics)); | 615 | memcpy(&priv->statistics, &pkt->u.stats, sizeof(priv->statistics)); |
570 | 616 | ||
571 | set_bit(STATUS_STATISTICS, &priv->status); | 617 | set_bit(STATUS_STATISTICS, &priv->status); |
@@ -582,9 +628,6 @@ void iwl_rx_statistics(struct iwl_priv *priv, | |||
582 | iwl_rx_calc_noise(priv); | 628 | iwl_rx_calc_noise(priv); |
583 | queue_work(priv->workqueue, &priv->run_time_calib_work); | 629 | queue_work(priv->workqueue, &priv->run_time_calib_work); |
584 | } | 630 | } |
585 | |||
586 | iwl_leds_background(priv); | ||
587 | |||
588 | if (priv->cfg->ops->lib->temp_ops.temperature && change) | 631 | if (priv->cfg->ops->lib->temp_ops.temperature && change) |
589 | priv->cfg->ops->lib->temp_ops.temperature(priv); | 632 | priv->cfg->ops->lib->temp_ops.temperature(priv); |
590 | } | 633 | } |
@@ -878,6 +921,10 @@ static void iwl_pass_packet_to_mac80211(struct iwl_priv *priv, | |||
878 | struct iwl_rx_mem_buffer *rxb, | 921 | struct iwl_rx_mem_buffer *rxb, |
879 | struct ieee80211_rx_status *stats) | 922 | struct ieee80211_rx_status *stats) |
880 | { | 923 | { |
924 | struct sk_buff *skb; | ||
925 | int ret = 0; | ||
926 | __le16 fc = hdr->frame_control; | ||
927 | |||
881 | /* We only process data packets if the interface is open */ | 928 | /* We only process data packets if the interface is open */ |
882 | if (unlikely(!priv->is_open)) { | 929 | if (unlikely(!priv->is_open)) { |
883 | IWL_DEBUG_DROP_LIMIT(priv, | 930 | IWL_DEBUG_DROP_LIMIT(priv, |
@@ -890,15 +937,43 @@ static void iwl_pass_packet_to_mac80211(struct iwl_priv *priv, | |||
890 | iwl_set_decrypted_flag(priv, hdr, ampdu_status, stats)) | 937 | iwl_set_decrypted_flag(priv, hdr, ampdu_status, stats)) |
891 | return; | 938 | return; |
892 | 939 | ||
893 | /* Resize SKB from mac header to end of packet */ | 940 | skb = alloc_skb(IWL_LINK_HDR_MAX, GFP_ATOMIC); |
894 | skb_reserve(rxb->skb, (void *)hdr - (void *)rxb->skb->data); | 941 | if (!skb) { |
895 | skb_put(rxb->skb, len); | 942 | IWL_ERR(priv, "alloc_skb failed\n"); |
943 | return; | ||
944 | } | ||
945 | |||
946 | skb_add_rx_frag(skb, 0, rxb->page, (void *)hdr - rxb_addr(rxb), len); | ||
947 | |||
948 | /* mac80211 currently doesn't support paged SKB. Convert it to | ||
949 | * linear SKB for management frame and data frame requires | ||
950 | * software decryption or software defragementation. */ | ||
951 | if (ieee80211_is_mgmt(fc) || | ||
952 | ieee80211_has_protected(fc) || | ||
953 | ieee80211_has_morefrags(fc) || | ||
954 | le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG) | ||
955 | ret = skb_linearize(skb); | ||
956 | else | ||
957 | ret = __pskb_pull_tail(skb, min_t(u16, IWL_LINK_HDR_MAX, len)) ? | ||
958 | 0 : -ENOMEM; | ||
959 | |||
960 | if (ret) { | ||
961 | kfree_skb(skb); | ||
962 | goto out; | ||
963 | } | ||
964 | |||
965 | /* | ||
966 | * XXX: We cannot touch the page and its virtual memory (hdr) after | ||
967 | * here. It might have already been freed by the above skb change. | ||
968 | */ | ||
969 | |||
970 | iwl_update_stats(priv, false, fc, len); | ||
971 | memcpy(IEEE80211_SKB_RXCB(skb), stats, sizeof(*stats)); | ||
896 | 972 | ||
897 | iwl_update_stats(priv, false, hdr->frame_control, len); | 973 | ieee80211_rx(priv->hw, skb); |
898 | memcpy(IEEE80211_SKB_RXCB(rxb->skb), stats, sizeof(*stats)); | 974 | out: |
899 | ieee80211_rx_irqsafe(priv->hw, rxb->skb); | 975 | priv->alloc_rxb_page--; |
900 | priv->alloc_rxb_skb--; | 976 | rxb->page = NULL; |
901 | rxb->skb = NULL; | ||
902 | } | 977 | } |
903 | 978 | ||
904 | /* This is necessary only for a number of statistics, see the caller. */ | 979 | /* This is necessary only for a number of statistics, see the caller. */ |
@@ -926,7 +1001,7 @@ void iwl_rx_reply_rx(struct iwl_priv *priv, | |||
926 | { | 1001 | { |
927 | struct ieee80211_hdr *header; | 1002 | struct ieee80211_hdr *header; |
928 | struct ieee80211_rx_status rx_status; | 1003 | struct ieee80211_rx_status rx_status; |
929 | struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; | 1004 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
930 | struct iwl_rx_phy_res *phy_res; | 1005 | struct iwl_rx_phy_res *phy_res; |
931 | __le32 rx_pkt_status; | 1006 | __le32 rx_pkt_status; |
932 | struct iwl4965_rx_mpdu_res_start *amsdu; | 1007 | struct iwl4965_rx_mpdu_res_start *amsdu; |
@@ -1087,7 +1162,7 @@ EXPORT_SYMBOL(iwl_rx_reply_rx); | |||
1087 | void iwl_rx_reply_rx_phy(struct iwl_priv *priv, | 1162 | void iwl_rx_reply_rx_phy(struct iwl_priv *priv, |
1088 | struct iwl_rx_mem_buffer *rxb) | 1163 | struct iwl_rx_mem_buffer *rxb) |
1089 | { | 1164 | { |
1090 | struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; | 1165 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
1091 | priv->last_phy_res[0] = 1; | 1166 | priv->last_phy_res[0] = 1; |
1092 | memcpy(&priv->last_phy_res[1], &(pkt->u.raw[0]), | 1167 | memcpy(&priv->last_phy_res[1], &(pkt->u.raw[0]), |
1093 | sizeof(struct iwl_rx_phy_res)); | 1168 | sizeof(struct iwl_rx_phy_res)); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c index 41f9a0621250..4fca65a2fe9c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-scan.c +++ b/drivers/net/wireless/iwlwifi/iwl-scan.c | |||
@@ -111,7 +111,7 @@ EXPORT_SYMBOL(iwl_scan_cancel_timeout); | |||
111 | static int iwl_send_scan_abort(struct iwl_priv *priv) | 111 | static int iwl_send_scan_abort(struct iwl_priv *priv) |
112 | { | 112 | { |
113 | int ret = 0; | 113 | int ret = 0; |
114 | struct iwl_rx_packet *res; | 114 | struct iwl_rx_packet *pkt; |
115 | struct iwl_host_cmd cmd = { | 115 | struct iwl_host_cmd cmd = { |
116 | .id = REPLY_SCAN_ABORT_CMD, | 116 | .id = REPLY_SCAN_ABORT_CMD, |
117 | .flags = CMD_WANT_SKB, | 117 | .flags = CMD_WANT_SKB, |
@@ -131,21 +131,21 @@ static int iwl_send_scan_abort(struct iwl_priv *priv) | |||
131 | return ret; | 131 | return ret; |
132 | } | 132 | } |
133 | 133 | ||
134 | res = (struct iwl_rx_packet *)cmd.reply_skb->data; | 134 | pkt = (struct iwl_rx_packet *)cmd.reply_page; |
135 | if (res->u.status != CAN_ABORT_STATUS) { | 135 | if (pkt->u.status != CAN_ABORT_STATUS) { |
136 | /* The scan abort will return 1 for success or | 136 | /* The scan abort will return 1 for success or |
137 | * 2 for "failure". A failure condition can be | 137 | * 2 for "failure". A failure condition can be |
138 | * due to simply not being in an active scan which | 138 | * due to simply not being in an active scan which |
139 | * can occur if we send the scan abort before we | 139 | * can occur if we send the scan abort before we |
140 | * the microcode has notified us that a scan is | 140 | * the microcode has notified us that a scan is |
141 | * completed. */ | 141 | * completed. */ |
142 | IWL_DEBUG_INFO(priv, "SCAN_ABORT returned %d.\n", res->u.status); | 142 | IWL_DEBUG_INFO(priv, "SCAN_ABORT returned %d.\n", pkt->u.status); |
143 | clear_bit(STATUS_SCAN_ABORTING, &priv->status); | 143 | clear_bit(STATUS_SCAN_ABORTING, &priv->status); |
144 | clear_bit(STATUS_SCAN_HW, &priv->status); | 144 | clear_bit(STATUS_SCAN_HW, &priv->status); |
145 | } | 145 | } |
146 | 146 | ||
147 | priv->alloc_rxb_skb--; | 147 | priv->alloc_rxb_page--; |
148 | dev_kfree_skb_any(cmd.reply_skb); | 148 | free_pages(cmd.reply_page, priv->hw_params.rx_page_order); |
149 | 149 | ||
150 | return ret; | 150 | return ret; |
151 | } | 151 | } |
@@ -155,7 +155,7 @@ static void iwl_rx_reply_scan(struct iwl_priv *priv, | |||
155 | struct iwl_rx_mem_buffer *rxb) | 155 | struct iwl_rx_mem_buffer *rxb) |
156 | { | 156 | { |
157 | #ifdef CONFIG_IWLWIFI_DEBUG | 157 | #ifdef CONFIG_IWLWIFI_DEBUG |
158 | struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; | 158 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
159 | struct iwl_scanreq_notification *notif = | 159 | struct iwl_scanreq_notification *notif = |
160 | (struct iwl_scanreq_notification *)pkt->u.raw; | 160 | (struct iwl_scanreq_notification *)pkt->u.raw; |
161 | 161 | ||
@@ -167,7 +167,7 @@ static void iwl_rx_reply_scan(struct iwl_priv *priv, | |||
167 | static void iwl_rx_scan_start_notif(struct iwl_priv *priv, | 167 | static void iwl_rx_scan_start_notif(struct iwl_priv *priv, |
168 | struct iwl_rx_mem_buffer *rxb) | 168 | struct iwl_rx_mem_buffer *rxb) |
169 | { | 169 | { |
170 | struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; | 170 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
171 | struct iwl_scanstart_notification *notif = | 171 | struct iwl_scanstart_notification *notif = |
172 | (struct iwl_scanstart_notification *)pkt->u.raw; | 172 | (struct iwl_scanstart_notification *)pkt->u.raw; |
173 | priv->scan_start_tsf = le32_to_cpu(notif->tsf_low); | 173 | priv->scan_start_tsf = le32_to_cpu(notif->tsf_low); |
@@ -186,7 +186,7 @@ static void iwl_rx_scan_results_notif(struct iwl_priv *priv, | |||
186 | struct iwl_rx_mem_buffer *rxb) | 186 | struct iwl_rx_mem_buffer *rxb) |
187 | { | 187 | { |
188 | #ifdef CONFIG_IWLWIFI_DEBUG | 188 | #ifdef CONFIG_IWLWIFI_DEBUG |
189 | struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; | 189 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
190 | struct iwl_scanresults_notification *notif = | 190 | struct iwl_scanresults_notification *notif = |
191 | (struct iwl_scanresults_notification *)pkt->u.raw; | 191 | (struct iwl_scanresults_notification *)pkt->u.raw; |
192 | 192 | ||
@@ -213,7 +213,7 @@ static void iwl_rx_scan_complete_notif(struct iwl_priv *priv, | |||
213 | struct iwl_rx_mem_buffer *rxb) | 213 | struct iwl_rx_mem_buffer *rxb) |
214 | { | 214 | { |
215 | #ifdef CONFIG_IWLWIFI_DEBUG | 215 | #ifdef CONFIG_IWLWIFI_DEBUG |
216 | struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; | 216 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
217 | struct iwl_scancomplete_notification *scan_notif = (void *)pkt->u.raw; | 217 | struct iwl_scancomplete_notification *scan_notif = (void *)pkt->u.raw; |
218 | 218 | ||
219 | IWL_DEBUG_SCAN(priv, "Scan complete: %d channels (TSF 0x%08X:%08X) - %d\n", | 219 | IWL_DEBUG_SCAN(priv, "Scan complete: %d channels (TSF 0x%08X:%08X) - %d\n", |
diff --git a/drivers/net/wireless/iwlwifi/iwl-spectrum.c b/drivers/net/wireless/iwlwifi/iwl-spectrum.c index 022bcf115731..1ea5cd345fe8 100644 --- a/drivers/net/wireless/iwlwifi/iwl-spectrum.c +++ b/drivers/net/wireless/iwlwifi/iwl-spectrum.c | |||
@@ -177,7 +177,7 @@ static int iwl_get_measurement(struct iwl_priv *priv, | |||
177 | static void iwl_rx_spectrum_measure_notif(struct iwl_priv *priv, | 177 | static void iwl_rx_spectrum_measure_notif(struct iwl_priv *priv, |
178 | struct iwl_rx_mem_buffer *rxb) | 178 | struct iwl_rx_mem_buffer *rxb) |
179 | { | 179 | { |
180 | struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; | 180 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
181 | struct iwl_spectrum_notification *report = &(pkt->u.spectrum_notif); | 181 | struct iwl_spectrum_notification *report = &(pkt->u.spectrum_notif); |
182 | 182 | ||
183 | if (!report->state) { | 183 | if (!report->state) { |
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c index c6633fec8216..dc74c16d36a8 100644 --- a/drivers/net/wireless/iwlwifi/iwl-sta.c +++ b/drivers/net/wireless/iwlwifi/iwl-sta.c | |||
@@ -99,32 +99,25 @@ static void iwl_sta_ucode_activate(struct iwl_priv *priv, u8 sta_id) | |||
99 | 99 | ||
100 | static void iwl_add_sta_callback(struct iwl_priv *priv, | 100 | static void iwl_add_sta_callback(struct iwl_priv *priv, |
101 | struct iwl_device_cmd *cmd, | 101 | struct iwl_device_cmd *cmd, |
102 | struct sk_buff *skb) | 102 | struct iwl_rx_packet *pkt) |
103 | { | 103 | { |
104 | struct iwl_rx_packet *res = NULL; | ||
105 | struct iwl_addsta_cmd *addsta = | 104 | struct iwl_addsta_cmd *addsta = |
106 | (struct iwl_addsta_cmd *)cmd->cmd.payload; | 105 | (struct iwl_addsta_cmd *)cmd->cmd.payload; |
107 | u8 sta_id = addsta->sta.sta_id; | 106 | u8 sta_id = addsta->sta.sta_id; |
108 | 107 | ||
109 | if (!skb) { | 108 | if (pkt->hdr.flags & IWL_CMD_FAILED_MSK) { |
110 | IWL_ERR(priv, "Error: Response NULL in REPLY_ADD_STA.\n"); | ||
111 | return; | ||
112 | } | ||
113 | |||
114 | res = (struct iwl_rx_packet *)skb->data; | ||
115 | if (res->hdr.flags & IWL_CMD_FAILED_MSK) { | ||
116 | IWL_ERR(priv, "Bad return from REPLY_ADD_STA (0x%08X)\n", | 109 | IWL_ERR(priv, "Bad return from REPLY_ADD_STA (0x%08X)\n", |
117 | res->hdr.flags); | 110 | pkt->hdr.flags); |
118 | return; | 111 | return; |
119 | } | 112 | } |
120 | 113 | ||
121 | switch (res->u.add_sta.status) { | 114 | switch (pkt->u.add_sta.status) { |
122 | case ADD_STA_SUCCESS_MSK: | 115 | case ADD_STA_SUCCESS_MSK: |
123 | iwl_sta_ucode_activate(priv, sta_id); | 116 | iwl_sta_ucode_activate(priv, sta_id); |
124 | /* fall through */ | 117 | /* fall through */ |
125 | default: | 118 | default: |
126 | IWL_DEBUG_HC(priv, "Received REPLY_ADD_STA:(0x%08X)\n", | 119 | IWL_DEBUG_HC(priv, "Received REPLY_ADD_STA:(0x%08X)\n", |
127 | res->u.add_sta.status); | 120 | pkt->u.add_sta.status); |
128 | break; | 121 | break; |
129 | } | 122 | } |
130 | } | 123 | } |
@@ -132,7 +125,7 @@ static void iwl_add_sta_callback(struct iwl_priv *priv, | |||
132 | int iwl_send_add_sta(struct iwl_priv *priv, | 125 | int iwl_send_add_sta(struct iwl_priv *priv, |
133 | struct iwl_addsta_cmd *sta, u8 flags) | 126 | struct iwl_addsta_cmd *sta, u8 flags) |
134 | { | 127 | { |
135 | struct iwl_rx_packet *res = NULL; | 128 | struct iwl_rx_packet *pkt = NULL; |
136 | int ret = 0; | 129 | int ret = 0; |
137 | u8 data[sizeof(*sta)]; | 130 | u8 data[sizeof(*sta)]; |
138 | struct iwl_host_cmd cmd = { | 131 | struct iwl_host_cmd cmd = { |
@@ -152,15 +145,15 @@ int iwl_send_add_sta(struct iwl_priv *priv, | |||
152 | if (ret || (flags & CMD_ASYNC)) | 145 | if (ret || (flags & CMD_ASYNC)) |
153 | return ret; | 146 | return ret; |
154 | 147 | ||
155 | res = (struct iwl_rx_packet *)cmd.reply_skb->data; | 148 | pkt = (struct iwl_rx_packet *)cmd.reply_page; |
156 | if (res->hdr.flags & IWL_CMD_FAILED_MSK) { | 149 | if (pkt->hdr.flags & IWL_CMD_FAILED_MSK) { |
157 | IWL_ERR(priv, "Bad return from REPLY_ADD_STA (0x%08X)\n", | 150 | IWL_ERR(priv, "Bad return from REPLY_ADD_STA (0x%08X)\n", |
158 | res->hdr.flags); | 151 | pkt->hdr.flags); |
159 | ret = -EIO; | 152 | ret = -EIO; |
160 | } | 153 | } |
161 | 154 | ||
162 | if (ret == 0) { | 155 | if (ret == 0) { |
163 | switch (res->u.add_sta.status) { | 156 | switch (pkt->u.add_sta.status) { |
164 | case ADD_STA_SUCCESS_MSK: | 157 | case ADD_STA_SUCCESS_MSK: |
165 | iwl_sta_ucode_activate(priv, sta->sta.sta_id); | 158 | iwl_sta_ucode_activate(priv, sta->sta.sta_id); |
166 | IWL_DEBUG_INFO(priv, "REPLY_ADD_STA PASSED\n"); | 159 | IWL_DEBUG_INFO(priv, "REPLY_ADD_STA PASSED\n"); |
@@ -172,8 +165,8 @@ int iwl_send_add_sta(struct iwl_priv *priv, | |||
172 | } | 165 | } |
173 | } | 166 | } |
174 | 167 | ||
175 | priv->alloc_rxb_skb--; | 168 | priv->alloc_rxb_page--; |
176 | dev_kfree_skb_any(cmd.reply_skb); | 169 | free_pages(cmd.reply_page, priv->hw_params.rx_page_order); |
177 | 170 | ||
178 | return ret; | 171 | return ret; |
179 | } | 172 | } |
@@ -324,26 +317,19 @@ static void iwl_sta_ucode_deactivate(struct iwl_priv *priv, const char *addr) | |||
324 | 317 | ||
325 | static void iwl_remove_sta_callback(struct iwl_priv *priv, | 318 | static void iwl_remove_sta_callback(struct iwl_priv *priv, |
326 | struct iwl_device_cmd *cmd, | 319 | struct iwl_device_cmd *cmd, |
327 | struct sk_buff *skb) | 320 | struct iwl_rx_packet *pkt) |
328 | { | 321 | { |
329 | struct iwl_rx_packet *res = NULL; | ||
330 | struct iwl_rem_sta_cmd *rm_sta = | 322 | struct iwl_rem_sta_cmd *rm_sta = |
331 | (struct iwl_rem_sta_cmd *)cmd->cmd.payload; | 323 | (struct iwl_rem_sta_cmd *)cmd->cmd.payload; |
332 | const char *addr = rm_sta->addr; | 324 | const char *addr = rm_sta->addr; |
333 | 325 | ||
334 | if (!skb) { | 326 | if (pkt->hdr.flags & IWL_CMD_FAILED_MSK) { |
335 | IWL_ERR(priv, "Error: Response NULL in REPLY_REMOVE_STA.\n"); | ||
336 | return; | ||
337 | } | ||
338 | |||
339 | res = (struct iwl_rx_packet *)skb->data; | ||
340 | if (res->hdr.flags & IWL_CMD_FAILED_MSK) { | ||
341 | IWL_ERR(priv, "Bad return from REPLY_REMOVE_STA (0x%08X)\n", | 327 | IWL_ERR(priv, "Bad return from REPLY_REMOVE_STA (0x%08X)\n", |
342 | res->hdr.flags); | 328 | pkt->hdr.flags); |
343 | return; | 329 | return; |
344 | } | 330 | } |
345 | 331 | ||
346 | switch (res->u.rem_sta.status) { | 332 | switch (pkt->u.rem_sta.status) { |
347 | case REM_STA_SUCCESS_MSK: | 333 | case REM_STA_SUCCESS_MSK: |
348 | iwl_sta_ucode_deactivate(priv, addr); | 334 | iwl_sta_ucode_deactivate(priv, addr); |
349 | break; | 335 | break; |
@@ -356,7 +342,7 @@ static void iwl_remove_sta_callback(struct iwl_priv *priv, | |||
356 | static int iwl_send_remove_station(struct iwl_priv *priv, const u8 *addr, | 342 | static int iwl_send_remove_station(struct iwl_priv *priv, const u8 *addr, |
357 | u8 flags) | 343 | u8 flags) |
358 | { | 344 | { |
359 | struct iwl_rx_packet *res = NULL; | 345 | struct iwl_rx_packet *pkt; |
360 | int ret; | 346 | int ret; |
361 | 347 | ||
362 | struct iwl_rem_sta_cmd rm_sta_cmd; | 348 | struct iwl_rem_sta_cmd rm_sta_cmd; |
@@ -381,15 +367,15 @@ static int iwl_send_remove_station(struct iwl_priv *priv, const u8 *addr, | |||
381 | if (ret || (flags & CMD_ASYNC)) | 367 | if (ret || (flags & CMD_ASYNC)) |
382 | return ret; | 368 | return ret; |
383 | 369 | ||
384 | res = (struct iwl_rx_packet *)cmd.reply_skb->data; | 370 | pkt = (struct iwl_rx_packet *)cmd.reply_page; |
385 | if (res->hdr.flags & IWL_CMD_FAILED_MSK) { | 371 | if (pkt->hdr.flags & IWL_CMD_FAILED_MSK) { |
386 | IWL_ERR(priv, "Bad return from REPLY_REMOVE_STA (0x%08X)\n", | 372 | IWL_ERR(priv, "Bad return from REPLY_REMOVE_STA (0x%08X)\n", |
387 | res->hdr.flags); | 373 | pkt->hdr.flags); |
388 | ret = -EIO; | 374 | ret = -EIO; |
389 | } | 375 | } |
390 | 376 | ||
391 | if (!ret) { | 377 | if (!ret) { |
392 | switch (res->u.rem_sta.status) { | 378 | switch (pkt->u.rem_sta.status) { |
393 | case REM_STA_SUCCESS_MSK: | 379 | case REM_STA_SUCCESS_MSK: |
394 | iwl_sta_ucode_deactivate(priv, addr); | 380 | iwl_sta_ucode_deactivate(priv, addr); |
395 | IWL_DEBUG_ASSOC(priv, "REPLY_REMOVE_STA PASSED\n"); | 381 | IWL_DEBUG_ASSOC(priv, "REPLY_REMOVE_STA PASSED\n"); |
@@ -401,8 +387,8 @@ static int iwl_send_remove_station(struct iwl_priv *priv, const u8 *addr, | |||
401 | } | 387 | } |
402 | } | 388 | } |
403 | 389 | ||
404 | priv->alloc_rxb_skb--; | 390 | priv->alloc_rxb_page--; |
405 | dev_kfree_skb_any(cmd.reply_skb); | 391 | free_pages(cmd.reply_page, priv->hw_params.rx_page_order); |
406 | 392 | ||
407 | return ret; | 393 | return ret; |
408 | } | 394 | } |
diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c index c832ba085dba..8ae4c9b614e7 100644 --- a/drivers/net/wireless/iwlwifi/iwl-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-tx.c | |||
@@ -131,7 +131,7 @@ void iwl_tx_queue_free(struct iwl_priv *priv, int txq_id) | |||
131 | struct iwl_tx_queue *txq = &priv->txq[txq_id]; | 131 | struct iwl_tx_queue *txq = &priv->txq[txq_id]; |
132 | struct iwl_queue *q = &txq->q; | 132 | struct iwl_queue *q = &txq->q; |
133 | struct pci_dev *dev = priv->pci_dev; | 133 | struct pci_dev *dev = priv->pci_dev; |
134 | int i, len; | 134 | int i; |
135 | 135 | ||
136 | if (q->n_bd == 0) | 136 | if (q->n_bd == 0) |
137 | return; | 137 | return; |
@@ -141,8 +141,6 @@ void iwl_tx_queue_free(struct iwl_priv *priv, int txq_id) | |||
141 | q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd)) | 141 | q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd)) |
142 | priv->cfg->ops->lib->txq_free_tfd(priv, txq); | 142 | priv->cfg->ops->lib->txq_free_tfd(priv, txq); |
143 | 143 | ||
144 | len = sizeof(struct iwl_device_cmd) * q->n_window; | ||
145 | |||
146 | /* De-alloc array of command/tx buffers */ | 144 | /* De-alloc array of command/tx buffers */ |
147 | for (i = 0; i < TFD_TX_CMD_SLOTS; i++) | 145 | for (i = 0; i < TFD_TX_CMD_SLOTS; i++) |
148 | kfree(txq->cmd[i]); | 146 | kfree(txq->cmd[i]); |
@@ -180,14 +178,11 @@ void iwl_cmd_queue_free(struct iwl_priv *priv) | |||
180 | struct iwl_tx_queue *txq = &priv->txq[IWL_CMD_QUEUE_NUM]; | 178 | struct iwl_tx_queue *txq = &priv->txq[IWL_CMD_QUEUE_NUM]; |
181 | struct iwl_queue *q = &txq->q; | 179 | struct iwl_queue *q = &txq->q; |
182 | struct pci_dev *dev = priv->pci_dev; | 180 | struct pci_dev *dev = priv->pci_dev; |
183 | int i, len; | 181 | int i; |
184 | 182 | ||
185 | if (q->n_bd == 0) | 183 | if (q->n_bd == 0) |
186 | return; | 184 | return; |
187 | 185 | ||
188 | len = sizeof(struct iwl_device_cmd) * q->n_window; | ||
189 | len += IWL_MAX_SCAN_SIZE; | ||
190 | |||
191 | /* De-alloc array of command/tx buffers */ | 186 | /* De-alloc array of command/tx buffers */ |
192 | for (i = 0; i <= TFD_CMD_SLOTS; i++) | 187 | for (i = 0; i <= TFD_CMD_SLOTS; i++) |
193 | kfree(txq->cmd[i]); | 188 | kfree(txq->cmd[i]); |
@@ -405,15 +400,19 @@ void iwl_hw_txq_ctx_free(struct iwl_priv *priv) | |||
405 | int txq_id; | 400 | int txq_id; |
406 | 401 | ||
407 | /* Tx queues */ | 402 | /* Tx queues */ |
408 | for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++) | 403 | if (priv->txq) |
409 | if (txq_id == IWL_CMD_QUEUE_NUM) | 404 | for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; |
410 | iwl_cmd_queue_free(priv); | 405 | txq_id++) |
411 | else | 406 | if (txq_id == IWL_CMD_QUEUE_NUM) |
412 | iwl_tx_queue_free(priv, txq_id); | 407 | iwl_cmd_queue_free(priv); |
413 | 408 | else | |
409 | iwl_tx_queue_free(priv, txq_id); | ||
414 | iwl_free_dma_ptr(priv, &priv->kw); | 410 | iwl_free_dma_ptr(priv, &priv->kw); |
415 | 411 | ||
416 | iwl_free_dma_ptr(priv, &priv->scd_bc_tbls); | 412 | iwl_free_dma_ptr(priv, &priv->scd_bc_tbls); |
413 | |||
414 | /* free tx queue structure */ | ||
415 | iwl_free_txq_mem(priv); | ||
417 | } | 416 | } |
418 | EXPORT_SYMBOL(iwl_hw_txq_ctx_free); | 417 | EXPORT_SYMBOL(iwl_hw_txq_ctx_free); |
419 | 418 | ||
@@ -445,6 +444,12 @@ int iwl_txq_ctx_reset(struct iwl_priv *priv) | |||
445 | IWL_ERR(priv, "Keep Warm allocation failed\n"); | 444 | IWL_ERR(priv, "Keep Warm allocation failed\n"); |
446 | goto error_kw; | 445 | goto error_kw; |
447 | } | 446 | } |
447 | |||
448 | /* allocate tx queue structure */ | ||
449 | ret = iwl_alloc_txq_mem(priv); | ||
450 | if (ret) | ||
451 | goto error; | ||
452 | |||
448 | spin_lock_irqsave(&priv->lock, flags); | 453 | spin_lock_irqsave(&priv->lock, flags); |
449 | 454 | ||
450 | /* Turn off all Tx DMA fifos */ | 455 | /* Turn off all Tx DMA fifos */ |
@@ -581,9 +586,7 @@ static void iwl_tx_cmd_build_rate(struct iwl_priv *priv, | |||
581 | u8 rate_plcp; | 586 | u8 rate_plcp; |
582 | 587 | ||
583 | /* Set retry limit on DATA packets and Probe Responses*/ | 588 | /* Set retry limit on DATA packets and Probe Responses*/ |
584 | if (priv->data_retry_limit != -1) | 589 | if (ieee80211_is_probe_resp(fc)) |
585 | data_retry_limit = priv->data_retry_limit; | ||
586 | else if (ieee80211_is_probe_resp(fc)) | ||
587 | data_retry_limit = 3; | 590 | data_retry_limit = 3; |
588 | else | 591 | else |
589 | data_retry_limit = IWL_DEFAULT_TX_RETRY; | 592 | data_retry_limit = IWL_DEFAULT_TX_RETRY; |
@@ -1145,7 +1148,7 @@ static void iwl_hcmd_queue_reclaim(struct iwl_priv *priv, int txq_id, | |||
1145 | */ | 1148 | */ |
1146 | void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) | 1149 | void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) |
1147 | { | 1150 | { |
1148 | struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; | 1151 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
1149 | u16 sequence = le16_to_cpu(pkt->hdr.sequence); | 1152 | u16 sequence = le16_to_cpu(pkt->hdr.sequence); |
1150 | int txq_id = SEQ_TO_QUEUE(sequence); | 1153 | int txq_id = SEQ_TO_QUEUE(sequence); |
1151 | int index = SEQ_TO_INDEX(sequence); | 1154 | int index = SEQ_TO_INDEX(sequence); |
@@ -1172,10 +1175,10 @@ void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) | |||
1172 | 1175 | ||
1173 | /* Input error checking is done when commands are added to queue. */ | 1176 | /* Input error checking is done when commands are added to queue. */ |
1174 | if (meta->flags & CMD_WANT_SKB) { | 1177 | if (meta->flags & CMD_WANT_SKB) { |
1175 | meta->source->reply_skb = rxb->skb; | 1178 | meta->source->reply_page = (unsigned long)rxb_addr(rxb); |
1176 | rxb->skb = NULL; | 1179 | rxb->page = NULL; |
1177 | } else if (meta->callback) | 1180 | } else if (meta->callback) |
1178 | meta->callback(priv, cmd, rxb->skb); | 1181 | meta->callback(priv, cmd, pkt); |
1179 | 1182 | ||
1180 | iwl_hcmd_queue_reclaim(priv, txq_id, index, cmd_index); | 1183 | iwl_hcmd_queue_reclaim(priv, txq_id, index, cmd_index); |
1181 | 1184 | ||
@@ -1434,7 +1437,7 @@ static int iwl_tx_status_reply_compressed_ba(struct iwl_priv *priv, | |||
1434 | void iwl_rx_reply_compressed_ba(struct iwl_priv *priv, | 1437 | void iwl_rx_reply_compressed_ba(struct iwl_priv *priv, |
1435 | struct iwl_rx_mem_buffer *rxb) | 1438 | struct iwl_rx_mem_buffer *rxb) |
1436 | { | 1439 | { |
1437 | struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; | 1440 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
1438 | struct iwl_compressed_ba_resp *ba_resp = &pkt->u.compressed_ba; | 1441 | struct iwl_compressed_ba_resp *ba_resp = &pkt->u.compressed_ba; |
1439 | struct iwl_tx_queue *txq = NULL; | 1442 | struct iwl_tx_queue *txq = NULL; |
1440 | struct iwl_ht_agg *agg; | 1443 | struct iwl_ht_agg *agg; |
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index c347d6631d85..bfd7f497157f 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c | |||
@@ -88,7 +88,6 @@ MODULE_LICENSE("GPL"); | |||
88 | 88 | ||
89 | /* module parameters */ | 89 | /* module parameters */ |
90 | struct iwl_mod_params iwl3945_mod_params = { | 90 | struct iwl_mod_params iwl3945_mod_params = { |
91 | .num_of_queues = IWL39_NUM_QUEUES, /* Not used */ | ||
92 | .sw_crypto = 1, | 91 | .sw_crypto = 1, |
93 | .restart_fw = 1, | 92 | .restart_fw = 1, |
94 | /* the rest are 0 by default */ | 93 | /* the rest are 0 by default */ |
@@ -366,13 +365,13 @@ static void iwl3945_build_tx_cmd_hwcrypto(struct iwl_priv *priv, | |||
366 | struct sk_buff *skb_frag, | 365 | struct sk_buff *skb_frag, |
367 | int sta_id) | 366 | int sta_id) |
368 | { | 367 | { |
369 | struct iwl3945_tx_cmd *tx = (struct iwl3945_tx_cmd *)cmd->cmd.payload; | 368 | struct iwl3945_tx_cmd *tx_cmd = (struct iwl3945_tx_cmd *)cmd->cmd.payload; |
370 | struct iwl_hw_key *keyinfo = &priv->stations[sta_id].keyinfo; | 369 | struct iwl_hw_key *keyinfo = &priv->stations[sta_id].keyinfo; |
371 | 370 | ||
372 | switch (keyinfo->alg) { | 371 | switch (keyinfo->alg) { |
373 | case ALG_CCMP: | 372 | case ALG_CCMP: |
374 | tx->sec_ctl = TX_CMD_SEC_CCM; | 373 | tx_cmd->sec_ctl = TX_CMD_SEC_CCM; |
375 | memcpy(tx->key, keyinfo->key, keyinfo->keylen); | 374 | memcpy(tx_cmd->key, keyinfo->key, keyinfo->keylen); |
376 | IWL_DEBUG_TX(priv, "tx_cmd with AES hwcrypto\n"); | 375 | IWL_DEBUG_TX(priv, "tx_cmd with AES hwcrypto\n"); |
377 | break; | 376 | break; |
378 | 377 | ||
@@ -380,13 +379,13 @@ static void iwl3945_build_tx_cmd_hwcrypto(struct iwl_priv *priv, | |||
380 | break; | 379 | break; |
381 | 380 | ||
382 | case ALG_WEP: | 381 | case ALG_WEP: |
383 | tx->sec_ctl = TX_CMD_SEC_WEP | | 382 | tx_cmd->sec_ctl = TX_CMD_SEC_WEP | |
384 | (info->control.hw_key->hw_key_idx & TX_CMD_SEC_MSK) << TX_CMD_SEC_SHIFT; | 383 | (info->control.hw_key->hw_key_idx & TX_CMD_SEC_MSK) << TX_CMD_SEC_SHIFT; |
385 | 384 | ||
386 | if (keyinfo->keylen == 13) | 385 | if (keyinfo->keylen == 13) |
387 | tx->sec_ctl |= TX_CMD_SEC_KEY128; | 386 | tx_cmd->sec_ctl |= TX_CMD_SEC_KEY128; |
388 | 387 | ||
389 | memcpy(&tx->key[3], keyinfo->key, keyinfo->keylen); | 388 | memcpy(&tx_cmd->key[3], keyinfo->key, keyinfo->keylen); |
390 | 389 | ||
391 | IWL_DEBUG_TX(priv, "Configuring packet for WEP encryption " | 390 | IWL_DEBUG_TX(priv, "Configuring packet for WEP encryption " |
392 | "with key %d\n", info->control.hw_key->hw_key_idx); | 391 | "with key %d\n", info->control.hw_key->hw_key_idx); |
@@ -406,12 +405,11 @@ static void iwl3945_build_tx_cmd_basic(struct iwl_priv *priv, | |||
406 | struct ieee80211_tx_info *info, | 405 | struct ieee80211_tx_info *info, |
407 | struct ieee80211_hdr *hdr, u8 std_id) | 406 | struct ieee80211_hdr *hdr, u8 std_id) |
408 | { | 407 | { |
409 | struct iwl3945_tx_cmd *tx = (struct iwl3945_tx_cmd *)cmd->cmd.payload; | 408 | struct iwl3945_tx_cmd *tx_cmd = (struct iwl3945_tx_cmd *)cmd->cmd.payload; |
410 | __le32 tx_flags = tx->tx_flags; | 409 | __le32 tx_flags = tx_cmd->tx_flags; |
411 | __le16 fc = hdr->frame_control; | 410 | __le16 fc = hdr->frame_control; |
412 | u8 rc_flags = info->control.rates[0].flags; | ||
413 | 411 | ||
414 | tx->stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE; | 412 | tx_cmd->stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE; |
415 | if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) { | 413 | if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) { |
416 | tx_flags |= TX_CMD_FLG_ACK_MSK; | 414 | tx_flags |= TX_CMD_FLG_ACK_MSK; |
417 | if (ieee80211_is_mgmt(fc)) | 415 | if (ieee80211_is_mgmt(fc)) |
@@ -424,25 +422,19 @@ static void iwl3945_build_tx_cmd_basic(struct iwl_priv *priv, | |||
424 | tx_flags |= TX_CMD_FLG_SEQ_CTL_MSK; | 422 | tx_flags |= TX_CMD_FLG_SEQ_CTL_MSK; |
425 | } | 423 | } |
426 | 424 | ||
427 | tx->sta_id = std_id; | 425 | tx_cmd->sta_id = std_id; |
428 | if (ieee80211_has_morefrags(fc)) | 426 | if (ieee80211_has_morefrags(fc)) |
429 | tx_flags |= TX_CMD_FLG_MORE_FRAG_MSK; | 427 | tx_flags |= TX_CMD_FLG_MORE_FRAG_MSK; |
430 | 428 | ||
431 | if (ieee80211_is_data_qos(fc)) { | 429 | if (ieee80211_is_data_qos(fc)) { |
432 | u8 *qc = ieee80211_get_qos_ctl(hdr); | 430 | u8 *qc = ieee80211_get_qos_ctl(hdr); |
433 | tx->tid_tspec = qc[0] & 0xf; | 431 | tx_cmd->tid_tspec = qc[0] & 0xf; |
434 | tx_flags &= ~TX_CMD_FLG_SEQ_CTL_MSK; | 432 | tx_flags &= ~TX_CMD_FLG_SEQ_CTL_MSK; |
435 | } else { | 433 | } else { |
436 | tx_flags |= TX_CMD_FLG_SEQ_CTL_MSK; | 434 | tx_flags |= TX_CMD_FLG_SEQ_CTL_MSK; |
437 | } | 435 | } |
438 | 436 | ||
439 | if (rc_flags & IEEE80211_TX_RC_USE_RTS_CTS) { | 437 | priv->cfg->ops->utils->rts_tx_cmd_flag(info, &tx_flags); |
440 | tx_flags |= TX_CMD_FLG_RTS_MSK; | ||
441 | tx_flags &= ~TX_CMD_FLG_CTS_MSK; | ||
442 | } else if (rc_flags & IEEE80211_TX_RC_USE_CTS_PROTECT) { | ||
443 | tx_flags &= ~TX_CMD_FLG_RTS_MSK; | ||
444 | tx_flags |= TX_CMD_FLG_CTS_MSK; | ||
445 | } | ||
446 | 438 | ||
447 | if ((tx_flags & TX_CMD_FLG_RTS_MSK) || (tx_flags & TX_CMD_FLG_CTS_MSK)) | 439 | if ((tx_flags & TX_CMD_FLG_RTS_MSK) || (tx_flags & TX_CMD_FLG_CTS_MSK)) |
448 | tx_flags |= TX_CMD_FLG_FULL_TXOP_PROT_MSK; | 440 | tx_flags |= TX_CMD_FLG_FULL_TXOP_PROT_MSK; |
@@ -450,16 +442,16 @@ static void iwl3945_build_tx_cmd_basic(struct iwl_priv *priv, | |||
450 | tx_flags &= ~(TX_CMD_FLG_ANT_SEL_MSK); | 442 | tx_flags &= ~(TX_CMD_FLG_ANT_SEL_MSK); |
451 | if (ieee80211_is_mgmt(fc)) { | 443 | if (ieee80211_is_mgmt(fc)) { |
452 | if (ieee80211_is_assoc_req(fc) || ieee80211_is_reassoc_req(fc)) | 444 | if (ieee80211_is_assoc_req(fc) || ieee80211_is_reassoc_req(fc)) |
453 | tx->timeout.pm_frame_timeout = cpu_to_le16(3); | 445 | tx_cmd->timeout.pm_frame_timeout = cpu_to_le16(3); |
454 | else | 446 | else |
455 | tx->timeout.pm_frame_timeout = cpu_to_le16(2); | 447 | tx_cmd->timeout.pm_frame_timeout = cpu_to_le16(2); |
456 | } else { | 448 | } else { |
457 | tx->timeout.pm_frame_timeout = 0; | 449 | tx_cmd->timeout.pm_frame_timeout = 0; |
458 | } | 450 | } |
459 | 451 | ||
460 | tx->driver_txop = 0; | 452 | tx_cmd->driver_txop = 0; |
461 | tx->tx_flags = tx_flags; | 453 | tx_cmd->tx_flags = tx_flags; |
462 | tx->next_frame_len = 0; | 454 | tx_cmd->next_frame_len = 0; |
463 | } | 455 | } |
464 | 456 | ||
465 | /* | 457 | /* |
@@ -469,7 +461,7 @@ static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) | |||
469 | { | 461 | { |
470 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; | 462 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; |
471 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | 463 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
472 | struct iwl3945_tx_cmd *tx; | 464 | struct iwl3945_tx_cmd *tx_cmd; |
473 | struct iwl_tx_queue *txq = NULL; | 465 | struct iwl_tx_queue *txq = NULL; |
474 | struct iwl_queue *q = NULL; | 466 | struct iwl_queue *q = NULL; |
475 | struct iwl_device_cmd *out_cmd; | 467 | struct iwl_device_cmd *out_cmd; |
@@ -568,9 +560,9 @@ static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) | |||
568 | /* Init first empty entry in queue's array of Tx/cmd buffers */ | 560 | /* Init first empty entry in queue's array of Tx/cmd buffers */ |
569 | out_cmd = txq->cmd[idx]; | 561 | out_cmd = txq->cmd[idx]; |
570 | out_meta = &txq->meta[idx]; | 562 | out_meta = &txq->meta[idx]; |
571 | tx = (struct iwl3945_tx_cmd *)out_cmd->cmd.payload; | 563 | tx_cmd = (struct iwl3945_tx_cmd *)out_cmd->cmd.payload; |
572 | memset(&out_cmd->hdr, 0, sizeof(out_cmd->hdr)); | 564 | memset(&out_cmd->hdr, 0, sizeof(out_cmd->hdr)); |
573 | memset(tx, 0, sizeof(*tx)); | 565 | memset(tx_cmd, 0, sizeof(*tx_cmd)); |
574 | 566 | ||
575 | /* | 567 | /* |
576 | * Set up the Tx-command (not MAC!) header. | 568 | * Set up the Tx-command (not MAC!) header. |
@@ -583,7 +575,7 @@ static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) | |||
583 | INDEX_TO_SEQ(q->write_ptr))); | 575 | INDEX_TO_SEQ(q->write_ptr))); |
584 | 576 | ||
585 | /* Copy MAC header from skb into command buffer */ | 577 | /* Copy MAC header from skb into command buffer */ |
586 | memcpy(tx->hdr, hdr, hdr_len); | 578 | memcpy(tx_cmd->hdr, hdr, hdr_len); |
587 | 579 | ||
588 | 580 | ||
589 | if (info->control.hw_key) | 581 | if (info->control.hw_key) |
@@ -597,12 +589,12 @@ static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) | |||
597 | 589 | ||
598 | /* Total # bytes to be transmitted */ | 590 | /* Total # bytes to be transmitted */ |
599 | len = (u16)skb->len; | 591 | len = (u16)skb->len; |
600 | tx->len = cpu_to_le16(len); | 592 | tx_cmd->len = cpu_to_le16(len); |
601 | 593 | ||
602 | iwl_dbg_log_tx_data_frame(priv, len, hdr); | 594 | iwl_dbg_log_tx_data_frame(priv, len, hdr); |
603 | iwl_update_stats(priv, true, fc, len); | 595 | iwl_update_stats(priv, true, fc, len); |
604 | tx->tx_flags &= ~TX_CMD_FLG_ANT_A_MSK; | 596 | tx_cmd->tx_flags &= ~TX_CMD_FLG_ANT_A_MSK; |
605 | tx->tx_flags &= ~TX_CMD_FLG_ANT_B_MSK; | 597 | tx_cmd->tx_flags &= ~TX_CMD_FLG_ANT_B_MSK; |
606 | 598 | ||
607 | if (!ieee80211_has_morefrags(hdr->frame_control)) { | 599 | if (!ieee80211_has_morefrags(hdr->frame_control)) { |
608 | txq->need_update = 1; | 600 | txq->need_update = 1; |
@@ -615,9 +607,9 @@ static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) | |||
615 | 607 | ||
616 | IWL_DEBUG_TX(priv, "sequence nr = 0X%x \n", | 608 | IWL_DEBUG_TX(priv, "sequence nr = 0X%x \n", |
617 | le16_to_cpu(out_cmd->hdr.sequence)); | 609 | le16_to_cpu(out_cmd->hdr.sequence)); |
618 | IWL_DEBUG_TX(priv, "tx_flags = 0X%x \n", le32_to_cpu(tx->tx_flags)); | 610 | IWL_DEBUG_TX(priv, "tx_flags = 0X%x \n", le32_to_cpu(tx_cmd->tx_flags)); |
619 | iwl_print_hex_dump(priv, IWL_DL_TX, tx, sizeof(*tx)); | 611 | iwl_print_hex_dump(priv, IWL_DL_TX, tx_cmd, sizeof(*tx_cmd)); |
620 | iwl_print_hex_dump(priv, IWL_DL_TX, (u8 *)tx->hdr, | 612 | iwl_print_hex_dump(priv, IWL_DL_TX, (u8 *)tx_cmd->hdr, |
621 | ieee80211_hdrlen(fc)); | 613 | ieee80211_hdrlen(fc)); |
622 | 614 | ||
623 | /* | 615 | /* |
@@ -753,7 +745,7 @@ static int iwl3945_get_measurement(struct iwl_priv *priv, | |||
753 | u8 type) | 745 | u8 type) |
754 | { | 746 | { |
755 | struct iwl_spectrum_cmd spectrum; | 747 | struct iwl_spectrum_cmd spectrum; |
756 | struct iwl_rx_packet *res; | 748 | struct iwl_rx_packet *pkt; |
757 | struct iwl_host_cmd cmd = { | 749 | struct iwl_host_cmd cmd = { |
758 | .id = REPLY_SPECTRUM_MEASUREMENT_CMD, | 750 | .id = REPLY_SPECTRUM_MEASUREMENT_CMD, |
759 | .data = (void *)&spectrum, | 751 | .data = (void *)&spectrum, |
@@ -798,18 +790,18 @@ static int iwl3945_get_measurement(struct iwl_priv *priv, | |||
798 | if (rc) | 790 | if (rc) |
799 | return rc; | 791 | return rc; |
800 | 792 | ||
801 | res = (struct iwl_rx_packet *)cmd.reply_skb->data; | 793 | pkt = (struct iwl_rx_packet *)cmd.reply_page; |
802 | if (res->hdr.flags & IWL_CMD_FAILED_MSK) { | 794 | if (pkt->hdr.flags & IWL_CMD_FAILED_MSK) { |
803 | IWL_ERR(priv, "Bad return from REPLY_RX_ON_ASSOC command\n"); | 795 | IWL_ERR(priv, "Bad return from REPLY_RX_ON_ASSOC command\n"); |
804 | rc = -EIO; | 796 | rc = -EIO; |
805 | } | 797 | } |
806 | 798 | ||
807 | spectrum_resp_status = le16_to_cpu(res->u.spectrum.status); | 799 | spectrum_resp_status = le16_to_cpu(pkt->u.spectrum.status); |
808 | switch (spectrum_resp_status) { | 800 | switch (spectrum_resp_status) { |
809 | case 0: /* Command will be handled */ | 801 | case 0: /* Command will be handled */ |
810 | if (res->u.spectrum.id != 0xff) { | 802 | if (pkt->u.spectrum.id != 0xff) { |
811 | IWL_DEBUG_INFO(priv, "Replaced existing measurement: %d\n", | 803 | IWL_DEBUG_INFO(priv, "Replaced existing measurement: %d\n", |
812 | res->u.spectrum.id); | 804 | pkt->u.spectrum.id); |
813 | priv->measurement_status &= ~MEASUREMENT_READY; | 805 | priv->measurement_status &= ~MEASUREMENT_READY; |
814 | } | 806 | } |
815 | priv->measurement_status |= MEASUREMENT_ACTIVE; | 807 | priv->measurement_status |= MEASUREMENT_ACTIVE; |
@@ -821,7 +813,7 @@ static int iwl3945_get_measurement(struct iwl_priv *priv, | |||
821 | break; | 813 | break; |
822 | } | 814 | } |
823 | 815 | ||
824 | dev_kfree_skb_any(cmd.reply_skb); | 816 | free_pages(cmd.reply_page, priv->hw_params.rx_page_order); |
825 | 817 | ||
826 | return rc; | 818 | return rc; |
827 | } | 819 | } |
@@ -830,7 +822,7 @@ static int iwl3945_get_measurement(struct iwl_priv *priv, | |||
830 | static void iwl3945_rx_reply_alive(struct iwl_priv *priv, | 822 | static void iwl3945_rx_reply_alive(struct iwl_priv *priv, |
831 | struct iwl_rx_mem_buffer *rxb) | 823 | struct iwl_rx_mem_buffer *rxb) |
832 | { | 824 | { |
833 | struct iwl_rx_packet *pkt = (void *)rxb->skb->data; | 825 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
834 | struct iwl_alive_resp *palive; | 826 | struct iwl_alive_resp *palive; |
835 | struct delayed_work *pwork; | 827 | struct delayed_work *pwork; |
836 | 828 | ||
@@ -867,7 +859,7 @@ static void iwl3945_rx_reply_add_sta(struct iwl_priv *priv, | |||
867 | struct iwl_rx_mem_buffer *rxb) | 859 | struct iwl_rx_mem_buffer *rxb) |
868 | { | 860 | { |
869 | #ifdef CONFIG_IWLWIFI_DEBUG | 861 | #ifdef CONFIG_IWLWIFI_DEBUG |
870 | struct iwl_rx_packet *pkt = (void *)rxb->skb->data; | 862 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
871 | #endif | 863 | #endif |
872 | 864 | ||
873 | IWL_DEBUG_RX(priv, "Received REPLY_ADD_STA: 0x%02X\n", pkt->u.status); | 865 | IWL_DEBUG_RX(priv, "Received REPLY_ADD_STA: 0x%02X\n", pkt->u.status); |
@@ -903,7 +895,7 @@ static void iwl3945_rx_beacon_notif(struct iwl_priv *priv, | |||
903 | struct iwl_rx_mem_buffer *rxb) | 895 | struct iwl_rx_mem_buffer *rxb) |
904 | { | 896 | { |
905 | #ifdef CONFIG_IWLWIFI_DEBUG | 897 | #ifdef CONFIG_IWLWIFI_DEBUG |
906 | struct iwl_rx_packet *pkt = (void *)rxb->skb->data; | 898 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
907 | struct iwl3945_beacon_notif *beacon = &(pkt->u.beacon_status); | 899 | struct iwl3945_beacon_notif *beacon = &(pkt->u.beacon_status); |
908 | u8 rate = beacon->beacon_notify_hdr.rate; | 900 | u8 rate = beacon->beacon_notify_hdr.rate; |
909 | 901 | ||
@@ -926,7 +918,7 @@ static void iwl3945_rx_beacon_notif(struct iwl_priv *priv, | |||
926 | static void iwl3945_rx_card_state_notif(struct iwl_priv *priv, | 918 | static void iwl3945_rx_card_state_notif(struct iwl_priv *priv, |
927 | struct iwl_rx_mem_buffer *rxb) | 919 | struct iwl_rx_mem_buffer *rxb) |
928 | { | 920 | { |
929 | struct iwl_rx_packet *pkt = (void *)rxb->skb->data; | 921 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
930 | u32 flags = le32_to_cpu(pkt->u.card_state_notif.flags); | 922 | u32 flags = le32_to_cpu(pkt->u.card_state_notif.flags); |
931 | unsigned long status = priv->status; | 923 | unsigned long status = priv->status; |
932 | 924 | ||
@@ -1090,7 +1082,7 @@ static int iwl3945_rx_queue_restock(struct iwl_priv *priv) | |||
1090 | list_del(element); | 1082 | list_del(element); |
1091 | 1083 | ||
1092 | /* Point to Rx buffer via next RBD in circular buffer */ | 1084 | /* Point to Rx buffer via next RBD in circular buffer */ |
1093 | rxq->bd[rxq->write] = iwl3945_dma_addr2rbd_ptr(priv, rxb->real_dma_addr); | 1085 | rxq->bd[rxq->write] = iwl3945_dma_addr2rbd_ptr(priv, rxb->page_dma); |
1094 | rxq->queue[rxq->write] = rxb; | 1086 | rxq->queue[rxq->write] = rxb; |
1095 | rxq->write = (rxq->write + 1) & RX_QUEUE_MASK; | 1087 | rxq->write = (rxq->write + 1) & RX_QUEUE_MASK; |
1096 | rxq->free_count--; | 1088 | rxq->free_count--; |
@@ -1130,8 +1122,9 @@ static void iwl3945_rx_allocate(struct iwl_priv *priv, gfp_t priority) | |||
1130 | struct iwl_rx_queue *rxq = &priv->rxq; | 1122 | struct iwl_rx_queue *rxq = &priv->rxq; |
1131 | struct list_head *element; | 1123 | struct list_head *element; |
1132 | struct iwl_rx_mem_buffer *rxb; | 1124 | struct iwl_rx_mem_buffer *rxb; |
1133 | struct sk_buff *skb; | 1125 | struct page *page; |
1134 | unsigned long flags; | 1126 | unsigned long flags; |
1127 | gfp_t gfp_mask = priority; | ||
1135 | 1128 | ||
1136 | while (1) { | 1129 | while (1) { |
1137 | spin_lock_irqsave(&rxq->lock, flags); | 1130 | spin_lock_irqsave(&rxq->lock, flags); |
@@ -1143,10 +1136,14 @@ static void iwl3945_rx_allocate(struct iwl_priv *priv, gfp_t priority) | |||
1143 | spin_unlock_irqrestore(&rxq->lock, flags); | 1136 | spin_unlock_irqrestore(&rxq->lock, flags); |
1144 | 1137 | ||
1145 | if (rxq->free_count > RX_LOW_WATERMARK) | 1138 | if (rxq->free_count > RX_LOW_WATERMARK) |
1146 | priority |= __GFP_NOWARN; | 1139 | gfp_mask |= __GFP_NOWARN; |
1140 | |||
1141 | if (priv->hw_params.rx_page_order > 0) | ||
1142 | gfp_mask |= __GFP_COMP; | ||
1143 | |||
1147 | /* Alloc a new receive buffer */ | 1144 | /* Alloc a new receive buffer */ |
1148 | skb = alloc_skb(priv->hw_params.rx_buf_size, priority); | 1145 | page = alloc_pages(gfp_mask, priv->hw_params.rx_page_order); |
1149 | if (!skb) { | 1146 | if (!page) { |
1150 | if (net_ratelimit()) | 1147 | if (net_ratelimit()) |
1151 | IWL_DEBUG_INFO(priv, "Failed to allocate SKB buffer.\n"); | 1148 | IWL_DEBUG_INFO(priv, "Failed to allocate SKB buffer.\n"); |
1152 | if ((rxq->free_count <= RX_LOW_WATERMARK) && | 1149 | if ((rxq->free_count <= RX_LOW_WATERMARK) && |
@@ -1163,7 +1160,7 @@ static void iwl3945_rx_allocate(struct iwl_priv *priv, gfp_t priority) | |||
1163 | spin_lock_irqsave(&rxq->lock, flags); | 1160 | spin_lock_irqsave(&rxq->lock, flags); |
1164 | if (list_empty(&rxq->rx_used)) { | 1161 | if (list_empty(&rxq->rx_used)) { |
1165 | spin_unlock_irqrestore(&rxq->lock, flags); | 1162 | spin_unlock_irqrestore(&rxq->lock, flags); |
1166 | dev_kfree_skb_any(skb); | 1163 | __free_pages(page, priv->hw_params.rx_page_order); |
1167 | return; | 1164 | return; |
1168 | } | 1165 | } |
1169 | element = rxq->rx_used.next; | 1166 | element = rxq->rx_used.next; |
@@ -1171,26 +1168,18 @@ static void iwl3945_rx_allocate(struct iwl_priv *priv, gfp_t priority) | |||
1171 | list_del(element); | 1168 | list_del(element); |
1172 | spin_unlock_irqrestore(&rxq->lock, flags); | 1169 | spin_unlock_irqrestore(&rxq->lock, flags); |
1173 | 1170 | ||
1174 | rxb->skb = skb; | 1171 | rxb->page = page; |
1175 | |||
1176 | /* If radiotap head is required, reserve some headroom here. | ||
1177 | * The physical head count is a variable rx_stats->phy_count. | ||
1178 | * We reserve 4 bytes here. Plus these extra bytes, the | ||
1179 | * headroom of the physical head should be enough for the | ||
1180 | * radiotap head that iwl3945 supported. See iwl3945_rt. | ||
1181 | */ | ||
1182 | skb_reserve(rxb->skb, 4); | ||
1183 | |||
1184 | /* Get physical address of RB/SKB */ | 1172 | /* Get physical address of RB/SKB */ |
1185 | rxb->real_dma_addr = pci_map_single(priv->pci_dev, | 1173 | rxb->page_dma = pci_map_page(priv->pci_dev, page, 0, |
1186 | rxb->skb->data, | 1174 | PAGE_SIZE << priv->hw_params.rx_page_order, |
1187 | priv->hw_params.rx_buf_size, | 1175 | PCI_DMA_FROMDEVICE); |
1188 | PCI_DMA_FROMDEVICE); | ||
1189 | 1176 | ||
1190 | spin_lock_irqsave(&rxq->lock, flags); | 1177 | spin_lock_irqsave(&rxq->lock, flags); |
1178 | |||
1191 | list_add_tail(&rxb->list, &rxq->rx_free); | 1179 | list_add_tail(&rxb->list, &rxq->rx_free); |
1192 | priv->alloc_rxb_skb++; | ||
1193 | rxq->free_count++; | 1180 | rxq->free_count++; |
1181 | priv->alloc_rxb_page++; | ||
1182 | |||
1194 | spin_unlock_irqrestore(&rxq->lock, flags); | 1183 | spin_unlock_irqrestore(&rxq->lock, flags); |
1195 | } | 1184 | } |
1196 | } | 1185 | } |
@@ -1206,14 +1195,14 @@ void iwl3945_rx_queue_reset(struct iwl_priv *priv, struct iwl_rx_queue *rxq) | |||
1206 | for (i = 0; i < RX_FREE_BUFFERS + RX_QUEUE_SIZE; i++) { | 1195 | for (i = 0; i < RX_FREE_BUFFERS + RX_QUEUE_SIZE; i++) { |
1207 | /* In the reset function, these buffers may have been allocated | 1196 | /* In the reset function, these buffers may have been allocated |
1208 | * to an SKB, so we need to unmap and free potential storage */ | 1197 | * to an SKB, so we need to unmap and free potential storage */ |
1209 | if (rxq->pool[i].skb != NULL) { | 1198 | if (rxq->pool[i].page != NULL) { |
1210 | pci_unmap_single(priv->pci_dev, | 1199 | pci_unmap_page(priv->pci_dev, rxq->pool[i].page_dma, |
1211 | rxq->pool[i].real_dma_addr, | 1200 | PAGE_SIZE << priv->hw_params.rx_page_order, |
1212 | priv->hw_params.rx_buf_size, | 1201 | PCI_DMA_FROMDEVICE); |
1213 | PCI_DMA_FROMDEVICE); | 1202 | priv->alloc_rxb_page--; |
1214 | priv->alloc_rxb_skb--; | 1203 | __free_pages(rxq->pool[i].page, |
1215 | dev_kfree_skb(rxq->pool[i].skb); | 1204 | priv->hw_params.rx_page_order); |
1216 | rxq->pool[i].skb = NULL; | 1205 | rxq->pool[i].page = NULL; |
1217 | } | 1206 | } |
1218 | list_add_tail(&rxq->pool[i].list, &rxq->rx_used); | 1207 | list_add_tail(&rxq->pool[i].list, &rxq->rx_used); |
1219 | } | 1208 | } |
@@ -1221,8 +1210,8 @@ void iwl3945_rx_queue_reset(struct iwl_priv *priv, struct iwl_rx_queue *rxq) | |||
1221 | /* Set us so that we have processed and used all buffers, but have | 1210 | /* Set us so that we have processed and used all buffers, but have |
1222 | * not restocked the Rx queue with fresh buffers */ | 1211 | * not restocked the Rx queue with fresh buffers */ |
1223 | rxq->read = rxq->write = 0; | 1212 | rxq->read = rxq->write = 0; |
1224 | rxq->free_count = 0; | ||
1225 | rxq->write_actual = 0; | 1213 | rxq->write_actual = 0; |
1214 | rxq->free_count = 0; | ||
1226 | spin_unlock_irqrestore(&rxq->lock, flags); | 1215 | spin_unlock_irqrestore(&rxq->lock, flags); |
1227 | } | 1216 | } |
1228 | 1217 | ||
@@ -1255,12 +1244,14 @@ static void iwl3945_rx_queue_free(struct iwl_priv *priv, struct iwl_rx_queue *rx | |||
1255 | { | 1244 | { |
1256 | int i; | 1245 | int i; |
1257 | for (i = 0; i < RX_QUEUE_SIZE + RX_FREE_BUFFERS; i++) { | 1246 | for (i = 0; i < RX_QUEUE_SIZE + RX_FREE_BUFFERS; i++) { |
1258 | if (rxq->pool[i].skb != NULL) { | 1247 | if (rxq->pool[i].page != NULL) { |
1259 | pci_unmap_single(priv->pci_dev, | 1248 | pci_unmap_page(priv->pci_dev, rxq->pool[i].page_dma, |
1260 | rxq->pool[i].real_dma_addr, | 1249 | PAGE_SIZE << priv->hw_params.rx_page_order, |
1261 | priv->hw_params.rx_buf_size, | 1250 | PCI_DMA_FROMDEVICE); |
1262 | PCI_DMA_FROMDEVICE); | 1251 | __free_pages(rxq->pool[i].page, |
1263 | dev_kfree_skb(rxq->pool[i].skb); | 1252 | priv->hw_params.rx_page_order); |
1253 | rxq->pool[i].page = NULL; | ||
1254 | priv->alloc_rxb_page--; | ||
1264 | } | 1255 | } |
1265 | } | 1256 | } |
1266 | 1257 | ||
@@ -1376,7 +1367,7 @@ static void iwl3945_rx_handle(struct iwl_priv *priv) | |||
1376 | i = rxq->read; | 1367 | i = rxq->read; |
1377 | 1368 | ||
1378 | /* calculate total frames need to be restock after handling RX */ | 1369 | /* calculate total frames need to be restock after handling RX */ |
1379 | total_empty = r - priv->rxq.write_actual; | 1370 | total_empty = r - rxq->write_actual; |
1380 | if (total_empty < 0) | 1371 | if (total_empty < 0) |
1381 | total_empty += RX_QUEUE_SIZE; | 1372 | total_empty += RX_QUEUE_SIZE; |
1382 | 1373 | ||
@@ -1396,10 +1387,10 @@ static void iwl3945_rx_handle(struct iwl_priv *priv) | |||
1396 | 1387 | ||
1397 | rxq->queue[i] = NULL; | 1388 | rxq->queue[i] = NULL; |
1398 | 1389 | ||
1399 | pci_unmap_single(priv->pci_dev, rxb->real_dma_addr, | 1390 | pci_unmap_page(priv->pci_dev, rxb->page_dma, |
1400 | priv->hw_params.rx_buf_size, | 1391 | PAGE_SIZE << priv->hw_params.rx_page_order, |
1401 | PCI_DMA_FROMDEVICE); | 1392 | PCI_DMA_FROMDEVICE); |
1402 | pkt = (struct iwl_rx_packet *)rxb->skb->data; | 1393 | pkt = rxb_addr(rxb); |
1403 | 1394 | ||
1404 | trace_iwlwifi_dev_rx(priv, pkt, | 1395 | trace_iwlwifi_dev_rx(priv, pkt, |
1405 | le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK); | 1396 | le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK); |
@@ -1420,44 +1411,55 @@ static void iwl3945_rx_handle(struct iwl_priv *priv) | |||
1420 | if (priv->rx_handlers[pkt->hdr.cmd]) { | 1411 | if (priv->rx_handlers[pkt->hdr.cmd]) { |
1421 | IWL_DEBUG_RX(priv, "r = %d, i = %d, %s, 0x%02x\n", r, i, | 1412 | IWL_DEBUG_RX(priv, "r = %d, i = %d, %s, 0x%02x\n", r, i, |
1422 | get_cmd_string(pkt->hdr.cmd), pkt->hdr.cmd); | 1413 | get_cmd_string(pkt->hdr.cmd), pkt->hdr.cmd); |
1423 | priv->rx_handlers[pkt->hdr.cmd] (priv, rxb); | ||
1424 | priv->isr_stats.rx_handlers[pkt->hdr.cmd]++; | 1414 | priv->isr_stats.rx_handlers[pkt->hdr.cmd]++; |
1415 | priv->rx_handlers[pkt->hdr.cmd] (priv, rxb); | ||
1425 | } else { | 1416 | } else { |
1426 | /* No handling needed */ | 1417 | /* No handling needed */ |
1427 | IWL_DEBUG_RX(priv, "r %d i %d No handler needed for %s, 0x%02x\n", | 1418 | IWL_DEBUG_RX(priv, |
1419 | "r %d i %d No handler needed for %s, 0x%02x\n", | ||
1428 | r, i, get_cmd_string(pkt->hdr.cmd), | 1420 | r, i, get_cmd_string(pkt->hdr.cmd), |
1429 | pkt->hdr.cmd); | 1421 | pkt->hdr.cmd); |
1430 | } | 1422 | } |
1431 | 1423 | ||
1424 | /* | ||
1425 | * XXX: After here, we should always check rxb->page | ||
1426 | * against NULL before touching it or its virtual | ||
1427 | * memory (pkt). Because some rx_handler might have | ||
1428 | * already taken or freed the pages. | ||
1429 | */ | ||
1430 | |||
1432 | if (reclaim) { | 1431 | if (reclaim) { |
1433 | /* Invoke any callbacks, transfer the skb to caller, and | 1432 | /* Invoke any callbacks, transfer the buffer to caller, |
1434 | * fire off the (possibly) blocking iwl_send_cmd() | 1433 | * and fire off the (possibly) blocking iwl_send_cmd() |
1435 | * as we reclaim the driver command queue */ | 1434 | * as we reclaim the driver command queue */ |
1436 | if (rxb && rxb->skb) | 1435 | if (rxb->page) |
1437 | iwl_tx_cmd_complete(priv, rxb); | 1436 | iwl_tx_cmd_complete(priv, rxb); |
1438 | else | 1437 | else |
1439 | IWL_WARN(priv, "Claim null rxb?\n"); | 1438 | IWL_WARN(priv, "Claim null rxb?\n"); |
1440 | } | 1439 | } |
1441 | 1440 | ||
1442 | /* For now we just don't re-use anything. We can tweak this | 1441 | /* Reuse the page if possible. For notification packets and |
1443 | * later to try and re-use notification packets and SKBs that | 1442 | * SKBs that fail to Rx correctly, add them back into the |
1444 | * fail to Rx correctly */ | 1443 | * rx_free list for reuse later. */ |
1445 | if (rxb->skb != NULL) { | ||
1446 | priv->alloc_rxb_skb--; | ||
1447 | dev_kfree_skb_any(rxb->skb); | ||
1448 | rxb->skb = NULL; | ||
1449 | } | ||
1450 | |||
1451 | spin_lock_irqsave(&rxq->lock, flags); | 1444 | spin_lock_irqsave(&rxq->lock, flags); |
1452 | list_add_tail(&rxb->list, &priv->rxq.rx_used); | 1445 | if (rxb->page != NULL) { |
1446 | rxb->page_dma = pci_map_page(priv->pci_dev, rxb->page, | ||
1447 | 0, PAGE_SIZE << priv->hw_params.rx_page_order, | ||
1448 | PCI_DMA_FROMDEVICE); | ||
1449 | list_add_tail(&rxb->list, &rxq->rx_free); | ||
1450 | rxq->free_count++; | ||
1451 | } else | ||
1452 | list_add_tail(&rxb->list, &rxq->rx_used); | ||
1453 | |||
1453 | spin_unlock_irqrestore(&rxq->lock, flags); | 1454 | spin_unlock_irqrestore(&rxq->lock, flags); |
1455 | |||
1454 | i = (i + 1) & RX_QUEUE_MASK; | 1456 | i = (i + 1) & RX_QUEUE_MASK; |
1455 | /* If there are a lot of unused frames, | 1457 | /* If there are a lot of unused frames, |
1456 | * restock the Rx queue so ucode won't assert. */ | 1458 | * restock the Rx queue so ucode won't assert. */ |
1457 | if (fill_rx) { | 1459 | if (fill_rx) { |
1458 | count++; | 1460 | count++; |
1459 | if (count >= 8) { | 1461 | if (count >= 8) { |
1460 | priv->rxq.read = i; | 1462 | rxq->read = i; |
1461 | iwl3945_rx_replenish_now(priv); | 1463 | iwl3945_rx_replenish_now(priv); |
1462 | count = 0; | 1464 | count = 0; |
1463 | } | 1465 | } |
@@ -1465,7 +1467,7 @@ static void iwl3945_rx_handle(struct iwl_priv *priv) | |||
1465 | } | 1467 | } |
1466 | 1468 | ||
1467 | /* Backtrack one entry */ | 1469 | /* Backtrack one entry */ |
1468 | priv->rxq.read = i; | 1470 | rxq->read = i; |
1469 | if (fill_rx) | 1471 | if (fill_rx) |
1470 | iwl3945_rx_replenish_now(priv); | 1472 | iwl3945_rx_replenish_now(priv); |
1471 | else | 1473 | else |
@@ -1686,6 +1688,8 @@ static void iwl3945_irq_tasklet(struct iwl_priv *priv) | |||
1686 | } | 1688 | } |
1687 | #endif | 1689 | #endif |
1688 | 1690 | ||
1691 | spin_unlock_irqrestore(&priv->lock, flags); | ||
1692 | |||
1689 | /* Since CSR_INT and CSR_FH_INT_STATUS reads and clears are not | 1693 | /* Since CSR_INT and CSR_FH_INT_STATUS reads and clears are not |
1690 | * atomic, make sure that inta covers all the interrupts that | 1694 | * atomic, make sure that inta covers all the interrupts that |
1691 | * we've discovered, even if FH interrupt came in just after | 1695 | * we've discovered, even if FH interrupt came in just after |
@@ -1707,8 +1711,6 @@ static void iwl3945_irq_tasklet(struct iwl_priv *priv) | |||
1707 | 1711 | ||
1708 | handled |= CSR_INT_BIT_HW_ERR; | 1712 | handled |= CSR_INT_BIT_HW_ERR; |
1709 | 1713 | ||
1710 | spin_unlock_irqrestore(&priv->lock, flags); | ||
1711 | |||
1712 | return; | 1714 | return; |
1713 | } | 1715 | } |
1714 | 1716 | ||
@@ -1800,7 +1802,6 @@ static void iwl3945_irq_tasklet(struct iwl_priv *priv) | |||
1800 | "flags 0x%08lx\n", inta, inta_mask, inta_fh, flags); | 1802 | "flags 0x%08lx\n", inta, inta_mask, inta_fh, flags); |
1801 | } | 1803 | } |
1802 | #endif | 1804 | #endif |
1803 | spin_unlock_irqrestore(&priv->lock, flags); | ||
1804 | } | 1805 | } |
1805 | 1806 | ||
1806 | static int iwl3945_get_channels_for_scan(struct iwl_priv *priv, | 1807 | static int iwl3945_get_channels_for_scan(struct iwl_priv *priv, |
@@ -2563,11 +2564,6 @@ static void __iwl3945_down(struct iwl_priv *priv) | |||
2563 | test_bit(STATUS_EXIT_PENDING, &priv->status) << | 2564 | test_bit(STATUS_EXIT_PENDING, &priv->status) << |
2564 | STATUS_EXIT_PENDING; | 2565 | STATUS_EXIT_PENDING; |
2565 | 2566 | ||
2566 | priv->cfg->ops->lib->apm_ops.reset(priv); | ||
2567 | spin_lock_irqsave(&priv->lock, flags); | ||
2568 | iwl_clear_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); | ||
2569 | spin_unlock_irqrestore(&priv->lock, flags); | ||
2570 | |||
2571 | iwl3945_hw_txq_ctx_stop(priv); | 2567 | iwl3945_hw_txq_ctx_stop(priv); |
2572 | iwl3945_hw_rxq_stop(priv); | 2568 | iwl3945_hw_rxq_stop(priv); |
2573 | 2569 | ||
@@ -2576,10 +2572,8 @@ static void __iwl3945_down(struct iwl_priv *priv) | |||
2576 | 2572 | ||
2577 | udelay(5); | 2573 | udelay(5); |
2578 | 2574 | ||
2579 | if (exit_pending) | 2575 | /* Stop the device, and put it in low power state */ |
2580 | priv->cfg->ops->lib->apm_ops.stop(priv); | 2576 | priv->cfg->ops->lib->apm_ops.stop(priv); |
2581 | else | ||
2582 | priv->cfg->ops->lib->apm_ops.reset(priv); | ||
2583 | 2577 | ||
2584 | exit: | 2578 | exit: |
2585 | memset(&priv->card_alive, 0, sizeof(struct iwl_alive_resp)); | 2579 | memset(&priv->card_alive, 0, sizeof(struct iwl_alive_resp)); |
@@ -2724,19 +2718,34 @@ static void iwl3945_bg_alive_start(struct work_struct *data) | |||
2724 | mutex_unlock(&priv->mutex); | 2718 | mutex_unlock(&priv->mutex); |
2725 | } | 2719 | } |
2726 | 2720 | ||
2721 | /* | ||
2722 | * 3945 cannot interrupt driver when hardware rf kill switch toggles; | ||
2723 | * driver must poll CSR_GP_CNTRL_REG register for change. This register | ||
2724 | * *is* readable even when device has been SW_RESET into low power mode | ||
2725 | * (e.g. during RF KILL). | ||
2726 | */ | ||
2727 | static void iwl3945_rfkill_poll(struct work_struct *data) | 2727 | static void iwl3945_rfkill_poll(struct work_struct *data) |
2728 | { | 2728 | { |
2729 | struct iwl_priv *priv = | 2729 | struct iwl_priv *priv = |
2730 | container_of(data, struct iwl_priv, rfkill_poll.work); | 2730 | container_of(data, struct iwl_priv, rfkill_poll.work); |
2731 | bool old_rfkill = test_bit(STATUS_RF_KILL_HW, &priv->status); | ||
2732 | bool new_rfkill = !(iwl_read32(priv, CSR_GP_CNTRL) | ||
2733 | & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW); | ||
2731 | 2734 | ||
2732 | if (iwl_read32(priv, CSR_GP_CNTRL) & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW) | 2735 | if (new_rfkill != old_rfkill) { |
2733 | clear_bit(STATUS_RF_KILL_HW, &priv->status); | 2736 | if (new_rfkill) |
2734 | else | 2737 | set_bit(STATUS_RF_KILL_HW, &priv->status); |
2735 | set_bit(STATUS_RF_KILL_HW, &priv->status); | 2738 | else |
2739 | clear_bit(STATUS_RF_KILL_HW, &priv->status); | ||
2736 | 2740 | ||
2737 | wiphy_rfkill_set_hw_state(priv->hw->wiphy, | 2741 | wiphy_rfkill_set_hw_state(priv->hw->wiphy, new_rfkill); |
2738 | test_bit(STATUS_RF_KILL_HW, &priv->status)); | ||
2739 | 2742 | ||
2743 | IWL_DEBUG_RF_KILL(priv, "RF_KILL bit toggled to %s.\n", | ||
2744 | new_rfkill ? "disable radio" : "enable radio"); | ||
2745 | } | ||
2746 | |||
2747 | /* Keep this running, even if radio now enabled. This will be | ||
2748 | * cancelled in mac_start() if system decides to start again */ | ||
2740 | queue_delayed_work(priv->workqueue, &priv->rfkill_poll, | 2749 | queue_delayed_work(priv->workqueue, &priv->rfkill_poll, |
2741 | round_jiffies_relative(2 * HZ)); | 2750 | round_jiffies_relative(2 * HZ)); |
2742 | 2751 | ||
@@ -3797,7 +3806,6 @@ static int iwl3945_init_drv(struct iwl_priv *priv) | |||
3797 | /* Clear the driver's (not device's) station table */ | 3806 | /* Clear the driver's (not device's) station table */ |
3798 | iwl_clear_stations_table(priv); | 3807 | iwl_clear_stations_table(priv); |
3799 | 3808 | ||
3800 | priv->data_retry_limit = -1; | ||
3801 | priv->ieee_channels = NULL; | 3809 | priv->ieee_channels = NULL; |
3802 | priv->ieee_rates = NULL; | 3810 | priv->ieee_rates = NULL; |
3803 | priv->band = IEEE80211_BAND_2GHZ; | 3811 | priv->band = IEEE80211_BAND_2GHZ; |
@@ -4056,6 +4064,7 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e | |||
4056 | &priv->bands[IEEE80211_BAND_2GHZ].channels[5]); | 4064 | &priv->bands[IEEE80211_BAND_2GHZ].channels[5]); |
4057 | iwl3945_setup_deferred_work(priv); | 4065 | iwl3945_setup_deferred_work(priv); |
4058 | iwl3945_setup_rx_handlers(priv); | 4066 | iwl3945_setup_rx_handlers(priv); |
4067 | iwl_power_initialize(priv); | ||
4059 | 4068 | ||
4060 | /********************************* | 4069 | /********************************* |
4061 | * 8. Setup and Register mac80211 | 4070 | * 8. Setup and Register mac80211 |
@@ -4126,6 +4135,15 @@ static void __devexit iwl3945_pci_remove(struct pci_dev *pdev) | |||
4126 | iwl3945_down(priv); | 4135 | iwl3945_down(priv); |
4127 | } | 4136 | } |
4128 | 4137 | ||
4138 | /* | ||
4139 | * Make sure device is reset to low power before unloading driver. | ||
4140 | * This may be redundant with iwl_down(), but there are paths to | ||
4141 | * run iwl_down() without calling apm_ops.stop(), and there are | ||
4142 | * paths to avoid running iwl_down() at all before leaving driver. | ||
4143 | * This (inexpensive) call *makes sure* device is reset. | ||
4144 | */ | ||
4145 | priv->cfg->ops->lib->apm_ops.stop(priv); | ||
4146 | |||
4129 | /* make sure we flush any pending irq or | 4147 | /* make sure we flush any pending irq or |
4130 | * tasklet for the driver | 4148 | * tasklet for the driver |
4131 | */ | 4149 | */ |