Here's what I found in the kernel source's iwl3945-base.c file:

/* Convert linear signal-to-noise ratio into dB */
static u8 ratio2dB[100] = {
/*       0   1   2   3   4   5   6   7   8   9 */
         0,  0,  6, 10, 12, 14, 16, 17, 18, 19, /* 00 - 09 */
        20, 21, 22, 22, 23, 23, 24, 25, 26, 26, /* 10 - 19 */
        26, 26, 26, 27, 27, 28, 28, 28, 29, 29, /* 20 - 29 */
        29, 30, 30, 30, 31, 31, 31, 31, 32, 32, /* 30 - 39 */
        32, 32, 32, 33, 33, 33, 33, 33, 34, 34, /* 40 - 49 */
        34, 34, 34, 34, 35, 35, 35, 35, 35, 35, /* 50 - 59 */
        36, 36, 36, 36, 36, 36, 36, 37, 37, 37, /* 60 - 69 */
        37, 37, 37, 37, 37, 38, 38, 38, 38, 38, /* 70 - 79 */
        38, 38, 38, 38, 38, 39, 39, 39, 39, 39, /* 80 - 89 */
        39, 39, 39, 39, 39, 40, 40, 40, 40, 40  /* 90 - 99 */
};

/* Calculates a relative dB value from a ratio of linear
 *   (i.e. not dB) signal levels.
 * Conversion assumes that levels are voltages (20*log), not powers (10*log). */
int iwl3945_calc_db_from_ratio(int sig_ratio)
{
        /* 1000:1 or higher just report as 60 dB */
        if (sig_ratio >= 1000)
                return 60;

        /* 100:1 or higher, divide by 10 and use table,
         *   add 20 dB to make up for divide by 10 */
        if (sig_ratio >= 100)
                return (20 + (int)ratio2dB[sig_ratio/10]);

        /* We shouldn't see this */
        if (sig_ratio < 1)
                return 0;

        /* Use table for ratios 1:1 - 99:1 */
        return (int)ratio2dB[sig_ratio];
}

#define PERFECT_RSSI (-20) /* dBm */
#define WORST_RSSI (-95)   /* dBm */
#define RSSI_RANGE (PERFECT_RSSI - WORST_RSSI)

/* Calculate an indication of rx signal quality (a percentage, not dBm!).
 * See http://www.ces.clemson.edu/linux/signal_quality.shtml for info
 *   about formulas used below. */
int iwl3945_calc_sig_qual(int rssi_dbm, int noise_dbm)
{
        int sig_qual;
        int degradation = PERFECT_RSSI - rssi_dbm;

        /* If we get a noise measurement, use signal-to-noise ratio (SNR)
         * as indicator; formula is (signal dbm - noise dbm).
         * SNR at or above 40 is a great signal (100%).
         * Below that, scale to fit SNR of 0 - 40 dB within 0 - 100% indicator.
         * Weakest usable signal is usually 10 - 15 dB SNR. */
        if (noise_dbm) {
                if (rssi_dbm - noise_dbm >= 40)
                        return 100;
                else if (rssi_dbm < noise_dbm)
                        return 0;
                sig_qual = ((rssi_dbm - noise_dbm) * 5) / 2;

        /* Else use just the signal level.
         * This formula is a least squares fit of data points collected and
         *   compared with a reference system that had a percentage (%) display
         *   for signal quality. */
        } else
                sig_qual = (100 * (RSSI_RANGE * RSSI_RANGE) - degradation *
                            (15 * RSSI_RANGE + 62 * degradation)) /
                           (RSSI_RANGE * RSSI_RANGE);

        if (sig_qual > 100)
                sig_qual = 100;
        else if (sig_qual < 1)
                sig_qual = 0;

        return sig_qual;
}

-- 
iwl3945 sometimes does not detect ESSIDs, whereas ipw3945 works perfectly
https://bugs.launchpad.net/bugs/177624
You received this bug notification because you are a member of Ubuntu
Bugs, which is subscribed to Ubuntu.

-- 
ubuntu-bugs mailing list
[email protected]
https://lists.ubuntu.com/mailman/listinfo/ubuntu-bugs

Reply via email to