2530 lines · 51.0 KB · C
RawDownload
/* * Intel WiFi Link driver. * * Written without any documentation but Damien Bergaminis * OpenBSD iwn(4) driver sources. Requires intel firmware * to be present in /lib/firmware/iwn-* on attach. */ #include "u.h"#include "../port/lib.h"#include "mem.h"#include "dat.h"#include "fns.h"#include "io.h"#include "../port/error.h"#include "../port/netif.h" #include "etherif.h"#include "wifi.h" enum {	Ntxlog		= 8,	Ntx		= 1<<Ntxlog,	Nrxlog		= 8,	Nrx		= 1<<Nrxlog, 	Rstatsize	= 16,	Rbufsize	= 4*1024,	Rdscsize	= 8, 	Tbufsize	= 4*1024,	Tdscsize	= 128,	Tcmdsize	= 140,}; /* registers */enum {	Cfg		= 0x000,	/* config register */		MacSi		= 1<<8,		RadioSi		= 1<<9,		EepromLocked	= 1<<21,		NicReady	= 1<<22,		HapwakeL1A	= 1<<23,		PrepareDone	= 1<<25,		Prepare		= 1<<27, 	Isr		= 0x008,	/* interrupt status */	Imr		= 0x00c,	/* interrupt mask */		Ialive		= 1<<0,		Iwakeup		= 1<<1,		Iswrx		= 1<<3,		Ictreached	= 1<<6,		Irftoggled	= 1<<7,		Iswerr		= 1<<25,		Isched		= 1<<26,		Ifhtx		= 1<<27,		Irxperiodic	= 1<<28,		Ihwerr		= 1<<29,		Ifhrx		= 1<<31, 		Ierr		= Iswerr | Ihwerr,		Idefmask	= Ierr | Ifhtx | Ifhrx | Ialive | Iwakeup | Iswrx | Ictreached | Irftoggled, 	FhIsr		= 0x010,	/* second interrupt status */ 	Reset		= 0x020,			Rev		= 0x028,	/* hardware revision */ 	EepromIo	= 0x02c,	/* EEPROM i/o register */	EepromGp	= 0x030,			OtpromGp	= 0x034,		DevSelOtp	= 1<<16,		RelativeAccess	= 1<<17,		EccCorrStts	= 1<<20,		EccUncorrStts	= 1<<21, 	Gpc		= 0x024,	/* gp cntrl */		MacAccessEna	= 1<<0,		MacClockReady	= 1<<0,		InitDone	= 1<<2,		MacAccessReq	= 1<<3,		NicSleep	= 1<<4,		RfKill		= 1<<27, 	Gio		= 0x03c,		EnaL0S		= 1<<1, 	GpDrv	= 0x050,		GpDrvCalV6	= 1<<2,		GpDrv1X2	= 1<<3,		GpDrvRadioIqInvert	= 1<<7,  	Led		= 0x094,		LedBsmCtrl	= 1<<5,		LedOn		= 0x38,		LedOff		= 0x78, 	UcodeGp1Clr	= 0x05c,		UcodeGp1RfKill		= 1<<1,		UcodeGp1CmdBlocked	= 1<<2,		UcodeGp1CtempStopRf	= 1<<3, 	ShadowRegCtrl	= 0x0a8, 	Giochicken	= 0x100,		L1AnoL0Srx	= 1<<23,		DisL0Stimer	= 1<<29, 	AnaPll		= 0x20c, 	Dbghpetmem	= 0x240,	Dbglinkpwrmgmt	= 0x250, 	MemRaddr	= 0x40c,	MemWaddr	= 0x410,	MemWdata	= 0x418,	MemRdata	= 0x41c, 	PrphWaddr	= 0x444,	PrphRaddr	= 0x448,	PrphWdata	= 0x44c,	PrphRdata	= 0x450, 	HbusTargWptr	= 0x460,}; /* * Flow-Handler registers. */enum {	FhTfbdCtrl0	= 0x1900,	// +q*8	FhTfbdCtrl1	= 0x1904,	// +q*8 	FhKwAddr	= 0x197c, 	FhSramAddr	= 0x19a4,	// +q*4	FhCbbcQueue	= 0x19d0,	// +q*4	FhStatusWptr	= 0x1bc0,	FhRxBase	= 0x1bc4,	FhRxWptr	= 0x1bc8,	FhRxConfig	= 0x1c00,		FhRxConfigEna		= 1<<31,		FhRxConfigRbSize8K	= 1<<16,		FhRxConfigSingleFrame	= 1<<15,		FhRxConfigIrqDstHost	= 1<<12,		FhRxConfigIgnRxfEmpty	= 1<<2, 		FhRxConfigNrbdShift	= 20,		FhRxConfigRbTimeoutShift= 4, 	FhRxStatus	= 0x1c44, 	FhTxConfig	= 0x1d00,	// +q*32		FhTxConfigDmaCreditEna	= 1<<3,		FhTxConfigDmaEna	= 1<<31,		FhTxConfigCirqHostEndTfd= 1<<20, 	FhTxBufStatus	= 0x1d08,	// +q*32		FhTxBufStatusTbNumShift	= 20,		FhTxBufStatusTbIdxShift = 12,		FhTxBufStatusTfbdValid	= 3, 	FhTxChicken	= 0x1e98,	FhTxStatus	= 0x1eb0,}; /* * NIC internal memory offsets. */enum {	ApmgClkCtrl	= 0x3000,	ApmgClkEna	= 0x3004,	ApmgClkDis	= 0x3008,		DmaClkRqt	= 1<<9,		BsmClkRqt	= 1<<11, 	ApmgPs		= 0x300c,		EarlyPwroffDis	= 1<<22,		PwrSrcVMain	= 0<<24,		PwrSrcVAux	= 2<<24,		PwrSrcMask	= 3<<24,		ResetReq	= 1<<26, 	ApmgDigitalSvr	= 0x3058,	ApmgAnalogSvr	= 0x306c,	ApmgPciStt	= 0x3010,	BsmWrCtrl	= 0x3400,	BsmWrMemSrc	= 0x3404,	BsmWrMemDst	= 0x3408,	BsmWrDwCount	= 0x340c,	BsmDramTextAddr	= 0x3490,	BsmDramTextSize	= 0x3494,	BsmDramDataAddr	= 0x3498,	BsmDramDataSize	= 0x349c,	BsmSramBase	= 0x3800,}; /* * TX scheduler registers. */enum {	SchedBase		= 0xa02c00,	SchedSramAddr		= SchedBase, 	SchedDramAddr4965	= SchedBase+0x010,	SchedTxFact4965		= SchedBase+0x01c,	SchedQueueRdptr4965	= SchedBase+0x064,	// +q*4	SchedQChainSel4965	= SchedBase+0x0d0,	SchedIntrMask4965	= SchedBase+0x0e4,	SchedQueueStatus4965	= SchedBase+0x104,	// +q*4 	SchedDramAddr5000	= SchedBase+0x008,	SchedTxFact5000		= SchedBase+0x010,	SchedQueueRdptr5000	= SchedBase+0x068,	// +q*4	SchedQChainSel5000	= SchedBase+0x0e8,	SchedIntrMask5000	= SchedBase+0x108,	SchedQueueStatus5000	= SchedBase+0x10c,	// +q*4	SchedAggrSel5000	= SchedBase+0x248,}; enum {	SchedCtxOff4965		= 0x380,	SchedCtxLen4965		= 416, 	SchedCtxOff5000		= 0x600,	SchedCtxLen5000		= 512,}; enum {	FilterPromisc		= 1<<0,	FilterCtl		= 1<<1,	FilterMulticast		= 1<<2,	FilterNoDecrypt		= 1<<3,	FilterBSS		= 1<<5,	FilterBeacon		= 1<<6,}; enum {	RFlag24Ghz		= 1<<0,	RFlagCCK		= 1<<1,	RFlagAuto		= 1<<2,	RFlagShSlot		= 1<<4,	RFlagShPreamble		= 1<<5,	RFlagNoDiversity	= 1<<7,	RFlagAntennaA		= 1<<8,	RFlagAntennaB		= 1<<9,	RFlagTSF		= 1<<15,	RFlagCTSToSelf		= 1<<30,}; typedef struct FWInfo FWInfo;typedef struct FWImage FWImage;typedef struct FWSect FWSect; typedef struct TXQ TXQ;typedef struct RXQ RXQ; typedef struct Ctlr Ctlr; struct FWSect{	uchar	*data;	uint	size;}; struct FWImage{	struct {		FWSect	text;		FWSect	data;	} init, main, boot; 	uint	rev;	uint	build;	char	descr[64+1];	uchar	data[];}; struct FWInfo{	uchar	major;	uchar	minjor;	uchar	type;	uchar	subtype; 	u32int	logptr;	u32int	errptr;	u32int	tstamp;	u32int	valid;}; struct TXQ{	uint	n;	uint	i;	Block	**b;	uchar	*d;	uchar	*c; 	uint	lastcmd; 	Rendez;	QLock;}; struct RXQ{	uint	i;	Block	**b;	u32int	*p;	uchar	*s;}; struct Ctlr {	Lock;	QLock; 	Ctlr *link;	Pcidev *pdev;	Wifi *wifi; 	int type;	int port;	int power;	int active;	int broken;	int attached; 	u32int ie; 	u32int *nic;	uchar *kwpage; 	/* assigned node ids in hardware node table or -1 if unassigned */	int bcastnodeid;	int bssnodeid; 	/* current receiver settings */	uchar bssid[Eaddrlen];	int channel;	int prom;	int aid; 	RXQ rx;	TXQ tx[20]; 	struct {		Rendez;		u32int	m;		u32int	w;	} wait; 	struct {		uchar	type;		uchar	step;		uchar	dash;		uchar	txantmask;		uchar	rxantmask;	} rfcfg; 	struct {		int	otp;		uint	off; 		uchar	version;		uchar	type;		u16int	volt;		u16int	temp;		u16int	rawtemp; 		char	regdom[4+1]; 		u32int	crystal;	} eeprom; 	struct {		Block	*cmd[21];		int	done;	} calib; 	struct {		u32int	base;		uchar	*s;	} sched; 	FWInfo fwinfo;	FWImage *fw;}; /* controller types */enum {	Type4965	= 0,	Type5300	= 2,	Type5350	= 3,	Type5150	= 4,	Type5100	= 5,	Type1000	= 6,	Type6000	= 7,	Type6050	= 8,	Type6005	= 11,	Type2030	= 12,}; static char *fwname[16] = {	[Type4965] "iwn-4965",	[Type5300] "iwn-5000",	[Type5350] "iwn-5000",	[Type5150] "iwn-5150",	[Type5100] "iwn-5000",	[Type1000] "iwn-1000",	[Type6000] "iwn-6000",	[Type6050] "iwn-6050",	[Type6005] "iwn-6005",	[Type2030] "iwn-2030",}; static char *qcmd(Ctlr *ctlr, uint qid, uint code, uchar *data, int size, Block *block);static char *flushq(Ctlr *ctlr, uint qid);static char *cmd(Ctlr *ctlr, uint code, uchar *data, int size); #define csr32r(c, r)	(*((c)->nic+((r)/4)))#define csr32w(c, r, v)	(*((c)->nic+((r)/4)) = (v)) static uintget16(uchar *p){	return *((u16int*)p);}static uintget32(uchar *p){	return *((u32int*)p);}static voidput32(uchar *p, uint v){	*((u32int*)p) = v;}static voidput16(uchar *p, uint v){	*((u16int*)p) = v;}; static char*niclock(Ctlr *ctlr){	int i; 	csr32w(ctlr, Gpc, csr32r(ctlr, Gpc) | MacAccessReq);	for(i=0; i<1000; i++){		if((csr32r(ctlr, Gpc) & (NicSleep | MacAccessEna)) == MacAccessEna)			return 0;		delay(10);	}	return "niclock: timeout";} static voidnicunlock(Ctlr *ctlr){	csr32w(ctlr, Gpc, csr32r(ctlr, Gpc) & ~MacAccessReq);} static u32intprphread(Ctlr *ctlr, uint off){	csr32w(ctlr, PrphRaddr, ((sizeof(u32int)-1)<<24) | off);	coherence();	return csr32r(ctlr, PrphRdata);}static voidprphwrite(Ctlr *ctlr, uint off, u32int data){	csr32w(ctlr, PrphWaddr, ((sizeof(u32int)-1)<<24) | off);	coherence();	csr32w(ctlr, PrphWdata, data);} static u32intmemread(Ctlr *ctlr, uint off){	csr32w(ctlr, MemRaddr, off);	coherence();	return csr32r(ctlr, MemRdata);}static voidmemwrite(Ctlr *ctlr, uint off, u32int data){	csr32w(ctlr, MemWaddr, off);	coherence();	csr32w(ctlr, MemWdata, data);} static voidsetfwinfo(Ctlr *ctlr, uchar *d, int len){	FWInfo *i; 	if(len < 32)		return;	i = &ctlr->fwinfo;

Lines 1–500 of 2530.

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t