[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