In addition, support bringing down/up NAN interface and send EVENT_INTERFACE_ENABLED/DISABLED when rfkill is unblocked or blocked. Signed-off-by: Ilan Peer <ilan.peer@xxxxxxxxx> Signed-off-by: Andrei Otcheretianski <andrei.otcheretianski@xxxxxxxxx> --- src/drivers/driver_nl80211.c | 107 +++++++++++++++++++++++++++++++++-- src/drivers/driver_nl80211.h | 4 ++ 2 files changed, 105 insertions(+), 6 deletions(-) diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c index ad98f3292d..71ddb7664a 100644 --- a/src/drivers/driver_nl80211.c +++ b/src/drivers/driver_nl80211.c @@ -201,6 +201,9 @@ static int nl80211_put_mesh_config(struct nl_msg *msg, static int i802_sta_disassoc(void *priv, const u8 *own_addr, const u8 *addr, u16 reason, int link_id); +#ifdef CONFIG_NAN +static void wpa_driver_nl80211_nan_stop(void *priv); +#endif /* CONFIG_NAN */ /* Converts nl80211_chan_width to a common format */ enum chan_width convert2width(int width) @@ -2172,8 +2175,8 @@ static void wpa_driver_nl80211_rfkill_blocked(void *ctx) wpa_printf(MSG_DEBUG, "nl80211: RFKILL blocked"); /* - * rtnetlink ifdown handler will report interfaces other than the P2P - * Device interface as disabled. + * rtnetlink ifdown handler will report interfaces other than the + * P2P/NAN Device interfaces as disabled. */ if (!nl80211_is_netdev_iftype(drv->nlmode)) wpa_supplicant_event(drv->ctx, EVENT_INTERFACE_DISABLED, NULL); @@ -2194,8 +2197,8 @@ static void wpa_driver_nl80211_rfkill_unblocked(void *ctx) nl80211_disable_11b_rates(drv, drv->ifindex, 1); /* - * rtnetlink ifup handler will report interfaces other than the P2P - * Device interface as enabled. + * rtnetlink ifup handler will report interfaces other than the P2P/NAN + * Device interfaces as enabled. */ if (!nl80211_is_netdev_iftype(drv->nlmode)) wpa_supplicant_event(drv->ctx, EVENT_INTERFACE_ENABLED, NULL); @@ -2996,9 +2999,21 @@ static int nl80211_set_p2pdev(struct i802_bss *bss, int start) } -int nl80211_set_nandev(struct i802_bss *bss, int start) +static int nl80211_set_nandev(struct i802_bss *bss, int start) { - /* TODO: This will be implemented once NAN start/stop APIs are added */ +#ifdef CONFIG_NAN + /* + * We don't implicitly start NAN. + * NAN is started through a dedicated API, however we do need to + * stop it. + * For rfkill, we rely on ENABLED/DISABLED events. + */ + if (start) + return 0; + + wpa_driver_nl80211_nan_stop(bss); + +#endif /* CONFIG_NAN */ return 0; } @@ -14997,6 +15012,82 @@ wpa_driver_get_multi_hw_info(void *priv, unsigned int *num_multi_hws) } +#ifdef CONFIG_NAN + +static int wpa_driver_nl80211_nan_start(void *priv, + struct nan_cluster_config *params) +{ + struct i802_bss *bss = priv; + struct wpa_driver_nl80211_data *drv = bss->drv; + struct nl_msg *msg; + u32 bands = 0; + int ret; + + if (drv->nlmode != NL80211_IFTYPE_NAN) + return -EOPNOTSUPP; + + if (drv->nan_started) + return -EALREADY; + + wpa_printf(MSG_DEBUG, "nl80211: Start/Join NAN cluster"); + + if (params->dual_band > 1) + return -EINVAL; + + bands |= BIT(NL80211_BAND_2GHZ); + + if (params->dual_band) { + if (drv->capa.nan_flags & + WPA_DRIVER_FLAGS_NAN_SUPPORT_DUAL_BAND) { + bands |= BIT(NL80211_BAND_5GHZ); + } else { + wpa_printf(MSG_DEBUG, + "nl80211: Driver doesn't support NAN dual band operation"); + return -EINVAL; + } + } + + msg = nl80211_cmd_msg(bss, 0, NL80211_CMD_START_NAN); + if (!msg || nla_put_u8(msg, NL80211_ATTR_NAN_MASTER_PREF, + params->master_pref) || + (bands && nla_put_u32(msg, NL80211_ATTR_BANDS, bands))) { + wpa_printf(MSG_ERROR, "Failed to build start NAN command"); + goto fail; + } + + ret = send_and_recv_resp(drv, msg, NULL, NULL); + if (!ret) + drv->nan_started = 1; + + return ret; +fail: + nlmsg_free(msg); + return -1; +} + +static void wpa_driver_nl80211_nan_stop(void *priv) +{ + struct i802_bss *bss = priv; + struct wpa_driver_nl80211_data *drv = bss->drv; + struct nl_msg *msg; + + if (drv->nlmode != NL80211_IFTYPE_NAN || !drv->nan_started) + return; + + msg = nl80211_cmd_msg(bss, 0, NL80211_CMD_STOP_NAN); + if (!msg) { + wpa_printf(MSG_ERROR, "Failed to alloc NAN stop command"); + return; + } + + if (send_and_recv_resp(bss->drv, msg, NULL, NULL)) + wpa_printf(MSG_ERROR, "Failed to send NAN stop command"); + + drv->nan_started = 0; +} + +#endif /* CONFIG_NAN */ + const struct wpa_driver_ops wpa_driver_nl80211_ops = { .name = "nl80211", .desc = "Linux nl80211/cfg80211", @@ -15168,4 +15259,8 @@ const struct wpa_driver_ops wpa_driver_nl80211_ops = { .radio_disable = testing_nl80211_radio_disable, #endif /* CONFIG_TESTING_OPTIONS */ .get_multi_hw_info = wpa_driver_get_multi_hw_info, +#ifdef CONFIG_NAN + .nan_start = wpa_driver_nl80211_nan_start, + .nan_stop = wpa_driver_nl80211_nan_stop, +#endif /*CONFIG_NAN */ }; diff --git a/src/drivers/driver_nl80211.h b/src/drivers/driver_nl80211.h index d8b3157c6c..17d3a938f9 100644 --- a/src/drivers/driver_nl80211.h +++ b/src/drivers/driver_nl80211.h @@ -272,6 +272,10 @@ struct wpa_driver_nl80211_data { u8 *pending_link_reconfig_data; size_t pending_link_reconfig_data_len; #endif /* CONFIG_DRIVER_NL80211_QCA */ + +#ifdef CONFIG_NAN + unsigned int nan_started:1; +#endif /* CONFIG_NAN */ }; struct nl_msg; -- 2.49.0 _______________________________________________ Hostap mailing list Hostap@xxxxxxxxxxxxxxxxxxx http://lists.infradead.org/mailman/listinfo/hostap