From patchwork Fri Jul 26 17:58:34 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Karl Beldan X-Patchwork-Id: 2834300 Return-Path: X-Original-To: patchwork-linux-wireless@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork2.web.kernel.org (Postfix) with ESMTP id B9DE9C0319 for ; Fri, 26 Jul 2013 18:06:02 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 8CCD320198 for ; Fri, 26 Jul 2013 18:06:01 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 3ADBD2017E for ; Fri, 26 Jul 2013 18:06:00 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751301Ab3GZSF6 (ORCPT ); Fri, 26 Jul 2013 14:05:58 -0400 Received: from mail-we0-f171.google.com ([74.125.82.171]:57315 "EHLO mail-we0-f171.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751080Ab3GZSF5 (ORCPT ); Fri, 26 Jul 2013 14:05:57 -0400 Received: by mail-we0-f171.google.com with SMTP id q55so2188421wes.30 for ; Fri, 26 Jul 2013 11:05:56 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id:x-mailer; bh=i6g//KcqcqEKXUn+cuAZYLT1Zn+kTI4kvO/WiJoktvs=; b=A4TOg4I2z2U1O32t9xEOXVyVT1tgkTFZXbae3+3XMyPMQJanvaPEDBgcJjct/RwlCE jLXStl8DNp5QdTPCnwj8Pw11AdxPCGEFsK7ahd9s1LUBlYcjIN9bAancZIPYPp8yimcW yQOeJsKMJVTKgPKPtt2OdzIwquB8Z0mNQ1ei8on0Xrl3FlYddJvMwQFzu95azDimdYJG yKN5Px3a7w2+8XWtYU80W9Un4Ze9zRQVdeTxxTA3jUmYEaeVOaj9QEFP+XPRJF5aCD8H gGJ9VyRc6og61qDFycdQkbcCJsxFoPND9f9IFGR3KvaFafoCZUq1wjIT55c4Xn9kORWw 1EHQ== X-Received: by 10.194.19.130 with SMTP id f2mr34880717wje.22.1374861956184; Fri, 26 Jul 2013 11:05:56 -0700 (PDT) Received: from magnum.frso.rivierawaves.com (vpn.rivierawaves.com. [91.151.119.162]) by mx.google.com with ESMTPSA id i1sm6368657wiz.6.2013.07.26.11.05.54 for (version=TLSv1.2 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Fri, 26 Jul 2013 11:05:55 -0700 (PDT) From: Karl Beldan To: Johannes Berg Cc: linux-wireless , Karl Beldan , Karl Beldan Subject: [PATCH] [PATCH] mac80211: handle VHT radiotap info for tx status Date: Fri, 26 Jul 2013 19:58:34 +0200 Message-Id: <1374861514-29022-1-git-send-email-karl.beldan@gmail.com> X-Mailer: git-send-email 1.8.2 Sender: linux-wireless-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org X-Spam-Status: No, score=-8.2 required=5.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, T_DKIM_INVALID, UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Karl Beldan The radiotap VHT info is 12 bytes (required to be aligned on 2) : u16 known - IEEE80211_RADIOTAP_VHT_KNOWN_* u8 flags - IEEE80211_RADIOTAP_VHT_FLAG_* u8 bandwidth u8 mcs_nss[4] u8 coding u8 group_id u16 partial_aid ATM mac80211 can properly handle IEEE80211_RADIOTAP_VHT_KNOWN_GI, IEEE80211_RADIOTAP_VHT_KNOWN_BANDWIDTH and mcs_nss[0] (i.e single user). Signed-off-by: Karl Beldan --- net/mac80211/status.c | 76 ++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 63 insertions(+), 13 deletions(-) diff --git a/net/mac80211/status.c b/net/mac80211/status.c index 6ad4c14..1a1c7fd 100644 --- a/net/mac80211/status.c +++ b/net/mac80211/status.c @@ -235,7 +235,8 @@ static int ieee80211_tx_radiotap_len(struct ieee80211_tx_info *info) /* IEEE80211_RADIOTAP_RATE rate */ if (info->status.rates[0].idx >= 0 && - !(info->status.rates[0].flags & IEEE80211_TX_RC_MCS)) + !(info->status.rates[0].flags & (IEEE80211_TX_RC_MCS | + IEEE80211_TX_RC_VHT_MCS))) len += 2; /* IEEE80211_RADIOTAP_TX_FLAGS */ @@ -244,16 +245,21 @@ static int ieee80211_tx_radiotap_len(struct ieee80211_tx_info *info) /* IEEE80211_RADIOTAP_DATA_RETRIES */ len += 1; - /* IEEE80211_TX_RC_MCS */ - if (info->status.rates[0].idx >= 0 && - info->status.rates[0].flags & IEEE80211_TX_RC_MCS) - len += 3; + /* IEEE80211_RADIOTAP_MCS + * IEEE80211_RADIOTAP_VHT */ + if (info->status.rates[0].idx >= 0) { + if (info->status.rates[0].flags & IEEE80211_TX_RC_MCS) + len += 3; + else if (info->status.rates[0].flags & IEEE80211_TX_RC_VHT_MCS) + len += ALIGN(len, 2) + 12; + } return len; } static void -ieee80211_add_tx_radiotap_header(struct ieee80211_supported_band *sband, +ieee80211_add_tx_radiotap_header(struct ieee80211_local *local, + struct ieee80211_supported_band *sband, struct sk_buff *skb, int retry_count, int rtap_len, int shift) { @@ -280,7 +286,8 @@ ieee80211_add_tx_radiotap_header(struct ieee80211_supported_band *sband, /* IEEE80211_RADIOTAP_RATE */ if (info->status.rates[0].idx >= 0 && - !(info->status.rates[0].flags & IEEE80211_TX_RC_MCS)) { + !(info->status.rates[0].flags & (IEEE80211_TX_RC_MCS | + IEEE80211_TX_RC_VHT_MCS))) { u16 rate; rthdr->it_present |= cpu_to_le32(1 << IEEE80211_RADIOTAP_RATE); @@ -310,9 +317,12 @@ ieee80211_add_tx_radiotap_header(struct ieee80211_supported_band *sband, *pos = retry_count; pos++; - /* IEEE80211_TX_RC_MCS */ - if (info->status.rates[0].idx >= 0 && - info->status.rates[0].flags & IEEE80211_TX_RC_MCS) { + if (info->status.rates[0].idx < 0) + return; + + /* IEEE80211_RADIOTAP_MCS + * IEEE80211_RADIOTAP_VHT */ + if (info->status.rates[0].flags & IEEE80211_TX_RC_MCS) { rthdr->it_present |= cpu_to_le32(1 << IEEE80211_RADIOTAP_MCS); pos[0] = IEEE80211_RADIOTAP_MCS_HAVE_MCS | IEEE80211_RADIOTAP_MCS_HAVE_GI | @@ -325,8 +335,48 @@ ieee80211_add_tx_radiotap_header(struct ieee80211_supported_band *sband, pos[1] |= IEEE80211_RADIOTAP_MCS_FMT_GF; pos[2] = info->status.rates[0].idx; pos += 3; - } + } else if (info->status.rates[0].flags & IEEE80211_TX_RC_VHT_MCS) { + u16 known = local->hw.radiotap_vht_details & + (IEEE80211_RADIOTAP_VHT_KNOWN_GI | + IEEE80211_RADIOTAP_VHT_KNOWN_BANDWIDTH); + + rthdr->it_present |= cpu_to_le32(1 << IEEE80211_RADIOTAP_VHT); + + /* required alignment from rthdr */ + pos = (u8 *)rthdr + ALIGN(pos - (u8 *)rthdr, 2); + /* u16 known - IEEE80211_RADIOTAP_VHT_KNOWN_* */ + put_unaligned_le16(known, pos); + pos += 2; + + /* u8 flags - IEEE80211_RADIOTAP_VHT_FLAG_* */ + if (info->status.rates[0].flags & IEEE80211_TX_RC_SHORT_GI) + *pos |= IEEE80211_RADIOTAP_VHT_FLAG_SGI; + pos++; + + /* u8 bandwidth */ + if (info->status.rates[0].flags & IEEE80211_TX_RC_40_MHZ_WIDTH) + *pos = 1; + else if (info->status.rates[0].flags & IEEE80211_TX_RC_80_MHZ_WIDTH) + *pos = 4; + else if (info->status.rates[0].flags & IEEE80211_TX_RC_160_MHZ_WIDTH) + *pos = 11; + else /* IEEE80211_TX_RC_20_MHZ_WIDTH */ + *pos = 0; + pos++; + + /* u8 mcs_nss[4] */ + *pos = (ieee80211_rate_get_vht_mcs(&info->status.rates[0]) << 4) | + ieee80211_rate_get_vht_nss(&info->status.rates[0]); + pos += 4; + + /* u8 coding */ + pos++; + /* u8 group_id */ + pos++; + /* u16 partial_aid */ + pos += 2; + } } static void ieee80211_report_used_skb(struct ieee80211_local *local, @@ -631,8 +681,8 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb) dev_kfree_skb(skb); return; } - ieee80211_add_tx_radiotap_header(sband, skb, retry_count, rtap_len, - shift); + ieee80211_add_tx_radiotap_header(local, sband, skb, retry_count, + rtap_len, shift); /* XXX: is this sufficient for BPF? */ skb_set_mac_header(skb, 0);