]> git.lizzy.rs Git - plan9front.git/blobdiff - sys/src/9/pc/ether8169.c
pc/ether*: use 64-bit physical addresses and check pci membar types and sizes
[plan9front.git] / sys / src / 9 / pc / ether8169.c
index cf9ebdf089dbb9ffab7c4b399ff613ab7e6a41b1..bf6cf8ef48f5f90a37fa33f150a810653c6658b3 100644 (file)
@@ -15,9 +15,8 @@
 #include "io.h"
 #include "../port/error.h"
 #include "../port/netif.h"
-
-#include "etherif.h"
-#include "ethermii.h"
+#include "../port/etherif.h"
+#include "../port/ethermii.h"
 
 enum {                                 /* registers */
        Idr0            = 0x00,         /* MAC address */
@@ -120,6 +119,12 @@ enum {                                     /* Tcr */
        Macv28          = 0x2c000000,   /* RTL8111/8168B */
        Macv29          = 0x40800000,   /* RTL8101/8102E */
        Macv30          = 0x24000000,   /* RTL8101E? (untested) */
+       Macv39          = 0x44800000,   /* RTL8106E */
+       Macv40          = 0x4c000000,   /* RTL8168G */
+       Macv42          = 0x50800000,   /* RTL8168GU */
+       Macv44          = 0x5c800000,   /* RTL8411B */
+       Macv45          = 0x54000000,   /* RTL8111HN */
+
        Ifg0            = 0x01000000,   /* Interframe Gap 0 */
        Ifg1            = 0x02000000,   /* Interframe Gap 1 */
 };
@@ -178,6 +183,7 @@ enum {                                      /* Cplusc */
        Dac             = 0x0010,       /* PCI Dual Address Cycle Enable */
        Rxchksum        = 0x0020,       /* Receive Checksum Offload Enable */
        Rxvlan          = 0x0040,       /* Receive VLAN De-tagging Enable */
+       Macstatdis      = 0x0080,       /* Disable Mac Statistics */
        Endian          = 0x0200,       /* Endian Mode */
 };
 
@@ -585,7 +591,7 @@ rtl8169ifstat(Ether* edev, void* a, long n, ulong offset)
        l += snprint(p+l, READSTR-l, "multicast: %ud\n", ctlr->mcast);
 
        if(ctlr->mii != nil && ctlr->mii->curphy != nil){
-               l += snprint(p+l, READSTR, "phy:   ");
+               l += snprint(p+l, READSTR-l, "phy:   ");
                for(i = 0; i < NMiiPhyr; i++){
                        if(i && ((i & 0x07) == 0))
                                l += snprint(p+l, READSTR-l, "\n       ");
@@ -668,7 +674,7 @@ rtl8169init(Ether* edev)
        u32int r;
        Block *bp;
        Ctlr *ctlr;
-       u8int cplusc;
+       u16int cplusc;
 
        ctlr = edev->ctlr;
        ilock(ctlr);
@@ -697,7 +703,16 @@ rtl8169init(Ether* edev)
 
        cplusc = csr16r(ctlr, Cplusc);
        cplusc &= ~(Endian|Rxchksum);
-       cplusc |= Txenb|Rxenb|Mulrw;
+       cplusc |= Txenb|Mulrw;
+       switch(ctlr->macv){
+       case Macv40:
+       case Macv44:
+               cplusc |= Macstatdis;
+               break;
+       default:
+               cplusc |= Rxenb;
+               break;
+       }
        csr16w(ctlr, Cplusc, cplusc);
 
        csr32w(ctlr, Tnpds+4, 0);
@@ -709,7 +724,15 @@ rtl8169init(Ether* edev)
 
        csr32w(ctlr, Tcr, Ifg1|Ifg0|Mtxdmaunlimited);
        ctlr->tcr = csr32r(ctlr, Tcr);
-       ctlr->rcr = Rxfthnone|Mrxdmaunlimited|Ab|Am|Apm;
+       switch(ctlr->macv){
+       case Macv42:
+       case Macv45:
+               ctlr->rcr = Rxfth256|Mrxdmaunlimited|Ab|Am|Apm;
+               break;
+       default:
+               ctlr->rcr = Rxfthnone|Mrxdmaunlimited|Ab|Am|Apm;
+               break;
+       }
        ctlr->mchash = 0;
        csr32w(ctlr, Mar0,   0);
        csr32w(ctlr, Mar0+4, 0);
@@ -816,15 +839,12 @@ rtl8169link(Ether* edev)
 
        ctlr = edev->ctlr;
 
+       r = csr8r(ctlr, Phystatus);
        /*
         * Maybe the link changed - do we care very much?
         * Could stall transmits if no link, maybe?
         */
-       if(!((r = csr8r(ctlr, Phystatus)) & Linksts)){
-               edev->link = 0;
-               return;
-       }
-       edev->link = 1;
+       edev->link = (r & Linksts) != 0;
 
        limit = 256*1024;
        if(r & Speed10){
@@ -906,8 +926,10 @@ rtl8169receive(Ether* edev)
        int x;
 
        ctlr = edev->ctlr;
-       x = ctlr->rdh;
-       for(;;){
+       if(ctlr->nrq < ctlr->nrd/2)
+               rtl8169replenish(ctlr);
+
+       for(x = ctlr->rdh; x != ctlr->rdt;){
                d = &ctlr->rd[x];
                if((control = d->control) & Own)
                        break;
@@ -955,7 +977,7 @@ rtl8169receive(Ether* edev)
                                bp->flag |= Bipck;
                                break;
                        }
-                       etheriq(edev, bp, 1);
+                       etheriq(edev, bp);
                }else{
                        if(!(control & Res))
                                ctlr->frag++;
@@ -1040,6 +1062,11 @@ vetmacv(Ctlr *ctlr, uint *macv)
        case Macv28:
        case Macv29:
        case Macv30:
+       case Macv39:
+       case Macv40:
+       case Macv42:
+       case Macv44:
+       case Macv45:
                break;
        }
        return 0;
@@ -1091,25 +1118,17 @@ rtl8169pci(void)
                ctlr->pciv = i;
                ctlr->pcie = pcie;
 
+               pcienable(p);
                if(vetmacv(ctlr, &macv) == -1){
+                       pcidisable(p);
                        iofree(port);
                        free(ctlr);
                        print("rtl8169: unknown mac %.4ux %.8ux\n", p->did, macv);
                        continue;
                }
 
-               if(pcigetpms(p) > 0){
-                       pcisetpms(p, 0);
-
-                       for(i = 0; i < 6; i++)
-                               pcicfgw32(p, PciBAR0+i*4, p->mem[i].bar);
-                       pcicfgw8(p, PciINTL, p->intl);
-                       pcicfgw8(p, PciLTR, p->ltr);
-                       pcicfgw8(p, PciCLS, p->cls);
-                       pcicfgw16(p, PciPCR, p->pcr);
-               }
-
                if(rtl8169reset(ctlr)){
+                       pcidisable(p);
                        iofree(port);
                        free(ctlr);
                        print("rtl8169: reset failed\n");
@@ -1187,7 +1206,6 @@ rtl8169pnp(Ether* edev)
 
        edev->attach = rtl8169attach;
        edev->transmit = rtl8169transmit;
-       edev->interrupt = rtl8169interrupt;
        edev->ifstat = rtl8169ifstat;
 
        edev->arg = edev;
@@ -1196,6 +1214,8 @@ rtl8169pnp(Ether* edev)
 
        rtl8169link(edev);
 
+       intrenable(edev->irq, rtl8169interrupt, edev, edev->tbdf, edev->name);
+
        return 0;
 }