aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/iwl-4965.c
diff options
context:
space:
mode:
authorTomas Winkler <tomas.winkler@intel.com>2008-03-01 18:52:00 -0500
committerJohn W. Linville <linville@tuxdriver.com>2008-03-06 17:09:46 -0500
commit17744ff6ae7eafe33dac9772f2ef9ab5fb738db8 (patch)
treefff5b091d2d6ed8682893f66072c698aa7308218 /drivers/net/wireless/iwlwifi/iwl-4965.c
parent8211ef78d9023a8772e5acf6b7934598156b2fc8 (diff)
iwlwifi: Fix 52 rate report in rx status
This patch fixes reporting rate in RX packets in 52 band. The rate was updated from CCK rate index instead of OFDM rate 6M Most of the patch is collateral clean up Signed-off-by: Tomas Winkler <tomas.winkler@intel.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-4965.c')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965.c250
1 files changed, 217 insertions, 33 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c
index a9c30bcb65b8..8b9c419e094e 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965.c
+++ b/drivers/net/wireless/iwlwifi/iwl-4965.c
@@ -122,6 +122,35 @@ static u8 is_single_stream(struct iwl4965_priv *priv)
122 return 0; 122 return 0;
123} 123}
124 124
125int iwl4965_hwrate_to_plcp_idx(u32 rate_n_flags)
126{
127 int idx = 0;
128
129 /* 4965 HT rate format */
130 if (rate_n_flags & RATE_MCS_HT_MSK) {
131 idx = (rate_n_flags & 0xff);
132
133 if (idx >= IWL_RATE_MIMO_6M_PLCP)
134 idx = idx - IWL_RATE_MIMO_6M_PLCP;
135
136 idx += IWL_FIRST_OFDM_RATE;
137 /* skip 9M not supported in ht*/
138 if (idx >= IWL_RATE_9M_INDEX)
139 idx += 1;
140 if ((idx >= IWL_FIRST_OFDM_RATE) && (idx <= IWL_LAST_OFDM_RATE))
141 return idx;
142
143 /* 4965 legacy rate format, search for match in table */
144 } else {
145 for (idx = 0; idx < ARRAY_SIZE(iwl4965_rates); idx++)
146 if (iwl4965_rates[idx].plcp == (rate_n_flags & 0xFF))
147 return idx;
148 }
149
150 return -1;
151}
152
153
125/* 154/*
126 * Determine how many receiver/antenna chains to use. 155 * Determine how many receiver/antenna chains to use.
127 * More provides better reception via diversity. Fewer saves power. 156 * More provides better reception via diversity. Fewer saves power.
@@ -3523,6 +3552,160 @@ static void iwl4965_update_ps_mode(struct iwl4965_priv *priv, u16 ps_bit, u8 *ad
3523 } 3552 }
3524 } 3553 }
3525} 3554}
3555#ifdef CONFIG_IWL4965_DEBUG
3556
3557/**
3558 * iwl4965_dbg_report_frame - dump frame to syslog during debug sessions
3559 *
3560 * You may hack this function to show different aspects of received frames,
3561 * including selective frame dumps.
3562 * group100 parameter selects whether to show 1 out of 100 good frames.
3563 *
3564 * TODO: This was originally written for 3945, need to audit for
3565 * proper operation with 4965.
3566 */
3567static void iwl4965_dbg_report_frame(struct iwl4965_priv *priv,
3568 struct iwl4965_rx_packet *pkt,
3569 struct ieee80211_hdr *header, int group100)
3570{
3571 u32 to_us;
3572 u32 print_summary = 0;
3573 u32 print_dump = 0; /* set to 1 to dump all frames' contents */
3574 u32 hundred = 0;
3575 u32 dataframe = 0;
3576 u16 fc;
3577 u16 seq_ctl;
3578 u16 channel;
3579 u16 phy_flags;
3580 int rate_sym;
3581 u16 length;
3582 u16 status;
3583 u16 bcn_tmr;
3584 u32 tsf_low;
3585 u64 tsf;
3586 u8 rssi;
3587 u8 agc;
3588 u16 sig_avg;
3589 u16 noise_diff;
3590 struct iwl4965_rx_frame_stats *rx_stats = IWL_RX_STATS(pkt);
3591 struct iwl4965_rx_frame_hdr *rx_hdr = IWL_RX_HDR(pkt);
3592 struct iwl4965_rx_frame_end *rx_end = IWL_RX_END(pkt);
3593 u8 *data = IWL_RX_DATA(pkt);
3594
3595 if (likely(!(iwl4965_debug_level & IWL_DL_RX)))
3596 return;
3597
3598 /* MAC header */
3599 fc = le16_to_cpu(header->frame_control);
3600 seq_ctl = le16_to_cpu(header->seq_ctrl);
3601
3602 /* metadata */
3603 channel = le16_to_cpu(rx_hdr->channel);
3604 phy_flags = le16_to_cpu(rx_hdr->phy_flags);
3605 rate_sym = rx_hdr->rate;
3606 length = le16_to_cpu(rx_hdr->len);
3607
3608 /* end-of-frame status and timestamp */
3609 status = le32_to_cpu(rx_end->status);
3610 bcn_tmr = le32_to_cpu(rx_end->beacon_timestamp);
3611 tsf_low = le64_to_cpu(rx_end->timestamp) & 0x0ffffffff;
3612 tsf = le64_to_cpu(rx_end->timestamp);
3613
3614 /* signal statistics */
3615 rssi = rx_stats->rssi;
3616 agc = rx_stats->agc;
3617 sig_avg = le16_to_cpu(rx_stats->sig_avg);
3618 noise_diff = le16_to_cpu(rx_stats->noise_diff);
3619
3620 to_us = !compare_ether_addr(header->addr1, priv->mac_addr);
3621
3622 /* if data frame is to us and all is good,
3623 * (optionally) print summary for only 1 out of every 100 */
3624 if (to_us && (fc & ~IEEE80211_FCTL_PROTECTED) ==
3625 (IEEE80211_FCTL_FROMDS | IEEE80211_FTYPE_DATA)) {
3626 dataframe = 1;
3627 if (!group100)
3628 print_summary = 1; /* print each frame */
3629 else if (priv->framecnt_to_us < 100) {
3630 priv->framecnt_to_us++;
3631 print_summary = 0;
3632 } else {
3633 priv->framecnt_to_us = 0;
3634 print_summary = 1;
3635 hundred = 1;
3636 }
3637 } else {
3638 /* print summary for all other frames */
3639 print_summary = 1;
3640 }
3641
3642 if (print_summary) {
3643 char *title;
3644 int rate_idx;
3645 u32 bitrate;
3646
3647 if (hundred)
3648 title = "100Frames";
3649 else if (fc & IEEE80211_FCTL_RETRY)
3650 title = "Retry";
3651 else if (ieee80211_is_assoc_response(fc))
3652 title = "AscRsp";
3653 else if (ieee80211_is_reassoc_response(fc))
3654 title = "RasRsp";
3655 else if (ieee80211_is_probe_response(fc)) {
3656 title = "PrbRsp";
3657 print_dump = 1; /* dump frame contents */
3658 } else if (ieee80211_is_beacon(fc)) {
3659 title = "Beacon";
3660 print_dump = 1; /* dump frame contents */
3661 } else if (ieee80211_is_atim(fc))
3662 title = "ATIM";
3663 else if (ieee80211_is_auth(fc))
3664 title = "Auth";
3665 else if (ieee80211_is_deauth(fc))
3666 title = "DeAuth";
3667 else if (ieee80211_is_disassoc(fc))
3668 title = "DisAssoc";
3669 else
3670 title = "Frame";
3671
3672 rate_idx = iwl4965_hwrate_to_plcp_idx(rate_sym);
3673 if (unlikely(rate_idx == -1))
3674 bitrate = 0;
3675 else
3676 bitrate = iwl4965_rates[rate_idx].ieee / 2;
3677
3678 /* print frame summary.
3679 * MAC addresses show just the last byte (for brevity),
3680 * but you can hack it to show more, if you'd like to. */
3681 if (dataframe)
3682 IWL_DEBUG_RX("%s: mhd=0x%04x, dst=0x%02x, "
3683 "len=%u, rssi=%d, chnl=%d, rate=%u, \n",
3684 title, fc, header->addr1[5],
3685 length, rssi, channel, bitrate);
3686 else {
3687 /* src/dst addresses assume managed mode */
3688 IWL_DEBUG_RX("%s: 0x%04x, dst=0x%02x, "
3689 "src=0x%02x, rssi=%u, tim=%lu usec, "
3690 "phy=0x%02x, chnl=%d\n",
3691 title, fc, header->addr1[5],
3692 header->addr3[5], rssi,
3693 tsf_low - priv->scan_start_tsf,
3694 phy_flags, channel);
3695 }
3696 }
3697 if (print_dump)
3698 iwl4965_print_hex_dump(IWL_DL_RX, data, length);
3699}
3700#else
3701static inline void iwl4965_dbg_report_frame(struct iwl4965_priv *priv,
3702 struct iwl4965_rx_packet *pkt,
3703 struct ieee80211_hdr *header,
3704 int group100)
3705{
3706}
3707#endif
3708
3526 3709
3527#define IWL_DELAY_NEXT_SCAN_AFTER_ASSOC (HZ*6) 3710#define IWL_DELAY_NEXT_SCAN_AFTER_ASSOC (HZ*6)
3528 3711
@@ -3531,6 +3714,8 @@ static void iwl4965_update_ps_mode(struct iwl4965_priv *priv, u16 ps_bit, u8 *ad
3531static void iwl4965_rx_reply_rx(struct iwl4965_priv *priv, 3714static void iwl4965_rx_reply_rx(struct iwl4965_priv *priv,
3532 struct iwl4965_rx_mem_buffer *rxb) 3715 struct iwl4965_rx_mem_buffer *rxb)
3533{ 3716{
3717 struct ieee80211_hdr *header;
3718 struct ieee80211_rx_status rx_status;
3534 struct iwl4965_rx_packet *pkt = (void *)rxb->skb->data; 3719 struct iwl4965_rx_packet *pkt = (void *)rxb->skb->data;
3535 /* Use phy data (Rx signal strength, etc.) contained within 3720 /* Use phy data (Rx signal strength, etc.) contained within
3536 * this rx packet for legacy frames, 3721 * this rx packet for legacy frames,
@@ -3541,27 +3726,29 @@ static void iwl4965_rx_reply_rx(struct iwl4965_priv *priv,
3541 (struct iwl4965_rx_phy_res *)&priv->last_phy_res[1]; 3726 (struct iwl4965_rx_phy_res *)&priv->last_phy_res[1];
3542 __le32 *rx_end; 3727 __le32 *rx_end;
3543 unsigned int len = 0; 3728 unsigned int len = 0;
3544 struct ieee80211_hdr *header;
3545 u16 fc; 3729 u16 fc;
3546 struct ieee80211_rx_status stats = {
3547 .mactime = le64_to_cpu(rx_start->timestamp),
3548 .freq = ieee80211chan2mhz(le16_to_cpu(rx_start->channel)),
3549 .band =
3550 (rx_start->phy_flags & RX_RES_PHY_FLAGS_BAND_24_MSK) ?
3551 IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ,
3552 .antenna = 0,
3553 .rate_idx = iwl4965_rate_index_from_plcp(
3554 le32_to_cpu(rx_start->rate_n_flags)),
3555 .flag = 0,
3556 };
3557 u8 network_packet; 3730 u8 network_packet;
3558 3731
3732 rx_status.mactime = le64_to_cpu(rx_start->timestamp);
3733 rx_status.freq = ieee80211chan2mhz(le16_to_cpu(rx_start->channel));
3734 rx_status.band = (rx_start->phy_flags & RX_RES_PHY_FLAGS_BAND_24_MSK) ?
3735 IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ;
3736 rx_status.rate_idx = iwl4965_hwrate_to_plcp_idx(
3737 le32_to_cpu(rx_start->rate_n_flags));
3738
3739 if (rx_status.band == IEEE80211_BAND_5GHZ)
3740 rx_status.rate_idx -= IWL_FIRST_OFDM_RATE;
3741
3742 rx_status.antenna = 0;
3743 rx_status.flag = 0;
3744
3559 if ((unlikely(rx_start->cfg_phy_cnt > 20))) { 3745 if ((unlikely(rx_start->cfg_phy_cnt > 20))) {
3560 IWL_DEBUG_DROP 3746 IWL_DEBUG_DROP
3561 ("dsp size out of range [0,20]: " 3747 ("dsp size out of range [0,20]: "
3562 "%d/n", rx_start->cfg_phy_cnt); 3748 "%d/n", rx_start->cfg_phy_cnt);
3563 return; 3749 return;
3564 } 3750 }
3751
3565 if (!include_phy) { 3752 if (!include_phy) {
3566 if (priv->last_phy_res[0]) 3753 if (priv->last_phy_res[0])
3567 rx_start = (struct iwl4965_rx_phy_res *) 3754 rx_start = (struct iwl4965_rx_phy_res *)
@@ -3580,7 +3767,7 @@ static void iwl4965_rx_reply_rx(struct iwl4965_priv *priv,
3580 + rx_start->cfg_phy_cnt); 3767 + rx_start->cfg_phy_cnt);
3581 3768
3582 len = le16_to_cpu(rx_start->byte_count); 3769 len = le16_to_cpu(rx_start->byte_count);
3583 rx_end = (__le32 *) (pkt->u.raw + rx_start->cfg_phy_cnt + 3770 rx_end = (__le32 *)(pkt->u.raw + rx_start->cfg_phy_cnt +
3584 sizeof(struct iwl4965_rx_phy_res) + len); 3771 sizeof(struct iwl4965_rx_phy_res) + len);
3585 } else { 3772 } else {
3586 struct iwl4965_rx_mpdu_res_start *amsdu = 3773 struct iwl4965_rx_mpdu_res_start *amsdu =
@@ -3603,7 +3790,7 @@ static void iwl4965_rx_reply_rx(struct iwl4965_priv *priv,
3603 priv->ucode_beacon_time = le32_to_cpu(rx_start->beacon_time_stamp); 3790 priv->ucode_beacon_time = le32_to_cpu(rx_start->beacon_time_stamp);
3604 3791
3605 /* Find max signal strength (dBm) among 3 antenna/receiver chains */ 3792 /* Find max signal strength (dBm) among 3 antenna/receiver chains */
3606 stats.ssi = iwl4965_calc_rssi(rx_start); 3793 rx_status.ssi = iwl4965_calc_rssi(rx_start);
3607 3794
3608 /* Meaningful noise values are available only from beacon statistics, 3795 /* Meaningful noise values are available only from beacon statistics,
3609 * which are gathered only when associated, and indicate noise 3796 * which are gathered only when associated, and indicate noise
@@ -3611,32 +3798,29 @@ static void iwl4965_rx_reply_rx(struct iwl4965_priv *priv,
3611 * Ignore these noise values while scanning (other channels) */ 3798 * Ignore these noise values while scanning (other channels) */
3612 if (iwl4965_is_associated(priv) && 3799 if (iwl4965_is_associated(priv) &&
3613 !test_bit(STATUS_SCANNING, &priv->status)) { 3800 !test_bit(STATUS_SCANNING, &priv->status)) {
3614 stats.noise = priv->last_rx_noise; 3801 rx_status.noise = priv->last_rx_noise;
3615 stats.signal = iwl4965_calc_sig_qual(stats.ssi, stats.noise); 3802 rx_status.signal = iwl4965_calc_sig_qual(rx_status.ssi,
3803 rx_status.noise);
3616 } else { 3804 } else {
3617 stats.noise = IWL_NOISE_MEAS_NOT_AVAILABLE; 3805 rx_status.noise = IWL_NOISE_MEAS_NOT_AVAILABLE;
3618 stats.signal = iwl4965_calc_sig_qual(stats.ssi, 0); 3806 rx_status.signal = iwl4965_calc_sig_qual(rx_status.ssi, 0);
3619 } 3807 }
3620 3808
3621 /* Reset beacon noise level if not associated. */ 3809 /* Reset beacon noise level if not associated. */
3622 if (!iwl4965_is_associated(priv)) 3810 if (!iwl4965_is_associated(priv))
3623 priv->last_rx_noise = IWL_NOISE_MEAS_NOT_AVAILABLE; 3811 priv->last_rx_noise = IWL_NOISE_MEAS_NOT_AVAILABLE;
3624 3812
3625#ifdef CONFIG_IWL4965_DEBUG 3813 /* Set "1" to report good data frames in groups of 100 */
3626 /* TODO: Parts of iwl4965_report_frame are broken for 4965 */ 3814 /* FIXME: need to optimze the call: */
3627 if (iwl4965_debug_level & (IWL_DL_RX)) 3815 iwl4965_dbg_report_frame(priv, pkt, header, 1);
3628 /* Set "1" to report good data frames in groups of 100 */ 3816
3629 iwl4965_report_frame(priv, pkt, header, 1); 3817 IWL_DEBUG_STATS_LIMIT("Rssi %d, noise %d, qual %d, TSF %llu\n",
3630 3818 rx_status.ssi, rx_status.noise, rx_status.signal,
3631 if (iwl4965_debug_level & (IWL_DL_RX | IWL_DL_STATS)) 3819 rx_status.mactime);
3632 IWL_DEBUG_RX("Rssi %d, noise %d, qual %d, TSF %lu\n",
3633 stats.ssi, stats.noise, stats.signal,
3634 (long unsigned int)le64_to_cpu(rx_start->timestamp));
3635#endif
3636 3820
3637 network_packet = iwl4965_is_network_packet(priv, header); 3821 network_packet = iwl4965_is_network_packet(priv, header);
3638 if (network_packet) { 3822 if (network_packet) {
3639 priv->last_rx_rssi = stats.ssi; 3823 priv->last_rx_rssi = rx_status.ssi;
3640 priv->last_beacon_time = priv->ucode_beacon_time; 3824 priv->last_beacon_time = priv->ucode_beacon_time;
3641 priv->last_tsf = le64_to_cpu(rx_start->timestamp); 3825 priv->last_tsf = le64_to_cpu(rx_start->timestamp);
3642 } 3826 }
@@ -3739,7 +3923,7 @@ static void iwl4965_rx_reply_rx(struct iwl4965_priv *priv,
3739 return; 3923 return;
3740 } 3924 }
3741 } 3925 }
3742 iwl4965_handle_data_packet(priv, 0, include_phy, rxb, &stats); 3926 iwl4965_handle_data_packet(priv, 0, include_phy, rxb, &rx_status);
3743 break; 3927 break;
3744 3928
3745 case IEEE80211_FTYPE_CTL: 3929 case IEEE80211_FTYPE_CTL:
@@ -3748,7 +3932,7 @@ static void iwl4965_rx_reply_rx(struct iwl4965_priv *priv,
3748 case IEEE80211_STYPE_BACK_REQ: 3932 case IEEE80211_STYPE_BACK_REQ:
3749 IWL_DEBUG_HT("IEEE80211_STYPE_BACK_REQ arrived\n"); 3933 IWL_DEBUG_HT("IEEE80211_STYPE_BACK_REQ arrived\n");
3750 iwl4965_handle_data_packet(priv, 0, include_phy, 3934 iwl4965_handle_data_packet(priv, 0, include_phy,
3751 rxb, &stats); 3935 rxb, &rx_status);
3752 break; 3936 break;
3753 default: 3937 default:
3754 break; 3938 break;
@@ -3778,7 +3962,7 @@ static void iwl4965_rx_reply_rx(struct iwl4965_priv *priv,
3778 print_mac(mac3, header->addr3)); 3962 print_mac(mac3, header->addr3));
3779 else 3963 else
3780 iwl4965_handle_data_packet(priv, 1, include_phy, rxb, 3964 iwl4965_handle_data_packet(priv, 1, include_phy, rxb,
3781 &stats); 3965 &rx_status);
3782 break; 3966 break;
3783 } 3967 }
3784 default: 3968 default: