#include "dat.h"
#include "fns.h"
#include "io.h"
+#include "../port/pci.h"
#include "../port/error.h"
#include "../port/netif.h"
-
-#include "etherif.h"
+#include "../port/etherif.h"
/*
* note: the 82575, 82576 and 82580 are operated using registers aliased
F79phy = 1<<5,
Fnofct = 1<<6,
Fbadcsum= 1<<7,
+ Fnofca = 1<<8,
};
typedef struct Ctlrtype Ctlrtype;
[i82567m] "i82567m", 1514, Fload,
[i82571] "i82571", 9234, Fpba,
[i82572] "i82572", 9234, Fpba,
-[i82573] "i82573", 8192, Fert, /* terrible perf above 8k */
+[i82573] "i82573", 8192, Fert|Fbadcsum, /* terrible perf above 8k */
[i82574] "i82574", 9018, 0,
[i82575] "i82575", 9728, F75|Fflashea,
[i82576] "i82576", 9728, F75,
[i82580] "i82580", 9728, F75|F79phy,
[i82583] "i82583", 1514, 0,
[i210] "i210", 9728, F75|Fnofct|Fert,
-[i217] "i217", 9728, Fload|Fnofct|Fert|Fbadcsum,
-[i218] "i218", 9728, Fload|Fert|F79phy|Fnofct|Fbadcsum,
-[i219] "i219", 9728, Fload|Fert|F79phy|Fnofct|Fbadcsum,
+[i217] "i217", 2048, Fload|Fert|F79phy|Fnofct|Fnofca|Fbadcsum,/* 9018, but unstable above 2k */
+[i218] "i218", 9018, Fload|Fert|F79phy|Fnofct|Fnofca|Fbadcsum,
+[i219] "i219", 9018, Fload|Fert|F79phy|Fnofct|Fnofca|Fbadcsum,
[i350] "i350", 9728, F75|F79phy|Fnofct,
};
typedef struct Ctlr Ctlr;
struct Ctlr {
- ulong port;
+ uvlong port;
Pcidev *pcidev;
Ctlr *next;
int active;
void *alloc; /* receive/transmit descriptors */
int nrd;
int ntd;
- uint rbsz;
+ int rbsz;
u32int *nic;
Lock imlock;
case i82577:
case i82577m:
case i82579:
- case i210:
case i217:
case i218:
case i219:
csr32w(ctlr, Rctl, Dpf|Bsize2048|Bam|RdtmsHALF);
else{
i = ctlr->rbsz / 1024;
- if(ctlr->rbsz % 1024)
- i++;
if(cttab[ctlr->type].flag & F75){
csr32w(ctlr, Rctl, Lpe|Dpf|Bsize2048|Bam|RdtmsHALF|Secrc);
if(ctlr->type != i82575)
bp->checksum = rd->checksum;
bp->flag |= Bpktck;
}
- etheriq(edev, bp, 1);
+ etheriq(edev, bp);
} else
freeb(bp);
ctlr->rb[rdh] = nil;
microdelay(1);
}
if((phy & (MDIe|MDIready)) != MDIready){
- print("%s: phy %d wedged %.8ux\n", cttab[c->type].name, phyno, phy);
+ print("%s: phy %d wedged %.8ux\n", cname(c), phyno, phy);
return ~0;
}
return phy & 0xffff;
static void
phyl79proc(void *v)
{
- uint a, i, r, phy, phyno;
+ uint i, r, phy, phyno;
Ctlr *c;
Ether *e;
lsleep(c, Lsc);
for(;;){
- phy = phyread(c, phyno, Phystat);
- if(phy == ~0){
- phy = 0;
- i = 3;
- goto next;
+ phy = 0;
+ for(i=0; i<4; i++){
+ tsleep(&up->sleep, return0, 0, 150);
+ phy = phyread(c, phyno, Phystat);
+ if(phy == ~0)
+ continue;
+ if(phy & Ans){
+ r = phyread(c, phyno, Phyctl);
+ if(r == ~0)
+ continue;
+ phywrite(c, phyno, Phyctl, r | Ran | Ean);
+ }
+ break;
}
i = (phy>>8) & 3;
- a = phy & Ans;
- if(a){
- r = phyread(c, phyno, Phyctl);
- phywrite(c, phyno, Phyctl, r | Ran | Ean);
- }
-next:
e->link = i != 3 && (phy & Link) != 0;
if(e->link == 0)
i = 3;
if(c->pcidev->mem[1].bar == 0)
return fload32(c); /* i219 */
- va = vmap(c->pcidev->mem[1].bar & ~0x0f, c->pcidev->mem[1].size);
+ if(c->pcidev->mem[1].bar & 1)
+ return -1;
+
+ va = vmap(c->pcidev->mem[1].bar & ~0xF, c->pcidev->mem[1].size);
if(va == nil)
return -1;
f.reg = va;
memset(ctlr->mta, 0, sizeof(ctlr->mta));
for(i = 0; i < 128; i++)
csr32w(ctlr, Mta + i*4, 0);
- csr32w(ctlr, Fcal, 0x00C28001);
- csr32w(ctlr, Fcah, 0x0100);
+ if((flag & Fnofca) == 0){
+ csr32w(ctlr, Fcal, 0x00C28001);
+ csr32w(ctlr, Fcah, 0x0100);
+ }
if((flag & Fnofct) == 0)
csr32w(ctlr, Fct, 0x8808);
csr32w(ctlr, Fcttv, 0x0100);
case 0x1570: /* i219-v */
case 0x15b8: /* i219-v */
case 0x15b9: /* i219-lm */
+ case 0x15bb: /* i219-lm */
+ case 0x15bd: /* i219-lm */
case 0x15d6: /* i219-v */
case 0x15d7: /* i219-lm */
case 0x15d8: /* i219-v */
case 0x15e3: /* i219-lm */
+ case 0x0d4c: /* i219-lm */
return i219;
case 0x151f: /* i350 “powerville” eeprom-less */
case 0x1521: /* i350 copper */
for(p = nil; p = pcimatch(p, 0x8086, 0);){
hbafixup(p);
+ if(p->mem[0].bar & 1)
+ continue;
if((type = didtype(p->did)) == -1)
continue;
ctlr = malloc(sizeof(Ctlr));
}
ctlr->type = type;
ctlr->pcidev = p;
- ctlr->rbsz = cttab[type].mtu;
- ctlr->port = p->mem[0].bar & ~0x0F;
+ ctlr->rbsz = ROUND(cttab[type].mtu, 1024);
+ ctlr->port = p->mem[0].bar & ~0xF;
if(i82563ctlrhead != nil)
i82563ctlrtail->next = ctlr;
else
p = ctlr->pcidev;
ctlr->nic = vmap(ctlr->port, p->mem[0].size);
if(ctlr->nic == nil){
- print("%s: can't map 0x%lux\n", cname(ctlr), ctlr->port);
+ print("%s: can't map %llux\n", cname(ctlr), ctlr->port);
return -1;
}
+ pcienable(p);
if(i82563reset(ctlr)){
+ pcidisable(p);
vunmap(ctlr->nic, p->mem[0].size);
return -1;
}
- pcisetbme(ctlr->pcidev);
+ pcisetbme(p);
return 0;
}
edev->irq = ctlr->pcidev->intl;
edev->tbdf = ctlr->pcidev->tbdf;
edev->mbps = 1000;
- edev->maxmtu = ctlr->rbsz;
+ edev->maxmtu = cttab[ctlr->type].mtu;
memmove(edev->ea, ctlr->ra, Eaddrlen);
/*
*/
edev->attach = i82563attach;
// edev->transmit = i82563transmit;
- edev->interrupt = i82563interrupt;
edev->ifstat = i82563ifstat;
edev->ctl = i82563ctl;
edev->shutdown = i82563shutdown;
edev->multicast = i82563multicast;
+ intrenable(edev->irq, i82563interrupt, edev, edev->tbdf, edev->name);
+
return 0;
}