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 */