Эх сурвалжийг харах

wl1271: Add SSID configuration for JOIN in ad-hoc

This patch adds code to extract the SSID from the beacon template used for
ad-hoc. The mac80211 currently does not provide the SSID, so this is a
workaround for that, for now.

Signed-off-by: Juuso Oikarinen <juuso.oikarinen@nokia.com>
Reviewed-by: Luciano Coelho <luciano.coelho@nokia.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Juuso Oikarinen 15 жил өмнө
parent
commit
30240fc76a

+ 8 - 2
drivers/net/wireless/wl12xx/wl1271_event.c

@@ -92,7 +92,12 @@ static int wl1271_event_ps_report(struct wl1271 *wl,
 						 true);
 						 true);
 		} else {
 		} else {
 			wl1271_error("PSM entry failed, giving up.\n");
 			wl1271_error("PSM entry failed, giving up.\n");
-			/* make sure the firmware goes into active mode */
+			/* FIXME: this may need to be reconsidered. for now it
+			   is not possible to indicate to the mac80211
+			   afterwards that PSM entry failed. To maximize
+			   functionality (receiving data and remaining
+			   associated) make sure that we are in sync with the
+			   AP in regard of PSM mode. */
 			ret = wl1271_ps_set_mode(wl, STATION_ACTIVE_MODE,
 			ret = wl1271_ps_set_mode(wl, STATION_ACTIVE_MODE,
 						 false);
 						 false);
 			wl->psm_entry_retry = 0;
 			wl->psm_entry_retry = 0;
@@ -124,7 +129,8 @@ static int wl1271_event_ps_report(struct wl1271 *wl,
 			break;
 			break;
 		}
 		}
 
 
-		/* make sure the firmware goes to active mode */
+		/* make sure the firmware goes to active mode - the frame to
+		   be sent next will indicate to the AP, that we are active. */
 		ret = wl1271_ps_set_mode(wl, STATION_ACTIVE_MODE,
 		ret = wl1271_ps_set_mode(wl, STATION_ACTIVE_MODE,
 					 false);
 					 false);
 		break;
 		break;

+ 43 - 26
drivers/net/wireless/wl12xx/wl1271_main.c

@@ -1549,6 +1549,23 @@ out:
 	return ret;
 	return ret;
 }
 }
 
 
+static void wl1271_ssid_set(struct wl1271 *wl, struct sk_buff *beacon)
+{
+	u8 *ptr = beacon->data +
+		offsetof(struct ieee80211_mgmt, u.beacon.variable);
+
+	/* find the location of the ssid in the beacon */
+	while (ptr < beacon->data + beacon->len) {
+		if (ptr[0] == WLAN_EID_SSID) {
+			wl->ssid_len = ptr[1];
+			memcpy(wl->ssid, ptr+2, wl->ssid_len);
+			return;
+		}
+		ptr += ptr[1];
+	}
+	wl1271_error("ad-hoc beacon template has no SSID!\n");
+}
+
 static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw,
 static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw,
 				       struct ieee80211_vif *vif,
 				       struct ieee80211_vif *vif,
 				       struct ieee80211_bss_conf *bss_conf,
 				       struct ieee80211_bss_conf *bss_conf,
@@ -1566,40 +1583,17 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw,
 	if (ret < 0)
 	if (ret < 0)
 		goto out;
 		goto out;
 
 
-	if ((changed & BSS_CHANGED_BSSID) &&
-	    /*
-	     * Now we know the correct bssid, so we send a new join command
-	     * and enable the BSSID filter
-	     */
-	    memcmp(wl->bssid, bss_conf->bssid, ETH_ALEN)) {
-			wl->rx_config |= CFG_BSSID_FILTER_EN;
-			memcpy(wl->bssid, bss_conf->bssid, ETH_ALEN);
-			ret = wl1271_cmd_build_null_data(wl);
-			if (ret < 0) {
-				wl1271_warning("cmd buld null data failed %d",
-					       ret);
-				goto out_sleep;
-			}
-			ret = wl1271_cmd_join(wl);
-			if (ret < 0) {
-				wl1271_warning("cmd join failed %d", ret);
-				goto out_sleep;
-			}
-			set_bit(WL1271_FLAG_JOINED, &wl->flags);
-	}
-
 	if (wl->bss_type == BSS_TYPE_IBSS) {
 	if (wl->bss_type == BSS_TYPE_IBSS) {
 		/* FIXME: This implements rudimentary ad-hoc support -
 		/* FIXME: This implements rudimentary ad-hoc support -
 		   proper templates are on the wish list and notification
 		   proper templates are on the wish list and notification
 		   on when they change. This patch will update the templates
 		   on when they change. This patch will update the templates
-		   on every call to this function. Also, the firmware will not
-		   answer to probe-requests as it does not have the proper
-		   SSID set in the JOIN command. The probe-response template
-		   is set nevertheless, as the FW will ASSERT without it */
+		   on every call to this function. */
 		struct sk_buff *beacon = ieee80211_beacon_get(hw, vif);
 		struct sk_buff *beacon = ieee80211_beacon_get(hw, vif);
 
 
 		if (beacon) {
 		if (beacon) {
 			struct ieee80211_hdr *hdr;
 			struct ieee80211_hdr *hdr;
+
+			wl1271_ssid_set(wl, beacon);
 			ret = wl1271_cmd_template_set(wl, CMD_TEMPL_BEACON,
 			ret = wl1271_cmd_template_set(wl, CMD_TEMPL_BEACON,
 						      beacon->data,
 						      beacon->data,
 						      beacon->len);
 						      beacon->len);
@@ -1624,6 +1618,29 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw,
 		}
 		}
 	}
 	}
 
 
+	if ((changed & BSS_CHANGED_BSSID) &&
+	    /*
+	     * Now we know the correct bssid, so we send a new join command
+	     * and enable the BSSID filter
+	     */
+	    memcmp(wl->bssid, bss_conf->bssid, ETH_ALEN)) {
+			wl->rx_config |= CFG_BSSID_FILTER_EN;
+			memcpy(wl->bssid, bss_conf->bssid, ETH_ALEN);
+			ret = wl1271_cmd_build_null_data(wl);
+			if (ret < 0) {
+				wl1271_warning("cmd buld null data failed %d",
+					       ret);
+				goto out_sleep;
+			}
+
+			ret = wl1271_cmd_join(wl);
+			if (ret < 0) {
+				wl1271_warning("cmd join failed %d", ret);
+				goto out_sleep;
+			}
+			set_bit(WL1271_FLAG_JOINED, &wl->flags);
+	}
+
 	if (changed & BSS_CHANGED_ASSOC) {
 	if (changed & BSS_CHANGED_ASSOC) {
 		if (bss_conf->assoc) {
 		if (bss_conf->assoc) {
 			wl->aid = bss_conf->aid;
 			wl->aid = bss_conf->aid;