summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorppatience0 <ppatience0@gmail.com>2013-10-03 17:13:08 -0400
committerppatience0 <ppatience0@gmail.com>2013-10-03 17:13:08 -0400
commit9eab198d05b29be79433aa3cc3a762cff8012680 (patch)
treeb35f49179db813d43efce95c55d6e17a3800232f
parent60e3d2782b30019769bd250c15329108fab1cc5a (diff)
downloadplan9front-9eab198d05b29be79433aa3cc3a762cff8012680.tar.xz
ether83815: fix `auto neg timed out' error with sis 900 rev 635.
the openbsd sis(4) driver does not actually go through the rest of softreset() with sis cards. also, rev 635 reads the mac address differently, so copy-paste code from openbsd to handle that.
-rw-r--r--sys/src/9/pc/ether83815.c20
1 files changed, 19 insertions, 1 deletions
diff --git a/sys/src/9/pc/ether83815.c b/sys/src/9/pc/ether83815.c
index 6b3a4cf73..a17f2d0e6 100644
--- a/sys/src/9/pc/ether83815.c
+++ b/sys/src/9/pc/ether83815.c
@@ -92,6 +92,7 @@ enum { /* PCI vendor & device IDs */
SiSrev630s = 0x81,
SiSrev630e = 0x82,
SiSrev630ea1 = 0x83,
+ SiSrev635 = 0x90,
SiSeenodeaddr = 8, /* short addr of SiS eeprom mac addr */
SiS630eenodeaddr = 9, /* likewise for the 630 */
@@ -166,6 +167,7 @@ static Ctlr* ctlrtail;
enum {
/* registers (could memory map) */
Rcr= 0x00, /* command register */
+ Rld= 1<<10, /* reload */
Rst= 1<<8,
Rxr= 1<<5, /* receiver reset */
Txr= 1<<4, /* transmitter reset */
@@ -772,6 +774,8 @@ softreset(Ctlr* ctlr, int resetphys)
* Soft-reset the controller
*/
resetctlr(ctlr);
+ if(ctlr->id != Nat83815)
+ return 0;
csr32w(ctlr, Rccsr, Pmests);
csr32w(ctlr, Rccsr, 0);
csr32w(ctlr, Rcfg, csr32r(ctlr, Rcfg) | Pint_acen);
@@ -923,7 +927,21 @@ sissrom(Ctlr *ctlr)
int i, off = SiSeenodeaddr, cnt = sizeof ee.eaddr / sizeof(short);
ushort *shp = (ushort *)ee.eaddr;
- if(!is630(ctlr->id, ctlr->pcidev) || !sisrdcmos(ctlr)) {
+ if(ctlr->id == SiS900 && ctlr->pcidev->rid == SiSrev635) {
+ csr32w(ctlr, Rcr, csr32r(ctlr, Rcr) | Rld);
+ csr32w(ctlr, Rcr, csr32r(ctlr, Rcr) & ~Rld);
+ csr32w(ctlr, Rrfcr, csr32r(ctlr, Rrfcr) & ~Rfen);
+
+ csr32w(ctlr, Rrfcr, 0);
+ *shp++ = csr32r(ctlr, Rrfdr);
+ csr32w(ctlr, Rrfcr, 1<<16);
+ *shp++ = csr32r(ctlr, Rrfdr);
+ csr32w(ctlr, Rrfcr, 1<<17);
+ *shp = csr32r(ctlr, Rrfdr);
+
+ csr32w(ctlr, Rrfcr, csr32r(ctlr, Rrfcr) | Rfen);
+ memmove(ctlr->sromea, ee.eaddr, sizeof ctlr->sromea);
+ } else if(!is630(ctlr->id, ctlr->pcidev) || !sisrdcmos(ctlr)) {
for (i = 0; i < cnt; i++)
*shp++ = eegetw(ctlr, off++);
memmove(ctlr->sromea, ee.eaddr, sizeof ctlr->sromea);