#include "io.h"
#include "../port/error.h"
#include "../port/netif.h"
-#include "etherif.h"
+#include "../port/etherif.h"
/*
* // comments note conflicts with 82563-style drivers,
Txdctl = 0x06028/4, /* " control */
Tdwbal = 0x06038/4, /* " write-back address low */
Tdwbah = 0x0603c/4,
-
+ Dmatxctl = 0x04a80/4,
+
Dtxctl = 0x07e00/4, /* tx dma control */
Tdcatxctrl = 0x07200/4, /* tx dca register (0-15) */
Tipg = 0x0cb00/4, /* tx inter-packet gap */
Wthresh = 16, /* writeback threshold */
Renable = 1<<25,
+ /* Dmatxctl */
+ Txen = 1<<0,
+
/* Rxctl */
Rxen = 1<<0,
Dmbyps = 1<<1,
typedef struct {
Pcidev *p;
Ether *edev;
+ uintptr io;
u32int *reg;
u32int *regmsi;
uchar flag;
Block **tb;
uchar ra[Eaddrlen];
- uchar mta[128];
+ u32int mta[128];
ulong stats[nelem(stattab)];
uint speeds[3];
} Ctlr;
/* tweakable paramaters */
enum {
- Rbsz = 12*1024,
+ Mtu = 12*1024,
Nrd = 256,
Ntd = 256,
Nrb = 256,
e = v;
c = e->ctlr;
+ while(waserror())
+ ;
for (;;) {
r = c->reg[Links];
e->link = (r & Lnkup) != 0;
e = v;
c = e->ctlr;
+ while(waserror())
+ ;
for (;;) {
sleep(&c->trendez, tim, c); /* transmit kicks us */
c->tim = 0;
c->reg[Fctrl] |= Bam;
c->reg[Rxcsum] |= Ipcs;
- c->reg[Srrctl] = (c->rbsz + 1023)/1024;
+ c->reg[Srrctl] = c->rbsz / 1024;
c->reg[Mhadd] = c->rbsz << 16;
c->reg[Hlreg0] |= Jumboen;
c = e->ctlr;
m = c->nrd - 1;
rdh = 0;
+ while(waserror())
+ ;
loop:
replenish(c, rdh);
im(c, Irx0);
b = c->rb[rdh];
c->rb[rdh] = 0;
b->wp += r->length;
- b->lim = b->wp; /* lie like a dog */
if(!(r->status & Ixsm)){
if(r->status & Ipcs)
b->flag |= Bipck;
b->checksum = r->cksum;
}
// r->status = 0;
- etheriq(e, b, 1);
+ etheriq(e, b);
c->rdfree--;
rdh = Next(rdh, m);
goto loop1; /* UGH */
reset(Ctlr *c)
{
int i;
- uchar *p;
if(detach(c)){
print("82598: reset timeout\n");
}
if(eeload(c)){
print("82598: eeprom failure\n");
- return -1;
+ memset(c->ra, 0, Eaddrlen);
}
- p = c->ra;
- c->reg[Ral] = p[3]<<24 | p[2]<<16 | p[1]<<8 | p[0];
- c->reg[Rah] = p[5]<<8 | p[4] | 1<<31;
readstats(c);
for(i = 0; i<nelem(c->stats); i++)
c->tdh = c->ntd - 1;
c->tdt = 0;
c->reg[Txdctl] |= Ten;
+
+ c->reg[Dmatxctl] |= Txen;
}
static void
static void
scan(void)
{
- ulong io, iomsi;
+ uintptr io, iomsi;
void *mem, *memmsi;
int pciregs, pcimsix;
Ctlr *c;
pcimsix = 3;
break;
case 0x10fb: /* 82599 */
+ case 0x1528: /* T540-T1 */
pcimsix = 4;
break;
+
default:
continue;
}
io = p->mem[pciregs].bar & ~0xf;
mem = vmap(io, p->mem[pciregs].size);
if(mem == nil){
- print("i82598: can't map regs %#p\n", p->mem[pciregs].bar);
+ print("i82598: can't map regs %#p\n", io);
free(c);
continue;
}
iomsi = p->mem[pcimsix].bar & ~0xf;
memmsi = vmap(iomsi, p->mem[pcimsix].size);
if(memmsi == nil){
- print("i82598: can't map msi-x regs %#p\n", p->mem[pcimsix].bar);
+ print("i82598: can't map msi-x regs %#p\n", iomsi);
vunmap(mem, p->mem[pciregs].size);
free(c);
continue;
}
+ pcienable(p);
c->p = p;
+ c->io = io;
c->reg = (u32int*)mem;
c->regmsi = (u32int*)memmsi;
- c->rbsz = Rbsz;
+ c->rbsz = ROUND(Mtu, 1024);
if(reset(c)){
print("i82598: can't reset\n");
free(c);
static int
pnp(Ether *e)
{
+ static uchar zeros[Eaddrlen];
int i;
Ctlr *c = nil;
+ uchar *p;
if(nctlr == 0)
scan();
c = ctlrtab[i];
if(c == nil || c->flag & Factive)
continue;
- if(e->port == 0 || e->port == (ulong)c->reg)
+ if(e->port == 0 || e->port == c->io)
break;
}
if (i >= nctlr)
return -1;
+
+ if(memcmp(c->ra, zeros, Eaddrlen) != 0)
+ memmove(e->ea, c->ra, Eaddrlen);
+
+ p = e->ea;
+ c->reg[Ral] = p[3]<<24 | p[2]<<16 | p[1]<<8 | p[0];
+ c->reg[Rah] = p[5]<<8 | p[4] | 1<<31;
+
c->flag |= Factive;
e->ctlr = c;
e->port = (uintptr)c->reg;
e->irq = c->p->intl;
e->tbdf = c->p->tbdf;
e->mbps = 10000;
- e->maxmtu = c->rbsz;
- memmove(e->ea, c->ra, Eaddrlen);
+ e->maxmtu = Mtu;
+
e->arg = e;
e->attach = attach;
e->ctl = ctl;
e->ifstat = ifstat;
- e->interrupt = interrupt;
e->multicast = multicast;
e->promiscuous = promiscuous;
e->shutdown = shutdown;
e->transmit = transmit;
+ intrenable(e->irq, interrupt, e, e->tbdf, e->name);
+
return 0;
}