static void i82563interrupt(Ureg*, void* arg) { int icr, im, rdh, txdw = 0; Block *bp; Ctlr *ctlr; Ether *edev; Rdesc *rdesc; edev = arg; ctlr = edev->ctlr; ilock(&ctlr->imlock); csr32w(ctlr, Imc, ~0); im = ctlr->im; for(icr = csr32r(ctlr, Icr); icr & ctlr->im; icr = csr32r(ctlr, Icr)){ if(icr & (Rxseq|Lsc)){ /* should be more here */ } rdh = ctlr->rdh; for (;;) { rdesc = &ctlr->rdba[rdh]; if(!(rdesc->status & Rdd)) break; if ((rdesc->status & Reop) && rdesc->errors == 0) { bp = ctlr->rb[rdh]; if(0 && memcmp(bp->rp, broadcast, 6) != 0) print("#l%d: rx %d %E %E %d\n", edev->ctlrno, rdh, bp->rp, bp->rp+6, rdesc->length); ctlr->rb[rdh] = nil; bp->wp += rdesc->length; if (interesting(bp)) toringbuf(edev, bp); freeb(bp); } else if (rdesc->status & Reop && rdesc->errors) print("%s: input packet error %#ux\n", tname[ctlr->type], rdesc->errors); rdesc->status = 0; rdh = NEXT(rdh, Nrdesc); } ctlr->rdh = rdh; if(icr & Rxdmt0) i82563replenish(ctlr); if(icr & Txdw){ im &= ~Txdw; txdw++; } } ctlr->im = im; csr32w(ctlr, Ims, im); iunlock(&ctlr->imlock); if(txdw) i82563transmit(edev); }
static void vgberxeof(Ether* edev) { Ctlr* ctlr; int i; uint32_t length, status; Rd* rd; uint8_t *rb; ctlr = edev->ctlr; if(ctlr->debugflags & DumpRx) print("vgbe: rx_eof\n"); for(i = 0; i < RxCount; i++){ rd = &ctlr->rdring[i]; status = le32toh(rd->status); if(status & Own) continue; if(status & Rxok){ if(ctlr->debugflags & DumpRx) print("vgbe: Receive successful!\n"); length = status >> RDSizShift; length &= RDSizMask; if(ctlr->debugflags & DumpRx) print("vgbe: Rx-rd[%03d] status=%#08ulx ctl=%#08ulx len=%uld bytes\n", i, status, rd->control, length); rb = ctlr->rxbuf[i]; ctlr->stats.rx++; if(ctlr->debugflags & DumpRx){ print("&edev->rb[edev->ri] %ulx rb %ulx length %uld\n", &edev->rb[edev->ri], rb, length); for(i = 0; i < length; i++) print("%x ", rb[i]); print("\n"); } toringbuf(edev, rb, length); }else print("vgbe: Rx-rd[%#02x] *BAD FRAME* status=%#08ulx ctl=%#08ulx\n", i, status, rd->control); /* reset packet ... */ rd->status = htole32(Own); rd->control = htole32(0); }
static void igbeinterrupt(Ureg*, void* arg) { Block *bp; Ctlr *ctlr; Ether *edev; Rdesc *rdesc; int icr, im, rdh, txdw = 0; edev = arg; ctlr = edev->ctlr; ilock(&ctlr->imlock); csr32w(ctlr, Imc, ~0); im = ctlr->im; if((icr = csr32r(ctlr, Icr)) & ctlr->im){ /* * Link status changed. */ if(icr & (Rxseq|Lsc)){ /* * More here... */ } /* * Process any received packets. */ rdh = ctlr->rdh; for(;;){ rdesc = &ctlr->rdba[rdh]; if(!(rdesc->status & Rdd)) break; if ((rdesc->status & Reop) && rdesc->errors == 0) { bp = ctlr->rb[rdh]; ctlr->rb[rdh] = nil; /* * it appears that the original 82543 needed * to have the Ethernet CRC excluded, but that * the newer chips do not? */ bp->wp += rdesc->length /* -4 */; toringbuf(edev, bp); freeb(bp); } else if ((rdesc->status & Reop) && rdesc->errors) print("igbe: input packet error 0x%ux\n", rdesc->errors); rdesc->status = 0; rdh = NEXT(rdh, Nrdesc); } ctlr->rdh = rdh; if(icr & Rxdmt0) igbereplenish(ctlr); if(icr & Txdw){ im &= ~Txdw; txdw++; } } ctlr->im = im; csr32w(ctlr, Ims, im); iunlock(&ctlr->imlock); if(txdw) igbetransmit(edev); }