1224266Sadrian/* 2224266Sadrian * Copyright (c) 2011 Adrian Chadd, Xenion Pty Ltd. 3224266Sadrian * 4224266Sadrian * Redistribution and use in source and binary forms, with or without 5224266Sadrian * modification, are permitted provided that the following conditions 6224266Sadrian * are met: 7224266Sadrian * 1. Redistributions of source code must retain the above copyright 8224266Sadrian * notice, this list of conditions and the following disclaimer. 9224266Sadrian * 2. Redistributions in binary form must reproduce the above copyright 10224266Sadrian * notice, this list of conditions and the following disclaimer in the 11224266Sadrian * documentation and/or other materials provided with the distribution. 12224266Sadrian * 13224266Sadrian * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 14224266Sadrian * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15224266Sadrian * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 16224266Sadrian * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 17224266Sadrian * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18224266Sadrian * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 19224266Sadrian * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 20224266Sadrian * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 21224266Sadrian * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 22224266Sadrian * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 23224266Sadrian * SUCH DAMAGE. 24224266Sadrian * 25224266Sadrian * $FreeBSD$ 26224266Sadrian */ 27224266Sadrian 28224266Sadrian#include "diag.h" 29224266Sadrian 30224266Sadrian#include "ah.h" 31224266Sadrian#include "ah_internal.h" 32224266Sadrian 33224266Sadrian#ifndef ATH_DEFAULT 34224266Sadrian#define ATH_DEFAULT "ath0" 35224266Sadrian#endif 36224266Sadrian 37224266Sadrian#include <getopt.h> 38224266Sadrian#include <errno.h> 39224266Sadrian#include <err.h> 40224266Sadrian#include <stdlib.h> 41224266Sadrian#include <string.h> 42224266Sadrian#include <ctype.h> 43224266Sadrian#include <unistd.h> 44224266Sadrian 45224266Sadrianstruct radarhandler { 46224266Sadrian struct ath_diag atd; 47224266Sadrian int s; 48224266Sadrian struct ifreq ifr; 49224266Sadrian int ah_devid; 50224266Sadrian}; 51224266Sadrian 52224266Sadrianint 53224266Sadrianradar_opendev(struct radarhandler *radar, const char *devid) 54224266Sadrian{ 55224266Sadrian HAL_REVS revs; 56224266Sadrian 57224266Sadrian radar->s = socket(AF_INET, SOCK_DGRAM, 0); 58224266Sadrian if (radar->s < 0) { 59224266Sadrian warn("socket"); 60224266Sadrian return 0; 61224266Sadrian } 62224266Sadrian 63224266Sadrian strncpy(radar->atd.ad_name, devid, sizeof (radar->atd.ad_name)); 64224266Sadrian 65224266Sadrian /* Get the hardware revision, just to verify things are working */ 66224266Sadrian radar->atd.ad_id = HAL_DIAG_REVS; 67224266Sadrian radar->atd.ad_out_data = (caddr_t) &revs; 68224266Sadrian radar->atd.ad_out_size = sizeof(revs); 69224266Sadrian if (ioctl(radar->s, SIOCGATHDIAG, &radar->atd) < 0) { 70224266Sadrian warn(radar->atd.ad_name); 71224266Sadrian return 0; 72224266Sadrian } 73224266Sadrian radar->ah_devid = revs.ah_devid; 74224266Sadrian return 1; 75224266Sadrian} 76224266Sadrian 77224266Sadrianvoid 78224266Sadrianradar_closedev(struct radarhandler *radar) 79224266Sadrian{ 80224266Sadrian close(radar->s); 81224266Sadrian radar->s = -1; 82224266Sadrian} 83224266Sadrian 84224266Sadrianvoid 85224266Sadrianradarset(struct radarhandler *radar, int op, u_int32_t param) 86224266Sadrian{ 87224266Sadrian HAL_PHYERR_PARAM pe; 88224266Sadrian 89224266Sadrian pe.pe_firpwr = HAL_PHYERR_PARAM_NOVAL; 90224266Sadrian pe.pe_rrssi = HAL_PHYERR_PARAM_NOVAL; 91224266Sadrian pe.pe_height = HAL_PHYERR_PARAM_NOVAL; 92224266Sadrian pe.pe_prssi = HAL_PHYERR_PARAM_NOVAL; 93224266Sadrian pe.pe_inband = HAL_PHYERR_PARAM_NOVAL; 94224266Sadrian pe.pe_enabled = HAL_PHYERR_PARAM_NOVAL; 95224266Sadrian 96224266Sadrian pe.pe_relpwr = HAL_PHYERR_PARAM_NOVAL; 97224266Sadrian pe.pe_relstep = HAL_PHYERR_PARAM_NOVAL; 98224266Sadrian pe.pe_maxlen = HAL_PHYERR_PARAM_NOVAL; 99224266Sadrian pe.pe_usefir128 = HAL_PHYERR_PARAM_NOVAL; 100224266Sadrian pe.pe_blockradar = HAL_PHYERR_PARAM_NOVAL; 101224266Sadrian pe.pe_enmaxrssi = HAL_PHYERR_PARAM_NOVAL; 102224266Sadrian 103224266Sadrian pe.pe_extchannel = HAL_PHYERR_PARAM_NOVAL; 104231710Sadrian pe.pe_enrelpwr = HAL_PHYERR_PARAM_NOVAL; 105231710Sadrian pe.pe_en_relstep_check = HAL_PHYERR_PARAM_NOVAL; 106224266Sadrian 107224266Sadrian switch (op) { 108224266Sadrian case DFS_PARAM_ENABLE: 109224266Sadrian pe.pe_enabled = param; 110224266Sadrian break; 111224266Sadrian case DFS_PARAM_FIRPWR: 112224266Sadrian pe.pe_firpwr = param; 113224266Sadrian break; 114224266Sadrian case DFS_PARAM_RRSSI: 115224266Sadrian pe.pe_rrssi = param; 116224266Sadrian break; 117224266Sadrian case DFS_PARAM_HEIGHT: 118224266Sadrian pe.pe_height = param; 119224266Sadrian break; 120224266Sadrian case DFS_PARAM_PRSSI: 121224266Sadrian pe.pe_prssi = param; 122224266Sadrian break; 123224266Sadrian case DFS_PARAM_INBAND: 124224266Sadrian pe.pe_inband = param; 125224266Sadrian break; 126224266Sadrian case DFS_PARAM_RELPWR: 127224266Sadrian pe.pe_relpwr = param; 128224266Sadrian break; 129224266Sadrian case DFS_PARAM_RELSTEP: 130224266Sadrian pe.pe_relstep = param; 131224266Sadrian break; 132224266Sadrian case DFS_PARAM_MAXLEN: 133224266Sadrian pe.pe_maxlen = param; 134224266Sadrian break; 135224266Sadrian case DFS_PARAM_USEFIR128: 136224266Sadrian pe.pe_usefir128 = param; 137224266Sadrian break; 138224266Sadrian case DFS_PARAM_BLOCKRADAR: 139224266Sadrian pe.pe_blockradar = param; 140224266Sadrian break; 141224266Sadrian case DFS_PARAM_MAXRSSI_EN: 142224266Sadrian pe.pe_enmaxrssi = param; 143224266Sadrian break; 144224266Sadrian case DFS_PARAM_EN_EXTCH: 145224266Sadrian pe.pe_extchannel = param; 146224266Sadrian break; 147231710Sadrian case DFS_PARAM_RELPWR_EN: 148231710Sadrian pe.pe_enrelpwr = param; 149231710Sadrian break; 150231710Sadrian case DFS_PARAM_RELSTEP_EN: 151231710Sadrian pe.pe_en_relstep_check = param; 152231710Sadrian break; 153224266Sadrian } 154231710Sadrian 155224266Sadrian radar->atd.ad_id = DFS_SET_THRESH | ATH_DIAG_IN; 156224266Sadrian radar->atd.ad_out_data = NULL; 157224266Sadrian radar->atd.ad_out_size = 0; 158224266Sadrian radar->atd.ad_in_data = (caddr_t) &pe; 159224266Sadrian radar->atd.ad_in_size = sizeof(HAL_PHYERR_PARAM); 160224266Sadrian if (ioctl(radar->s, SIOCGATHPHYERR, &radar->atd) < 0) 161224266Sadrian err(1, radar->atd.ad_name); 162224266Sadrian} 163224266Sadrian 164224266Sadrianstatic void 165224266Sadrianradar_get(struct radarhandler *radar) 166224266Sadrian{ 167224266Sadrian HAL_PHYERR_PARAM pe; 168224266Sadrian 169224266Sadrian radar->atd.ad_id = DFS_GET_THRESH | ATH_DIAG_DYN; 170224266Sadrian memset(&pe, 0, sizeof(pe)); 171224266Sadrian 172224266Sadrian radar->atd.ad_in_data = NULL; 173224266Sadrian radar->atd.ad_in_size = 0; 174224266Sadrian radar->atd.ad_out_data = (caddr_t) &pe; 175224266Sadrian radar->atd.ad_out_size = sizeof(pe); 176224266Sadrian 177224266Sadrian if (ioctl(radar->s, SIOCGATHPHYERR, &radar->atd) < 0) 178224266Sadrian err(1, radar->atd.ad_name); 179224266Sadrian 180224266Sadrian printf("Radar parameters (raw):\n"); 181224266Sadrian printf(" pe_enabled: %d\n", pe.pe_enabled); 182224266Sadrian printf(" pe_firpwr: %d\n", pe.pe_firpwr); 183224266Sadrian printf(" pe_rrssi: %d\n", pe.pe_rrssi); 184224266Sadrian printf(" pe_height: %d\n", pe.pe_height); 185224266Sadrian printf(" pe_prssi: %d\n", pe.pe_prssi); 186224266Sadrian printf(" pe_inband: %d\n", pe.pe_inband); 187224266Sadrian printf(" pe_relpwr: %d\n", pe.pe_relpwr); 188224266Sadrian printf(" pe_relstep: %d\n", pe.pe_relstep); 189224266Sadrian printf(" pe_maxlen: %d\n", pe.pe_maxlen); 190224266Sadrian printf(" pe_usefir128: %d\n", pe.pe_usefir128); 191224266Sadrian printf(" pe_blockradar: %d\n", pe.pe_blockradar); 192224266Sadrian printf(" pe_enmaxrssi: %d\n", pe.pe_enmaxrssi); 193224266Sadrian printf(" pe_extchannel: %d\n", pe.pe_extchannel); 194231710Sadrian printf(" pe_enrelpwr: %d\n", pe.pe_enrelpwr); 195231710Sadrian printf(" pe_en_relstep_check: %d\n", pe.pe_en_relstep_check); 196224266Sadrian} 197224266Sadrian 198224266Sadrianstatic int 199231710Sadrianradar_set_param(struct radarhandler *radar, const char *param, 200231710Sadrian const char *val) 201224266Sadrian{ 202224266Sadrian int v; 203224266Sadrian 204224266Sadrian v = atoi(val); 205224266Sadrian 206231710Sadrian if (strcmp(param, "enabled") == 0) { 207231710Sadrian radarset(radar, DFS_PARAM_ENABLE, v); 208231710Sadrian } else if (strcmp(param, "firpwr") == 0) { 209224266Sadrian radarset(radar, DFS_PARAM_FIRPWR, v); 210224266Sadrian } else if (strcmp(param, "rrssi") == 0) { 211224266Sadrian radarset(radar, DFS_PARAM_RRSSI, v); 212224266Sadrian } else if (strcmp(param, "height") == 0) { 213224266Sadrian radarset(radar, DFS_PARAM_HEIGHT, v); 214224266Sadrian } else if (strcmp(param, "prssi") == 0) { 215224266Sadrian radarset(radar, DFS_PARAM_PRSSI, v); 216224266Sadrian } else if (strcmp(param, "inband") == 0) { 217224266Sadrian radarset(radar, DFS_PARAM_INBAND, v); 218224266Sadrian } else if (strcmp(param, "relpwr") == 0) { 219224266Sadrian radarset(radar, DFS_PARAM_RELPWR, v); 220224266Sadrian } else if (strcmp(param, "relstep") == 0) { 221224266Sadrian radarset(radar, DFS_PARAM_RELSTEP, v); 222224266Sadrian } else if (strcmp(param, "maxlen") == 0) { 223224266Sadrian radarset(radar, DFS_PARAM_MAXLEN, v); 224230923Sadrian } else if (strcmp(param, "usefir128") == 0) { 225230923Sadrian radarset(radar, DFS_PARAM_USEFIR128, v); 226230923Sadrian } else if (strcmp(param, "blockradar") == 0) { 227230923Sadrian radarset(radar, DFS_PARAM_BLOCKRADAR, v); 228230923Sadrian } else if (strcmp(param, "enmaxrssi") == 0) { 229230923Sadrian radarset(radar, DFS_PARAM_MAXRSSI_EN, v); 230224266Sadrian } else if (strcmp(param, "extchannel") == 0) { 231224266Sadrian radarset(radar, DFS_PARAM_EN_EXTCH, v); 232231710Sadrian } else if (strcmp(param, "enrelpwr") == 0) { 233231710Sadrian radarset(radar, DFS_PARAM_RELPWR_EN, v); 234231710Sadrian } else if (strcmp(param, "en_relstep_check") == 0) { 235231710Sadrian radarset(radar, DFS_PARAM_RELSTEP_EN, v); 236224266Sadrian } else { 237224266Sadrian return 0; 238224266Sadrian } 239224266Sadrian 240224266Sadrian return 1; 241224266Sadrian} 242224266Sadrian 243224266Sadrianvoid 244224266Sadrianusage(const char *progname) 245224266Sadrian{ 246224266Sadrian printf("Usage:\n"); 247224266Sadrian printf("\t%s: [-i <interface>] <cmd> (<arg>)\n", progname); 248224266Sadrian printf("\t%s: [-h]\n", progname); 249224266Sadrian printf("\n"); 250224266Sadrian printf("Valid commands:\n"); 251224266Sadrian printf("\tget:\t\tGet current radar parameters\n"); 252224266Sadrian printf("\tset <param> <value>:\t\tSet radar parameter\n"); 253224266Sadrian} 254224266Sadrian 255224266Sadrianint 256224266Sadrianmain(int argc, char *argv[]) 257224266Sadrian{ 258224266Sadrian struct radarhandler radar; 259224266Sadrian const char *devname = ATH_DEFAULT; 260224266Sadrian const char *progname = argv[0]; 261224266Sadrian 262224266Sadrian memset(&radar, 0, sizeof(radar)); 263224266Sadrian 264224266Sadrian /* Parse command line options */ 265224266Sadrian if (argc >= 2 && strcmp(argv[1], "-h") == 0) { 266224266Sadrian usage(progname); 267224266Sadrian exit(0); 268224266Sadrian } 269224266Sadrian if (argc >= 2 && strcmp(argv[1], "-?") == 0) { 270224266Sadrian usage(progname); 271224266Sadrian exit(0); 272224266Sadrian } 273224266Sadrian 274224266Sadrian if (argc >= 2 && strcmp(argv[1], "-i") == 0) { 275224266Sadrian if (argc == 2) { 276224266Sadrian usage(progname); 277224266Sadrian exit(127); 278224266Sadrian } 279224266Sadrian devname = argv[2]; 280224266Sadrian argc -= 2; argv += 2; 281224266Sadrian } 282224266Sadrian 283224266Sadrian /* At this point we require at least one command */ 284224266Sadrian if (argc == 1) { 285224266Sadrian usage(progname); 286224266Sadrian exit(127); 287224266Sadrian } 288224266Sadrian 289224266Sadrian if (radar_opendev(&radar, devname) == 0) 290224266Sadrian exit(127); 291224266Sadrian 292224266Sadrian if (strcasecmp(argv[1], "get") == 0) { 293224266Sadrian radar_get(&radar); 294224266Sadrian } else if (strcasecmp(argv[1], "set") == 0) { 295224266Sadrian if (argc < 4) { 296224266Sadrian usage(progname); 297224266Sadrian exit(127); 298224266Sadrian } 299224266Sadrian if (radar_set_param(&radar, argv[2], argv[3]) == 0) { 300224266Sadrian usage(progname); 301224266Sadrian exit(127); 302224266Sadrian } 303224266Sadrian } else { 304224266Sadrian usage(progname); 305224266Sadrian exit(127); 306224266Sadrian } 307224266Sadrian 308224266Sadrian /* wrap up */ 309224266Sadrian radar_closedev(&radar); 310224266Sadrian exit(0); 311224266Sadrian} 312