From 8c86e440c2f7ffb5fef72ee76009d36e64ad388a Mon Sep 17 00:00:00 2001 From: Arne Date: Sat, 11 Jan 2025 22:04:11 +0000 Subject: [PATCH] ethervgbe: implement proper speed and link detection --- sys/src/9/pc/ethervgbe.c | 32 ++++++++++++++++++++++++++++---- 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/sys/src/9/pc/ethervgbe.c b/sys/src/9/pc/ethervgbe.c index a25e417bd..03c61b613 100644 --- a/sys/src/9/pc/ethervgbe.c +++ b/sys/src/9/pc/ethervgbe.c @@ -335,6 +335,8 @@ struct Ctlr uchar maddrs[32][Eaddrlen]; uint camidx; + Bpool pool; + RxDesc* rx_ring; Block* rx_blocks[RxCount]; @@ -531,7 +533,7 @@ vgbenewrx(Ctlr* ctlr, int i) Block* block; RxDesc* desc; - block = iallocb(RxSize); + block = iallocbp(&ctlr->pool); if(block == nil) return -1; @@ -659,6 +661,25 @@ vgbetxeof(Ether* edev) 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 vgbeinterrupt(Ureg *, void* arg) { @@ -713,7 +734,7 @@ vgbeinterrupt(Ureg *, void* arg) print("vgbe: irq: PHY interrupt\n"); if(status & Isr_LinkStatus){ - ethersetlink(edev, riob(ctlr, PhySts0) & PhySts_Link); + vgbelink(edev); vgbemiip(ctlr, 1); } if(status & Isr_RxNoDesc) @@ -835,6 +856,9 @@ vgbeattach(Ether* edev) ctlr->rx_ring = rxdesc; ctlr->tx_ring = txdesc; + ctlr->pool.size = RxSize; + growbp(&ctlr->pool, RxCount*4); + /* Allocate Rx blocks, initialize Rx ring. */ for(i = 0; i < RxCount; i++) vgbenewrx(ctlr, i); @@ -1258,8 +1282,6 @@ vgbepnp(Ether* edev) edev->port = ctlr->port; edev->irq = ctlr->pdev->intl; edev->tbdf = ctlr->pdev->tbdf; - edev->mbps = 1000; - edev->link = (riob(ctlr, PhySts0) & PhySts_Link) ? 1 : 0; memmove(edev->ea, ctlr->ea, Eaddrlen); edev->attach = vgbeattach; edev->transmit = vgbetransmit; @@ -1270,6 +1292,8 @@ vgbepnp(Ether* edev) edev->ctl = vgbectl; edev->arg = edev; + vgbelink(edev); + intrenable(edev->irq, vgbeinterrupt, edev, edev->tbdf, edev->name); return 0;