#define DEBUG if(1){}else print
#define SEEKEYS 0
// Lucent's Length-Type-Value records to talk to the wavelan.
// most operational parameters are read/set using this.
enum
{
WTyp_Stats = 0xf100,
WTyp_Scan = 0xf101,
WTyp_Link = 0xf200,
WTyp_Ptype = 0xfc00,
WTyp_Mac = 0xfc01,
WTyp_WantName = 0xfc02,
WTyp_Chan = 0xfc03,
WTyp_NetName = 0xfc04,
WTyp_ApDens = 0xfc06,
WTyp_MaxLen = 0xfc07,
WTyp_PM = 0xfc09,
WTyp_PMWait = 0xfc0c,
WTyp_NodeName = 0xfc0e,
WTyp_Crypt = 0xfc20,
WTyp_XClear = 0xfc22,
WTyp_CreateIBSS = 0xfc81,
WTyp_RtsThres = 0xfc83,
WTyp_TxRate = 0xfc84,
WTx1Mbps = 0x0,
WTx2Mbps = 0x1,
WTxAuto = 0x3,
WTyp_Prom = 0xfc85,
WTyp_Keys = 0xfcb0,
WTyp_TxKey = 0xfcb1,
WTyp_StationID = 0xfd20,
WTyp_CurName = 0xfd41,
WTyp_BaseID = 0xfd42, // ID of the currently connected-to base station
WTyp_CurTxRate = 0xfd44, // Current TX rate
WTyp_HasCrypt = 0xfd4f,
WTyp_Tick = 0xfce0,
};
// Controller
enum
{
WDfltIRQ = 3, // default irq
WDfltIOB = 0x180, // default IO base
WIOLen = 0x40, // Hermes IO length
WTmOut = 65536, // Cmd time out
WPTypeManaged = 1,
WPTypeWDS = 2,
WPTypeAdHoc = 3,
WDfltPType = WPTypeManaged,
WDfltApDens = 1,
WDfltRtsThres = 2347, // == disabled
WDfltTxRate = WTxAuto, // 2Mbps
WMaxLen = 2304,
WNameLen = 32,
WNKeys = 4,
WKeyLen = 14,
WMinKeyLen = 5,
WMaxKeyLen = 13,
// Wavelan hermes registers
WR_Cmd = 0x00,
WCmdIni = 0x0000,
WCmdEna = 0x0001,
WCmdDis = 0x0002,
WCmdTx = 0x000b,
WCmdMalloc = 0x000a,
WCmdEnquire = 0x0011,
WCmdMsk = 0x003f,
WCmdAccRd = 0x0021,
WCmdReclaim = 0x0100,
WCmdAccWr = 0x0121,
WCmdBusy = 0x8000,
WR_Parm0 = 0x02,
WR_Parm1 = 0x04,
WR_Parm2 = 0x06,
WR_Sts = 0x08,
WR_InfoId = 0x10,
WR_Sel0 = 0x18,
WR_Sel1 = 0x1a,
WR_Off0 = 0x1c,
WR_Off1 = 0x1e,
WBusyOff = 0x8000,
WErrOff = 0x4000,
WResSts = 0x7f00,
WR_RXId = 0x20,
WR_Alloc = 0x22,
WR_EvSts = 0x30,
WR_IntEna = 0x32,
WCmdEv = 0x0010,
WRXEv = 0x0001,
WTXEv = 0x0002,
WTxErrEv = 0x0004,
WAllocEv = 0x0008,
WInfoEv = 0x0080,
WIDropEv = 0x2000,
WTickEv = 0x8000,
WEvs = WRXEv|WTXEv|WAllocEv|WInfoEv|WIDropEv,
WR_EvAck = 0x34,
WR_Data0 = 0x36,
WR_Data1 = 0x38,
WR_PciCor = 0x26,
WR_PciHcr = 0x2E,
// Frame stuff
WF_Err = 0x0003,
WF_1042 = 0x2000,
WF_Tunnel = 0x4000,
WF_WMP = 0x6000,
WF_Data = 0x0008,
WSnapK1 = 0xaa,
WSnapK2 = 0x00,
WSnapCtlr = 0x03,
WSnap0 = (WSnapK1|(WSnapK1<<8)),
WSnap1 = (WSnapK2|(WSnapCtlr<<8)),
WSnapHdrLen = 6,
WF_802_11_Off = 0x44,
WF_802_3_Off = 0x2e,
};
typedef struct Ctlr Ctlr;
typedef struct Wltv Wltv;
typedef struct WFrame WFrame;
typedef struct Stats Stats;
typedef struct WStats WStats;
typedef struct WScan WScan;
typedef struct WKey WKey;
struct WStats
{
ulong ntxuframes; // unicast frames
ulong ntxmframes; // multicast frames
ulong ntxfrags; // fragments
ulong ntxubytes; // unicast bytes
ulong ntxmbytes; // multicast bytes
ulong ntxdeferred; // deferred transmits
ulong ntxsretries; // single retries
ulong ntxmultiretries; // multiple retries
ulong ntxretrylimit;
ulong ntxdiscards;
ulong nrxuframes; // unicast frames
ulong nrxmframes; // multicast frames
ulong nrxfrags; // fragments
ulong nrxubytes; // unicast bytes
ulong nrxmbytes; // multicast bytes
ulong nrxfcserr;
ulong nrxdropnobuf;
ulong nrxdropnosa;
ulong nrxcantdecrypt;
ulong nrxmsgfrag;
ulong nrxmsgbadfrag;
ulong end;
};
struct WScan
{
ushort chan; /* dss channel */
ushort noise; /* average noise in the air */
ushort signal; /* signal strength */
uchar bssid[Eaddrlen]; /* MAC address of the ap */
ushort interval; /* beacon transmit interval */
ushort capinfo; /* capability bits (0-ess, 1-ibss, 4-privacy [wep]) */
ushort ssid_len; /* ssid length */
char ssid[WNameLen]; /* ssid (ap name) */
};
struct WFrame
{
ushort sts;
ushort rsvd0;
ushort rsvd1;
ushort qinfo;
ushort rsvd2;
ushort rsvd3;
ushort txctl;
ushort framectl;
ushort id;
uchar addr1[Eaddrlen];
uchar addr2[Eaddrlen];
uchar addr3[Eaddrlen];
ushort seqctl;
uchar addr4[Eaddrlen];
ushort dlen;
uchar dstaddr[Eaddrlen];
uchar srcaddr[Eaddrlen];
ushort len;
ushort dat[3];
ushort type;
};
struct WKey
{
ushort len;
char dat[WKeyLen];
};
struct Wltv
{
ushort len;
ushort type;
union
{
struct {
ushort val;
ushort pad;
};
struct {
uchar addr[8];
};
struct {
ushort slen;
char s[WNameLen];
};
struct {
char name[WNameLen];
};
struct {
WKey keys[WNKeys];
};
};
};
// What the driver thinks. Not what the card thinks.
struct Stats
{
ulong nints;
ulong ndoubleint;
ulong nrx;
ulong ntx;
ulong ntxrq;
ulong nrxerr;
ulong ntxerr;
ulong nalloc; // allocation (reclaim) events
ulong ninfo;
ulong nidrop;
ulong nwatchdogs; // transmit time outs, actually
int ticks;
int tickintr;
int signal;
int noise;
};
enum {
Attached = 0x01,
Power = 0x02,
};
struct Ctlr
{
Lock;
int state; // Attached | Power
int slot;
int iob;
int createibss;
int ptype;
int apdensity;
int rtsthres;
int txbusy;
int txrate;
int txdid;
int txmid;
int txtmout;
int maxlen;
int chan;
int pmena;
int pmwait;
Proc *timerproc;
int scanticks;
char netname[WNameLen];
char wantname[WNameLen];
char nodename[WNameLen];
WFrame txf;
uchar txbuf[1536];
int hascrypt; // card has encryption
int crypt; // encryption off/on
int txkey; // transmit key
Wltv keys; // default keys
int xclear; // exclude clear packets off/on
int ctlrno;
ushort *mmb;
/* for PCI-based devices */
Ctlr *next;
int active;
Pcidev *pcidev;
Stats;
WStats;
};
extern char* wavenames[];
void csr_outs(Ctlr*, int, ushort);
ushort csr_ins(Ctlr*, int);
void w_intdis(Ctlr*);
int w_cmd(Ctlr *, ushort, ushort);
void ltv_outs(Ctlr*, int, ushort);
int ltv_ins(Ctlr*, int);
int w_option(Ctlr*, char*, long);
int w_inltv(Ctlr*, Wltv*);
void w_attach(Ether*);
void w_interrupt(Ureg*,void*);
void w_transmit(Ether*);
long w_ifstat(Ether*, void*, long, ulong);
long w_ctl(Ether*, void*, long);
void w_promiscuous(void*, int);
void w_multicast(void*, uchar*, int);
int wavelanreset(Ether*, Ctlr*);
|