#include "io.h"
#include "../port/error.h"
#include "../port/netif.h"
-
-#include "etherif.h"
-#include "wifi.h"
+#include "../port/etherif.h"
+#include "../port/wifi.h"
enum {
+ MaxQueue = 24*1024, /* total buffer is 2*MaxQueue: 48k at 22Mbit ≅ 20ms */
+
Ntxlog = 8,
Ntx = 1<<Ntxlog,
+ Ntxqmax = MaxQueue/1500,
+
Nrxlog = 8,
Nrx = 1<<Nrxlog,
Type1000 = 6,
Type6000 = 7,
Type6050 = 8,
- Type6005 = 11,
+ Type6005 = 11, /* also Centrino Advanced-N 6030, 6235 */
Type2030 = 12,
+ Type2000 = 16,
};
-static char *fwname[16] = {
+static char *fwname[32] = {
[Type4965] "iwn-4965",
[Type5300] "iwn-5000",
[Type5350] "iwn-5000",
[Type1000] "iwn-1000",
[Type6000] "iwn-6000",
[Type6050] "iwn-6050",
- [Type6005] "iwn-6005",
+ [Type6005] "iwn-6005", /* see in iwlattach() below */
[Type2030] "iwn-2030",
+ [Type2000] "iwn-2000",
};
static char *qcmd(Ctlr *ctlr, uint qid, uint code, uchar *data, int size, Block *block);
uint u, caloff, regoff;
ctlr = edev->ctlr;
+
+ /* Clear device-specific "PCI retry timeout" register (41h). */
+ if(pcicfgr8(ctlr->pdev, 0x41) != 0)
+ pcicfgw8(ctlr->pdev, 0x41, 0);
+
+ /* Clear interrupt disable bit. Hardware bug workaround. */
+ if(ctlr->pdev->pcr & 0x400){
+ ctlr->pdev->pcr &= ~0x400;
+ pcicfgw16(ctlr->pdev, PciPCR, ctlr->pdev->pcr);
+ }
+
+ ctlr->type = (csr32r(ctlr, Rev) >> 4) & 0x1F;
+ if(fwname[ctlr->type] == nil){
+ print("iwl: unsupported controller type %d\n", ctlr->type);
+ return -1;
+ }
+
if((err = handover(ctlr)) != nil)
goto Err;
if((err = poweron(ctlr)) != nil)
ctlr->eeprom.temp = 0;
ctlr->eeprom.rawtemp = 0;
- if(ctlr->type == Type2030){
+ if(ctlr->type == Type2030 || ctlr->type == Type2000){
if((err = eepromread(ctlr, b, 2, caloff + 0x12a)) != nil)
goto Err2;
ctlr->eeprom.temp = get16(b);
csr32w(ctlr, GpDrv, csr32r(ctlr, GpDrv) | GpDrvCalV6);
if(ctlr->type == Type6005)
csr32w(ctlr, GpDrv, csr32r(ctlr, GpDrv) | GpDrv1X2);
- if(ctlr->type == Type2030)
+ if(ctlr->type == Type2030 || ctlr->type == Type2000)
csr32w(ctlr, GpDrv, csr32r(ctlr, GpDrv) | GpDrvRadioIqInvert);
nicunlock(ctlr);
Block *b;
i = cmds[q];
- if(i == 8 && ctlr->type != Type5150 && ctlr->type != Type2030)
+ if(i == 8 && ctlr->type != Type5150 && ctlr->type != Type2030 &&
+ ctlr->type != Type2000)
continue;
if(i == 17 && (ctlr->type >= Type6000 || ctlr->type == Type5150) &&
- ctlr->type != Type2030)
+ ctlr->type != Type2030 && ctlr->type != Type2000)
continue;
if((b = ctlr->calib.cmd[i]) == nil)
break;
case Type2030:
+ case Type2000:
memset(c, 0, sizeof(c));
c[0] = 18;
c[1] = 0;
txqready(void *arg)
{
TXQ *q = arg;
- return q->n < Ntx;
+ return q->n < Ntxqmax;
}
static char*
ilock(ctlr);
q = &ctlr->tx[qid];
- while(q->n >= Ntx && !ctlr->broken){
+ while(q->n >= Ntxqmax && !ctlr->broken){
iunlock(ctlr);
qlock(q);
if(!waserror()){
- tsleep(q, txqready, q, 10);
+ tsleep(q, txqready, q, 5);
poperror();
}
qunlock(q);
ctlr->channel = bss->channel;
bss = nil;
}
+ flags = RFlagTSF | RFlagCTSToSelf | RFlag24Ghz | RFlagAuto;
if(bss != nil){
+ if(bss->cap & (1<<5))
+ flags |= RFlagShPreamble;
+ if(bss->cap & (1<<10))
+ flags |= RFlagShSlot;
ctlr->channel = bss->channel;
memmove(ctlr->bssid, bss->bssid, Eaddrlen);
ctlr->aid = bss->aid;
ctlr->bcastnodeid = -1;
ctlr->bssnodeid = -1;
}
- flags = RFlagTSF | RFlagCTSToSelf | RFlag24Ghz | RFlagAuto;
if(ctlr->aid != 0)
setled(ctlr, 2, 0, 1); /* on when associated */
{ 4, 20, RFlagCCK },
{ 11, 55, RFlagCCK },
{ 22, 110, RFlagCCK },
+
{ 12, 0xd, 0 },
{ 18, 0xf, 0 },
{ 24, 0x5, 0 },
0x80 | 4,
0x80 | 11,
0x80 | 22,
+
0x80 | 12,
0x80 | 18,
0x80 | 24,
flags |= TFlagFullTxOp;
}
}
+ if(p >= wifi->rates)
+ rate = p - wifi->rates;
+ else
+ rate = 0;
qunlock(ctlr);
- rate = 0;
- if(p >= iwlrates && p < &iwlrates[nelem(ratetab)])
- rate = p - iwlrates;
-
/* select first available antenna */
ant = ctlr->rfcfg.txantmask & 7;
ant |= (ant == 0);
error("wifi disabled by switch");
if(ctlr->wifi == nil){
+ qsetlimit(edev->oq, MaxQueue);
+
ctlr->wifi = wifiattach(edev, transmit);
/* tested with 2230, it has transmit issues using higher bit rates */
if(ctlr->type != Type2030)
}
if(ctlr->fw == nil){
- fw = readfirmware(fwname[ctlr->type]);
+ char *fn = fwname[ctlr->type];
+ if(ctlr->type == Type6005){
+ switch(ctlr->pdev->did){
+ case 0x0082: /* Centrino Advanced-N 6205 */
+ case 0x0085: /* Centrino Advanced-N 6205 */
+ break;
+ default: /* Centrino Advanced-N 6030, 6235 */
+ fn = "iwn-6030";
+ }
+ }
+ fw = readfirmware(fn);
print("#l%d: firmware: %s, rev %ux, build %ud, size %ux+%ux+%ux+%ux+%ux\n",
- edev->ctlrno,
- fwname[ctlr->type],
+ edev->ctlrno, fn,
fw->rev, fw->build,
fw->main.text.size, fw->main.data.size,
fw->init.text.size, fw->init.data.size,
case 0x4229: /* WiFi Link 4965 */
case 0x4230: /* WiFi Link 4965 */
case 0x4232: /* Wifi Link 5100 */
+ case 0x4235: /* Intel Corporation Ultimate N WiFi Link 5300 */
case 0x4236: /* WiFi Link 5300 AGN */
case 0x4237: /* Wifi Link 5100 AGN */
+ case 0x4239: /* Centrino Advanced-N 6200 */
case 0x423d: /* Wifi Link 5150 */
+ case 0x423b: /* PRO/Wireless 5350 AGN */
+ case 0x0082: /* Centrino Advanced-N 6205 */
case 0x0085: /* Centrino Advanced-N 6205 */
case 0x422b: /* Centrino Ultimate-N 6300 variant 1 */
case 0x4238: /* Centrino Ultimate-N 6300 variant 2 */
case 0x08ae: /* Centrino Wireless-N 100 */
case 0x0083: /* Centrino Wireless-N 1000 */
+ case 0x008a: /* Centrino Wireless-N 1030 */
+ case 0x0891: /* Centrino Wireless-N 2200 */
case 0x0887: /* Centrino Wireless-N 2230 */
case 0x0888: /* Centrino Wireless-N 2230 */
+ case 0x0090: /* Centrino Advanced-N 6030 */
+ case 0x0091: /* Centrino Advanced-N 6030 */
+ case 0x088e: /* Centrino Advanced-N 6235 */
+ case 0x088f: /* Centrino Advanced-N 6235 */
break;
}
- /* Clear device-specific "PCI retry timeout" register (41h). */
- if(pcicfgr8(pdev, 0x41) != 0)
- pcicfgw8(pdev, 0x41, 0);
-
- /* Clear interrupt disable bit. Hardware bug workaround. */
- if(pdev->pcr & 0x400){
- pdev->pcr &= ~0x400;
- pcicfgw16(pdev, PciPCR, pdev->pcr);
- }
-
- pcisetbme(pdev);
- pcisetpms(pdev, 0);
-
ctlr = malloc(sizeof(Ctlr));
if(ctlr == nil) {
print("iwl: unable to alloc Ctlr\n");
}
ctlr->nic = mem;
ctlr->pdev = pdev;
- ctlr->type = (csr32r(ctlr, Rev) >> 4) & 0xF;
-
- if(fwname[ctlr->type] == nil){
- print("iwl: unsupported controller type %d\n", ctlr->type);
- vunmap(mem, pdev->mem[0].size);
- free(ctlr);
- continue;
- }
if(iwlhead != nil)
iwltail->link = ctlr;
edev->irq = ctlr->pdev->intl;
edev->tbdf = ctlr->pdev->tbdf;
edev->arg = edev;
- edev->interrupt = iwlinterrupt;
edev->attach = iwlattach;
edev->ifstat = iwlifstat;
edev->ctl = iwlctl;
edev->multicast = iwlmulticast;
edev->mbps = 54;
+ pcienable(ctlr->pdev);
if(iwlinit(edev) < 0){
+ pcidisable(ctlr->pdev);
edev->ctlr = nil;
goto again;
}
+
+ pcisetbme(ctlr->pdev);
+ intrenable(edev->irq, iwlinterrupt, edev, edev->tbdf, edev->name);
return 0;
}