diff options
author | ambrisko <ambrisko@FreeBSD.org> | 2002-12-29 19:22:07 +0000 |
---|---|---|
committer | ambrisko <ambrisko@FreeBSD.org> | 2002-12-29 19:22:07 +0000 |
commit | a533b45945ae54fcc48ff5129510549f213638c3 (patch) | |
tree | a6fad0ec9730bbbd04d5904f5219a75ce5c7cabb /usr.sbin | |
parent | 1ec5f03e6d974f74f3960788e6bf478e5cce3bf1 (diff) | |
download | FreeBSD-src-a533b45945ae54fcc48ff5129510549f213638c3.zip FreeBSD-src-a533b45945ae54fcc48ff5129510549f213638c3.tar.gz |
Add support for MPI-350 the mini-pci Cisco Aironet card. This needs more
work. The interface was gleaned from the Linux driver. Currently only
one RX & one TX buffer are used. Firmware support is not tested so for the
MPI-350 so it is disabled. Signal cache and monitor mode are not supported
yet. Signal cache is not supported since in encapsulation mode ethernet
frames are returned by the chip. LAN monitor mode support will be added
shortly. Thanks to Warner for the MPI-350 card he sent me.
Add support for RSSI map from PR kern/32880 which was incomplete. Enhanced
with the ability to select the cache mode of raw, dbm or per-cent.
Clean up Signal/Noise/Quality structures and units with help from
Marco Molteni.
Change flash to use a malloc'ed buffer when needed.
PR: kern/32880
Submitted by: Douglas S. J. De Couto decouto@pdos.lcs.mit.edu,
Marco Molteni
MFC: 3 weeks
Diffstat (limited to 'usr.sbin')
-rw-r--r-- | usr.sbin/ancontrol/ancontrol.8 | 27 | ||||
-rw-r--r-- | usr.sbin/ancontrol/ancontrol.c | 122 |
2 files changed, 128 insertions, 21 deletions
diff --git a/usr.sbin/ancontrol/ancontrol.8 b/usr.sbin/ancontrol/ancontrol.8 index 2376675..f6cb667 100644 --- a/usr.sbin/ancontrol/ancontrol.8 +++ b/usr.sbin/ancontrol/ancontrol.8 @@ -50,6 +50,12 @@ .Nm .Fl i Ar iface Fl C .Nm +.Fl i Ar iface Fl Q +.Nm +.Fl i Ar iface Fl Z +.Nm +.Fl i Ar iface Fl R +.Nm .Fl i Ar iface Fl t Cm 0 Ns - Ns Cm 4 .Nm .Fl i Ar iface Fl s Cm 0 Ns - Ns Cm 3 @@ -190,6 +196,27 @@ Display current NIC configuration. This shows the current operation mode, receive mode, MAC address, power save settings, various timing settings, channel selection, diversity, transmit power and transmit speed. +.It Fl i Ar iface Fl Q +Display the cached signal strength information maintained by the +.Xr an 4 +driver. +The driver retains information about signal strength and +noise level for packets received from different hosts. +The signal strength and noise level values are displayed in units of dBms by +default. +The +.Va machdep.an_cache_mode +.Xr sysctl 8 +variable can be set to +.Cm raw , dbm +or +.Cm per . +.It Fl i Ar iface Fl Z +Clear the signal strength cache maintained internally by the +.Xr an 4 +driver. +.It Fl i Ar iface Fl R +Display RSSI map that converts from the RSSI index to percent and dBm. .It Fl i Ar iface Fl t Cm 0 Ns - Ns Cm 4 Select transmit speed. The available settings are as follows: diff --git a/usr.sbin/ancontrol/ancontrol.c b/usr.sbin/ancontrol/ancontrol.c index 543b37a..db3c038 100644 --- a/usr.sbin/ancontrol/ancontrol.c +++ b/usr.sbin/ancontrol/ancontrol.c @@ -58,8 +58,9 @@ static const char rcsid[] = #include <errno.h> #include <err.h> #include <md4.h> +#include <ctype.h> -static void an_getval(const char *, struct an_req *); +static int an_getval(const char *, struct an_req *); static void an_setval(const char *, struct an_req *); static void an_printwords(u_int16_t *, int); static void an_printspeeds(u_int8_t*, int); @@ -86,6 +87,7 @@ static void an_str2key(char *, struct an_ltv_key *); static void an_setkeys(const char *, char *, int); static void an_enable_tx_key(const char *, char *); static void an_enable_leap_mode(const char *, char *); +static void an_dumprssimap(const char *); static void usage(char *); int main(int, char **); @@ -131,12 +133,14 @@ int main(int, char **); #define ACT_SET_MONITOR_MODE 37 #define ACT_SET_LEAP_MODE 38 -static void an_getval(iface, areq) +#define ACT_DUMPRSSIMAP 39 + +static int an_getval(iface, areq) const char *iface; struct an_req *areq; { struct ifreq ifr; - int s; + int s, okay = 1; bzero((char *)&ifr, sizeof(ifr)); @@ -148,12 +152,14 @@ static void an_getval(iface, areq) if (s == -1) err(1, "socket"); - if (ioctl(s, SIOCGAIRONET, &ifr) == -1) + if (ioctl(s, SIOCGAIRONET, &ifr) == -1) { + okay = 0; err(1, "SIOCGAIRONET"); + } close(s); - return; + return okay; } static void an_setval(iface, areq) @@ -260,6 +266,21 @@ static void an_dumpstatus(iface) { struct an_ltv_status *sts; struct an_req areq; + struct an_ltv_rssi_map an_rssimap; + int rssimap_valid = 0; + + /* + * Try to get RSSI to percent and dBM table + */ + + an_rssimap.an_len = sizeof(an_rssimap); + an_rssimap.an_type = AN_RID_RSSI_MAP; + rssimap_valid = an_getval(iface, (struct an_req*)&an_rssimap); + + if (rssimap_valid) + printf("RSSI table:\t\t[ present ]\n"); + else + printf("RSSI table:\t\t[ not available ]\n"); areq.an_len = sizeof(areq); areq.an_type = AN_RID_STATUS; @@ -288,10 +309,22 @@ static void an_dumpstatus(iface) printf("]\n"); printf("Error code:\t\t"); an_printhex((char *)&sts->an_errcode, 1); - printf("\nSignal quality:\t\t"); - an_printhex((char *)&sts->an_cur_signal_quality, 1); - printf("\nSignal strength:\t[ %d%% ]",sts->an_normalized_rssi); - printf("\nMax Noise:\t\t[ %d%% ]",sts->an_avg_noise_prev_min); + if (rssimap_valid) + printf("\nSignal strength:\t[ %d%% ]", + an_rssimap.an_entries[ + sts->an_normalized_strength].an_rss_pct); + else + printf("\nSignal strength:\t[ %d%% ]", + sts->an_normalized_strength); + printf("\nAverage Noise:\t\t[ %d%% ]",sts->an_avg_noise_prev_min_pc); + if (rssimap_valid) + printf("\nSignal quality:\t\t[ %d%% ]", + an_rssimap.an_entries[ + sts->an_cur_signal_quality].an_rss_pct); + else + printf("\nSignal quality:\t\t[ %d ]", + sts->an_cur_signal_quality); + printf("\nMax Noise:\t\t[ %d%% ]",sts->an_max_noise_prev_min_pc); /* * XXX: This uses the old definition of the rate field (units of * 500kbps). Technically the new definition is that this field @@ -378,7 +411,9 @@ static void an_dumpcaps(iface) printf("\nSupported speeds:\t"); an_printspeeds(caps->an_rates, 8); printf("\nRX Diversity:\t\t[ "); - if (caps->an_rx_diversity == AN_DIVERSITY_ANTENNA_1_ONLY) + if (caps->an_rx_diversity == AN_DIVERSITY_FACTORY_DEFAULT) + printf("factory default"); + else if (caps->an_rx_diversity == AN_DIVERSITY_ANTENNA_1_ONLY) printf("antenna 1 only"); else if (caps->an_rx_diversity == AN_DIVERSITY_ANTENNA_2_ONLY) printf("antenna 2 only"); @@ -386,11 +421,13 @@ static void an_dumpcaps(iface) printf("antenna 1 and 2"); printf(" ]"); printf("\nTX Diversity:\t\t[ "); - if (caps->an_rx_diversity == AN_DIVERSITY_ANTENNA_1_ONLY) + if (caps->an_tx_diversity == AN_DIVERSITY_FACTORY_DEFAULT) + printf("factory default"); + else if (caps->an_tx_diversity == AN_DIVERSITY_ANTENNA_1_ONLY) printf("antenna 1 only"); - else if (caps->an_rx_diversity == AN_DIVERSITY_ANTENNA_2_ONLY) + else if (caps->an_tx_diversity == AN_DIVERSITY_ANTENNA_2_ONLY) printf("antenna 2 only"); - else if (caps->an_rx_diversity == AN_DIVERSITY_ANTENNA_1_AND_2) + else if (caps->an_tx_diversity == AN_DIVERSITY_ANTENNA_1_AND_2) printf("antenna 1 and 2"); printf(" ]"); printf("\nSupported power levels:\t"); @@ -786,7 +823,9 @@ static void an_dumpconfig(iface) printf(" ]"); printf("\nRX Diversity:\t\t\t\t[ "); diversity = cfg->an_diversity & 0xFF; - if (diversity == AN_DIVERSITY_ANTENNA_1_ONLY) + if (diversity == AN_DIVERSITY_FACTORY_DEFAULT) + printf("factory default"); + else if (diversity == AN_DIVERSITY_ANTENNA_1_ONLY) printf("antenna 1 only"); else if (diversity == AN_DIVERSITY_ANTENNA_2_ONLY) printf("antenna 2 only"); @@ -795,7 +834,9 @@ static void an_dumpconfig(iface) printf(" ]"); printf("\nTX Diversity:\t\t\t\t[ "); diversity = (cfg->an_diversity >> 8) & 0xFF; - if (diversity == AN_DIVERSITY_ANTENNA_1_ONLY) + if (diversity == AN_DIVERSITY_FACTORY_DEFAULT) + printf("factory default"); + else if (diversity == AN_DIVERSITY_ANTENNA_1_ONLY) printf("antenna 1 only"); else if (diversity == AN_DIVERSITY_ANTENNA_2_ONLY) printf("antenna 2 only"); @@ -828,6 +869,34 @@ static void an_dumpconfig(iface) return; } +static void an_dumprssimap(iface) + const char *iface; +{ + struct an_ltv_rssi_map *rssi; + struct an_req areq; + int i; + + areq.an_len = sizeof(areq); + areq.an_type = AN_RID_RSSI_MAP; + + an_getval(iface, &areq); + + rssi = (struct an_ltv_rssi_map *)&areq; + + printf("idx\tpct\t dBm\n"); + + for (i = 0; i < 0xFF; i++) { + /* + * negate the dBm value: it's the only way the power + * level makes sense + */ + printf("%3d\t%3d\t%4d\n", i, + rssi->an_entries[i].an_rss_pct, + - rssi->an_entries[i].an_rss_dbm); + } + + return; +} static void usage(p) char *p; @@ -838,6 +907,7 @@ static void usage(p) fprintf(stderr, "\t%s -i iface -I (show NIC capabilities)\n", p); fprintf(stderr, "\t%s -i iface -T (show stats counters)\n", p); fprintf(stderr, "\t%s -i iface -C (show current config)\n", p); + fprintf(stderr, "\t%s -i iface -R (show RSSI map)\n", p); fprintf(stderr, "\t%s -i iface -t 0-4 (set TX speed)\n", p); fprintf(stderr, "\t%s -i iface -s 0-3 (set power save mode)\n", p); fprintf(stderr, "\t%s -i iface [-v 1-4] -a AP (specify AP)\n", p); @@ -924,12 +994,12 @@ static void an_setconfig(iface, act, arg) errx(1, "bad diversity setting: %d", diversity); break; } - if (atoi(arg) == ACT_SET_DIVERSITY_RX) { - cfg->an_diversity &= 0x00FF; - cfg->an_diversity |= (diversity << 8); - } else { + if (act == ACT_SET_DIVERSITY_RX) { cfg->an_diversity &= 0xFF00; cfg->an_diversity |= diversity; + } else { + cfg->an_diversity &= 0x00FF; + cfg->an_diversity |= (diversity << 8); } break; case ACT_SET_TXPWR: @@ -1519,7 +1589,7 @@ int main(argc, argv) opterr = 1; while ((ch = getopt(argc, argv, - "ANISCTht:a:e:o:s:n:v:d:j:b:c:r:p:w:m:l:k:K:W:QZM:L:")) != -1) { + "ANISCTRht:a:e:o:s:n:v:d:j:b:c:r:p:w:m:l:k:K:W:QZM:L:")) != -1) { switch(ch) { case 'Z': #ifdef ANCACHE @@ -1553,6 +1623,9 @@ int main(argc, argv) case 'C': act = ACT_DUMPCONFIG; break; + case 'R': + act = ACT_DUMPRSSIMAP; + break; case 't': act = ACT_SET_TXRATE; arg = optarg; @@ -1605,9 +1678,13 @@ int main(argc, argv) act = ACT_SET_DIVERSITY_TX; break; default: - errx(1, "must specift RX or TX diversity"); + errx(1, "must specify RX or TX diversity"); break; } + if (!isdigit(*optarg)) { + errx(1, "%s is not numeric", optarg); + exit(1); + } arg = optarg; break; case 'j': @@ -1718,6 +1795,9 @@ int main(argc, argv) case ACT_DUMPAP: an_dumpap(iface); break; + case ACT_DUMPRSSIMAP: + an_dumprssimap(iface); + break; case ACT_SET_SSID1: case ACT_SET_SSID2: case ACT_SET_SSID3: |