aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/iwl-3945.c
diff options
context:
space:
mode:
authorJohn W. Linville <linville@tuxdriver.com>2010-04-15 16:21:34 -0400
committerJohn W. Linville <linville@tuxdriver.com>2010-04-15 16:21:34 -0400
commit5c01d5669356e13f0fb468944c1dd4c6a7e978ad (patch)
treefa43345288d7b25fac92b3b35360a177c4947313 /drivers/net/wireless/iwlwifi/iwl-3945.c
parentfea069152614cdeefba4b2bf80afcddb9c217fc8 (diff)
parenta5e944f1d955f3819503348426763e21e0413ba6 (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.c79
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
197static const char *iwl3945_get_tx_fail_reason(u32 status) 197static 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
2827static struct iwl_cfg iwl3945_abg_cfg = { 2777static 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
2846DEFINE_PCI_DEVICE_TABLE(iwl3945_hw_card_ids) = { 2797DEFINE_PCI_DEVICE_TABLE(iwl3945_hw_card_ids) = {