Browse Source

wlcore: initiate ROC/CROC on sta state updates

Use the sta_state notifications to ROC when a station
is about to connect, and CROC respectively on
authorization (success) / deletion (failure).

Change the wl12xx_update_sta_state() flow to bail out
only on error, so multiple code blocks could refer
to the same state.

Signed-off-by: Eliad Peller <eliad@wizery.com>
Reviewed-by: Arik Nemtsov <arik@wizery.com>
Signed-off-by: Luciano Coelho <coelho@ti.com>
Eliad Peller 12 years ago
parent
commit
2993626678
1 changed files with 28 additions and 16 deletions
  1. 28 16
      drivers/net/wireless/ti/wlcore/main.c

+ 28 - 16
drivers/net/wireless/ti/wlcore/main.c

@@ -83,8 +83,6 @@ static int wl12xx_set_authorized(struct wl1271 *wl,
 	if (ret < 0)
 		return ret;
 
-	wl12xx_croc(wl, wlvif->role_id);
-
 	wl1271_info("Association completed.");
 	return 0;
 }
@@ -3974,14 +3972,6 @@ sta_not_found:
 			wl1271_warning("cmd join failed %d", ret);
 			goto out;
 		}
-
-		/* ROC until connected (after EAPOL exchange) */
-		if (!is_ibss) {
-			ret = wl12xx_roc(wl, wlvif, wlvif->role_id,
-					 wlvif->band, wlvif->channel);
-			if (ret < 0)
-				goto out;
-		}
 	}
 
 	if (changed & BSS_CHANGED_ASSOC) {
@@ -4398,8 +4388,11 @@ static int wl12xx_update_sta_state(struct wl1271 *wl,
 	/* Add station (AP mode) */
 	if (is_ap &&
 	    old_state == IEEE80211_STA_NOTEXIST &&
-	    new_state == IEEE80211_STA_NONE)
-		return wl12xx_sta_add(wl, wlvif, sta);
+	    new_state == IEEE80211_STA_NONE) {
+		ret = wl12xx_sta_add(wl, wlvif, sta);
+		if (ret)
+			return ret;
+	}
 
 	/* Remove station (AP mode) */
 	if (is_ap &&
@@ -4407,7 +4400,6 @@ static int wl12xx_update_sta_state(struct wl1271 *wl,
 	    new_state == IEEE80211_STA_NOTEXIST) {
 		/* must not fail */
 		wl12xx_sta_remove(wl, wlvif, sta);
-		return 0;
 	}
 
 	/* Authorize station (AP mode) */
@@ -4419,14 +4411,17 @@ static int wl12xx_update_sta_state(struct wl1271 *wl,
 
 		ret = wl1271_acx_set_ht_capabilities(wl, &sta->ht_cap, true,
 						     hlid);
-		return ret;
+		if (ret)
+			return ret;
 	}
 
 	/* Authorize station */
 	if (is_sta &&
 	    new_state == IEEE80211_STA_AUTHORIZED) {
 		set_bit(WLVIF_FLAG_STA_AUTHORIZED, &wlvif->flags);
-		return wl12xx_set_authorized(wl, wlvif);
+		ret = wl12xx_set_authorized(wl, wlvif);
+		if (ret)
+			return ret;
 	}
 
 	if (is_sta &&
@@ -4434,9 +4429,26 @@ static int wl12xx_update_sta_state(struct wl1271 *wl,
 	    new_state == IEEE80211_STA_ASSOC) {
 		clear_bit(WLVIF_FLAG_STA_AUTHORIZED, &wlvif->flags);
 		clear_bit(WLVIF_FLAG_STA_STATE_SENT, &wlvif->flags);
-		return 0;
 	}
 
+	/* clear ROCs on failure or authorization */
+	if (is_sta &&
+	    (new_state == IEEE80211_STA_AUTHORIZED ||
+	     new_state == IEEE80211_STA_NOTEXIST)) {
+		if (test_bit(wlvif->role_id, wl->roc_map))
+			wl12xx_croc(wl, wlvif->role_id);
+	}
+
+	if (is_sta &&
+	    old_state == IEEE80211_STA_NOTEXIST &&
+	    new_state == IEEE80211_STA_NONE) {
+		if (find_first_bit(wl->roc_map,
+				   WL12XX_MAX_ROLES) >= WL12XX_MAX_ROLES) {
+			WARN_ON(wlvif->role_id == WL12XX_INVALID_ROLE_ID);
+			wl12xx_roc(wl, wlvif, wlvif->role_id,
+				   wlvif->band, wlvif->channel);
+		}
+	}
 	return 0;
 }