This is a program for configuring the Parameter Storage Area on ISA
Wavelan cards via the 'wl' driver. It can be used to set the IRQ, and discover all manner of odd things about the device.
This commit is contained in:
parent
e847647398
commit
1b6394c6c7
7
usr.sbin/wlconfig/Makefile
Normal file
7
usr.sbin/wlconfig/Makefile
Normal file
@ -0,0 +1,7 @@
|
||||
# $Id$
|
||||
PROG= wlconfig
|
||||
SRCS= wlconfig.c
|
||||
CFLAGS+= Wall
|
||||
MAN8= wlconfig.8
|
||||
|
||||
.include <bsd.prog.mk>
|
103
usr.sbin/wlconfig/wlconfig.8
Normal file
103
usr.sbin/wlconfig/wlconfig.8
Normal file
@ -0,0 +1,103 @@
|
||||
.Dd December 26 1996
|
||||
.Os
|
||||
.Dt WLCONFIG 8
|
||||
.Sh NAME
|
||||
.Nm wlconfig
|
||||
.Nd read/write wavelan config parameters
|
||||
.Sh SYNOPSIS
|
||||
.Nm wlconfig
|
||||
.Ar ifname
|
||||
.Op Ar param value ...
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm wlconfig
|
||||
command can be used to read and set parameters for the NCR/AT&T Wavelan
|
||||
radio LAN card. Various parameters stored in the nonvolatile Parameter
|
||||
Storage Area (PSA) on the card can be modified with this program, which
|
||||
obviates the need for the DOS-based
|
||||
.Nm instconf.exe
|
||||
program.
|
||||
.Pp
|
||||
The
|
||||
.Ar ifname
|
||||
parameter specifies the wavelan interface name (eg.
|
||||
.Pa wl0
|
||||
). If no other arguments are supplied, the current contents of the PSA
|
||||
are interpreted and displayed.
|
||||
.Pp
|
||||
The
|
||||
.Ar param
|
||||
and
|
||||
.Ar value
|
||||
arguments can be used to change the value of several of the parameters.
|
||||
Any number of
|
||||
.Ar param value
|
||||
pairs may be supplied.
|
||||
.Bl -tag -width 15n -compat -offset indent
|
||||
.It Va param
|
||||
.Va value
|
||||
.It irq
|
||||
IRQ value (used at next reset), may be one of 3,4,5,6,10,11,12,15
|
||||
.It mac
|
||||
Local MAC value (ethernet address)
|
||||
.It macsel
|
||||
.Sq soft
|
||||
(as set by the
|
||||
.Sq mac
|
||||
parameter) or
|
||||
.Sq default
|
||||
(as set at the factory).
|
||||
.It nwid
|
||||
The NWID is a 2-byte parameter passed to the card's radio modem.
|
||||
NWIDs allow multiple logically discrete networks to operate
|
||||
independantly whilse occupying the same airspace.
|
||||
Packets with a different NWID are simply ignored by the modem.
|
||||
In the hardware, NWIDs are stored long-term in non-volative memory
|
||||
(called the PSA or programmable storage area), and are loaded by
|
||||
software into the radio modem when the driver is
|
||||
initialized. This sets the default NWID loaded at startup.
|
||||
.It curnwid
|
||||
This sets the current operating NWID (but does not save it to the
|
||||
PSA).
|
||||
.El
|
||||
.Pp
|
||||
Note that if the IRQ on the Wavelan card is incorrect, the interface
|
||||
will be configured, but will not function. The
|
||||
.Nm wlconfig
|
||||
program should then be used to reconfigure the card to a sensible
|
||||
value.
|
||||
.Sh EXAMPLES
|
||||
Set the NWID to 0x1234 :
|
||||
.Bd -literal -offset
|
||||
# wlconfig wl0 nwid 0x1234
|
||||
.Ed
|
||||
.Pp
|
||||
Show the current settings :
|
||||
.Bd -literal -offset
|
||||
# wlconfig wl0
|
||||
Board type : ISA
|
||||
Base address options : 0x300, 0x390, 0x3c0, 0x3e0
|
||||
Waitstates : 0
|
||||
Bus mode : ISA
|
||||
IRQ : 10
|
||||
Default MAC address : 08:00:0e:20:3d:4b
|
||||
Soft MAC address : 00:00:00:00:00:00
|
||||
Current MAC address : Default
|
||||
Adapter compatability : PC-AT 2.4GHz
|
||||
Threshold preset : 1
|
||||
Call code required : NO
|
||||
Subband : 2425MHz
|
||||
Quality threshold : 3
|
||||
Hardware version : 0 (Rel1/Rel2)
|
||||
Network ID enable : YES
|
||||
NWID : 0xdead
|
||||
Datalink security : NO
|
||||
Databus width : 16 (variable)
|
||||
Configuration state : unconfigured
|
||||
CRC-16 : 0x3c26
|
||||
CRC status : OK
|
||||
.Ed
|
||||
.Sh HISTORY
|
||||
This implementation of the
|
||||
.Nm wlconfig
|
||||
command is completely new, written for Hilink Internet by Michael Smith.
|
325
usr.sbin/wlconfig/wlconfig.c
Normal file
325
usr.sbin/wlconfig/wlconfig.c
Normal file
@ -0,0 +1,325 @@
|
||||
/*
|
||||
* Copyright (C) 1996
|
||||
* Michael Smith. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY Michael Smith AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL Michael Smith OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
*/
|
||||
/*
|
||||
* wlconfig.c
|
||||
*
|
||||
* utility to read out and change various WAVELAN parameters.
|
||||
* Currently supports NWID and IRQ values.
|
||||
*
|
||||
* The NWID is used by 2 or more wavelan controllers to determine
|
||||
* if packets should be received or not. It is a filter that
|
||||
* is roughly analogous to the "channel" setting with a garage
|
||||
* door controller. Two companies side by side with wavelan devices
|
||||
* that could actually hear each other can use different NWIDs
|
||||
* and ignore packets. In truth however, the air space is shared,
|
||||
* and the NWID is a virtual filter.
|
||||
*
|
||||
* In the current set of wavelan drivers, ioctls changed only
|
||||
* the runtime radio modem registers which act in a manner analogous
|
||||
* to an ethernet transceiver. The ioctls do not change the
|
||||
* stored nvram PSA (or parameter storage area). At boot, the PSA
|
||||
* values are stored in the radio modem. Thus when the
|
||||
* system reboots it will restore the wavelan NWID to the value
|
||||
* stored in the PSA. The NCR/ATT dos utilities must be used to
|
||||
* change the initial NWID values in the PSA. The wlconfig utility
|
||||
* may be used to set a different NWID at runtime; this is only
|
||||
* permitted while the interface is up and running.
|
||||
*
|
||||
* By contrast, the IRQ value can only be changed while the
|
||||
* Wavelan card is down and unconfigured, and it will remain
|
||||
* disabled after an IRQ change until reboot.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <machine/if_wl_wavelan.h>
|
||||
|
||||
#include <net/if.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/if_ether.h>
|
||||
extern struct ether_addr *ether_aton(char *a);
|
||||
|
||||
#include <err.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <limits.h>
|
||||
|
||||
/* translate IRQ bit to number */
|
||||
/* array for maping irq numbers to values for the irq parameter register */
|
||||
static int irqvals[16] = {
|
||||
0, 0, 0, 0x01, 0x02, 0x04, 0, 0x08, 0, 0, 0x10, 0x20, 0x40, 0, 0, 0x80
|
||||
};
|
||||
|
||||
int
|
||||
wlirq(int irqval)
|
||||
{
|
||||
int irq;
|
||||
|
||||
for(irq = 0; irq < 16; irq++)
|
||||
if(irqvals[irq] == irqval)
|
||||
return(irq);
|
||||
return 0;
|
||||
}
|
||||
|
||||
char *compat_type[] = {
|
||||
"PC-AT 915MHz",
|
||||
"PC-MC 915MHz",
|
||||
"PC-AT 2.4GHz",
|
||||
"PC-MC 2.4GHz",
|
||||
"PCCARD or 1/2 size AT, 915MHz or 2.4GHz"
|
||||
};
|
||||
|
||||
char *subband[] = {
|
||||
"915MHz/see WaveModem",
|
||||
"2425MHz",
|
||||
"2460MHz",
|
||||
"2484MHz",
|
||||
"2430.5MHz"
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
** print_psa
|
||||
**
|
||||
** Given a pointer to a PSA structure, print it out
|
||||
*/
|
||||
void
|
||||
print_psa(u_char *psa, int currnwid)
|
||||
{
|
||||
int nwid;
|
||||
|
||||
/*
|
||||
** Work out what sort of board we have
|
||||
*/
|
||||
if (psa[0] == 0x14) {
|
||||
printf("Board type : Microchannel\n");
|
||||
} else {
|
||||
if (psa[1] == 0) {
|
||||
printf("Board type : PCCARD\n");
|
||||
} else {
|
||||
printf("Board type : ISA");
|
||||
if ((psa[4] == 0) &&
|
||||
(psa[5] == 0) &&
|
||||
(psa[6] == 0))
|
||||
printf(" (DEC OEM)");
|
||||
printf("\n");
|
||||
printf("Base address options : 0x300, 0x%02x0, 0x%02x0, 0x%02x0\n",
|
||||
(int)psa[1], (int)psa[2], (int)psa[3]);
|
||||
printf("Waitstates : %d\n",psa[7] & 0xf);
|
||||
printf("Bus mode : %s\n",(psa[7] & 0x10) ? "EISA" : "ISA");
|
||||
printf("IRQ : %d\n",wlirq(psa[8]));
|
||||
}
|
||||
}
|
||||
printf("Default MAC address : %02x:%02x:%02x:%02x:%02x:%02x\n",
|
||||
psa[0x10],psa[0x11],psa[0x12],psa[0x13],psa[0x14],psa[0x15]);
|
||||
printf("Soft MAC address : %02x:%02x:%02x:%02x:%02x:%02x\n",
|
||||
psa[0x16],psa[0x17],psa[0x18],psa[0x19],psa[0x1a],psa[0x1b]);
|
||||
printf("Current MAC address : %s\n",(psa[0x1c] & 0x1) ? "Soft" : "Default");
|
||||
printf("Adapter compatability : ");
|
||||
if (psa[0x1d] < 5) {
|
||||
printf("%s\n",compat_type[psa[0x1d]]);
|
||||
} else {
|
||||
printf("unknown\n");
|
||||
}
|
||||
printf("Threshold preset : %d\n",psa[0x1e]);
|
||||
printf("Call code required : %s\n",(psa[0x1f] & 0x1) ? "YES" : "NO");
|
||||
if (psa[0x1f] & 0x1)
|
||||
printf("Call code : 0x%02x%02x%02x%02x%02x%02x%02x%02x\n",
|
||||
psa[0x30],psa[0x31],psa[0x32],psa[0x33],psa[0x34],psa[0x35],psa[0x36],psa[0x37]);
|
||||
printf("Subband : %s\n",subband[psa[0x20] & 0xf]);
|
||||
printf("Quality threshold : %d\n",psa[0x21]);
|
||||
printf("Hardware version : %d (%s)\n",psa[0x22],psa[0x22] ? "Rel3" : "Rel1/Rel2");
|
||||
printf("Network ID enable : %s\n",(psa[0x25] & 0x1) ? "YES" : "NO");
|
||||
if (psa[0x25] & 0x1) {
|
||||
nwid = (psa[0x23] << 8) + psa[0x24];
|
||||
printf("NWID : 0x%04x\n",nwid);
|
||||
if (nwid != currnwid) {
|
||||
printf("Current NWID : 0x%04x\n",currnwid);
|
||||
}
|
||||
}
|
||||
printf("Datalink security : %s\n",(psa[0x26] & 0x1) ? "YES" : "NO");
|
||||
if (psa[0x26] & 0x1) {
|
||||
printf("Encryption key : ");
|
||||
if (psa[0x27] == 0) {
|
||||
printf("DENIED\n");
|
||||
} else {
|
||||
printf("0x%02x%02x%02x%02x%02x%02x%02x%02x\n",
|
||||
psa[0x27],psa[0x28],psa[0x29],psa[0x2a],psa[0x2b],psa[0x2c],psa[0x2d],psa[0x2e]);
|
||||
}
|
||||
}
|
||||
printf("Databus width : %d (%s)\n",
|
||||
(psa[0x2f] & 0x1) ? 16 : 8, (psa[0x2f] & 0x80) ? "fixed" : "variable");
|
||||
printf("Configuration state : %sconfigured\n",(psa[0x38] & 0x1) ? "" : "un");
|
||||
printf("CRC-16 : 0x%02x%02x\n",psa[0x3e],psa[0x3d]);
|
||||
printf("CRC status : ");
|
||||
switch(psa[0x3f]) {
|
||||
case 0xaa:
|
||||
printf("OK\n");
|
||||
break;
|
||||
case 0x55:
|
||||
printf("BAD\n");
|
||||
break;
|
||||
default:
|
||||
printf("Error\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
syntax(char *pname)
|
||||
{
|
||||
fprintf(stderr,"Usage: %s <ifname> [<param> <value> ...]\n",pname);
|
||||
fprintf(stderr," <ifname> Wavelan interface name.\n");
|
||||
fprintf(stderr," <param> Parameter name (see below)\n");
|
||||
fprintf(stderr," <value> New value for parameter.\n");
|
||||
fprintf(stderr," Parameter name: Value:\n");
|
||||
fprintf(stderr," irq 3,4,5,6,10,11,12,15\n");
|
||||
fprintf(stderr," mac soft ethernet address\n");
|
||||
fprintf(stderr," macsel soft or default\n");
|
||||
fprintf(stderr," nwid default NWID (0x0-0xffff)\n");
|
||||
fprintf(stderr," currnwid current NWID (0x0-0xffff) or 'get'\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
void
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
int sd;
|
||||
struct ifreq ifr;
|
||||
u_char psabuf[0x40];
|
||||
int val, argind, i;
|
||||
char *cp, *param, *value;
|
||||
struct ether_addr *ea;
|
||||
int work = 0;
|
||||
int currnwid;
|
||||
|
||||
if ((argc < 2) || (argc % 2))
|
||||
syntax(argv[0]);
|
||||
|
||||
/* get a socket */
|
||||
sd = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if (sd < 0)
|
||||
err(1,"socket");
|
||||
strncpy(ifr.ifr_name, argv[1], sizeof(ifr.ifr_name));
|
||||
ifr.ifr_addr.sa_family = AF_INET;
|
||||
|
||||
/* get the PSA */
|
||||
ifr.ifr_data = (caddr_t)psabuf;
|
||||
if (ioctl(sd, SIOCGWLPSA, (caddr_t)&ifr))
|
||||
err(1,"Get PSA");
|
||||
|
||||
/* get the current NWID */
|
||||
if (ioctl(sd, SIOCGWLCNWID, (caddr_t)&ifr))
|
||||
err(1,"Get NWID");
|
||||
currnwid = (int)ifr.ifr_data;
|
||||
|
||||
/* just dump and exit? */
|
||||
if (argc == 2) {
|
||||
print_psa(psabuf, currnwid);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
/* loop reading arg pairs */
|
||||
for (argind = 2; argind < argc; argind += 2) {
|
||||
|
||||
param = argv[argind];
|
||||
value = argv[argind+1];
|
||||
|
||||
/* What to do? */
|
||||
|
||||
if (!strcasecmp(param,"currnwid")) { /* set current NWID */
|
||||
val = strtol(value,&cp,0);
|
||||
if ((val < 0) || (val > 0xffff) || (cp == value))
|
||||
errx(1,"Bad NWID '%s'",value);
|
||||
|
||||
ifr.ifr_data = (caddr_t)val;
|
||||
if (ioctl(sd, SIOCSWLCNWID, (caddr_t)&ifr))
|
||||
err(1,"Set NWID (interface not up?)");
|
||||
continue ;
|
||||
}
|
||||
|
||||
if (!strcasecmp(param,"irq")) {
|
||||
val = strtol(value,&cp,0);
|
||||
val = irqvals[val];
|
||||
if ((val == 0) || (cp == value))
|
||||
errx(1,"Bad IRQ '%s'",value);
|
||||
psabuf[WLPSA_IRQNO] = (u_char)val;
|
||||
work = 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!strcasecmp(param,"mac")) {
|
||||
if ((ea = ether_aton(value)) == NULL)
|
||||
errx(1,"Bad ethernet address '%s'",value);
|
||||
for (i = 0; i < 6; i++)
|
||||
psabuf[WLPSA_LOCALMAC + i] = ea->octet[i];
|
||||
work = 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!strcasecmp(param,"macsel")) {
|
||||
if (!strcasecmp(value,"local")) {
|
||||
psabuf[WLPSA_MACSEL] |= 0x1;
|
||||
work = 1;
|
||||
continue;
|
||||
}
|
||||
if (!strcasecmp(value,"universal")) {
|
||||
psabuf[WLPSA_MACSEL] &= ~0x1;
|
||||
work = 1;
|
||||
continue;
|
||||
}
|
||||
errx(1,"Bad macsel value '%s'",value);
|
||||
}
|
||||
|
||||
if (!strcasecmp(param,"nwid")) {
|
||||
val = strtol(value,&cp,0);
|
||||
if ((val < 0) || (val > 0xffff) || (cp == value))
|
||||
errx(1,"Bad NWID '%s'",value);
|
||||
psabuf[WLPSA_NWID] = (val >> 8) & 0xff;
|
||||
psabuf[WLPSA_NWID+1] = val & 0xff;
|
||||
work = 1;
|
||||
continue;
|
||||
}
|
||||
errx(1,"Unknown parameter '%s'",param);
|
||||
}
|
||||
if (work) {
|
||||
ifr.ifr_data = (caddr_t)psabuf;
|
||||
if (ioctl(sd, SIOCSWLPSA, (caddr_t)&ifr))
|
||||
err(1,"Set PSA");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user