lkml.org 
[lkml]   [2014]   [Feb]   [20]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 3.13 14/99] ath9k_htc: make ->sta_rc_update atomic for most calls
    Date
    3.13-stable review patch.  If anyone has any objections, please let me know.

    ------------------

    From: Stanislaw Gruszka <sgruszka@redhat.com>

    commit 2fa4cb905605c863bf570027233af7afd8149ae4 upstream.

    sta_rc_update() callback must be atomic, hence we can not take mutexes
    or do other operations, which can sleep in ath9k_htc_sta_rc_update().

    I think we can just return from ath9k_htc_sta_rc_update(), if it is
    called without IEEE80211_RC_SUPP_RATES_CHANGED bit. That will help
    with scheduling while atomic bug for most cases (except mesh and IBSS
    modes).

    For mesh and IBSS I do not see other solution like creating additional
    workqueue, because sending firmware command require us to sleep, but
    this can be done in additional patch.

    Patch partially fixes bug:
    https://bugzilla.redhat.com/show_bug.cgi?id=990955

    Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
    Signed-off-by: John W. Linville <linville@tuxdriver.com>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

    ---
    drivers/net/wireless/ath/ath9k/htc_drv_main.c | 25 +++++++++++++------------
    1 file changed, 13 insertions(+), 12 deletions(-)

    --- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c
    +++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
    @@ -1315,21 +1315,22 @@ static void ath9k_htc_sta_rc_update(stru
    struct ath_common *common = ath9k_hw_common(priv->ah);
    struct ath9k_htc_target_rate trate;

    + if (!(changed & IEEE80211_RC_SUPP_RATES_CHANGED))
    + return;
    +
    mutex_lock(&priv->mutex);
    ath9k_htc_ps_wakeup(priv);

    - if (changed & IEEE80211_RC_SUPP_RATES_CHANGED) {
    - memset(&trate, 0, sizeof(struct ath9k_htc_target_rate));
    - ath9k_htc_setup_rate(priv, sta, &trate);
    - if (!ath9k_htc_send_rate_cmd(priv, &trate))
    - ath_dbg(common, CONFIG,
    - "Supported rates for sta: %pM updated, rate caps: 0x%X\n",
    - sta->addr, be32_to_cpu(trate.capflags));
    - else
    - ath_dbg(common, CONFIG,
    - "Unable to update supported rates for sta: %pM\n",
    - sta->addr);
    - }
    + memset(&trate, 0, sizeof(struct ath9k_htc_target_rate));
    + ath9k_htc_setup_rate(priv, sta, &trate);
    + if (!ath9k_htc_send_rate_cmd(priv, &trate))
    + ath_dbg(common, CONFIG,
    + "Supported rates for sta: %pM updated, rate caps: 0x%X\n",
    + sta->addr, be32_to_cpu(trate.capflags));
    + else
    + ath_dbg(common, CONFIG,
    + "Unable to update supported rates for sta: %pM\n",
    + sta->addr);

    ath9k_htc_ps_restore(priv);
    mutex_unlock(&priv->mutex);



    \
     
     \ /
      Last update: 2014-02-21 02:02    [W:2.355 / U:0.084 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site