diff options
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-agn.c')
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-agn.c | 1229 |
1 files changed, 943 insertions, 286 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 921dc4a26fe2..bdff56583e11 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /****************************************************************************** | 1 | /****************************************************************************** |
2 | * | 2 | * |
3 | * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved. | 3 | * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved. |
4 | * | 4 | * |
5 | * Portions of this file are derived from the ipw3945 project, as well | 5 | * Portions of this file are derived from the ipw3945 project, as well |
6 | * as portions of the ieee80211 subsystem header files. | 6 | * as portions of the ieee80211 subsystem header files. |
@@ -31,6 +31,7 @@ | |||
31 | #include <linux/module.h> | 31 | #include <linux/module.h> |
32 | #include <linux/init.h> | 32 | #include <linux/init.h> |
33 | #include <linux/pci.h> | 33 | #include <linux/pci.h> |
34 | #include <linux/slab.h> | ||
34 | #include <linux/dma-mapping.h> | 35 | #include <linux/dma-mapping.h> |
35 | #include <linux/delay.h> | 36 | #include <linux/delay.h> |
36 | #include <linux/sched.h> | 37 | #include <linux/sched.h> |
@@ -73,13 +74,7 @@ | |||
73 | #define VD | 74 | #define VD |
74 | #endif | 75 | #endif |
75 | 76 | ||
76 | #ifdef CONFIG_IWLWIFI_SPECTRUM_MEASUREMENT | 77 | #define DRV_VERSION IWLWIFI_VERSION VD |
77 | #define VS "s" | ||
78 | #else | ||
79 | #define VS | ||
80 | #endif | ||
81 | |||
82 | #define DRV_VERSION IWLWIFI_VERSION VD VS | ||
83 | 78 | ||
84 | 79 | ||
85 | MODULE_DESCRIPTION(DRV_DESCRIPTION); | 80 | MODULE_DESCRIPTION(DRV_DESCRIPTION); |
@@ -123,6 +118,17 @@ int iwl_commit_rxon(struct iwl_priv *priv) | |||
123 | return -EINVAL; | 118 | return -EINVAL; |
124 | } | 119 | } |
125 | 120 | ||
121 | /* | ||
122 | * receive commit_rxon request | ||
123 | * abort any previous channel switch if still in process | ||
124 | */ | ||
125 | if (priv->switch_rxon.switch_in_progress && | ||
126 | (priv->switch_rxon.channel != priv->staging_rxon.channel)) { | ||
127 | IWL_DEBUG_11H(priv, "abort channel switch on %d\n", | ||
128 | le16_to_cpu(priv->switch_rxon.channel)); | ||
129 | priv->switch_rxon.switch_in_progress = false; | ||
130 | } | ||
131 | |||
126 | /* If we don't need to send a full RXON, we can use | 132 | /* If we don't need to send a full RXON, we can use |
127 | * iwl_rxon_assoc_cmd which is used to reconfigure filter | 133 | * iwl_rxon_assoc_cmd which is used to reconfigure filter |
128 | * and other flags for the current radio configuration. */ | 134 | * and other flags for the current radio configuration. */ |
@@ -134,6 +140,7 @@ int iwl_commit_rxon(struct iwl_priv *priv) | |||
134 | } | 140 | } |
135 | 141 | ||
136 | memcpy(active_rxon, &priv->staging_rxon, sizeof(*active_rxon)); | 142 | memcpy(active_rxon, &priv->staging_rxon, sizeof(*active_rxon)); |
143 | iwl_print_rx_config_cmd(priv); | ||
137 | return 0; | 144 | return 0; |
138 | } | 145 | } |
139 | 146 | ||
@@ -191,11 +198,8 @@ int iwl_commit_rxon(struct iwl_priv *priv) | |||
191 | priv->start_calib = 0; | 198 | priv->start_calib = 0; |
192 | 199 | ||
193 | /* Add the broadcast address so we can send broadcast frames */ | 200 | /* Add the broadcast address so we can send broadcast frames */ |
194 | if (iwl_rxon_add_station(priv, iwl_bcast_addr, 0) == | 201 | priv->cfg->ops->lib->add_bcast_station(priv); |
195 | IWL_INVALID_STATION) { | 202 | |
196 | IWL_ERR(priv, "Error adding BROADCAST address for transmit.\n"); | ||
197 | return -EIO; | ||
198 | } | ||
199 | 203 | ||
200 | /* If we have set the ASSOC_MSK and we are in BSS mode then | 204 | /* If we have set the ASSOC_MSK and we are in BSS mode then |
201 | * add the IWL_AP_ID to the station rate table */ | 205 | * add the IWL_AP_ID to the station rate table */ |
@@ -233,6 +237,7 @@ int iwl_commit_rxon(struct iwl_priv *priv) | |||
233 | } | 237 | } |
234 | memcpy(active_rxon, &priv->staging_rxon, sizeof(*active_rxon)); | 238 | memcpy(active_rxon, &priv->staging_rxon, sizeof(*active_rxon)); |
235 | } | 239 | } |
240 | iwl_print_rx_config_cmd(priv); | ||
236 | 241 | ||
237 | iwl_init_sensitivity(priv); | 242 | iwl_init_sensitivity(priv); |
238 | 243 | ||
@@ -302,7 +307,7 @@ static void iwl_free_frame(struct iwl_priv *priv, struct iwl_frame *frame) | |||
302 | list_add(&frame->list, &priv->free_frames); | 307 | list_add(&frame->list, &priv->free_frames); |
303 | } | 308 | } |
304 | 309 | ||
305 | static unsigned int iwl_fill_beacon_frame(struct iwl_priv *priv, | 310 | static u32 iwl_fill_beacon_frame(struct iwl_priv *priv, |
306 | struct ieee80211_hdr *hdr, | 311 | struct ieee80211_hdr *hdr, |
307 | int left) | 312 | int left) |
308 | { | 313 | { |
@@ -319,34 +324,74 @@ static unsigned int iwl_fill_beacon_frame(struct iwl_priv *priv, | |||
319 | return priv->ibss_beacon->len; | 324 | return priv->ibss_beacon->len; |
320 | } | 325 | } |
321 | 326 | ||
327 | /* Parse the beacon frame to find the TIM element and set tim_idx & tim_size */ | ||
328 | static void iwl_set_beacon_tim(struct iwl_priv *priv, | ||
329 | struct iwl_tx_beacon_cmd *tx_beacon_cmd, | ||
330 | u8 *beacon, u32 frame_size) | ||
331 | { | ||
332 | u16 tim_idx; | ||
333 | struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)beacon; | ||
334 | |||
335 | /* | ||
336 | * The index is relative to frame start but we start looking at the | ||
337 | * variable-length part of the beacon. | ||
338 | */ | ||
339 | tim_idx = mgmt->u.beacon.variable - beacon; | ||
340 | |||
341 | /* Parse variable-length elements of beacon to find WLAN_EID_TIM */ | ||
342 | while ((tim_idx < (frame_size - 2)) && | ||
343 | (beacon[tim_idx] != WLAN_EID_TIM)) | ||
344 | tim_idx += beacon[tim_idx+1] + 2; | ||
345 | |||
346 | /* If TIM field was found, set variables */ | ||
347 | if ((tim_idx < (frame_size - 1)) && (beacon[tim_idx] == WLAN_EID_TIM)) { | ||
348 | tx_beacon_cmd->tim_idx = cpu_to_le16(tim_idx); | ||
349 | tx_beacon_cmd->tim_size = beacon[tim_idx+1]; | ||
350 | } else | ||
351 | IWL_WARN(priv, "Unable to find TIM Element in beacon\n"); | ||
352 | } | ||
353 | |||
322 | static unsigned int iwl_hw_get_beacon_cmd(struct iwl_priv *priv, | 354 | static unsigned int iwl_hw_get_beacon_cmd(struct iwl_priv *priv, |
323 | struct iwl_frame *frame, u8 rate) | 355 | struct iwl_frame *frame) |
324 | { | 356 | { |
325 | struct iwl_tx_beacon_cmd *tx_beacon_cmd; | 357 | struct iwl_tx_beacon_cmd *tx_beacon_cmd; |
326 | unsigned int frame_size; | 358 | u32 frame_size; |
359 | u32 rate_flags; | ||
360 | u32 rate; | ||
361 | /* | ||
362 | * We have to set up the TX command, the TX Beacon command, and the | ||
363 | * beacon contents. | ||
364 | */ | ||
327 | 365 | ||
366 | /* Initialize memory */ | ||
328 | tx_beacon_cmd = &frame->u.beacon; | 367 | tx_beacon_cmd = &frame->u.beacon; |
329 | memset(tx_beacon_cmd, 0, sizeof(*tx_beacon_cmd)); | 368 | memset(tx_beacon_cmd, 0, sizeof(*tx_beacon_cmd)); |
330 | 369 | ||
331 | tx_beacon_cmd->tx.sta_id = priv->hw_params.bcast_sta_id; | 370 | /* Set up TX beacon contents */ |
332 | tx_beacon_cmd->tx.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE; | ||
333 | |||
334 | frame_size = iwl_fill_beacon_frame(priv, tx_beacon_cmd->frame, | 371 | frame_size = iwl_fill_beacon_frame(priv, tx_beacon_cmd->frame, |
335 | sizeof(frame->u) - sizeof(*tx_beacon_cmd)); | 372 | sizeof(frame->u) - sizeof(*tx_beacon_cmd)); |
373 | if (WARN_ON_ONCE(frame_size > MAX_MPDU_SIZE)) | ||
374 | return 0; | ||
336 | 375 | ||
337 | BUG_ON(frame_size > MAX_MPDU_SIZE); | 376 | /* Set up TX command fields */ |
338 | tx_beacon_cmd->tx.len = cpu_to_le16((u16)frame_size); | 377 | tx_beacon_cmd->tx.len = cpu_to_le16((u16)frame_size); |
378 | tx_beacon_cmd->tx.sta_id = priv->hw_params.bcast_sta_id; | ||
379 | tx_beacon_cmd->tx.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE; | ||
380 | tx_beacon_cmd->tx.tx_flags = TX_CMD_FLG_SEQ_CTL_MSK | | ||
381 | TX_CMD_FLG_TSF_MSK | TX_CMD_FLG_STA_RATE_MSK; | ||
339 | 382 | ||
340 | if ((rate == IWL_RATE_1M_PLCP) || (rate >= IWL_RATE_2M_PLCP)) | 383 | /* Set up TX beacon command fields */ |
341 | tx_beacon_cmd->tx.rate_n_flags = | 384 | iwl_set_beacon_tim(priv, tx_beacon_cmd, (u8 *)tx_beacon_cmd->frame, |
342 | iwl_hw_set_rate_n_flags(rate, RATE_MCS_CCK_MSK); | 385 | frame_size); |
343 | else | ||
344 | tx_beacon_cmd->tx.rate_n_flags = | ||
345 | iwl_hw_set_rate_n_flags(rate, 0); | ||
346 | 386 | ||
347 | tx_beacon_cmd->tx.tx_flags = TX_CMD_FLG_SEQ_CTL_MSK | | 387 | /* Set up packet rate and flags */ |
348 | TX_CMD_FLG_TSF_MSK | | 388 | rate = iwl_rate_get_lowest_plcp(priv); |
349 | TX_CMD_FLG_STA_RATE_MSK; | 389 | priv->mgmt_tx_ant = iwl_toggle_tx_ant(priv, priv->mgmt_tx_ant); |
390 | rate_flags = iwl_ant_idx_to_flags(priv->mgmt_tx_ant); | ||
391 | if ((rate >= IWL_FIRST_CCK_RATE) && (rate <= IWL_LAST_CCK_RATE)) | ||
392 | rate_flags |= RATE_MCS_CCK_MSK; | ||
393 | tx_beacon_cmd->tx.rate_n_flags = iwl_hw_set_rate_n_flags(rate, | ||
394 | rate_flags); | ||
350 | 395 | ||
351 | return sizeof(*tx_beacon_cmd) + frame_size; | 396 | return sizeof(*tx_beacon_cmd) + frame_size; |
352 | } | 397 | } |
@@ -355,19 +400,20 @@ static int iwl_send_beacon_cmd(struct iwl_priv *priv) | |||
355 | struct iwl_frame *frame; | 400 | struct iwl_frame *frame; |
356 | unsigned int frame_size; | 401 | unsigned int frame_size; |
357 | int rc; | 402 | int rc; |
358 | u8 rate; | ||
359 | 403 | ||
360 | frame = iwl_get_free_frame(priv); | 404 | frame = iwl_get_free_frame(priv); |
361 | |||
362 | if (!frame) { | 405 | if (!frame) { |
363 | IWL_ERR(priv, "Could not obtain free frame buffer for beacon " | 406 | IWL_ERR(priv, "Could not obtain free frame buffer for beacon " |
364 | "command.\n"); | 407 | "command.\n"); |
365 | return -ENOMEM; | 408 | return -ENOMEM; |
366 | } | 409 | } |
367 | 410 | ||
368 | rate = iwl_rate_get_lowest_plcp(priv); | 411 | frame_size = iwl_hw_get_beacon_cmd(priv, frame); |
369 | 412 | if (!frame_size) { | |
370 | frame_size = iwl_hw_get_beacon_cmd(priv, frame, rate); | 413 | IWL_ERR(priv, "Error configuring the beacon command\n"); |
414 | iwl_free_frame(priv, frame); | ||
415 | return -EINVAL; | ||
416 | } | ||
371 | 417 | ||
372 | rc = iwl_send_cmd_pdu(priv, REPLY_TX_BEACON, frame_size, | 418 | rc = iwl_send_cmd_pdu(priv, REPLY_TX_BEACON, frame_size, |
373 | &frame->u.cmd[0]); | 419 | &frame->u.cmd[0]); |
@@ -525,7 +571,7 @@ int iwl_hw_tx_queue_init(struct iwl_priv *priv, | |||
525 | static void iwl_rx_reply_alive(struct iwl_priv *priv, | 571 | static void iwl_rx_reply_alive(struct iwl_priv *priv, |
526 | struct iwl_rx_mem_buffer *rxb) | 572 | struct iwl_rx_mem_buffer *rxb) |
527 | { | 573 | { |
528 | struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; | 574 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
529 | struct iwl_alive_resp *palive; | 575 | struct iwl_alive_resp *palive; |
530 | struct delayed_work *pwork; | 576 | struct delayed_work *pwork; |
531 | 577 | ||
@@ -604,14 +650,139 @@ static void iwl_bg_statistics_periodic(unsigned long data) | |||
604 | if (!iwl_is_ready_rf(priv)) | 650 | if (!iwl_is_ready_rf(priv)) |
605 | return; | 651 | return; |
606 | 652 | ||
607 | iwl_send_statistics_request(priv, CMD_ASYNC); | 653 | iwl_send_statistics_request(priv, CMD_ASYNC, false); |
654 | } | ||
655 | |||
656 | |||
657 | static void iwl_print_cont_event_trace(struct iwl_priv *priv, u32 base, | ||
658 | u32 start_idx, u32 num_events, | ||
659 | u32 mode) | ||
660 | { | ||
661 | u32 i; | ||
662 | u32 ptr; /* SRAM byte address of log data */ | ||
663 | u32 ev, time, data; /* event log data */ | ||
664 | unsigned long reg_flags; | ||
665 | |||
666 | if (mode == 0) | ||
667 | ptr = base + (4 * sizeof(u32)) + (start_idx * 2 * sizeof(u32)); | ||
668 | else | ||
669 | ptr = base + (4 * sizeof(u32)) + (start_idx * 3 * sizeof(u32)); | ||
670 | |||
671 | /* Make sure device is powered up for SRAM reads */ | ||
672 | spin_lock_irqsave(&priv->reg_lock, reg_flags); | ||
673 | if (iwl_grab_nic_access(priv)) { | ||
674 | spin_unlock_irqrestore(&priv->reg_lock, reg_flags); | ||
675 | return; | ||
676 | } | ||
677 | |||
678 | /* Set starting address; reads will auto-increment */ | ||
679 | _iwl_write_direct32(priv, HBUS_TARG_MEM_RADDR, ptr); | ||
680 | rmb(); | ||
681 | |||
682 | /* | ||
683 | * "time" is actually "data" for mode 0 (no timestamp). | ||
684 | * place event id # at far right for easier visual parsing. | ||
685 | */ | ||
686 | for (i = 0; i < num_events; i++) { | ||
687 | ev = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT); | ||
688 | time = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT); | ||
689 | if (mode == 0) { | ||
690 | trace_iwlwifi_dev_ucode_cont_event(priv, | ||
691 | 0, time, ev); | ||
692 | } else { | ||
693 | data = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT); | ||
694 | trace_iwlwifi_dev_ucode_cont_event(priv, | ||
695 | time, data, ev); | ||
696 | } | ||
697 | } | ||
698 | /* Allow device to power down */ | ||
699 | iwl_release_nic_access(priv); | ||
700 | spin_unlock_irqrestore(&priv->reg_lock, reg_flags); | ||
701 | } | ||
702 | |||
703 | static void iwl_continuous_event_trace(struct iwl_priv *priv) | ||
704 | { | ||
705 | u32 capacity; /* event log capacity in # entries */ | ||
706 | u32 base; /* SRAM byte address of event log header */ | ||
707 | u32 mode; /* 0 - no timestamp, 1 - timestamp recorded */ | ||
708 | u32 num_wraps; /* # times uCode wrapped to top of log */ | ||
709 | u32 next_entry; /* index of next entry to be written by uCode */ | ||
710 | |||
711 | if (priv->ucode_type == UCODE_INIT) | ||
712 | base = le32_to_cpu(priv->card_alive_init.error_event_table_ptr); | ||
713 | else | ||
714 | base = le32_to_cpu(priv->card_alive.log_event_table_ptr); | ||
715 | if (priv->cfg->ops->lib->is_valid_rtc_data_addr(base)) { | ||
716 | capacity = iwl_read_targ_mem(priv, base); | ||
717 | num_wraps = iwl_read_targ_mem(priv, base + (2 * sizeof(u32))); | ||
718 | mode = iwl_read_targ_mem(priv, base + (1 * sizeof(u32))); | ||
719 | next_entry = iwl_read_targ_mem(priv, base + (3 * sizeof(u32))); | ||
720 | } else | ||
721 | return; | ||
722 | |||
723 | if (num_wraps == priv->event_log.num_wraps) { | ||
724 | iwl_print_cont_event_trace(priv, | ||
725 | base, priv->event_log.next_entry, | ||
726 | next_entry - priv->event_log.next_entry, | ||
727 | mode); | ||
728 | priv->event_log.non_wraps_count++; | ||
729 | } else { | ||
730 | if ((num_wraps - priv->event_log.num_wraps) > 1) | ||
731 | priv->event_log.wraps_more_count++; | ||
732 | else | ||
733 | priv->event_log.wraps_once_count++; | ||
734 | trace_iwlwifi_dev_ucode_wrap_event(priv, | ||
735 | num_wraps - priv->event_log.num_wraps, | ||
736 | next_entry, priv->event_log.next_entry); | ||
737 | if (next_entry < priv->event_log.next_entry) { | ||
738 | iwl_print_cont_event_trace(priv, base, | ||
739 | priv->event_log.next_entry, | ||
740 | capacity - priv->event_log.next_entry, | ||
741 | mode); | ||
742 | |||
743 | iwl_print_cont_event_trace(priv, base, 0, | ||
744 | next_entry, mode); | ||
745 | } else { | ||
746 | iwl_print_cont_event_trace(priv, base, | ||
747 | next_entry, capacity - next_entry, | ||
748 | mode); | ||
749 | |||
750 | iwl_print_cont_event_trace(priv, base, 0, | ||
751 | next_entry, mode); | ||
752 | } | ||
753 | } | ||
754 | priv->event_log.num_wraps = num_wraps; | ||
755 | priv->event_log.next_entry = next_entry; | ||
756 | } | ||
757 | |||
758 | /** | ||
759 | * iwl_bg_ucode_trace - Timer callback to log ucode event | ||
760 | * | ||
761 | * The timer is continually set to execute every | ||
762 | * UCODE_TRACE_PERIOD milliseconds after the last timer expired | ||
763 | * this function is to perform continuous uCode event logging operation | ||
764 | * if enabled | ||
765 | */ | ||
766 | static void iwl_bg_ucode_trace(unsigned long data) | ||
767 | { | ||
768 | struct iwl_priv *priv = (struct iwl_priv *)data; | ||
769 | |||
770 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) | ||
771 | return; | ||
772 | |||
773 | if (priv->event_log.ucode_trace) { | ||
774 | iwl_continuous_event_trace(priv); | ||
775 | /* Reschedule the timer to occur in UCODE_TRACE_PERIOD */ | ||
776 | mod_timer(&priv->ucode_trace, | ||
777 | jiffies + msecs_to_jiffies(UCODE_TRACE_PERIOD)); | ||
778 | } | ||
608 | } | 779 | } |
609 | 780 | ||
610 | static void iwl_rx_beacon_notif(struct iwl_priv *priv, | 781 | static void iwl_rx_beacon_notif(struct iwl_priv *priv, |
611 | struct iwl_rx_mem_buffer *rxb) | 782 | struct iwl_rx_mem_buffer *rxb) |
612 | { | 783 | { |
613 | #ifdef CONFIG_IWLWIFI_DEBUG | 784 | #ifdef CONFIG_IWLWIFI_DEBUG |
614 | struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; | 785 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
615 | struct iwl4965_beacon_notif *beacon = | 786 | struct iwl4965_beacon_notif *beacon = |
616 | (struct iwl4965_beacon_notif *)pkt->u.raw; | 787 | (struct iwl4965_beacon_notif *)pkt->u.raw; |
617 | u8 rate = iwl_hw_get_rate(beacon->beacon_notify_hdr.rate_n_flags); | 788 | u8 rate = iwl_hw_get_rate(beacon->beacon_notify_hdr.rate_n_flags); |
@@ -635,16 +806,18 @@ static void iwl_rx_beacon_notif(struct iwl_priv *priv, | |||
635 | static void iwl_rx_card_state_notif(struct iwl_priv *priv, | 806 | static void iwl_rx_card_state_notif(struct iwl_priv *priv, |
636 | struct iwl_rx_mem_buffer *rxb) | 807 | struct iwl_rx_mem_buffer *rxb) |
637 | { | 808 | { |
638 | struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; | 809 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
639 | u32 flags = le32_to_cpu(pkt->u.card_state_notif.flags); | 810 | u32 flags = le32_to_cpu(pkt->u.card_state_notif.flags); |
640 | unsigned long status = priv->status; | 811 | unsigned long status = priv->status; |
641 | 812 | ||
642 | IWL_DEBUG_RF_KILL(priv, "Card state received: HW:%s SW:%s\n", | 813 | IWL_DEBUG_RF_KILL(priv, "Card state received: HW:%s SW:%s CT:%s\n", |
643 | (flags & HW_CARD_DISABLED) ? "Kill" : "On", | 814 | (flags & HW_CARD_DISABLED) ? "Kill" : "On", |
644 | (flags & SW_CARD_DISABLED) ? "Kill" : "On"); | 815 | (flags & SW_CARD_DISABLED) ? "Kill" : "On", |
816 | (flags & CT_CARD_DISABLED) ? | ||
817 | "Reached" : "Not reached"); | ||
645 | 818 | ||
646 | if (flags & (SW_CARD_DISABLED | HW_CARD_DISABLED | | 819 | if (flags & (SW_CARD_DISABLED | HW_CARD_DISABLED | |
647 | RF_CARD_DISABLED)) { | 820 | CT_CARD_DISABLED)) { |
648 | 821 | ||
649 | iwl_write32(priv, CSR_UCODE_DRV_GP1_SET, | 822 | iwl_write32(priv, CSR_UCODE_DRV_GP1_SET, |
650 | CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED); | 823 | CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED); |
@@ -658,10 +831,10 @@ static void iwl_rx_card_state_notif(struct iwl_priv *priv, | |||
658 | iwl_write_direct32(priv, HBUS_TARG_MBX_C, | 831 | iwl_write_direct32(priv, HBUS_TARG_MBX_C, |
659 | HBUS_TARG_MBX_C_REG_BIT_CMD_BLOCKED); | 832 | HBUS_TARG_MBX_C_REG_BIT_CMD_BLOCKED); |
660 | } | 833 | } |
661 | if (flags & RF_CARD_DISABLED) | 834 | if (flags & CT_CARD_DISABLED) |
662 | iwl_tt_enter_ct_kill(priv); | 835 | iwl_tt_enter_ct_kill(priv); |
663 | } | 836 | } |
664 | if (!(flags & RF_CARD_DISABLED)) | 837 | if (!(flags & CT_CARD_DISABLED)) |
665 | iwl_tt_exit_ct_kill(priv); | 838 | iwl_tt_exit_ct_kill(priv); |
666 | 839 | ||
667 | if (flags & HW_CARD_DISABLED) | 840 | if (flags & HW_CARD_DISABLED) |
@@ -711,6 +884,8 @@ static void iwl_setup_rx_handlers(struct iwl_priv *priv) | |||
711 | priv->rx_handlers[REPLY_ALIVE] = iwl_rx_reply_alive; | 884 | priv->rx_handlers[REPLY_ALIVE] = iwl_rx_reply_alive; |
712 | priv->rx_handlers[REPLY_ERROR] = iwl_rx_reply_error; | 885 | priv->rx_handlers[REPLY_ERROR] = iwl_rx_reply_error; |
713 | priv->rx_handlers[CHANNEL_SWITCH_NOTIFICATION] = iwl_rx_csa; | 886 | priv->rx_handlers[CHANNEL_SWITCH_NOTIFICATION] = iwl_rx_csa; |
887 | priv->rx_handlers[SPECTRUM_MEASURE_NOTIFICATION] = | ||
888 | iwl_rx_spectrum_measure_notif; | ||
714 | priv->rx_handlers[PM_SLEEP_NOTIFICATION] = iwl_rx_pm_sleep_notif; | 889 | priv->rx_handlers[PM_SLEEP_NOTIFICATION] = iwl_rx_pm_sleep_notif; |
715 | priv->rx_handlers[PM_DEBUG_STATISTIC_NOTIFIC] = | 890 | priv->rx_handlers[PM_DEBUG_STATISTIC_NOTIFIC] = |
716 | iwl_rx_pm_debug_statistics_notif; | 891 | iwl_rx_pm_debug_statistics_notif; |
@@ -721,10 +896,9 @@ static void iwl_setup_rx_handlers(struct iwl_priv *priv) | |||
721 | * statistics request from the host as well as for the periodic | 896 | * statistics request from the host as well as for the periodic |
722 | * statistics notifications (after received beacons) from the uCode. | 897 | * statistics notifications (after received beacons) from the uCode. |
723 | */ | 898 | */ |
724 | priv->rx_handlers[REPLY_STATISTICS_CMD] = iwl_rx_statistics; | 899 | priv->rx_handlers[REPLY_STATISTICS_CMD] = iwl_reply_statistics; |
725 | priv->rx_handlers[STATISTICS_NOTIFICATION] = iwl_rx_statistics; | 900 | priv->rx_handlers[STATISTICS_NOTIFICATION] = iwl_rx_statistics; |
726 | 901 | ||
727 | iwl_setup_spectrum_handlers(priv); | ||
728 | iwl_setup_rx_scan_handlers(priv); | 902 | iwl_setup_rx_scan_handlers(priv); |
729 | 903 | ||
730 | /* status change handler */ | 904 | /* status change handler */ |
@@ -770,7 +944,7 @@ void iwl_rx_handle(struct iwl_priv *priv) | |||
770 | IWL_DEBUG_RX(priv, "r = %d, i = %d\n", r, i); | 944 | IWL_DEBUG_RX(priv, "r = %d, i = %d\n", r, i); |
771 | 945 | ||
772 | /* calculate total frames need to be restock after handling RX */ | 946 | /* calculate total frames need to be restock after handling RX */ |
773 | total_empty = r - priv->rxq.write_actual; | 947 | total_empty = r - rxq->write_actual; |
774 | if (total_empty < 0) | 948 | if (total_empty < 0) |
775 | total_empty += RX_QUEUE_SIZE; | 949 | total_empty += RX_QUEUE_SIZE; |
776 | 950 | ||
@@ -787,10 +961,13 @@ void iwl_rx_handle(struct iwl_priv *priv) | |||
787 | 961 | ||
788 | rxq->queue[i] = NULL; | 962 | rxq->queue[i] = NULL; |
789 | 963 | ||
790 | pci_unmap_single(priv->pci_dev, rxb->real_dma_addr, | 964 | pci_unmap_page(priv->pci_dev, rxb->page_dma, |
791 | priv->hw_params.rx_buf_size + 256, | 965 | PAGE_SIZE << priv->hw_params.rx_page_order, |
792 | PCI_DMA_FROMDEVICE); | 966 | PCI_DMA_FROMDEVICE); |
793 | pkt = (struct iwl_rx_packet *)rxb->skb->data; | 967 | pkt = rxb_addr(rxb); |
968 | |||
969 | trace_iwlwifi_dev_rx(priv, pkt, | ||
970 | le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK); | ||
794 | 971 | ||
795 | /* Reclaim a command buffer only if this packet is a response | 972 | /* Reclaim a command buffer only if this packet is a response |
796 | * to a (driver-originated) command. | 973 | * to a (driver-originated) command. |
@@ -812,8 +989,8 @@ void iwl_rx_handle(struct iwl_priv *priv) | |||
812 | if (priv->rx_handlers[pkt->hdr.cmd]) { | 989 | if (priv->rx_handlers[pkt->hdr.cmd]) { |
813 | IWL_DEBUG_RX(priv, "r = %d, i = %d, %s, 0x%02x\n", r, | 990 | IWL_DEBUG_RX(priv, "r = %d, i = %d, %s, 0x%02x\n", r, |
814 | i, get_cmd_string(pkt->hdr.cmd), pkt->hdr.cmd); | 991 | i, get_cmd_string(pkt->hdr.cmd), pkt->hdr.cmd); |
815 | priv->rx_handlers[pkt->hdr.cmd] (priv, rxb); | ||
816 | priv->isr_stats.rx_handlers[pkt->hdr.cmd]++; | 992 | priv->isr_stats.rx_handlers[pkt->hdr.cmd]++; |
993 | priv->rx_handlers[pkt->hdr.cmd] (priv, rxb); | ||
817 | } else { | 994 | } else { |
818 | /* No handling needed */ | 995 | /* No handling needed */ |
819 | IWL_DEBUG_RX(priv, | 996 | IWL_DEBUG_RX(priv, |
@@ -822,35 +999,45 @@ void iwl_rx_handle(struct iwl_priv *priv) | |||
822 | pkt->hdr.cmd); | 999 | pkt->hdr.cmd); |
823 | } | 1000 | } |
824 | 1001 | ||
1002 | /* | ||
1003 | * XXX: After here, we should always check rxb->page | ||
1004 | * against NULL before touching it or its virtual | ||
1005 | * memory (pkt). Because some rx_handler might have | ||
1006 | * already taken or freed the pages. | ||
1007 | */ | ||
1008 | |||
825 | if (reclaim) { | 1009 | if (reclaim) { |
826 | /* Invoke any callbacks, transfer the skb to caller, and | 1010 | /* Invoke any callbacks, transfer the buffer to caller, |
827 | * fire off the (possibly) blocking iwl_send_cmd() | 1011 | * and fire off the (possibly) blocking iwl_send_cmd() |
828 | * as we reclaim the driver command queue */ | 1012 | * as we reclaim the driver command queue */ |
829 | if (rxb && rxb->skb) | 1013 | if (rxb->page) |
830 | iwl_tx_cmd_complete(priv, rxb); | 1014 | iwl_tx_cmd_complete(priv, rxb); |
831 | else | 1015 | else |
832 | IWL_WARN(priv, "Claim null rxb?\n"); | 1016 | IWL_WARN(priv, "Claim null rxb?\n"); |
833 | } | 1017 | } |
834 | 1018 | ||
835 | /* For now we just don't re-use anything. We can tweak this | 1019 | /* Reuse the page if possible. For notification packets and |
836 | * later to try and re-use notification packets and SKBs that | 1020 | * SKBs that fail to Rx correctly, add them back into the |
837 | * fail to Rx correctly */ | 1021 | * rx_free list for reuse later. */ |
838 | if (rxb->skb != NULL) { | ||
839 | priv->alloc_rxb_skb--; | ||
840 | dev_kfree_skb_any(rxb->skb); | ||
841 | rxb->skb = NULL; | ||
842 | } | ||
843 | |||
844 | spin_lock_irqsave(&rxq->lock, flags); | 1022 | spin_lock_irqsave(&rxq->lock, flags); |
845 | list_add_tail(&rxb->list, &priv->rxq.rx_used); | 1023 | if (rxb->page != NULL) { |
1024 | rxb->page_dma = pci_map_page(priv->pci_dev, rxb->page, | ||
1025 | 0, PAGE_SIZE << priv->hw_params.rx_page_order, | ||
1026 | PCI_DMA_FROMDEVICE); | ||
1027 | list_add_tail(&rxb->list, &rxq->rx_free); | ||
1028 | rxq->free_count++; | ||
1029 | } else | ||
1030 | list_add_tail(&rxb->list, &rxq->rx_used); | ||
1031 | |||
846 | spin_unlock_irqrestore(&rxq->lock, flags); | 1032 | spin_unlock_irqrestore(&rxq->lock, flags); |
1033 | |||
847 | i = (i + 1) & RX_QUEUE_MASK; | 1034 | i = (i + 1) & RX_QUEUE_MASK; |
848 | /* If there are a lot of unused frames, | 1035 | /* If there are a lot of unused frames, |
849 | * restock the Rx queue so ucode wont assert. */ | 1036 | * restock the Rx queue so ucode wont assert. */ |
850 | if (fill_rx) { | 1037 | if (fill_rx) { |
851 | count++; | 1038 | count++; |
852 | if (count >= 8) { | 1039 | if (count >= 8) { |
853 | priv->rxq.read = i; | 1040 | rxq->read = i; |
854 | iwl_rx_replenish_now(priv); | 1041 | iwl_rx_replenish_now(priv); |
855 | count = 0; | 1042 | count = 0; |
856 | } | 1043 | } |
@@ -858,7 +1045,7 @@ void iwl_rx_handle(struct iwl_priv *priv) | |||
858 | } | 1045 | } |
859 | 1046 | ||
860 | /* Backtrack one entry */ | 1047 | /* Backtrack one entry */ |
861 | priv->rxq.read = i; | 1048 | rxq->read = i; |
862 | if (fill_rx) | 1049 | if (fill_rx) |
863 | iwl_rx_replenish_now(priv); | 1050 | iwl_rx_replenish_now(priv); |
864 | else | 1051 | else |
@@ -878,6 +1065,7 @@ static void iwl_irq_tasklet_legacy(struct iwl_priv *priv) | |||
878 | u32 inta, handled = 0; | 1065 | u32 inta, handled = 0; |
879 | u32 inta_fh; | 1066 | u32 inta_fh; |
880 | unsigned long flags; | 1067 | unsigned long flags; |
1068 | u32 i; | ||
881 | #ifdef CONFIG_IWLWIFI_DEBUG | 1069 | #ifdef CONFIG_IWLWIFI_DEBUG |
882 | u32 inta_mask; | 1070 | u32 inta_mask; |
883 | #endif | 1071 | #endif |
@@ -905,6 +1093,8 @@ static void iwl_irq_tasklet_legacy(struct iwl_priv *priv) | |||
905 | } | 1093 | } |
906 | #endif | 1094 | #endif |
907 | 1095 | ||
1096 | spin_unlock_irqrestore(&priv->lock, flags); | ||
1097 | |||
908 | /* Since CSR_INT and CSR_FH_INT_STATUS reads and clears are not | 1098 | /* Since CSR_INT and CSR_FH_INT_STATUS reads and clears are not |
909 | * atomic, make sure that inta covers all the interrupts that | 1099 | * atomic, make sure that inta covers all the interrupts that |
910 | * we've discovered, even if FH interrupt came in just after | 1100 | * we've discovered, even if FH interrupt came in just after |
@@ -926,8 +1116,6 @@ static void iwl_irq_tasklet_legacy(struct iwl_priv *priv) | |||
926 | 1116 | ||
927 | handled |= CSR_INT_BIT_HW_ERR; | 1117 | handled |= CSR_INT_BIT_HW_ERR; |
928 | 1118 | ||
929 | spin_unlock_irqrestore(&priv->lock, flags); | ||
930 | |||
931 | return; | 1119 | return; |
932 | } | 1120 | } |
933 | 1121 | ||
@@ -995,19 +1183,17 @@ static void iwl_irq_tasklet_legacy(struct iwl_priv *priv) | |||
995 | handled |= CSR_INT_BIT_SW_ERR; | 1183 | handled |= CSR_INT_BIT_SW_ERR; |
996 | } | 1184 | } |
997 | 1185 | ||
998 | /* uCode wakes up after power-down sleep */ | 1186 | /* |
1187 | * uCode wakes up after power-down sleep. | ||
1188 | * Tell device about any new tx or host commands enqueued, | ||
1189 | * and about any Rx buffers made available while asleep. | ||
1190 | */ | ||
999 | if (inta & CSR_INT_BIT_WAKEUP) { | 1191 | if (inta & CSR_INT_BIT_WAKEUP) { |
1000 | IWL_DEBUG_ISR(priv, "Wakeup interrupt\n"); | 1192 | IWL_DEBUG_ISR(priv, "Wakeup interrupt\n"); |
1001 | iwl_rx_queue_update_write_ptr(priv, &priv->rxq); | 1193 | iwl_rx_queue_update_write_ptr(priv, &priv->rxq); |
1002 | iwl_txq_update_write_ptr(priv, &priv->txq[0]); | 1194 | for (i = 0; i < priv->hw_params.max_txq_num; i++) |
1003 | iwl_txq_update_write_ptr(priv, &priv->txq[1]); | 1195 | iwl_txq_update_write_ptr(priv, &priv->txq[i]); |
1004 | iwl_txq_update_write_ptr(priv, &priv->txq[2]); | ||
1005 | iwl_txq_update_write_ptr(priv, &priv->txq[3]); | ||
1006 | iwl_txq_update_write_ptr(priv, &priv->txq[4]); | ||
1007 | iwl_txq_update_write_ptr(priv, &priv->txq[5]); | ||
1008 | |||
1009 | priv->isr_stats.wakeup++; | 1196 | priv->isr_stats.wakeup++; |
1010 | |||
1011 | handled |= CSR_INT_BIT_WAKEUP; | 1197 | handled |= CSR_INT_BIT_WAKEUP; |
1012 | } | 1198 | } |
1013 | 1199 | ||
@@ -1020,11 +1206,12 @@ static void iwl_irq_tasklet_legacy(struct iwl_priv *priv) | |||
1020 | handled |= (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX); | 1206 | handled |= (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX); |
1021 | } | 1207 | } |
1022 | 1208 | ||
1209 | /* This "Tx" DMA channel is used only for loading uCode */ | ||
1023 | if (inta & CSR_INT_BIT_FH_TX) { | 1210 | if (inta & CSR_INT_BIT_FH_TX) { |
1024 | IWL_DEBUG_ISR(priv, "Tx interrupt\n"); | 1211 | IWL_DEBUG_ISR(priv, "uCode load interrupt\n"); |
1025 | priv->isr_stats.tx++; | 1212 | priv->isr_stats.tx++; |
1026 | handled |= CSR_INT_BIT_FH_TX; | 1213 | handled |= CSR_INT_BIT_FH_TX; |
1027 | /* FH finished to write, send event */ | 1214 | /* Wake up uCode load routine, now that load is complete */ |
1028 | priv->ucode_write_complete = 1; | 1215 | priv->ucode_write_complete = 1; |
1029 | wake_up_interruptible(&priv->wait_command_queue); | 1216 | wake_up_interruptible(&priv->wait_command_queue); |
1030 | } | 1217 | } |
@@ -1054,7 +1241,6 @@ static void iwl_irq_tasklet_legacy(struct iwl_priv *priv) | |||
1054 | "flags 0x%08lx\n", inta, inta_mask, inta_fh, flags); | 1241 | "flags 0x%08lx\n", inta, inta_mask, inta_fh, flags); |
1055 | } | 1242 | } |
1056 | #endif | 1243 | #endif |
1057 | spin_unlock_irqrestore(&priv->lock, flags); | ||
1058 | } | 1244 | } |
1059 | 1245 | ||
1060 | /* tasklet for iwlagn interrupt */ | 1246 | /* tasklet for iwlagn interrupt */ |
@@ -1063,6 +1249,7 @@ static void iwl_irq_tasklet(struct iwl_priv *priv) | |||
1063 | u32 inta = 0; | 1249 | u32 inta = 0; |
1064 | u32 handled = 0; | 1250 | u32 handled = 0; |
1065 | unsigned long flags; | 1251 | unsigned long flags; |
1252 | u32 i; | ||
1066 | #ifdef CONFIG_IWLWIFI_DEBUG | 1253 | #ifdef CONFIG_IWLWIFI_DEBUG |
1067 | u32 inta_mask; | 1254 | u32 inta_mask; |
1068 | #endif | 1255 | #endif |
@@ -1072,7 +1259,15 @@ static void iwl_irq_tasklet(struct iwl_priv *priv) | |||
1072 | /* Ack/clear/reset pending uCode interrupts. | 1259 | /* Ack/clear/reset pending uCode interrupts. |
1073 | * Note: Some bits in CSR_INT are "OR" of bits in CSR_FH_INT_STATUS, | 1260 | * Note: Some bits in CSR_INT are "OR" of bits in CSR_FH_INT_STATUS, |
1074 | */ | 1261 | */ |
1075 | iwl_write32(priv, CSR_INT, priv->inta); | 1262 | /* There is a hardware bug in the interrupt mask function that some |
1263 | * interrupts (i.e. CSR_INT_BIT_SCD) can still be generated even if | ||
1264 | * they are disabled in the CSR_INT_MASK register. Furthermore the | ||
1265 | * ICT interrupt handling mechanism has another bug that might cause | ||
1266 | * these unmasked interrupts fail to be detected. We workaround the | ||
1267 | * hardware bugs here by ACKing all the possible interrupts so that | ||
1268 | * interrupt coalescing can still be achieved. | ||
1269 | */ | ||
1270 | iwl_write32(priv, CSR_INT, priv->inta | ~priv->inta_mask); | ||
1076 | 1271 | ||
1077 | inta = priv->inta; | 1272 | inta = priv->inta; |
1078 | 1273 | ||
@@ -1084,6 +1279,9 @@ static void iwl_irq_tasklet(struct iwl_priv *priv) | |||
1084 | inta, inta_mask); | 1279 | inta, inta_mask); |
1085 | } | 1280 | } |
1086 | #endif | 1281 | #endif |
1282 | |||
1283 | spin_unlock_irqrestore(&priv->lock, flags); | ||
1284 | |||
1087 | /* saved interrupt in inta variable now we can reset priv->inta */ | 1285 | /* saved interrupt in inta variable now we can reset priv->inta */ |
1088 | priv->inta = 0; | 1286 | priv->inta = 0; |
1089 | 1287 | ||
@@ -1099,8 +1297,6 @@ static void iwl_irq_tasklet(struct iwl_priv *priv) | |||
1099 | 1297 | ||
1100 | handled |= CSR_INT_BIT_HW_ERR; | 1298 | handled |= CSR_INT_BIT_HW_ERR; |
1101 | 1299 | ||
1102 | spin_unlock_irqrestore(&priv->lock, flags); | ||
1103 | |||
1104 | return; | 1300 | return; |
1105 | } | 1301 | } |
1106 | 1302 | ||
@@ -1172,12 +1368,8 @@ static void iwl_irq_tasklet(struct iwl_priv *priv) | |||
1172 | if (inta & CSR_INT_BIT_WAKEUP) { | 1368 | if (inta & CSR_INT_BIT_WAKEUP) { |
1173 | IWL_DEBUG_ISR(priv, "Wakeup interrupt\n"); | 1369 | IWL_DEBUG_ISR(priv, "Wakeup interrupt\n"); |
1174 | iwl_rx_queue_update_write_ptr(priv, &priv->rxq); | 1370 | iwl_rx_queue_update_write_ptr(priv, &priv->rxq); |
1175 | iwl_txq_update_write_ptr(priv, &priv->txq[0]); | 1371 | for (i = 0; i < priv->hw_params.max_txq_num; i++) |
1176 | iwl_txq_update_write_ptr(priv, &priv->txq[1]); | 1372 | iwl_txq_update_write_ptr(priv, &priv->txq[i]); |
1177 | iwl_txq_update_write_ptr(priv, &priv->txq[2]); | ||
1178 | iwl_txq_update_write_ptr(priv, &priv->txq[3]); | ||
1179 | iwl_txq_update_write_ptr(priv, &priv->txq[4]); | ||
1180 | iwl_txq_update_write_ptr(priv, &priv->txq[5]); | ||
1181 | 1373 | ||
1182 | priv->isr_stats.wakeup++; | 1374 | priv->isr_stats.wakeup++; |
1183 | 1375 | ||
@@ -1206,26 +1398,36 @@ static void iwl_irq_tasklet(struct iwl_priv *priv) | |||
1206 | * 3- update RX shared data to indicate last write index. | 1398 | * 3- update RX shared data to indicate last write index. |
1207 | * 4- send interrupt. | 1399 | * 4- send interrupt. |
1208 | * This could lead to RX race, driver could receive RX interrupt | 1400 | * This could lead to RX race, driver could receive RX interrupt |
1209 | * but the shared data changes does not reflect this. | 1401 | * but the shared data changes does not reflect this; |
1210 | * this could lead to RX race, RX periodic will solve this race | 1402 | * periodic interrupt will detect any dangling Rx activity. |
1211 | */ | 1403 | */ |
1212 | iwl_write32(priv, CSR_INT_PERIODIC_REG, | 1404 | |
1405 | /* Disable periodic interrupt; we use it as just a one-shot. */ | ||
1406 | iwl_write8(priv, CSR_INT_PERIODIC_REG, | ||
1213 | CSR_INT_PERIODIC_DIS); | 1407 | CSR_INT_PERIODIC_DIS); |
1214 | iwl_rx_handle(priv); | 1408 | iwl_rx_handle(priv); |
1215 | /* Only set RX periodic if real RX is received. */ | 1409 | |
1410 | /* | ||
1411 | * Enable periodic interrupt in 8 msec only if we received | ||
1412 | * real RX interrupt (instead of just periodic int), to catch | ||
1413 | * any dangling Rx interrupt. If it was just the periodic | ||
1414 | * interrupt, there was no dangling Rx activity, and no need | ||
1415 | * to extend the periodic interrupt; one-shot is enough. | ||
1416 | */ | ||
1216 | if (inta & (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX)) | 1417 | if (inta & (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX)) |
1217 | iwl_write32(priv, CSR_INT_PERIODIC_REG, | 1418 | iwl_write8(priv, CSR_INT_PERIODIC_REG, |
1218 | CSR_INT_PERIODIC_ENA); | 1419 | CSR_INT_PERIODIC_ENA); |
1219 | 1420 | ||
1220 | priv->isr_stats.rx++; | 1421 | priv->isr_stats.rx++; |
1221 | } | 1422 | } |
1222 | 1423 | ||
1424 | /* This "Tx" DMA channel is used only for loading uCode */ | ||
1223 | if (inta & CSR_INT_BIT_FH_TX) { | 1425 | if (inta & CSR_INT_BIT_FH_TX) { |
1224 | iwl_write32(priv, CSR_FH_INT_STATUS, CSR49_FH_INT_TX_MASK); | 1426 | iwl_write32(priv, CSR_FH_INT_STATUS, CSR49_FH_INT_TX_MASK); |
1225 | IWL_DEBUG_ISR(priv, "Tx interrupt\n"); | 1427 | IWL_DEBUG_ISR(priv, "uCode load interrupt\n"); |
1226 | priv->isr_stats.tx++; | 1428 | priv->isr_stats.tx++; |
1227 | handled |= CSR_INT_BIT_FH_TX; | 1429 | handled |= CSR_INT_BIT_FH_TX; |
1228 | /* FH finished to write, send event */ | 1430 | /* Wake up uCode load routine, now that load is complete */ |
1229 | priv->ucode_write_complete = 1; | 1431 | priv->ucode_write_complete = 1; |
1230 | wake_up_interruptible(&priv->wait_command_queue); | 1432 | wake_up_interruptible(&priv->wait_command_queue); |
1231 | } | 1433 | } |
@@ -1240,14 +1442,10 @@ static void iwl_irq_tasklet(struct iwl_priv *priv) | |||
1240 | inta & ~priv->inta_mask); | 1442 | inta & ~priv->inta_mask); |
1241 | } | 1443 | } |
1242 | 1444 | ||
1243 | |||
1244 | /* Re-enable all interrupts */ | 1445 | /* Re-enable all interrupts */ |
1245 | /* only Re-enable if diabled by irq */ | 1446 | /* only Re-enable if diabled by irq */ |
1246 | if (test_bit(STATUS_INT_ENABLED, &priv->status)) | 1447 | if (test_bit(STATUS_INT_ENABLED, &priv->status)) |
1247 | iwl_enable_interrupts(priv); | 1448 | iwl_enable_interrupts(priv); |
1248 | |||
1249 | spin_unlock_irqrestore(&priv->lock, flags); | ||
1250 | |||
1251 | } | 1449 | } |
1252 | 1450 | ||
1253 | 1451 | ||
@@ -1274,59 +1472,66 @@ static void iwl_nic_start(struct iwl_priv *priv) | |||
1274 | } | 1472 | } |
1275 | 1473 | ||
1276 | 1474 | ||
1475 | static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context); | ||
1476 | static int iwl_mac_setup_register(struct iwl_priv *priv); | ||
1477 | |||
1478 | static int __must_check iwl_request_firmware(struct iwl_priv *priv, bool first) | ||
1479 | { | ||
1480 | const char *name_pre = priv->cfg->fw_name_pre; | ||
1481 | |||
1482 | if (first) | ||
1483 | priv->fw_index = priv->cfg->ucode_api_max; | ||
1484 | else | ||
1485 | priv->fw_index--; | ||
1486 | |||
1487 | if (priv->fw_index < priv->cfg->ucode_api_min) { | ||
1488 | IWL_ERR(priv, "no suitable firmware found!\n"); | ||
1489 | return -ENOENT; | ||
1490 | } | ||
1491 | |||
1492 | sprintf(priv->firmware_name, "%s%d%s", | ||
1493 | name_pre, priv->fw_index, ".ucode"); | ||
1494 | |||
1495 | IWL_DEBUG_INFO(priv, "attempting to load firmware '%s'\n", | ||
1496 | priv->firmware_name); | ||
1497 | |||
1498 | return request_firmware_nowait(THIS_MODULE, 1, priv->firmware_name, | ||
1499 | &priv->pci_dev->dev, GFP_KERNEL, priv, | ||
1500 | iwl_ucode_callback); | ||
1501 | } | ||
1502 | |||
1277 | /** | 1503 | /** |
1278 | * iwl_read_ucode - Read uCode images from disk file. | 1504 | * iwl_ucode_callback - callback when firmware was loaded |
1279 | * | 1505 | * |
1280 | * Copy into buffers for card to fetch via bus-mastering | 1506 | * If loaded successfully, copies the firmware into buffers |
1507 | * for the card to fetch (via DMA). | ||
1281 | */ | 1508 | */ |
1282 | static int iwl_read_ucode(struct iwl_priv *priv) | 1509 | static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) |
1283 | { | 1510 | { |
1511 | struct iwl_priv *priv = context; | ||
1284 | struct iwl_ucode_header *ucode; | 1512 | struct iwl_ucode_header *ucode; |
1285 | int ret = -EINVAL, index; | ||
1286 | const struct firmware *ucode_raw; | ||
1287 | const char *name_pre = priv->cfg->fw_name_pre; | ||
1288 | const unsigned int api_max = priv->cfg->ucode_api_max; | 1513 | const unsigned int api_max = priv->cfg->ucode_api_max; |
1289 | const unsigned int api_min = priv->cfg->ucode_api_min; | 1514 | const unsigned int api_min = priv->cfg->ucode_api_min; |
1290 | char buf[25]; | ||
1291 | u8 *src; | 1515 | u8 *src; |
1292 | size_t len; | 1516 | size_t len; |
1293 | u32 api_ver, build; | 1517 | u32 api_ver, build; |
1294 | u32 inst_size, data_size, init_size, init_data_size, boot_size; | 1518 | u32 inst_size, data_size, init_size, init_data_size, boot_size; |
1519 | int err; | ||
1295 | u16 eeprom_ver; | 1520 | u16 eeprom_ver; |
1296 | 1521 | ||
1297 | /* Ask kernel firmware_class module to get the boot firmware off disk. | 1522 | if (!ucode_raw) { |
1298 | * request_firmware() is synchronous, file is in memory on return. */ | 1523 | IWL_ERR(priv, "request for firmware file '%s' failed.\n", |
1299 | for (index = api_max; index >= api_min; index--) { | 1524 | priv->firmware_name); |
1300 | sprintf(buf, "%s%d%s", name_pre, index, ".ucode"); | 1525 | goto try_again; |
1301 | ret = request_firmware(&ucode_raw, buf, &priv->pci_dev->dev); | ||
1302 | if (ret < 0) { | ||
1303 | IWL_ERR(priv, "%s firmware file req failed: %d\n", | ||
1304 | buf, ret); | ||
1305 | if (ret == -ENOENT) | ||
1306 | continue; | ||
1307 | else | ||
1308 | goto error; | ||
1309 | } else { | ||
1310 | if (index < api_max) | ||
1311 | IWL_ERR(priv, "Loaded firmware %s, " | ||
1312 | "which is deprecated. " | ||
1313 | "Please use API v%u instead.\n", | ||
1314 | buf, api_max); | ||
1315 | |||
1316 | IWL_DEBUG_INFO(priv, "Got firmware '%s' file (%zd bytes) from disk\n", | ||
1317 | buf, ucode_raw->size); | ||
1318 | break; | ||
1319 | } | ||
1320 | } | 1526 | } |
1321 | 1527 | ||
1322 | if (ret < 0) | 1528 | IWL_DEBUG_INFO(priv, "Loaded firmware file '%s' (%zd bytes).\n", |
1323 | goto error; | 1529 | priv->firmware_name, ucode_raw->size); |
1324 | 1530 | ||
1325 | /* Make sure that we got at least the v1 header! */ | 1531 | /* Make sure that we got at least the v1 header! */ |
1326 | if (ucode_raw->size < priv->cfg->ops->ucode->get_header_size(1)) { | 1532 | if (ucode_raw->size < priv->cfg->ops->ucode->get_header_size(1)) { |
1327 | IWL_ERR(priv, "File size way too small!\n"); | 1533 | IWL_ERR(priv, "File size way too small!\n"); |
1328 | ret = -EINVAL; | 1534 | goto try_again; |
1329 | goto err_release; | ||
1330 | } | 1535 | } |
1331 | 1536 | ||
1332 | /* Data from ucode file: header followed by uCode images */ | 1537 | /* Data from ucode file: header followed by uCode images */ |
@@ -1351,10 +1556,9 @@ static int iwl_read_ucode(struct iwl_priv *priv) | |||
1351 | IWL_ERR(priv, "Driver unable to support your firmware API. " | 1556 | IWL_ERR(priv, "Driver unable to support your firmware API. " |
1352 | "Driver supports v%u, firmware is v%u.\n", | 1557 | "Driver supports v%u, firmware is v%u.\n", |
1353 | api_max, api_ver); | 1558 | api_max, api_ver); |
1354 | priv->ucode_ver = 0; | 1559 | goto try_again; |
1355 | ret = -EINVAL; | ||
1356 | goto err_release; | ||
1357 | } | 1560 | } |
1561 | |||
1358 | if (api_ver != api_max) | 1562 | if (api_ver != api_max) |
1359 | IWL_ERR(priv, "Firmware has old API version. Expected v%u, " | 1563 | IWL_ERR(priv, "Firmware has old API version. Expected v%u, " |
1360 | "got v%u. New firmware can be obtained " | 1564 | "got v%u. New firmware can be obtained " |
@@ -1367,6 +1571,14 @@ static int iwl_read_ucode(struct iwl_priv *priv) | |||
1367 | IWL_UCODE_API(priv->ucode_ver), | 1571 | IWL_UCODE_API(priv->ucode_ver), |
1368 | IWL_UCODE_SERIAL(priv->ucode_ver)); | 1572 | IWL_UCODE_SERIAL(priv->ucode_ver)); |
1369 | 1573 | ||
1574 | snprintf(priv->hw->wiphy->fw_version, | ||
1575 | sizeof(priv->hw->wiphy->fw_version), | ||
1576 | "%u.%u.%u.%u", | ||
1577 | IWL_UCODE_MAJOR(priv->ucode_ver), | ||
1578 | IWL_UCODE_MINOR(priv->ucode_ver), | ||
1579 | IWL_UCODE_API(priv->ucode_ver), | ||
1580 | IWL_UCODE_SERIAL(priv->ucode_ver)); | ||
1581 | |||
1370 | if (build) | 1582 | if (build) |
1371 | IWL_DEBUG_INFO(priv, "Build %u\n", build); | 1583 | IWL_DEBUG_INFO(priv, "Build %u\n", build); |
1372 | 1584 | ||
@@ -1388,6 +1600,12 @@ static int iwl_read_ucode(struct iwl_priv *priv) | |||
1388 | IWL_DEBUG_INFO(priv, "f/w package hdr boot inst size = %u\n", | 1600 | IWL_DEBUG_INFO(priv, "f/w package hdr boot inst size = %u\n", |
1389 | boot_size); | 1601 | boot_size); |
1390 | 1602 | ||
1603 | /* | ||
1604 | * For any of the failures below (before allocating pci memory) | ||
1605 | * we will try to load a version with a smaller API -- maybe the | ||
1606 | * user just got a corrupted version of the latest API. | ||
1607 | */ | ||
1608 | |||
1391 | /* Verify size of file vs. image size info in file's header */ | 1609 | /* Verify size of file vs. image size info in file's header */ |
1392 | if (ucode_raw->size != | 1610 | if (ucode_raw->size != |
1393 | priv->cfg->ops->ucode->get_header_size(api_ver) + | 1611 | priv->cfg->ops->ucode->get_header_size(api_ver) + |
@@ -1397,41 +1615,35 @@ static int iwl_read_ucode(struct iwl_priv *priv) | |||
1397 | IWL_DEBUG_INFO(priv, | 1615 | IWL_DEBUG_INFO(priv, |
1398 | "uCode file size %d does not match expected size\n", | 1616 | "uCode file size %d does not match expected size\n", |
1399 | (int)ucode_raw->size); | 1617 | (int)ucode_raw->size); |
1400 | ret = -EINVAL; | 1618 | goto try_again; |
1401 | goto err_release; | ||
1402 | } | 1619 | } |
1403 | 1620 | ||
1404 | /* Verify that uCode images will fit in card's SRAM */ | 1621 | /* Verify that uCode images will fit in card's SRAM */ |
1405 | if (inst_size > priv->hw_params.max_inst_size) { | 1622 | if (inst_size > priv->hw_params.max_inst_size) { |
1406 | IWL_DEBUG_INFO(priv, "uCode instr len %d too large to fit in\n", | 1623 | IWL_DEBUG_INFO(priv, "uCode instr len %d too large to fit in\n", |
1407 | inst_size); | 1624 | inst_size); |
1408 | ret = -EINVAL; | 1625 | goto try_again; |
1409 | goto err_release; | ||
1410 | } | 1626 | } |
1411 | 1627 | ||
1412 | if (data_size > priv->hw_params.max_data_size) { | 1628 | if (data_size > priv->hw_params.max_data_size) { |
1413 | IWL_DEBUG_INFO(priv, "uCode data len %d too large to fit in\n", | 1629 | IWL_DEBUG_INFO(priv, "uCode data len %d too large to fit in\n", |
1414 | data_size); | 1630 | data_size); |
1415 | ret = -EINVAL; | 1631 | goto try_again; |
1416 | goto err_release; | ||
1417 | } | 1632 | } |
1418 | if (init_size > priv->hw_params.max_inst_size) { | 1633 | if (init_size > priv->hw_params.max_inst_size) { |
1419 | IWL_INFO(priv, "uCode init instr len %d too large to fit in\n", | 1634 | IWL_INFO(priv, "uCode init instr len %d too large to fit in\n", |
1420 | init_size); | 1635 | init_size); |
1421 | ret = -EINVAL; | 1636 | goto try_again; |
1422 | goto err_release; | ||
1423 | } | 1637 | } |
1424 | if (init_data_size > priv->hw_params.max_data_size) { | 1638 | if (init_data_size > priv->hw_params.max_data_size) { |
1425 | IWL_INFO(priv, "uCode init data len %d too large to fit in\n", | 1639 | IWL_INFO(priv, "uCode init data len %d too large to fit in\n", |
1426 | init_data_size); | 1640 | init_data_size); |
1427 | ret = -EINVAL; | 1641 | goto try_again; |
1428 | goto err_release; | ||
1429 | } | 1642 | } |
1430 | if (boot_size > priv->hw_params.max_bsm_size) { | 1643 | if (boot_size > priv->hw_params.max_bsm_size) { |
1431 | IWL_INFO(priv, "uCode boot instr len %d too large to fit in\n", | 1644 | IWL_INFO(priv, "uCode boot instr len %d too large to fit in\n", |
1432 | boot_size); | 1645 | boot_size); |
1433 | ret = -EINVAL; | 1646 | goto try_again; |
1434 | goto err_release; | ||
1435 | } | 1647 | } |
1436 | 1648 | ||
1437 | /* Allocate ucode buffers for card's bus-master loading ... */ | 1649 | /* Allocate ucode buffers for card's bus-master loading ... */ |
@@ -1515,23 +1727,38 @@ static int iwl_read_ucode(struct iwl_priv *priv) | |||
1515 | IWL_DEBUG_INFO(priv, "Copying (but not loading) boot instr len %Zd\n", len); | 1727 | IWL_DEBUG_INFO(priv, "Copying (but not loading) boot instr len %Zd\n", len); |
1516 | memcpy(priv->ucode_boot.v_addr, src, len); | 1728 | memcpy(priv->ucode_boot.v_addr, src, len); |
1517 | 1729 | ||
1730 | /************************************************** | ||
1731 | * This is still part of probe() in a sense... | ||
1732 | * | ||
1733 | * 9. Setup and register with mac80211 and debugfs | ||
1734 | **************************************************/ | ||
1735 | err = iwl_mac_setup_register(priv); | ||
1736 | if (err) | ||
1737 | goto out_unbind; | ||
1738 | |||
1739 | err = iwl_dbgfs_register(priv, DRV_NAME); | ||
1740 | if (err) | ||
1741 | IWL_ERR(priv, "failed to create debugfs files. Ignoring error: %d\n", err); | ||
1742 | |||
1518 | /* We have our copies now, allow OS release its copies */ | 1743 | /* We have our copies now, allow OS release its copies */ |
1519 | release_firmware(ucode_raw); | 1744 | release_firmware(ucode_raw); |
1520 | return 0; | 1745 | return; |
1746 | |||
1747 | try_again: | ||
1748 | /* try next, if any */ | ||
1749 | if (iwl_request_firmware(priv, false)) | ||
1750 | goto out_unbind; | ||
1751 | release_firmware(ucode_raw); | ||
1752 | return; | ||
1521 | 1753 | ||
1522 | err_pci_alloc: | 1754 | err_pci_alloc: |
1523 | IWL_ERR(priv, "failed to allocate pci memory\n"); | 1755 | IWL_ERR(priv, "failed to allocate pci memory\n"); |
1524 | ret = -ENOMEM; | ||
1525 | iwl_dealloc_ucode_pci(priv); | 1756 | iwl_dealloc_ucode_pci(priv); |
1526 | 1757 | out_unbind: | |
1527 | err_release: | 1758 | device_release_driver(&priv->pci_dev->dev); |
1528 | release_firmware(ucode_raw); | 1759 | release_firmware(ucode_raw); |
1529 | |||
1530 | error: | ||
1531 | return ret; | ||
1532 | } | 1760 | } |
1533 | 1761 | ||
1534 | #ifdef CONFIG_IWLWIFI_DEBUG | ||
1535 | static const char *desc_lookup_text[] = { | 1762 | static const char *desc_lookup_text[] = { |
1536 | "OK", | 1763 | "OK", |
1537 | "FAIL", | 1764 | "FAIL", |
@@ -1561,7 +1788,7 @@ static const char *desc_lookup_text[] = { | |||
1561 | "DEBUG_1", | 1788 | "DEBUG_1", |
1562 | "DEBUG_2", | 1789 | "DEBUG_2", |
1563 | "DEBUG_3", | 1790 | "DEBUG_3", |
1564 | "UNKNOWN" | 1791 | "ADVANCED SYSASSERT" |
1565 | }; | 1792 | }; |
1566 | 1793 | ||
1567 | static const char *desc_lookup(int i) | 1794 | static const char *desc_lookup(int i) |
@@ -1589,7 +1816,9 @@ void iwl_dump_nic_error_log(struct iwl_priv *priv) | |||
1589 | base = le32_to_cpu(priv->card_alive.error_event_table_ptr); | 1816 | base = le32_to_cpu(priv->card_alive.error_event_table_ptr); |
1590 | 1817 | ||
1591 | if (!priv->cfg->ops->lib->is_valid_rtc_data_addr(base)) { | 1818 | if (!priv->cfg->ops->lib->is_valid_rtc_data_addr(base)) { |
1592 | IWL_ERR(priv, "Not valid error log pointer 0x%08X\n", base); | 1819 | IWL_ERR(priv, |
1820 | "Not valid error log pointer 0x%08X for %s uCode\n", | ||
1821 | base, (priv->ucode_type == UCODE_INIT) ? "Init" : "RT"); | ||
1593 | return; | 1822 | return; |
1594 | } | 1823 | } |
1595 | 1824 | ||
@@ -1611,6 +1840,9 @@ void iwl_dump_nic_error_log(struct iwl_priv *priv) | |||
1611 | line = iwl_read_targ_mem(priv, base + 9 * sizeof(u32)); | 1840 | line = iwl_read_targ_mem(priv, base + 9 * sizeof(u32)); |
1612 | time = iwl_read_targ_mem(priv, base + 11 * sizeof(u32)); | 1841 | time = iwl_read_targ_mem(priv, base + 11 * sizeof(u32)); |
1613 | 1842 | ||
1843 | trace_iwlwifi_dev_ucode_error(priv, desc, time, data1, data2, line, | ||
1844 | blink1, blink2, ilink1, ilink2); | ||
1845 | |||
1614 | IWL_ERR(priv, "Desc Time " | 1846 | IWL_ERR(priv, "Desc Time " |
1615 | "data1 data2 line\n"); | 1847 | "data1 data2 line\n"); |
1616 | IWL_ERR(priv, "%-28s (#%02d) %010u 0x%08X 0x%08X %u\n", | 1848 | IWL_ERR(priv, "%-28s (#%02d) %010u 0x%08X 0x%08X %u\n", |
@@ -1627,17 +1859,19 @@ void iwl_dump_nic_error_log(struct iwl_priv *priv) | |||
1627 | * iwl_print_event_log - Dump error event log to syslog | 1859 | * iwl_print_event_log - Dump error event log to syslog |
1628 | * | 1860 | * |
1629 | */ | 1861 | */ |
1630 | static void iwl_print_event_log(struct iwl_priv *priv, u32 start_idx, | 1862 | static int iwl_print_event_log(struct iwl_priv *priv, u32 start_idx, |
1631 | u32 num_events, u32 mode) | 1863 | u32 num_events, u32 mode, |
1864 | int pos, char **buf, size_t bufsz) | ||
1632 | { | 1865 | { |
1633 | u32 i; | 1866 | u32 i; |
1634 | u32 base; /* SRAM byte address of event log header */ | 1867 | u32 base; /* SRAM byte address of event log header */ |
1635 | u32 event_size; /* 2 u32s, or 3 u32s if timestamp recorded */ | 1868 | u32 event_size; /* 2 u32s, or 3 u32s if timestamp recorded */ |
1636 | u32 ptr; /* SRAM byte address of log data */ | 1869 | u32 ptr; /* SRAM byte address of log data */ |
1637 | u32 ev, time, data; /* event log data */ | 1870 | u32 ev, time, data; /* event log data */ |
1871 | unsigned long reg_flags; | ||
1638 | 1872 | ||
1639 | if (num_events == 0) | 1873 | if (num_events == 0) |
1640 | return; | 1874 | return pos; |
1641 | if (priv->ucode_type == UCODE_INIT) | 1875 | if (priv->ucode_type == UCODE_INIT) |
1642 | base = le32_to_cpu(priv->card_alive_init.log_event_table_ptr); | 1876 | base = le32_to_cpu(priv->card_alive_init.log_event_table_ptr); |
1643 | else | 1877 | else |
@@ -1650,26 +1884,95 @@ static void iwl_print_event_log(struct iwl_priv *priv, u32 start_idx, | |||
1650 | 1884 | ||
1651 | ptr = base + EVENT_START_OFFSET + (start_idx * event_size); | 1885 | ptr = base + EVENT_START_OFFSET + (start_idx * event_size); |
1652 | 1886 | ||
1887 | /* Make sure device is powered up for SRAM reads */ | ||
1888 | spin_lock_irqsave(&priv->reg_lock, reg_flags); | ||
1889 | iwl_grab_nic_access(priv); | ||
1890 | |||
1891 | /* Set starting address; reads will auto-increment */ | ||
1892 | _iwl_write_direct32(priv, HBUS_TARG_MEM_RADDR, ptr); | ||
1893 | rmb(); | ||
1894 | |||
1653 | /* "time" is actually "data" for mode 0 (no timestamp). | 1895 | /* "time" is actually "data" for mode 0 (no timestamp). |
1654 | * place event id # at far right for easier visual parsing. */ | 1896 | * place event id # at far right for easier visual parsing. */ |
1655 | for (i = 0; i < num_events; i++) { | 1897 | for (i = 0; i < num_events; i++) { |
1656 | ev = iwl_read_targ_mem(priv, ptr); | 1898 | ev = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT); |
1657 | ptr += sizeof(u32); | 1899 | time = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT); |
1658 | time = iwl_read_targ_mem(priv, ptr); | ||
1659 | ptr += sizeof(u32); | ||
1660 | if (mode == 0) { | 1900 | if (mode == 0) { |
1661 | /* data, ev */ | 1901 | /* data, ev */ |
1662 | IWL_ERR(priv, "EVT_LOG:0x%08x:%04u\n", time, ev); | 1902 | if (bufsz) { |
1903 | pos += scnprintf(*buf + pos, bufsz - pos, | ||
1904 | "EVT_LOG:0x%08x:%04u\n", | ||
1905 | time, ev); | ||
1906 | } else { | ||
1907 | trace_iwlwifi_dev_ucode_event(priv, 0, | ||
1908 | time, ev); | ||
1909 | IWL_ERR(priv, "EVT_LOG:0x%08x:%04u\n", | ||
1910 | time, ev); | ||
1911 | } | ||
1663 | } else { | 1912 | } else { |
1664 | data = iwl_read_targ_mem(priv, ptr); | 1913 | data = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT); |
1665 | ptr += sizeof(u32); | 1914 | if (bufsz) { |
1666 | IWL_ERR(priv, "EVT_LOGT:%010u:0x%08x:%04u\n", | 1915 | pos += scnprintf(*buf + pos, bufsz - pos, |
1916 | "EVT_LOGT:%010u:0x%08x:%04u\n", | ||
1917 | time, data, ev); | ||
1918 | } else { | ||
1919 | IWL_ERR(priv, "EVT_LOGT:%010u:0x%08x:%04u\n", | ||
1667 | time, data, ev); | 1920 | time, data, ev); |
1921 | trace_iwlwifi_dev_ucode_event(priv, time, | ||
1922 | data, ev); | ||
1923 | } | ||
1924 | } | ||
1925 | } | ||
1926 | |||
1927 | /* Allow device to power down */ | ||
1928 | iwl_release_nic_access(priv); | ||
1929 | spin_unlock_irqrestore(&priv->reg_lock, reg_flags); | ||
1930 | return pos; | ||
1931 | } | ||
1932 | |||
1933 | /** | ||
1934 | * iwl_print_last_event_logs - Dump the newest # of event log to syslog | ||
1935 | */ | ||
1936 | static int iwl_print_last_event_logs(struct iwl_priv *priv, u32 capacity, | ||
1937 | u32 num_wraps, u32 next_entry, | ||
1938 | u32 size, u32 mode, | ||
1939 | int pos, char **buf, size_t bufsz) | ||
1940 | { | ||
1941 | /* | ||
1942 | * display the newest DEFAULT_LOG_ENTRIES entries | ||
1943 | * i.e the entries just before the next ont that uCode would fill. | ||
1944 | */ | ||
1945 | if (num_wraps) { | ||
1946 | if (next_entry < size) { | ||
1947 | pos = iwl_print_event_log(priv, | ||
1948 | capacity - (size - next_entry), | ||
1949 | size - next_entry, mode, | ||
1950 | pos, buf, bufsz); | ||
1951 | pos = iwl_print_event_log(priv, 0, | ||
1952 | next_entry, mode, | ||
1953 | pos, buf, bufsz); | ||
1954 | } else | ||
1955 | pos = iwl_print_event_log(priv, next_entry - size, | ||
1956 | size, mode, pos, buf, bufsz); | ||
1957 | } else { | ||
1958 | if (next_entry < size) { | ||
1959 | pos = iwl_print_event_log(priv, 0, next_entry, | ||
1960 | mode, pos, buf, bufsz); | ||
1961 | } else { | ||
1962 | pos = iwl_print_event_log(priv, next_entry - size, | ||
1963 | size, mode, pos, buf, bufsz); | ||
1668 | } | 1964 | } |
1669 | } | 1965 | } |
1966 | return pos; | ||
1670 | } | 1967 | } |
1671 | 1968 | ||
1672 | void iwl_dump_nic_event_log(struct iwl_priv *priv) | 1969 | /* For sanity check only. Actual size is determined by uCode, typ. 512 */ |
1970 | #define MAX_EVENT_LOG_SIZE (512) | ||
1971 | |||
1972 | #define DEFAULT_DUMP_EVENT_LOG_ENTRIES (20) | ||
1973 | |||
1974 | int iwl_dump_nic_event_log(struct iwl_priv *priv, bool full_log, | ||
1975 | char **buf, bool display) | ||
1673 | { | 1976 | { |
1674 | u32 base; /* SRAM byte address of event log header */ | 1977 | u32 base; /* SRAM byte address of event log header */ |
1675 | u32 capacity; /* event log capacity in # entries */ | 1978 | u32 capacity; /* event log capacity in # entries */ |
@@ -1677,6 +1980,8 @@ void iwl_dump_nic_event_log(struct iwl_priv *priv) | |||
1677 | u32 num_wraps; /* # times uCode wrapped to top of log */ | 1980 | u32 num_wraps; /* # times uCode wrapped to top of log */ |
1678 | u32 next_entry; /* index of next entry to be written by uCode */ | 1981 | u32 next_entry; /* index of next entry to be written by uCode */ |
1679 | u32 size; /* # entries that we'll print */ | 1982 | u32 size; /* # entries that we'll print */ |
1983 | int pos = 0; | ||
1984 | size_t bufsz = 0; | ||
1680 | 1985 | ||
1681 | if (priv->ucode_type == UCODE_INIT) | 1986 | if (priv->ucode_type == UCODE_INIT) |
1682 | base = le32_to_cpu(priv->card_alive_init.log_event_table_ptr); | 1987 | base = le32_to_cpu(priv->card_alive_init.log_event_table_ptr); |
@@ -1684,8 +1989,10 @@ void iwl_dump_nic_event_log(struct iwl_priv *priv) | |||
1684 | base = le32_to_cpu(priv->card_alive.log_event_table_ptr); | 1989 | base = le32_to_cpu(priv->card_alive.log_event_table_ptr); |
1685 | 1990 | ||
1686 | if (!priv->cfg->ops->lib->is_valid_rtc_data_addr(base)) { | 1991 | if (!priv->cfg->ops->lib->is_valid_rtc_data_addr(base)) { |
1687 | IWL_ERR(priv, "Invalid event log pointer 0x%08X\n", base); | 1992 | IWL_ERR(priv, |
1688 | return; | 1993 | "Invalid event log pointer 0x%08X for %s uCode\n", |
1994 | base, (priv->ucode_type == UCODE_INIT) ? "Init" : "RT"); | ||
1995 | return -EINVAL; | ||
1689 | } | 1996 | } |
1690 | 1997 | ||
1691 | /* event log header */ | 1998 | /* event log header */ |
@@ -1694,27 +2001,71 @@ void iwl_dump_nic_event_log(struct iwl_priv *priv) | |||
1694 | num_wraps = iwl_read_targ_mem(priv, base + (2 * sizeof(u32))); | 2001 | num_wraps = iwl_read_targ_mem(priv, base + (2 * sizeof(u32))); |
1695 | next_entry = iwl_read_targ_mem(priv, base + (3 * sizeof(u32))); | 2002 | next_entry = iwl_read_targ_mem(priv, base + (3 * sizeof(u32))); |
1696 | 2003 | ||
2004 | if (capacity > MAX_EVENT_LOG_SIZE) { | ||
2005 | IWL_ERR(priv, "Log capacity %d is bogus, limit to %d entries\n", | ||
2006 | capacity, MAX_EVENT_LOG_SIZE); | ||
2007 | capacity = MAX_EVENT_LOG_SIZE; | ||
2008 | } | ||
2009 | |||
2010 | if (next_entry > MAX_EVENT_LOG_SIZE) { | ||
2011 | IWL_ERR(priv, "Log write index %d is bogus, limit to %d\n", | ||
2012 | next_entry, MAX_EVENT_LOG_SIZE); | ||
2013 | next_entry = MAX_EVENT_LOG_SIZE; | ||
2014 | } | ||
2015 | |||
1697 | size = num_wraps ? capacity : next_entry; | 2016 | size = num_wraps ? capacity : next_entry; |
1698 | 2017 | ||
1699 | /* bail out if nothing in log */ | 2018 | /* bail out if nothing in log */ |
1700 | if (size == 0) { | 2019 | if (size == 0) { |
1701 | IWL_ERR(priv, "Start IWL Event Log Dump: nothing in log\n"); | 2020 | IWL_ERR(priv, "Start IWL Event Log Dump: nothing in log\n"); |
1702 | return; | 2021 | return pos; |
1703 | } | 2022 | } |
1704 | 2023 | ||
1705 | IWL_ERR(priv, "Start IWL Event Log Dump: display count %d, wraps %d\n", | 2024 | #ifdef CONFIG_IWLWIFI_DEBUG |
1706 | size, num_wraps); | 2025 | if (!(iwl_get_debug_level(priv) & IWL_DL_FW_ERRORS) && !full_log) |
1707 | 2026 | size = (size > DEFAULT_DUMP_EVENT_LOG_ENTRIES) | |
1708 | /* if uCode has wrapped back to top of log, start at the oldest entry, | 2027 | ? DEFAULT_DUMP_EVENT_LOG_ENTRIES : size; |
1709 | * i.e the next one that uCode would fill. */ | 2028 | #else |
1710 | if (num_wraps) | 2029 | size = (size > DEFAULT_DUMP_EVENT_LOG_ENTRIES) |
1711 | iwl_print_event_log(priv, next_entry, | 2030 | ? DEFAULT_DUMP_EVENT_LOG_ENTRIES : size; |
1712 | capacity - next_entry, mode); | 2031 | #endif |
1713 | /* (then/else) start at top of log */ | 2032 | IWL_ERR(priv, "Start IWL Event Log Dump: display last %u entries\n", |
1714 | iwl_print_event_log(priv, 0, next_entry, mode); | 2033 | size); |
1715 | 2034 | ||
1716 | } | 2035 | #ifdef CONFIG_IWLWIFI_DEBUG |
2036 | if (display) { | ||
2037 | if (full_log) | ||
2038 | bufsz = capacity * 48; | ||
2039 | else | ||
2040 | bufsz = size * 48; | ||
2041 | *buf = kmalloc(bufsz, GFP_KERNEL); | ||
2042 | if (!*buf) | ||
2043 | return -ENOMEM; | ||
2044 | } | ||
2045 | if ((iwl_get_debug_level(priv) & IWL_DL_FW_ERRORS) || full_log) { | ||
2046 | /* | ||
2047 | * if uCode has wrapped back to top of log, | ||
2048 | * start at the oldest entry, | ||
2049 | * i.e the next one that uCode would fill. | ||
2050 | */ | ||
2051 | if (num_wraps) | ||
2052 | pos = iwl_print_event_log(priv, next_entry, | ||
2053 | capacity - next_entry, mode, | ||
2054 | pos, buf, bufsz); | ||
2055 | /* (then/else) start at top of log */ | ||
2056 | pos = iwl_print_event_log(priv, 0, | ||
2057 | next_entry, mode, pos, buf, bufsz); | ||
2058 | } else | ||
2059 | pos = iwl_print_last_event_logs(priv, capacity, num_wraps, | ||
2060 | next_entry, size, mode, | ||
2061 | pos, buf, bufsz); | ||
2062 | #else | ||
2063 | pos = iwl_print_last_event_logs(priv, capacity, num_wraps, | ||
2064 | next_entry, size, mode, | ||
2065 | pos, buf, bufsz); | ||
1717 | #endif | 2066 | #endif |
2067 | return pos; | ||
2068 | } | ||
1718 | 2069 | ||
1719 | /** | 2070 | /** |
1720 | * iwl_alive_start - called after REPLY_ALIVE notification received | 2071 | * iwl_alive_start - called after REPLY_ALIVE notification received |
@@ -1763,6 +2114,10 @@ static void iwl_alive_start(struct iwl_priv *priv) | |||
1763 | priv->active_rate = priv->rates_mask; | 2114 | priv->active_rate = priv->rates_mask; |
1764 | priv->active_rate_basic = priv->rates_mask & IWL_BASIC_RATES_MASK; | 2115 | priv->active_rate_basic = priv->rates_mask & IWL_BASIC_RATES_MASK; |
1765 | 2116 | ||
2117 | /* Configure Tx antenna selection based on H/W config */ | ||
2118 | if (priv->cfg->ops->hcmd->set_tx_ant) | ||
2119 | priv->cfg->ops->hcmd->set_tx_ant(priv, priv->cfg->valid_tx_ant); | ||
2120 | |||
1766 | if (iwl_is_associated(priv)) { | 2121 | if (iwl_is_associated(priv)) { |
1767 | struct iwl_rxon_cmd *active_rxon = | 2122 | struct iwl_rxon_cmd *active_rxon = |
1768 | (struct iwl_rxon_cmd *)&priv->active_rxon; | 2123 | (struct iwl_rxon_cmd *)&priv->active_rxon; |
@@ -1790,7 +2145,7 @@ static void iwl_alive_start(struct iwl_priv *priv) | |||
1790 | /* At this point, the NIC is initialized and operational */ | 2145 | /* At this point, the NIC is initialized and operational */ |
1791 | iwl_rf_kill_ct_config(priv); | 2146 | iwl_rf_kill_ct_config(priv); |
1792 | 2147 | ||
1793 | iwl_leds_register(priv); | 2148 | iwl_leds_init(priv); |
1794 | 2149 | ||
1795 | IWL_DEBUG_INFO(priv, "ALIVE processing complete.\n"); | 2150 | IWL_DEBUG_INFO(priv, "ALIVE processing complete.\n"); |
1796 | set_bit(STATUS_READY, &priv->status); | 2151 | set_bit(STATUS_READY, &priv->status); |
@@ -1828,8 +2183,6 @@ static void __iwl_down(struct iwl_priv *priv) | |||
1828 | if (!exit_pending) | 2183 | if (!exit_pending) |
1829 | set_bit(STATUS_EXIT_PENDING, &priv->status); | 2184 | set_bit(STATUS_EXIT_PENDING, &priv->status); |
1830 | 2185 | ||
1831 | iwl_leds_unregister(priv); | ||
1832 | |||
1833 | iwl_clear_stations_table(priv); | 2186 | iwl_clear_stations_table(priv); |
1834 | 2187 | ||
1835 | /* Unblock any waiting calls */ | 2188 | /* Unblock any waiting calls */ |
@@ -1877,24 +2230,20 @@ static void __iwl_down(struct iwl_priv *priv) | |||
1877 | 2230 | ||
1878 | /* device going down, Stop using ICT table */ | 2231 | /* device going down, Stop using ICT table */ |
1879 | iwl_disable_ict(priv); | 2232 | iwl_disable_ict(priv); |
1880 | spin_lock_irqsave(&priv->lock, flags); | ||
1881 | iwl_clear_bit(priv, CSR_GP_CNTRL, | ||
1882 | CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); | ||
1883 | spin_unlock_irqrestore(&priv->lock, flags); | ||
1884 | 2233 | ||
1885 | iwl_txq_ctx_stop(priv); | 2234 | iwl_txq_ctx_stop(priv); |
1886 | iwl_rxq_stop(priv); | 2235 | iwl_rxq_stop(priv); |
1887 | 2236 | ||
1888 | iwl_write_prph(priv, APMG_CLK_DIS_REG, | 2237 | /* Power-down device's busmaster DMA clocks */ |
1889 | APMG_CLK_VAL_DMA_CLK_RQT); | 2238 | iwl_write_prph(priv, APMG_CLK_DIS_REG, APMG_CLK_VAL_DMA_CLK_RQT); |
1890 | |||
1891 | udelay(5); | 2239 | udelay(5); |
1892 | 2240 | ||
1893 | /* FIXME: apm_ops.suspend(priv) */ | 2241 | /* Make sure (redundant) we've released our request to stay awake */ |
1894 | if (exit_pending) | 2242 | iwl_clear_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); |
1895 | priv->cfg->ops->lib->apm_ops.stop(priv); | 2243 | |
1896 | else | 2244 | /* Stop the device, and put it in low power state */ |
1897 | priv->cfg->ops->lib->apm_ops.reset(priv); | 2245 | priv->cfg->ops->lib->apm_ops.stop(priv); |
2246 | |||
1898 | exit: | 2247 | exit: |
1899 | memset(&priv->card_alive, 0, sizeof(struct iwl_alive_resp)); | 2248 | memset(&priv->card_alive, 0, sizeof(struct iwl_alive_resp)); |
1900 | 2249 | ||
@@ -2121,18 +2470,6 @@ static void iwl_bg_run_time_calib_work(struct work_struct *work) | |||
2121 | return; | 2470 | return; |
2122 | } | 2471 | } |
2123 | 2472 | ||
2124 | static void iwl_bg_up(struct work_struct *data) | ||
2125 | { | ||
2126 | struct iwl_priv *priv = container_of(data, struct iwl_priv, up); | ||
2127 | |||
2128 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) | ||
2129 | return; | ||
2130 | |||
2131 | mutex_lock(&priv->mutex); | ||
2132 | __iwl_up(priv); | ||
2133 | mutex_unlock(&priv->mutex); | ||
2134 | } | ||
2135 | |||
2136 | static void iwl_bg_restart(struct work_struct *data) | 2473 | static void iwl_bg_restart(struct work_struct *data) |
2137 | { | 2474 | { |
2138 | struct iwl_priv *priv = container_of(data, struct iwl_priv, restart); | 2475 | struct iwl_priv *priv = container_of(data, struct iwl_priv, restart); |
@@ -2149,7 +2486,13 @@ static void iwl_bg_restart(struct work_struct *data) | |||
2149 | ieee80211_restart_hw(priv->hw); | 2486 | ieee80211_restart_hw(priv->hw); |
2150 | } else { | 2487 | } else { |
2151 | iwl_down(priv); | 2488 | iwl_down(priv); |
2152 | queue_work(priv->workqueue, &priv->up); | 2489 | |
2490 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) | ||
2491 | return; | ||
2492 | |||
2493 | mutex_lock(&priv->mutex); | ||
2494 | __iwl_up(priv); | ||
2495 | mutex_unlock(&priv->mutex); | ||
2153 | } | 2496 | } |
2154 | } | 2497 | } |
2155 | 2498 | ||
@@ -2281,6 +2624,71 @@ void iwl_post_associate(struct iwl_priv *priv) | |||
2281 | 2624 | ||
2282 | #define UCODE_READY_TIMEOUT (4 * HZ) | 2625 | #define UCODE_READY_TIMEOUT (4 * HZ) |
2283 | 2626 | ||
2627 | /* | ||
2628 | * Not a mac80211 entry point function, but it fits in with all the | ||
2629 | * other mac80211 functions grouped here. | ||
2630 | */ | ||
2631 | static int iwl_mac_setup_register(struct iwl_priv *priv) | ||
2632 | { | ||
2633 | int ret; | ||
2634 | struct ieee80211_hw *hw = priv->hw; | ||
2635 | hw->rate_control_algorithm = "iwl-agn-rs"; | ||
2636 | |||
2637 | /* Tell mac80211 our characteristics */ | ||
2638 | hw->flags = IEEE80211_HW_SIGNAL_DBM | | ||
2639 | IEEE80211_HW_NOISE_DBM | | ||
2640 | IEEE80211_HW_AMPDU_AGGREGATION | | ||
2641 | IEEE80211_HW_SPECTRUM_MGMT; | ||
2642 | |||
2643 | if (!priv->cfg->broken_powersave) | ||
2644 | hw->flags |= IEEE80211_HW_SUPPORTS_PS | | ||
2645 | IEEE80211_HW_SUPPORTS_DYNAMIC_PS; | ||
2646 | |||
2647 | if (priv->cfg->sku & IWL_SKU_N) | ||
2648 | hw->flags |= IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS | | ||
2649 | IEEE80211_HW_SUPPORTS_STATIC_SMPS; | ||
2650 | |||
2651 | hw->sta_data_size = sizeof(struct iwl_station_priv); | ||
2652 | hw->wiphy->interface_modes = | ||
2653 | BIT(NL80211_IFTYPE_STATION) | | ||
2654 | BIT(NL80211_IFTYPE_ADHOC); | ||
2655 | |||
2656 | hw->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY | | ||
2657 | WIPHY_FLAG_DISABLE_BEACON_HINTS; | ||
2658 | |||
2659 | /* | ||
2660 | * For now, disable PS by default because it affects | ||
2661 | * RX performance significantly. | ||
2662 | */ | ||
2663 | hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; | ||
2664 | |||
2665 | hw->wiphy->max_scan_ssids = PROBE_OPTION_MAX; | ||
2666 | /* we create the 802.11 header and a zero-length SSID element */ | ||
2667 | hw->wiphy->max_scan_ie_len = IWL_MAX_PROBE_REQUEST - 24 - 2; | ||
2668 | |||
2669 | /* Default value; 4 EDCA QOS priorities */ | ||
2670 | hw->queues = 4; | ||
2671 | |||
2672 | hw->max_listen_interval = IWL_CONN_MAX_LISTEN_INTERVAL; | ||
2673 | |||
2674 | if (priv->bands[IEEE80211_BAND_2GHZ].n_channels) | ||
2675 | priv->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = | ||
2676 | &priv->bands[IEEE80211_BAND_2GHZ]; | ||
2677 | if (priv->bands[IEEE80211_BAND_5GHZ].n_channels) | ||
2678 | priv->hw->wiphy->bands[IEEE80211_BAND_5GHZ] = | ||
2679 | &priv->bands[IEEE80211_BAND_5GHZ]; | ||
2680 | |||
2681 | ret = ieee80211_register_hw(priv->hw); | ||
2682 | if (ret) { | ||
2683 | IWL_ERR(priv, "Failed to register hw (error %d)\n", ret); | ||
2684 | return ret; | ||
2685 | } | ||
2686 | priv->mac80211_registered = 1; | ||
2687 | |||
2688 | return 0; | ||
2689 | } | ||
2690 | |||
2691 | |||
2284 | static int iwl_mac_start(struct ieee80211_hw *hw) | 2692 | static int iwl_mac_start(struct ieee80211_hw *hw) |
2285 | { | 2693 | { |
2286 | struct iwl_priv *priv = hw->priv; | 2694 | struct iwl_priv *priv = hw->priv; |
@@ -2290,21 +2698,7 @@ static int iwl_mac_start(struct ieee80211_hw *hw) | |||
2290 | 2698 | ||
2291 | /* we should be verifying the device is ready to be opened */ | 2699 | /* we should be verifying the device is ready to be opened */ |
2292 | mutex_lock(&priv->mutex); | 2700 | mutex_lock(&priv->mutex); |
2293 | |||
2294 | /* fetch ucode file from disk, alloc and copy to bus-master buffers ... | ||
2295 | * ucode filename and max sizes are card-specific. */ | ||
2296 | |||
2297 | if (!priv->ucode_code.len) { | ||
2298 | ret = iwl_read_ucode(priv); | ||
2299 | if (ret) { | ||
2300 | IWL_ERR(priv, "Could not read microcode: %d\n", ret); | ||
2301 | mutex_unlock(&priv->mutex); | ||
2302 | return ret; | ||
2303 | } | ||
2304 | } | ||
2305 | |||
2306 | ret = __iwl_up(priv); | 2701 | ret = __iwl_up(priv); |
2307 | |||
2308 | mutex_unlock(&priv->mutex); | 2702 | mutex_unlock(&priv->mutex); |
2309 | 2703 | ||
2310 | if (ret) | 2704 | if (ret) |
@@ -2328,6 +2722,8 @@ static int iwl_mac_start(struct ieee80211_hw *hw) | |||
2328 | } | 2722 | } |
2329 | } | 2723 | } |
2330 | 2724 | ||
2725 | iwl_led_start(priv); | ||
2726 | |||
2331 | out: | 2727 | out: |
2332 | priv->is_open = 1; | 2728 | priv->is_open = 1; |
2333 | IWL_DEBUG_MAC80211(priv, "leave\n"); | 2729 | IWL_DEBUG_MAC80211(priv, "leave\n"); |
@@ -2404,6 +2800,10 @@ void iwl_config_ap(struct iwl_priv *priv) | |||
2404 | IWL_WARN(priv, "REPLY_RXON_TIMING failed - " | 2800 | IWL_WARN(priv, "REPLY_RXON_TIMING failed - " |
2405 | "Attempting to continue.\n"); | 2801 | "Attempting to continue.\n"); |
2406 | 2802 | ||
2803 | /* AP has all antennas */ | ||
2804 | priv->chain_noise_data.active_chains = | ||
2805 | priv->hw_params.valid_rx_ant; | ||
2806 | iwl_set_rxon_ht(priv, &priv->current_ht_config); | ||
2407 | if (priv->cfg->ops->hcmd->set_rxon_chain) | 2807 | if (priv->cfg->ops->hcmd->set_rxon_chain) |
2408 | priv->cfg->ops->hcmd->set_rxon_chain(priv); | 2808 | priv->cfg->ops->hcmd->set_rxon_chain(priv); |
2409 | 2809 | ||
@@ -2432,10 +2832,11 @@ void iwl_config_ap(struct iwl_priv *priv) | |||
2432 | /* restore RXON assoc */ | 2832 | /* restore RXON assoc */ |
2433 | priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK; | 2833 | priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK; |
2434 | iwlcore_commit_rxon(priv); | 2834 | iwlcore_commit_rxon(priv); |
2835 | iwl_reset_qos(priv); | ||
2435 | spin_lock_irqsave(&priv->lock, flags); | 2836 | spin_lock_irqsave(&priv->lock, flags); |
2436 | iwl_activate_qos(priv, 1); | 2837 | iwl_activate_qos(priv, 1); |
2437 | spin_unlock_irqrestore(&priv->lock, flags); | 2838 | spin_unlock_irqrestore(&priv->lock, flags); |
2438 | iwl_rxon_add_station(priv, iwl_bcast_addr, 0); | 2839 | iwl_add_bcast_station(priv); |
2439 | } | 2840 | } |
2440 | iwl_send_beacon_cmd(priv); | 2841 | iwl_send_beacon_cmd(priv); |
2441 | 2842 | ||
@@ -2445,14 +2846,18 @@ void iwl_config_ap(struct iwl_priv *priv) | |||
2445 | } | 2846 | } |
2446 | 2847 | ||
2447 | static void iwl_mac_update_tkip_key(struct ieee80211_hw *hw, | 2848 | static void iwl_mac_update_tkip_key(struct ieee80211_hw *hw, |
2448 | struct ieee80211_key_conf *keyconf, const u8 *addr, | 2849 | struct ieee80211_vif *vif, |
2449 | u32 iv32, u16 *phase1key) | 2850 | struct ieee80211_key_conf *keyconf, |
2851 | struct ieee80211_sta *sta, | ||
2852 | u32 iv32, u16 *phase1key) | ||
2450 | { | 2853 | { |
2451 | 2854 | ||
2452 | struct iwl_priv *priv = hw->priv; | 2855 | struct iwl_priv *priv = hw->priv; |
2453 | IWL_DEBUG_MAC80211(priv, "enter\n"); | 2856 | IWL_DEBUG_MAC80211(priv, "enter\n"); |
2454 | 2857 | ||
2455 | iwl_update_tkip_key(priv, keyconf, addr, iv32, phase1key); | 2858 | iwl_update_tkip_key(priv, keyconf, |
2859 | sta ? sta->addr : iwl_bcast_addr, | ||
2860 | iv32, phase1key); | ||
2456 | 2861 | ||
2457 | IWL_DEBUG_MAC80211(priv, "leave\n"); | 2862 | IWL_DEBUG_MAC80211(priv, "leave\n"); |
2458 | } | 2863 | } |
@@ -2527,6 +2932,7 @@ static int iwl_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | |||
2527 | } | 2932 | } |
2528 | 2933 | ||
2529 | static int iwl_mac_ampdu_action(struct ieee80211_hw *hw, | 2934 | static int iwl_mac_ampdu_action(struct ieee80211_hw *hw, |
2935 | struct ieee80211_vif *vif, | ||
2530 | enum ieee80211_ampdu_mlme_action action, | 2936 | enum ieee80211_ampdu_mlme_action action, |
2531 | struct ieee80211_sta *sta, u16 tid, u16 *ssn) | 2937 | struct ieee80211_sta *sta, u16 tid, u16 *ssn) |
2532 | { | 2938 | { |
@@ -2560,6 +2966,9 @@ static int iwl_mac_ampdu_action(struct ieee80211_hw *hw, | |||
2560 | return 0; | 2966 | return 0; |
2561 | else | 2967 | else |
2562 | return ret; | 2968 | return ret; |
2969 | case IEEE80211_AMPDU_TX_OPERATIONAL: | ||
2970 | /* do nothing */ | ||
2971 | return -EOPNOTSUPP; | ||
2563 | default: | 2972 | default: |
2564 | IWL_DEBUG_HT(priv, "unknown\n"); | 2973 | IWL_DEBUG_HT(priv, "unknown\n"); |
2565 | return -EINVAL; | 2974 | return -EINVAL; |
@@ -2580,6 +2989,47 @@ static int iwl_mac_get_stats(struct ieee80211_hw *hw, | |||
2580 | return 0; | 2989 | return 0; |
2581 | } | 2990 | } |
2582 | 2991 | ||
2992 | static void iwl_mac_sta_notify(struct ieee80211_hw *hw, | ||
2993 | struct ieee80211_vif *vif, | ||
2994 | enum sta_notify_cmd cmd, | ||
2995 | struct ieee80211_sta *sta) | ||
2996 | { | ||
2997 | struct iwl_priv *priv = hw->priv; | ||
2998 | struct iwl_station_priv *sta_priv = (void *)sta->drv_priv; | ||
2999 | int sta_id; | ||
3000 | |||
3001 | /* | ||
3002 | * TODO: We really should use this callback to | ||
3003 | * actually maintain the station table in | ||
3004 | * the device. | ||
3005 | */ | ||
3006 | |||
3007 | switch (cmd) { | ||
3008 | case STA_NOTIFY_ADD: | ||
3009 | atomic_set(&sta_priv->pending_frames, 0); | ||
3010 | if (vif->type == NL80211_IFTYPE_AP) | ||
3011 | sta_priv->client = true; | ||
3012 | break; | ||
3013 | case STA_NOTIFY_SLEEP: | ||
3014 | WARN_ON(!sta_priv->client); | ||
3015 | sta_priv->asleep = true; | ||
3016 | if (atomic_read(&sta_priv->pending_frames) > 0) | ||
3017 | ieee80211_sta_block_awake(hw, sta, true); | ||
3018 | break; | ||
3019 | case STA_NOTIFY_AWAKE: | ||
3020 | WARN_ON(!sta_priv->client); | ||
3021 | if (!sta_priv->asleep) | ||
3022 | break; | ||
3023 | sta_priv->asleep = false; | ||
3024 | sta_id = iwl_find_station(priv, sta->addr); | ||
3025 | if (sta_id != IWL_INVALID_STATION) | ||
3026 | iwl_sta_modify_ps_wake(priv, sta_id); | ||
3027 | break; | ||
3028 | default: | ||
3029 | break; | ||
3030 | } | ||
3031 | } | ||
3032 | |||
2583 | /***************************************************************************** | 3033 | /***************************************************************************** |
2584 | * | 3034 | * |
2585 | * sysfs attributes | 3035 | * sysfs attributes |
@@ -2774,7 +3224,7 @@ static ssize_t show_statistics(struct device *d, | |||
2774 | return -EAGAIN; | 3224 | return -EAGAIN; |
2775 | 3225 | ||
2776 | mutex_lock(&priv->mutex); | 3226 | mutex_lock(&priv->mutex); |
2777 | rc = iwl_send_statistics_request(priv, 0); | 3227 | rc = iwl_send_statistics_request(priv, CMD_SYNC, false); |
2778 | mutex_unlock(&priv->mutex); | 3228 | mutex_unlock(&priv->mutex); |
2779 | 3229 | ||
2780 | if (rc) { | 3230 | if (rc) { |
@@ -2799,6 +3249,40 @@ static ssize_t show_statistics(struct device *d, | |||
2799 | 3249 | ||
2800 | static DEVICE_ATTR(statistics, S_IRUGO, show_statistics, NULL); | 3250 | static DEVICE_ATTR(statistics, S_IRUGO, show_statistics, NULL); |
2801 | 3251 | ||
3252 | static ssize_t show_rts_ht_protection(struct device *d, | ||
3253 | struct device_attribute *attr, char *buf) | ||
3254 | { | ||
3255 | struct iwl_priv *priv = dev_get_drvdata(d); | ||
3256 | |||
3257 | return sprintf(buf, "%s\n", | ||
3258 | priv->cfg->use_rts_for_ht ? "RTS/CTS" : "CTS-to-self"); | ||
3259 | } | ||
3260 | |||
3261 | static ssize_t store_rts_ht_protection(struct device *d, | ||
3262 | struct device_attribute *attr, | ||
3263 | const char *buf, size_t count) | ||
3264 | { | ||
3265 | struct iwl_priv *priv = dev_get_drvdata(d); | ||
3266 | unsigned long val; | ||
3267 | int ret; | ||
3268 | |||
3269 | ret = strict_strtoul(buf, 10, &val); | ||
3270 | if (ret) | ||
3271 | IWL_INFO(priv, "Input is not in decimal form.\n"); | ||
3272 | else { | ||
3273 | if (!iwl_is_associated(priv)) | ||
3274 | priv->cfg->use_rts_for_ht = val ? true : false; | ||
3275 | else | ||
3276 | IWL_ERR(priv, "Sta associated with AP - " | ||
3277 | "Change protection mechanism is not allowed\n"); | ||
3278 | ret = count; | ||
3279 | } | ||
3280 | return ret; | ||
3281 | } | ||
3282 | |||
3283 | static DEVICE_ATTR(rts_ht_protection, S_IWUSR | S_IRUGO, | ||
3284 | show_rts_ht_protection, store_rts_ht_protection); | ||
3285 | |||
2802 | 3286 | ||
2803 | /***************************************************************************** | 3287 | /***************************************************************************** |
2804 | * | 3288 | * |
@@ -2812,7 +3296,6 @@ static void iwl_setup_deferred_work(struct iwl_priv *priv) | |||
2812 | 3296 | ||
2813 | init_waitqueue_head(&priv->wait_command_queue); | 3297 | init_waitqueue_head(&priv->wait_command_queue); |
2814 | 3298 | ||
2815 | INIT_WORK(&priv->up, iwl_bg_up); | ||
2816 | INIT_WORK(&priv->restart, iwl_bg_restart); | 3299 | INIT_WORK(&priv->restart, iwl_bg_restart); |
2817 | INIT_WORK(&priv->rx_replenish, iwl_bg_rx_replenish); | 3300 | INIT_WORK(&priv->rx_replenish, iwl_bg_rx_replenish); |
2818 | INIT_WORK(&priv->beacon_update, iwl_bg_beacon_update); | 3301 | INIT_WORK(&priv->beacon_update, iwl_bg_beacon_update); |
@@ -2829,6 +3312,10 @@ static void iwl_setup_deferred_work(struct iwl_priv *priv) | |||
2829 | priv->statistics_periodic.data = (unsigned long)priv; | 3312 | priv->statistics_periodic.data = (unsigned long)priv; |
2830 | priv->statistics_periodic.function = iwl_bg_statistics_periodic; | 3313 | priv->statistics_periodic.function = iwl_bg_statistics_periodic; |
2831 | 3314 | ||
3315 | init_timer(&priv->ucode_trace); | ||
3316 | priv->ucode_trace.data = (unsigned long)priv; | ||
3317 | priv->ucode_trace.function = iwl_bg_ucode_trace; | ||
3318 | |||
2832 | if (!priv->cfg->use_isr_legacy) | 3319 | if (!priv->cfg->use_isr_legacy) |
2833 | tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long)) | 3320 | tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long)) |
2834 | iwl_irq_tasklet, (unsigned long)priv); | 3321 | iwl_irq_tasklet, (unsigned long)priv); |
@@ -2844,9 +3331,109 @@ static void iwl_cancel_deferred_work(struct iwl_priv *priv) | |||
2844 | 3331 | ||
2845 | cancel_delayed_work_sync(&priv->init_alive_start); | 3332 | cancel_delayed_work_sync(&priv->init_alive_start); |
2846 | cancel_delayed_work(&priv->scan_check); | 3333 | cancel_delayed_work(&priv->scan_check); |
3334 | cancel_work_sync(&priv->start_internal_scan); | ||
2847 | cancel_delayed_work(&priv->alive_start); | 3335 | cancel_delayed_work(&priv->alive_start); |
2848 | cancel_work_sync(&priv->beacon_update); | 3336 | cancel_work_sync(&priv->beacon_update); |
2849 | del_timer_sync(&priv->statistics_periodic); | 3337 | del_timer_sync(&priv->statistics_periodic); |
3338 | del_timer_sync(&priv->ucode_trace); | ||
3339 | } | ||
3340 | |||
3341 | static void iwl_init_hw_rates(struct iwl_priv *priv, | ||
3342 | struct ieee80211_rate *rates) | ||
3343 | { | ||
3344 | int i; | ||
3345 | |||
3346 | for (i = 0; i < IWL_RATE_COUNT_LEGACY; i++) { | ||
3347 | rates[i].bitrate = iwl_rates[i].ieee * 5; | ||
3348 | rates[i].hw_value = i; /* Rate scaling will work on indexes */ | ||
3349 | rates[i].hw_value_short = i; | ||
3350 | rates[i].flags = 0; | ||
3351 | if ((i >= IWL_FIRST_CCK_RATE) && (i <= IWL_LAST_CCK_RATE)) { | ||
3352 | /* | ||
3353 | * If CCK != 1M then set short preamble rate flag. | ||
3354 | */ | ||
3355 | rates[i].flags |= | ||
3356 | (iwl_rates[i].plcp == IWL_RATE_1M_PLCP) ? | ||
3357 | 0 : IEEE80211_RATE_SHORT_PREAMBLE; | ||
3358 | } | ||
3359 | } | ||
3360 | } | ||
3361 | |||
3362 | static int iwl_init_drv(struct iwl_priv *priv) | ||
3363 | { | ||
3364 | int ret; | ||
3365 | |||
3366 | priv->ibss_beacon = NULL; | ||
3367 | |||
3368 | spin_lock_init(&priv->sta_lock); | ||
3369 | spin_lock_init(&priv->hcmd_lock); | ||
3370 | |||
3371 | INIT_LIST_HEAD(&priv->free_frames); | ||
3372 | |||
3373 | mutex_init(&priv->mutex); | ||
3374 | mutex_init(&priv->sync_cmd_mutex); | ||
3375 | |||
3376 | /* Clear the driver's (not device's) station table */ | ||
3377 | iwl_clear_stations_table(priv); | ||
3378 | |||
3379 | priv->ieee_channels = NULL; | ||
3380 | priv->ieee_rates = NULL; | ||
3381 | priv->band = IEEE80211_BAND_2GHZ; | ||
3382 | |||
3383 | priv->iw_mode = NL80211_IFTYPE_STATION; | ||
3384 | priv->current_ht_config.smps = IEEE80211_SMPS_STATIC; | ||
3385 | priv->missed_beacon_threshold = IWL_MISSED_BEACON_THRESHOLD_DEF; | ||
3386 | |||
3387 | /* initialize force reset */ | ||
3388 | priv->force_reset[IWL_RF_RESET].reset_duration = | ||
3389 | IWL_DELAY_NEXT_FORCE_RF_RESET; | ||
3390 | priv->force_reset[IWL_FW_RESET].reset_duration = | ||
3391 | IWL_DELAY_NEXT_FORCE_FW_RELOAD; | ||
3392 | |||
3393 | /* Choose which receivers/antennas to use */ | ||
3394 | if (priv->cfg->ops->hcmd->set_rxon_chain) | ||
3395 | priv->cfg->ops->hcmd->set_rxon_chain(priv); | ||
3396 | |||
3397 | iwl_init_scan_params(priv); | ||
3398 | |||
3399 | iwl_reset_qos(priv); | ||
3400 | |||
3401 | priv->qos_data.qos_active = 0; | ||
3402 | priv->qos_data.qos_cap.val = 0; | ||
3403 | |||
3404 | priv->rates_mask = IWL_RATES_MASK; | ||
3405 | /* Set the tx_power_user_lmt to the lowest power level | ||
3406 | * this value will get overwritten by channel max power avg | ||
3407 | * from eeprom */ | ||
3408 | priv->tx_power_user_lmt = IWL_TX_POWER_TARGET_POWER_MIN; | ||
3409 | |||
3410 | ret = iwl_init_channel_map(priv); | ||
3411 | if (ret) { | ||
3412 | IWL_ERR(priv, "initializing regulatory failed: %d\n", ret); | ||
3413 | goto err; | ||
3414 | } | ||
3415 | |||
3416 | ret = iwlcore_init_geos(priv); | ||
3417 | if (ret) { | ||
3418 | IWL_ERR(priv, "initializing geos failed: %d\n", ret); | ||
3419 | goto err_free_channel_map; | ||
3420 | } | ||
3421 | iwl_init_hw_rates(priv, priv->ieee_rates); | ||
3422 | |||
3423 | return 0; | ||
3424 | |||
3425 | err_free_channel_map: | ||
3426 | iwl_free_channel_map(priv); | ||
3427 | err: | ||
3428 | return ret; | ||
3429 | } | ||
3430 | |||
3431 | static void iwl_uninit_drv(struct iwl_priv *priv) | ||
3432 | { | ||
3433 | iwl_calib_free_results(priv); | ||
3434 | iwlcore_free_geos(priv); | ||
3435 | iwl_free_channel_map(priv); | ||
3436 | kfree(priv->scan); | ||
2850 | } | 3437 | } |
2851 | 3438 | ||
2852 | static struct attribute *iwl_sysfs_entries[] = { | 3439 | static struct attribute *iwl_sysfs_entries[] = { |
@@ -2855,6 +3442,7 @@ static struct attribute *iwl_sysfs_entries[] = { | |||
2855 | &dev_attr_statistics.attr, | 3442 | &dev_attr_statistics.attr, |
2856 | &dev_attr_temperature.attr, | 3443 | &dev_attr_temperature.attr, |
2857 | &dev_attr_tx_power.attr, | 3444 | &dev_attr_tx_power.attr, |
3445 | &dev_attr_rts_ht_protection.attr, | ||
2858 | #ifdef CONFIG_IWLWIFI_DEBUG | 3446 | #ifdef CONFIG_IWLWIFI_DEBUG |
2859 | &dev_attr_debug_level.attr, | 3447 | &dev_attr_debug_level.attr, |
2860 | #endif | 3448 | #endif |
@@ -2877,12 +3465,12 @@ static struct ieee80211_ops iwl_hw_ops = { | |||
2877 | .set_key = iwl_mac_set_key, | 3465 | .set_key = iwl_mac_set_key, |
2878 | .update_tkip_key = iwl_mac_update_tkip_key, | 3466 | .update_tkip_key = iwl_mac_update_tkip_key, |
2879 | .get_stats = iwl_mac_get_stats, | 3467 | .get_stats = iwl_mac_get_stats, |
2880 | .get_tx_stats = iwl_mac_get_tx_stats, | ||
2881 | .conf_tx = iwl_mac_conf_tx, | 3468 | .conf_tx = iwl_mac_conf_tx, |
2882 | .reset_tsf = iwl_mac_reset_tsf, | 3469 | .reset_tsf = iwl_mac_reset_tsf, |
2883 | .bss_info_changed = iwl_bss_info_changed, | 3470 | .bss_info_changed = iwl_bss_info_changed, |
2884 | .ampdu_action = iwl_mac_ampdu_action, | 3471 | .ampdu_action = iwl_mac_ampdu_action, |
2885 | .hw_scan = iwl_mac_hw_scan | 3472 | .hw_scan = iwl_mac_hw_scan, |
3473 | .sta_notify = iwl_mac_sta_notify, | ||
2886 | }; | 3474 | }; |
2887 | 3475 | ||
2888 | static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | 3476 | static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) |
@@ -2972,10 +3560,19 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
2972 | (unsigned long long) pci_resource_len(pdev, 0)); | 3560 | (unsigned long long) pci_resource_len(pdev, 0)); |
2973 | IWL_DEBUG_INFO(priv, "pci_resource_base = %p\n", priv->hw_base); | 3561 | IWL_DEBUG_INFO(priv, "pci_resource_base = %p\n", priv->hw_base); |
2974 | 3562 | ||
2975 | /* this spin lock will be used in apm_ops.init and EEPROM access | 3563 | /* these spin locks will be used in apm_ops.init and EEPROM access |
2976 | * we should init now | 3564 | * we should init now |
2977 | */ | 3565 | */ |
2978 | spin_lock_init(&priv->reg_lock); | 3566 | spin_lock_init(&priv->reg_lock); |
3567 | spin_lock_init(&priv->lock); | ||
3568 | |||
3569 | /* | ||
3570 | * stop and reset the on-board processor just in case it is in a | ||
3571 | * strange state ... like being left stranded by a primary kernel | ||
3572 | * and this is now the kdump kernel trying to start up | ||
3573 | */ | ||
3574 | iwl_write32(priv, CSR_RESET, CSR_RESET_REG_FLAG_NEVO_RESET); | ||
3575 | |||
2979 | iwl_hw_detect(priv); | 3576 | iwl_hw_detect(priv); |
2980 | IWL_INFO(priv, "Detected Intel Wireless WiFi Link %s REV=0x%X\n", | 3577 | IWL_INFO(priv, "Detected Intel Wireless WiFi Link %s REV=0x%X\n", |
2981 | priv->cfg->name, priv->hw_rev); | 3578 | priv->cfg->name, priv->hw_rev); |
@@ -2990,12 +3587,6 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
2990 | goto out_iounmap; | 3587 | goto out_iounmap; |
2991 | } | 3588 | } |
2992 | 3589 | ||
2993 | /* amp init */ | ||
2994 | err = priv->cfg->ops->lib->apm_ops.init(priv); | ||
2995 | if (err < 0) { | ||
2996 | IWL_ERR(priv, "Failed to init APMG\n"); | ||
2997 | goto out_iounmap; | ||
2998 | } | ||
2999 | /***************** | 3590 | /***************** |
3000 | * 4. Read EEPROM | 3591 | * 4. Read EEPROM |
3001 | *****************/ | 3592 | *****************/ |
@@ -3056,9 +3647,9 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
3056 | iwl_setup_deferred_work(priv); | 3647 | iwl_setup_deferred_work(priv); |
3057 | iwl_setup_rx_handlers(priv); | 3648 | iwl_setup_rx_handlers(priv); |
3058 | 3649 | ||
3059 | /********************************** | 3650 | /********************************************* |
3060 | * 8. Setup and register mac80211 | 3651 | * 8. Enable interrupts and read RFKILL state |
3061 | **********************************/ | 3652 | *********************************************/ |
3062 | 3653 | ||
3063 | /* enable interrupts if needed: hw bug w/a */ | 3654 | /* enable interrupts if needed: hw bug w/a */ |
3064 | pci_read_config_word(priv->pci_dev, PCI_COMMAND, &pci_cmd); | 3655 | pci_read_config_word(priv->pci_dev, PCI_COMMAND, &pci_cmd); |
@@ -3069,14 +3660,6 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
3069 | 3660 | ||
3070 | iwl_enable_interrupts(priv); | 3661 | iwl_enable_interrupts(priv); |
3071 | 3662 | ||
3072 | err = iwl_setup_mac(priv); | ||
3073 | if (err) | ||
3074 | goto out_remove_sysfs; | ||
3075 | |||
3076 | err = iwl_dbgfs_register(priv, DRV_NAME); | ||
3077 | if (err) | ||
3078 | IWL_ERR(priv, "failed to create debugfs files. Ignoring error: %d\n", err); | ||
3079 | |||
3080 | /* If platform's RF_KILL switch is NOT set to KILL */ | 3663 | /* If platform's RF_KILL switch is NOT set to KILL */ |
3081 | if (iwl_read32(priv, CSR_GP_CNTRL) & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW) | 3664 | if (iwl_read32(priv, CSR_GP_CNTRL) & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW) |
3082 | clear_bit(STATUS_RF_KILL_HW, &priv->status); | 3665 | clear_bit(STATUS_RF_KILL_HW, &priv->status); |
@@ -3088,6 +3671,11 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
3088 | 3671 | ||
3089 | iwl_power_initialize(priv); | 3672 | iwl_power_initialize(priv); |
3090 | iwl_tt_initialize(priv); | 3673 | iwl_tt_initialize(priv); |
3674 | |||
3675 | err = iwl_request_firmware(priv, true); | ||
3676 | if (err) | ||
3677 | goto out_remove_sysfs; | ||
3678 | |||
3091 | return 0; | 3679 | return 0; |
3092 | 3680 | ||
3093 | out_remove_sysfs: | 3681 | out_remove_sysfs: |
@@ -3141,6 +3729,15 @@ static void __devexit iwl_pci_remove(struct pci_dev *pdev) | |||
3141 | iwl_down(priv); | 3729 | iwl_down(priv); |
3142 | } | 3730 | } |
3143 | 3731 | ||
3732 | /* | ||
3733 | * Make sure device is reset to low power before unloading driver. | ||
3734 | * This may be redundant with iwl_down(), but there are paths to | ||
3735 | * run iwl_down() without calling apm_ops.stop(), and there are | ||
3736 | * paths to avoid running iwl_down() at all before leaving driver. | ||
3737 | * This (inexpensive) call *makes sure* device is reset. | ||
3738 | */ | ||
3739 | priv->cfg->ops->lib->apm_ops.stop(priv); | ||
3740 | |||
3144 | iwl_tt_exit(priv); | 3741 | iwl_tt_exit(priv); |
3145 | 3742 | ||
3146 | /* make sure we flush any pending irq or | 3743 | /* make sure we flush any pending irq or |
@@ -3197,43 +3794,103 @@ static void __devexit iwl_pci_remove(struct pci_dev *pdev) | |||
3197 | *****************************************************************************/ | 3794 | *****************************************************************************/ |
3198 | 3795 | ||
3199 | /* Hardware specific file defines the PCI IDs table for that hardware module */ | 3796 | /* Hardware specific file defines the PCI IDs table for that hardware module */ |
3200 | static struct pci_device_id iwl_hw_card_ids[] = { | 3797 | static DEFINE_PCI_DEVICE_TABLE(iwl_hw_card_ids) = { |
3201 | #ifdef CONFIG_IWL4965 | 3798 | #ifdef CONFIG_IWL4965 |
3202 | {IWL_PCI_DEVICE(0x4229, PCI_ANY_ID, iwl4965_agn_cfg)}, | 3799 | {IWL_PCI_DEVICE(0x4229, PCI_ANY_ID, iwl4965_agn_cfg)}, |
3203 | {IWL_PCI_DEVICE(0x4230, PCI_ANY_ID, iwl4965_agn_cfg)}, | 3800 | {IWL_PCI_DEVICE(0x4230, PCI_ANY_ID, iwl4965_agn_cfg)}, |
3204 | #endif /* CONFIG_IWL4965 */ | 3801 | #endif /* CONFIG_IWL4965 */ |
3205 | #ifdef CONFIG_IWL5000 | 3802 | #ifdef CONFIG_IWL5000 |
3206 | {IWL_PCI_DEVICE(0x4232, 0x1205, iwl5100_bg_cfg)}, | 3803 | /* 5100 Series WiFi */ |
3207 | {IWL_PCI_DEVICE(0x4232, 0x1305, iwl5100_bg_cfg)}, | 3804 | {IWL_PCI_DEVICE(0x4232, 0x1201, iwl5100_agn_cfg)}, /* Mini Card */ |
3208 | {IWL_PCI_DEVICE(0x4232, 0x1206, iwl5100_abg_cfg)}, | 3805 | {IWL_PCI_DEVICE(0x4232, 0x1301, iwl5100_agn_cfg)}, /* Half Mini Card */ |
3209 | {IWL_PCI_DEVICE(0x4232, 0x1306, iwl5100_abg_cfg)}, | 3806 | {IWL_PCI_DEVICE(0x4232, 0x1204, iwl5100_agn_cfg)}, /* Mini Card */ |
3210 | {IWL_PCI_DEVICE(0x4232, 0x1326, iwl5100_abg_cfg)}, | 3807 | {IWL_PCI_DEVICE(0x4232, 0x1304, iwl5100_agn_cfg)}, /* Half Mini Card */ |
3211 | {IWL_PCI_DEVICE(0x4237, 0x1216, iwl5100_abg_cfg)}, | 3808 | {IWL_PCI_DEVICE(0x4232, 0x1205, iwl5100_bgn_cfg)}, /* Mini Card */ |
3212 | {IWL_PCI_DEVICE(0x4232, PCI_ANY_ID, iwl5100_agn_cfg)}, | 3809 | {IWL_PCI_DEVICE(0x4232, 0x1305, iwl5100_bgn_cfg)}, /* Half Mini Card */ |
3213 | {IWL_PCI_DEVICE(0x4235, PCI_ANY_ID, iwl5300_agn_cfg)}, | 3810 | {IWL_PCI_DEVICE(0x4232, 0x1206, iwl5100_abg_cfg)}, /* Mini Card */ |
3214 | {IWL_PCI_DEVICE(0x4236, PCI_ANY_ID, iwl5300_agn_cfg)}, | 3811 | {IWL_PCI_DEVICE(0x4232, 0x1306, iwl5100_abg_cfg)}, /* Half Mini Card */ |
3215 | {IWL_PCI_DEVICE(0x4237, PCI_ANY_ID, iwl5100_agn_cfg)}, | 3812 | {IWL_PCI_DEVICE(0x4232, 0x1221, iwl5100_agn_cfg)}, /* Mini Card */ |
3216 | /* 5350 WiFi/WiMax */ | 3813 | {IWL_PCI_DEVICE(0x4232, 0x1321, iwl5100_agn_cfg)}, /* Half Mini Card */ |
3217 | {IWL_PCI_DEVICE(0x423A, 0x1001, iwl5350_agn_cfg)}, | 3814 | {IWL_PCI_DEVICE(0x4232, 0x1224, iwl5100_agn_cfg)}, /* Mini Card */ |
3218 | {IWL_PCI_DEVICE(0x423A, 0x1021, iwl5350_agn_cfg)}, | 3815 | {IWL_PCI_DEVICE(0x4232, 0x1324, iwl5100_agn_cfg)}, /* Half Mini Card */ |
3219 | {IWL_PCI_DEVICE(0x423B, 0x1011, iwl5350_agn_cfg)}, | 3816 | {IWL_PCI_DEVICE(0x4232, 0x1225, iwl5100_bgn_cfg)}, /* Mini Card */ |
3220 | /* 5150 Wifi/WiMax */ | 3817 | {IWL_PCI_DEVICE(0x4232, 0x1325, iwl5100_bgn_cfg)}, /* Half Mini Card */ |
3221 | {IWL_PCI_DEVICE(0x423C, PCI_ANY_ID, iwl5150_agn_cfg)}, | 3818 | {IWL_PCI_DEVICE(0x4232, 0x1226, iwl5100_abg_cfg)}, /* Mini Card */ |
3222 | {IWL_PCI_DEVICE(0x423D, PCI_ANY_ID, iwl5150_agn_cfg)}, | 3819 | {IWL_PCI_DEVICE(0x4232, 0x1326, iwl5100_abg_cfg)}, /* Half Mini Card */ |
3223 | /* 6000/6050 Series */ | 3820 | {IWL_PCI_DEVICE(0x4237, 0x1211, iwl5100_agn_cfg)}, /* Mini Card */ |
3224 | {IWL_PCI_DEVICE(0x008D, PCI_ANY_ID, iwl6000h_2agn_cfg)}, | 3821 | {IWL_PCI_DEVICE(0x4237, 0x1311, iwl5100_agn_cfg)}, /* Half Mini Card */ |
3225 | {IWL_PCI_DEVICE(0x008E, PCI_ANY_ID, iwl6000h_2agn_cfg)}, | 3822 | {IWL_PCI_DEVICE(0x4237, 0x1214, iwl5100_agn_cfg)}, /* Mini Card */ |
3226 | {IWL_PCI_DEVICE(0x422B, PCI_ANY_ID, iwl6000_3agn_cfg)}, | 3823 | {IWL_PCI_DEVICE(0x4237, 0x1314, iwl5100_agn_cfg)}, /* Half Mini Card */ |
3227 | {IWL_PCI_DEVICE(0x422C, PCI_ANY_ID, iwl6000i_2agn_cfg)}, | 3824 | {IWL_PCI_DEVICE(0x4237, 0x1215, iwl5100_bgn_cfg)}, /* Mini Card */ |
3228 | {IWL_PCI_DEVICE(0x4238, PCI_ANY_ID, iwl6000_3agn_cfg)}, | 3825 | {IWL_PCI_DEVICE(0x4237, 0x1315, iwl5100_bgn_cfg)}, /* Half Mini Card */ |
3229 | {IWL_PCI_DEVICE(0x4239, PCI_ANY_ID, iwl6000i_2agn_cfg)}, | 3826 | {IWL_PCI_DEVICE(0x4237, 0x1216, iwl5100_abg_cfg)}, /* Mini Card */ |
3230 | {IWL_PCI_DEVICE(0x0086, PCI_ANY_ID, iwl6050_3agn_cfg)}, | 3827 | {IWL_PCI_DEVICE(0x4237, 0x1316, iwl5100_abg_cfg)}, /* Half Mini Card */ |
3231 | {IWL_PCI_DEVICE(0x0087, PCI_ANY_ID, iwl6050_2agn_cfg)}, | 3828 | |
3232 | {IWL_PCI_DEVICE(0x0088, PCI_ANY_ID, iwl6050_3agn_cfg)}, | 3829 | /* 5300 Series WiFi */ |
3233 | {IWL_PCI_DEVICE(0x0089, PCI_ANY_ID, iwl6050_2agn_cfg)}, | 3830 | {IWL_PCI_DEVICE(0x4235, 0x1021, iwl5300_agn_cfg)}, /* Mini Card */ |
3831 | {IWL_PCI_DEVICE(0x4235, 0x1121, iwl5300_agn_cfg)}, /* Half Mini Card */ | ||
3832 | {IWL_PCI_DEVICE(0x4235, 0x1024, iwl5300_agn_cfg)}, /* Mini Card */ | ||
3833 | {IWL_PCI_DEVICE(0x4235, 0x1124, iwl5300_agn_cfg)}, /* Half Mini Card */ | ||
3834 | {IWL_PCI_DEVICE(0x4235, 0x1001, iwl5300_agn_cfg)}, /* Mini Card */ | ||
3835 | {IWL_PCI_DEVICE(0x4235, 0x1101, iwl5300_agn_cfg)}, /* Half Mini Card */ | ||
3836 | {IWL_PCI_DEVICE(0x4235, 0x1004, iwl5300_agn_cfg)}, /* Mini Card */ | ||
3837 | {IWL_PCI_DEVICE(0x4235, 0x1104, iwl5300_agn_cfg)}, /* Half Mini Card */ | ||
3838 | {IWL_PCI_DEVICE(0x4236, 0x1011, iwl5300_agn_cfg)}, /* Mini Card */ | ||
3839 | {IWL_PCI_DEVICE(0x4236, 0x1111, iwl5300_agn_cfg)}, /* Half Mini Card */ | ||
3840 | {IWL_PCI_DEVICE(0x4236, 0x1014, iwl5300_agn_cfg)}, /* Mini Card */ | ||
3841 | {IWL_PCI_DEVICE(0x4236, 0x1114, iwl5300_agn_cfg)}, /* Half Mini Card */ | ||
3842 | |||
3843 | /* 5350 Series WiFi/WiMax */ | ||
3844 | {IWL_PCI_DEVICE(0x423A, 0x1001, iwl5350_agn_cfg)}, /* Mini Card */ | ||
3845 | {IWL_PCI_DEVICE(0x423A, 0x1021, iwl5350_agn_cfg)}, /* Mini Card */ | ||
3846 | {IWL_PCI_DEVICE(0x423B, 0x1011, iwl5350_agn_cfg)}, /* Mini Card */ | ||
3847 | |||
3848 | /* 5150 Series Wifi/WiMax */ | ||
3849 | {IWL_PCI_DEVICE(0x423C, 0x1201, iwl5150_agn_cfg)}, /* Mini Card */ | ||
3850 | {IWL_PCI_DEVICE(0x423C, 0x1301, iwl5150_agn_cfg)}, /* Half Mini Card */ | ||
3851 | {IWL_PCI_DEVICE(0x423C, 0x1206, iwl5150_abg_cfg)}, /* Mini Card */ | ||
3852 | {IWL_PCI_DEVICE(0x423C, 0x1306, iwl5150_abg_cfg)}, /* Half Mini Card */ | ||
3853 | {IWL_PCI_DEVICE(0x423C, 0x1221, iwl5150_agn_cfg)}, /* Mini Card */ | ||
3854 | {IWL_PCI_DEVICE(0x423C, 0x1321, iwl5150_agn_cfg)}, /* Half Mini Card */ | ||
3855 | |||
3856 | {IWL_PCI_DEVICE(0x423D, 0x1211, iwl5150_agn_cfg)}, /* Mini Card */ | ||
3857 | {IWL_PCI_DEVICE(0x423D, 0x1311, iwl5150_agn_cfg)}, /* Half Mini Card */ | ||
3858 | {IWL_PCI_DEVICE(0x423D, 0x1216, iwl5150_abg_cfg)}, /* Mini Card */ | ||
3859 | {IWL_PCI_DEVICE(0x423D, 0x1316, iwl5150_abg_cfg)}, /* Half Mini Card */ | ||
3860 | |||
3861 | /* 6x00 Series */ | ||
3862 | {IWL_PCI_DEVICE(0x422B, 0x1101, iwl6000_3agn_cfg)}, | ||
3863 | {IWL_PCI_DEVICE(0x422B, 0x1121, iwl6000_3agn_cfg)}, | ||
3864 | {IWL_PCI_DEVICE(0x422C, 0x1301, iwl6000i_2agn_cfg)}, | ||
3865 | {IWL_PCI_DEVICE(0x422C, 0x1306, iwl6000i_2abg_cfg)}, | ||
3866 | {IWL_PCI_DEVICE(0x422C, 0x1307, iwl6000i_2bg_cfg)}, | ||
3867 | {IWL_PCI_DEVICE(0x422C, 0x1321, iwl6000i_2agn_cfg)}, | ||
3868 | {IWL_PCI_DEVICE(0x422C, 0x1326, iwl6000i_2abg_cfg)}, | ||
3869 | {IWL_PCI_DEVICE(0x4238, 0x1111, iwl6000_3agn_cfg)}, | ||
3870 | {IWL_PCI_DEVICE(0x4239, 0x1311, iwl6000i_2agn_cfg)}, | ||
3871 | {IWL_PCI_DEVICE(0x4239, 0x1316, iwl6000i_2abg_cfg)}, | ||
3872 | |||
3873 | /* 6x50 WiFi/WiMax Series */ | ||
3874 | {IWL_PCI_DEVICE(0x0087, 0x1301, iwl6050_2agn_cfg)}, | ||
3875 | {IWL_PCI_DEVICE(0x0087, 0x1306, iwl6050_2abg_cfg)}, | ||
3876 | {IWL_PCI_DEVICE(0x0087, 0x1321, iwl6050_2agn_cfg)}, | ||
3877 | {IWL_PCI_DEVICE(0x0087, 0x1326, iwl6050_2abg_cfg)}, | ||
3878 | {IWL_PCI_DEVICE(0x0089, 0x1311, iwl6050_2agn_cfg)}, | ||
3879 | {IWL_PCI_DEVICE(0x0089, 0x1316, iwl6050_2abg_cfg)}, | ||
3880 | |||
3234 | /* 1000 Series WiFi */ | 3881 | /* 1000 Series WiFi */ |
3235 | {IWL_PCI_DEVICE(0x0083, PCI_ANY_ID, iwl1000_bgn_cfg)}, | 3882 | {IWL_PCI_DEVICE(0x0083, 0x1205, iwl1000_bgn_cfg)}, |
3236 | {IWL_PCI_DEVICE(0x0084, PCI_ANY_ID, iwl1000_bgn_cfg)}, | 3883 | {IWL_PCI_DEVICE(0x0083, 0x1305, iwl1000_bgn_cfg)}, |
3884 | {IWL_PCI_DEVICE(0x0083, 0x1225, iwl1000_bgn_cfg)}, | ||
3885 | {IWL_PCI_DEVICE(0x0083, 0x1325, iwl1000_bgn_cfg)}, | ||
3886 | {IWL_PCI_DEVICE(0x0084, 0x1215, iwl1000_bgn_cfg)}, | ||
3887 | {IWL_PCI_DEVICE(0x0084, 0x1315, iwl1000_bgn_cfg)}, | ||
3888 | {IWL_PCI_DEVICE(0x0083, 0x1206, iwl1000_bg_cfg)}, | ||
3889 | {IWL_PCI_DEVICE(0x0083, 0x1306, iwl1000_bg_cfg)}, | ||
3890 | {IWL_PCI_DEVICE(0x0083, 0x1226, iwl1000_bg_cfg)}, | ||
3891 | {IWL_PCI_DEVICE(0x0083, 0x1326, iwl1000_bg_cfg)}, | ||
3892 | {IWL_PCI_DEVICE(0x0084, 0x1216, iwl1000_bg_cfg)}, | ||
3893 | {IWL_PCI_DEVICE(0x0084, 0x1316, iwl1000_bg_cfg)}, | ||
3237 | #endif /* CONFIG_IWL5000 */ | 3894 | #endif /* CONFIG_IWL5000 */ |
3238 | 3895 | ||
3239 | {0} | 3896 | {0} |
@@ -3288,9 +3945,9 @@ module_exit(iwl_exit); | |||
3288 | module_init(iwl_init); | 3945 | module_init(iwl_init); |
3289 | 3946 | ||
3290 | #ifdef CONFIG_IWLWIFI_DEBUG | 3947 | #ifdef CONFIG_IWLWIFI_DEBUG |
3291 | module_param_named(debug50, iwl_debug_level, uint, 0444); | 3948 | module_param_named(debug50, iwl_debug_level, uint, S_IRUGO); |
3292 | MODULE_PARM_DESC(debug50, "50XX debug output mask (deprecated)"); | 3949 | MODULE_PARM_DESC(debug50, "50XX debug output mask (deprecated)"); |
3293 | module_param_named(debug, iwl_debug_level, uint, 0644); | 3950 | module_param_named(debug, iwl_debug_level, uint, S_IRUGO | S_IWUSR); |
3294 | MODULE_PARM_DESC(debug, "debug output mask"); | 3951 | MODULE_PARM_DESC(debug, "debug output mask"); |
3295 | #endif | 3952 | #endif |
3296 | 3953 | ||