diff options
author | John W. Linville <linville@tuxdriver.com> | 2010-04-15 16:21:34 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2010-04-15 16:21:34 -0400 |
commit | 5c01d5669356e13f0fb468944c1dd4c6a7e978ad (patch) | |
tree | fa43345288d7b25fac92b3b35360a177c4947313 /drivers/net/wireless/iwlwifi/iwl-3945.c | |
parent | fea069152614cdeefba4b2bf80afcddb9c217fc8 (diff) | |
parent | a5e944f1d955f3819503348426763e21e0413ba6 (diff) |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6 into for-davem
Conflicts:
Documentation/feature-removal-schedule.txt
drivers/net/wireless/ath/ath5k/phy.c
drivers/net/wireless/wl12xx/wl1271_main.c
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-3945.c')
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-3945.c | 79 |
1 files changed, 15 insertions, 64 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c index 7ac6cec006d0..bde3b4cbab9d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.c +++ b/drivers/net/wireless/iwlwifi/iwl-3945.c | |||
@@ -192,12 +192,12 @@ static int iwl3945_hwrate_to_plcp_idx(u8 plcp) | |||
192 | } | 192 | } |
193 | 193 | ||
194 | #ifdef CONFIG_IWLWIFI_DEBUG | 194 | #ifdef CONFIG_IWLWIFI_DEBUG |
195 | #define TX_STATUS_ENTRY(x) case TX_STATUS_FAIL_ ## x: return #x | 195 | #define TX_STATUS_ENTRY(x) case TX_3945_STATUS_FAIL_ ## x: return #x |
196 | 196 | ||
197 | static const char *iwl3945_get_tx_fail_reason(u32 status) | 197 | static const char *iwl3945_get_tx_fail_reason(u32 status) |
198 | { | 198 | { |
199 | switch (status & TX_STATUS_MSK) { | 199 | switch (status & TX_STATUS_MSK) { |
200 | case TX_STATUS_SUCCESS: | 200 | case TX_3945_STATUS_SUCCESS: |
201 | return "SUCCESS"; | 201 | return "SUCCESS"; |
202 | TX_STATUS_ENTRY(SHORT_LIMIT); | 202 | TX_STATUS_ENTRY(SHORT_LIMIT); |
203 | TX_STATUS_ENTRY(LONG_LIMIT); | 203 | TX_STATUS_ENTRY(LONG_LIMIT); |
@@ -487,7 +487,7 @@ static void _iwl3945_dbg_report_frame(struct iwl_priv *priv, | |||
487 | * but you can hack it to show more, if you'd like to. */ | 487 | * but you can hack it to show more, if you'd like to. */ |
488 | if (dataframe) | 488 | if (dataframe) |
489 | IWL_DEBUG_RX(priv, "%s: mhd=0x%04x, dst=0x%02x, " | 489 | IWL_DEBUG_RX(priv, "%s: mhd=0x%04x, dst=0x%02x, " |
490 | "len=%u, rssi=%d, chnl=%d, rate=%d, \n", | 490 | "len=%u, rssi=%d, chnl=%d, rate=%d,\n", |
491 | title, le16_to_cpu(fc), header->addr1[5], | 491 | title, le16_to_cpu(fc), header->addr1[5], |
492 | length, rssi, channel, rate); | 492 | length, rssi, channel, rate); |
493 | else { | 493 | else { |
@@ -549,7 +549,6 @@ static void iwl3945_pass_packet_to_mac80211(struct iwl_priv *priv, | |||
549 | struct iwl3945_rx_frame_end *rx_end = IWL_RX_END(pkt); | 549 | struct iwl3945_rx_frame_end *rx_end = IWL_RX_END(pkt); |
550 | u16 len = le16_to_cpu(rx_hdr->len); | 550 | u16 len = le16_to_cpu(rx_hdr->len); |
551 | struct sk_buff *skb; | 551 | struct sk_buff *skb; |
552 | int ret; | ||
553 | __le16 fc = hdr->frame_control; | 552 | __le16 fc = hdr->frame_control; |
554 | 553 | ||
555 | /* We received data from the HW, so stop the watchdog */ | 554 | /* We received data from the HW, so stop the watchdog */ |
@@ -566,9 +565,9 @@ static void iwl3945_pass_packet_to_mac80211(struct iwl_priv *priv, | |||
566 | return; | 565 | return; |
567 | } | 566 | } |
568 | 567 | ||
569 | skb = alloc_skb(IWL_LINK_HDR_MAX * 2, GFP_ATOMIC); | 568 | skb = dev_alloc_skb(128); |
570 | if (!skb) { | 569 | if (!skb) { |
571 | IWL_ERR(priv, "alloc_skb failed\n"); | 570 | IWL_ERR(priv, "dev_alloc_skb failed\n"); |
572 | return; | 571 | return; |
573 | } | 572 | } |
574 | 573 | ||
@@ -577,37 +576,13 @@ static void iwl3945_pass_packet_to_mac80211(struct iwl_priv *priv, | |||
577 | (struct ieee80211_hdr *)rxb_addr(rxb), | 576 | (struct ieee80211_hdr *)rxb_addr(rxb), |
578 | le32_to_cpu(rx_end->status), stats); | 577 | le32_to_cpu(rx_end->status), stats); |
579 | 578 | ||
580 | skb_reserve(skb, IWL_LINK_HDR_MAX); | ||
581 | skb_add_rx_frag(skb, 0, rxb->page, | 579 | skb_add_rx_frag(skb, 0, rxb->page, |
582 | (void *)rx_hdr->payload - (void *)pkt, len); | 580 | (void *)rx_hdr->payload - (void *)pkt, len); |
583 | 581 | ||
584 | /* mac80211 currently doesn't support paged SKB. Convert it to | ||
585 | * linear SKB for management frame and data frame requires | ||
586 | * software decryption or software defragementation. */ | ||
587 | if (ieee80211_is_mgmt(fc) || | ||
588 | ieee80211_has_protected(fc) || | ||
589 | ieee80211_has_morefrags(fc) || | ||
590 | le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG) | ||
591 | ret = skb_linearize(skb); | ||
592 | else | ||
593 | ret = __pskb_pull_tail(skb, min_t(u16, IWL_LINK_HDR_MAX, len)) ? | ||
594 | 0 : -ENOMEM; | ||
595 | |||
596 | if (ret) { | ||
597 | kfree_skb(skb); | ||
598 | goto out; | ||
599 | } | ||
600 | |||
601 | /* | ||
602 | * XXX: We cannot touch the page and its virtual memory (pkt) after | ||
603 | * here. It might have already been freed by the above skb change. | ||
604 | */ | ||
605 | |||
606 | iwl_update_stats(priv, false, fc, len); | 582 | iwl_update_stats(priv, false, fc, len); |
607 | memcpy(IEEE80211_SKB_RXCB(skb), stats, sizeof(*stats)); | 583 | memcpy(IEEE80211_SKB_RXCB(skb), stats, sizeof(*stats)); |
608 | 584 | ||
609 | ieee80211_rx(priv->hw, skb); | 585 | ieee80211_rx(priv->hw, skb); |
610 | out: | ||
611 | priv->alloc_rxb_page--; | 586 | priv->alloc_rxb_page--; |
612 | rxb->page = NULL; | 587 | rxb->page = NULL; |
613 | } | 588 | } |
@@ -623,9 +598,8 @@ static void iwl3945_rx_reply_rx(struct iwl_priv *priv, | |||
623 | struct iwl3945_rx_frame_stats *rx_stats = IWL_RX_STATS(pkt); | 598 | struct iwl3945_rx_frame_stats *rx_stats = IWL_RX_STATS(pkt); |
624 | struct iwl3945_rx_frame_hdr *rx_hdr = IWL_RX_HDR(pkt); | 599 | struct iwl3945_rx_frame_hdr *rx_hdr = IWL_RX_HDR(pkt); |
625 | struct iwl3945_rx_frame_end *rx_end = IWL_RX_END(pkt); | 600 | struct iwl3945_rx_frame_end *rx_end = IWL_RX_END(pkt); |
626 | int snr; | 601 | u16 rx_stats_sig_avg __maybe_unused = le16_to_cpu(rx_stats->sig_avg); |
627 | u16 rx_stats_sig_avg = le16_to_cpu(rx_stats->sig_avg); | 602 | u16 rx_stats_noise_diff __maybe_unused = le16_to_cpu(rx_stats->noise_diff); |
628 | u16 rx_stats_noise_diff = le16_to_cpu(rx_stats->noise_diff); | ||
629 | u8 network_packet; | 603 | u8 network_packet; |
630 | 604 | ||
631 | rx_status.flag = 0; | 605 | rx_status.flag = 0; |
@@ -663,43 +637,19 @@ static void iwl3945_rx_reply_rx(struct iwl_priv *priv, | |||
663 | /* Convert 3945's rssi indicator to dBm */ | 637 | /* Convert 3945's rssi indicator to dBm */ |
664 | rx_status.signal = rx_stats->rssi - IWL39_RSSI_OFFSET; | 638 | rx_status.signal = rx_stats->rssi - IWL39_RSSI_OFFSET; |
665 | 639 | ||
666 | /* Set default noise value to -127 */ | 640 | IWL_DEBUG_STATS(priv, "Rssi %d sig_avg %d noise_diff %d\n", |
667 | if (priv->last_rx_noise == 0) | 641 | rx_status.signal, rx_stats_sig_avg, |
668 | priv->last_rx_noise = IWL_NOISE_MEAS_NOT_AVAILABLE; | 642 | rx_stats_noise_diff); |
669 | |||
670 | /* 3945 provides noise info for OFDM frames only. | ||
671 | * sig_avg and noise_diff are measured by the 3945's digital signal | ||
672 | * processor (DSP), and indicate linear levels of signal level and | ||
673 | * distortion/noise within the packet preamble after | ||
674 | * automatic gain control (AGC). sig_avg should stay fairly | ||
675 | * constant if the radio's AGC is working well. | ||
676 | * Since these values are linear (not dB or dBm), linear | ||
677 | * signal-to-noise ratio (SNR) is (sig_avg / noise_diff). | ||
678 | * Convert linear SNR to dB SNR, then subtract that from rssi dBm | ||
679 | * to obtain noise level in dBm. | ||
680 | * Calculate rx_status.signal (quality indicator in %) based on SNR. */ | ||
681 | if (rx_stats_noise_diff) { | ||
682 | snr = rx_stats_sig_avg / rx_stats_noise_diff; | ||
683 | rx_status.noise = rx_status.signal - | ||
684 | iwl3945_calc_db_from_ratio(snr); | ||
685 | } else { | ||
686 | rx_status.noise = priv->last_rx_noise; | ||
687 | } | ||
688 | |||
689 | |||
690 | IWL_DEBUG_STATS(priv, "Rssi %d noise %d sig_avg %d noise_diff %d\n", | ||
691 | rx_status.signal, rx_status.noise, | ||
692 | rx_stats_sig_avg, rx_stats_noise_diff); | ||
693 | 643 | ||
694 | header = (struct ieee80211_hdr *)IWL_RX_DATA(pkt); | 644 | header = (struct ieee80211_hdr *)IWL_RX_DATA(pkt); |
695 | 645 | ||
696 | network_packet = iwl3945_is_network_packet(priv, header); | 646 | network_packet = iwl3945_is_network_packet(priv, header); |
697 | 647 | ||
698 | IWL_DEBUG_STATS_LIMIT(priv, "[%c] %d RSSI:%d Signal:%u, Noise:%u, Rate:%u\n", | 648 | IWL_DEBUG_STATS_LIMIT(priv, "[%c] %d RSSI:%d Signal:%u, Rate:%u\n", |
699 | network_packet ? '*' : ' ', | 649 | network_packet ? '*' : ' ', |
700 | le16_to_cpu(rx_hdr->channel), | 650 | le16_to_cpu(rx_hdr->channel), |
701 | rx_status.signal, rx_status.signal, | 651 | rx_status.signal, rx_status.signal, |
702 | rx_status.noise, rx_status.rate_idx); | 652 | rx_status.rate_idx); |
703 | 653 | ||
704 | /* Set "1" to report good data frames in groups of 100 */ | 654 | /* Set "1" to report good data frames in groups of 100 */ |
705 | iwl3945_dbg_report_frame(priv, pkt, header, 1); | 655 | iwl3945_dbg_report_frame(priv, pkt, header, 1); |
@@ -710,7 +660,6 @@ static void iwl3945_rx_reply_rx(struct iwl_priv *priv, | |||
710 | le32_to_cpu(rx_end->beacon_timestamp); | 660 | le32_to_cpu(rx_end->beacon_timestamp); |
711 | priv->_3945.last_tsf = le64_to_cpu(rx_end->timestamp); | 661 | priv->_3945.last_tsf = le64_to_cpu(rx_end->timestamp); |
712 | priv->_3945.last_rx_rssi = rx_status.signal; | 662 | priv->_3945.last_rx_rssi = rx_status.signal; |
713 | priv->last_rx_noise = rx_status.noise; | ||
714 | } | 663 | } |
715 | 664 | ||
716 | iwl3945_pass_packet_to_mac80211(priv, rxb, &rx_status); | 665 | iwl3945_pass_packet_to_mac80211(priv, rxb, &rx_status); |
@@ -1050,7 +999,7 @@ static void iwl3945_nic_config(struct iwl_priv *priv) | |||
1050 | IWL_DEBUG_INFO(priv, "HW Revision ID = 0x%X\n", rev_id); | 999 | IWL_DEBUG_INFO(priv, "HW Revision ID = 0x%X\n", rev_id); |
1051 | 1000 | ||
1052 | if (rev_id & PCI_CFG_REV_ID_BIT_RTP) | 1001 | if (rev_id & PCI_CFG_REV_ID_BIT_RTP) |
1053 | IWL_DEBUG_INFO(priv, "RTP type \n"); | 1002 | IWL_DEBUG_INFO(priv, "RTP type\n"); |
1054 | else if (rev_id & PCI_CFG_REV_ID_BIT_BASIC_SKU) { | 1003 | else if (rev_id & PCI_CFG_REV_ID_BIT_BASIC_SKU) { |
1055 | IWL_DEBUG_INFO(priv, "3945 RADIO-MB type\n"); | 1004 | IWL_DEBUG_INFO(priv, "3945 RADIO-MB type\n"); |
1056 | iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG, | 1005 | iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG, |
@@ -2822,6 +2771,7 @@ static struct iwl_cfg iwl3945_bg_cfg = { | |||
2822 | .broken_powersave = true, | 2771 | .broken_powersave = true, |
2823 | .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, | 2772 | .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, |
2824 | .monitor_recover_period = IWL_MONITORING_PERIOD, | 2773 | .monitor_recover_period = IWL_MONITORING_PERIOD, |
2774 | .max_event_log_size = 512, | ||
2825 | }; | 2775 | }; |
2826 | 2776 | ||
2827 | static struct iwl_cfg iwl3945_abg_cfg = { | 2777 | static struct iwl_cfg iwl3945_abg_cfg = { |
@@ -2841,6 +2791,7 @@ static struct iwl_cfg iwl3945_abg_cfg = { | |||
2841 | .broken_powersave = true, | 2791 | .broken_powersave = true, |
2842 | .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, | 2792 | .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, |
2843 | .monitor_recover_period = IWL_MONITORING_PERIOD, | 2793 | .monitor_recover_period = IWL_MONITORING_PERIOD, |
2794 | .max_event_log_size = 512, | ||
2844 | }; | 2795 | }; |
2845 | 2796 | ||
2846 | DEFINE_PCI_DEVICE_TABLE(iwl3945_hw_card_ids) = { | 2797 | DEFINE_PCI_DEVICE_TABLE(iwl3945_hw_card_ids) = { |