driver: Function to directly poll signal quality
This provides a means for the supplicant to directly request signal quality metrics from the driver. This is useful, for example for background scan algorithms that might ask desire this information out-of-band with CQM events. Signed-off-by: Paul Stewart <pstew@google.com>
This commit is contained in:
parent
14dc00115e
commit
1c5c7273f5
4 changed files with 51 additions and 14 deletions
|
@ -706,6 +706,17 @@ enum tdls_oper {
|
||||||
TDLS_DISABLE
|
TDLS_DISABLE
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct wpa_signal_info - Information about channel signal quality
|
||||||
|
*/
|
||||||
|
struct wpa_signal_info {
|
||||||
|
u32 frequency;
|
||||||
|
int above_threshold;
|
||||||
|
int current_signal;
|
||||||
|
int current_noise;
|
||||||
|
int current_txrate;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* struct wpa_driver_ops - Driver interface API definition
|
* struct wpa_driver_ops - Driver interface API definition
|
||||||
*
|
*
|
||||||
|
@ -2221,6 +2232,13 @@ struct wpa_driver_ops {
|
||||||
const u8 *buf, size_t len);
|
const u8 *buf, size_t len);
|
||||||
|
|
||||||
int (*tdls_oper)(void *priv, enum tdls_oper oper, const u8 *peer);
|
int (*tdls_oper)(void *priv, enum tdls_oper oper, const u8 *peer);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* signal_poll - Get current connection information
|
||||||
|
* @priv: Private driver interface data
|
||||||
|
* @signal_info: Connection info structure
|
||||||
|
*/
|
||||||
|
int (*signal_poll)(void *priv, struct wpa_signal_info *signal_info);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -3051,15 +3069,9 @@ union wpa_event_data {
|
||||||
} eapol_rx;
|
} eapol_rx;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* struct signal_change - Data for EVENT_SIGNAL_CHANGE events
|
* signal_change - Data for EVENT_SIGNAL_CHANGE events
|
||||||
*/
|
*/
|
||||||
struct signal_change {
|
struct wpa_signal_info signal_change;
|
||||||
u32 frequency;
|
|
||||||
int above_threshold;
|
|
||||||
int current_signal;
|
|
||||||
int current_noise;
|
|
||||||
int current_txrate;
|
|
||||||
} signal_change;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* struct best_channel - Data for EVENT_BEST_CHANNEL events
|
* struct best_channel - Data for EVENT_BEST_CHANNEL events
|
||||||
|
|
|
@ -3326,5 +3326,6 @@ const struct wpa_driver_ops wpa_driver_ndis_ops = {
|
||||||
NULL /* p2p_reject */,
|
NULL /* p2p_reject */,
|
||||||
NULL /* p2p_invite */,
|
NULL /* p2p_invite */,
|
||||||
NULL /* send_tdls_mgmt */,
|
NULL /* send_tdls_mgmt */,
|
||||||
NULL /* tdls_oper */
|
NULL /* tdls_oper */,
|
||||||
|
NULL /* signal_poll */
|
||||||
};
|
};
|
||||||
|
|
|
@ -1082,7 +1082,7 @@ static int get_link_signal(struct nl_msg *msg, void *arg)
|
||||||
[NL80211_RATE_INFO_40_MHZ_WIDTH] = { .type = NLA_FLAG },
|
[NL80211_RATE_INFO_40_MHZ_WIDTH] = { .type = NLA_FLAG },
|
||||||
[NL80211_RATE_INFO_SHORT_GI] = { .type = NLA_FLAG },
|
[NL80211_RATE_INFO_SHORT_GI] = { .type = NLA_FLAG },
|
||||||
};
|
};
|
||||||
struct signal_change *sig_change = arg;
|
struct wpa_signal_info *sig_change = arg;
|
||||||
|
|
||||||
nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
|
nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
|
||||||
genlmsg_attrlen(gnlh, 0), NULL);
|
genlmsg_attrlen(gnlh, 0), NULL);
|
||||||
|
@ -1115,7 +1115,7 @@ static int get_link_signal(struct nl_msg *msg, void *arg)
|
||||||
|
|
||||||
|
|
||||||
static int nl80211_get_link_signal(struct wpa_driver_nl80211_data *drv,
|
static int nl80211_get_link_signal(struct wpa_driver_nl80211_data *drv,
|
||||||
struct signal_change *sig)
|
struct wpa_signal_info *sig)
|
||||||
{
|
{
|
||||||
struct nl_msg *msg;
|
struct nl_msg *msg;
|
||||||
|
|
||||||
|
@ -1147,7 +1147,7 @@ static int get_link_noise(struct nl_msg *msg, void *arg)
|
||||||
[NL80211_SURVEY_INFO_FREQUENCY] = { .type = NLA_U32 },
|
[NL80211_SURVEY_INFO_FREQUENCY] = { .type = NLA_U32 },
|
||||||
[NL80211_SURVEY_INFO_NOISE] = { .type = NLA_U8 },
|
[NL80211_SURVEY_INFO_NOISE] = { .type = NLA_U8 },
|
||||||
};
|
};
|
||||||
struct signal_change *sig_change = arg;
|
struct wpa_signal_info *sig_change = arg;
|
||||||
|
|
||||||
nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
|
nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
|
||||||
genlmsg_attrlen(gnlh, 0), NULL);
|
genlmsg_attrlen(gnlh, 0), NULL);
|
||||||
|
@ -1183,7 +1183,7 @@ static int get_link_noise(struct nl_msg *msg, void *arg)
|
||||||
|
|
||||||
|
|
||||||
static int nl80211_get_link_noise(struct wpa_driver_nl80211_data *drv,
|
static int nl80211_get_link_noise(struct wpa_driver_nl80211_data *drv,
|
||||||
struct signal_change *sig_change)
|
struct wpa_signal_info *sig_change)
|
||||||
{
|
{
|
||||||
struct nl_msg *msg;
|
struct nl_msg *msg;
|
||||||
|
|
||||||
|
@ -1217,7 +1217,7 @@ static void nl80211_cqm_event(struct wpa_driver_nl80211_data *drv,
|
||||||
struct nlattr *cqm[NL80211_ATTR_CQM_MAX + 1];
|
struct nlattr *cqm[NL80211_ATTR_CQM_MAX + 1];
|
||||||
enum nl80211_cqm_rssi_threshold_event event;
|
enum nl80211_cqm_rssi_threshold_event event;
|
||||||
union wpa_event_data ed;
|
union wpa_event_data ed;
|
||||||
struct signal_change sig;
|
struct wpa_signal_info sig;
|
||||||
int res;
|
int res;
|
||||||
|
|
||||||
if (tb[NL80211_ATTR_CQM] == NULL ||
|
if (tb[NL80211_ATTR_CQM] == NULL ||
|
||||||
|
@ -6370,6 +6370,21 @@ nla_put_failure:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int nl80211_signal_poll(void *priv, struct wpa_signal_info *si)
|
||||||
|
{
|
||||||
|
struct i802_bss *bss = priv;
|
||||||
|
struct wpa_driver_nl80211_data *drv = bss->drv;
|
||||||
|
int res;
|
||||||
|
|
||||||
|
os_memset(si, 0, sizeof(*si));
|
||||||
|
res = nl80211_get_link_signal(drv, si);
|
||||||
|
if (res != 0)
|
||||||
|
return res;
|
||||||
|
|
||||||
|
return nl80211_get_link_noise(drv, si);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int nl80211_send_frame(void *priv, const u8 *data, size_t data_len,
|
static int nl80211_send_frame(void *priv, const u8 *data, size_t data_len,
|
||||||
int encrypt)
|
int encrypt)
|
||||||
{
|
{
|
||||||
|
@ -6520,6 +6535,7 @@ const struct wpa_driver_ops wpa_driver_nl80211_ops = {
|
||||||
.resume = wpa_driver_nl80211_resume,
|
.resume = wpa_driver_nl80211_resume,
|
||||||
.send_ft_action = nl80211_send_ft_action,
|
.send_ft_action = nl80211_send_ft_action,
|
||||||
.signal_monitor = nl80211_signal_monitor,
|
.signal_monitor = nl80211_signal_monitor,
|
||||||
|
.signal_poll = nl80211_signal_poll,
|
||||||
.send_frame = nl80211_send_frame,
|
.send_frame = nl80211_send_frame,
|
||||||
.set_intra_bss = nl80211_set_intra_bss,
|
.set_intra_bss = nl80211_set_intra_bss,
|
||||||
.set_param = nl80211_set_param,
|
.set_param = nl80211_set_param,
|
||||||
|
|
|
@ -504,6 +504,14 @@ static inline int wpa_drv_signal_monitor(struct wpa_supplicant *wpa_s,
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline int wpa_drv_signal_poll(struct wpa_supplicant *wpa_s,
|
||||||
|
struct wpa_signal_info *si)
|
||||||
|
{
|
||||||
|
if (wpa_s->driver->signal_poll)
|
||||||
|
return wpa_s->driver->signal_poll(wpa_s->drv_priv, si);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
static inline int wpa_drv_set_ap_wps_ie(struct wpa_supplicant *wpa_s,
|
static inline int wpa_drv_set_ap_wps_ie(struct wpa_supplicant *wpa_s,
|
||||||
const struct wpabuf *beacon,
|
const struct wpabuf *beacon,
|
||||||
const struct wpabuf *proberesp,
|
const struct wpabuf *proberesp,
|
||||||
|
|
Loading…
Reference in a new issue