mirror of
https://git.kernel.org/pub/scm/network/wireless/iwd.git
synced 2024-11-29 13:59:24 +01:00
wiphy: Add wiphy_get_supported_rates
Add code to parse the supported data rates info from the wiphy dumps and expose it for P2P's use with a getter function.
This commit is contained in:
parent
971e1d2038
commit
07cef99e5c
84
src/wiphy.c
84
src/wiphy.c
@ -76,6 +76,7 @@ struct wiphy {
|
|||||||
struct watchlist state_watches;
|
struct watchlist state_watches;
|
||||||
uint8_t extended_capabilities[EXT_CAP_LEN + 2]; /* max bitmap size + IE header */
|
uint8_t extended_capabilities[EXT_CAP_LEN + 2]; /* max bitmap size + IE header */
|
||||||
uint8_t *iftype_extended_capabilities[NUM_NL80211_IFTYPES];
|
uint8_t *iftype_extended_capabilities[NUM_NL80211_IFTYPES];
|
||||||
|
uint8_t *supported_rates[NUM_NL80211_BANDS];
|
||||||
uint8_t rm_enabled_capabilities[7]; /* 5 size max + header */
|
uint8_t rm_enabled_capabilities[7]; /* 5 size max + header */
|
||||||
|
|
||||||
bool support_scheduled_scan:1;
|
bool support_scheduled_scan:1;
|
||||||
@ -212,6 +213,9 @@ static void wiphy_free(void *data)
|
|||||||
for (i = 0; i < NUM_NL80211_IFTYPES; i++)
|
for (i = 0; i < NUM_NL80211_IFTYPES; i++)
|
||||||
l_free(wiphy->iftype_extended_capabilities[i]);
|
l_free(wiphy->iftype_extended_capabilities[i]);
|
||||||
|
|
||||||
|
for (i = 0; i < NUM_NL80211_BANDS; i++)
|
||||||
|
l_free(wiphy->supported_rates[i]);
|
||||||
|
|
||||||
scan_freq_set_free(wiphy->supported_freqs);
|
scan_freq_set_free(wiphy->supported_freqs);
|
||||||
watchlist_destroy(&wiphy->state_watches);
|
watchlist_destroy(&wiphy->state_watches);
|
||||||
l_free(wiphy->model_str);
|
l_free(wiphy->model_str);
|
||||||
@ -481,6 +485,20 @@ bool wiphy_supports_iftype(struct wiphy *wiphy, uint32_t iftype)
|
|||||||
return wiphy->supported_iftypes & (1 << (iftype - 1));
|
return wiphy->supported_iftypes & (1 << (iftype - 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const uint8_t *wiphy_get_supported_rates(struct wiphy *wiphy, unsigned int band,
|
||||||
|
unsigned int *out_num)
|
||||||
|
{
|
||||||
|
if (band >= L_ARRAY_SIZE(wiphy->supported_rates))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (out_num)
|
||||||
|
*out_num =
|
||||||
|
(uint8_t *) rawmemchr(wiphy->supported_rates[band], 0) -
|
||||||
|
wiphy->supported_rates[band];
|
||||||
|
|
||||||
|
return wiphy->supported_rates[band];
|
||||||
|
}
|
||||||
|
|
||||||
uint32_t wiphy_state_watch_add(struct wiphy *wiphy,
|
uint32_t wiphy_state_watch_add(struct wiphy *wiphy,
|
||||||
wiphy_state_watch_func_t func,
|
wiphy_state_watch_func_t func,
|
||||||
void *user_data, wiphy_destroy_func_t destroy)
|
void *user_data, wiphy_destroy_func_t destroy)
|
||||||
@ -625,20 +643,70 @@ static void parse_supported_frequencies(struct wiphy *wiphy,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static uint8_t *parse_supported_rates(struct l_genl_attr *attr)
|
||||||
|
{
|
||||||
|
uint16_t type;
|
||||||
|
uint16_t len;
|
||||||
|
const void *data;
|
||||||
|
struct l_genl_attr nested;
|
||||||
|
int count = 0;
|
||||||
|
uint8_t *ret;
|
||||||
|
|
||||||
|
if (!l_genl_attr_recurse(attr, &nested))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
while (l_genl_attr_next(&nested, NULL, NULL, NULL))
|
||||||
|
count++;
|
||||||
|
|
||||||
|
if (!l_genl_attr_recurse(attr, &nested))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
ret = l_malloc(count + 1);
|
||||||
|
ret[count] = 0;
|
||||||
|
|
||||||
|
count = 0;
|
||||||
|
|
||||||
|
while (l_genl_attr_next(&nested, NULL, NULL, NULL)) {
|
||||||
|
struct l_genl_attr nested2;
|
||||||
|
|
||||||
|
if (!l_genl_attr_recurse(&nested, &nested2)) {
|
||||||
|
l_free(ret);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (l_genl_attr_next(&nested2, &type, &len, &data)) {
|
||||||
|
if (type != NL80211_BITRATE_ATTR_RATE || len != 4)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Convert from the 100kb/s units reported by the
|
||||||
|
* kernel to the 500kb/s used in 802.11 IEs.
|
||||||
|
*/
|
||||||
|
ret[count++] = *(const uint32_t *) data / 5;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static void parse_supported_bands(struct wiphy *wiphy,
|
static void parse_supported_bands(struct wiphy *wiphy,
|
||||||
struct l_genl_attr *bands)
|
struct l_genl_attr *bands)
|
||||||
{
|
{
|
||||||
uint16_t type, len;
|
uint16_t type;
|
||||||
const void *data;
|
|
||||||
struct l_genl_attr attr;
|
struct l_genl_attr attr;
|
||||||
|
|
||||||
l_debug("");
|
l_debug("");
|
||||||
|
|
||||||
while (l_genl_attr_next(bands, NULL, NULL, NULL)) {
|
while (l_genl_attr_next(bands, &type, NULL, NULL)) {
|
||||||
|
enum nl80211_band band = type;
|
||||||
|
|
||||||
|
if (band != NL80211_BAND_2GHZ && band != NL80211_BAND_5GHZ)
|
||||||
|
continue;
|
||||||
|
|
||||||
if (!l_genl_attr_recurse(bands, &attr))
|
if (!l_genl_attr_recurse(bands, &attr))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
while (l_genl_attr_next(&attr, &type, &len, &data)) {
|
while (l_genl_attr_next(&attr, &type, NULL, NULL)) {
|
||||||
struct l_genl_attr freqs;
|
struct l_genl_attr freqs;
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
@ -648,6 +716,14 @@ static void parse_supported_bands(struct wiphy *wiphy,
|
|||||||
|
|
||||||
parse_supported_frequencies(wiphy, &freqs);
|
parse_supported_frequencies(wiphy, &freqs);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case NL80211_BAND_ATTR_RATES:
|
||||||
|
if (wiphy->supported_rates[band])
|
||||||
|
continue;
|
||||||
|
|
||||||
|
wiphy->supported_rates[band] =
|
||||||
|
parse_supported_rates(&attr);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -66,6 +66,8 @@ bool wiphy_has_ext_feature(struct wiphy *wiphy, uint32_t feature);
|
|||||||
uint8_t wiphy_get_max_num_ssids_per_scan(struct wiphy *wiphy);
|
uint8_t wiphy_get_max_num_ssids_per_scan(struct wiphy *wiphy);
|
||||||
uint32_t wiphy_get_max_roc_duration(struct wiphy *wiphy);
|
uint32_t wiphy_get_max_roc_duration(struct wiphy *wiphy);
|
||||||
bool wiphy_supports_iftype(struct wiphy *wiphy, uint32_t iftype);
|
bool wiphy_supports_iftype(struct wiphy *wiphy, uint32_t iftype);
|
||||||
|
const uint8_t *wiphy_get_supported_rates(struct wiphy *wiphy, unsigned int band,
|
||||||
|
unsigned int *out_num);
|
||||||
bool wiphy_supports_adhoc_rsn(struct wiphy *wiphy);
|
bool wiphy_supports_adhoc_rsn(struct wiphy *wiphy);
|
||||||
bool wiphy_can_offchannel_tx(struct wiphy *wiphy);
|
bool wiphy_can_offchannel_tx(struct wiphy *wiphy);
|
||||||
bool wiphy_supports_qos_set_map(struct wiphy *wiphy);
|
bool wiphy_supports_qos_set_map(struct wiphy *wiphy);
|
||||||
|
Loading…
Reference in New Issue
Block a user