shithub: riscv

Download patch

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);
 
--