[PATCH 4/8] wcn36xx: do not use current_vif on data path

Eugene Krasnikov k.eugene.e at gmail.com
Mon Sep 9 09:35:18 EDT 2013


use sta pointer or list of vifs instead.

Signed-off-by: Eugene Krasnikov <k.eugene.e at gmail.com>
---
 dxe.c     |  3 ++-
 dxe.h     |  3 +++
 main.c    |  4 +++-
 txrx.c    | 52 ++++++++++++++++++++++++++++++++++++++++------------
 wcn36xx.h |  1 +
 5 files changed, 49 insertions(+), 14 deletions(-)

diff --git a/dxe.c b/dxe.c
index 93ea934..ee25786 100644
--- a/dxe.c
+++ b/dxe.c
@@ -577,6 +577,7 @@ void wcn36xx_dxe_free_mem_pools(struct wcn36xx *wcn)
 }
 
 int wcn36xx_dxe_tx_frame(struct wcn36xx *wcn,
+			 struct wcn36xx_vif *vif_priv,
 			 struct sk_buff *skb,
 			 bool is_low)
 {
@@ -655,7 +656,7 @@ int wcn36xx_dxe_tx_frame(struct wcn36xx *wcn,
 	 * mode and writing to the register will not wake up the chip. Instead
 	 * notify chip about new frame through SMSM bus.
 	 */
-	if (is_low &&  wcn->current_vif->pw_state == WCN36XX_BMPS) {
+	if (is_low &&  vif_priv->pw_state == WCN36XX_BMPS) {
 		wcn->ctrl_ops->smsm_change_state(
 				  0,
 				  WCN36XX_SMSM_WLAN_TX_ENABLE);
diff --git a/dxe.h b/dxe.h
index 38e458e..c88562f 100644
--- a/dxe.h
+++ b/dxe.h
@@ -265,6 +265,8 @@ struct wcn36xx_dxe_mem_pool {
 	void		*virt_addr;
 	dma_addr_t	phy_addr;
 };
+
+struct wcn36xx_vif;
 int wcn36xx_dxe_allocate_mem_pools(struct wcn36xx *wcn);
 void wcn36xx_dxe_free_mem_pools(struct wcn36xx *wcn);
 void wcn36xx_dxe_rx_frame(struct wcn36xx *wcn);
@@ -274,6 +276,7 @@ int wcn36xx_dxe_init(struct wcn36xx *wcn);
 void wcn36xx_dxe_deinit(struct wcn36xx *wcn);
 int wcn36xx_dxe_init_channels(struct wcn36xx *wcn);
 int wcn36xx_dxe_tx_frame(struct wcn36xx *wcn,
+			 struct wcn36xx_vif *vif_priv,
 			 struct sk_buff *skb,
 			 bool is_low);
 void wcn36xx_dxe_tx_ack_ind(struct wcn36xx *wcn, u32 status);
diff --git a/main.c b/main.c
index 814b101..b701ef1 100644
--- a/main.c
+++ b/main.c
@@ -700,7 +700,8 @@ static int wcn36xx_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
 		    vif, sta->addr);
 
 	wcn->sta = (struct wcn36xx_sta *)sta->drv_priv;
-	vif_priv->sta = (struct wcn36xx_sta *)sta->drv_priv;
+	vif_priv->sta = sta_priv;
+	sta_priv->vif = vif_priv;
 	/*
 	 * For STA mode HW will be configured on BSS_CHANGED_ASSOC because
 	 * at this stage AID is not available yet.
@@ -725,6 +726,7 @@ static int wcn36xx_sta_remove(struct ieee80211_hw *hw,
 
 	wcn36xx_smd_delete_sta(wcn, sta_priv->sta_index);
 	vif_priv->sta = NULL;
+	sta_priv->vif = NULL;
 	return 0;
 }
 
diff --git a/txrx.c b/txrx.c
index 309e26d..b2b60e3 100644
--- a/txrx.c
+++ b/txrx.c
@@ -96,23 +96,42 @@ static void wcn36xx_set_tx_pdu(struct wcn36xx_tx_bd *bd,
 	bd->pdu.tid = tid;
 }
 
+static inline struct wcn36xx_vif *get_vif_by_addr(struct wcn36xx *wcn,
+						  u8 *addr)
+{
+	struct wcn36xx_vif *vif_priv = NULL;
+	struct ieee80211_vif *vif = NULL;
+	list_for_each_entry(vif_priv, &wcn->vif_list, list) {
+			vif = container_of((void *)vif_priv,
+				   struct ieee80211_vif,
+				   drv_priv);
+			if (memcmp(vif->addr, addr, ETH_ALEN) == 0)
+				return vif_priv;
+	}
+	wcn36xx_warn("vif %pM not found\n", addr);
+	return NULL;
+}
 static void wcn36xx_set_tx_data(struct wcn36xx_tx_bd *bd,
 				struct wcn36xx *wcn,
+				struct wcn36xx_vif **vif_priv,
 				struct wcn36xx_sta *sta_priv,
 				struct ieee80211_hdr *hdr,
 				bool bcast)
 {
-	struct ieee80211_vif *vif = container_of((void *)wcn->current_vif,
-						 struct ieee80211_vif,
-						 drv_priv);
+	struct ieee80211_vif *vif = NULL;
+	struct wcn36xx_vif *__vif_priv = NULL;
 	bd->bd_rate = WCN36XX_BD_RATE_DATA;
-	bd->dpu_sign = wcn->current_vif->ucast_dpu_signature;
 
 	/*
 	 * For not unicast frames mac80211 will not set sta pointer so use
 	 * self_sta_index instead.
 	 */
 	if (sta_priv) {
+		__vif_priv = sta_priv->vif;
+		vif = container_of((void *)__vif_priv,
+				   struct ieee80211_vif,
+				   drv_priv);
+
 		if (vif->type == NL80211_IFTYPE_STATION) {
 			bd->sta_index = sta_priv->bss_sta_index;
 			bd->dpu_desc_idx = sta_priv->bss_dpu_desc_index;
@@ -123,10 +142,13 @@ static void wcn36xx_set_tx_data(struct wcn36xx_tx_bd *bd,
 			bd->dpu_desc_idx = sta_priv->dpu_desc_index;
 		}
 	} else {
-		bd->sta_index = wcn->current_vif->self_sta_index;
-		bd->dpu_desc_idx = wcn->current_vif->self_dpu_desc_index;
+		__vif_priv = get_vif_by_addr(wcn, hdr->addr2);
+		bd->sta_index = __vif_priv->self_sta_index;
+		bd->dpu_desc_idx = __vif_priv->self_dpu_desc_index;
 	}
 
+	bd->dpu_sign = __vif_priv->ucast_dpu_signature;
+
 	if (ieee80211_is_nullfunc(hdr->frame_control) ||
 	   (sta_priv && !sta_priv->is_data_encrypted))
 		bd->dpu_ne = 1;
@@ -135,15 +157,19 @@ static void wcn36xx_set_tx_data(struct wcn36xx_tx_bd *bd,
 		bd->ub = 1;
 		bd->ack_policy = 1;
 	}
+	*vif_priv = __vif_priv;
 }
 
 static void wcn36xx_set_tx_mgmt(struct wcn36xx_tx_bd *bd,
 				struct wcn36xx *wcn,
+				struct wcn36xx_vif **vif_priv,
 				struct ieee80211_hdr *hdr,
 				bool bcast)
 {
-	bd->sta_index = wcn->current_vif->self_sta_index;
-	bd->dpu_desc_idx = wcn->current_vif->self_dpu_desc_index;
+	struct wcn36xx_vif *__vif_priv =
+		get_vif_by_addr(wcn, hdr->addr2);
+	bd->sta_index = __vif_priv->self_sta_index;
+	bd->dpu_desc_idx = __vif_priv->self_dpu_desc_index;
 	bd->dpu_ne = 1;
 
 	/* default rate for unicast */
@@ -160,7 +186,7 @@ static void wcn36xx_set_tx_mgmt(struct wcn36xx_tx_bd *bd,
 	 * In joining state trick hardware that probe is sent as
 	 * unicast even if address is broadcast.
 	 */
-	if (wcn->current_vif->is_joining &&
+	if (__vif_priv->is_joining &&
 	    ieee80211_is_probe_req(hdr->frame_control))
 		bcast = false;
 
@@ -172,6 +198,7 @@ static void wcn36xx_set_tx_mgmt(struct wcn36xx_tx_bd *bd,
 		bd->queue_id = WCN36XX_TX_B_WQ_ID;
 	} else
 		bd->queue_id = WCN36XX_TX_U_WQ_ID;
+	*vif_priv = __vif_priv;
 }
 
 int wcn36xx_start_tx(struct wcn36xx *wcn,
@@ -179,6 +206,7 @@ int wcn36xx_start_tx(struct wcn36xx *wcn,
 		     struct sk_buff *skb)
 {
 	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
+	struct wcn36xx_vif *vif_priv = NULL;
 	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
 	unsigned long flags;
 	bool is_low = ieee80211_is_data(hdr->frame_control);
@@ -233,7 +261,7 @@ int wcn36xx_start_tx(struct wcn36xx *wcn,
 
 	/* Data frames served first*/
 	if (is_low) {
-		wcn36xx_set_tx_data(bd, wcn, sta_priv, hdr, bcast);
+		wcn36xx_set_tx_data(bd, wcn, &vif_priv, sta_priv, hdr, bcast);
 		wcn36xx_set_tx_pdu(bd,
 			   ieee80211_is_data_qos(hdr->frame_control) ?
 			   sizeof(struct ieee80211_qos_hdr) :
@@ -241,7 +269,7 @@ int wcn36xx_start_tx(struct wcn36xx *wcn,
 			   skb->len, sta_priv ? sta_priv->tid : 0);
 	} else {
 		/* MGMT and CTRL frames are handeld here*/
-		wcn36xx_set_tx_mgmt(bd, wcn, hdr, bcast);
+		wcn36xx_set_tx_mgmt(bd, wcn, &vif_priv, hdr, bcast);
 		wcn36xx_set_tx_pdu(bd,
 			   ieee80211_is_data_qos(hdr->frame_control) ?
 			   sizeof(struct ieee80211_qos_hdr) :
@@ -252,5 +280,5 @@ int wcn36xx_start_tx(struct wcn36xx *wcn,
 	buff_to_be((u32 *)bd, sizeof(*bd)/sizeof(u32));
 	bd->tx_bd_sign = 0xbdbdbdbd;
 
-	return wcn36xx_dxe_tx_frame(wcn, skb, is_low);
+	return wcn36xx_dxe_tx_frame(wcn, vif_priv, skb, is_low);
 }
diff --git a/wcn36xx.h b/wcn36xx.h
index 1c8aaa7..3ada137 100644
--- a/wcn36xx.h
+++ b/wcn36xx.h
@@ -153,6 +153,7 @@ struct wcn36xx_vif {
  * |______________|_____________|_______________|
  */
 struct wcn36xx_sta {
+	struct wcn36xx_vif *vif;
 	u16 aid;
 	u16 tid;
 	u8 sta_index;
-- 
1.8.2.2




More information about the wcn36xx mailing list