9front - general discussion about 9front
 help / color / mirror / Atom feed
From: Arne Meyer <meyer.arne83@gmail.com>
To: 9front@9front.org
Subject: [9front] [patch] ethervgbe fixes
Date: Sat, 21 May 2022 15:46:54 +0000	[thread overview]
Message-ID: <CACr+GXYvYMSEKzDeRxYy-gZDC4z3ZufPn6hg4eNj+J39Vg_2EQ@mail.gmail.com> (raw)

[-- Attachment #1: Type: text/plain, Size: 174 bytes --]

Hello,

this patch fixes a few issues i've had with ethervgbe.

fixes to the multicast filter make ipv6 work.
link discovery works and gbit autonegotiation.

Greetings,
Arne

[-- Attachment #2: vgbe.patch --]
[-- Type: application/octet-stream, Size: 6030 bytes --]

diff --git a/sys/src/9/pc/ethervgbe.c b/sys/src/9/pc/ethervgbe.c
index eaf0a33b5..047d64f63 100644
--- a/sys/src/9/pc/ethervgbe.c
+++ b/sys/src/9/pc/ethervgbe.c
@@ -90,11 +90,32 @@ enum
 
 	MiiAddr		= 0x71,			/* MII address */
 	MiiData		= 0x72,			/* MII data */
+	PhySts0		= 0x6e,			/* Phy Status */
+		PhySts_TxF			= 0x01,
+		PhySts_RxF			= 0x02,
+		PhySts_Speed10		= 0x04,
+		PhySts_Speed1000	= 0x08,
+		PhySts_Fd			= 0x10,
+		PhySts_Link			= 0x40,
+		PhySts_RestSts		= 0x80,
 
 	/* 64 bits related registers. */
 	TxDescHi	= 0x18,
 	DataBufHi	= 0x1d,
 
+	/* CAM Registers */
+	Cam0 		= 0x10,
+	CamAddr		= 0x68,
+		CamAddr_Enable	= 0x80,
+	CamCtl		= 0x69,
+		CamCtl_PageSel	= 0xc0,
+		CamCtl_Write	= 0x04,
+		CamCtl_Read		= 0x08,
+	CamPageSel	= 0x69,			/* Alias of CamCtl for better readability */
+		CamPageSel_Mar		= 0x00,
+		CamPageSel_CamMask	= 0x40,
+		CamPageSel_CamData	= 0x80,
+
 	/* Rx engine registers. */
 	RxDescLo	= 0x38,			/* Rx descriptor base address (lo 32 bits) */
 	RxCsrS		= 0x32,			/* Rx descriptor queue control/status (Set) */
@@ -311,6 +332,9 @@ struct Ctlr
 	int	active;
 	uchar	ea[6];
 
+	uchar maddrs[32][Eaddrlen];
+	uint camidx;
+
 	RxDesc*	rx_ring;
 	Block*	rx_blocks[RxCount];
 
@@ -339,6 +363,33 @@ static Ctlr* vgbetail;
 #define ciow(c, r, b)	wiow(c, r, riob(c, r) & ~b)
 #define ciol(c, r, b)	wiol(c, r, riob(c, r) & ~b)
 
+
+static void
+vgbemiip(Ctlr* ctlr, int on)
+{
+	int i;
+
+	wiob(ctlr, MiiCmd, 0);
+	wiob(ctlr, MiiAddr, 0x80);
+
+	for(i = 0; i < 10000; i++){
+		if(riob(ctlr, MiiStatus) & MiiStatus_idle)
+			break;
+		microdelay(1);
+	}
+
+	if(on == 0)
+		return;
+
+	wiob(ctlr, MiiCmd, MiiCmd_auto);
+
+	for(i = 0; i < 10000; i++){
+                if(riob(ctlr, MiiStatus) & MiiStatus_idle)
+                        break;
+                microdelay(1);
+        }
+}
+
 static int
 vgbemiiw(Mii* mii, int phy, int addr, int data)
 {
@@ -350,6 +401,8 @@ vgbemiiw(Mii* mii, int phy, int addr, int data)
 
 	ctlr = mii->ctlr;
 
+	vgbemiip(ctlr, 0);
+
 	wiob(ctlr, MiiAddr, addr);
 	wiow(ctlr, MiiData, (ushort) data);
 	wiob(ctlr, MiiCmd, MiiCmd_write);
@@ -363,6 +416,8 @@ vgbemiiw(Mii* mii, int phy, int addr, int data)
 		return -1;
 	}
 
+	vgbemiip(ctlr, 1);
+
 	return 0;
 }
 
@@ -371,12 +426,15 @@ vgbemiir(Mii* mii, int phy, int addr)
 {
 	Ctlr* ctlr;
 	int i;
+	u16int r;
 
 	if(phy != 1)
 		return -1;
 
 	ctlr = mii->ctlr;
 
+	vgbemiip(ctlr, 0);
+
 	wiob(ctlr, MiiAddr, addr);
 	wiob(ctlr, MiiCmd, MiiCmd_read);
 
@@ -389,7 +447,11 @@ vgbemiir(Mii* mii, int phy, int addr)
 		return -1;
 	}
 
-	return riow(ctlr, MiiData);
+	r = riow(ctlr, MiiData);
+
+	vgbemiip(ctlr, 1);
+
+	return r;
 }
 
 static long
@@ -652,9 +714,11 @@ vgbeinterrupt(Ureg *, void* arg)
 	if(status & Isr_PhyIntr)
 		print("vgbe: irq: PHY interrupt\n");
 
-	if(status & Isr_LinkStatus)
+	if(status & Isr_LinkStatus){
+		edev->link = (riob(ctlr, PhySts0) & PhySts_Link) ? 1 : 0;
+		vgbemiip(ctlr, 1);
 		print("vgbe: irq: link status change\n");
-
+	}
 	if(status & Isr_RxNoDesc)
 		print("vgbe: irq: ran out of Rx descriptors\n");
 
@@ -778,9 +842,21 @@ vgbeattach(Ether* edev)
 	for(i = 0; i < RxCount; i++)
 		vgbenewrx(ctlr, i);
 
+
+	/* Clear CAM Filter */
+	ciob(ctlr, CamCtl, CamCtl_PageSel);
+	siob(ctlr, CamPageSel, CamPageSel_CamMask);
+	wiob(ctlr, CamAddr, CamAddr_Enable);
+	for(i = 0; i < 8; i++)
+		wiob(ctlr, Cam0+i, 0);
+
+	wiob(ctlr, CamAddr, 0);
+	ciob(ctlr, CamCtl, CamCtl_PageSel);
+	siob(ctlr, CamPageSel, CamPageSel_Mar);
+
 	/* Init Rx MAC. */
 	wiob(ctlr, RxControl,
-		RxControl_MultiCast|RxControl_BroadCast|RxControl_UniCast);
+		RxControl_BroadCast|RxControl_UniCast);
 	wiob(ctlr, RxConfig, RxConfig_VlanOpt0);
 
 	/* Load Rx ring. */
@@ -825,7 +901,7 @@ vgbeattach(Ether* edev)
 static void
 vgbereset(Ctlr* ctlr)
 {
-//	MiiPhy* phy;
+	MiiPhy* phy;
 	int timeo, i;
 
 //	print("vgbe: reset\n");
@@ -898,8 +974,10 @@ vgbereset(Ctlr* ctlr)
 		return;
 	}
 
-//	phy = ctlr->mii->curphy;
-//	print("vgbe: phy:oui %#x\n", phy->oui);
+	phy = ctlr->mii->curphy;
+	print("vgbe: phy:oui %#x\n", phy->oui);
+
+	vgbemiip(ctlr, 1);
 }
 
 static void
@@ -1092,13 +1170,63 @@ vgbectl(Ether* edev, void* buf, long n)
 static void
 vgbepromiscuous(void* arg, int on)
 {
-	USED(arg, on);
+	Ether* edev;
+	Ctlr* ctlr;
+
+	edev = arg;
+	ctlr = edev->ctlr;
+	if(on)
+	   siob(ctlr, RxControl, RxControl_Promisc | RxControl_MultiCast);
+	else
+	   ciob(ctlr, RxControl, RxControl_Promisc | RxControl_MultiCast);
 }
 
 /* multicast already on, don't need to do anything */
 static void
-vgbemulticast(void*, uchar*, int)
+vgbemulticast(void* ether, uchar* ea, int add)
 {
+	Ether* edev;
+	Ctlr* ctlr;
+	int i;
+
+	edev = ether;
+	ctlr = edev->ctlr;
+
+	if(!add || ctlr->camidx == 32)
+		return;
+
+	for(i = 0; i < ctlr->camidx; i++){
+		if(memcmp(ea, ctlr->maddrs[i], Eaddrlen) == 0)
+			return;
+	}
+
+	memmove(ctlr->maddrs[i], ea, Eaddrlen);
+
+	ciob(ctlr, CamCtl, CamCtl_PageSel);
+ 	siob(ctlr, CamPageSel, CamPageSel_CamData);
+
+	wiob(ctlr, CamAddr, CamAddr_Enable | ctlr->camidx);
+
+	for(i = 0; i < Eaddrlen; i++)
+		wiob(ctlr, Cam0+i, ea[i]);
+
+	siob(ctlr, CamCtl, CamCtl_Write);
+
+	for(i = 0; i < 10000; i++){
+		microdelay(1);
+		if((riob(ctlr, CamCtl) & CamCtl_Write) == 0)
+			break; 	
+	}
+	
+	ciob(ctlr, CamCtl, CamCtl_PageSel);
+	siob(ctlr, CamPageSel, CamPageSel_CamMask);
+	siob(ctlr, Cam0+(ctlr->camidx/8), 1<<(ctlr->camidx&7));
+
+	ctlr->camidx++;
+  
+	wiob(ctlr, CamAddr, 0);
+	ciob(ctlr, CamCtl, CamCtl_PageSel);
+	siob(ctlr, CamPageSel, CamPageSel_Mar);
 }
 
 static int
@@ -1134,11 +1262,12 @@ vgbepnp(Ether* edev)
 	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;
 	edev->ifstat = vgbeifstat;
-//	edev->promiscuous = vgbepromiscuous;
+	edev->promiscuous = vgbepromiscuous;
 	edev->multicast = vgbemulticast;
 //	edev->shutdown = vgbeshutdown;
 	edev->ctl = vgbectl;

             reply	other threads:[~2022-05-21 15:48 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-05-21 15:46 Arne Meyer [this message]
2022-06-04 16:40 ` [9front] " Arne Meyer
2022-06-04 16:44 ` [9front] " ori

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=CACr+GXYvYMSEKzDeRxYy-gZDC4z3ZufPn6hg4eNj+J39Vg_2EQ@mail.gmail.com \
    --to=meyer.arne83@gmail.com \
    --cc=9front@9front.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).