From bf1dec110d517755e66125d4b8699f50b8e6dfcf Mon Sep 17 00:00:00 2001 From: Manel Caro Date: Thu, 7 Mar 2019 20:13:19 +0100 Subject: Calibrator and uim Initial Commit --- wl18xx_plt.c | 787 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 787 insertions(+) create mode 100644 wl18xx_plt.c (limited to 'wl18xx_plt.c') diff --git a/wl18xx_plt.c b/wl18xx_plt.c new file mode 100644 index 0000000..6bfaf2a --- /dev/null +++ b/wl18xx_plt.c @@ -0,0 +1,787 @@ +/* + * This file is part of calibrator + * + * Copyright (C) 2011 Texas Instruments + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#include "calibrator.h" +#include "plt.h" +#include "wl18xx_plt.h" + +SECTION(wl18xx_plt); + +static int plt_wl18xx_set_antenna_diversity_5G(struct nl80211_state *state, struct nl_cb *cb, + struct nl_msg *msg, int argc, char **argv) +{ + struct nlattr *key; + struct wl18xx_cmd_set_antenna_diversity_5G prms; + + if (argc != 1) + return 1; + + prms.test.id = WL18XX_TEST_CMD_5GHZ_ANTENNA_DIVERSITY; + prms.mode = (__u8)atoi(argv[0]); + + if (prms.mode > 1) + return 1; + + key = nla_nest_start(msg, NL80211_ATTR_TESTDATA); + if (!key) { + fprintf(stderr, "fail to nla_nest_start()\n"); + return 1; + } + + printf("Calibrator:: Set antenna diversity 5G (mode=%d)\n", + prms.mode); + + NLA_PUT_U32(msg, WL1271_TM_ATTR_CMD_ID, WL1271_TM_CMD_TEST); + NLA_PUT(msg, WL1271_TM_ATTR_DATA, sizeof(prms), &prms); + + nla_nest_end(msg, key); + + return 0; + +nla_put_failure: + fprintf(stderr, "%s> building message failed\n", __func__); + return 2; +} + +COMMAND(wl18xx_plt, set_antenna_diversity_5G , "", + NL80211_CMD_TESTMODE, 0, CIB_NETDEV, plt_wl18xx_set_antenna_diversity_5G, + " Set antenna diversity 5G\n"); + + +static int plt_wl18xx_tx_tone_stop(struct nl80211_state *state, struct nl_cb *cb, + struct nl_msg *msg, int argc, char **argv) +{ + struct nlattr *key; + struct wl18xx_cmd_phy_tx_tone_stop prms; + + if (argc != 0) + return 1; + + prms.test.id = WL18XX_TEST_CMD_STOP_TX_TONE; + + key = nla_nest_start(msg, NL80211_ATTR_TESTDATA); + if (!key) { + fprintf(stderr, "fail to nla_nest_start()\n"); + return 1; + } + + printf("Calibrator:: Stopping TX Tone\n"); + + NLA_PUT_U32(msg, WL1271_TM_ATTR_CMD_ID, WL1271_TM_CMD_TEST); + NLA_PUT(msg, WL1271_TM_ATTR_DATA, sizeof(prms), &prms); + + nla_nest_end(msg, key); + + return 0; + +nla_put_failure: + fprintf(stderr, "%s> building message failed\n", __func__); + return 2; +} + +COMMAND(wl18xx_plt, tx_tone_stop , "", + NL80211_CMD_TESTMODE, 0, CIB_NETDEV, plt_wl18xx_tx_tone_stop, + " Stop TX Tone\n"); + + + +static int plt_wl18xx_tx_tone_start(struct nl80211_state *state, struct nl_cb *cb, + struct nl_msg *msg, int argc, char **argv) +{ + struct nlattr *key; + struct wl18xx_cmd_phy_tx_tone_start prms; + + if (argc != 4) + return 1; + + prms.test.id = WL18XX_TEST_CMD_START_TX_TONE; + + prms.mode = (__u8)atoi(argv[0]); + prms.bin_index = (__s8)atoi(argv[1]); + prms.trigger_iqram_recording = 0; + prms.sig_gen_cw_en = 0; + prms.sig_gen_mod_en = 0; + prms.ant_mode = (__u8)atoi(argv[2]); + prms.set_rx_aux_on = 0; + prms.gain_index = (__u8)atoi(argv[3]); + + if (prms.mode > 2) + return 1; + + if ((prms.bin_index > 32) || (prms.bin_index < (-32))) + return 1; + + if (prms.ant_mode > 2) + return 1; + + if (prms.gain_index > 4) + return 1; + + + key = nla_nest_start(msg, NL80211_ATTR_TESTDATA); + if (!key) { + fprintf(stderr, "fail to nla_nest_start()\n"); + return 1; + } + + printf("Calibrator:: Starting TX Tone (mode=%d, bin_index=%d, ant_mode=%d, gain_index=%d)\n", + prms.mode, prms.bin_index, prms.ant_mode, prms.gain_index); + + NLA_PUT_U32(msg, WL1271_TM_ATTR_CMD_ID, WL1271_TM_CMD_TEST); + NLA_PUT(msg, WL1271_TM_ATTR_DATA, sizeof(prms), &prms); + + nla_nest_end(msg, key); + + return 0; + +nla_put_failure: + fprintf(stderr, "%s> building message failed\n", __func__); + return 2; +} + +COMMAND(wl18xx_plt, tx_tone_start , " ", + NL80211_CMD_TESTMODE, 0, CIB_NETDEV, plt_wl18xx_tx_tone_start, + "Start TX Tone\n\n" + "\t\t tone mode:\n" + "\t\t\t0 = silence\n" + "\t\t\t1 = carrier feedthrough\n" + "\t\t\t2 = single tone\n" + "\t the offset (in round number of bins) of the tone from the carrier: [(-32)-32]\n" + "\t antenna selection:\n" + "\t\t\t0 = auto\n" + "\t\t\t1 = TX1\n" + "\t\t\t2 = TX2\n" + "\t PA gain step: 2.4GHz: 0-1, 5GHz: 0-4\n"); + + +static int plt_wl18xx_phy_reg_write(struct nl80211_state *state, struct nl_cb *cb, + struct nl_msg *msg, int argc, char **argv) +{ + struct nlattr *key; + struct wl18xx_cmd_phy_reg_write prms; + + if (argc != 2) + return 1; + + prms.test.id = WL18XX_TEST_CMD_PHY_ADDR_WRITE; + + + prms.addr = strtol(argv[0], NULL, 16); + prms.data = strtol(argv[1], NULL, 16); + + key = nla_nest_start(msg, NL80211_ATTR_TESTDATA); + if (!key) { + fprintf(stderr, "fail to nla_nest_start()\n"); + return 1; + } + + NLA_PUT_U32(msg, WL1271_TM_ATTR_CMD_ID, WL1271_TM_CMD_TEST); + NLA_PUT(msg, WL1271_TM_ATTR_DATA, sizeof(prms), &prms); + + nla_nest_end(msg, key); + + return 0; + +nla_put_failure: + fprintf(stderr, "%s> building message failed\n", __func__); + return 2; +} + +COMMAND(wl18xx_plt, phy_reg_write , " ", + NL80211_CMD_TESTMODE, 0, CIB_NETDEV, plt_wl18xx_phy_reg_write, + " Write PHY register for PLT.\n"); + + +static int plt_wl18xx_display_phy_reg_read(struct nl_msg *msg, void *arg) +{ + struct nlattr *tb[NL80211_ATTR_MAX + 1]; + struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg)); + struct nlattr *td[WL1271_TM_ATTR_MAX + 1]; + struct wl18xx_cmd_phy_reg_read *prms; + + nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0), + genlmsg_attrlen(gnlh, 0), NULL); + + if (!tb[NL80211_ATTR_TESTDATA]) { + fprintf(stderr, "no data!\n"); + return NL_SKIP; + } + + nla_parse(td, WL1271_TM_ATTR_MAX, nla_data(tb[NL80211_ATTR_TESTDATA]), + nla_len(tb[NL80211_ATTR_TESTDATA]), NULL); + + prms = (struct wl18xx_cmd_phy_reg_read *) nla_data(td[WL1271_TM_ATTR_DATA]); + + printf("Register Address: \t0x%x\t", prms->addr); + printf("is:\t0x%x\n", prms->data); + + return NL_SKIP; +} + + +static int plt_wl18xx_phy_reg_read(struct nl80211_state *state, struct nl_cb *cb, + struct nl_msg *msg, int argc, char **argv) +{ + struct nlattr *key; + struct wl18xx_cmd_phy_reg_read prms; + + if (argc != 1) + return 1; + + prms.test.id = WL18XX_TEST_CMD_PHY_ADDR_READ; + + prms.addr = strtol(argv[0], NULL, 16); + + key = nla_nest_start(msg, NL80211_ATTR_TESTDATA); + if (!key) { + fprintf(stderr, "fail to nla_nest_start()\n"); + return 1; + } + + NLA_PUT_U32(msg, WL1271_TM_ATTR_CMD_ID, WL1271_TM_CMD_TEST); + NLA_PUT(msg, WL1271_TM_ATTR_DATA, sizeof(prms), &prms); + NLA_PUT_U8(msg, WL1271_TM_ATTR_ANSWER, 1); + + nla_nest_end(msg, key); + + nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, + plt_wl18xx_display_phy_reg_read, NULL); + + return 0; + +nla_put_failure: + fprintf(stderr, "%s> building message failed\n", __func__); + return 2; +} + +COMMAND(wl18xx_plt, phy_reg_read , "", + NL80211_CMD_TESTMODE, 0, CIB_NETDEV, plt_wl18xx_phy_reg_read, + " Read PHY register for PLT.\n"); + + +static int plt_wl18xx_set_antenna_mode_5G(struct nl80211_state *state, struct nl_cb *cb, + struct nl_msg *msg, int argc, char **argv) +{ + struct nlattr *key; + struct wl18xx_cmd_set_antenna_mode_5G prms; + + if (argc != 4) + return 1; + + prms.test.id = WL18XX_TEST_CMD_SET_ANTENNA_MODE_5G; + + + prms.mac_prim_rx_chain = (__u8)atoi(argv[0]); + prms.mac_rx_chain1_en = (__u8)atoi(argv[1]); + prms.mac_rx_chain2_en = (__u8)atoi(argv[2]); + prms.mac_tx_chain1_en = (__u8)atoi(argv[3]); + + if ((prms.mac_prim_rx_chain != 1 && prms.mac_prim_rx_chain != 2 )) + return 1; + + if ((prms.mac_rx_chain1_en > 1) || (prms.mac_rx_chain2_en > 1) + || (prms.mac_tx_chain1_en > 1)) + return 1; + + key = nla_nest_start(msg, NL80211_ATTR_TESTDATA); + if (!key) { + fprintf(stderr, "fail to nla_nest_start()\n"); + return 1; + } + + NLA_PUT_U32(msg, WL1271_TM_ATTR_CMD_ID, WL1271_TM_CMD_TEST); + NLA_PUT(msg, WL1271_TM_ATTR_DATA, sizeof(prms), &prms); + + nla_nest_end(msg, key); + + return 0; + +nla_put_failure: + fprintf(stderr, "%s> building message failed\n", __func__); + return 2; +} + +COMMAND(wl18xx_plt, set_antenna_mode_5G , " " + " ", + NL80211_CMD_TESTMODE, 0, CIB_NETDEV, plt_wl18xx_set_antenna_mode_5G, + "set antenna mode 5G for PLT.\n"); + + +static int plt_wl18xx_set_antenna_mode_24G(struct nl80211_state *state, struct nl_cb *cb, + struct nl_msg *msg, int argc, char **argv) +{ + struct nlattr *key; + struct wl18xx_cmd_set_antenna_mode_24G prms; + + if (argc != 6) + return 1; + + prms.test.id = WL18XX_TEST_CMD_SET_ANTENNA_MODE_24G; + + + prms.mac_prim_rx_chain = (__u8)atoi(argv[0]); + prms.mac_prim_tx_chain = (__u8)atoi(argv[1]); + prms.mac_rx_chain1_en = (__u8)atoi(argv[2]); + prms.mac_rx_chain2_en = (__u8)atoi(argv[3]); + prms.mac_tx_chain1_en = (__u8)atoi(argv[4]); + prms.mac_tx_chain2_en = (__u8)atoi(argv[5]); + + if ((prms.mac_prim_rx_chain != 1 && prms.mac_prim_rx_chain != 2 ) || + (prms.mac_prim_tx_chain != 1 && prms.mac_prim_tx_chain != 2 )) + return 1; + + if ((prms.mac_rx_chain1_en > 1) || (prms.mac_rx_chain2_en > 1) || + (prms.mac_tx_chain1_en > 1) || (prms.mac_tx_chain2_en > 1)) + return 1; + + key = nla_nest_start(msg, NL80211_ATTR_TESTDATA); + if (!key) { + fprintf(stderr, "fail to nla_nest_start()\n"); + return 1; + } + + NLA_PUT_U32(msg, WL1271_TM_ATTR_CMD_ID, WL1271_TM_CMD_TEST); + NLA_PUT(msg, WL1271_TM_ATTR_DATA, sizeof(prms), &prms); + + nla_nest_end(msg, key); + + return 0; + +nla_put_failure: + fprintf(stderr, "%s> building message failed\n", __func__); + return 2; +} + +COMMAND(wl18xx_plt, set_antenna_mode_24G , " " + " ", + NL80211_CMD_TESTMODE, 0, CIB_NETDEV, plt_wl18xx_set_antenna_mode_24G, + "set antenna mode 2.4G for PLT.\n"); + +static int plt_wl18xx_set_tx_power(struct nl80211_state *state, + struct nl_cb *cb, struct nl_msg *msg, int argc, char **argv) +{ + struct nlattr *key; + struct wl18xx_cmd_set_tx_power prms; + + if (argc != 12) + return 1; + + prms.test.id = WL18XX_TEST_CMD_TX_POWER; + + prms.mac_des_pwr = (__s32)atoi(argv[0]); + prms.mac_lvl_idx = atoi(argv[1]); + prms.freq_band = atoi(argv[2]); + prms.freq_prim_chan_num = atoi(argv[3]); + prms.freq_prim_chan_loc = atoi(argv[4]); + prms.mac_ant_select = atoi(argv[5]); + prms.mac_non_srv = atoi(argv[6]); + prms.mac_chan_lim_dis = atoi(argv[7]); + prms.mac_fem_lim_dis = atoi(argv[8]); + prms.mac_gain_calc_mode = atoi(argv[9]); + prms.mac_analog_gain_control_idx = atoi(argv[10]); + prms.mac_post_dpd_gain = atoi(argv[11]); + + if ((prms.mac_gain_calc_mode == 0) || (prms.mac_gain_calc_mode == 1)) { + if ((prms.mac_des_pwr > 20000) || (prms.mac_des_pwr < 0)) { + fprintf(stderr, "Power Mode: TX Output Power is out of range (0-20.000dBm)\n"); + return 1; + } + } + + if (prms.mac_gain_calc_mode == 2) { + if ((prms.mac_des_pwr > -4000) || (prms.mac_des_pwr < -15000)) { + fprintf(stderr, "dBPsat Mode: TX Output Power is out of range (-15.000-(-4.000)dBm)\n"); + return 1; + } + } + + if (prms.mac_lvl_idx > 3) + return 1; + + if (prms.freq_band > 2) + return 1; + + if (prms.freq_prim_chan_num <= 0) + return 1; + + if (prms.mac_ant_select > 3) + return 1; + + if (prms.mac_non_srv > 1) + return 1; + + if (prms.mac_chan_lim_dis > 1) + return 1; + + if (prms.mac_fem_lim_dis > 1) + return 1; + + if (prms.mac_gain_calc_mode > 2) + return 1; + + if (prms.mac_analog_gain_control_idx > 4) + return 1; + + if (prms.mac_post_dpd_gain > 4) + return 1; + + key = nla_nest_start(msg, NL80211_ATTR_TESTDATA); + if (!key) { + fprintf(stderr, "fail to nla_nest_start()\n"); + return 1; + } + + NLA_PUT_U32(msg, WL1271_TM_ATTR_CMD_ID, WL1271_TM_CMD_TEST); + NLA_PUT(msg, WL1271_TM_ATTR_DATA, sizeof(prms), &prms); + + nla_nest_end(msg, key); + + return 0; + +nla_put_failure: + fprintf(stderr, "%s> building message failed\n", __func__); + return 2; +} + +COMMAND(wl18xx_plt, set_tx_power, " " + " " + " " + " ", + NL80211_CMD_TESTMODE, 0, CIB_NETDEV, plt_wl18xx_set_tx_power, + "set TX transmissions power for PLT.\n"); + +static int plt_wl18xx_tune_channel(struct nl80211_state *state, struct nl_cb *cb, + struct nl_msg *msg, int argc, char **argv) +{ + struct nlattr *key; + struct wl18xx_cmd_channel_tune prms; + + if (argc != 3) + return 1; + + prms.test.id = WL18XX_TEST_CMD_CHANNEL_TUNE; + prms.channel = (__u8)atoi(argv[0]); + prms.band = (__u8)atoi(argv[1]); + prms.bandwidth = (__u8)atoi(argv[2]); + prms.rfSetIdx = 0; /* Set to Zero to support backward competability only for RTTT */ + + key = nla_nest_start(msg, NL80211_ATTR_TESTDATA); + if (!key) { + fprintf(stderr, "fail to nla_nest_start()\n"); + return 1; + } + + NLA_PUT_U32(msg, WL1271_TM_ATTR_CMD_ID, WL1271_TM_CMD_TEST); + NLA_PUT(msg, WL1271_TM_ATTR_DATA, sizeof(prms), &prms); + + nla_nest_end(msg, key); + + return 0; + +nla_put_failure: + fprintf(stderr, "%s> building message failed\n", __func__); + return 2; +} + +COMMAND(wl18xx_plt, tune_channel, " ", + NL80211_CMD_TESTMODE, 0, CIB_NETDEV, plt_wl18xx_tune_channel, + "Set channel, band and bandwidth for PLT.\n"); + +#define RX_FILTER_MAGIC_NUMBER 0xabadabad + +static int plt_wl18xx_start_rx(struct nl80211_state *state, struct nl_cb *cb, + struct nl_msg *msg, int argc, char **argv) +{ + struct nlattr *key; + struct wl18xx_cmd_start_rx prms; + + if (argc > 2) + return 1; + + prms.test.id = WL18XX_TEST_CMD_START_RX_SIMULATION; + + if (argc == 2) { + str2mac(prms.src_addr, argv[0]); + str2mac(prms.dst_addr, argv[1]); + prms.magic_num = RX_FILTER_MAGIC_NUMBER; + } + + key = nla_nest_start(msg, NL80211_ATTR_TESTDATA); + if (!key) { + fprintf(stderr, "fail to nla_nest_start()\n"); + return 1; + } + + NLA_PUT_U32(msg, WL1271_TM_ATTR_CMD_ID, WL1271_TM_CMD_TEST); + NLA_PUT(msg, WL1271_TM_ATTR_DATA, sizeof(prms), &prms); + + nla_nest_end(msg, key); + printf("Calibrator:: Starting RX Simulation (Note that statistics counters are being reset)...\n"); + + return 0; + +nla_put_failure: + fprintf(stderr, "%s> building message failed\n", __func__); + return 2; +} + +COMMAND(wl18xx_plt, start_rx, " ", + NL80211_CMD_TESTMODE, 0, CIB_NETDEV, plt_wl18xx_start_rx, + "Start gathering RX statistics for PLT.\n"); + +static int plt_wl18xx_stop_rx(struct nl80211_state *state, struct nl_cb *cb, + struct nl_msg *msg, int argc, char **argv) +{ + struct nlattr *key; + struct wl18xx_cmd_stop_rx prms; + + if (argc != 0) + return 1; + + prms.test.id = WL18XX_TEST_CMD_STOP_RX_SIMULATION; + + key = nla_nest_start(msg, NL80211_ATTR_TESTDATA); + if (!key) { + fprintf(stderr, "fail to nla_nest_start()\n"); + return 1; + } + + NLA_PUT_U32(msg, WL1271_TM_ATTR_CMD_ID, WL1271_TM_CMD_TEST); + NLA_PUT(msg, WL1271_TM_ATTR_DATA, sizeof(prms), &prms); + + nla_nest_end(msg, key); + printf("Calibrator:: Stopping RX Simulation\n"); + + return 0; + +nla_put_failure: + fprintf(stderr, "%s> building message failed\n", __func__); + return 2; +} + +COMMAND(wl18xx_plt, stop_rx, "", + NL80211_CMD_TESTMODE, 0, CIB_NETDEV, plt_wl18xx_stop_rx, + "Stop gathering RX statistics for PLT.\n"); + +static int plt_wl18xx_display_rx_stats(struct nl_msg *msg, void *arg) +{ + struct nlattr *tb[NL80211_ATTR_MAX + 1]; + struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg)); + struct nlattr *td[WL1271_TM_ATTR_MAX + 1]; + struct wl18xx_cmd_rx_stats *prms; + + nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0), + genlmsg_attrlen(gnlh, 0), NULL); + + if (!tb[NL80211_ATTR_TESTDATA]) { + fprintf(stderr, "no data!\n"); + return NL_SKIP; + } + + nla_parse(td, WL1271_TM_ATTR_MAX, nla_data(tb[NL80211_ATTR_TESTDATA]), + nla_len(tb[NL80211_ATTR_TESTDATA]), NULL); + + prms = (struct wl18xx_cmd_rx_stats *) nla_data(td[WL1271_TM_ATTR_DATA]); + + printf("\nRX statistics (status %d)\n", prms->radio_status); + printf("Total Received Packets:\t%d\n", prms->total); + printf("FCS Errors:\t\t%d\n", prms->errors); + printf("MAC Mismatch:\t\t%d\n", prms->addr_mm); + printf("Good Packets:\t\t%d\n", prms->good); + printf("Average RSSI (SOC):\t%d\n", prms->rssi_soc); + printf("Average RSSI (ANT):\t%d\n", prms->rssi_ant); + + if(prms->total) { + float per = ((float)prms->total - (float)prms->good)/(float)prms->total; + printf("PER:\t\t\t%f # PER = Total Bad / Total Received\n", per); + } else { + printf("PER:\t\t\tN/A # PER = Total Bad / Total Received\n"); + } + + return NL_SKIP; +} + +static int plt_wl18xx_get_rx_stats(struct nl80211_state *state, struct nl_cb *cb, + struct nl_msg *msg, int argc, char **argv) +{ + struct nlattr *key; + struct wl18xx_cmd_rx_stats prms; + + if (argc != 0) + return 1; + + prms.test.id = WL18XX_TEST_CMD_GET_RX_STATISTICS; + + key = nla_nest_start(msg, NL80211_ATTR_TESTDATA); + if (!key) { + fprintf(stderr, "fail to nla_nest_start()\n"); + return 1; + } + + NLA_PUT_U32(msg, WL1271_TM_ATTR_CMD_ID, WL1271_TM_CMD_TEST); + NLA_PUT(msg, WL1271_TM_ATTR_DATA, sizeof(prms), &prms); + NLA_PUT_U8(msg, WL1271_TM_ATTR_ANSWER, 1); + + nla_nest_end(msg, key); + + nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, + plt_wl18xx_display_rx_stats, NULL); + + return 0; + +nla_put_failure: + fprintf(stderr, "%s> building message failed\n", __func__); + return 2; +} + +COMMAND(wl18xx_plt, get_rx_stats, "", + NL80211_CMD_TESTMODE, 0, CIB_NETDEV, plt_wl18xx_get_rx_stats, + "Retrieve RX statistics for PLT.\n"); + +static int plt_wl18xx_start_tx(struct nl80211_state *state, struct nl_cb *cb, + struct nl_msg *msg, int argc, char **argv) +{ + struct nlattr *key; + struct wl18xx_cmd_start_tx prms; + + if (argc != 11) + return 1; + + prms.test.id = WL18XX_TEST_CMD_START_TX_SIMULATION; + + prms.delay = atoi(argv[0]); + prms.rate = atoi(argv[1]); + prms.size = atoi(argv[2]); + prms.mode = atoi(argv[3]); + prms.data_type = atoi(argv[4]); + prms.gi = atoi(argv[5]); + prms.options1 = atoi(argv[6]); + prms.options2 = atoi(argv[7]); + str2mac(prms.src_addr, argv[8]); + str2mac(prms.dst_addr, argv[9]); + prms.bandwidth = atoi(argv[10]); + + if (prms.delay < 200) { + fprintf(stderr, "Delay is out of range (valid range >=200us)\n"); + return 1; + } + if (prms.size > 4065) { + fprintf(stderr, "Packet Size is out of range (valid range <=4065B)\n"); + return 1; + } + if (prms.rate < 0 || prms.rate > 29) + return 1; + if (prms.gi != 0 && prms.gi != 1) + return 1; + if (prms.bandwidth != 0 && prms.bandwidth != 1) + return 1; + + key = nla_nest_start(msg, NL80211_ATTR_TESTDATA); + if (!key) { + fprintf(stderr, "fail to nla_nest_start()\n"); + return 1; + } + printf("Calibrator:: Starting TX Simulation (delay=%d, rate=%d, size=%d, mode=%d\n" + " data_type=%d, BW=%d, gi=%d, opt1=0x%x, opt2=0x%x\n" + " src=%02x:%02x:%02x:%02x:%02x:%02x\n" + " dst=%02x:%02x:%02x:%02x:%02x:%02x)...\n", + prms.delay, prms.rate, prms.size, prms.mode, prms.data_type, + prms.bandwidth, prms.gi, prms.options1,prms.options2, + prms.src_addr[0],prms.src_addr[1],prms.src_addr[2],prms.src_addr[3],prms.src_addr[4],prms.src_addr[5], + prms.dst_addr[0],prms.dst_addr[1],prms.dst_addr[2],prms.dst_addr[3],prms.dst_addr[4],prms.dst_addr[5]); + + NLA_PUT_U32(msg, WL1271_TM_ATTR_CMD_ID, WL1271_TM_CMD_TEST); + NLA_PUT(msg, WL1271_TM_ATTR_DATA, sizeof(prms), &prms); + + nla_nest_end(msg, key); + + return 0; + +nla_put_failure: + fprintf(stderr, "%s> building message failed\n", __func__); + return 2; +} + +COMMAND(wl18xx_plt, start_tx, " " + " ", + NL80211_CMD_TESTMODE, 0, CIB_NETDEV, plt_wl18xx_start_tx, + "Start TX transmissions for PLT.\n\n" + "\t\tdelay between packets in us: 200-...\n" + "\t\ttransmission rate:\n" + "\t\t\t0 = 1.0 Mbps\t\t\t1 = 2.0 Mbps\n" + "\t\t\t2 = 5.0 Mbps\t\t\t3 = 11.0 Mbps\n" + "\t\t\t4 = 6.0 Mbps\t\t\t5 = 9.0 Mbps\n" + "\t\t\t6 = 12.0 Mbps\t\t\t7 = 18.0 Mbps\n" + "\t\t\t8 = 24.0 Mbps\t\t\t9 = 36.0 Mbps\n" + "\t\t\t10 = 48.0 Mbps\t\t\t11 = 54.0 Mbps\n" + "\t\t\t12 = 6.5 Mbps (MCS0)\t\t13 = 13.0 Mbps (MCS1)\n" + "\t\t\t14 = 19.5 Mbps (MCS2)\t\t15 = 26.0 Mbps (MCS3)\n" + "\t\t\t16 = 39.0 Mbps (MCS4)\t\t17 = 52.0 Mbps (MCS5)\n" + "\t\t\t18 = 58.5 Mbps (MCS6)\t\t19 = 65.0 Mbps (MCS7)\n" + "\t\t\t20 = MCS8/MCS4 at 40MHz\t21 = MCS9/MCS5 at 40MHz\n" + "\t\t\t22 = MCS10/MCS6 at 40MHz\t23 = MCS11/MCS7 at 40MHz\n" + "\t\t\t24 = MCS12/MCS7 at 40MHz SGI\t25 = MCS13\n" + "\t\t\t26 = MCS14\t\t\t27 = MCS15\n" + "\t\tpacket size (bytes): 0-4065\n" + "\t\tnumber of packets (0 = endless)\n" + "\tnot supported\n" + "\t\tguard interval (0 = normal, 1 = short)\n" + "\tunused\n" + "\tsupported options according to bitmap:\n" + "\t\t\tbit1 - override CCA\n" + "\t\t\tbit2 - fixed/incremental sequence number\n" + "\tsource MAC address (XX:XX:XX:XX:XX:XX)\n" + "\tdestination MAC address (XX:XX:XX:XX:XX:XX)\n" + "\tchannel width (0 = 20 MHz, 1 = 40 MHz)"); + +static int plt_wl18xx_stop_tx(struct nl80211_state *state, struct nl_cb *cb, + struct nl_msg *msg, int argc, char **argv) +{ + struct nlattr *key; + struct wl18xx_cmd_stop_tx prms; + + if (argc != 0) + return 1; + + prms.test.id = WL18XX_TEST_CMD_STOP_TX_SIMULATION; + + key = nla_nest_start(msg, NL80211_ATTR_TESTDATA); + if (!key) { + fprintf(stderr, "fail to nla_nest_start()\n"); + return 1; + } + + NLA_PUT_U32(msg, WL1271_TM_ATTR_CMD_ID, WL1271_TM_CMD_TEST); + NLA_PUT(msg, WL1271_TM_ATTR_DATA, sizeof(prms), &prms); + + nla_nest_end(msg, key); + + return 0; + +nla_put_failure: + fprintf(stderr, "%s> building message failed\n", __func__); + return 2; +} + +COMMAND(wl18xx_plt, stop_tx, "", + NL80211_CMD_TESTMODE, 0, CIB_NETDEV, plt_wl18xx_stop_tx, + "Stop TX transmissions for PLT.\n"); + -- cgit v1.1