* [9front] [patch] ethervgbe fixes
@ 2022-05-21 15:46 Arne Meyer
2022-06-04 16:40 ` [9front] " Arne Meyer
2022-06-04 16:44 ` [9front] " ori
0 siblings, 2 replies; 3+ messages in thread
From: Arne Meyer @ 2022-05-21 15:46 UTC (permalink / raw)
To: 9front
[-- 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;
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2022-06-04 16:48 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-05-21 15:46 [9front] [patch] ethervgbe fixes Arne Meyer
2022-06-04 16:40 ` [9front] " Arne Meyer
2022-06-04 16:44 ` [9front] " ori
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).