ethervgbe: implement proper speed and link detection

This commit is contained in:
Arne 2025-01-11 22:04:11 +00:00
parent 0336b2fad3
commit 8c86e440c2

View file

@ -335,6 +335,8 @@ struct Ctlr
uchar maddrs[32][Eaddrlen]; uchar maddrs[32][Eaddrlen];
uint camidx; uint camidx;
Bpool pool;
RxDesc* rx_ring; RxDesc* rx_ring;
Block* rx_blocks[RxCount]; Block* rx_blocks[RxCount];
@ -531,7 +533,7 @@ vgbenewrx(Ctlr* ctlr, int i)
Block* block; Block* block;
RxDesc* desc; RxDesc* desc;
block = iallocb(RxSize); block = iallocbp(&ctlr->pool);
if(block == nil) if(block == nil)
return -1; return -1;
@ -659,6 +661,25 @@ vgbetxeof(Ether* edev)
wiob(ctlr, TxCsrS, TxCsr_Wakeup); wiob(ctlr, TxCsrS, TxCsr_Wakeup);
} }
static void
vgbelink(Ether *edev)
{
Ctlr *ctlr;
uchar status;
ctlr = edev->ctlr;
status = riob(ctlr, PhySts0);
if(status & PhySts_Speed1000)
ethersetspeed(edev, 1000);
else if(status & PhySts_Speed10)
ethersetspeed(edev, 10);
else
ethersetspeed(edev, 100);
ethersetlink(edev, status & PhySts_Link);
}
static void static void
vgbeinterrupt(Ureg *, void* arg) vgbeinterrupt(Ureg *, void* arg)
{ {
@ -713,7 +734,7 @@ vgbeinterrupt(Ureg *, void* arg)
print("vgbe: irq: PHY interrupt\n"); print("vgbe: irq: PHY interrupt\n");
if(status & Isr_LinkStatus){ if(status & Isr_LinkStatus){
ethersetlink(edev, riob(ctlr, PhySts0) & PhySts_Link); vgbelink(edev);
vgbemiip(ctlr, 1); vgbemiip(ctlr, 1);
} }
if(status & Isr_RxNoDesc) if(status & Isr_RxNoDesc)
@ -835,6 +856,9 @@ vgbeattach(Ether* edev)
ctlr->rx_ring = rxdesc; ctlr->rx_ring = rxdesc;
ctlr->tx_ring = txdesc; ctlr->tx_ring = txdesc;
ctlr->pool.size = RxSize;
growbp(&ctlr->pool, RxCount*4);
/* Allocate Rx blocks, initialize Rx ring. */ /* Allocate Rx blocks, initialize Rx ring. */
for(i = 0; i < RxCount; i++) for(i = 0; i < RxCount; i++)
vgbenewrx(ctlr, i); vgbenewrx(ctlr, i);
@ -1258,8 +1282,6 @@ vgbepnp(Ether* edev)
edev->port = ctlr->port; edev->port = ctlr->port;
edev->irq = ctlr->pdev->intl; edev->irq = ctlr->pdev->intl;
edev->tbdf = ctlr->pdev->tbdf; edev->tbdf = ctlr->pdev->tbdf;
edev->mbps = 1000;
edev->link = (riob(ctlr, PhySts0) & PhySts_Link) ? 1 : 0;
memmove(edev->ea, ctlr->ea, Eaddrlen); memmove(edev->ea, ctlr->ea, Eaddrlen);
edev->attach = vgbeattach; edev->attach = vgbeattach;
edev->transmit = vgbetransmit; edev->transmit = vgbetransmit;
@ -1270,6 +1292,8 @@ vgbepnp(Ether* edev)
edev->ctl = vgbectl; edev->ctl = vgbectl;
edev->arg = edev; edev->arg = edev;
vgbelink(edev);
intrenable(edev->irq, vgbeinterrupt, edev, edev->tbdf, edev->name); intrenable(edev->irq, vgbeinterrupt, edev, edev->tbdf, edev->name);
return 0; return 0;