Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1796513
  • 博文数量: 306
  • 博客积分: 3133
  • 博客等级: 中校
  • 技术积分: 3932
  • 用 户 组: 普通用户
  • 注册时间: 2009-04-19 16:50
文章分类

全部博文(306)

文章存档

2018年(7)

2017年(18)

2016年(39)

2015年(35)

2014年(52)

2013年(39)

2012年(22)

2011年(29)

2010年(53)

2009年(12)

分类: LINUX

2014-05-22 16:41:01

原文地址:RSSI in wifi 作者:疯也枉然

iwconfig ath0

ath0      IEEE 802.11ng ESSID:"Atheros_AP51"

.......

          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,

* , or .   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 这只是个理论值,在实际的环境中 估计还要乘个不小的系数呢。

阅读(1343) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~