diff options
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-agn-rx.c')
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-agn-rx.c | 182 |
1 files changed, 91 insertions, 91 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rx.c b/drivers/net/wireless/iwlwifi/iwl-agn-rx.c index 30bb5bbb0cd7..44c6f712b77d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rx.c | |||
@@ -131,26 +131,27 @@ const char *get_cmd_string(u8 cmd) | |||
131 | ******************************************************************************/ | 131 | ******************************************************************************/ |
132 | 132 | ||
133 | static int iwlagn_rx_reply_error(struct iwl_priv *priv, | 133 | static int iwlagn_rx_reply_error(struct iwl_priv *priv, |
134 | struct iwl_rx_mem_buffer *rxb, | 134 | struct iwl_rx_cmd_buffer *rxb, |
135 | struct iwl_device_cmd *cmd) | 135 | struct iwl_device_cmd *cmd) |
136 | { | 136 | { |
137 | struct iwl_rx_packet *pkt = rxb_addr(rxb); | 137 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
138 | struct iwl_error_resp *err_resp = (void *)pkt->data; | ||
138 | 139 | ||
139 | IWL_ERR(priv, "Error Reply type 0x%08X cmd %s (0x%02X) " | 140 | IWL_ERR(priv, "Error Reply type 0x%08X cmd %s (0x%02X) " |
140 | "seq 0x%04X ser 0x%08X\n", | 141 | "seq 0x%04X ser 0x%08X\n", |
141 | le32_to_cpu(pkt->u.err_resp.error_type), | 142 | le32_to_cpu(err_resp->error_type), |
142 | get_cmd_string(pkt->u.err_resp.cmd_id), | 143 | get_cmd_string(err_resp->cmd_id), |
143 | pkt->u.err_resp.cmd_id, | 144 | err_resp->cmd_id, |
144 | le16_to_cpu(pkt->u.err_resp.bad_cmd_seq_num), | 145 | le16_to_cpu(err_resp->bad_cmd_seq_num), |
145 | le32_to_cpu(pkt->u.err_resp.error_info)); | 146 | le32_to_cpu(err_resp->error_info)); |
146 | return 0; | 147 | return 0; |
147 | } | 148 | } |
148 | 149 | ||
149 | static int iwlagn_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb, | 150 | static int iwlagn_rx_csa(struct iwl_priv *priv, struct iwl_rx_cmd_buffer *rxb, |
150 | struct iwl_device_cmd *cmd) | 151 | struct iwl_device_cmd *cmd) |
151 | { | 152 | { |
152 | struct iwl_rx_packet *pkt = rxb_addr(rxb); | 153 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
153 | struct iwl_csa_notification *csa = &(pkt->u.csa_notif); | 154 | struct iwl_csa_notification *csa = (void *)pkt->data; |
154 | /* | 155 | /* |
155 | * MULTI-FIXME | 156 | * MULTI-FIXME |
156 | * See iwlagn_mac_channel_switch. | 157 | * See iwlagn_mac_channel_switch. |
@@ -158,7 +159,7 @@ static int iwlagn_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb, | |||
158 | struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; | 159 | struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; |
159 | struct iwl_rxon_cmd *rxon = (void *)&ctx->active; | 160 | struct iwl_rxon_cmd *rxon = (void *)&ctx->active; |
160 | 161 | ||
161 | if (!test_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->shrd->status)) | 162 | if (!test_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status)) |
162 | return 0; | 163 | return 0; |
163 | 164 | ||
164 | if (!le32_to_cpu(csa->status) && csa->channel == priv->switch_channel) { | 165 | if (!le32_to_cpu(csa->status) && csa->channel == priv->switch_channel) { |
@@ -177,11 +178,11 @@ static int iwlagn_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb, | |||
177 | 178 | ||
178 | 179 | ||
179 | static int iwlagn_rx_spectrum_measure_notif(struct iwl_priv *priv, | 180 | static int iwlagn_rx_spectrum_measure_notif(struct iwl_priv *priv, |
180 | struct iwl_rx_mem_buffer *rxb, | 181 | struct iwl_rx_cmd_buffer *rxb, |
181 | struct iwl_device_cmd *cmd) | 182 | struct iwl_device_cmd *cmd) |
182 | { | 183 | { |
183 | struct iwl_rx_packet *pkt = rxb_addr(rxb); | 184 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
184 | struct iwl_spectrum_notification *report = &(pkt->u.spectrum_notif); | 185 | struct iwl_spectrum_notification *report = (void *)pkt->data; |
185 | 186 | ||
186 | if (!report->state) { | 187 | if (!report->state) { |
187 | IWL_DEBUG_11H(priv, | 188 | IWL_DEBUG_11H(priv, |
@@ -195,12 +196,12 @@ static int iwlagn_rx_spectrum_measure_notif(struct iwl_priv *priv, | |||
195 | } | 196 | } |
196 | 197 | ||
197 | static int iwlagn_rx_pm_sleep_notif(struct iwl_priv *priv, | 198 | static int iwlagn_rx_pm_sleep_notif(struct iwl_priv *priv, |
198 | struct iwl_rx_mem_buffer *rxb, | 199 | struct iwl_rx_cmd_buffer *rxb, |
199 | struct iwl_device_cmd *cmd) | 200 | struct iwl_device_cmd *cmd) |
200 | { | 201 | { |
201 | #ifdef CONFIG_IWLWIFI_DEBUG | 202 | #ifdef CONFIG_IWLWIFI_DEBUG |
202 | struct iwl_rx_packet *pkt = rxb_addr(rxb); | 203 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
203 | struct iwl_sleep_notification *sleep = &(pkt->u.sleep_notif); | 204 | struct iwl_sleep_notification *sleep = (void *)pkt->data; |
204 | IWL_DEBUG_RX(priv, "sleep mode: %d, src: %d\n", | 205 | IWL_DEBUG_RX(priv, "sleep mode: %d, src: %d\n", |
205 | sleep->pm_sleep_mode, sleep->pm_wakeup_src); | 206 | sleep->pm_sleep_mode, sleep->pm_wakeup_src); |
206 | #endif | 207 | #endif |
@@ -208,7 +209,7 @@ static int iwlagn_rx_pm_sleep_notif(struct iwl_priv *priv, | |||
208 | } | 209 | } |
209 | 210 | ||
210 | static int iwlagn_rx_pm_debug_statistics_notif(struct iwl_priv *priv, | 211 | static int iwlagn_rx_pm_debug_statistics_notif(struct iwl_priv *priv, |
211 | struct iwl_rx_mem_buffer *rxb, | 212 | struct iwl_rx_cmd_buffer *rxb, |
212 | struct iwl_device_cmd *cmd) | 213 | struct iwl_device_cmd *cmd) |
213 | { | 214 | { |
214 | struct iwl_rx_packet *pkt = rxb_addr(rxb); | 215 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
@@ -217,16 +218,16 @@ static int iwlagn_rx_pm_debug_statistics_notif(struct iwl_priv *priv, | |||
217 | IWL_DEBUG_RADIO(priv, "Dumping %d bytes of unhandled " | 218 | IWL_DEBUG_RADIO(priv, "Dumping %d bytes of unhandled " |
218 | "notification for %s:\n", len, | 219 | "notification for %s:\n", len, |
219 | get_cmd_string(pkt->hdr.cmd)); | 220 | get_cmd_string(pkt->hdr.cmd)); |
220 | iwl_print_hex_dump(priv, IWL_DL_RADIO, pkt->u.raw, len); | 221 | iwl_print_hex_dump(priv, IWL_DL_RADIO, pkt->data, len); |
221 | return 0; | 222 | return 0; |
222 | } | 223 | } |
223 | 224 | ||
224 | static int iwlagn_rx_beacon_notif(struct iwl_priv *priv, | 225 | static int iwlagn_rx_beacon_notif(struct iwl_priv *priv, |
225 | struct iwl_rx_mem_buffer *rxb, | 226 | struct iwl_rx_cmd_buffer *rxb, |
226 | struct iwl_device_cmd *cmd) | 227 | struct iwl_device_cmd *cmd) |
227 | { | 228 | { |
228 | struct iwl_rx_packet *pkt = rxb_addr(rxb); | 229 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
229 | struct iwlagn_beacon_notif *beacon = (void *)pkt->u.raw; | 230 | struct iwlagn_beacon_notif *beacon = (void *)pkt->data; |
230 | #ifdef CONFIG_IWLWIFI_DEBUG | 231 | #ifdef CONFIG_IWLWIFI_DEBUG |
231 | u16 status = le16_to_cpu(beacon->beacon_notify_hdr.status.status); | 232 | u16 status = le16_to_cpu(beacon->beacon_notify_hdr.status.status); |
232 | u8 rate = iwl_hw_get_rate(beacon->beacon_notify_hdr.rate_n_flags); | 233 | u8 rate = iwl_hw_get_rate(beacon->beacon_notify_hdr.rate_n_flags); |
@@ -266,6 +267,8 @@ static bool iwlagn_good_ack_health(struct iwl_priv *priv, | |||
266 | if (priv->agg_tids_count) | 267 | if (priv->agg_tids_count) |
267 | return true; | 268 | return true; |
268 | 269 | ||
270 | lockdep_assert_held(&priv->statistics.lock); | ||
271 | |||
269 | old = &priv->statistics.tx; | 272 | old = &priv->statistics.tx; |
270 | 273 | ||
271 | actual_delta = le32_to_cpu(cur->actual_ack_cnt) - | 274 | actual_delta = le32_to_cpu(cur->actual_ack_cnt) - |
@@ -318,7 +321,7 @@ static bool iwlagn_good_plcp_health(struct iwl_priv *priv, | |||
318 | unsigned int msecs) | 321 | unsigned int msecs) |
319 | { | 322 | { |
320 | int delta; | 323 | int delta; |
321 | int threshold = cfg(priv)->base_params->plcp_delta_threshold; | 324 | int threshold = priv->plcp_delta_threshold; |
322 | 325 | ||
323 | if (threshold == IWL_MAX_PLCP_ERR_THRESHOLD_DISABLE) { | 326 | if (threshold == IWL_MAX_PLCP_ERR_THRESHOLD_DISABLE) { |
324 | IWL_DEBUG_RADIO(priv, "plcp_err check disabled\n"); | 327 | IWL_DEBUG_RADIO(priv, "plcp_err check disabled\n"); |
@@ -352,7 +355,7 @@ static void iwlagn_recover_from_statistics(struct iwl_priv *priv, | |||
352 | { | 355 | { |
353 | unsigned int msecs; | 356 | unsigned int msecs; |
354 | 357 | ||
355 | if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) | 358 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) |
356 | return; | 359 | return; |
357 | 360 | ||
358 | msecs = jiffies_to_msecs(stamp - priv->rx_statistics_jiffies); | 361 | msecs = jiffies_to_msecs(stamp - priv->rx_statistics_jiffies); |
@@ -487,7 +490,7 @@ iwlagn_accumulative_statistics(struct iwl_priv *priv, | |||
487 | #endif | 490 | #endif |
488 | 491 | ||
489 | static int iwlagn_rx_statistics(struct iwl_priv *priv, | 492 | static int iwlagn_rx_statistics(struct iwl_priv *priv, |
490 | struct iwl_rx_mem_buffer *rxb, | 493 | struct iwl_rx_cmd_buffer *rxb, |
491 | struct iwl_device_cmd *cmd) | 494 | struct iwl_device_cmd *cmd) |
492 | { | 495 | { |
493 | unsigned long stamp = jiffies; | 496 | unsigned long stamp = jiffies; |
@@ -509,9 +512,11 @@ static int iwlagn_rx_statistics(struct iwl_priv *priv, | |||
509 | IWL_DEBUG_RX(priv, "Statistics notification received (%d bytes).\n", | 512 | IWL_DEBUG_RX(priv, "Statistics notification received (%d bytes).\n", |
510 | len); | 513 | len); |
511 | 514 | ||
515 | spin_lock(&priv->statistics.lock); | ||
516 | |||
512 | if (len == sizeof(struct iwl_bt_notif_statistics)) { | 517 | if (len == sizeof(struct iwl_bt_notif_statistics)) { |
513 | struct iwl_bt_notif_statistics *stats; | 518 | struct iwl_bt_notif_statistics *stats; |
514 | stats = &pkt->u.stats_bt; | 519 | stats = (void *)&pkt->data; |
515 | flag = &stats->flag; | 520 | flag = &stats->flag; |
516 | common = &stats->general.common; | 521 | common = &stats->general.common; |
517 | rx_non_phy = &stats->rx.general.common; | 522 | rx_non_phy = &stats->rx.general.common; |
@@ -529,7 +534,7 @@ static int iwlagn_rx_statistics(struct iwl_priv *priv, | |||
529 | #endif | 534 | #endif |
530 | } else if (len == sizeof(struct iwl_notif_statistics)) { | 535 | } else if (len == sizeof(struct iwl_notif_statistics)) { |
531 | struct iwl_notif_statistics *stats; | 536 | struct iwl_notif_statistics *stats; |
532 | stats = &pkt->u.stats; | 537 | stats = (void *)&pkt->data; |
533 | flag = &stats->flag; | 538 | flag = &stats->flag; |
534 | common = &stats->general.common; | 539 | common = &stats->general.common; |
535 | rx_non_phy = &stats->rx.general; | 540 | rx_non_phy = &stats->rx.general; |
@@ -542,6 +547,7 @@ static int iwlagn_rx_statistics(struct iwl_priv *priv, | |||
542 | WARN_ONCE(1, "len %d doesn't match BT (%zu) or normal (%zu)\n", | 547 | WARN_ONCE(1, "len %d doesn't match BT (%zu) or normal (%zu)\n", |
543 | len, sizeof(struct iwl_bt_notif_statistics), | 548 | len, sizeof(struct iwl_bt_notif_statistics), |
544 | sizeof(struct iwl_notif_statistics)); | 549 | sizeof(struct iwl_notif_statistics)); |
550 | spin_unlock(&priv->statistics.lock); | ||
545 | return 0; | 551 | return 0; |
546 | } | 552 | } |
547 | 553 | ||
@@ -569,7 +575,7 @@ static int iwlagn_rx_statistics(struct iwl_priv *priv, | |||
569 | 575 | ||
570 | priv->rx_statistics_jiffies = stamp; | 576 | priv->rx_statistics_jiffies = stamp; |
571 | 577 | ||
572 | set_bit(STATUS_STATISTICS, &priv->shrd->status); | 578 | set_bit(STATUS_STATISTICS, &priv->status); |
573 | 579 | ||
574 | /* Reschedule the statistics timer to occur in | 580 | /* Reschedule the statistics timer to occur in |
575 | * reg_recalib_period seconds to ensure we get a | 581 | * reg_recalib_period seconds to ensure we get a |
@@ -578,23 +584,27 @@ static int iwlagn_rx_statistics(struct iwl_priv *priv, | |||
578 | mod_timer(&priv->statistics_periodic, jiffies + | 584 | mod_timer(&priv->statistics_periodic, jiffies + |
579 | msecs_to_jiffies(reg_recalib_period * 1000)); | 585 | msecs_to_jiffies(reg_recalib_period * 1000)); |
580 | 586 | ||
581 | if (unlikely(!test_bit(STATUS_SCANNING, &priv->shrd->status)) && | 587 | if (unlikely(!test_bit(STATUS_SCANNING, &priv->status)) && |
582 | (pkt->hdr.cmd == STATISTICS_NOTIFICATION)) { | 588 | (pkt->hdr.cmd == STATISTICS_NOTIFICATION)) { |
583 | iwlagn_rx_calc_noise(priv); | 589 | iwlagn_rx_calc_noise(priv); |
584 | queue_work(priv->workqueue, &priv->run_time_calib_work); | 590 | queue_work(priv->workqueue, &priv->run_time_calib_work); |
585 | } | 591 | } |
586 | if (cfg(priv)->lib->temperature && change) | 592 | if (cfg(priv)->lib->temperature && change) |
587 | cfg(priv)->lib->temperature(priv); | 593 | cfg(priv)->lib->temperature(priv); |
594 | |||
595 | spin_unlock(&priv->statistics.lock); | ||
596 | |||
588 | return 0; | 597 | return 0; |
589 | } | 598 | } |
590 | 599 | ||
591 | static int iwlagn_rx_reply_statistics(struct iwl_priv *priv, | 600 | static int iwlagn_rx_reply_statistics(struct iwl_priv *priv, |
592 | struct iwl_rx_mem_buffer *rxb, | 601 | struct iwl_rx_cmd_buffer *rxb, |
593 | struct iwl_device_cmd *cmd) | 602 | struct iwl_device_cmd *cmd) |
594 | { | 603 | { |
595 | struct iwl_rx_packet *pkt = rxb_addr(rxb); | 604 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
605 | struct iwl_notif_statistics *stats = (void *)pkt->data; | ||
596 | 606 | ||
597 | if (le32_to_cpu(pkt->u.stats.flag) & UCODE_STATISTICS_CLEAR_MSK) { | 607 | if (le32_to_cpu(stats->flag) & UCODE_STATISTICS_CLEAR_MSK) { |
598 | #ifdef CONFIG_IWLWIFI_DEBUGFS | 608 | #ifdef CONFIG_IWLWIFI_DEBUGFS |
599 | memset(&priv->accum_stats, 0, | 609 | memset(&priv->accum_stats, 0, |
600 | sizeof(priv->accum_stats)); | 610 | sizeof(priv->accum_stats)); |
@@ -612,12 +622,13 @@ static int iwlagn_rx_reply_statistics(struct iwl_priv *priv, | |||
612 | /* Handle notification from uCode that card's power state is changing | 622 | /* Handle notification from uCode that card's power state is changing |
613 | * due to software, hardware, or critical temperature RFKILL */ | 623 | * due to software, hardware, or critical temperature RFKILL */ |
614 | static int iwlagn_rx_card_state_notif(struct iwl_priv *priv, | 624 | static int iwlagn_rx_card_state_notif(struct iwl_priv *priv, |
615 | struct iwl_rx_mem_buffer *rxb, | 625 | struct iwl_rx_cmd_buffer *rxb, |
616 | struct iwl_device_cmd *cmd) | 626 | struct iwl_device_cmd *cmd) |
617 | { | 627 | { |
618 | struct iwl_rx_packet *pkt = rxb_addr(rxb); | 628 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
619 | u32 flags = le32_to_cpu(pkt->u.card_state_notif.flags); | 629 | struct iwl_card_state_notif *card_state_notif = (void *)pkt->data; |
620 | unsigned long status = priv->shrd->status; | 630 | u32 flags = le32_to_cpu(card_state_notif->flags); |
631 | unsigned long status = priv->status; | ||
621 | 632 | ||
622 | IWL_DEBUG_RF_KILL(priv, "Card state received: HW:%s SW:%s CT:%s\n", | 633 | IWL_DEBUG_RF_KILL(priv, "Card state received: HW:%s SW:%s CT:%s\n", |
623 | (flags & HW_CARD_DISABLED) ? "Kill" : "On", | 634 | (flags & HW_CARD_DISABLED) ? "Kill" : "On", |
@@ -647,32 +658,31 @@ static int iwlagn_rx_card_state_notif(struct iwl_priv *priv, | |||
647 | iwl_tt_exit_ct_kill(priv); | 658 | iwl_tt_exit_ct_kill(priv); |
648 | 659 | ||
649 | if (flags & HW_CARD_DISABLED) | 660 | if (flags & HW_CARD_DISABLED) |
650 | set_bit(STATUS_RF_KILL_HW, &priv->shrd->status); | 661 | set_bit(STATUS_RF_KILL_HW, &priv->status); |
651 | else | 662 | else |
652 | clear_bit(STATUS_RF_KILL_HW, &priv->shrd->status); | 663 | clear_bit(STATUS_RF_KILL_HW, &priv->status); |
653 | 664 | ||
654 | 665 | ||
655 | if (!(flags & RXON_CARD_DISABLED)) | 666 | if (!(flags & RXON_CARD_DISABLED)) |
656 | iwl_scan_cancel(priv); | 667 | iwl_scan_cancel(priv); |
657 | 668 | ||
658 | if ((test_bit(STATUS_RF_KILL_HW, &status) != | 669 | if ((test_bit(STATUS_RF_KILL_HW, &status) != |
659 | test_bit(STATUS_RF_KILL_HW, &priv->shrd->status))) | 670 | test_bit(STATUS_RF_KILL_HW, &priv->status))) |
660 | wiphy_rfkill_set_hw_state(priv->hw->wiphy, | 671 | wiphy_rfkill_set_hw_state(priv->hw->wiphy, |
661 | test_bit(STATUS_RF_KILL_HW, &priv->shrd->status)); | 672 | test_bit(STATUS_RF_KILL_HW, &priv->status)); |
662 | else | 673 | else |
663 | wake_up(&priv->shrd->wait_command_queue); | 674 | wake_up(&trans(priv)->wait_command_queue); |
664 | return 0; | 675 | return 0; |
665 | } | 676 | } |
666 | 677 | ||
667 | static int iwlagn_rx_missed_beacon_notif(struct iwl_priv *priv, | 678 | static int iwlagn_rx_missed_beacon_notif(struct iwl_priv *priv, |
668 | struct iwl_rx_mem_buffer *rxb, | 679 | struct iwl_rx_cmd_buffer *rxb, |
669 | struct iwl_device_cmd *cmd) | 680 | struct iwl_device_cmd *cmd) |
670 | 681 | ||
671 | { | 682 | { |
672 | struct iwl_rx_packet *pkt = rxb_addr(rxb); | 683 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
673 | struct iwl_missed_beacon_notif *missed_beacon; | 684 | struct iwl_missed_beacon_notif *missed_beacon = (void *)pkt->data; |
674 | 685 | ||
675 | missed_beacon = &pkt->u.missed_beacon; | ||
676 | if (le32_to_cpu(missed_beacon->consecutive_missed_beacons) > | 686 | if (le32_to_cpu(missed_beacon->consecutive_missed_beacons) > |
677 | priv->missed_beacon_threshold) { | 687 | priv->missed_beacon_threshold) { |
678 | IWL_DEBUG_CALIB(priv, | 688 | IWL_DEBUG_CALIB(priv, |
@@ -681,7 +691,7 @@ static int iwlagn_rx_missed_beacon_notif(struct iwl_priv *priv, | |||
681 | le32_to_cpu(missed_beacon->total_missed_becons), | 691 | le32_to_cpu(missed_beacon->total_missed_becons), |
682 | le32_to_cpu(missed_beacon->num_recvd_beacons), | 692 | le32_to_cpu(missed_beacon->num_recvd_beacons), |
683 | le32_to_cpu(missed_beacon->num_expected_beacons)); | 693 | le32_to_cpu(missed_beacon->num_expected_beacons)); |
684 | if (!test_bit(STATUS_SCANNING, &priv->shrd->status)) | 694 | if (!test_bit(STATUS_SCANNING, &priv->status)) |
685 | iwl_init_sensitivity(priv); | 695 | iwl_init_sensitivity(priv); |
686 | } | 696 | } |
687 | return 0; | 697 | return 0; |
@@ -690,13 +700,13 @@ static int iwlagn_rx_missed_beacon_notif(struct iwl_priv *priv, | |||
690 | /* Cache phy data (Rx signal strength, etc) for HT frame (REPLY_RX_PHY_CMD). | 700 | /* Cache phy data (Rx signal strength, etc) for HT frame (REPLY_RX_PHY_CMD). |
691 | * This will be used later in iwl_rx_reply_rx() for REPLY_RX_MPDU_CMD. */ | 701 | * This will be used later in iwl_rx_reply_rx() for REPLY_RX_MPDU_CMD. */ |
692 | static int iwlagn_rx_reply_rx_phy(struct iwl_priv *priv, | 702 | static int iwlagn_rx_reply_rx_phy(struct iwl_priv *priv, |
693 | struct iwl_rx_mem_buffer *rxb, | 703 | struct iwl_rx_cmd_buffer *rxb, |
694 | struct iwl_device_cmd *cmd) | 704 | struct iwl_device_cmd *cmd) |
695 | { | 705 | { |
696 | struct iwl_rx_packet *pkt = rxb_addr(rxb); | 706 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
697 | 707 | ||
698 | priv->last_phy_res_valid = true; | 708 | priv->last_phy_res_valid = true; |
699 | memcpy(&priv->last_phy_res, pkt->u.raw, | 709 | memcpy(&priv->last_phy_res, pkt->data, |
700 | sizeof(struct iwl_rx_phy_res)); | 710 | sizeof(struct iwl_rx_phy_res)); |
701 | return 0; | 711 | return 0; |
702 | } | 712 | } |
@@ -757,12 +767,14 @@ static void iwlagn_pass_packet_to_mac80211(struct iwl_priv *priv, | |||
757 | struct ieee80211_hdr *hdr, | 767 | struct ieee80211_hdr *hdr, |
758 | u16 len, | 768 | u16 len, |
759 | u32 ampdu_status, | 769 | u32 ampdu_status, |
760 | struct iwl_rx_mem_buffer *rxb, | 770 | struct iwl_rx_cmd_buffer *rxb, |
761 | struct ieee80211_rx_status *stats) | 771 | struct ieee80211_rx_status *stats) |
762 | { | 772 | { |
763 | struct sk_buff *skb; | 773 | struct sk_buff *skb; |
764 | __le16 fc = hdr->frame_control; | 774 | __le16 fc = hdr->frame_control; |
765 | struct iwl_rxon_context *ctx; | 775 | struct iwl_rxon_context *ctx; |
776 | struct page *p; | ||
777 | int offset; | ||
766 | 778 | ||
767 | /* We only process data packets if the interface is open */ | 779 | /* We only process data packets if the interface is open */ |
768 | if (unlikely(!priv->is_open)) { | 780 | if (unlikely(!priv->is_open)) { |
@@ -782,7 +794,9 @@ static void iwlagn_pass_packet_to_mac80211(struct iwl_priv *priv, | |||
782 | return; | 794 | return; |
783 | } | 795 | } |
784 | 796 | ||
785 | skb_add_rx_frag(skb, 0, rxb->page, (void *)hdr - rxb_addr(rxb), len); | 797 | offset = (void *)hdr - rxb_addr(rxb); |
798 | p = rxb_steal_page(rxb); | ||
799 | skb_add_rx_frag(skb, 0, p, offset, len); | ||
786 | 800 | ||
787 | iwl_update_stats(priv, false, fc, len); | 801 | iwl_update_stats(priv, false, fc, len); |
788 | 802 | ||
@@ -793,23 +807,18 @@ static void iwlagn_pass_packet_to_mac80211(struct iwl_priv *priv, | |||
793 | * sometimes even after already having transmitted frames for the | 807 | * sometimes even after already having transmitted frames for the |
794 | * association because the new RXON may reset the information. | 808 | * association because the new RXON may reset the information. |
795 | */ | 809 | */ |
796 | if (unlikely(ieee80211_is_beacon(fc))) { | 810 | if (unlikely(ieee80211_is_beacon(fc) && priv->passive_no_rx)) { |
797 | for_each_context(priv, ctx) { | 811 | for_each_context(priv, ctx) { |
798 | if (!ctx->last_tx_rejected) | ||
799 | continue; | ||
800 | if (compare_ether_addr(hdr->addr3, | 812 | if (compare_ether_addr(hdr->addr3, |
801 | ctx->active.bssid_addr)) | 813 | ctx->active.bssid_addr)) |
802 | continue; | 814 | continue; |
803 | ctx->last_tx_rejected = false; | 815 | iwlagn_lift_passive_no_rx(priv); |
804 | iwl_trans_wake_any_queue(trans(priv), ctx->ctxid, | ||
805 | "channel got active"); | ||
806 | } | 816 | } |
807 | } | 817 | } |
808 | 818 | ||
809 | memcpy(IEEE80211_SKB_RXCB(skb), stats, sizeof(*stats)); | 819 | memcpy(IEEE80211_SKB_RXCB(skb), stats, sizeof(*stats)); |
810 | 820 | ||
811 | ieee80211_rx(priv->hw, skb); | 821 | ieee80211_rx(priv->hw, skb); |
812 | rxb->page = NULL; | ||
813 | } | 822 | } |
814 | 823 | ||
815 | static u32 iwlagn_translate_rx_status(struct iwl_priv *priv, u32 decrypt_in) | 824 | static u32 iwlagn_translate_rx_status(struct iwl_priv *priv, u32 decrypt_in) |
@@ -915,7 +924,7 @@ static int iwlagn_calc_rssi(struct iwl_priv *priv, | |||
915 | /* Called for REPLY_RX (legacy ABG frames), or | 924 | /* Called for REPLY_RX (legacy ABG frames), or |
916 | * REPLY_RX_MPDU_CMD (HT high-throughput N frames). */ | 925 | * REPLY_RX_MPDU_CMD (HT high-throughput N frames). */ |
917 | static int iwlagn_rx_reply_rx(struct iwl_priv *priv, | 926 | static int iwlagn_rx_reply_rx(struct iwl_priv *priv, |
918 | struct iwl_rx_mem_buffer *rxb, | 927 | struct iwl_rx_cmd_buffer *rxb, |
919 | struct iwl_device_cmd *cmd) | 928 | struct iwl_device_cmd *cmd) |
920 | { | 929 | { |
921 | struct ieee80211_hdr *header; | 930 | struct ieee80211_hdr *header; |
@@ -938,12 +947,12 @@ static int iwlagn_rx_reply_rx(struct iwl_priv *priv, | |||
938 | * received. | 947 | * received. |
939 | */ | 948 | */ |
940 | if (pkt->hdr.cmd == REPLY_RX) { | 949 | if (pkt->hdr.cmd == REPLY_RX) { |
941 | phy_res = (struct iwl_rx_phy_res *)pkt->u.raw; | 950 | phy_res = (struct iwl_rx_phy_res *)pkt->data; |
942 | header = (struct ieee80211_hdr *)(pkt->u.raw + sizeof(*phy_res) | 951 | header = (struct ieee80211_hdr *)(pkt->data + sizeof(*phy_res) |
943 | + phy_res->cfg_phy_cnt); | 952 | + phy_res->cfg_phy_cnt); |
944 | 953 | ||
945 | len = le16_to_cpu(phy_res->byte_count); | 954 | len = le16_to_cpu(phy_res->byte_count); |
946 | rx_pkt_status = *(__le32 *)(pkt->u.raw + sizeof(*phy_res) + | 955 | rx_pkt_status = *(__le32 *)(pkt->data + sizeof(*phy_res) + |
947 | phy_res->cfg_phy_cnt + len); | 956 | phy_res->cfg_phy_cnt + len); |
948 | ampdu_status = le32_to_cpu(rx_pkt_status); | 957 | ampdu_status = le32_to_cpu(rx_pkt_status); |
949 | } else { | 958 | } else { |
@@ -952,10 +961,10 @@ static int iwlagn_rx_reply_rx(struct iwl_priv *priv, | |||
952 | return 0; | 961 | return 0; |
953 | } | 962 | } |
954 | phy_res = &priv->last_phy_res; | 963 | phy_res = &priv->last_phy_res; |
955 | amsdu = (struct iwl_rx_mpdu_res_start *)pkt->u.raw; | 964 | amsdu = (struct iwl_rx_mpdu_res_start *)pkt->data; |
956 | header = (struct ieee80211_hdr *)(pkt->u.raw + sizeof(*amsdu)); | 965 | header = (struct ieee80211_hdr *)(pkt->data + sizeof(*amsdu)); |
957 | len = le16_to_cpu(amsdu->byte_count); | 966 | len = le16_to_cpu(amsdu->byte_count); |
958 | rx_pkt_status = *(__le32 *)(pkt->u.raw + sizeof(*amsdu) + len); | 967 | rx_pkt_status = *(__le32 *)(pkt->data + sizeof(*amsdu) + len); |
959 | ampdu_status = iwlagn_translate_rx_status(priv, | 968 | ampdu_status = iwlagn_translate_rx_status(priv, |
960 | le32_to_cpu(rx_pkt_status)); | 969 | le32_to_cpu(rx_pkt_status)); |
961 | } | 970 | } |
@@ -1035,12 +1044,12 @@ static int iwlagn_rx_reply_rx(struct iwl_priv *priv, | |||
1035 | } | 1044 | } |
1036 | 1045 | ||
1037 | static int iwlagn_rx_noa_notification(struct iwl_priv *priv, | 1046 | static int iwlagn_rx_noa_notification(struct iwl_priv *priv, |
1038 | struct iwl_rx_mem_buffer *rxb, | 1047 | struct iwl_rx_cmd_buffer *rxb, |
1039 | struct iwl_device_cmd *cmd) | 1048 | struct iwl_device_cmd *cmd) |
1040 | { | 1049 | { |
1041 | struct iwl_wipan_noa_data *new_data, *old_data; | 1050 | struct iwl_wipan_noa_data *new_data, *old_data; |
1042 | struct iwl_rx_packet *pkt = rxb_addr(rxb); | 1051 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
1043 | struct iwl_wipan_noa_notification *noa_notif = (void *)pkt->u.raw; | 1052 | struct iwl_wipan_noa_notification *noa_notif = (void *)pkt->data; |
1044 | 1053 | ||
1045 | /* no condition -- we're in softirq */ | 1054 | /* no condition -- we're in softirq */ |
1046 | old_data = rcu_dereference_protected(priv->noa_data, true); | 1055 | old_data = rcu_dereference_protected(priv->noa_data, true); |
@@ -1086,7 +1095,7 @@ static int iwlagn_rx_noa_notification(struct iwl_priv *priv, | |||
1086 | */ | 1095 | */ |
1087 | void iwl_setup_rx_handlers(struct iwl_priv *priv) | 1096 | void iwl_setup_rx_handlers(struct iwl_priv *priv) |
1088 | { | 1097 | { |
1089 | int (**handlers)(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb, | 1098 | int (**handlers)(struct iwl_priv *priv, struct iwl_rx_cmd_buffer *rxb, |
1090 | struct iwl_device_cmd *cmd); | 1099 | struct iwl_device_cmd *cmd); |
1091 | 1100 | ||
1092 | handlers = priv->rx_handlers; | 1101 | handlers = priv->rx_handlers; |
@@ -1131,21 +1140,20 @@ void iwl_setup_rx_handlers(struct iwl_priv *priv) | |||
1131 | priv->rx_handlers[REPLY_TX] = iwlagn_rx_reply_tx; | 1140 | priv->rx_handlers[REPLY_TX] = iwlagn_rx_reply_tx; |
1132 | 1141 | ||
1133 | /* set up notification wait support */ | 1142 | /* set up notification wait support */ |
1134 | spin_lock_init(&priv->shrd->notif_wait_lock); | 1143 | iwl_notification_wait_init(&priv->notif_wait); |
1135 | INIT_LIST_HEAD(&priv->shrd->notif_waits); | ||
1136 | init_waitqueue_head(&priv->shrd->notif_waitq); | ||
1137 | 1144 | ||
1138 | /* Set up BT Rx handlers */ | 1145 | /* Set up BT Rx handlers */ |
1139 | if (cfg(priv)->lib->bt_rx_handler_setup) | 1146 | if (cfg(priv)->bt_params) |
1140 | cfg(priv)->lib->bt_rx_handler_setup(priv); | 1147 | iwlagn_bt_rx_handler_setup(priv); |
1141 | |||
1142 | } | 1148 | } |
1143 | 1149 | ||
1144 | int iwl_rx_dispatch(struct iwl_op_mode *op_mode, struct iwl_rx_mem_buffer *rxb, | 1150 | int iwl_rx_dispatch(struct iwl_op_mode *op_mode, struct iwl_rx_cmd_buffer *rxb, |
1145 | struct iwl_device_cmd *cmd) | 1151 | struct iwl_device_cmd *cmd) |
1146 | { | 1152 | { |
1147 | struct iwl_rx_packet *pkt = rxb_addr(rxb); | 1153 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
1148 | struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode); | 1154 | struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode); |
1155 | void (*pre_rx_handler)(struct iwl_priv *, | ||
1156 | struct iwl_rx_cmd_buffer *); | ||
1149 | int err = 0; | 1157 | int err = 0; |
1150 | 1158 | ||
1151 | /* | 1159 | /* |
@@ -1153,30 +1161,22 @@ int iwl_rx_dispatch(struct iwl_op_mode *op_mode, struct iwl_rx_mem_buffer *rxb, | |||
1153 | * even if the RX handler consumes the RXB we have | 1161 | * even if the RX handler consumes the RXB we have |
1154 | * access to it in the notification wait entry. | 1162 | * access to it in the notification wait entry. |
1155 | */ | 1163 | */ |
1156 | if (!list_empty(&priv->shrd->notif_waits)) { | 1164 | iwl_notification_wait_notify(&priv->notif_wait, pkt); |
1157 | struct iwl_notification_wait *w; | 1165 | |
1158 | 1166 | /* RX data may be forwarded to userspace (using pre_rx_handler) in one | |
1159 | spin_lock(&priv->shrd->notif_wait_lock); | 1167 | * of two cases: the first, that the user owns the uCode through |
1160 | list_for_each_entry(w, &priv->shrd->notif_waits, list) { | 1168 | * testmode - in such case the pre_rx_handler is set and no further |
1161 | if (w->cmd != pkt->hdr.cmd) | 1169 | * processing takes place. The other case is when the user want to |
1162 | continue; | 1170 | * monitor the rx w/o affecting the regular flow - the pre_rx_handler |
1163 | IWL_DEBUG_RX(priv, | 1171 | * will be set but the ownership flag != IWL_OWNERSHIP_TM and the flow |
1164 | "Notif: %s, 0x%02x - wake the callers up\n", | 1172 | * continues. |
1165 | get_cmd_string(pkt->hdr.cmd), | 1173 | * We need to use ACCESS_ONCE to prevent a case where the handler |
1166 | pkt->hdr.cmd); | 1174 | * changes between the check and the call. |
1167 | w->triggered = true; | 1175 | */ |
1168 | if (w->fn) | 1176 | pre_rx_handler = ACCESS_ONCE(priv->pre_rx_handler); |
1169 | w->fn(trans(priv), pkt, w->fn_data); | 1177 | if (pre_rx_handler) |
1170 | } | 1178 | pre_rx_handler(priv, rxb); |
1171 | spin_unlock(&priv->shrd->notif_wait_lock); | 1179 | if (priv->ucode_owner != IWL_OWNERSHIP_TM) { |
1172 | |||
1173 | wake_up_all(&priv->shrd->notif_waitq); | ||
1174 | } | ||
1175 | |||
1176 | if (priv->pre_rx_handler && | ||
1177 | priv->shrd->ucode_owner == IWL_OWNERSHIP_TM) | ||
1178 | priv->pre_rx_handler(priv, rxb); | ||
1179 | else { | ||
1180 | /* Based on type of command response or notification, | 1180 | /* Based on type of command response or notification, |
1181 | * handle those that need handling via function in | 1181 | * handle those that need handling via function in |
1182 | * rx_handlers table. See iwl_setup_rx_handlers() */ | 1182 | * rx_handlers table. See iwl_setup_rx_handlers() */ |