kernel: fq_codel: dont reinit flow state
[openwrt/staging/stintel.git] / package / iwinfo / src / iwinfo_nl80211.c
index 528615079a4b5f0730968d872ecf9beb9e22eef3..304a18b3ecb8582ad204b456adf5cd3ba3d28bdc 100644 (file)
@@ -351,6 +351,20 @@ static int nl80211_freq2channel(int freq)
        return (freq / 5) - 1000;
 }
 
+static int nl80211_channel2freq(int channel, const char *band)
+{
+       if (channel == 14)
+               return 2484;
+
+       if ((channel < 14) && (!band || band[0] != 'a'))
+               return (channel * 5) + 2407;
+
+       if (channel > 0)
+               return (1000 + channel) * 5;
+
+       return 0;
+}
+
 static char * nl80211_getval(const char *ifname, const char *buf, const char *key)
 {
        int i, len;
@@ -700,7 +714,7 @@ void nl80211_close(void)
        }
 }
 
-int nl80211_get_mode(const char *ifname, char *buf)
+int nl80211_get_mode(const char *ifname, int *buf)
 {
        return wext_get_mode(ifname, buf);
 }
@@ -751,32 +765,68 @@ int nl80211_get_bssid(const char *ifname, char *buf)
        return -1;
 }
 
-int nl80211_get_channel(const char *ifname, int *buf)
+
+static int nl80211_get_frequency_cb(struct nl_msg *msg, void *arg)
 {
-       char *first;
+       int *freq = arg;
+       struct nlattr **attr = nl80211_parse(msg);
+       struct nlattr *binfo[NL80211_BSS_MAX + 1];
 
-       if (!wext_get_channel(ifname, buf))
-               return 0;
+       static struct nla_policy bss_policy[NL80211_BSS_MAX + 1] = {
+               [NL80211_BSS_FREQUENCY] = { .type = NLA_U32 },
+       };
 
-       else if ((first = nl80211_phy2ifname(nl80211_ifname2phy(ifname))) != NULL)
-               return wext_get_channel(first, buf);
+       if (attr[NL80211_ATTR_BSS] &&
+           !nla_parse_nested(binfo, NL80211_BSS_MAX,
+                             attr[NL80211_ATTR_BSS], bss_policy))
+       {
+               if (binfo[NL80211_BSS_FREQUENCY])
+                       *freq = nla_get_u32(binfo[NL80211_BSS_FREQUENCY]);
+       }
 
-       return -1;
+       return NL_SKIP;
 }
 
 int nl80211_get_frequency(const char *ifname, int *buf)
 {
-       char *first;
+       char *res, *channel;
+       struct nl80211_msg_conveyor *req;
 
-       if (!wext_get_frequency(ifname, buf))
-               return 0;
+       *buf = 0;
 
-       else if ((first = nl80211_phy2ifname(nl80211_ifname2phy(ifname))) != NULL)
-               return wext_get_frequency(first, buf);
+       if ((res = nl80211_hostapd_info(ifname)) &&
+           (channel = nl80211_getval(NULL, res, "channel")))
+       {
+               *buf = nl80211_channel2freq(atoi(channel),
+                                           nl80211_getval(NULL, res, "hw_mode"));
+       }
+       else
+       {
+               res = nl80211_phy2ifname(ifname);
+               req = nl80211_msg(res ? res : ifname, NL80211_CMD_GET_SCAN, NLM_F_DUMP);
+
+               if (req)
+               {
+                       nl80211_send(req, nl80211_get_frequency_cb, buf);
+                       nl80211_free(req);
+               }
+       }
+
+       return (*buf == 0) ? -1 : 0;
+}
+
+int nl80211_get_channel(const char *ifname, int *buf)
+{
+       if (!nl80211_get_frequency(ifname, buf))
+       {
+               *buf = nl80211_freq2channel(*buf);
+               return 0;
+       }
 
        return -1;
 }
 
+
 int nl80211_get_txpower(const char *ifname, int *buf)
 {
        return wext_get_txpower(ifname, buf);
@@ -1371,7 +1421,7 @@ int nl80211_get_txpwrlist(const char *ifname, char *buf, int *len)
                nl80211_free(req);
        }
 
-       if (dbm_max > -1)
+       if (dbm_max > 0)
        {
                for (dbm_cur = 0, dbm_cnt = 0;
                     dbm_cur < dbm_max;
@@ -1525,9 +1575,9 @@ static int nl80211_get_scanlist_cb(struct nl_msg *msg, void *arg)
        memcpy(sl->e->mac, nla_data(bss[NL80211_BSS_BSSID]), 6);
 
        if (caps & (1<<1))
-               memcpy(sl->e->mode, "Ad-Hoc", 6);
+               sl->e->mode = IWINFO_OPMODE_ADHOC;
        else
-               memcpy(sl->e->mode, "Master", 6);
+               sl->e->mode = IWINFO_OPMODE_MASTER;
 
        if (caps & (1<<4))
                sl->e->crypto.enabled = 1;
@@ -1541,7 +1591,8 @@ static int nl80211_get_scanlist_cb(struct nl_msg *msg, void *arg)
 
        if (bss[NL80211_BSS_SIGNAL_MBM])
        {
-               sl->e->signal = nla_get_u32(bss[NL80211_BSS_SIGNAL_MBM]) / 100;
+               sl->e->signal =
+                       (uint8_t)((int32_t)nla_get_u32(bss[NL80211_BSS_SIGNAL_MBM]) / 100);
 
                rssi = sl->e->signal - 0x100;
 
@@ -1568,7 +1619,6 @@ static int nl80211_get_scanlist_cb(struct nl_msg *msg, void *arg)
 
 static int nl80211_get_scanlist_nl(const char *ifname, char *buf, int *len)
 {
-       struct nl_msg *ssids = NULL;
        struct nl80211_msg_conveyor *req;
        struct nl80211_scanlist sl = { .e = (struct iwinfo_scanlist_entry *)buf };
 
@@ -1590,11 +1640,6 @@ static int nl80211_get_scanlist_nl(const char *ifname, char *buf, int *len)
 
        *len = sl.len * sizeof(struct iwinfo_scanlist_entry);
        return *len ? 0 : -1;
-
-nla_put_failure:
-       if (ssids)
-               nlmsg_free(ssids);
-       return -1;
 }
 
 int nl80211_get_scanlist(const char *ifname, char *buf, int *len)
@@ -1652,7 +1697,7 @@ int nl80211_get_scanlist(const char *ifname, char *buf, int *len)
                                memcpy(e->ssid, ssid, min(strlen(ssid), sizeof(e->ssid) - 1));
 
                                /* Mode (assume master) */
-                               sprintf((char *)e->mode, "Master");
+                               e->mode = IWINFO_OPMODE_MASTER;
 
                                /* Channel */
                                e->channel = nl80211_freq2channel(freq);
@@ -1685,7 +1730,7 @@ int nl80211_get_scanlist(const char *ifname, char *buf, int *len)
                                nl80211_get_scancrypto(cipher, &e->crypto);
 
                                /* advance to next line */
-                               while( *res && *res++ != '\n' );
+                               while (*res && *res++ != '\n');
 
                                count++;
                                e++;