iwinfo: nl80211: fix hwmode parsing for multi-band NICs
authorDavid Bauer <mail@david-bauer.net>
Fri, 22 Apr 2022 21:56:35 +0000 (23:56 +0200)
committerDavid Bauer <mail@david-bauer.net>
Sat, 23 Apr 2022 09:59:29 +0000 (11:59 +0200)
In case a NIC supports multiple frequency bands, the supported
hw-modelist might not contain all valid hwmodes, as B/G/AD hwmodes are
only included based on the last parsed supported frequency.

In case a radio supports multiple bands, this might result in these
hwmodes not being flagged as supported.

Circumvent this by tracking all seen frequency bands using a bitmask
which later determined which HW modes are listed as supported.

Signed-off-by: David Bauer <mail@david-bauer.net>
include/iwinfo.h
iwinfo_nl80211.c

index 8469ee70f5e36342780817236d3994a440e0788e..e9b7451af037e997933c46f6a30a75b6af7504f9 100644 (file)
 #define IWINFO_80211_AD      (1 << 5)
 #define IWINFO_80211_AX      (1 << 6)
 
+#define IWINFO_BAND_24       (1 << 0)
+#define IWINFO_BAND_5        (1 << 1)
+#define IWINFO_BAND_6        (1 << 2)
+#define IWINFO_BAND_60       (1 << 3)
+
 #define IWINFO_CIPHER_NONE   (1 << 0)
 #define IWINFO_CIPHER_WEP40  (1 << 1)
 #define IWINFO_CIPHER_TKIP   (1 << 2)
index c4b0ee2d7f0635a99ab6a3b0e309319e85bcd6a4..5b5deec7c3f5103077530f31121997ccb0b734f4 100644 (file)
@@ -3012,7 +3012,8 @@ struct nl80211_modes
        uint32_t hw;
        uint32_t ht;
 
-       uint32_t nl_freq;
+       uint8_t bands;
+
        uint16_t nl_ht;
        uint32_t nl_vht;
        uint16_t he_phy_cap[6];
@@ -3044,12 +3045,13 @@ static int nl80211_eval_modelist(struct nl80211_modes *m)
                        m->ht |= IWINFO_HTMODE_HE160 | IWINFO_HTMODE_HE80_80;
        }
 
-       if (m->nl_freq < 2485)
+       if (m->bands & IWINFO_BAND_24)
        {
                m->hw |= IWINFO_80211_B;
                m->hw |= IWINFO_80211_G;
        }
-       else if (m->nl_vht)
+
+       if (m->nl_vht)
        {
                /* Treat any nonzero capability as 11ac */
                if (m->nl_vht > 0)
@@ -3068,11 +3070,13 @@ static int nl80211_eval_modelist(struct nl80211_modes *m)
                        }
                }
        }
-       else if (m->nl_freq >= 56160)
+
+       if (m->bands & IWINFO_BAND_60)
        {
                m->hw |= IWINFO_80211_AD;
        }
-       else if (!(m->hw & IWINFO_80211_AC))
+
+       if (!(m->hw & IWINFO_80211_AC))
        {
                m->hw |= IWINFO_80211_A;
        }
@@ -3088,6 +3092,7 @@ static int nl80211_get_modelist_cb(struct nl_msg *msg, void *arg)
        struct nlattr *bands[NL80211_BAND_ATTR_MAX + 1];
        struct nlattr *freqs[NL80211_FREQUENCY_ATTR_MAX + 1];
        struct nlattr *band, *freq;
+       uint32_t freq_mhz;
 
        if (attr[NL80211_ATTR_WIPHY_BANDS])
        {
@@ -3133,7 +3138,24 @@ static int nl80211_get_modelist_cb(struct nl_msg *msg, void *arg)
                                        if (!freqs[NL80211_FREQUENCY_ATTR_FREQ])
                                                continue;
 
-                                       m->nl_freq = nla_get_u32(freqs[NL80211_FREQUENCY_ATTR_FREQ]);
+                                       freq_mhz = nla_get_u32(freqs[NL80211_FREQUENCY_ATTR_FREQ]);
+
+                                       if (freq_mhz > 2400 && freq_mhz < 2485)
+                                       {
+                                               m->bands |= IWINFO_BAND_24;
+                                       }
+                                       else if (freq_mhz > 5000 && freq_mhz < 5850)
+                                       {
+                                               m->bands |= IWINFO_BAND_5;
+                                       }
+                                       else if (freq_mhz > 6000 && freq_mhz < 7120)
+                                       {
+                                               m->bands |= IWINFO_BAND_6;
+                                       }
+                                       else if (freq_mhz >= 56160)
+                                       {
+                                               m->bands |= IWINFO_BAND_60;
+                                       }
                                }
                        }
                }