ref: 8c86e440c2f7ffb5fef72ee76009d36e64ad388a
parent: 0336b2fad3affc680ab91f2b7d18a6e78ca8dcbe
author: Arne <cgnarne@netcologne.de>
date: Sat Jan 11 17:04:11 EST 2025
ethervgbe: implement proper speed and link detection
--- a/sys/src/9/pc/ethervgbe.c
+++ b/sys/src/9/pc/ethervgbe.c
@@ -335,6 +335,8 @@
uchar maddrs[32][Eaddrlen];
uint camidx;
+ Bpool pool;
+
RxDesc* rx_ring;
Block* rx_blocks[RxCount];
@@ -531,7 +533,7 @@
Block* block;
RxDesc* desc;
- block = iallocb(RxSize);
+ block = iallocbp(&ctlr->pool);
if(block == nil)
return -1;
@@ -660,6 +662,25 @@
}
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)
{
Ether* edev;
@@ -713,7 +734,7 @@
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 @@
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 @@
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;
@@ -1269,6 +1291,8 @@
edev->ifstat = vgbeifstat;
edev->ctl = vgbectl;
edev->arg = edev;
+
+ vgbelink(edev);
intrenable(edev->irq, vgbeinterrupt, edev, edev->tbdf, edev->name);
--
⑨