From 8d21eedde1693dbeec87f7374bed3e5ae61512a7 Mon Sep 17 00:00:00 2001 From: Lukasz Kucharczyk Date: Wed, 29 Feb 2012 15:15:07 +0100 Subject: cw1200: Change behavior on Action frame RX. When Action frame is received with linkid assigned (not equal 0), send reset and remap commands for this linkid to firmware. When Action frame is received without linkid (equal 0), assign new linkid, issue map and reset commands to firmware for this linkid. Note the different map-reset order for both cases! ST-Ericsson ID: 372718 ST-Ericsson FOSS-OUT ID: NA Signed-off-by: Lukasz Kucharczyk Change-Id: Ib839b92858564f4f759336cb83044217473cac53 Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/41137 Tested-by: Lukasz KUCHARCZYK Reviewed-by: Bartosz MARKOWSKI --- drivers/staging/cw1200/ap.c | 24 +++++++++++++++++++++++- drivers/staging/cw1200/cw1200.h | 7 +++++++ drivers/staging/cw1200/txrx.c | 16 +++++++++------- 3 files changed, 39 insertions(+), 8 deletions(-) diff --git a/drivers/staging/cw1200/ap.c b/drivers/staging/cw1200/ap.c index ff8d36cbedb..1211e127c52 100755 --- a/drivers/staging/cw1200/ap.c +++ b/drivers/staging/cw1200/ap.c @@ -1025,8 +1025,30 @@ void cw1200_link_id_gc_work(struct work_struct *work) WARN_ON(wsm_reset(priv, &reset)); spin_lock_bh(&priv->ps_state_lock); } else { - next_gc = min(next_gc, (unsigned long)ttl); + next_gc = min_t(unsigned long, next_gc, ttl); } +#if defined(CONFIG_CW1200_USE_STE_EXTENSIONS) + } else if (priv->link_id_db[i].status == CW1200_LINK_RESET || + priv->link_id_db[i].status == + CW1200_LINK_RESET_REMAP) { + int status = priv->link_id_db[i].status; + priv->link_id_db[i].status = + priv->link_id_db[i].prev_status; + priv->link_id_db[i].timestamp = now; + reset.link_id = i + 1; + spin_unlock_bh(&priv->ps_state_lock); + WARN_ON(wsm_reset(priv, &reset)); + if (status == CW1200_LINK_RESET_REMAP) { + memcpy(map_link.mac_addr, + priv->link_id_db[i].mac, + ETH_ALEN); + map_link.link_id = i + 1; + WARN_ON(wsm_map_link(priv, &map_link)); + next_gc = min(next_gc, + CW1200_LINK_ID_GC_TIMEOUT); + } + spin_lock_bh(&priv->ps_state_lock); +#endif } if (need_reset) { skb_queue_purge(&priv->link_id_db[i].rx_queue); diff --git a/drivers/staging/cw1200/cw1200.h b/drivers/staging/cw1200/cw1200.h index d3ecb2a950f..c24dc420db4 100644 --- a/drivers/staging/cw1200/cw1200.h +++ b/drivers/staging/cw1200/cw1200.h @@ -65,6 +65,10 @@ enum cw1200_link_status { CW1200_LINK_RESERVE, CW1200_LINK_SOFT, CW1200_LINK_HARD, +#if defined(CONFIG_CW1200_USE_STE_EXTENSIONS) + CW1200_LINK_RESET, + CW1200_LINK_RESET_REMAP, +#endif }; enum cw1200_bss_loss_status { @@ -77,6 +81,9 @@ enum cw1200_bss_loss_status { struct cw1200_link_entry { unsigned long timestamp; enum cw1200_link_status status; +#if defined(CONFIG_CW1200_USE_STE_EXTENSIONS) + enum cw1200_link_status prev_status; +#endif u8 mac[ETH_ALEN]; u8 buffered[CW1200_MAX_TID]; struct sk_buff_head rx_queue; diff --git a/drivers/staging/cw1200/txrx.c b/drivers/staging/cw1200/txrx.c index 9569fd5849f..b8859326612 100644 --- a/drivers/staging/cw1200/txrx.c +++ b/drivers/staging/cw1200/txrx.c @@ -1265,8 +1265,10 @@ void cw1200_link_id_reset(struct work_struct *work) flush_workqueue(priv->workqueue); /* Release the link ID */ spin_lock(&priv->ps_state_lock); + priv->link_id_db[temp_linkid - 1].prev_status = + priv->link_id_db[temp_linkid - 1].status; priv->link_id_db[temp_linkid - 1].status = - CW1200_LINK_RESERVE; + CW1200_LINK_RESET; spin_unlock(&priv->ps_state_lock); wsm_lock_tx_async(priv); if (queue_work(priv->workqueue, @@ -1275,15 +1277,15 @@ void cw1200_link_id_reset(struct work_struct *work) } } else { spin_lock(&priv->ps_state_lock); - entry = &priv->link_id_db[priv->action_linkid - 1]; + priv->link_id_db[priv->action_linkid - 1].prev_status = + priv->link_id_db[priv->action_linkid - 1].status; + priv->link_id_db[priv->action_linkid - 1].status = + CW1200_LINK_RESET_REMAP; + spin_unlock(&priv->ps_state_lock); wsm_lock_tx_async(priv); if (queue_work(priv->workqueue, &priv->link_id_work) <= 0) - wsm_unlock_tx(priv); - spin_unlock(&priv->ps_state_lock); + wsm_unlock_tx(priv); flush_workqueue(priv->workqueue); - temp_linkid = cw1200_alloc_link_id(priv, - &priv->action_frame_sa[0]); - WARN_ON(!temp_linkid); } } #endif -- cgit v1.2.3