]> git.karo-electronics.de Git - mv-sheeva.git/blobdiff - drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
brcm80211: moved power conversion functions
[mv-sheeva.git] / drivers / net / wireless / brcm80211 / brcmfmac / wl_cfg80211.c
index 27a748e5503635a295eca00dbf51a7827f1d3387..db9176d2d86a1857cbc1fac070de27bca08126a3 100644 (file)
@@ -247,6 +247,90 @@ static const u32 __wl_cipher_suites[] = {
        WLAN_CIPHER_SUITE_AES_CMAC,
 };
 
+/* Quarter dBm units to mW
+ * Table starts at QDBM_OFFSET, so the first entry is mW for qdBm=153
+ * Table is offset so the last entry is largest mW value that fits in
+ * a u16.
+ */
+
+#define QDBM_OFFSET 153                /* Offset for first entry */
+#define QDBM_TABLE_LEN 40      /* Table size */
+
+/* Smallest mW value that will round up to the first table entry, QDBM_OFFSET.
+ * Value is ( mW(QDBM_OFFSET - 1) + mW(QDBM_OFFSET) ) / 2
+ */
+#define QDBM_TABLE_LOW_BOUND 6493      /* Low bound */
+
+/* Largest mW value that will round down to the last table entry,
+ * QDBM_OFFSET + QDBM_TABLE_LEN-1.
+ * Value is ( mW(QDBM_OFFSET + QDBM_TABLE_LEN - 1) +
+ * mW(QDBM_OFFSET + QDBM_TABLE_LEN) ) / 2.
+ */
+#define QDBM_TABLE_HIGH_BOUND 64938    /* High bound */
+
+static const u16 nqdBm_to_mW_map[QDBM_TABLE_LEN] = {
+/* qdBm:       +0      +1      +2      +3      +4      +5      +6      +7 */
+/* 153: */ 6683, 7079, 7499, 7943, 8414, 8913, 9441, 10000,
+/* 161: */ 10593, 11220, 11885, 12589, 13335, 14125, 14962, 15849,
+/* 169: */ 16788, 17783, 18836, 19953, 21135, 22387, 23714, 25119,
+/* 177: */ 26607, 28184, 29854, 31623, 33497, 35481, 37584, 39811,
+/* 185: */ 42170, 44668, 47315, 50119, 53088, 56234, 59566, 63096
+};
+
+static u16 brcmf_qdbm_to_mw(u8 qdbm)
+{
+       uint factor = 1;
+       int idx = qdbm - QDBM_OFFSET;
+
+       if (idx >= QDBM_TABLE_LEN)
+               /* clamp to max u16 mW value */
+               return 0xFFFF;
+
+       /* scale the qdBm index up to the range of the table 0-40
+        * where an offset of 40 qdBm equals a factor of 10 mW.
+        */
+       while (idx < 0) {
+               idx += 40;
+               factor *= 10;
+       }
+
+       /* return the mW value scaled down to the correct factor of 10,
+        * adding in factor/2 to get proper rounding.
+        */
+       return (nqdBm_to_mW_map[idx] + factor / 2) / factor;
+}
+
+static u8 brcmf_mw_to_qdbm(u16 mw)
+{
+       u8 qdbm;
+       int offset;
+       uint mw_uint = mw;
+       uint boundary;
+
+       /* handle boundary case */
+       if (mw_uint <= 1)
+               return 0;
+
+       offset = QDBM_OFFSET;
+
+       /* move mw into the range of the table */
+       while (mw_uint < QDBM_TABLE_LOW_BOUND) {
+               mw_uint *= 10;
+               offset -= 40;
+       }
+
+       for (qdbm = 0; qdbm < QDBM_TABLE_LEN - 1; qdbm++) {
+               boundary = nqdBm_to_mW_map[qdbm] + (nqdBm_to_mW_map[qdbm + 1] -
+                                                   nqdBm_to_mW_map[qdbm]) / 2;
+               if (mw_uint < boundary)
+                       break;
+       }
+
+       qdbm += (u8) offset;
+
+       return qdbm;
+}
+
 /* function for reading/writing a single u32 from/to the dongle */
 static int
 brcmf_exec_dcmd_u32(struct net_device *ndev, u32 cmd, u32 *par)
@@ -1380,7 +1464,7 @@ brcmf_cfg80211_set_tx_power(struct wiphy *wiphy,
        else
                txpwrmw = (u16) dbm;
        err = brcmf_dev_intvar_set(ndev, "qtxpower",
-                       (s32) (brcmu_mw_to_qdbm(txpwrmw)));
+                       (s32) (brcmf_mw_to_qdbm(txpwrmw)));
        if (err)
                WL_ERR("qtxpower error (%d)\n", err);
        cfg_priv->conf->tx_power = dbm;
@@ -1409,7 +1493,7 @@ static s32 brcmf_cfg80211_get_tx_power(struct wiphy *wiphy, s32 *dbm)
        }
 
        result = (u8) (txpwrdbm & ~WL_TXPWR_OVERRIDE);
-       *dbm = (s32) brcmu_qdbm_to_mw(result);
+       *dbm = (s32) brcmf_qdbm_to_mw(result);
 
 done:
        WL_TRACE("Exit\n");