From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on inbox.vuxu.org X-Spam-Level: X-Spam-Status: No, score=-0.0 required=5.0 tests=T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.4 Received: (qmail 31903 invoked from network); 6 Nov 2023 08:57:13 -0000 Received: from 9front.inri.net (168.235.81.73) by inbox.vuxu.org with ESMTPUTF8; 6 Nov 2023 08:57:13 -0000 Received: from oneiri.one ([170.39.227.229]) by 9front; Mon Nov 6 03:56:04 -0500 2023 Message-ID: <7F669AA1E6587746F88D8D73EB771359@oneiri.one> From: Aidan K. Wiggins Date: Mon, 06 Nov 2023 00:55:54 -0800 To: 9front@9front.org MIME-Version: 1.0 Content-Type: text/plain; charset="US-ASCII" Content-Transfer-Encoding: 7bit List-ID: <9front.9front.org> List-Help: X-Glyph: ➈ X-Bullshit: SVG over HTTP session table Subject: [9front] [PATCH] nusb/ether: implement link status for a88179 Reply-To: 9front@9front.org Precedence: bulk In addition to a179linkstatus(), there is now proper link detection on start, and the phy no longer auto powers off when not talked to. diff 9973c9276dcb2ff075a78737c403750b0201655f uncommitted --- a/sys/src/cmd/nusb/ether/asix.c +++ b/sys/src/cmd/nusb/ether/asix.c @@ -46,6 +46,9 @@ Bmcranena = 0x1000, /* auto neg. enable */ Bmcrar = 0x0200, /* announce restart */ + Miibmsr = 0x01, + Bmsrlink = 0x0004, + Miiad = 0x04, /* advertise reg. */ Adcsma = 0x0001, Ad1000f = 0x0200, @@ -421,11 +424,11 @@ Aphy = 0x02, Physts = 0x02, Phyid = 0x03, + Phyfd = 0x11, /* Control */ Crxctl = 0x0b, Cmed = 0x22, /* medium status register */ - Cmmsr = 0x24, /* control monitor */ Mrwmp = 0x04, Mpmepol = 0x20, @@ -436,7 +439,6 @@ Cphyiprl = 0x0020, Cblkinq = 0x2e, - Csclk = 0x33, /* select clock */ Sclkbcs = 0x01, Sclkacs = 0x02, @@ -443,10 +445,17 @@ Cpwtrl = 0x54, Cpwtrh = 0x55, + Capo = 0x91, /* auto-power off phy */ - Usbss = 0x04, - Usbhs = 0x02, + /* USB/Link conn. */ Usbfs = 0x01, + Usbhs = 0x02, + Usbss = 0x04, + Link10 = 0x10, + Link100 = 0x20, + Link1000 = 0x40, + + Linkfd = 0x2000, }; static int @@ -580,6 +589,24 @@ } static int +a179linkup(Dev *d) +{ + int timeout; + ushort link; + + timeout = 5000; + do{ + link = a179miiread(d, Miibmsr); + if(link & Bmsrlink) + return 0; + sleep(50); + }while(timeout -= 50); + + fprint(2, "%s: a179linkup: no link\n", argv0); + return -1; +} + +static int a179promiscuous(Dev *d, int on) { ushort rxctl; @@ -605,6 +632,21 @@ return a179set2(d, Crxctl, rxctl); } +static int +a179linkspeed(Dev *d) +{ + uchar link; + + a179get(d, Amac, Physts, 1, &link, 1); + if(link & Link1000) + return 1000; + if(link & Link100) + return 100; + if(link & Link10) + return 10; + return 0; +} + int a88179init(Dev *d) { @@ -614,8 +656,9 @@ {0x07, 0xae, 0x07, 0x04, 0xff}, {0x07, 0xcc, 0x4c, 0x04, 0x08} }; + ushort mode, fd; uchar link; - int bmcr, spd; + int spd; a179set2(d, Cphy, 0); a179set2(d, Cphy, Cphyiprl); @@ -622,7 +665,6 @@ sleep(200); a179set1(d, Csclk, Sclkacs|Sclkbcs); sleep(100); - a179set(d, Amac, Cblkinq, 5, qctrl[0], 5); a179set1(d, Cpwtrl, 0x34); a179set1(d, Cpwtrh, 0x52); if(setmac){ @@ -634,29 +676,40 @@ return -1; if(a179set1(d, Cmmsr, Mpmetyp|Mpmepol|Mrwmp) < 0) return -1; - if(a179set2(d, Cmed, Mall179) < 0) + if(a179set(d, Capo, 0, 0, nil, 0) < 0) return -1; + if(a179linkup(d) < 0) + return -1; + + spd = 3; /* default bulkinq */ + mode = Mtfc | Mrfc | Mre; a179get(d, Amac, Physts, 1, &link, 1); - switch(link){ - case Usbss: spd = 0; break; - case Usbhs: spd = 1; break; - case Usbss|Usbhs: spd = 2; break; - default: spd = 3; - } + if(link & Link1000){ + mode |= Mgm|Mmhz|Mjfe|Munk; + if(link & Usbss) + spd = 0; + else if(link & Usbhs) + spd = 1; + }else if(link & Link100){ + mode |= Mps; + if(link & (Usbss|Usbhs)) + spd = 2; + } /* Link10 */ a179set(d, Amac, Cblkinq, 5, qctrl[spd], 5); a179bufsz = 1024*(qctrl[spd][3]+2); + fd = a179miiread(d, Phyfd); + if(fd & Linkfd) + mode |= Mfd; - bmcr = a179miiread(d, Miibmcr); - if((bmcr & Bmcranena) != 0){ - bmcr |= Bmcrar; - a179miiwrite(d, Miibmcr, bmcr); - } + if(a179set2(d, Cmed, mode) < 0) + return -1; epreceive = a179receive; eptransmit = a179transmit; eppromiscuous = a179promiscuous; epmulticast = a179multicast; + eplinkspeed = a179linkspeed; return 0; }