[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