nl80211: add htmode to iwinfo_ops
authorDaniel Danzberger <daniel@dd-wrt.com>
Thu, 19 Dec 2019 14:41:24 +0000 (15:41 +0100)
committerHauke Mehrtens <hauke@hauke-m.de>
Sun, 5 Jan 2020 16:17:40 +0000 (17:17 +0100)
This callback shows the currently active HTMODE of the device.

Signed-off-by: Daniel Danzberger <daniel@dd-wrt.com>
include/iwinfo.h
iwinfo_nl80211.c

index d035c9c89a596cbb8f5d105303747b5f14307ffb..5e64294392901308dcfa344197e67129fd326ef6 100644 (file)
@@ -88,8 +88,9 @@ enum iwinfo_htmode {
        IWINFO_HTMODE_VHT80      = (1 << 4),
        IWINFO_HTMODE_VHT80_80   = (1 << 5),
        IWINFO_HTMODE_VHT160     = (1 << 6),
+       IWINFO_HTMODE_NOHT       = (1 << 7),
 
-       IWINFO_HTMODE_COUNT      = 7
+       IWINFO_HTMODE_COUNT      = 8
 };
 
 extern const char *IWINFO_HTMODE_NAMES[IWINFO_HTMODE_COUNT];
@@ -231,6 +232,7 @@ struct iwinfo_ops {
        int (*mbssid_support)(const char *, int *);
        int (*hwmodelist)(const char *, int *);
        int (*htmodelist)(const char *, int *);
+       int (*htmode)(const char *, int *);
        int (*ssid)(const char *, char *);
        int (*bssid)(const char *, char *);
        int (*country)(const char *, char *);
index 5990c782184063483d7fc0512a45b6c84c071e74..2b2a04386ee5faf8a38f8601d991795f503597c5 100644 (file)
@@ -2958,6 +2958,75 @@ out:
        return -1;
 }
 
+struct chan_info {
+       int width;
+       int mode;
+};
+
+static int nl80211_get_htmode_cb(struct nl_msg *msg, void *arg)
+{
+       struct nlattr **tb = nl80211_parse(msg);
+       struct nlattr *cur;
+       struct chan_info *chn = arg;
+
+       if ((cur = tb[NL80211_ATTR_CHANNEL_WIDTH]))
+               chn->width = nla_get_u32(cur);
+
+       if ((cur = tb[NL80211_ATTR_BSS_HT_OPMODE]))
+               chn->mode = nla_get_u32(cur);
+
+       return NL_SKIP;
+}
+
+static int nl80211_get_htmode(const char *ifname, int *buf)
+{
+       struct chan_info chn = { .width = 0, .mode = 0 };
+       char *res;
+       int err;
+
+       res = nl80211_phy2ifname(ifname);
+       *buf = 0;
+
+       err =  nl80211_request(res ? res : ifname,
+                               NL80211_CMD_GET_INTERFACE, 0,
+                               nl80211_get_htmode_cb, &chn);
+       if (err)
+               return -1;
+
+       switch (chn.width) {
+       case NL80211_CHAN_WIDTH_20:
+               if (chn.mode == -1)
+                       *buf = IWINFO_HTMODE_VHT20;
+               else
+                       *buf = IWINFO_HTMODE_HT20;
+               break;
+       case NL80211_CHAN_WIDTH_40:
+               if (chn.mode == -1)
+                       *buf = IWINFO_HTMODE_VHT40;
+               else
+                       *buf = IWINFO_HTMODE_HT40;
+               break;
+       case NL80211_CHAN_WIDTH_80:
+               *buf = IWINFO_HTMODE_VHT80;
+               break;
+       case NL80211_CHAN_WIDTH_80P80:
+               *buf = IWINFO_HTMODE_VHT80_80;
+               break;
+       case NL80211_CHAN_WIDTH_160:
+               *buf = IWINFO_HTMODE_VHT160;
+               break;
+       case NL80211_CHAN_WIDTH_5:
+       case NL80211_CHAN_WIDTH_10:
+       case NL80211_CHAN_WIDTH_20_NOHT:
+               *buf = IWINFO_HTMODE_NOHT;
+               break;
+       default:
+               return -1;
+       }
+
+       return 0;
+}
+
 static int nl80211_get_htmodelist(const char *ifname, int *buf)
 {
        struct nl80211_modes m = { 0 };
@@ -3147,6 +3216,7 @@ const struct iwinfo_ops nl80211_ops = {
        .mbssid_support   = nl80211_get_mbssid_support,
        .hwmodelist       = nl80211_get_hwmodelist,
        .htmodelist       = nl80211_get_htmodelist,
+       .htmode           = nl80211_get_htmode,
        .mode             = nl80211_get_mode,
        .ssid             = nl80211_get_ssid,
        .bssid            = nl80211_get_bssid,