+int nl80211_get_hwmodelist(const char *ifname, int *buf)
+{
+ int bands_remain, freqs_remain;
+ struct nl80211_msg_conveyor *req, *res;
+ struct nlattr *bands[NL80211_BAND_ATTR_MAX + 1];
+ struct nlattr *freqs[NL80211_FREQUENCY_ATTR_MAX + 1];
+ struct nlattr *band, *freq;
+ uint16_t caps = 0;
+
+ req = nl80211_msg(ifname, NL80211_CMD_GET_WIPHY, 0);
+ if( req )
+ {
+ res = nl80211_send(req);
+ if( res )
+ {
+ nla_for_each_nested(band,
+ res->attr[NL80211_ATTR_WIPHY_BANDS], bands_remain)
+ {
+ nla_parse(bands, NL80211_BAND_ATTR_MAX, nla_data(band),
+ nla_len(band), NULL);
+
+ if( bands[NL80211_BAND_ATTR_HT_CAPA] )
+ caps = nla_get_u16(bands[NL80211_BAND_ATTR_HT_CAPA]);
+
+ /* Treat HT20/HT40 as 11n */
+ if( caps & (1 << 1) )
+ *buf |= IWINFO_80211_N;
+
+ nla_for_each_nested(freq,
+ bands[NL80211_BAND_ATTR_FREQS], freqs_remain)
+ {
+ nla_parse(freqs, NL80211_FREQUENCY_ATTR_MAX,
+ nla_data(freq), nla_len(freq), NULL);
+
+ if( !freqs[NL80211_FREQUENCY_ATTR_FREQ] )
+ continue;
+
+ if( nla_get_u32(freqs[NL80211_FREQUENCY_ATTR_FREQ]) < 2485 )
+ {
+ *buf |= IWINFO_80211_B;
+ *buf |= IWINFO_80211_G;
+ }
+ else
+ {
+ *buf |= IWINFO_80211_A;
+ }
+ }
+ }
+ nl80211_free(res);
+ }
+ nl80211_free(req);
+ }
+
+ return *buf ? 0 : -1;
+}
+