[PATCH 5/9] wcn:36xx remember list of vif

Eugene Krasnikov k.eugene.e at gmail.com
Fri Sep 6 04:09:17 EDT 2013


instead of using current_vif look for corresponding vif
in the list.

Signed-off-by: Eugene Krasnikov <k.eugene.e at gmail.com>
---
 main.c    | 22 ++++++++++-------
 smd.c     | 82 ++++++++++++++++++++++++++++++++++++++-------------------------
 wcn36xx.h |  3 +++
 3 files changed, 66 insertions(+), 41 deletions(-)

diff --git a/main.c b/main.c
index a203e28..d5cf15d 100644
--- a/main.c
+++ b/main.c
@@ -238,7 +238,7 @@ static int wcn36xx_start(struct ieee80211_hw *hw)
 		if (ret)
 			wcn36xx_warn("Exchange feature caps failed\n");
 	}
-
+	INIT_LIST_HEAD(&wcn->vif_list);
 	return 0;
 
 out_smd_stop:
@@ -493,8 +493,8 @@ static void wcn36xx_bss_info_changed(struct ieee80211_hw *hw,
 	struct sk_buff *skb = NULL;
 	u16 tim_off, tim_len;
 	enum wcn36xx_hal_link_state link_state;
-
-	wcn->current_vif = (struct wcn36xx_vif *)vif->drv_priv;
+	struct wcn36xx_vif *vif_priv = (struct wcn36xx_vif *)vif->drv_priv;
+	wcn->current_vif = vif_priv;
 
 	wcn36xx_dbg(WCN36XX_DBG_MAC, "mac bss info changed vif %p changed 0x%08x\n",
 		    vif, changed);
@@ -513,7 +513,7 @@ static void wcn36xx_bss_info_changed(struct ieee80211_hw *hw,
 
 		if (!is_zero_ether_addr(bss_conf->bssid)) {
 			wcn->is_joining = true;
-			wcn->current_vif->bss_index = 0xff;
+			vif_priv->bss_index = 0xff;
 			wcn36xx_smd_join(wcn, bss_conf->bssid,
 					 vif->addr, WCN36XX_HW_CHANNEL(wcn));
 			wcn36xx_smd_config_bss(wcn, vif, NULL,
@@ -600,7 +600,7 @@ static void wcn36xx_bss_info_changed(struct ieee80211_hw *hw,
 			    bss_conf->enable_beacon);
 
 		if (bss_conf->enable_beacon) {
-			wcn->current_vif->bss_index = 0xff;
+			vif_priv->bss_index = 0xff;
 			wcn36xx_smd_config_bss(wcn, vif, NULL,
 					       wcn->addresses.addr, false);
 			skb = ieee80211_beacon_get_tim(hw, vif, &tim_off,
@@ -644,7 +644,10 @@ static void wcn36xx_remove_interface(struct ieee80211_hw *hw,
 				     struct ieee80211_vif *vif)
 {
 	struct wcn36xx *wcn = hw->priv;
+	struct wcn36xx_vif *vif_priv = (struct wcn36xx_vif *)vif->drv_priv;
 	wcn36xx_dbg(WCN36XX_DBG_MAC, "mac remove interface vif %p\n", vif);
+
+	list_del(&vif_priv->list);
 	wcn36xx_smd_delete_sta_self(wcn, vif->addr);
 }
 
@@ -652,7 +655,7 @@ static int wcn36xx_add_interface(struct ieee80211_hw *hw,
 				 struct ieee80211_vif *vif)
 {
 	struct wcn36xx *wcn = hw->priv;
-
+	struct wcn36xx_vif *vif_priv = (struct wcn36xx_vif *)vif->drv_priv;
 	wcn36xx_dbg(WCN36XX_DBG_MAC, "mac add interface vif %p type %d\n",
 		    vif, vif->type);
 
@@ -665,6 +668,7 @@ static int wcn36xx_add_interface(struct ieee80211_hw *hw,
 		return -EOPNOTSUPP;
 	}
 
+	list_add(&vif_priv->list, &wcn->vif_list);
 	wcn36xx_smd_add_sta_self(wcn, vif);
 
 	return 0;
@@ -674,11 +678,12 @@ static int wcn36xx_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
 			   struct ieee80211_sta *sta)
 {
 	struct wcn36xx *wcn = hw->priv;
-
+	struct wcn36xx_vif *vif_priv = (struct wcn36xx_vif *)vif->drv_priv;
 	wcn36xx_dbg(WCN36XX_DBG_MAC, "mac sta add vif %p sta %pM\n",
 		    vif, sta->addr);
 
 	wcn->sta = (struct wcn36xx_sta *)sta->drv_priv;
+	vif_priv->sta = (struct wcn36xx_sta *)sta->drv_priv;
 	wcn->aid = sta->aid;
 	wcn36xx_smd_config_sta(wcn, vif, sta);
 
@@ -690,13 +695,14 @@ static int wcn36xx_sta_remove(struct ieee80211_hw *hw,
 			      struct ieee80211_sta *sta)
 {
 	struct wcn36xx *wcn = hw->priv;
+	struct wcn36xx_vif *vif_priv = (struct wcn36xx_vif *)vif->drv_priv;
 	struct wcn36xx_sta *sta_priv = (struct wcn36xx_sta *)sta->drv_priv;
 
 	wcn36xx_dbg(WCN36XX_DBG_MAC, "mac sta remove vif %p sta %pM index %d\n",
 		    vif, sta->addr, sta_priv->sta_index);
 
 	wcn36xx_smd_delete_sta(wcn, sta_priv->sta_index);
-
+	vif_priv->sta = NULL;
 	return 0;
 }
 
diff --git a/smd.c b/smd.c
index 42ee1d8..9ebe859 100644
--- a/smd.c
+++ b/smd.c
@@ -1834,29 +1834,42 @@ static int wcn36xx_smd_missed_beacon_ind(struct wcn36xx *wcn,
 					 void *buf,
 					 size_t len)
 {
-	struct ieee80211_vif *vif = container_of((void *)wcn->current_vif,
+	struct wcn36xx_hal_missed_beacon_ind_msg *rsp = buf;
+	struct ieee80211_vif *vif = NULL;
+	struct wcn36xx_vif *tmp;
+
+	/* Old FW does not have bss index */
+	if (wcn36xx_is_fw_version(wcn, 1, 2, 2, 24)) {
+		list_for_each_entry(tmp, &wcn->vif_list, list) {
+			wcn36xx_dbg(WCN36XX_DBG_HAL, "beacon missed bss_index %d\n",
+				    tmp->bss_index);
+			vif = container_of((void *)tmp,
 						 struct ieee80211_vif,
 						 drv_priv);
+			ieee80211_connection_loss(vif);
+			return 0;
+		}
+	}
 
-	mutex_lock(&wcn->pm_mutex);
-
-	/*
-	 * In suspended state mac80211 is still sleeping and that means we
-	 * cannot notify it about connection lost. Wait until resume and
-	 * then notify mac80211 about it.
-	 */
-	if (wcn->is_suspended) {
-		wcn36xx_dbg(WCN36XX_DBG_HAL,
-		    "postpone connection lost notification\n");
-		wcn->is_con_lost_pending = true;
-	} else {
-		wcn36xx_dbg(WCN36XX_DBG_HAL, "beacon missed\n");
-		ieee80211_connection_loss(vif);
+	if (len != sizeof(*rsp)) {
+		wcn36xx_warn("Corrupted missed beacon indication\n");
+		return -EIO;
 	}
 
-	mutex_unlock(&wcn->pm_mutex);
+	list_for_each_entry(tmp, &wcn->vif_list, list) {
+		if (tmp->bss_index == rsp->bss_index) {
+			wcn36xx_dbg(WCN36XX_DBG_HAL, "beacon missed bss_index %d\n",
+				    rsp->bss_index);
+			vif = container_of((void *)tmp,
+						 struct ieee80211_vif,
+						 drv_priv);
+			ieee80211_connection_loss(vif);
+			return 0;
+		}
+	}
 
-	return 0;
+	wcn36xx_warn("BSS index %d not found\n", rsp->bss_index);
+	return -ENOENT;
 }
 
 static int wcn36xx_smd_delete_sta_context_ind(struct wcn36xx *wcn,
@@ -1864,29 +1877,32 @@ static int wcn36xx_smd_delete_sta_context_ind(struct wcn36xx *wcn,
 					      size_t len)
 {
 	struct wcn36xx_hal_delete_sta_context_ind_msg *rsp = buf;
-	struct ieee80211_vif *vif = container_of((void *)wcn->current_vif,
-						 struct ieee80211_vif,
-						 drv_priv);
-	struct ieee80211_sta *sta;
+	struct wcn36xx_vif *tmp;
+	struct ieee80211_sta *sta = NULL;
 
 	if (len != sizeof(*rsp)) {
-		wcn36xx_warn("Bad delete sta indication\n");
+		wcn36xx_warn("Corrupted delete sta indication\n");
 		return -EIO;
 	}
 
-
-	rcu_read_lock();
-
-	sta = ieee80211_find_sta(vif, rsp->addr2);
-	if (sta) {
-		wcn36xx_dbg(WCN36XX_DBG_HAL,
-		    "delete station indication %pM\n", rsp->addr2);
-		ieee80211_report_low_ack(sta, 0);
+	list_for_each_entry(tmp, &wcn->vif_list, list) {
+		if (sta && (tmp->sta->sta_index == rsp->sta_id)) {
+			sta = container_of((void *)tmp->sta,
+						 struct ieee80211_sta,
+						 drv_priv);
+			wcn36xx_dbg(WCN36XX_DBG_HAL,
+				    "delete station indication %pM index %d\n",
+				    rsp->addr2,
+				    rsp->sta_id);
+			ieee80211_report_low_ack(sta, 0);
+			return 0;
+		}
 	}
 
-	rcu_read_unlock();
-
-	return 0;
+	wcn36xx_warn("STA with addr %pM and index %d not found\n",
+		     rsp->addr2,
+		     rsp->sta_id);
+	return -ENOENT;
 }
 
 int wcn36xx_smd_update_cfg(struct wcn36xx *wcn, u32 cfg_id, u32 value)
diff --git a/wcn36xx.h b/wcn36xx.h
index 8f21551..aac9d6a 100644
--- a/wcn36xx.h
+++ b/wcn36xx.h
@@ -114,6 +114,8 @@ struct wcn36xx_platform_ctrl_ops {
  * enter/exit_bmps.
  */
 struct wcn36xx_vif {
+	struct list_head list;
+	struct wcn36xx_sta *sta;
 	u8 bss_index;
 	u8 ucast_dpu_signature;
 	/* Returned from WCN36XX_HAL_ADD_STA_SELF_RSP */
@@ -158,6 +160,7 @@ struct wcn36xx {
 	struct mac_address	addresses;
 	struct wcn36xx_hal_mac_ssid ssid;
 	u16			aid;
+	struct list_head	vif_list;
 	struct wcn36xx_vif	*current_vif;
 	struct wcn36xx_sta	*sta;
 	u8			dtim_period;
-- 
1.8.2.2




More information about the wcn36xx mailing list