From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail.linuxfoundation.org ([140.211.169.12]:45620 "EHLO mail.linuxfoundation.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932493AbdEKOWt (ORCPT ); Thu, 11 May 2017 10:22:49 -0400 From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Johannes Berg , Luca Coelho Subject: [PATCH 4.9 032/103] iwlwifi: mvm: overwrite skb info later Date: Thu, 11 May 2017 16:12:01 +0200 Message-Id: <20170511141213.161780436@linuxfoundation.org> In-Reply-To: <20170511141210.778405364@linuxfoundation.org> References: <20170511141210.778405364@linuxfoundation.org> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Sender: stable-owner@vger.kernel.org List-ID: 4.9-stable review patch. If anyone has any objections, please let me know. ------------------ From: Johannes Berg commit bd05a5bd6b11d7fd26a668de83c5cb996de05f8f upstream. We don't really need clear the skb's status area nor store the dev_cmd into it until we really commit to the frame by handing it to the transport - defer those operations until just before we do that. This doesn't entirely fix the bug with frames not getting sent out after having been deferred due to DQA, because it doesn't restore the info->driver_data[0] place that was already set to zero (or another value) by the A-MSDU logic. Fixes: 24afba7690e4 ("iwlwifi: mvm: support bss dynamic alloc/dealloc of queues") Signed-off-by: Johannes Berg Signed-off-by: Luca Coelho Signed-off-by: Greg Kroah-Hartman --- drivers/net/wireless/intel/iwlwifi/mvm/tx.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) --- a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c @@ -459,7 +459,6 @@ iwl_mvm_set_tx_params(struct iwl_mvm *mv struct ieee80211_sta *sta, u8 sta_id) { struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; - struct ieee80211_tx_info *skb_info = IEEE80211_SKB_CB(skb); struct iwl_device_cmd *dev_cmd; struct iwl_tx_cmd *tx_cmd; @@ -479,12 +478,18 @@ iwl_mvm_set_tx_params(struct iwl_mvm *mv iwl_mvm_set_tx_cmd_rate(mvm, tx_cmd, info, sta, hdr->frame_control); + return dev_cmd; +} + +static void iwl_mvm_skb_prepare_status(struct sk_buff *skb, + struct iwl_device_cmd *cmd) +{ + struct ieee80211_tx_info *skb_info = IEEE80211_SKB_CB(skb); + memset(&skb_info->status, 0, sizeof(skb_info->status)); memset(skb_info->driver_data, 0, sizeof(skb_info->driver_data)); - skb_info->driver_data[1] = dev_cmd; - - return dev_cmd; + skb_info->driver_data[1] = cmd; } static int iwl_mvm_get_ctrl_vif_queue(struct iwl_mvm *mvm, @@ -598,6 +603,9 @@ int iwl_mvm_tx_skb_non_sta(struct iwl_mv if (!dev_cmd) return -1; + /* From now on, we cannot access info->control */ + iwl_mvm_skb_prepare_status(skb, dev_cmd); + tx_cmd = (struct iwl_tx_cmd *)dev_cmd->payload; /* Copy MAC header from skb into command buffer */ @@ -908,7 +916,6 @@ static int iwl_mvm_tx_mpdu(struct iwl_mv goto drop; tx_cmd = (struct iwl_tx_cmd *)dev_cmd->payload; - /* From now on, we cannot access info->control */ /* * we handle that entirely ourselves -- for uAPSD the firmware @@ -1015,6 +1022,9 @@ static int iwl_mvm_tx_mpdu(struct iwl_mv IWL_DEBUG_TX(mvm, "TX to [%d|%d] Q:%d - seq: 0x%x\n", mvmsta->sta_id, tid, txq_id, IEEE80211_SEQ_TO_SN(seq_number)); + /* From now on, we cannot access info->control */ + iwl_mvm_skb_prepare_status(skb, dev_cmd); + if (iwl_trans_tx(mvm->trans, skb, dev_cmd, txq_id)) goto drop_unlock_sta;