aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBruno Randolf <br1@einfach.org>2008-05-08 13:15:40 -0400
committerJohn W. Linville <linville@tuxdriver.com>2008-05-14 16:29:49 -0400
commit566bfe5a8bcde13188a356f77666f8115813cf31 (patch)
tree785412c505e9efbd0fac477d71c8ca6945ffce04
parentfac371d9f09f461dfe9fbbceb2a38e2e12164dda (diff)
mac80211: use hardware flags for signal/noise units
trying to clean up the signal/noise code. the previous code in mac80211 had confusing names for the related variables, did not have much definition of what units of signal and noise were provided and used implicit mechanisms from the wireless extensions. this patch introduces hardware capability flags to let the hardware specify clearly if it can provide signal and noise level values and which units it can provide. this also anticipates possible new units like RCPI in the future. for signal: IEEE80211_HW_SIGNAL_UNSPEC - unspecified, unknown, hw specific IEEE80211_HW_SIGNAL_DB - dB difference to unspecified reference point IEEE80211_HW_SIGNAL_DBM - dBm, difference to 1mW for noise we currently only have dBm: IEEE80211_HW_NOISE_DBM - dBm, difference to 1mW if IEEE80211_HW_SIGNAL_UNSPEC or IEEE80211_HW_SIGNAL_DB is used the driver has to provide the maximum value (max_signal) it reports in order for applications to make sense of the signal values. i tried my best to find out for each driver what it can provide and update it but i'm not sure (?) for some of them and used the more conservative guess in doubt. this can be fixed easily after this patch has been merged by changing the hardware flags of the driver. DRIVER SIGNAL MAX NOISE QUAL ----------------------------------------------------------------- adm8211 unspec(?) 100 n/a missing at76_usb unspec(?) (?) unused missing ath5k dBm dBm percent rssi b43legacy dBm dBm percent jssi(?) b43 dBm dBm percent jssi(?) iwl-3945 dBm dBm percent snr+more iwl-4965 dBm dBm percent snr+more p54 unspec 127 n/a missing rt2x00 dBm n/a percent rssi+tx/rx frame success rt2400 dBm n/a rt2500pci dBm n/a rt2500usb dBm n/a rt61pci dBm n/a rt73usb dBm n/a rtl8180 unspec(?) 65 n/a (?) rtl8187 unspec(?) 65 (?) noise(?) zd1211 dB(?) 100 n/a percent drivers/net/wireless/ath5k/base.c: Changes-licensed-under: 3-Clause-BSD Signed-off-by: Bruno Randolf <br1@einfach.org> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r--drivers/net/wireless/adm8211.c7
-rw-r--r--drivers/net/wireless/ath5k/base.c23
-rw-r--r--drivers/net/wireless/b43/main.c8
-rw-r--r--drivers/net/wireless/b43/xmit.c5
-rw-r--r--drivers/net/wireless/b43legacy/main.c7
-rw-r--r--drivers/net/wireless/b43legacy/xmit.c4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945.c18
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965.c12
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.c16
-rw-r--r--drivers/net/wireless/iwlwifi/iwl3945-base.c15
-rw-r--r--drivers/net/wireless/p54/p54common.c7
-rw-r--r--drivers/net/wireless/rt2x00/rt2400pci.c5
-rw-r--r--drivers/net/wireless/rt2x00/rt2500pci.c6
-rw-r--r--drivers/net/wireless/rt2x00/rt2500usb.c6
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00dev.c4
-rw-r--r--drivers/net/wireless/rt2x00/rt61pci.c5
-rw-r--r--drivers/net/wireless/rt2x00/rt73usb.c5
-rw-r--r--drivers/net/wireless/rtl8180_dev.c9
-rw-r--r--drivers/net/wireless/rtl8187_dev.c10
-rw-r--r--drivers/net/wireless/zd1211rw/zd_mac.c12
-rw-r--r--include/net/mac80211.h47
-rw-r--r--net/ieee80211/ieee80211_rx.c2
-rw-r--r--net/mac80211/debugfs_sta.c2
-rw-r--r--net/mac80211/ieee80211_i.h2
-rw-r--r--net/mac80211/main.c10
-rw-r--r--net/mac80211/mlme.c12
-rw-r--r--net/mac80211/rx.c4
-rw-r--r--net/mac80211/sta_info.h2
-rw-r--r--net/mac80211/wext.c28
29 files changed, 148 insertions, 145 deletions
diff --git a/drivers/net/wireless/adm8211.c b/drivers/net/wireless/adm8211.c
index d93a1de77eb0..7af5d8851f67 100644
--- a/drivers/net/wireless/adm8211.c
+++ b/drivers/net/wireless/adm8211.c
@@ -445,9 +445,9 @@ static void adm8211_interrupt_rci(struct ieee80211_hw *dev)
445 struct ieee80211_rx_status rx_status = {0}; 445 struct ieee80211_rx_status rx_status = {0};
446 446
447 if (priv->pdev->revision < ADM8211_REV_CA) 447 if (priv->pdev->revision < ADM8211_REV_CA)
448 rx_status.ssi = rssi; 448 rx_status.signal = rssi;
449 else 449 else
450 rx_status.ssi = 100 - rssi; 450 rx_status.signal = 100 - rssi;
451 451
452 rx_status.rate_idx = rate; 452 rx_status.rate_idx = rate;
453 453
@@ -1893,9 +1893,10 @@ static int __devinit adm8211_probe(struct pci_dev *pdev,
1893 1893
1894 dev->extra_tx_headroom = sizeof(struct adm8211_tx_hdr); 1894 dev->extra_tx_headroom = sizeof(struct adm8211_tx_hdr);
1895 /* dev->flags = IEEE80211_HW_RX_INCLUDES_FCS in promisc mode */ 1895 /* dev->flags = IEEE80211_HW_RX_INCLUDES_FCS in promisc mode */
1896 dev->flags = IEEE80211_HW_SIGNAL_UNSPEC;
1896 1897
1897 dev->channel_change_time = 1000; 1898 dev->channel_change_time = 1000;
1898 dev->max_rssi = 100; /* FIXME: find better value */ 1899 dev->max_signal = 100; /* FIXME: find better value */
1899 1900
1900 dev->queues = 1; /* ADM8211C supports more, maybe ADM8211B too */ 1901 dev->queues = 1; /* ADM8211C supports more, maybe ADM8211B too */
1901 1902
diff --git a/drivers/net/wireless/ath5k/base.c b/drivers/net/wireless/ath5k/base.c
index 3201c1604340..dd8adaddd7a0 100644
--- a/drivers/net/wireless/ath5k/base.c
+++ b/drivers/net/wireless/ath5k/base.c
@@ -458,13 +458,11 @@ ath5k_pci_probe(struct pci_dev *pdev,
458 458
459 /* Initialize driver private data */ 459 /* Initialize driver private data */
460 SET_IEEE80211_DEV(hw, &pdev->dev); 460 SET_IEEE80211_DEV(hw, &pdev->dev);
461 hw->flags = IEEE80211_HW_RX_INCLUDES_FCS; 461 hw->flags = IEEE80211_HW_RX_INCLUDES_FCS |
462 IEEE80211_HW_SIGNAL_DBM |
463 IEEE80211_HW_NOISE_DBM;
462 hw->extra_tx_headroom = 2; 464 hw->extra_tx_headroom = 2;
463 hw->channel_change_time = 5000; 465 hw->channel_change_time = 5000;
464 /* these names are misleading */
465 hw->max_rssi = -110; /* signal in dBm */
466 hw->max_noise = -110; /* noise in dBm */
467 hw->max_signal = 100; /* we will provide a percentage based on rssi */
468 sc = hw->priv; 466 sc = hw->priv;
469 sc->hw = hw; 467 sc->hw = hw;
470 sc->pdev = pdev; 468 sc->pdev = pdev;
@@ -1893,20 +1891,9 @@ accept:
1893 rxs.freq = sc->curchan->center_freq; 1891 rxs.freq = sc->curchan->center_freq;
1894 rxs.band = sc->curband->band; 1892 rxs.band = sc->curband->band;
1895 1893
1896 /*
1897 * signal quality:
1898 * the names here are misleading and the usage of these
1899 * values by iwconfig makes it even worse
1900 */
1901 /* noise floor in dBm, from the last noise calibration */
1902 rxs.noise = sc->ah->ah_noise_floor; 1894 rxs.noise = sc->ah->ah_noise_floor;
1903 /* signal level in dBm */ 1895 rxs.signal = rxs.noise + rs.rs_rssi;
1904 rxs.ssi = rxs.noise + rs.rs_rssi; 1896 rxs.qual = rs.rs_rssi * 100 / 64;
1905 /*
1906 * "signal" is actually displayed as Link Quality by iwconfig
1907 * we provide a percentage based on rssi (assuming max rssi 64)
1908 */
1909 rxs.signal = rs.rs_rssi * 100 / 64;
1910 1897
1911 rxs.antenna = rs.rs_antenna; 1898 rxs.antenna = rs.rs_antenna;
1912 rxs.rate_idx = ath5k_hw_to_driver_rix(sc, rs.rs_rate); 1899 rxs.rate_idx = ath5k_hw_to_driver_rix(sc, rs.rs_rate);
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
index 7c23aa8705c2..fc23ba5309bd 100644
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -4466,10 +4466,10 @@ static int b43_wireless_init(struct ssb_device *dev)
4466 4466
4467 /* fill hw info */ 4467 /* fill hw info */
4468 hw->flags = IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE | 4468 hw->flags = IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE |
4469 IEEE80211_HW_RX_INCLUDES_FCS; 4469 IEEE80211_HW_RX_INCLUDES_FCS |
4470 hw->max_signal = 100; 4470 IEEE80211_HW_SIGNAL_DBM |
4471 hw->max_rssi = -110; 4471 IEEE80211_HW_NOISE_DBM;
4472 hw->max_noise = -110; 4472
4473 hw->queues = b43_modparam_qos ? 4 : 1; 4473 hw->queues = b43_modparam_qos ? 4 : 1;
4474 SET_IEEE80211_DEV(hw, dev->dev); 4474 SET_IEEE80211_DEV(hw, dev->dev);
4475 if (is_valid_ether_addr(sprom->et1mac)) 4475 if (is_valid_ether_addr(sprom->et1mac))
diff --git a/drivers/net/wireless/b43/xmit.c b/drivers/net/wireless/b43/xmit.c
index 88491947a209..afce9338d83a 100644
--- a/drivers/net/wireless/b43/xmit.c
+++ b/drivers/net/wireless/b43/xmit.c
@@ -581,12 +581,11 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr)
581 // and also find out what the maximum possible value is. 581 // and also find out what the maximum possible value is.
582 // Fill status.ssi and status.signal fields. 582 // Fill status.ssi and status.signal fields.
583 } else { 583 } else {
584 status.ssi = b43_rssi_postprocess(dev, rxhdr->jssi, 584 status.signal = b43_rssi_postprocess(dev, rxhdr->jssi,
585 (phystat0 & B43_RX_PHYST0_OFDM), 585 (phystat0 & B43_RX_PHYST0_OFDM),
586 (phystat0 & B43_RX_PHYST0_GAINCTL), 586 (phystat0 & B43_RX_PHYST0_GAINCTL),
587 (phystat3 & B43_RX_PHYST3_TRSTATE)); 587 (phystat3 & B43_RX_PHYST3_TRSTATE));
588 /* the next line looks wrong, but is what mac80211 wants */ 588 status.qual = (rxhdr->jssi * 100) / B43_RX_MAX_SSI;
589 status.signal = (rxhdr->jssi * 100) / B43_RX_MAX_SSI;
590 } 589 }
591 590
592 if (phystat0 & B43_RX_PHYST0_OFDM) 591 if (phystat0 & B43_RX_PHYST0_OFDM)
diff --git a/drivers/net/wireless/b43legacy/main.c b/drivers/net/wireless/b43legacy/main.c
index d3820dce3c43..7755c59e0803 100644
--- a/drivers/net/wireless/b43legacy/main.c
+++ b/drivers/net/wireless/b43legacy/main.c
@@ -3718,10 +3718,9 @@ static int b43legacy_wireless_init(struct ssb_device *dev)
3718 3718
3719 /* fill hw info */ 3719 /* fill hw info */
3720 hw->flags = IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE | 3720 hw->flags = IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE |
3721 IEEE80211_HW_RX_INCLUDES_FCS; 3721 IEEE80211_HW_RX_INCLUDES_FCS |
3722 hw->max_signal = 100; 3722 IEEE80211_HW_SIGNAL_DBM |
3723 hw->max_rssi = -110; 3723 IEEE80211_HW_NOISE_DBM;
3724 hw->max_noise = -110;
3725 hw->queues = 1; /* FIXME: hardware has more queues */ 3724 hw->queues = 1; /* FIXME: hardware has more queues */
3726 SET_IEEE80211_DEV(hw, dev->dev); 3725 SET_IEEE80211_DEV(hw, dev->dev);
3727 if (is_valid_ether_addr(sprom->et1mac)) 3726 if (is_valid_ether_addr(sprom->et1mac))
diff --git a/drivers/net/wireless/b43legacy/xmit.c b/drivers/net/wireless/b43legacy/xmit.c
index fc83dab6e2c7..bed9e041d6c5 100644
--- a/drivers/net/wireless/b43legacy/xmit.c
+++ b/drivers/net/wireless/b43legacy/xmit.c
@@ -532,12 +532,12 @@ void b43legacy_rx(struct b43legacy_wldev *dev,
532 } 532 }
533 } 533 }
534 534
535 status.ssi = b43legacy_rssi_postprocess(dev, jssi, 535 status.signal = b43legacy_rssi_postprocess(dev, jssi,
536 (phystat0 & B43legacy_RX_PHYST0_OFDM), 536 (phystat0 & B43legacy_RX_PHYST0_OFDM),
537 (phystat0 & B43legacy_RX_PHYST0_GAINCTL), 537 (phystat0 & B43legacy_RX_PHYST0_GAINCTL),
538 (phystat3 & B43legacy_RX_PHYST3_TRSTATE)); 538 (phystat3 & B43legacy_RX_PHYST3_TRSTATE));
539 status.noise = dev->stats.link_noise; 539 status.noise = dev->stats.link_noise;
540 status.signal = (jssi * 100) / B43legacy_RX_MAX_SSI; 540 status.qual = (jssi * 100) / B43legacy_RX_MAX_SSI;
541 /* change to support A PHY */ 541 /* change to support A PHY */
542 if (phystat0 & B43legacy_RX_PHYST0_OFDM) 542 if (phystat0 & B43legacy_RX_PHYST0_OFDM)
543 status.rate_idx = b43legacy_plcp_get_bitrate_idx_ofdm(plcp, false); 543 status.rate_idx = b43legacy_plcp_get_bitrate_idx_ofdm(plcp, false);
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c
index 8464397f7816..d7beeff2642c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.c
@@ -520,7 +520,7 @@ static void iwl3945_add_radiotap(struct iwl3945_priv *priv,
520{ 520{
521 /* First cache any information we need before we overwrite 521 /* First cache any information we need before we overwrite
522 * the information provided in the skb from the hardware */ 522 * the information provided in the skb from the hardware */
523 s8 signal = stats->ssi; 523 s8 signal = stats->signal;
524 s8 noise = 0; 524 s8 noise = 0;
525 int rate = stats->rate_idx; 525 int rate = stats->rate_idx;
526 u64 tsf = stats->mactime; 526 u64 tsf = stats->mactime;
@@ -693,7 +693,7 @@ static void iwl3945_rx_reply_rx(struct iwl3945_priv *priv,
693 } 693 }
694 694
695 /* Convert 3945's rssi indicator to dBm */ 695 /* Convert 3945's rssi indicator to dBm */
696 rx_status.ssi = rx_stats->rssi - IWL_RSSI_OFFSET; 696 rx_status.signal = rx_stats->rssi - IWL_RSSI_OFFSET;
697 697
698 /* Set default noise value to -127 */ 698 /* Set default noise value to -127 */
699 if (priv->last_rx_noise == 0) 699 if (priv->last_rx_noise == 0)
@@ -712,21 +712,21 @@ static void iwl3945_rx_reply_rx(struct iwl3945_priv *priv,
712 * Calculate rx_status.signal (quality indicator in %) based on SNR. */ 712 * Calculate rx_status.signal (quality indicator in %) based on SNR. */
713 if (rx_stats_noise_diff) { 713 if (rx_stats_noise_diff) {
714 snr = rx_stats_sig_avg / rx_stats_noise_diff; 714 snr = rx_stats_sig_avg / rx_stats_noise_diff;
715 rx_status.noise = rx_status.ssi - 715 rx_status.noise = rx_status.signal -
716 iwl3945_calc_db_from_ratio(snr); 716 iwl3945_calc_db_from_ratio(snr);
717 rx_status.signal = iwl3945_calc_sig_qual(rx_status.ssi, 717 rx_status.qual = iwl3945_calc_sig_qual(rx_status.signal,
718 rx_status.noise); 718 rx_status.noise);
719 719
720 /* If noise info not available, calculate signal quality indicator (%) 720 /* If noise info not available, calculate signal quality indicator (%)
721 * using just the dBm signal level. */ 721 * using just the dBm signal level. */
722 } else { 722 } else {
723 rx_status.noise = priv->last_rx_noise; 723 rx_status.noise = priv->last_rx_noise;
724 rx_status.signal = iwl3945_calc_sig_qual(rx_status.ssi, 0); 724 rx_status.qual = iwl3945_calc_sig_qual(rx_status.signal, 0);
725 } 725 }
726 726
727 727
728 IWL_DEBUG_STATS("Rssi %d noise %d qual %d sig_avg %d noise_diff %d\n", 728 IWL_DEBUG_STATS("Rssi %d noise %d qual %d sig_avg %d noise_diff %d\n",
729 rx_status.ssi, rx_status.noise, rx_status.signal, 729 rx_status.signal, rx_status.noise, rx_status.qual,
730 rx_stats_sig_avg, rx_stats_noise_diff); 730 rx_stats_sig_avg, rx_stats_noise_diff);
731 731
732 header = (struct ieee80211_hdr *)IWL_RX_DATA(pkt); 732 header = (struct ieee80211_hdr *)IWL_RX_DATA(pkt);
@@ -736,8 +736,8 @@ static void iwl3945_rx_reply_rx(struct iwl3945_priv *priv,
736 IWL_DEBUG_STATS_LIMIT("[%c] %d RSSI:%d Signal:%u, Noise:%u, Rate:%u\n", 736 IWL_DEBUG_STATS_LIMIT("[%c] %d RSSI:%d Signal:%u, Noise:%u, Rate:%u\n",
737 network_packet ? '*' : ' ', 737 network_packet ? '*' : ' ',
738 le16_to_cpu(rx_hdr->channel), 738 le16_to_cpu(rx_hdr->channel),
739 rx_status.ssi, rx_status.ssi, 739 rx_status.signal, rx_status.signal,
740 rx_status.ssi, rx_status.rate_idx); 740 rx_status.noise, rx_status.rate_idx);
741 741
742#ifdef CONFIG_IWL3945_DEBUG 742#ifdef CONFIG_IWL3945_DEBUG
743 if (iwl3945_debug_level & (IWL_DL_RX)) 743 if (iwl3945_debug_level & (IWL_DL_RX))
@@ -748,7 +748,7 @@ static void iwl3945_rx_reply_rx(struct iwl3945_priv *priv,
748 if (network_packet) { 748 if (network_packet) {
749 priv->last_beacon_time = le32_to_cpu(rx_end->beacon_timestamp); 749 priv->last_beacon_time = le32_to_cpu(rx_end->beacon_timestamp);
750 priv->last_tsf = le64_to_cpu(rx_end->timestamp); 750 priv->last_tsf = le64_to_cpu(rx_end->timestamp);
751 priv->last_rx_rssi = rx_status.ssi; 751 priv->last_rx_rssi = rx_status.signal;
752 priv->last_rx_noise = rx_status.noise; 752 priv->last_rx_noise = rx_status.noise;
753 } 753 }
754 754
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c
index b7036e011457..45cbd7789bd0 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965.c
+++ b/drivers/net/wireless/iwlwifi/iwl-4965.c
@@ -2362,7 +2362,7 @@ static void iwl4965_add_radiotap(struct iwl_priv *priv,
2362 struct ieee80211_rx_status *stats, 2362 struct ieee80211_rx_status *stats,
2363 u32 ampdu_status) 2363 u32 ampdu_status)
2364{ 2364{
2365 s8 signal = stats->ssi; 2365 s8 signal = stats->signal;
2366 s8 noise = 0; 2366 s8 noise = 0;
2367 int rate = stats->rate_idx; 2367 int rate = stats->rate_idx;
2368 u64 tsf = stats->mactime; 2368 u64 tsf = stats->mactime;
@@ -2963,7 +2963,7 @@ static void iwl4965_rx_reply_rx(struct iwl_priv *priv,
2963 priv->ucode_beacon_time = le32_to_cpu(rx_start->beacon_time_stamp); 2963 priv->ucode_beacon_time = le32_to_cpu(rx_start->beacon_time_stamp);
2964 2964
2965 /* Find max signal strength (dBm) among 3 antenna/receiver chains */ 2965 /* Find max signal strength (dBm) among 3 antenna/receiver chains */
2966 rx_status.ssi = iwl4965_calc_rssi(priv, rx_start); 2966 rx_status.signal = iwl4965_calc_rssi(priv, rx_start);
2967 2967
2968 /* Meaningful noise values are available only from beacon statistics, 2968 /* Meaningful noise values are available only from beacon statistics,
2969 * which are gathered only when associated, and indicate noise 2969 * which are gathered only when associated, and indicate noise
@@ -2972,11 +2972,11 @@ static void iwl4965_rx_reply_rx(struct iwl_priv *priv,
2972 if (iwl_is_associated(priv) && 2972 if (iwl_is_associated(priv) &&
2973 !test_bit(STATUS_SCANNING, &priv->status)) { 2973 !test_bit(STATUS_SCANNING, &priv->status)) {
2974 rx_status.noise = priv->last_rx_noise; 2974 rx_status.noise = priv->last_rx_noise;
2975 rx_status.signal = iwl4965_calc_sig_qual(rx_status.ssi, 2975 rx_status.qual = iwl4965_calc_sig_qual(rx_status.signal,
2976 rx_status.noise); 2976 rx_status.noise);
2977 } else { 2977 } else {
2978 rx_status.noise = IWL_NOISE_MEAS_NOT_AVAILABLE; 2978 rx_status.noise = IWL_NOISE_MEAS_NOT_AVAILABLE;
2979 rx_status.signal = iwl4965_calc_sig_qual(rx_status.ssi, 0); 2979 rx_status.qual = iwl4965_calc_sig_qual(rx_status.signal, 0);
2980 } 2980 }
2981 2981
2982 /* Reset beacon noise level if not associated. */ 2982 /* Reset beacon noise level if not associated. */
@@ -2988,7 +2988,7 @@ static void iwl4965_rx_reply_rx(struct iwl_priv *priv,
2988 iwl4965_dbg_report_frame(priv, pkt, header, 1); 2988 iwl4965_dbg_report_frame(priv, pkt, header, 1);
2989 2989
2990 IWL_DEBUG_STATS_LIMIT("Rssi %d, noise %d, qual %d, TSF %llu\n", 2990 IWL_DEBUG_STATS_LIMIT("Rssi %d, noise %d, qual %d, TSF %llu\n",
2991 rx_status.ssi, rx_status.noise, rx_status.signal, 2991 rx_status.signal, rx_status.noise, rx_status.signal,
2992 (unsigned long long)rx_status.mactime); 2992 (unsigned long long)rx_status.mactime);
2993 2993
2994 2994
@@ -3000,7 +3000,7 @@ static void iwl4965_rx_reply_rx(struct iwl_priv *priv,
3000 3000
3001 network_packet = iwl4965_is_network_packet(priv, header); 3001 network_packet = iwl4965_is_network_packet(priv, header);
3002 if (network_packet) { 3002 if (network_packet) {
3003 priv->last_rx_rssi = rx_status.ssi; 3003 priv->last_rx_rssi = rx_status.signal;
3004 priv->last_beacon_time = priv->ucode_beacon_time; 3004 priv->last_beacon_time = priv->ucode_beacon_time;
3005 priv->last_tsf = le64_to_cpu(rx_start->timestamp); 3005 priv->last_tsf = le64_to_cpu(rx_start->timestamp);
3006 } 3006 }
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index 27e56b89d940..d3cbad2bf877 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -746,18 +746,10 @@ static void iwlcore_init_hw(struct iwl_priv *priv)
746 struct ieee80211_hw *hw = priv->hw; 746 struct ieee80211_hw *hw = priv->hw;
747 hw->rate_control_algorithm = "iwl-4965-rs"; 747 hw->rate_control_algorithm = "iwl-4965-rs";
748 748
749 /* Tell mac80211 and its clients (e.g. Wireless Extensions) 749 /* Tell mac80211 our characteristics */
750 * the range of signal quality values that we'll provide. 750 hw->flags = IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE |
751 * Negative values for level/noise indicate that we'll provide dBm. 751 IEEE80211_HW_SIGNAL_DBM |
752 * For WE, at least, non-0 values here *enable* display of values 752 IEEE80211_HW_NOISE_DBM;
753 * in app (iwconfig). */
754 hw->max_rssi = -20; /* signal level, negative indicates dBm */
755 hw->max_noise = -20; /* noise level, negative indicates dBm */
756 hw->max_signal = 100; /* link quality indication (%) */
757
758 /* Tell mac80211 our Tx characteristics */
759 hw->flags = IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE;
760
761 /* Default value; 4 EDCA QOS priorities */ 753 /* Default value; 4 EDCA QOS priorities */
762 hw->queues = 4; 754 hw->queues = 4;
763#ifdef CONFIG_IWL4965_HT 755#ifdef CONFIG_IWL4965_HT
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index 4baa185ba500..c1234ff4fc98 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -8029,17 +8029,10 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
8029 8029
8030 priv->ibss_beacon = NULL; 8030 priv->ibss_beacon = NULL;
8031 8031
8032 /* Tell mac80211 and its clients (e.g. Wireless Extensions) 8032 /* Tell mac80211 our characteristics */
8033 * the range of signal quality values that we'll provide. 8033 hw->flags = IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE |
8034 * Negative values for level/noise indicate that we'll provide dBm. 8034 IEEE80211_HW_SIGNAL_DBM |
8035 * For WE, at least, non-0 values here *enable* display of values 8035 IEEE80211_HW_NOISE_DBM;
8036 * in app (iwconfig). */
8037 hw->max_rssi = -20; /* signal level, negative indicates dBm */
8038 hw->max_noise = -20; /* noise level, negative indicates dBm */
8039 hw->max_signal = 100; /* link quality indication (%) */
8040
8041 /* Tell mac80211 our Tx characteristics */
8042 hw->flags = IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE;
8043 8036
8044 /* 4 EDCA QOS priorities */ 8037 /* 4 EDCA QOS priorities */
8045 hw->queues = 4; 8038 hw->queues = 4;
diff --git a/drivers/net/wireless/p54/p54common.c b/drivers/net/wireless/p54/p54common.c
index 33d608a60d79..9cbef5bce0f6 100644
--- a/drivers/net/wireless/p54/p54common.c
+++ b/drivers/net/wireless/p54/p54common.c
@@ -355,7 +355,7 @@ static void p54_rx_data(struct ieee80211_hw *dev, struct sk_buff *skb)
355 struct ieee80211_rx_status rx_status = {0}; 355 struct ieee80211_rx_status rx_status = {0};
356 u16 freq = le16_to_cpu(hdr->freq); 356 u16 freq = le16_to_cpu(hdr->freq);
357 357
358 rx_status.ssi = hdr->rssi; 358 rx_status.signal = hdr->rssi;
359 /* XX correct? */ 359 /* XX correct? */
360 rx_status.rate_idx = hdr->rate & 0xf; 360 rx_status.rate_idx = hdr->rate & 0xf;
361 rx_status.freq = freq; 361 rx_status.freq = freq;
@@ -1000,9 +1000,10 @@ struct ieee80211_hw *p54_init_common(size_t priv_data_len)
1000 skb_queue_head_init(&priv->tx_queue); 1000 skb_queue_head_init(&priv->tx_queue);
1001 dev->wiphy->bands[IEEE80211_BAND_2GHZ] = &band_2GHz; 1001 dev->wiphy->bands[IEEE80211_BAND_2GHZ] = &band_2GHz;
1002 dev->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | /* not sure */ 1002 dev->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | /* not sure */
1003 IEEE80211_HW_RX_INCLUDES_FCS; 1003 IEEE80211_HW_RX_INCLUDES_FCS |
1004 IEEE80211_HW_SIGNAL_UNSPEC;
1004 dev->channel_change_time = 1000; /* TODO: find actual value */ 1005 dev->channel_change_time = 1000; /* TODO: find actual value */
1005 dev->max_rssi = 127; 1006 dev->max_signal = 127;
1006 1007
1007 priv->tx_stats[0].limit = 5; 1008 priv->tx_stats[0].limit = 5;
1008 dev->queues = 1; 1009 dev->queues = 1;
diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c
index 247fbbfb0f2b..afa565c63621 100644
--- a/drivers/net/wireless/rt2x00/rt2400pci.c
+++ b/drivers/net/wireless/rt2x00/rt2400pci.c
@@ -1361,10 +1361,9 @@ static void rt2400pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
1361 /* 1361 /*
1362 * Initialize all hw fields. 1362 * Initialize all hw fields.
1363 */ 1363 */
1364 rt2x00dev->hw->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING; 1364 rt2x00dev->hw->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
1365 IEEE80211_HW_SIGNAL_DBM;
1365 rt2x00dev->hw->extra_tx_headroom = 0; 1366 rt2x00dev->hw->extra_tx_headroom = 0;
1366 rt2x00dev->hw->max_signal = MAX_SIGNAL;
1367 rt2x00dev->hw->max_rssi = MAX_RX_SSI;
1368 rt2x00dev->hw->queues = 2; 1367 rt2x00dev->hw->queues = 2;
1369 1368
1370 SET_IEEE80211_DEV(rt2x00dev->hw, &rt2x00dev_pci(rt2x00dev)->dev); 1369 SET_IEEE80211_DEV(rt2x00dev->hw, &rt2x00dev_pci(rt2x00dev)->dev);
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c
index 0d53c75d55dd..c06f1b5e5887 100644
--- a/drivers/net/wireless/rt2x00/rt2500pci.c
+++ b/drivers/net/wireless/rt2x00/rt2500pci.c
@@ -1680,10 +1680,10 @@ static void rt2500pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
1680 /* 1680 /*
1681 * Initialize all hw fields. 1681 * Initialize all hw fields.
1682 */ 1682 */
1683 rt2x00dev->hw->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING; 1683 rt2x00dev->hw->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
1684 IEEE80211_HW_SIGNAL_DBM;
1685
1684 rt2x00dev->hw->extra_tx_headroom = 0; 1686 rt2x00dev->hw->extra_tx_headroom = 0;
1685 rt2x00dev->hw->max_signal = MAX_SIGNAL;
1686 rt2x00dev->hw->max_rssi = MAX_RX_SSI;
1687 rt2x00dev->hw->queues = 2; 1687 rt2x00dev->hw->queues = 2;
1688 1688
1689 SET_IEEE80211_DEV(rt2x00dev->hw, &rt2x00dev_pci(rt2x00dev)->dev); 1689 SET_IEEE80211_DEV(rt2x00dev->hw, &rt2x00dev_pci(rt2x00dev)->dev);
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c
index 80b34d47114a..88bafdf8f0fa 100644
--- a/drivers/net/wireless/rt2x00/rt2500usb.c
+++ b/drivers/net/wireless/rt2x00/rt2500usb.c
@@ -1587,10 +1587,10 @@ static void rt2500usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
1587 rt2x00dev->hw->flags = 1587 rt2x00dev->hw->flags =
1588 IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE | 1588 IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE |
1589 IEEE80211_HW_RX_INCLUDES_FCS | 1589 IEEE80211_HW_RX_INCLUDES_FCS |
1590 IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING; 1590 IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
1591 IEEE80211_HW_SIGNAL_DBM;
1592
1591 rt2x00dev->hw->extra_tx_headroom = TXD_DESC_SIZE; 1593 rt2x00dev->hw->extra_tx_headroom = TXD_DESC_SIZE;
1592 rt2x00dev->hw->max_signal = MAX_SIGNAL;
1593 rt2x00dev->hw->max_rssi = MAX_RX_SSI;
1594 rt2x00dev->hw->queues = 2; 1594 rt2x00dev->hw->queues = 2;
1595 1595
1596 SET_IEEE80211_DEV(rt2x00dev->hw, &rt2x00dev_usb(rt2x00dev)->dev); 1596 SET_IEEE80211_DEV(rt2x00dev->hw, &rt2x00dev_usb(rt2x00dev)->dev);
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c
index 9929b15e28ba..f51a50b31e16 100644
--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
@@ -600,9 +600,9 @@ void rt2x00lib_rxdone(struct queue_entry *entry,
600 rt2x00dev->link.qual.rx_success++; 600 rt2x00dev->link.qual.rx_success++;
601 601
602 rx_status->rate_idx = idx; 602 rx_status->rate_idx = idx;
603 rx_status->signal = 603 rx_status->qual =
604 rt2x00lib_calculate_link_signal(rt2x00dev, rxdesc->rssi); 604 rt2x00lib_calculate_link_signal(rt2x00dev, rxdesc->rssi);
605 rx_status->ssi = rxdesc->rssi; 605 rx_status->signal = rxdesc->rssi;
606 rx_status->flag = rxdesc->flags; 606 rx_status->flag = rxdesc->flags;
607 rx_status->antenna = rt2x00dev->link.ant.active.rx; 607 rx_status->antenna = rt2x00dev->link.ant.active.rx;
608 608
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c
index 98af4d26583d..eaf23b908772 100644
--- a/drivers/net/wireless/rt2x00/rt61pci.c
+++ b/drivers/net/wireless/rt2x00/rt61pci.c
@@ -2245,10 +2245,9 @@ static void rt61pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
2245 */ 2245 */
2246 rt2x00dev->hw->flags = 2246 rt2x00dev->hw->flags =
2247 IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE | 2247 IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE |
2248 IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING; 2248 IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
2249 IEEE80211_HW_SIGNAL_DBM;
2249 rt2x00dev->hw->extra_tx_headroom = 0; 2250 rt2x00dev->hw->extra_tx_headroom = 0;
2250 rt2x00dev->hw->max_signal = MAX_SIGNAL;
2251 rt2x00dev->hw->max_rssi = MAX_RX_SSI;
2252 rt2x00dev->hw->queues = 4; 2251 rt2x00dev->hw->queues = 4;
2253 2252
2254 SET_IEEE80211_DEV(rt2x00dev->hw, &rt2x00dev_pci(rt2x00dev)->dev); 2253 SET_IEEE80211_DEV(rt2x00dev->hw, &rt2x00dev_pci(rt2x00dev)->dev);
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c
index 351d95c4f50d..51c5575ed02f 100644
--- a/drivers/net/wireless/rt2x00/rt73usb.c
+++ b/drivers/net/wireless/rt2x00/rt73usb.c
@@ -1830,10 +1830,9 @@ static void rt73usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
1830 */ 1830 */
1831 rt2x00dev->hw->flags = 1831 rt2x00dev->hw->flags =
1832 IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE | 1832 IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE |
1833 IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING; 1833 IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
1834 IEEE80211_HW_SIGNAL_DBM;
1834 rt2x00dev->hw->extra_tx_headroom = TXD_DESC_SIZE; 1835 rt2x00dev->hw->extra_tx_headroom = TXD_DESC_SIZE;
1835 rt2x00dev->hw->max_signal = MAX_SIGNAL;
1836 rt2x00dev->hw->max_rssi = MAX_RX_SSI;
1837 rt2x00dev->hw->queues = 4; 1836 rt2x00dev->hw->queues = 4;
1838 1837
1839 SET_IEEE80211_DEV(rt2x00dev->hw, &rt2x00dev_usb(rt2x00dev)->dev); 1838 SET_IEEE80211_DEV(rt2x00dev->hw, &rt2x00dev_usb(rt2x00dev)->dev);
diff --git a/drivers/net/wireless/rtl8180_dev.c b/drivers/net/wireless/rtl8180_dev.c
index c181f23e930d..c220998cee65 100644
--- a/drivers/net/wireless/rtl8180_dev.c
+++ b/drivers/net/wireless/rtl8180_dev.c
@@ -132,8 +132,8 @@ static void rtl8180_handle_rx(struct ieee80211_hw *dev)
132 132
133 rx_status.antenna = (flags2 >> 15) & 1; 133 rx_status.antenna = (flags2 >> 15) & 1;
134 /* TODO: improve signal/rssi reporting */ 134 /* TODO: improve signal/rssi reporting */
135 rx_status.signal = flags2 & 0xFF; 135 rx_status.qual = flags2 & 0xFF;
136 rx_status.ssi = (flags2 >> 8) & 0x7F; 136 rx_status.signal = (flags2 >> 8) & 0x7F;
137 /* XXX: is this correct? */ 137 /* XXX: is this correct? */
138 rx_status.rate_idx = (flags >> 20) & 0xF; 138 rx_status.rate_idx = (flags >> 20) & 0xF;
139 rx_status.freq = dev->conf.channel->center_freq; 139 rx_status.freq = dev->conf.channel->center_freq;
@@ -894,9 +894,10 @@ static int __devinit rtl8180_probe(struct pci_dev *pdev,
894 dev->wiphy->bands[IEEE80211_BAND_2GHZ] = &priv->band; 894 dev->wiphy->bands[IEEE80211_BAND_2GHZ] = &priv->band;
895 895
896 dev->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | 896 dev->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
897 IEEE80211_HW_RX_INCLUDES_FCS; 897 IEEE80211_HW_RX_INCLUDES_FCS |
898 IEEE80211_HW_SIGNAL_UNSPEC;
898 dev->queues = 1; 899 dev->queues = 1;
899 dev->max_rssi = 65; 900 dev->max_signal = 65;
900 901
901 reg = rtl818x_ioread32(priv, &priv->map->TX_CONF); 902 reg = rtl818x_ioread32(priv, &priv->map->TX_CONF);
902 reg &= RTL818X_TX_CONF_HWVER_MASK; 903 reg &= RTL818X_TX_CONF_HWVER_MASK;
diff --git a/drivers/net/wireless/rtl8187_dev.c b/drivers/net/wireless/rtl8187_dev.c
index d5787b37e1fb..e14c84248686 100644
--- a/drivers/net/wireless/rtl8187_dev.c
+++ b/drivers/net/wireless/rtl8187_dev.c
@@ -261,8 +261,8 @@ static void rtl8187_rx_cb(struct urb *urb)
261 } 261 }
262 262
263 rx_status.antenna = (hdr->signal >> 7) & 1; 263 rx_status.antenna = (hdr->signal >> 7) & 1;
264 rx_status.signal = 64 - min(hdr->noise, (u8)64); 264 rx_status.qual = 64 - min(hdr->noise, (u8)64);
265 rx_status.ssi = signal; 265 rx_status.signal = signal;
266 rx_status.rate_idx = rate; 266 rx_status.rate_idx = rate;
267 rx_status.freq = dev->conf.channel->center_freq; 267 rx_status.freq = dev->conf.channel->center_freq;
268 rx_status.band = dev->conf.channel->band; 268 rx_status.band = dev->conf.channel->band;
@@ -740,11 +740,11 @@ static int __devinit rtl8187_probe(struct usb_interface *intf,
740 740
741 priv->mode = IEEE80211_IF_TYPE_MNTR; 741 priv->mode = IEEE80211_IF_TYPE_MNTR;
742 dev->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | 742 dev->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
743 IEEE80211_HW_RX_INCLUDES_FCS; 743 IEEE80211_HW_RX_INCLUDES_FCS |
744 IEEE80211_HW_SIGNAL_UNSPEC;
744 dev->extra_tx_headroom = sizeof(struct rtl8187_tx_hdr); 745 dev->extra_tx_headroom = sizeof(struct rtl8187_tx_hdr);
745 dev->queues = 1; 746 dev->queues = 1;
746 dev->max_rssi = 65; 747 dev->max_signal = 65;
747 dev->max_signal = 64;
748 748
749 eeprom.data = dev; 749 eeprom.data = dev;
750 eeprom.register_read = rtl8187_eeprom_register_read; 750 eeprom.register_read = rtl8187_eeprom_register_read;
diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c
index ee4331229f1f..0c736735e217 100644
--- a/drivers/net/wireless/zd1211rw/zd_mac.c
+++ b/drivers/net/wireless/zd1211rw/zd_mac.c
@@ -638,7 +638,7 @@ static int filter_ack(struct ieee80211_hw *hw, struct ieee80211_hdr *rx_hdr,
638 638
639 memset(&status, 0, sizeof(status)); 639 memset(&status, 0, sizeof(status));
640 status.flags = IEEE80211_TX_STATUS_ACK; 640 status.flags = IEEE80211_TX_STATUS_ACK;
641 status.ack_signal = stats->ssi; 641 status.ack_signal = stats->signal;
642 __skb_unlink(skb, q); 642 __skb_unlink(skb, q);
643 tx_status(hw, skb, &status, 1); 643 tx_status(hw, skb, &status, 1);
644 goto out; 644 goto out;
@@ -691,8 +691,8 @@ int zd_mac_rx(struct ieee80211_hw *hw, const u8 *buffer, unsigned int length)
691 691
692 stats.freq = zd_channels[_zd_chip_get_channel(&mac->chip) - 1].center_freq; 692 stats.freq = zd_channels[_zd_chip_get_channel(&mac->chip) - 1].center_freq;
693 stats.band = IEEE80211_BAND_2GHZ; 693 stats.band = IEEE80211_BAND_2GHZ;
694 stats.ssi = status->signal_strength; 694 stats.signal = status->signal_strength;
695 stats.signal = zd_rx_qual_percent(buffer, 695 stats.qual = zd_rx_qual_percent(buffer,
696 length - sizeof(struct rx_status), 696 length - sizeof(struct rx_status),
697 status); 697 status);
698 698
@@ -997,10 +997,10 @@ struct ieee80211_hw *zd_mac_alloc_hw(struct usb_interface *intf)
997 hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &mac->band; 997 hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &mac->band;
998 998
999 hw->flags = IEEE80211_HW_RX_INCLUDES_FCS | 999 hw->flags = IEEE80211_HW_RX_INCLUDES_FCS |
1000 IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE; 1000 IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE |
1001 hw->max_rssi = 100; 1001 IEEE80211_HW_SIGNAL_DB;
1002 hw->max_signal = 100;
1003 1002
1003 hw->max_signal = 100;
1004 hw->queues = 1; 1004 hw->queues = 1;
1005 hw->extra_tx_headroom = sizeof(struct zd_ctrlset); 1005 hw->extra_tx_headroom = sizeof(struct zd_ctrlset);
1006 1006
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 75a34609eed7..909956c97c44 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -336,13 +336,16 @@ enum mac80211_rx_flags {
336 * The low-level driver should provide this information (the subset 336 * The low-level driver should provide this information (the subset
337 * supported by hardware) to the 802.11 code with each received 337 * supported by hardware) to the 802.11 code with each received
338 * frame. 338 * frame.
339 *
339 * @mactime: value in microseconds of the 64-bit Time Synchronization Function 340 * @mactime: value in microseconds of the 64-bit Time Synchronization Function
340 * (TSF) timer when the first data symbol (MPDU) arrived at the hardware. 341 * (TSF) timer when the first data symbol (MPDU) arrived at the hardware.
341 * @band: the active band when this frame was received 342 * @band: the active band when this frame was received
342 * @freq: frequency the radio was tuned to when receiving this frame, in MHz 343 * @freq: frequency the radio was tuned to when receiving this frame, in MHz
343 * @ssi: signal strength when receiving this frame 344 * @signal: signal strength when receiving this frame, either in dBm, in dB or
344 * @signal: used as 'qual' in statistics reporting 345 * unspecified depending on the hardware capabilities flags
345 * @noise: PHY noise when receiving this frame 346 * @IEEE80211_HW_SIGNAL_*
347 * @noise: noise when receiving this frame, in dBm.
348 * @qual: overall signal quality indication, in percent (0-100).
346 * @antenna: antenna used 349 * @antenna: antenna used
347 * @rate_idx: index of data rate into band's supported rates 350 * @rate_idx: index of data rate into band's supported rates
348 * @flag: %RX_FLAG_* 351 * @flag: %RX_FLAG_*
@@ -351,9 +354,9 @@ struct ieee80211_rx_status {
351 u64 mactime; 354 u64 mactime;
352 enum ieee80211_band band; 355 enum ieee80211_band band;
353 int freq; 356 int freq;
354 int ssi;
355 int signal; 357 int signal;
356 int noise; 358 int noise;
359 int qual;
357 int antenna; 360 int antenna;
358 int rate_idx; 361 int rate_idx;
359 int flag; 362 int flag;
@@ -392,7 +395,8 @@ enum ieee80211_tx_status_flags {
392 * relevant only if IEEE80211_TX_STATUS_AMPDU was set. 395 * relevant only if IEEE80211_TX_STATUS_AMPDU was set.
393 * @ampdu_ack_map: block ack bit map for the aggregation. 396 * @ampdu_ack_map: block ack bit map for the aggregation.
394 * relevant only if IEEE80211_TX_STATUS_AMPDU was set. 397 * relevant only if IEEE80211_TX_STATUS_AMPDU was set.
395 * @ack_signal: signal strength of the ACK frame 398 * @ack_signal: signal strength of the ACK frame either in dBm, dB or unspec
399 * depending on hardware capabilites flags @IEEE80211_HW_SIGNAL_*
396 */ 400 */
397struct ieee80211_tx_status { 401struct ieee80211_tx_status {
398 struct ieee80211_tx_control control; 402 struct ieee80211_tx_control control;
@@ -703,6 +707,25 @@ enum ieee80211_tkip_key_type {
703 * @IEEE80211_HW_2GHZ_SHORT_PREAMBLE_INCAPABLE: 707 * @IEEE80211_HW_2GHZ_SHORT_PREAMBLE_INCAPABLE:
704 * Hardware is not capable of receiving frames with short preamble on 708 * Hardware is not capable of receiving frames with short preamble on
705 * the 2.4 GHz band. 709 * the 2.4 GHz band.
710 *
711 * @IEEE80211_HW_SIGNAL_UNSPEC:
712 * Hardware can provide signal values but we don't know its units. We
713 * expect values between 0 and @max_signal.
714 * If possible please provide dB or dBm instead.
715 *
716 * @IEEE80211_HW_SIGNAL_DB:
717 * Hardware gives signal values in dB, decibel difference from an
718 * arbitrary, fixed reference. We expect values between 0 and @max_signal.
719 * If possible please provide dBm instead.
720 *
721 * @IEEE80211_HW_SIGNAL_DBM:
722 * Hardware gives signal values in dBm, decibel difference from
723 * one milliwatt. This is the preferred method since it is standardized
724 * between different devices. @max_signal does not need to be set.
725 *
726 * @IEEE80211_HW_NOISE_DBM:
727 * Hardware can provide noise (radio interference) values in units dBm,
728 * decibel difference from one milliwatt.
706 */ 729 */
707enum ieee80211_hw_flags { 730enum ieee80211_hw_flags {
708 IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE = 1<<0, 731 IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE = 1<<0,
@@ -710,6 +733,10 @@ enum ieee80211_hw_flags {
710 IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING = 1<<2, 733 IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING = 1<<2,
711 IEEE80211_HW_2GHZ_SHORT_SLOT_INCAPABLE = 1<<3, 734 IEEE80211_HW_2GHZ_SHORT_SLOT_INCAPABLE = 1<<3,
712 IEEE80211_HW_2GHZ_SHORT_PREAMBLE_INCAPABLE = 1<<4, 735 IEEE80211_HW_2GHZ_SHORT_PREAMBLE_INCAPABLE = 1<<4,
736 IEEE80211_HW_SIGNAL_UNSPEC = 1<<5,
737 IEEE80211_HW_SIGNAL_DB = 1<<6,
738 IEEE80211_HW_SIGNAL_DBM = 1<<7,
739 IEEE80211_HW_NOISE_DBM = 1<<8,
713}; 740};
714 741
715/** 742/**
@@ -740,12 +767,8 @@ enum ieee80211_hw_flags {
740 * 767 *
741 * @channel_change_time: time (in microseconds) it takes to change channels. 768 * @channel_change_time: time (in microseconds) it takes to change channels.
742 * 769 *
743 * @max_rssi: Maximum value for ssi in RX information, use 770 * @max_signal: Maximum value for signal (rssi) in RX information, used
744 * negative numbers for dBm and 0 to indicate no support. 771 * only when @IEEE80211_HW_SIGNAL_UNSPEC or @IEEE80211_HW_SIGNAL_DB
745 *
746 * @max_signal: like @max_rssi, but for the signal value.
747 *
748 * @max_noise: like @max_rssi, but for the noise value.
749 * 772 *
750 * @queues: number of available hardware transmit queues for 773 * @queues: number of available hardware transmit queues for
751 * data packets. WMM/QoS requires at least four, these 774 * data packets. WMM/QoS requires at least four, these
@@ -775,9 +798,7 @@ struct ieee80211_hw {
775 int channel_change_time; 798 int channel_change_time;
776 int vif_data_size; 799 int vif_data_size;
777 u16 queues, ampdu_queues; 800 u16 queues, ampdu_queues;
778 s8 max_rssi;
779 s8 max_signal; 801 s8 max_signal;
780 s8 max_noise;
781}; 802};
782 803
783/** 804/**
diff --git a/net/ieee80211/ieee80211_rx.c b/net/ieee80211/ieee80211_rx.c
index 200ee1e63728..69dbc342a464 100644
--- a/net/ieee80211/ieee80211_rx.c
+++ b/net/ieee80211/ieee80211_rx.c
@@ -391,7 +391,7 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
391 391
392 wstats.updated = 0; 392 wstats.updated = 0;
393 if (rx_stats->mask & IEEE80211_STATMASK_RSSI) { 393 if (rx_stats->mask & IEEE80211_STATMASK_RSSI) {
394 wstats.level = rx_stats->rssi; 394 wstats.level = rx_stats->signal;
395 wstats.updated |= IW_QUAL_LEVEL_UPDATED; 395 wstats.updated |= IW_QUAL_LEVEL_UPDATED;
396 } else 396 } else
397 wstats.updated |= IW_QUAL_LEVEL_INVALID; 397 wstats.updated |= IW_QUAL_LEVEL_INVALID;
diff --git a/net/mac80211/debugfs_sta.c b/net/mac80211/debugfs_sta.c
index 1f00273d99c2..a2cc0284c9d0 100644
--- a/net/mac80211/debugfs_sta.c
+++ b/net/mac80211/debugfs_sta.c
@@ -63,8 +63,8 @@ STA_FILE(tx_fragments, tx_fragments, LU);
63STA_FILE(tx_filtered, tx_filtered_count, LU); 63STA_FILE(tx_filtered, tx_filtered_count, LU);
64STA_FILE(tx_retry_failed, tx_retry_failed, LU); 64STA_FILE(tx_retry_failed, tx_retry_failed, LU);
65STA_FILE(tx_retry_count, tx_retry_count, LU); 65STA_FILE(tx_retry_count, tx_retry_count, LU);
66STA_FILE(last_rssi, last_rssi, D);
67STA_FILE(last_signal, last_signal, D); 66STA_FILE(last_signal, last_signal, D);
67STA_FILE(last_qual, last_qual, D);
68STA_FILE(last_noise, last_noise, D); 68STA_FILE(last_noise, last_noise, D);
69STA_FILE(channel_use, channel_use, D); 69STA_FILE(channel_use, channel_use, D);
70STA_FILE(wep_weak_iv_count, wep_weak_iv_count, LU); 70STA_FILE(wep_weak_iv_count, wep_weak_iv_count, LU);
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 173b7fcb3029..ed0d9b35ae6f 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -82,7 +82,7 @@ struct ieee80211_sta_bss {
82 u16 capability; /* host byte order */ 82 u16 capability; /* host byte order */
83 enum ieee80211_band band; 83 enum ieee80211_band band;
84 int freq; 84 int freq;
85 int rssi, signal, noise; 85 int signal, noise, qual;
86 u8 *wpa_ie; 86 u8 *wpa_ie;
87 size_t wpa_ie_len; 87 size_t wpa_ie_len;
88 u8 *rsn_ie; 88 u8 *rsn_ie;
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index f277407f0f5a..390df48dfd40 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -1702,13 +1702,13 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
1702 1702
1703 local->hw.conf.beacon_int = 1000; 1703 local->hw.conf.beacon_int = 1000;
1704 1704
1705 local->wstats_flags |= local->hw.max_rssi ? 1705 local->wstats_flags |= local->hw.flags & (IEEE80211_HW_SIGNAL_UNSPEC |
1706 IW_QUAL_LEVEL_UPDATED : IW_QUAL_LEVEL_INVALID; 1706 IEEE80211_HW_SIGNAL_DB |
1707 local->wstats_flags |= local->hw.max_signal ? 1707 IEEE80211_HW_SIGNAL_DBM) ?
1708 IW_QUAL_QUAL_UPDATED : IW_QUAL_QUAL_INVALID; 1708 IW_QUAL_QUAL_UPDATED : IW_QUAL_QUAL_INVALID;
1709 local->wstats_flags |= local->hw.max_noise ? 1709 local->wstats_flags |= local->hw.flags & IEEE80211_HW_NOISE_DBM ?
1710 IW_QUAL_NOISE_UPDATED : IW_QUAL_NOISE_INVALID; 1710 IW_QUAL_NOISE_UPDATED : IW_QUAL_NOISE_INVALID;
1711 if (local->hw.max_rssi < 0 || local->hw.max_noise < 0) 1711 if (local->hw.flags & IEEE80211_HW_SIGNAL_DBM)
1712 local->wstats_flags |= IW_QUAL_DBM; 1712 local->wstats_flags |= IW_QUAL_DBM;
1713 1713
1714 result = sta_info_start(local); 1714 result = sta_info_start(local);
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 6c4b27be35da..dda30e98aa1e 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -1959,8 +1959,8 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
1959 local->hw.conf.channel->center_freq, 1959 local->hw.conf.channel->center_freq,
1960 ifsta->ssid, ifsta->ssid_len); 1960 ifsta->ssid, ifsta->ssid_len);
1961 if (bss) { 1961 if (bss) {
1962 sta->last_rssi = bss->rssi;
1963 sta->last_signal = bss->signal; 1962 sta->last_signal = bss->signal;
1963 sta->last_qual = bss->qual;
1964 sta->last_noise = bss->noise; 1964 sta->last_noise = bss->noise;
1965 ieee80211_rx_bss_put(dev, bss); 1965 ieee80211_rx_bss_put(dev, bss);
1966 } 1966 }
@@ -2629,9 +2629,9 @@ static void ieee80211_rx_bss_info(struct net_device *dev,
2629 2629
2630 bss->timestamp = beacon_timestamp; 2630 bss->timestamp = beacon_timestamp;
2631 bss->last_update = jiffies; 2631 bss->last_update = jiffies;
2632 bss->rssi = rx_status->ssi;
2633 bss->signal = rx_status->signal; 2632 bss->signal = rx_status->signal;
2634 bss->noise = rx_status->noise; 2633 bss->noise = rx_status->noise;
2634 bss->qual = rx_status->qual;
2635 if (!beacon && !bss->probe_resp) 2635 if (!beacon && !bss->probe_resp)
2636 bss->probe_resp = true; 2636 bss->probe_resp = true;
2637 2637
@@ -3427,9 +3427,9 @@ static int ieee80211_sta_config_auth(struct net_device *dev,
3427 !ieee80211_sta_match_ssid(ifsta, bss->ssid, bss->ssid_len)) 3427 !ieee80211_sta_match_ssid(ifsta, bss->ssid, bss->ssid_len))
3428 continue; 3428 continue;
3429 3429
3430 if (!selected || top_rssi < bss->rssi) { 3430 if (!selected || top_rssi < bss->signal) {
3431 selected = bss; 3431 selected = bss;
3432 top_rssi = bss->rssi; 3432 top_rssi = bss->signal;
3433 } 3433 }
3434 } 3434 }
3435 if (selected) 3435 if (selected)
@@ -4060,8 +4060,8 @@ ieee80211_sta_scan_result(struct net_device *dev,
4060 4060
4061 memset(&iwe, 0, sizeof(iwe)); 4061 memset(&iwe, 0, sizeof(iwe));
4062 iwe.cmd = IWEVQUAL; 4062 iwe.cmd = IWEVQUAL;
4063 iwe.u.qual.qual = bss->signal; 4063 iwe.u.qual.qual = bss->qual;
4064 iwe.u.qual.level = bss->rssi; 4064 iwe.u.qual.level = bss->signal;
4065 iwe.u.qual.noise = bss->noise; 4065 iwe.u.qual.noise = bss->noise;
4066 iwe.u.qual.updated = local->wstats_flags; 4066 iwe.u.qual.updated = local->wstats_flags;
4067 current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, 4067 current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe,
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index b399e09ec7aa..474f13662c84 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -209,7 +209,7 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb,
209 cpu_to_le16(IEEE80211_CHAN_DYN | 209 cpu_to_le16(IEEE80211_CHAN_DYN |
210 IEEE80211_CHAN_2GHZ); 210 IEEE80211_CHAN_2GHZ);
211 211
212 rtfixed->antsignal = status->ssi; 212 rtfixed->antsignal = status->signal;
213 rthdr->it_len = cpu_to_le16(rtap_len); 213 rthdr->it_len = cpu_to_le16(rtap_len);
214 } 214 }
215 215
@@ -719,8 +719,8 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx)
719 719
720 sta->rx_fragments++; 720 sta->rx_fragments++;
721 sta->rx_bytes += rx->skb->len; 721 sta->rx_bytes += rx->skb->len;
722 sta->last_rssi = rx->status->ssi;
723 sta->last_signal = rx->status->signal; 722 sta->last_signal = rx->status->signal;
723 sta->last_qual = rx->status->qual;
724 sta->last_noise = rx->status->noise; 724 sta->last_noise = rx->status->noise;
725 725
726 if (!(rx->fc & IEEE80211_FCTL_MOREFRAGS)) { 726 if (!(rx->fc & IEEE80211_FCTL_MOREFRAGS)) {
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h
index 97a61c39ad90..e89cc1655547 100644
--- a/net/mac80211/sta_info.h
+++ b/net/mac80211/sta_info.h
@@ -216,8 +216,8 @@ struct sta_info {
216 * from this STA */ 216 * from this STA */
217 unsigned long rx_fragments; /* number of received MPDUs */ 217 unsigned long rx_fragments; /* number of received MPDUs */
218 unsigned long rx_dropped; /* number of dropped MPDUs from this STA */ 218 unsigned long rx_dropped; /* number of dropped MPDUs from this STA */
219 int last_rssi; /* RSSI of last received frame from this STA */
220 int last_signal; /* signal of last received frame from this STA */ 219 int last_signal; /* signal of last received frame from this STA */
220 int last_qual; /* qual of last received frame from this STA */
221 int last_noise; /* noise of last received frame from this STA */ 221 int last_noise; /* noise of last received frame from this STA */
222 /* last received seq/frag number from this STA (per RX queue) */ 222 /* last received seq/frag number from this STA (per RX queue) */
223 __le16 last_seq_ctrl[NUM_RX_DATA_QUEUES]; 223 __le16 last_seq_ctrl[NUM_RX_DATA_QUEUES];
diff --git a/net/mac80211/wext.c b/net/mac80211/wext.c
index 76e1de1dc735..6a342a9a40cd 100644
--- a/net/mac80211/wext.c
+++ b/net/mac80211/wext.c
@@ -169,14 +169,26 @@ static int ieee80211_ioctl_giwrange(struct net_device *dev,
169 range->num_encoding_sizes = 2; 169 range->num_encoding_sizes = 2;
170 range->max_encoding_tokens = NUM_DEFAULT_KEYS; 170 range->max_encoding_tokens = NUM_DEFAULT_KEYS;
171 171
172 range->max_qual.qual = local->hw.max_signal; 172 if (local->hw.flags & IEEE80211_HW_SIGNAL_UNSPEC ||
173 range->max_qual.level = local->hw.max_rssi; 173 local->hw.flags & IEEE80211_HW_SIGNAL_DB)
174 range->max_qual.noise = local->hw.max_noise; 174 range->max_qual.level = local->hw.max_signal;
175 else if (local->hw.flags & IEEE80211_HW_SIGNAL_DBM)
176 range->max_qual.level = -110;
177 else
178 range->max_qual.level = 0;
179
180 if (local->hw.flags & IEEE80211_HW_NOISE_DBM)
181 range->max_qual.noise = -110;
182 else
183 range->max_qual.noise = 0;
184
185 range->max_qual.qual = 100;
175 range->max_qual.updated = local->wstats_flags; 186 range->max_qual.updated = local->wstats_flags;
176 187
177 range->avg_qual.qual = local->hw.max_signal/2; 188 range->avg_qual.qual = 50;
178 range->avg_qual.level = 0; 189 /* not always true but better than nothing */
179 range->avg_qual.noise = 0; 190 range->avg_qual.level = range->max_qual.level / 2;
191 range->avg_qual.noise = range->max_qual.noise / 2;
180 range->avg_qual.updated = local->wstats_flags; 192 range->avg_qual.updated = local->wstats_flags;
181 193
182 range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 | 194 range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 |
@@ -996,8 +1008,8 @@ static struct iw_statistics *ieee80211_get_wireless_stats(struct net_device *dev
996 wstats->qual.noise = 0; 1008 wstats->qual.noise = 0;
997 wstats->qual.updated = IW_QUAL_ALL_INVALID; 1009 wstats->qual.updated = IW_QUAL_ALL_INVALID;
998 } else { 1010 } else {
999 wstats->qual.level = sta->last_rssi; 1011 wstats->qual.level = sta->last_signal;
1000 wstats->qual.qual = sta->last_signal; 1012 wstats->qual.qual = sta->last_qual;
1001 wstats->qual.noise = sta->last_noise; 1013 wstats->qual.noise = sta->last_noise;
1002 wstats->qual.updated = local->wstats_flags; 1014 wstats->qual.updated = local->wstats_flags;
1003 } 1015 }