Patchwork [V2,11/23] nl80211: Rework setting interface mode

login
register
mail settings
Submitter Arend van Spriel
Date May 29, 2013, 9:07 a.m.
Message ID <1369818491-7274-12-git-send-email-arend@broadcom.com>
Download mbox | patch
Permalink /patch/247200/
State Accepted
Headers show

Comments

Arend van Spriel - May 29, 2013, 9:07 a.m.
The function setting the interface mode also handles management
frame subscription. Rework it so subscription is done for the
P2P Device interface.

Signed-hostap: Arend van Spriel <arend@broadcom.com>
---
 src/drivers/driver_nl80211.c |   37 ++++++++++++++++++-------------------
 1 file changed, 18 insertions(+), 19 deletions(-)

Patch

diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
index 3ae3e99..4ee474a 100644
--- a/src/drivers/driver_nl80211.c
+++ b/src/drivers/driver_nl80211.c
@@ -615,7 +615,7 @@  static enum nl80211_iftype nl80211_get_ifmode(struct i802_bss *bss)
 
 	msg = nlmsg_alloc();
 	if (!msg)
-		return -1;
+		return NL80211_IFTYPE_UNSPECIFIED;
 
 	nl80211_cmd(bss->drv, msg, 0, NL80211_CMD_GET_INTERFACE);
 
@@ -3802,7 +3802,6 @@  nla_put_failure:
 }
 
 
-#ifndef HOSTAPD
 static int nl80211_set_p2pdev(struct i802_bss *bss, int start)
 {
 	struct wpa_driver_nl80211_data *drv = bss->drv;
@@ -3832,7 +3831,6 @@  nla_put_failure:
 	nlmsg_free(msg);
 	return ret;
 }
-#endif /* HOSTAPD */
 
 
 static int i802_set_iface_flags(struct i802_bss *bss, int up)
@@ -3854,7 +3852,7 @@  static int
 wpa_driver_nl80211_finish_drv_init(struct wpa_driver_nl80211_data *drv)
 {
 #ifndef HOSTAPD
-	enum nl80211_iftype nlmode = NL80211_IFTYPE_UNSPECIFIED;
+	enum nl80211_iftype nlmode = NL80211_IFTYPE_STATION;
 #endif /* HOSTAPD */
 	struct i802_bss *bss = &drv->first_bss;
 	int send_rfkill_event = 0;
@@ -3873,24 +3871,19 @@  wpa_driver_nl80211_finish_drv_init(struct wpa_driver_nl80211_data *drv)
 		return -1;
 
 #ifndef HOSTAPD
-	nlmode = nl80211_get_ifmode(bss);
+	if (dynamic_if)
+		nlmode = nl80211_get_ifmode(bss);
 
 	/*
 	 * Make sure the interface starts up in station mode unless this is a
 	 * dynamically added interface (e.g., P2P) that was already configured
 	 * with proper iftype.
 	 */
-	if (!dynamic_if) {
-		if (wpa_driver_nl80211_set_mode(bss, nlmode) < 0) {
-			wpa_printf(MSG_ERROR, "nl80211: Could not configure driver to use %s mode",
-				   nlmode == NL80211_IFTYPE_STATION ?
-				   "managed" : "P2P-Device");
-			return -1;
-		}
-
-		/* Always use managed mode internally, even for P2P Device */
-		drv->nlmode = NL80211_IFTYPE_STATION;
+	if (wpa_driver_nl80211_set_mode(bss, nlmode) < 0) {
+		wpa_printf(MSG_ERROR, "nl80211: Could not configure driver to use managed mode");
+		return -1;
 	}
+	drv->nlmode = nlmode;
 
 	if (nlmode == NL80211_IFTYPE_P2P_DEVICE) {
 		int ret = nl80211_set_p2pdev(bss, 1);
@@ -4014,10 +4007,12 @@  static void wpa_driver_nl80211_deinit(struct i802_bss *bss)
 	eloop_cancel_timeout(wpa_driver_nl80211_scan_timeout, drv, drv->ctx);
 
 	(void) i802_set_iface_flags(bss, 0);
-	wpa_driver_nl80211_set_mode(bss, NL80211_IFTYPE_STATION);
-	nl80211_mgmt_unsubscribe(bss, "deinit");
-	if (nl80211_get_ifmode(bss) == NL80211_IFTYPE_P2P_DEVICE)
+	if (drv->nlmode != NL80211_IFTYPE_P2P_DEVICE) {
+		wpa_driver_nl80211_set_mode(bss, NL80211_IFTYPE_STATION);
+	} else {
+		nl80211_mgmt_unsubscribe(bss, "deinit");
 		nl80211_del_p2pdev(bss);
+	}
 	nl_cb_put(drv->nl_cb);
 
 	nl80211_destroy_bss(&drv->first_bss);
@@ -5942,7 +5937,8 @@  static int wpa_driver_nl80211_send_mlme(struct i802_bss *bss, const u8 *data,
 	mgmt = (struct ieee80211_mgmt *) data;
 	fc = le_to_host16(mgmt->frame_control);
 
-	if (is_sta_interface(drv->nlmode) &&
+	if ((is_sta_interface(drv->nlmode) ||
+	     drv->nlmode == NL80211_IFTYPE_P2P_DEVICE) &&
 	    WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_MGMT &&
 	    WLAN_FC_GET_STYPE(fc) == WLAN_FC_STYPE_PROBE_RESP) {
 		/*
@@ -7884,6 +7880,9 @@  static int wpa_driver_nl80211_set_mode(struct i802_bss *bss,
 	int res;
 
 	res = nl80211_set_mode(drv, drv->ifindex, nlmode);
+	if (res && nlmode == nl80211_get_ifmode(bss))
+		res = 0;
+
 	if (res == 0) {
 		drv->nlmode = nlmode;
 		ret = 0;