else
range->max_qual.noise = 0;
- range->max_qual.qual = 100;
range->max_qual.updated = ieee80211_get_wstats_flags(local);
- range->avg_qual.qual = 50;
+ if (local->hw.flags & IEEE80211_HW_SIGNAL_DBM) {
+ /*
+ * cfg80211 assumes -110 to -40 dBm and clamps to that range
+ * for qual.qual, so tell userspace this is what we give it
+ * but take into account that we have to start from 0.
+ */
+ range->max_qual.qual = 70;
+ range->avg_qual.qual = 35;
+ } else {
+ /*
+ * cfg80211 just uses the level value for qual too, and it
+ * requires the level value to be 0 .. 100.
+ */
+ range->max_qual.qual = 100;
+ 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;
struct iw_event iwe;
u8 *buf, *cfg, *p;
u8 *ie = bss->pub.information_elements;
- int rem = bss->pub.len_information_elements, i;
+ int rem = bss->pub.len_information_elements, i, sig;
bool ismesh = false;
memset(&iwe, 0, sizeof(iwe));
iwe.cmd = IWEVQUAL;
iwe.u.qual.updated = IW_QUAL_LEVEL_UPDATED |
IW_QUAL_NOISE_INVALID |
- IW_QUAL_QUAL_INVALID;
+ IW_QUAL_QUAL_UPDATED;
switch (bss->pub.signal_type) {
case CFG80211_SIGNAL_TYPE_MBM:
- iwe.u.qual.level = bss->pub.signal / 100;
+ sig = bss->pub.signal / 100;
+ iwe.u.qual.level = sig;
iwe.u.qual.updated |= IW_QUAL_DBM;
+ if (sig < -110) /* rather bad */
+ sig = -110;
+ else if (sig > -40) /* perfect */
+ sig = -40;
+ /* will give a range of 0 .. 70 */
+ iwe.u.qual.qual = sig + 110;
break;
case CFG80211_SIGNAL_TYPE_UNSPEC:
iwe.u.qual.level = bss->pub.signal;
+ /* will give range 0 .. 100 */
+ iwe.u.qual.qual = bss->pub.signal;
break;
default:
/* not reached */