RSSI in madwifi


最近家裏無線信號很差,於是就學習一下madwifi中的rssi。
看一下iwconfig ath0裏面的信號參數是怎麼搞出來的。

iwconfig ath0

ath0      IEEE 802.11ng  ESSID:"Atheros_AP51" 

          Mode:Managed  Frequency:2.412 GHz  Access Point: 00:1F:33:F7:5E:27  

          Bit Rate:1 Mb/s   Tx-Power:17 dBm   Sensitivity=0/3 

          Retry:off   RTS thr:off   Fragment thr:off

          Encryption key:off

          Power Management:off

          Link Quality=79/94  Signal level=-16 dBm  Noise level=-95 dBm

          Rx invalid nwid:709  Rx invalid crypt:0  Rx invalid frag:0

          Tx excessive retries:0  Invalid misc:0   Missed beacon:0

 

比較關心紅色的結果的由來。

大致流程:

wireless tool   iwconfig.c

       iw_enum_devices Extract interface name     

       print_info

       get_info

       iw_get_stats

iw_get_ext      ioctl SIOCGIWSTATS

display_info

iw_print_stats

         sprintf(buffer,

                "Quality:%d/%d  Signal level:%d dBm  Noise level:%d dBm%s",

                qual->qual, range->max_qual.qual,

                qual->level - 0x100, qual->noise - 0x100,

                (qual->updated & 0x7) ? " (updated)" : "");

kernel      net/core/wireless.c

wireless_process_ioctl  

dev_iwstats (case SIOCGIWSTATS)

       get_wireless_stats 

dev->get_wireless_stats(dev)

madwifi

       ieee80211_ioctl_vattach

       dev->get_wireless_stats = ieee80211_iw_getstats

       set_quality

 

set_quality(struct iw_quality *iq, u_int rssi, __u8 noise)

{

       iq->qual = rssi;

       /* NB: max is 94 because noise is hardcoded to 161 */

       if (iq->qual > 94)

              iq->qual = 94;

 

       iq->noise = noise;         

/* This noise is read from the ieee80211com which is updated by the ath layer,

  * and the callback function of the ath layer points back to the function

  * in the hal layer, in dBm, an thus being casted into __u8.

  */  

       iq->level = iq->noise + iq->qual;

       iq->updated = 7;

}

Link Quality=79/94  Signal level=-16 dBm  Noise level=-95 dBm

 

最關鍵的就是 rssi noise 這兩個東西是從哪裏來的,先看看作者的註釋

/*

  * Units are in db above the noise floor. That means the

  * rssi values reported in the tx/rx descriptors in the

  * driver are the SNR expressed in db.

  *

  * If you assume that the noise floor is -95, which is an

  * excellent assumption 99.5 % of the time, then you can

  * derive the absolute signal level (i.e. -95 + rssi).

  * There are some other slight factors to take into account

  * depending on whether the rssi measurement is from 11b,

  * 11g, or 11a.   These differences are at most 2db and

  * can be documented.

  *

  * NB: various calculations are based on the orinoco/wavelan

  *     drivers for compatibility

  */

 

看代碼:

ieee80211_getrssi

       case IEEE80211_M_STA:             /* use stats from associated ap */

       default:

              TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next)

                     if (vap->iv_bss != NULL) {

                            rssi_samples++;

                            rssi_total += ic->ic_node_getrssi(vap->iv_bss);

                     }

              break;

       }

ic->ic_node_getrssi = ath_node_getrssi;

 

這個函數把 avgrssi 圓整一下。

ath_node_getrssi ()

{

#define    HAL_EP_RND(x, mul) /

       ((((x)%(mul)) >= ((mul)/2)) ? ((x) + ((mul) - 1)) / (mul) : (x)/(mul))

       int32_t avgrssi = ATH_NODE_CONST(ni)->an_avgrssi;

       int32_t rssi;

 

       /*

         * When only one frame is received there will be no state in

         * avgrssi so fallback on the value recorded by the 802.11 layer.

         */

       if (avgrssi != ATH_RSSI_DUMMY_MARKER)

              rssi = HAL_EP_RND(avgrssi, HAL_RSSI_EP_MULTIPLIER);

       else

              rssi = ni->ni_rssi;

       /* NB: theoretically we shouldn't need this, but be paranoid */

      return rssi;

#undef HAL_EP_RND

}

 

Avgrssi 來自哪裏呢?

來自 ath_rx_poll

ATH_RSSI_LPF(an->an_avgrssi, rxstat->rs_rssi);

其中 rxstat->rs_rssi 就是 descriptor 中提取出來的,

ds->ds_rxstat->rs_rssi = MS(ads->ds_rxstatus0, AR_RcvSigStrength);

MS 宏的作用是把 rssi descriptor 中取出來,根據 AR5416 datasheet 11n 2T3R 配置有 3 rssi 8bit 範圍就是 0~127 0x80 是不合法的值。

ds->ds_rxstat->rs_rssi = MS(ads->ds_rxstatus0, AR_RcvSigStrength);

ATH_RSSI_LPF(an->an_avgrssi, rxstat->rs_rssi);

 

#define    HAL_RSSI_EP_MULTIPLIER      (1<<7)    /* pow2 to optimize out * and / */

#define ATH_RSSI_LPF_LEN       10

#define ATH_RSSI_DUMMY_MARKER      0x127

#define ATH_EP_MUL(x, mul)      ((x) * (mul))

#define ATH_RSSI_IN(x)             (ATH_EP_MUL((x), HAL_RSSI_EP_MULTIPLIER))

#define ATH_LPF_RSSI(x, y, len) /

    ((x != ATH_RSSI_DUMMY_MARKER) ? (((x) * ((len) - 1) + (y)) / (len)) : (y))

#define ATH_RSSI_LPF(x, y) do {                                          /

    if ((y) >= -20)                                           /

           x = ATH_LPF_RSSI((x), ATH_RSSI_IN((y)), ATH_RSSI_LPF_LEN);      /

} while (0)

 

好複雜的變換,不知道美國人搞那麼複雜幹什麼,他們不是連加法都要用計算器的嗎?

舉個例子吧,假設驅動開始兩次 rx_poll Descriptor 中的 rssi 0x60 0x60

開始 an->an_avgrssi=0x127 不合法的值。

第一次計算:

ATH_RSSI_LPF(an->an_avgrssi, 0x60)

       x= an->an_avgrssi;

       x = ATH_LPF_RSSI((x), ATH_RSSI_IN((0x60)), 10);

       an->an_avgrssi =0x60*(1<<7)=0x3000;

 

第二次計算:

       ATH_RSSI_LPF(an->an_avgrssi, 0x60)

x = ATH_LPF_RSSI((0x3000), ATH_RSSI_IN((60)), 10);

  = ATH_LPF_RSSI((0x3000), 0x3000, 10);

= (0x3000*9+0x3000)/0x3000=10

 

總結一下:

1.    Rx Descriptor 中的 rssi(0 ~ 127)

2.    ATH_RSSI_LPF rssi 轉化爲 avgrssi

3.    ath_node_getrssi avgrssi 圓整後報告給上層。

 

圓整後的 avgrssi 的意義: SNR 即信噪比 噪聲功率通常假設爲 -95dbm 那麼信號功率就是: -95dbm + avgrssi

 

那麼信號強度和傳輸速率的關係是什麼呢,香儂定理可以回答這個問題。
54Mbps需要的SNR是7.4db 這只是個理論值,在實際的環境中 估計還要乘個不小的係數呢。

zz from http://blog.chinaunix.net/u2/83623/showart_1863143.html
發佈了17 篇原創文章 · 獲贊 3 · 訪問量 10萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章