From mboxrd@z Thu Jan 1 00:00:00 1970 From: Daniel Golle Date: Mon, 14 Nov 2011 14:10:46 +0100 Subject: [ath9k-devel] [PATCH v0 6/6] support for antenna configuration profiles Message-ID: <20111114131046.GA3250@localhost> List-Id: MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit To: ath9k-devel@lists.ath9k.org This adds support for controlling an external antenna switch to the iw userspace tool. The part in info.c doesn't work properly yet, somehow nla_parse doesn't like NL80211_ATTR_WIPHY_EXTANT_SUPP_PROFILES... Anyone can spot the mistake here maybe? (or is there anything wrong in my implementation in nl80211.c...?) Signed-off-by: Daniel Golle --- a/iw-3.1/phy.c +++ b/iw-3.1/phy.c @@ -333,3 +333,30 @@ COMMAND(set, antenna, " | all | NL80211_CMD_SET_WIPHY, 0, CIB_PHY, handle_antenna, "Set a bitmap of allowed antennas to use for TX and RX.\n" "The driver may reject antenna configurations it cannot support."); + +static int handle_extant(struct nl80211_state *state, + struct nl_cb *cb, + struct nl_msg *msg, + int argc, char **argv) +{ + char *end; + __u32 extant; + + if (argc == 1) { + extant = strtoul(argv[0], &end, 0); + if (*end) + return 1; + } else + return 1; + + NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_EXTANT_STATE, extant); + + return 0; + + nla_put_failure: + return -ENOBUFS; +} +COMMAND(set, extant, "", + NL80211_CMD_SET_WIPHY, 0, CIB_PHY, handle_extant, + "Select the external antenna switch configuration profile.\n" + "The driver accepts only profiles defined for the hardware."); --- a/iw-3.1/info.c +++ b/iw-3.1/info.c @@ -180,6 +197,65 @@ static int print_phy_handler(struct nl_m nla_get_u32(tb_msg[NL80211_ATTR_WIPHY_ANTENNA_TX]), nla_get_u32(tb_msg[NL80211_ATTR_WIPHY_ANTENNA_RX])); + if (tb_msg[NL80211_ATTR_WIPHY_EXTANT_SUPPORT]) + printf("\tConfigurable external antenna switch detected\n"); + + + if (tb_msg[NL80211_ATTR_WIPHY_EXTANT_SUPP_PROFILES]) { + struct nlattr *nl_easp, *tb_easp[NL80211_EASP_ATTR_MAX + 1]; + int err, rem_easp; + int current_profile, num_profiles = 0; + __u8 id; + static struct nla_policy easp_policy[NL80211_EASP_ATTR_MAX + 1] = { + [NL80211_EASP_ATTR_ID] = { .type = NLA_U32 }, + [NL80211_EASP_ATTR_NAME] = { }, + [NL80211_EASP_ATTR_DESC] = { }, + }; + + if (tb_msg[NL80211_ATTR_WIPHY_EXTANT_STATE]) { + current_profile = nla_get_u32(tb_msg[NL80211_ATTR_WIPHY_EXTANT_STATE]); + printf("\tSelected Profile: %x\n", current_profile); + } + else + current_profile = -1; + + nla_for_each_nested(nl_easp, tb_msg[NL80211_ATTR_WIPHY_EXTANT_SUPP_PROFILES], rem_easp) + num_profiles++; + + printf("\tSupports %u antenna switch profiles:\n", num_profiles); + + nla_for_each_nested(nl_easp, tb_msg[NL80211_ATTR_WIPHY_EXTANT_SUPP_PROFILES], rem_easp) + { + char *c; + int i,l; + c=(char*) nla_data(nl_easp); + l=nla_len(nl_easp); + printf("len(nla_msg)=%u\n", l); + printf("raw message follows:\n"); + for(i=0;i0 && (i%32) == 0) + printf("\n"); + }; + printf("\n-----------------\n"); + + err = nla_parse(tb_easp, NL80211_EASP_ATTR_MAX, nla_data(nl_easp), nla_len(nl_easp), easp_policy); + + if (err || !tb_easp[NL80211_EASP_ATTR_ID] || !tb_easp[NL80211_EASP_ATTR_NAME] || !tb_easp[NL80211_EASP_ATTR_DESC]) { + printf("cannot parse antenna switch profile, err %x\n", err); + goto broken_profile; + } + id = nla_get_u32(tb_easp[NL80211_EASP_ATTR_ID]); + printf("\t\t%u\t%s\t(%s)", id, nla_get_string(tb_easp[NL80211_EASP_ATTR_NAME]), + nla_get_string(tb_easp[NL80211_EASP_ATTR_DESC])); + if ( id == current_profile ) + printf(" [*]"); + printf("\n"); + } +broken_profile: + ; + } + if (tb_msg[NL80211_ATTR_SUPPORTED_IFTYPES]) { printf("\tSupported interface modes:\n"); nla_for_each_nested(nl_mode, tb_msg[NL80211_ATTR_SUPPORTED_IFTYPES], rem_mode)