From patchwork Fri Feb 22 00:30:44 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christian Lamparter X-Patchwork-Id: 2174121 Return-Path: X-Original-To: patchwork-linux-wireless@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork2.kernel.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by patchwork2.kernel.org (Postfix) with ESMTP id 73A16DF215 for ; Fri, 22 Feb 2013 00:30:55 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755502Ab3BVAax (ORCPT ); Thu, 21 Feb 2013 19:30:53 -0500 Received: from mail-ea0-f169.google.com ([209.85.215.169]:59416 "EHLO mail-ea0-f169.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754728Ab3BVAaw (ORCPT ); Thu, 21 Feb 2013 19:30:52 -0500 Received: by mail-ea0-f169.google.com with SMTP id d13so42080eaa.14 for ; Thu, 21 Feb 2013 16:30:51 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=googlemail.com; s=20120113; h=x-received:subject:to:cc:from:date:mime-version:content-type :content-transfer-encoding:message-id; bh=gCnoYi2pVCpZQY/9x+1MsAVW9tMiLKKkDbe7SR6oOlw=; b=fgtivWsLD+diOlooamw+jmalRWTRr3QEAnVln/RyO1QPtfDRJEfr07+8JNzNgf/Qit q/bW/LGMrQ/SITMcuMD9vsooAxNZzACC2hY67yKmwE7gcEuQyKzk8sClGhXSuSJdgnXx 5Qf53bIsWrLg1GXW7PCxe4YT7UG8ixQnHjyFi3rhbbGfo1YZifMn4X/SZeb5zRboY9md vMOgLEBWjkc6xGttCzwXQQ5I843U3doebQKywo3ab+ROlvkaOKlSybNju2oPLF58r36U U1cwGLWvumFg4ayMcVLvZFHlik4YDHWbozARdkIct/1nclop9jDtMZXsF0Gb7VS4aVp3 R/1A== X-Received: by 10.14.200.137 with SMTP id z9mr164923een.20.1361493050902; Thu, 21 Feb 2013 16:30:50 -0800 (PST) Received: from debian64.localnet (pD9F8BA93.dip.t-dialin.net. [217.248.186.147]) by mx.google.com with ESMTPS id l8sm556574een.10.2013.02.21.16.30.49 (version=TLSv1.2 cipher=RC4-SHA bits=128/128); Thu, 21 Feb 2013 16:30:49 -0800 (PST) Received: from localhost ([127.0.0.1] helo=debian64.localnet ident=chuck) by debian64.localnet with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.80) (envelope-from ) id 1U8gXG-0006wn-8E; Fri, 22 Feb 2013 01:30:46 +0100 Subject: [PATCH] carl9170: fix frame drop and WARN due to minstrel_ht change To: linux-wireless@vger.kernel.org Cc: "John W. Linville" From: Christian Lamparter Date: Fri, 22 Feb 2013 01:30:44 +0100 MIME-Version: 1.0 Message-Id: <201302220130.45434.chunkeey@googlemail.com> Sender: linux-wireless-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org With "mac80211/minstrel_ht: add support for using CCK rates" minstrel_ht selects legacy CCK rates as viable rates for outgoing frames which might be sent as part of an A-MPDU [IEEE80211_TX_CTL_AMPDU is set]. This behavior triggered the following WARN_ON in the driver: > WARNING: at carl9170/tx.c:995 carl9170_op_tx+0x1dd/0x6fd The driver assumed that the rate control algorithm made a mistake and dropped the frame. This patch removes the noisy warning altogether and allows said A-MPDU frames with CCK sample and/or fallback rates to be transmitted seamlessly. Signed-off-by: Christian Lamparter --- drivers/net/wireless/ath/carl9170/tx.c | 69 +++++++++++++------------------- 1 file changed, 28 insertions(+), 41 deletions(-) diff --git a/drivers/net/wireless/ath/carl9170/tx.c b/drivers/net/wireless/ath/carl9170/tx.c index 9c0b150..c61cafa 100644 --- a/drivers/net/wireless/ath/carl9170/tx.c +++ b/drivers/net/wireless/ath/carl9170/tx.c @@ -387,8 +387,7 @@ static void carl9170_tx_status_process_ampdu(struct ar9170 *ar, u8 tid; if (!(txinfo->flags & IEEE80211_TX_CTL_AMPDU) || - txinfo->flags & IEEE80211_TX_CTL_INJECTED || - (!(super->f.mac_control & cpu_to_le16(AR9170_TX_MAC_AGGR)))) + txinfo->flags & IEEE80211_TX_CTL_INJECTED) return; rcu_read_lock(); @@ -981,30 +980,6 @@ static int carl9170_tx_prepare(struct ar9170 *ar, SET_VAL(CARL9170_TX_SUPER_AMPDU_FACTOR, txc->s.ampdu_settings, factor); - - for (i = 0; i < CARL9170_TX_MAX_RATES; i++) { - txrate = &info->control.rates[i]; - if (txrate->idx >= 0) { - txc->s.ri[i] = - CARL9170_TX_SUPER_RI_AMPDU; - - if (WARN_ON(!(txrate->flags & - IEEE80211_TX_RC_MCS))) { - /* - * Not sure if it's even possible - * to aggregate non-ht rates with - * this HW. - */ - goto err_out; - } - continue; - } - - txrate->idx = 0; - txrate->count = ar->hw->max_rate_tries; - } - - mac_tmp |= cpu_to_le16(AR9170_TX_MAC_AGGR); } /* @@ -1012,11 +987,31 @@ static int carl9170_tx_prepare(struct ar9170 *ar, * taken from mac_control. For all fallback rate, the firmware * updates the mac_control flags from the rate info field. */ - for (i = 1; i < CARL9170_TX_MAX_RATES; i++) { + for (i = 0; i < CARL9170_TX_MAX_RATES; i++) { + __le32 phy_set; txrate = &info->control.rates[i]; if (txrate->idx < 0) break; + phy_set = carl9170_tx_physet(ar, info, txrate); + if (i == 0) { + /* first rate - part of the hw's frame header */ + txc->f.phy_control = phy_set; + + if (ampdu && txrate->flags & IEEE80211_TX_RC_MCS) + mac_tmp |= cpu_to_le16(AR9170_TX_MAC_AGGR); + if (carl9170_tx_rts_check(ar, txrate, ampdu, no_ack)) + mac_tmp |= cpu_to_le16(AR9170_TX_MAC_PROT_RTS); + else if (carl9170_tx_cts_check(ar, txrate)) + mac_tmp |= cpu_to_le16(AR9170_TX_MAC_PROT_CTS); + + } else { + /* fallback rates are stored in the firmware's + * retry rate set array. + */ + txc->s.rr[i - 1] = phy_set; + } + SET_VAL(CARL9170_TX_SUPER_RI_TRIES, txc->s.ri[i], txrate->count); @@ -1027,21 +1022,13 @@ static int carl9170_tx_prepare(struct ar9170 *ar, txc->s.ri[i] |= (AR9170_TX_MAC_PROT_CTS << CARL9170_TX_SUPER_RI_ERP_PROT_S); - txc->s.rr[i - 1] = carl9170_tx_physet(ar, info, txrate); + if (ampdu && (txrate->flags & IEEE80211_TX_RC_MCS)) + txc->s.ri[i] |= CARL9170_TX_SUPER_RI_AMPDU; } - txrate = &info->control.rates[0]; - SET_VAL(CARL9170_TX_SUPER_RI_TRIES, txc->s.ri[0], txrate->count); - - if (carl9170_tx_rts_check(ar, txrate, ampdu, no_ack)) - mac_tmp |= cpu_to_le16(AR9170_TX_MAC_PROT_RTS); - else if (carl9170_tx_cts_check(ar, txrate)) - mac_tmp |= cpu_to_le16(AR9170_TX_MAC_PROT_CTS); - txc->s.len = cpu_to_le16(skb->len); txc->f.length = cpu_to_le16(len + FCS_LEN); txc->f.mac_control = mac_tmp; - txc->f.phy_control = carl9170_tx_physet(ar, info, txrate); arinfo = (void *)info->rate_driver_data; arinfo->timeout = jiffies; @@ -1381,9 +1368,9 @@ static void carl9170_tx(struct ar9170 *ar) } static bool carl9170_tx_ampdu_queue(struct ar9170 *ar, - struct ieee80211_sta *sta, struct sk_buff *skb) + struct ieee80211_sta *sta, struct sk_buff *skb, + struct ieee80211_tx_info *txinfo) { - struct _carl9170_tx_superframe *super = (void *) skb->data; struct carl9170_sta_info *sta_info; struct carl9170_sta_tid *agg; struct sk_buff *iter; @@ -1450,7 +1437,7 @@ err_unlock: err_unlock_rcu: rcu_read_unlock(); - super->f.mac_control &= ~cpu_to_le16(AR9170_TX_MAC_AGGR); + txinfo->flags &= ~IEEE80211_TX_CTL_AMPDU; carl9170_tx_status(ar, skb, false); ar->tx_dropped++; return false; @@ -1492,7 +1479,7 @@ void carl9170_op_tx(struct ieee80211_hw *hw, * sta == NULL checks are redundant in this * special case. */ - run = carl9170_tx_ampdu_queue(ar, sta, skb); + run = carl9170_tx_ampdu_queue(ar, sta, skb, info); if (run) carl9170_tx_ampdu(ar);