mac80211: use hardware flags for signal/noise units
authorBruno Randolf <br1@einfach.org>
Thu, 8 May 2008 17:15:40 +0000 (19:15 +0200)
committerJohn W. Linville <linville@tuxdriver.com>
Wed, 14 May 2008 20:29:49 +0000 (16:29 -0400)
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>
29 files changed:
drivers/net/wireless/adm8211.c
drivers/net/wireless/ath5k/base.c
drivers/net/wireless/b43/main.c
drivers/net/wireless/b43/xmit.c
drivers/net/wireless/b43legacy/main.c
drivers/net/wireless/b43legacy/xmit.c
drivers/net/wireless/iwlwifi/iwl-3945.c
drivers/net/wireless/iwlwifi/iwl-4965.c
drivers/net/wireless/iwlwifi/iwl-core.c
drivers/net/wireless/iwlwifi/iwl3945-base.c
drivers/net/wireless/p54/p54common.c
drivers/net/wireless/rt2x00/rt2400pci.c
drivers/net/wireless/rt2x00/rt2500pci.c
drivers/net/wireless/rt2x00/rt2500usb.c
drivers/net/wireless/rt2x00/rt2x00dev.c
drivers/net/wireless/rt2x00/rt61pci.c
drivers/net/wireless/rt2x00/rt73usb.c
drivers/net/wireless/rtl8180_dev.c
drivers/net/wireless/rtl8187_dev.c
drivers/net/wireless/zd1211rw/zd_mac.c
include/net/mac80211.h
net/ieee80211/ieee80211_rx.c
net/mac80211/debugfs_sta.c
net/mac80211/ieee80211_i.h
net/mac80211/main.c
net/mac80211/mlme.c
net/mac80211/rx.c
net/mac80211/sta_info.h
net/mac80211/wext.c

index d93a1de77eb08afc95d1ffc26a5d3e722b567241..7af5d8851f6782f6f576c7efe96f4ba02ffb97d6 100644 (file)
@@ -445,9 +445,9 @@ static void adm8211_interrupt_rci(struct ieee80211_hw *dev)
                        struct ieee80211_rx_status rx_status = {0};
 
                        if (priv->pdev->revision < ADM8211_REV_CA)
-                               rx_status.ssi = rssi;
+                               rx_status.signal = rssi;
                        else
-                               rx_status.ssi = 100 - rssi;
+                               rx_status.signal = 100 - rssi;
 
                        rx_status.rate_idx = rate;
 
@@ -1893,9 +1893,10 @@ static int __devinit adm8211_probe(struct pci_dev *pdev,
 
        dev->extra_tx_headroom = sizeof(struct adm8211_tx_hdr);
        /* dev->flags = IEEE80211_HW_RX_INCLUDES_FCS in promisc mode */
+       dev->flags = IEEE80211_HW_SIGNAL_UNSPEC;
 
        dev->channel_change_time = 1000;
-       dev->max_rssi = 100;    /* FIXME: find better value */
+       dev->max_signal = 100;    /* FIXME: find better value */
 
        dev->queues = 1; /* ADM8211C supports more, maybe ADM8211B too */
 
index 3201c16043401fc741a47e1e477cbaaa8835e159..dd8adaddd7a01231577448ceeb0b7d665c630609 100644 (file)
@@ -458,13 +458,11 @@ ath5k_pci_probe(struct pci_dev *pdev,
 
        /* Initialize driver private data */
        SET_IEEE80211_DEV(hw, &pdev->dev);
-       hw->flags = IEEE80211_HW_RX_INCLUDES_FCS;
+       hw->flags = IEEE80211_HW_RX_INCLUDES_FCS |
+                   IEEE80211_HW_SIGNAL_DBM |
+                   IEEE80211_HW_NOISE_DBM;
        hw->extra_tx_headroom = 2;
        hw->channel_change_time = 5000;
-       /* these names are misleading */
-       hw->max_rssi = -110; /* signal in dBm */
-       hw->max_noise = -110; /* noise in dBm */
-       hw->max_signal = 100; /* we will provide a percentage based on rssi */
        sc = hw->priv;
        sc->hw = hw;
        sc->pdev = pdev;
@@ -1893,20 +1891,9 @@ accept:
                rxs.freq = sc->curchan->center_freq;
                rxs.band = sc->curband->band;
 
-               /*
-                * signal quality:
-                * the names here are misleading and the usage of these
-                * values by iwconfig makes it even worse
-                */
-               /* noise floor in dBm, from the last noise calibration */
                rxs.noise = sc->ah->ah_noise_floor;
-               /* signal level in dBm */
-               rxs.ssi = rxs.noise + rs.rs_rssi;
-               /*
-                * "signal" is actually displayed as Link Quality by iwconfig
-                * we provide a percentage based on rssi (assuming max rssi 64)
-                */
-               rxs.signal = rs.rs_rssi * 100 / 64;
+               rxs.signal = rxs.noise + rs.rs_rssi;
+               rxs.qual = rs.rs_rssi * 100 / 64;
 
                rxs.antenna = rs.rs_antenna;
                rxs.rate_idx = ath5k_hw_to_driver_rix(sc, rs.rs_rate);
index 7c23aa8705c234b123aba5af2943d0e7aad4cc07..fc23ba5309bd08aaa579fec578f0d75e644904da 100644 (file)
@@ -4466,10 +4466,10 @@ static int b43_wireless_init(struct ssb_device *dev)
 
        /* fill hw info */
        hw->flags = IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE |
-                   IEEE80211_HW_RX_INCLUDES_FCS;
-       hw->max_signal = 100;
-       hw->max_rssi = -110;
-       hw->max_noise = -110;
+                   IEEE80211_HW_RX_INCLUDES_FCS |
+                   IEEE80211_HW_SIGNAL_DBM |
+                   IEEE80211_HW_NOISE_DBM;
+
        hw->queues = b43_modparam_qos ? 4 : 1;
        SET_IEEE80211_DEV(hw, dev->dev);
        if (is_valid_ether_addr(sprom->et1mac))
index 88491947a20913dfe458fecc675885b8d9f3d68d..afce9338d83a2b305b403ed5362ac1e8ce950f29 100644 (file)
@@ -581,12 +581,11 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr)
                //      and also find out what the maximum possible value is.
                //      Fill status.ssi and status.signal fields.
        } else {
-               status.ssi = b43_rssi_postprocess(dev, rxhdr->jssi,
+               status.signal = b43_rssi_postprocess(dev, rxhdr->jssi,
                                                  (phystat0 & B43_RX_PHYST0_OFDM),
                                                  (phystat0 & B43_RX_PHYST0_GAINCTL),
                                                  (phystat3 & B43_RX_PHYST3_TRSTATE));
-               /* the next line looks wrong, but is what mac80211 wants */
-               status.signal = (rxhdr->jssi * 100) / B43_RX_MAX_SSI;
+               status.qual = (rxhdr->jssi * 100) / B43_RX_MAX_SSI;
        }
 
        if (phystat0 & B43_RX_PHYST0_OFDM)
index d3820dce3c43c3b53317f34c6a12bec0797d0963..7755c59e0803bb88dde4ef18b69b63e734125c6a 100644 (file)
@@ -3718,10 +3718,9 @@ static int b43legacy_wireless_init(struct ssb_device *dev)
 
        /* fill hw info */
        hw->flags = IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE |
-                   IEEE80211_HW_RX_INCLUDES_FCS;
-       hw->max_signal = 100;
-       hw->max_rssi = -110;
-       hw->max_noise = -110;
+                   IEEE80211_HW_RX_INCLUDES_FCS |
+                   IEEE80211_HW_SIGNAL_DBM |
+                   IEEE80211_HW_NOISE_DBM;
        hw->queues = 1; /* FIXME: hardware has more queues */
        SET_IEEE80211_DEV(hw, dev->dev);
        if (is_valid_ether_addr(sprom->et1mac))
index fc83dab6e2c7aedc51ca4270a8196c515c1f2c88..bed9e041d6c5518b48ce8e90673ee8d6b09c5f2b 100644 (file)
@@ -532,12 +532,12 @@ void b43legacy_rx(struct b43legacy_wldev *dev,
                }
        }
 
-       status.ssi = b43legacy_rssi_postprocess(dev, jssi,
+       status.signal = b43legacy_rssi_postprocess(dev, jssi,
                                      (phystat0 & B43legacy_RX_PHYST0_OFDM),
                                      (phystat0 & B43legacy_RX_PHYST0_GAINCTL),
                                      (phystat3 & B43legacy_RX_PHYST3_TRSTATE));
        status.noise = dev->stats.link_noise;
-       status.signal = (jssi * 100) / B43legacy_RX_MAX_SSI;
+       status.qual = (jssi * 100) / B43legacy_RX_MAX_SSI;
        /* change to support A PHY */
        if (phystat0 & B43legacy_RX_PHYST0_OFDM)
                status.rate_idx = b43legacy_plcp_get_bitrate_idx_ofdm(plcp, false);
index 8464397f78165154bf3dc03a3fc181238fa6c3f6..d7beeff2642c791ef0ddacc758f86ee6b54daeaa 100644 (file)
@@ -520,7 +520,7 @@ static void iwl3945_add_radiotap(struct iwl3945_priv *priv,
 {
        /* First cache any information we need before we overwrite
         * the information provided in the skb from the hardware */
-       s8 signal = stats->ssi;
+       s8 signal = stats->signal;
        s8 noise = 0;
        int rate = stats->rate_idx;
        u64 tsf = stats->mactime;
@@ -693,7 +693,7 @@ static void iwl3945_rx_reply_rx(struct iwl3945_priv *priv,
        }
 
        /* Convert 3945's rssi indicator to dBm */
-       rx_status.ssi = rx_stats->rssi - IWL_RSSI_OFFSET;
+       rx_status.signal = rx_stats->rssi - IWL_RSSI_OFFSET;
 
        /* Set default noise value to -127 */
        if (priv->last_rx_noise == 0)
@@ -712,21 +712,21 @@ static void iwl3945_rx_reply_rx(struct iwl3945_priv *priv,
         * Calculate rx_status.signal (quality indicator in %) based on SNR. */
        if (rx_stats_noise_diff) {
                snr = rx_stats_sig_avg / rx_stats_noise_diff;
-               rx_status.noise = rx_status.ssi -
+               rx_status.noise = rx_status.signal -
                                        iwl3945_calc_db_from_ratio(snr);
-               rx_status.signal = iwl3945_calc_sig_qual(rx_status.ssi,
+               rx_status.qual = iwl3945_calc_sig_qual(rx_status.signal,
                                                         rx_status.noise);
 
        /* If noise info not available, calculate signal quality indicator (%)
         *   using just the dBm signal level. */
        } else {
                rx_status.noise = priv->last_rx_noise;
-               rx_status.signal = iwl3945_calc_sig_qual(rx_status.ssi, 0);
+               rx_status.qual = iwl3945_calc_sig_qual(rx_status.signal, 0);
        }
 
 
        IWL_DEBUG_STATS("Rssi %d noise %d qual %d sig_avg %d noise_diff %d\n",
-                       rx_status.ssi, rx_status.noise, rx_status.signal,
+                       rx_status.signal, rx_status.noise, rx_status.qual,
                        rx_stats_sig_avg, rx_stats_noise_diff);
 
        header = (struct ieee80211_hdr *)IWL_RX_DATA(pkt);
@@ -736,8 +736,8 @@ static void iwl3945_rx_reply_rx(struct iwl3945_priv *priv,
        IWL_DEBUG_STATS_LIMIT("[%c] %d RSSI:%d Signal:%u, Noise:%u, Rate:%u\n",
                              network_packet ? '*' : ' ',
                              le16_to_cpu(rx_hdr->channel),
-                             rx_status.ssi, rx_status.ssi,
-                             rx_status.ssi, rx_status.rate_idx);
+                             rx_status.signal, rx_status.signal,
+                             rx_status.noise, rx_status.rate_idx);
 
 #ifdef CONFIG_IWL3945_DEBUG
        if (iwl3945_debug_level & (IWL_DL_RX))
@@ -748,7 +748,7 @@ static void iwl3945_rx_reply_rx(struct iwl3945_priv *priv,
        if (network_packet) {
                priv->last_beacon_time = le32_to_cpu(rx_end->beacon_timestamp);
                priv->last_tsf = le64_to_cpu(rx_end->timestamp);
-               priv->last_rx_rssi = rx_status.ssi;
+               priv->last_rx_rssi = rx_status.signal;
                priv->last_rx_noise = rx_status.noise;
        }
 
index b7036e0114571a5df787fc8040ed444dcae59ad4..45cbd7789bd03bae13fcced6723c324ca0b87cb3 100644 (file)
@@ -2362,7 +2362,7 @@ static void iwl4965_add_radiotap(struct iwl_priv *priv,
                                 struct ieee80211_rx_status *stats,
                                 u32 ampdu_status)
 {
-       s8 signal = stats->ssi;
+       s8 signal = stats->signal;
        s8 noise = 0;
        int rate = stats->rate_idx;
        u64 tsf = stats->mactime;
@@ -2963,7 +2963,7 @@ static void iwl4965_rx_reply_rx(struct iwl_priv *priv,
        priv->ucode_beacon_time = le32_to_cpu(rx_start->beacon_time_stamp);
 
        /* Find max signal strength (dBm) among 3 antenna/receiver chains */
-       rx_status.ssi = iwl4965_calc_rssi(priv, rx_start);
+       rx_status.signal = iwl4965_calc_rssi(priv, rx_start);
 
        /* Meaningful noise values are available only from beacon statistics,
         *   which are gathered only when associated, and indicate noise
@@ -2972,11 +2972,11 @@ static void iwl4965_rx_reply_rx(struct iwl_priv *priv,
        if (iwl_is_associated(priv) &&
            !test_bit(STATUS_SCANNING, &priv->status)) {
                rx_status.noise = priv->last_rx_noise;
-               rx_status.signal = iwl4965_calc_sig_qual(rx_status.ssi,
+               rx_status.qual = iwl4965_calc_sig_qual(rx_status.signal,
                                                         rx_status.noise);
        } else {
                rx_status.noise = IWL_NOISE_MEAS_NOT_AVAILABLE;
-               rx_status.signal = iwl4965_calc_sig_qual(rx_status.ssi, 0);
+               rx_status.qual = iwl4965_calc_sig_qual(rx_status.signal, 0);
        }
 
        /* Reset beacon noise level if not associated. */
@@ -2988,7 +2988,7 @@ static void iwl4965_rx_reply_rx(struct iwl_priv *priv,
        iwl4965_dbg_report_frame(priv, pkt, header, 1);
 
        IWL_DEBUG_STATS_LIMIT("Rssi %d, noise %d, qual %d, TSF %llu\n",
-                             rx_status.ssi, rx_status.noise, rx_status.signal,
+                             rx_status.signal, rx_status.noise, rx_status.signal,
                              (unsigned long long)rx_status.mactime);
 
 
@@ -3000,7 +3000,7 @@ static void iwl4965_rx_reply_rx(struct iwl_priv *priv,
 
        network_packet = iwl4965_is_network_packet(priv, header);
        if (network_packet) {
-               priv->last_rx_rssi = rx_status.ssi;
+               priv->last_rx_rssi = rx_status.signal;
                priv->last_beacon_time =  priv->ucode_beacon_time;
                priv->last_tsf = le64_to_cpu(rx_start->timestamp);
        }
index 27e56b89d940a0d0b54763386bf51afaec7e1c78..d3cbad2bf8770c0b58a45773f9fd268ee2c92d5e 100644 (file)
@@ -746,18 +746,10 @@ static void iwlcore_init_hw(struct iwl_priv *priv)
        struct ieee80211_hw *hw = priv->hw;
        hw->rate_control_algorithm = "iwl-4965-rs";
 
-       /* Tell mac80211 and its clients (e.g. Wireless Extensions)
-        *       the range of signal quality values that we'll provide.
-        * Negative values for level/noise indicate that we'll provide dBm.
-        * For WE, at least, non-0 values here *enable* display of values
-        *       in app (iwconfig). */
-       hw->max_rssi = -20; /* signal level, negative indicates dBm */
-       hw->max_noise = -20;    /* noise level, negative indicates dBm */
-       hw->max_signal = 100;   /* link quality indication (%) */
-
-       /* Tell mac80211 our Tx characteristics */
-       hw->flags = IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE;
-
+       /* Tell mac80211 our characteristics */
+       hw->flags = IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE |
+                   IEEE80211_HW_SIGNAL_DBM |
+                   IEEE80211_HW_NOISE_DBM;
        /* Default value; 4 EDCA QOS priorities */
        hw->queues = 4;
 #ifdef CONFIG_IWL4965_HT
index 4baa185ba500abe6d0418b34edfc7ffd0fa25a43..c1234ff4fc98ea58358eda424c79cfae4537bfdc 100644 (file)
@@ -8029,17 +8029,10 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
 
        priv->ibss_beacon = NULL;
 
-       /* Tell mac80211 and its clients (e.g. Wireless Extensions)
-        *   the range of signal quality values that we'll provide.
-        * Negative values for level/noise indicate that we'll provide dBm.
-        * For WE, at least, non-0 values here *enable* display of values
-        *   in app (iwconfig). */
-       hw->max_rssi = -20;     /* signal level, negative indicates dBm */
-       hw->max_noise = -20;    /* noise level, negative indicates dBm */
-       hw->max_signal = 100;   /* link quality indication (%) */
-
-       /* Tell mac80211 our Tx characteristics */
-       hw->flags = IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE;
+       /* Tell mac80211 our characteristics */
+       hw->flags = IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE |
+                   IEEE80211_HW_SIGNAL_DBM |
+                   IEEE80211_HW_NOISE_DBM;
 
        /* 4 EDCA QOS priorities */
        hw->queues = 4;
index 33d608a60d79dd815d8e0a517bbd7e6a61bbd2ac..9cbef5bce0f6fbb7360a6a2cef88b7b0c7108961 100644 (file)
@@ -355,7 +355,7 @@ static void p54_rx_data(struct ieee80211_hw *dev, struct sk_buff *skb)
        struct ieee80211_rx_status rx_status = {0};
        u16 freq = le16_to_cpu(hdr->freq);
 
-       rx_status.ssi = hdr->rssi;
+       rx_status.signal = hdr->rssi;
        /* XX correct? */
        rx_status.rate_idx = hdr->rate & 0xf;
        rx_status.freq = freq;
@@ -1000,9 +1000,10 @@ struct ieee80211_hw *p54_init_common(size_t priv_data_len)
        skb_queue_head_init(&priv->tx_queue);
        dev->wiphy->bands[IEEE80211_BAND_2GHZ] = &band_2GHz;
        dev->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | /* not sure */
-                   IEEE80211_HW_RX_INCLUDES_FCS;
+                    IEEE80211_HW_RX_INCLUDES_FCS |
+                    IEEE80211_HW_SIGNAL_UNSPEC;
        dev->channel_change_time = 1000;        /* TODO: find actual value */
-       dev->max_rssi = 127;
+       dev->max_signal = 127;
 
        priv->tx_stats[0].limit = 5;
        dev->queues = 1;
index 247fbbfb0f2b2a9b46b63561cbfe1268f25025b5..afa565c63621455ce726aef92721a535938beb00 100644 (file)
@@ -1361,10 +1361,9 @@ static void rt2400pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
        /*
         * Initialize all hw fields.
         */
-       rt2x00dev->hw->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING;
+       rt2x00dev->hw->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
+                              IEEE80211_HW_SIGNAL_DBM;
        rt2x00dev->hw->extra_tx_headroom = 0;
-       rt2x00dev->hw->max_signal = MAX_SIGNAL;
-       rt2x00dev->hw->max_rssi = MAX_RX_SSI;
        rt2x00dev->hw->queues = 2;
 
        SET_IEEE80211_DEV(rt2x00dev->hw, &rt2x00dev_pci(rt2x00dev)->dev);
index 0d53c75d55dd15af716d715eb784c9a4453aae2f..c06f1b5e5887d310ede169c9e25b2664b85b6eda 100644 (file)
@@ -1680,10 +1680,10 @@ static void rt2500pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
        /*
         * Initialize all hw fields.
         */
-       rt2x00dev->hw->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING;
+       rt2x00dev->hw->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
+                              IEEE80211_HW_SIGNAL_DBM;
+
        rt2x00dev->hw->extra_tx_headroom = 0;
-       rt2x00dev->hw->max_signal = MAX_SIGNAL;
-       rt2x00dev->hw->max_rssi = MAX_RX_SSI;
        rt2x00dev->hw->queues = 2;
 
        SET_IEEE80211_DEV(rt2x00dev->hw, &rt2x00dev_pci(rt2x00dev)->dev);
index 80b34d47114a89d291912b58276729e0882d6186..88bafdf8f0fa1cbf6e060c9a0ad2e55da8c7cf6f 100644 (file)
@@ -1587,10 +1587,10 @@ static void rt2500usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
        rt2x00dev->hw->flags =
            IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE |
            IEEE80211_HW_RX_INCLUDES_FCS |
-           IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING;
+           IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
+           IEEE80211_HW_SIGNAL_DBM;
+
        rt2x00dev->hw->extra_tx_headroom = TXD_DESC_SIZE;
-       rt2x00dev->hw->max_signal = MAX_SIGNAL;
-       rt2x00dev->hw->max_rssi = MAX_RX_SSI;
        rt2x00dev->hw->queues = 2;
 
        SET_IEEE80211_DEV(rt2x00dev->hw, &rt2x00dev_usb(rt2x00dev)->dev);
index 9929b15e28ba97ad8a03e5b8d704cc055065b71f..f51a50b31e16727762b75fbb929dab93a7c32b8e 100644 (file)
@@ -600,9 +600,9 @@ void rt2x00lib_rxdone(struct queue_entry *entry,
        rt2x00dev->link.qual.rx_success++;
 
        rx_status->rate_idx = idx;
-       rx_status->signal =
+       rx_status->qual =
            rt2x00lib_calculate_link_signal(rt2x00dev, rxdesc->rssi);
-       rx_status->ssi = rxdesc->rssi;
+       rx_status->signal = rxdesc->rssi;
        rx_status->flag = rxdesc->flags;
        rx_status->antenna = rt2x00dev->link.ant.active.rx;
 
index 98af4d26583d47330b9f9abcf81468c2c2f16d01..eaf23b90877215a52afc81d3f72e8ad8175a78c4 100644 (file)
@@ -2245,10 +2245,9 @@ static void rt61pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
         */
        rt2x00dev->hw->flags =
            IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE |
-           IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING;
+           IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
+           IEEE80211_HW_SIGNAL_DBM;
        rt2x00dev->hw->extra_tx_headroom = 0;
-       rt2x00dev->hw->max_signal = MAX_SIGNAL;
-       rt2x00dev->hw->max_rssi = MAX_RX_SSI;
        rt2x00dev->hw->queues = 4;
 
        SET_IEEE80211_DEV(rt2x00dev->hw, &rt2x00dev_pci(rt2x00dev)->dev);
index 351d95c4f50d7fc6de9a7420229cf2b776ef171f..51c5575ed02fe73989e82fa9b1706c4ee00668f3 100644 (file)
@@ -1830,10 +1830,9 @@ static void rt73usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
         */
        rt2x00dev->hw->flags =
            IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE |
-           IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING;
+           IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
+           IEEE80211_HW_SIGNAL_DBM;
        rt2x00dev->hw->extra_tx_headroom = TXD_DESC_SIZE;
-       rt2x00dev->hw->max_signal = MAX_SIGNAL;
-       rt2x00dev->hw->max_rssi = MAX_RX_SSI;
        rt2x00dev->hw->queues = 4;
 
        SET_IEEE80211_DEV(rt2x00dev->hw, &rt2x00dev_usb(rt2x00dev)->dev);
index c181f23e930dc96048f3b1d700434bbf92a6a26b..c220998cee65b46fd844cead4153023223fd95dc 100644 (file)
@@ -132,8 +132,8 @@ static void rtl8180_handle_rx(struct ieee80211_hw *dev)
 
                        rx_status.antenna = (flags2 >> 15) & 1;
                        /* TODO: improve signal/rssi reporting */
-                       rx_status.signal = flags2 & 0xFF;
-                       rx_status.ssi = (flags2 >> 8) & 0x7F;
+                       rx_status.qual = flags2 & 0xFF;
+                       rx_status.signal = (flags2 >> 8) & 0x7F;
                        /* XXX: is this correct? */
                        rx_status.rate_idx = (flags >> 20) & 0xF;
                        rx_status.freq = dev->conf.channel->center_freq;
@@ -894,9 +894,10 @@ static int __devinit rtl8180_probe(struct pci_dev *pdev,
        dev->wiphy->bands[IEEE80211_BAND_2GHZ] = &priv->band;
 
        dev->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
-                    IEEE80211_HW_RX_INCLUDES_FCS;
+                    IEEE80211_HW_RX_INCLUDES_FCS |
+                    IEEE80211_HW_SIGNAL_UNSPEC;
        dev->queues = 1;
-       dev->max_rssi = 65;
+       dev->max_signal = 65;
 
        reg = rtl818x_ioread32(priv, &priv->map->TX_CONF);
        reg &= RTL818X_TX_CONF_HWVER_MASK;
index d5787b37e1fb401695b43d2bf49022f5777b0a69..e14c84248686ca4581fc9c6c76f1aef8ec9cbee9 100644 (file)
@@ -261,8 +261,8 @@ static void rtl8187_rx_cb(struct urb *urb)
        }
 
        rx_status.antenna = (hdr->signal >> 7) & 1;
-       rx_status.signal = 64 - min(hdr->noise, (u8)64);
-       rx_status.ssi = signal;
+       rx_status.qual = 64 - min(hdr->noise, (u8)64);
+       rx_status.signal = signal;
        rx_status.rate_idx = rate;
        rx_status.freq = dev->conf.channel->center_freq;
        rx_status.band = dev->conf.channel->band;
@@ -740,11 +740,11 @@ static int __devinit rtl8187_probe(struct usb_interface *intf,
 
        priv->mode = IEEE80211_IF_TYPE_MNTR;
        dev->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
-                    IEEE80211_HW_RX_INCLUDES_FCS;
+                    IEEE80211_HW_RX_INCLUDES_FCS |
+                    IEEE80211_HW_SIGNAL_UNSPEC;
        dev->extra_tx_headroom = sizeof(struct rtl8187_tx_hdr);
        dev->queues = 1;
-       dev->max_rssi = 65;
-       dev->max_signal = 64;
+       dev->max_signal = 65;
 
        eeprom.data = dev;
        eeprom.register_read = rtl8187_eeprom_register_read;
index ee4331229f1f80f1c7f00580f9df7d9cbb2237d5..0c736735e2173daee686f55d66ff7dca717128df 100644 (file)
@@ -638,7 +638,7 @@ static int filter_ack(struct ieee80211_hw *hw, struct ieee80211_hdr *rx_hdr,
 
                        memset(&status, 0, sizeof(status));
                        status.flags = IEEE80211_TX_STATUS_ACK;
-                       status.ack_signal = stats->ssi;
+                       status.ack_signal = stats->signal;
                        __skb_unlink(skb, q);
                        tx_status(hw, skb, &status, 1);
                        goto out;
@@ -691,8 +691,8 @@ int zd_mac_rx(struct ieee80211_hw *hw, const u8 *buffer, unsigned int length)
 
        stats.freq = zd_channels[_zd_chip_get_channel(&mac->chip) - 1].center_freq;
        stats.band = IEEE80211_BAND_2GHZ;
-       stats.ssi = status->signal_strength;
-       stats.signal = zd_rx_qual_percent(buffer,
+       stats.signal = status->signal_strength;
+       stats.qual = zd_rx_qual_percent(buffer,
                                          length - sizeof(struct rx_status),
                                          status);
 
@@ -997,10 +997,10 @@ struct ieee80211_hw *zd_mac_alloc_hw(struct usb_interface *intf)
        hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &mac->band;
 
        hw->flags = IEEE80211_HW_RX_INCLUDES_FCS |
-                   IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE;
-       hw->max_rssi = 100;
-       hw->max_signal = 100;
+                   IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE |
+                   IEEE80211_HW_SIGNAL_DB;
 
+       hw->max_signal = 100;
        hw->queues = 1;
        hw->extra_tx_headroom = sizeof(struct zd_ctrlset);
 
index 75a34609eed7955ef84576e3667bc8540c5f4c05..909956c97c448f776228b6eba42b5fb87b091503 100644 (file)
@@ -336,13 +336,16 @@ enum mac80211_rx_flags {
  * The low-level driver should provide this information (the subset
  * supported by hardware) to the 802.11 code with each received
  * frame.
+ *
  * @mactime: value in microseconds of the 64-bit Time Synchronization Function
  *     (TSF) timer when the first data symbol (MPDU) arrived at the hardware.
  * @band: the active band when this frame was received
  * @freq: frequency the radio was tuned to when receiving this frame, in MHz
- * @ssi: signal strength when receiving this frame
- * @signal: used as 'qual' in statistics reporting
- * @noise: PHY noise when receiving this frame
+ * @signal: signal strength when receiving this frame, either in dBm, in dB or
+ *     unspecified depending on the hardware capabilities flags
+ *     @IEEE80211_HW_SIGNAL_*
+ * @noise: noise when receiving this frame, in dBm.
+ * @qual: overall signal quality indication, in percent (0-100).
  * @antenna: antenna used
  * @rate_idx: index of data rate into band's supported rates
  * @flag: %RX_FLAG_*
@@ -351,9 +354,9 @@ struct ieee80211_rx_status {
        u64 mactime;
        enum ieee80211_band band;
        int freq;
-       int ssi;
        int signal;
        int noise;
+       int qual;
        int antenna;
        int rate_idx;
        int flag;
@@ -392,7 +395,8 @@ enum ieee80211_tx_status_flags {
  *     relevant only if IEEE80211_TX_STATUS_AMPDU was set.
  * @ampdu_ack_map: block ack bit map for the aggregation.
  *     relevant only if IEEE80211_TX_STATUS_AMPDU was set.
- * @ack_signal: signal strength of the ACK frame
+ * @ack_signal: signal strength of the ACK frame either in dBm, dB or unspec
+ *     depending on hardware capabilites flags @IEEE80211_HW_SIGNAL_*
  */
 struct ieee80211_tx_status {
        struct ieee80211_tx_control control;
@@ -703,6 +707,25 @@ enum ieee80211_tkip_key_type {
  * @IEEE80211_HW_2GHZ_SHORT_PREAMBLE_INCAPABLE:
  *     Hardware is not capable of receiving frames with short preamble on
  *     the 2.4 GHz band.
+ *
+ * @IEEE80211_HW_SIGNAL_UNSPEC:
+ *     Hardware can provide signal values but we don't know its units. We
+ *     expect values between 0 and @max_signal.
+ *     If possible please provide dB or dBm instead.
+ *
+ * @IEEE80211_HW_SIGNAL_DB:
+ *     Hardware gives signal values in dB, decibel difference from an
+ *     arbitrary, fixed reference. We expect values between 0 and @max_signal.
+ *     If possible please provide dBm instead.
+ *
+ * @IEEE80211_HW_SIGNAL_DBM:
+ *     Hardware gives signal values in dBm, decibel difference from
+ *     one milliwatt. This is the preferred method since it is standardized
+ *     between different devices. @max_signal does not need to be set.
+ *
+ * @IEEE80211_HW_NOISE_DBM:
+ *     Hardware can provide noise (radio interference) values in units dBm,
+ *      decibel difference from one milliwatt.
  */
 enum ieee80211_hw_flags {
        IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE           = 1<<0,
@@ -710,6 +733,10 @@ enum ieee80211_hw_flags {
        IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING        = 1<<2,
        IEEE80211_HW_2GHZ_SHORT_SLOT_INCAPABLE          = 1<<3,
        IEEE80211_HW_2GHZ_SHORT_PREAMBLE_INCAPABLE      = 1<<4,
+       IEEE80211_HW_SIGNAL_UNSPEC                      = 1<<5,
+       IEEE80211_HW_SIGNAL_DB                          = 1<<6,
+       IEEE80211_HW_SIGNAL_DBM                         = 1<<7,
+       IEEE80211_HW_NOISE_DBM                          = 1<<8,
 };
 
 /**
@@ -740,12 +767,8 @@ enum ieee80211_hw_flags {
  *
  * @channel_change_time: time (in microseconds) it takes to change channels.
  *
- * @max_rssi: Maximum value for ssi in RX information, use
- *     negative numbers for dBm and 0 to indicate no support.
- *
- * @max_signal: like @max_rssi, but for the signal value.
- *
- * @max_noise: like @max_rssi, but for the noise value.
+ * @max_signal: Maximum value for signal (rssi) in RX information, used
+ *     only when @IEEE80211_HW_SIGNAL_UNSPEC or @IEEE80211_HW_SIGNAL_DB
  *
  * @queues: number of available hardware transmit queues for
  *     data packets. WMM/QoS requires at least four, these
@@ -775,9 +798,7 @@ struct ieee80211_hw {
        int channel_change_time;
        int vif_data_size;
        u16 queues, ampdu_queues;
-       s8 max_rssi;
        s8 max_signal;
-       s8 max_noise;
 };
 
 /**
index 200ee1e6372878787c46b63227dff24642806ffe..69dbc342a4649271341946341b6231495e293c91 100644 (file)
@@ -391,7 +391,7 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
 
                wstats.updated = 0;
                if (rx_stats->mask & IEEE80211_STATMASK_RSSI) {
-                       wstats.level = rx_stats->rssi;
+                       wstats.level = rx_stats->signal;
                        wstats.updated |= IW_QUAL_LEVEL_UPDATED;
                } else
                        wstats.updated |= IW_QUAL_LEVEL_INVALID;
index 1f00273d99c285a5646431dd986a312c8bd3c19b..a2cc0284c9d087203ca88925ad9570c080f91b58 100644 (file)
@@ -63,8 +63,8 @@ STA_FILE(tx_fragments, tx_fragments, LU);
 STA_FILE(tx_filtered, tx_filtered_count, LU);
 STA_FILE(tx_retry_failed, tx_retry_failed, LU);
 STA_FILE(tx_retry_count, tx_retry_count, LU);
-STA_FILE(last_rssi, last_rssi, D);
 STA_FILE(last_signal, last_signal, D);
+STA_FILE(last_qual, last_qual, D);
 STA_FILE(last_noise, last_noise, D);
 STA_FILE(channel_use, channel_use, D);
 STA_FILE(wep_weak_iv_count, wep_weak_iv_count, LU);
index 173b7fcb302954b8a712383b3ba8c958186da537..ed0d9b35ae6f6d161922f0ddb2df83a192bdbc3b 100644 (file)
@@ -82,7 +82,7 @@ struct ieee80211_sta_bss {
        u16 capability; /* host byte order */
        enum ieee80211_band band;
        int freq;
-       int rssi, signal, noise;
+       int signal, noise, qual;
        u8 *wpa_ie;
        size_t wpa_ie_len;
        u8 *rsn_ie;
index f277407f0f5a848d3484036f5e4a992d84903b20..390df48dfd40cff94521787006141db716e6ddbf 100644 (file)
@@ -1702,13 +1702,13 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
 
        local->hw.conf.beacon_int = 1000;
 
-       local->wstats_flags |= local->hw.max_rssi ?
-                              IW_QUAL_LEVEL_UPDATED : IW_QUAL_LEVEL_INVALID;
-       local->wstats_flags |= local->hw.max_signal ?
+       local->wstats_flags |= local->hw.flags & (IEEE80211_HW_SIGNAL_UNSPEC |
+                                                 IEEE80211_HW_SIGNAL_DB |
+                                                 IEEE80211_HW_SIGNAL_DBM) ?
                               IW_QUAL_QUAL_UPDATED : IW_QUAL_QUAL_INVALID;
-       local->wstats_flags |= local->hw.max_noise ?
+       local->wstats_flags |= local->hw.flags & IEEE80211_HW_NOISE_DBM ?
                               IW_QUAL_NOISE_UPDATED : IW_QUAL_NOISE_INVALID;
-       if (local->hw.max_rssi < 0 || local->hw.max_noise < 0)
+       if (local->hw.flags & IEEE80211_HW_SIGNAL_DBM)
                local->wstats_flags |= IW_QUAL_DBM;
 
        result = sta_info_start(local);
index 6c4b27be35da241187d652facf124334e1318b64..dda30e98aa1e6d0af837be7f339d05f481190220 100644 (file)
@@ -1959,8 +1959,8 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
                                           local->hw.conf.channel->center_freq,
                                           ifsta->ssid, ifsta->ssid_len);
                if (bss) {
-                       sta->last_rssi = bss->rssi;
                        sta->last_signal = bss->signal;
+                       sta->last_qual = bss->qual;
                        sta->last_noise = bss->noise;
                        ieee80211_rx_bss_put(dev, bss);
                }
@@ -2629,9 +2629,9 @@ static void ieee80211_rx_bss_info(struct net_device *dev,
 
        bss->timestamp = beacon_timestamp;
        bss->last_update = jiffies;
-       bss->rssi = rx_status->ssi;
        bss->signal = rx_status->signal;
        bss->noise = rx_status->noise;
+       bss->qual = rx_status->qual;
        if (!beacon && !bss->probe_resp)
                bss->probe_resp = true;
 
@@ -3427,9 +3427,9 @@ static int ieee80211_sta_config_auth(struct net_device *dev,
                    !ieee80211_sta_match_ssid(ifsta, bss->ssid, bss->ssid_len))
                        continue;
 
-               if (!selected || top_rssi < bss->rssi) {
+               if (!selected || top_rssi < bss->signal) {
                        selected = bss;
-                       top_rssi = bss->rssi;
+                       top_rssi = bss->signal;
                }
        }
        if (selected)
@@ -4060,8 +4060,8 @@ ieee80211_sta_scan_result(struct net_device *dev,
 
        memset(&iwe, 0, sizeof(iwe));
        iwe.cmd = IWEVQUAL;
-       iwe.u.qual.qual = bss->signal;
-       iwe.u.qual.level = bss->rssi;
+       iwe.u.qual.qual = bss->qual;
+       iwe.u.qual.level = bss->signal;
        iwe.u.qual.noise = bss->noise;
        iwe.u.qual.updated = local->wstats_flags;
        current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe,
index b399e09ec7aa04aabe93a3430a2359cdbb34246f..474f13662c8428bb83386f8bdda140811c1a66e6 100644 (file)
@@ -209,7 +209,7 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb,
                                cpu_to_le16(IEEE80211_CHAN_DYN |
                                            IEEE80211_CHAN_2GHZ);
 
-               rtfixed->antsignal = status->ssi;
+               rtfixed->antsignal = status->signal;
                rthdr->it_len = cpu_to_le16(rtap_len);
        }
 
@@ -719,8 +719,8 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx)
 
        sta->rx_fragments++;
        sta->rx_bytes += rx->skb->len;
-       sta->last_rssi = rx->status->ssi;
        sta->last_signal = rx->status->signal;
+       sta->last_qual = rx->status->qual;
        sta->last_noise = rx->status->noise;
 
        if (!(rx->fc & IEEE80211_FCTL_MOREFRAGS)) {
index 97a61c39ad90d25d8bbd609df012f1841ff601bc..e89cc1655547398d0dbefb2242cbfb355807f8ad 100644 (file)
@@ -216,8 +216,8 @@ struct sta_info {
                                       * from this STA */
        unsigned long rx_fragments; /* number of received MPDUs */
        unsigned long rx_dropped; /* number of dropped MPDUs from this STA */
-       int last_rssi; /* RSSI of last received frame from this STA */
        int last_signal; /* signal of last received frame from this STA */
+       int last_qual;  /* qual of last received frame from this STA */
        int last_noise; /* noise of last received frame from this STA */
        /* last received seq/frag number from this STA (per RX queue) */
        __le16 last_seq_ctrl[NUM_RX_DATA_QUEUES];
index 76e1de1dc735d959e62527132bad490a3e005513..6a342a9a40cd805609277d309b0b51bd46daee16 100644 (file)
@@ -169,14 +169,26 @@ static int ieee80211_ioctl_giwrange(struct net_device *dev,
        range->num_encoding_sizes = 2;
        range->max_encoding_tokens = NUM_DEFAULT_KEYS;
 
-       range->max_qual.qual = local->hw.max_signal;
-       range->max_qual.level = local->hw.max_rssi;
-       range->max_qual.noise = local->hw.max_noise;
+       if (local->hw.flags & IEEE80211_HW_SIGNAL_UNSPEC ||
+           local->hw.flags & IEEE80211_HW_SIGNAL_DB)
+               range->max_qual.level = local->hw.max_signal;
+       else if  (local->hw.flags & IEEE80211_HW_SIGNAL_DBM)
+               range->max_qual.level = -110;
+       else
+               range->max_qual.level = 0;
+
+       if (local->hw.flags & IEEE80211_HW_NOISE_DBM)
+               range->max_qual.noise = -110;
+       else
+               range->max_qual.noise = 0;
+
+       range->max_qual.qual = 100;
        range->max_qual.updated = local->wstats_flags;
 
-       range->avg_qual.qual = local->hw.max_signal/2;
-       range->avg_qual.level = 0;
-       range->avg_qual.noise = 0;
+       range->avg_qual.qual = 50;
+       /* not always true but better than nothing */
+       range->avg_qual.level = range->max_qual.level / 2;
+       range->avg_qual.noise = range->max_qual.noise / 2;
        range->avg_qual.updated = local->wstats_flags;
 
        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
                wstats->qual.noise = 0;
                wstats->qual.updated = IW_QUAL_ALL_INVALID;
        } else {
-               wstats->qual.level = sta->last_rssi;
-               wstats->qual.qual = sta->last_signal;
+               wstats->qual.level = sta->last_signal;
+               wstats->qual.qual = sta->last_qual;
                wstats->qual.noise = sta->last_noise;
                wstats->qual.updated = local->wstats_flags;
        }