From patchwork Fri May 20 10:13:43 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?UmFmYcWCIE1pxYJlY2tp?= X-Patchwork-Id: 9129161 X-Patchwork-Delegate: johannes@sipsolutions.net Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 49E3260467 for ; Fri, 20 May 2016 10:13:59 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 27E731FFC9 for ; Fri, 20 May 2016 10:13:59 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 0946B27A84; Fri, 20 May 2016 10:13:59 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.8 required=2.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_HI, T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 6DEC01FFC9 for ; Fri, 20 May 2016 10:13:58 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754340AbcETKNz (ORCPT ); Fri, 20 May 2016 06:13:55 -0400 Received: from mail-lf0-f68.google.com ([209.85.215.68]:35067 "EHLO mail-lf0-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753971AbcETKNy (ORCPT ); Fri, 20 May 2016 06:13:54 -0400 Received: by mail-lf0-f68.google.com with SMTP id p10so2153988lfb.2 for ; Fri, 20 May 2016 03:13:53 -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:mime-version :content-transfer-encoding; bh=1T+p0wD5PNv8G2Z+hMtthenWbwHZGdeWBCeNVJPl3N0=; b=vnLiHgATMAeooW+rMImM4uovpwNsnRanZA1riLrgT0x1NS7rmpiZ0AD5Lto58TlWxT ldL29sLNS9h/yI26XqW+qMFsQRcbyCdw5nJZ95ROcIKLinmFJMHA96O5dJZQIzpH9YLB HdDDn6HWYno/GkeUK9VyRLViKWzposvCbmSL2MpRcbXYQiKLha0KVWxd5vZy+Y35sZkk gfLra+CxfIEQWi3ntaSxDPDGzfHFCiiH4RrWBou9Oh08U9qZHOHzOlJ9mezY8WOtBVyc JY3umxJH7eRPCKYWR1yb5CWQlGx5zJQU43uyGYyNSyTCOvzerdXVLn4Auh1JF8TIAZ8l luCg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=1T+p0wD5PNv8G2Z+hMtthenWbwHZGdeWBCeNVJPl3N0=; b=hcCIdMb48uuDDJ9HaM3Bcihxh3AUAHGo/eePXz2MICyxa8K0pWSk38T8f7f30+R4Cx HRpgoiQ35R7RyBhoJQ2v9kKj2Pb8DDGvpWmedTjmPz67+LllNbSIwaXD/CfVlrCamPhg h5c4/jukgKiT4PX5tVe+pYERIdYYSJWIvBAz8SC+fru82fkiZVF2UHqjElWgyY44idoT g4iuF3R2Z6OlD0F2xv2hfYcg8Hxe+fpYZoSLtnPGQTUVS87Dw50B0cuBu9haB2+yAp7N kpElnNgSW8DmQlJXBr3Z48XeqFPWEOJDvPUnknMVPEWeBlLS+PkQTutP/tA7uCIOUHHn vGUQ== X-Gm-Message-State: AOPr4FX9z9jQYsls5/W90ANWZiQtZqw499kjXyoBsmLqwUy1Gv3/JAWuPbJUQF9MeBKd+A== X-Received: by 10.25.83.10 with SMTP id h10mr662997lfb.39.1463739232152; Fri, 20 May 2016 03:13:52 -0700 (PDT) Received: from linux-samsung.lan (ip-194-187-74-233.konfederacka.maverick.com.pl. [194.187.74.233]) by smtp.gmail.com with ESMTPSA id p199sm3154084lfd.12.2016.05.20.03.13.50 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 20 May 2016 03:13:51 -0700 (PDT) From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= To: Johannes Berg Cc: linux-wireless@vger.kernel.org, =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Subject: [PATCH iw] add "channels" PHY command listing frequencies with more details Date: Fri, 20 May 2016 12:13:43 +0200 Message-Id: <1463739223-19205-1-git-send-email-zajec5@gmail.com> X-Mailer: git-send-email 1.8.4.5 MIME-Version: 1.0 Sender: linux-wireless-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Channels (frequencies) are getting more details that users may want to know about. E.g. it's important to know which frequencies allow using 40/80/160 MHz channels to setup AP properly. We list channels in "info" command output but it's already quite big and it was agreed to introduce new command rather than expand the old one. This patch adds "channels" command printing what was already available in the "info" plus details about supported channel widths. It also removes DFS info from the "info" output. Signed-off-by: Rafał Miłecki --- info.c | 30 -------------- phy.c | 143 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 143 insertions(+), 30 deletions(-) diff --git a/info.c b/info.c index 32de0af..b375123 100644 --- a/info.c +++ b/info.c @@ -47,20 +47,6 @@ static char *cipher_name(__u32 c) } } -static char *dfs_state_name(enum nl80211_dfs_state state) -{ - switch (state) { - case NL80211_DFS_USABLE: - return "usable"; - case NL80211_DFS_AVAILABLE: - return "available"; - case NL80211_DFS_UNAVAILABLE: - return "unavailable"; - default: - return "unknown"; - } -} - static int ext_feature_isset(const unsigned char *ext_features, int ext_features_len, enum nl80211_ext_feature_index ftidx) { @@ -198,22 +184,6 @@ next: if (open) printf(")"); printf("\n"); - - if (!tb_freq[NL80211_FREQUENCY_ATTR_DISABLED] && tb_freq[NL80211_FREQUENCY_ATTR_DFS_STATE]) { - enum nl80211_dfs_state state = nla_get_u32(tb_freq[NL80211_FREQUENCY_ATTR_DFS_STATE]); - unsigned long time; - - printf("\t\t\t DFS state: %s", dfs_state_name(state)); - if (tb_freq[NL80211_FREQUENCY_ATTR_DFS_TIME]) { - time = nla_get_u32(tb_freq[NL80211_FREQUENCY_ATTR_DFS_TIME]); - printf(" (for %lu sec)", time/1000); - } - printf("\n"); - if (tb_freq[NL80211_FREQUENCY_ATTR_DFS_CAC_TIME]) - printf("\t\t\t DFS CAC time: %u ms\n", - nla_get_u32(tb_freq[NL80211_FREQUENCY_ATTR_DFS_CAC_TIME])); - } - } } diff --git a/phy.c b/phy.c index 13e8260..0639f25 100644 --- a/phy.c +++ b/phy.c @@ -14,6 +14,149 @@ #include "nl80211.h" #include "iw.h" +static char *dfs_state_name(enum nl80211_dfs_state state) +{ + switch (state) { + case NL80211_DFS_USABLE: + return "usable"; + case NL80211_DFS_AVAILABLE: + return "available"; + case NL80211_DFS_UNAVAILABLE: + return "unavailable"; + default: + return "unknown"; + } +} + +static int print_channels_handler(struct nl_msg *msg, void *arg) +{ + struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg)); + + struct nlattr *tb_msg[NL80211_ATTR_MAX + 1]; + struct nlattr *tb_band[NL80211_BAND_ATTR_MAX + 1]; + struct nlattr *tb_freq[NL80211_FREQUENCY_ATTR_MAX + 1]; + struct nlattr *nl_band; + struct nlattr *nl_freq; + int rem_band, rem_freq; + static int last_band = -1; + bool width_40, width_80, width_160; + + nla_parse(tb_msg, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0), genlmsg_attrlen(gnlh, 0), NULL); + + if (tb_msg[NL80211_ATTR_WIPHY_BANDS]) { + nla_for_each_nested(nl_band, tb_msg[NL80211_ATTR_WIPHY_BANDS], rem_band) { + if (last_band != nl_band->nla_type) { + printf("Band %d:\n", nl_band->nla_type + 1); + width_40 = false; + width_80 = false; + width_160 = false; + last_band = nl_band->nla_type; + } + + nla_parse(tb_band, NL80211_BAND_ATTR_MAX, nla_data(nl_band), nla_len(nl_band), NULL); + + if (tb_band[NL80211_BAND_ATTR_HT_CAPA]) { + __u16 cap = nla_get_u16(tb_band[NL80211_BAND_ATTR_HT_CAPA]); + + if (cap & BIT(1)) + width_40 = true; + } + + if (tb_band[NL80211_BAND_ATTR_VHT_CAPA]) { + __u32 capa; + + width_80 = true; + + capa = nla_get_u32(tb_band[NL80211_BAND_ATTR_VHT_CAPA]); + switch ((capa >> 2) & 3) { + case 2: + /* width_80p80 = true; */ + /* fall through */ + case 1: + width_160 = true; + break; + } + } + + if (tb_band[NL80211_BAND_ATTR_FREQS]) { + nla_for_each_nested(nl_freq, tb_band[NL80211_BAND_ATTR_FREQS], rem_freq) { + uint32_t freq; + + nla_parse(tb_freq, NL80211_FREQUENCY_ATTR_MAX, nla_data(nl_freq), nla_len(nl_freq), NULL); + + if (!tb_freq[NL80211_FREQUENCY_ATTR_FREQ]) + continue; + freq = nla_get_u32(tb_freq[NL80211_FREQUENCY_ATTR_FREQ]); + printf("\t* %d MHz [%d] ", freq, ieee80211_frequency_to_channel(freq)); + + if (tb_freq[NL80211_FREQUENCY_ATTR_DISABLED]) { + printf("(disabled)\n"); + continue; + } + printf("\n"); + + if (tb_freq[NL80211_FREQUENCY_ATTR_MAX_TX_POWER]) + printf("\t Maximum TX power: %.1f dBm\n", 0.01 * nla_get_u32(tb_freq[NL80211_FREQUENCY_ATTR_MAX_TX_POWER])); + + /* If both flags are set assume an new kernel */ + if (tb_freq[NL80211_FREQUENCY_ATTR_NO_IR] && tb_freq[__NL80211_FREQUENCY_ATTR_NO_IBSS]) { + printf("\t No IR\n"); + } else if (tb_freq[NL80211_FREQUENCY_ATTR_PASSIVE_SCAN]) { + printf("\t Passive scan\n"); + } else if (tb_freq[__NL80211_FREQUENCY_ATTR_NO_IBSS]){ + printf("\t No IBSS\n"); + } + + if (tb_freq[NL80211_FREQUENCY_ATTR_RADAR]) + printf("\t Radar detection\n"); + + printf("\t Channel widths:"); + if (!tb_freq[NL80211_FREQUENCY_ATTR_NO_20MHZ]) + printf(" 20MHz"); + if (width_40 && !tb_freq[NL80211_FREQUENCY_ATTR_NO_HT40_MINUS]) + printf(" HT40-"); + if (width_40 && !tb_freq[NL80211_FREQUENCY_ATTR_NO_HT40_PLUS]) + printf(" HT40+"); + if (width_80 && !tb_freq[NL80211_FREQUENCY_ATTR_NO_80MHZ]) + printf(" VHT80"); + if (width_160 && !tb_freq[NL80211_FREQUENCY_ATTR_NO_160MHZ]) + printf(" VHT160"); + printf("\n"); + + if (!tb_freq[NL80211_FREQUENCY_ATTR_DISABLED] && tb_freq[NL80211_FREQUENCY_ATTR_DFS_STATE]) { + enum nl80211_dfs_state state = nla_get_u32(tb_freq[NL80211_FREQUENCY_ATTR_DFS_STATE]); + unsigned long time; + + printf("\t DFS state: %s", dfs_state_name(state)); + if (tb_freq[NL80211_FREQUENCY_ATTR_DFS_TIME]) { + time = nla_get_u32(tb_freq[NL80211_FREQUENCY_ATTR_DFS_TIME]); + printf(" (for %lu sec)", time / 1000); + } + printf("\n"); + if (tb_freq[NL80211_FREQUENCY_ATTR_DFS_CAC_TIME]) + printf("\t DFS CAC time: %u ms\n", + nla_get_u32(tb_freq[NL80211_FREQUENCY_ATTR_DFS_CAC_TIME])); + } + } + } + } + } + + return NL_SKIP; +} + +static int handle_channels(struct nl80211_state *state, struct nl_msg *msg, + int argc, char **argv, enum id_input id) +{ + nla_put_flag(msg, NL80211_ATTR_SPLIT_WIPHY_DUMP); + nlmsg_hdr(msg)->nlmsg_flags |= NLM_F_DUMP; + + register_handler(print_channels_handler, NULL); + + return 0; +} +TOPLEVEL(channels, NULL, NL80211_CMD_GET_WIPHY, 0, CIB_PHY, handle_channels, "Show available channels."); + static int handle_name(struct nl80211_state *state, struct nl_msg *msg, int argc, char **argv,