]> git.lizzy.rs Git - plan9front.git/blobdiff - sys/src/9/pc/etheriwl.c
kernel: cleanup the software mouse cursor mess
[plan9front.git] / sys / src / 9 / pc / etheriwl.c
index a2e1c70468cadbe17365cbae9085308ef847922f..22e92884bbda48457c733c1a8d220d2e8f11e325 100644 (file)
 #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,
 
@@ -401,6 +404,7 @@ enum {
        Type6050        = 8,
        Type6005        = 11,   /* also Centrino Advanced-N 6030, 6235 */
        Type2030        = 12,
+       Type2000        = 16,
 };
 
 static char *fwname[32] = {
@@ -414,6 +418,7 @@ static char *fwname[32] = {
        [Type6050] "iwn-6050",
        [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);
@@ -818,6 +823,23 @@ iwlinit(Ether *edev)
        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)
@@ -863,7 +885,7 @@ iwlinit(Ether *edev)
 
        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);
@@ -1183,7 +1205,7 @@ reset(Ctlr *ctlr)
                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);
 
@@ -1435,10 +1457,11 @@ postboot(Ctlr *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)
@@ -1466,6 +1489,7 @@ postboot(Ctlr *ctlr)
                                break;
 
                        case Type2030:
+                       case Type2000:
                                memset(c, 0, sizeof(c));
                                c[0] = 18;
                                c[1] = 0;
@@ -1666,7 +1690,7 @@ static int
 txqready(void *arg)
 {
        TXQ *q = arg;
-       return q->n < Ntx;
+       return q->n < Ntxqmax;
 }
 
 static char*
@@ -1680,11 +1704,11 @@ qcmd(Ctlr *ctlr, uint qid, uint code, uchar *data, int size, Block *block)
 
        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);
@@ -1929,6 +1953,7 @@ static struct ratetab {
        {   4,  20, RFlagCCK },
        {  11,  55, RFlagCCK },
        {  22, 110, RFlagCCK },
+
        {  12, 0xd, 0 },
        {  18, 0xf, 0 },
        {  24, 0x5, 0 },
@@ -1945,6 +1970,7 @@ static uchar iwlrates[] = {
        0x80 | 4,
        0x80 | 11,
        0x80 | 22,
+
        0x80 | 12,
        0x80 | 18,
        0x80 | 24,
@@ -2026,12 +2052,12 @@ transmit(Wifi *wifi, Wnode *wn, Block *b)
                                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);
@@ -2192,6 +2218,8 @@ iwlattach(Ether *edev)
                        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)
@@ -2437,8 +2465,10 @@ iwlpci(void)
                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 */
@@ -2447,6 +2477,8 @@ iwlpci(void)
                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 */
@@ -2456,19 +2488,6 @@ iwlpci(void)
                        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");
@@ -2483,14 +2502,6 @@ iwlpci(void)
                }
                ctlr->nic = mem;
                ctlr->pdev = pdev;
-               ctlr->type = (csr32r(ctlr, Rev) >> 4) & 0x1F;
-
-               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;
@@ -2525,7 +2536,6 @@ again:
        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;
@@ -2534,10 +2544,15 @@ again:
        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;
 }