Return-path: Received: from wolverine01.qualcomm.com ([199.106.114.254]:56670 "EHLO wolverine01.qualcomm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754129Ab1H2RqE (ORCPT ); Mon, 29 Aug 2011 13:46:04 -0400 From: Rajkumar Manoharan To: CC: , Rajkumar Manoharan Subject: [RFC v3] mac80211: stop tx before doing hw config and rate update Date: Mon, 29 Aug 2011 23:16:27 +0530 Message-ID: <1314639987-5927-1-git-send-email-rmanohar@qca.qualcomm.com> (sfid-20110829_194608_686526_977D010F) MIME-Version: 1.0 Content-Type: text/plain Sender: linux-wireless-owner@vger.kernel.org List-ID: The assumption is that during the hw config, transmission was already stopped by mac80211. But during channel type change, the mac80211 continue to transmit frames. The driver like ath9k does chip reset while doing channel set. This could leads to buffer overflow at driver side. And also after configuring the channel and before calling rate updation, the frames are continued to xmit with older rates. This patch ensures that the frames are always xmitted with updated rates and avoid buffer overflow. Signed-off-by: Rajkumar Manoharan --- v2: Removed new stop queue reason code by netif v3: Replaced netif by ieee80211_queue_stop and call synchronize_net before flush net/mac80211/ieee80211_i.h | 1 + net/mac80211/mlme.c | 10 ++++++++++ 2 files changed, 11 insertions(+), 0 deletions(-) diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index c204cee..8db9f9a 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -670,6 +670,7 @@ enum queue_stop_reason { IEEE80211_QUEUE_STOP_REASON_AGGREGATION, IEEE80211_QUEUE_STOP_REASON_SUSPEND, IEEE80211_QUEUE_STOP_REASON_SKB_ADD, + IEEE80211_QUEUE_STOP_REASON_CHTYPE_CHANGE, }; #ifdef CONFIG_MAC80211_LEDS diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 60a6f27..5b51390 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -232,6 +232,13 @@ static u32 ieee80211_enable_ht(struct ieee80211_sub_if_data *sdata, WARN_ON(!ieee80211_set_channel_type(local, sdata, channel_type)); } + ieee80211_stop_queues_by_reason(&sdata->local->hw, + IEEE80211_QUEUE_STOP_REASON_CHTYPE_CHANGE); + + /* flush out all packets */ + synchronize_net(); + + drv_flush(local, false); /* channel_type change automatically detected */ ieee80211_hw_config(local, 0); @@ -245,6 +252,9 @@ static u32 ieee80211_enable_ht(struct ieee80211_sub_if_data *sdata, rcu_read_unlock(); } + ieee80211_wake_queues_by_reason(&sdata->local->hw, + IEEE80211_QUEUE_STOP_REASON_CHTYPE_CHANGE); + ht_opmode = le16_to_cpu(hti->operation_mode); /* if bss configuration changed store the new one */ -- 1.7.6.1