mirror of https://gitee.com/openkylin/linux.git
wlcore/wl18xx: handle rc updates in a separate work
sta_rc_update runs in atomic context. thus, a new work should be scheduled in order to configure the fw with the required configuration. Signed-off-by: Eliad Peller <eliad@wizery.com> Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
This commit is contained in:
parent
16129d1d59
commit
7d3b29e5c8
|
@ -1559,26 +1559,19 @@ static u32 wl18xx_pre_pkt_send(struct wl1271 *wl,
|
|||
}
|
||||
|
||||
static void wl18xx_sta_rc_update(struct wl1271 *wl,
|
||||
struct wl12xx_vif *wlvif,
|
||||
struct ieee80211_sta *sta,
|
||||
u32 changed)
|
||||
struct wl12xx_vif *wlvif)
|
||||
{
|
||||
bool wide = sta->bandwidth >= IEEE80211_STA_RX_BW_40;
|
||||
bool wide = wlvif->rc_update_bw >= IEEE80211_STA_RX_BW_40;
|
||||
|
||||
wl1271_debug(DEBUG_MAC80211, "mac80211 sta_rc_update wide %d", wide);
|
||||
|
||||
if (!(changed & IEEE80211_RC_BW_CHANGED))
|
||||
return;
|
||||
|
||||
mutex_lock(&wl->mutex);
|
||||
|
||||
/* sanity */
|
||||
if (WARN_ON(wlvif->bss_type != BSS_TYPE_STA_BSS))
|
||||
goto out;
|
||||
return;
|
||||
|
||||
/* ignore the change before association */
|
||||
if (!test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags))
|
||||
goto out;
|
||||
return;
|
||||
|
||||
/*
|
||||
* If we started out as wide, we can change the operation mode. If we
|
||||
|
@ -1589,9 +1582,6 @@ static void wl18xx_sta_rc_update(struct wl1271 *wl,
|
|||
wl18xx_acx_peer_ht_operation_mode(wl, wlvif->sta.hlid, wide);
|
||||
else
|
||||
ieee80211_connection_loss(wl12xx_wlvif_to_vif(wlvif));
|
||||
|
||||
out:
|
||||
mutex_unlock(&wl->mutex);
|
||||
}
|
||||
|
||||
static int wl18xx_set_peer_cap(struct wl1271 *wl,
|
||||
|
|
|
@ -211,11 +211,10 @@ wlcore_hw_pre_pkt_send(struct wl1271 *wl, u32 buf_offset, u32 last_len)
|
|||
}
|
||||
|
||||
static inline void
|
||||
wlcore_hw_sta_rc_update(struct wl1271 *wl, struct wl12xx_vif *wlvif,
|
||||
struct ieee80211_sta *sta, u32 changed)
|
||||
wlcore_hw_sta_rc_update(struct wl1271 *wl, struct wl12xx_vif *wlvif)
|
||||
{
|
||||
if (wl->ops->sta_rc_update)
|
||||
wl->ops->sta_rc_update(wl, wlvif, sta, changed);
|
||||
wl->ops->sta_rc_update(wl, wlvif);
|
||||
}
|
||||
|
||||
static inline int
|
||||
|
|
|
@ -226,6 +226,29 @@ void wl12xx_rearm_tx_watchdog_locked(struct wl1271 *wl)
|
|||
msecs_to_jiffies(wl->conf.tx.tx_watchdog_timeout));
|
||||
}
|
||||
|
||||
static void wlcore_rc_update_work(struct work_struct *work)
|
||||
{
|
||||
int ret;
|
||||
struct wl12xx_vif *wlvif = container_of(work, struct wl12xx_vif,
|
||||
rc_update_work);
|
||||
struct wl1271 *wl = wlvif->wl;
|
||||
|
||||
mutex_lock(&wl->mutex);
|
||||
|
||||
if (unlikely(wl->state != WLCORE_STATE_ON))
|
||||
goto out;
|
||||
|
||||
ret = wl1271_ps_elp_wakeup(wl);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
wlcore_hw_sta_rc_update(wl, wlvif);
|
||||
|
||||
wl1271_ps_elp_sleep(wl);
|
||||
out:
|
||||
mutex_unlock(&wl->mutex);
|
||||
}
|
||||
|
||||
static void wl12xx_tx_watchdog_work(struct work_struct *work)
|
||||
{
|
||||
struct delayed_work *dwork;
|
||||
|
@ -2279,6 +2302,7 @@ static int wl12xx_init_vif_data(struct wl1271 *wl, struct ieee80211_vif *vif)
|
|||
wl1271_rx_streaming_enable_work);
|
||||
INIT_WORK(&wlvif->rx_streaming_disable_work,
|
||||
wl1271_rx_streaming_disable_work);
|
||||
INIT_WORK(&wlvif->rc_update_work, wlcore_rc_update_work);
|
||||
INIT_DELAYED_WORK(&wlvif->channel_switch_work,
|
||||
wlcore_channel_switch_work);
|
||||
INIT_DELAYED_WORK(&wlvif->connection_loss_work,
|
||||
|
@ -2723,6 +2747,7 @@ static void __wl1271_op_remove_interface(struct wl1271 *wl,
|
|||
del_timer_sync(&wlvif->rx_streaming_timer);
|
||||
cancel_work_sync(&wlvif->rx_streaming_enable_work);
|
||||
cancel_work_sync(&wlvif->rx_streaming_disable_work);
|
||||
cancel_work_sync(&wlvif->rc_update_work);
|
||||
cancel_delayed_work_sync(&wlvif->connection_loss_work);
|
||||
cancel_delayed_work_sync(&wlvif->channel_switch_work);
|
||||
cancel_delayed_work_sync(&wlvif->pending_auth_complete_work);
|
||||
|
@ -5370,9 +5395,15 @@ static void wlcore_op_sta_rc_update(struct ieee80211_hw *hw,
|
|||
u32 changed)
|
||||
{
|
||||
struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
|
||||
struct wl1271 *wl = hw->priv;
|
||||
|
||||
wlcore_hw_sta_rc_update(wl, wlvif, sta, changed);
|
||||
wl1271_debug(DEBUG_MAC80211, "mac80211 sta_rc_update");
|
||||
|
||||
if (!(changed & IEEE80211_RC_BW_CHANGED))
|
||||
return;
|
||||
|
||||
/* this callback is atomic, so schedule a new work */
|
||||
wlvif->rc_update_bw = sta->bandwidth;
|
||||
ieee80211_queue_work(hw, &wlvif->rc_update_work);
|
||||
}
|
||||
|
||||
static int wlcore_op_get_rssi(struct ieee80211_hw *hw,
|
||||
|
|
|
@ -106,8 +106,7 @@ struct wlcore_ops {
|
|||
struct wl12xx_vif *wlvif,
|
||||
struct ieee80211_channel_switch *ch_switch);
|
||||
u32 (*pre_pkt_send)(struct wl1271 *wl, u32 buf_offset, u32 last_len);
|
||||
void (*sta_rc_update)(struct wl1271 *wl, struct wl12xx_vif *wlvif,
|
||||
struct ieee80211_sta *sta, u32 changed);
|
||||
void (*sta_rc_update)(struct wl1271 *wl, struct wl12xx_vif *wlvif);
|
||||
int (*set_peer_cap)(struct wl1271 *wl,
|
||||
struct ieee80211_sta_ht_cap *ht_cap,
|
||||
bool allow_ht_operation,
|
||||
|
|
|
@ -463,6 +463,10 @@ struct wl12xx_vif {
|
|||
/* work for canceling ROC after pending auth reply */
|
||||
struct delayed_work pending_auth_complete_work;
|
||||
|
||||
/* update rate conrol */
|
||||
enum ieee80211_sta_rx_bandwidth rc_update_bw;
|
||||
struct work_struct rc_update_work;
|
||||
|
||||
/*
|
||||
* total freed FW packets on the link.
|
||||
* For STA this holds the PN of the link to the AP.
|
||||
|
|
Loading…
Reference in New Issue