shithub: riscv

Download patch

ref: 52570a2a2d8566cedc9c9fdeb888635e70f33f2e
parent: abda59c7ecef03f9ab91568c8417f963fb7db894
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Sun Feb 19 13:20:46 EST 2017

ether82563: support for i219 (tested on t460p, thanks aiju)

--- a/sys/src/9/pc/ether82563.c
+++ b/sys/src/9/pc/ether82563.c
@@ -446,6 +446,7 @@
 	i210,
 	i217,
 	i218,
+	i219,
 	i350,
 	Nctlrtype,
 };
@@ -489,6 +490,7 @@
 [i210]		"i210",		9728,	F75|Fnofct|Fert,
 [i217]		"i217",		9728,	Fload|Fnofct|Fert|Fbadcsum,
 [i218]		"i218",		9728,	Fload|Fert|F79phy|Fnofct|Fbadcsum,
+[i219]		"i219",		9728,	Fload|Fert|F79phy|Fnofct,
 [i350]		"i350",		9728,	F75|F79phy|Fnofct,
 };
 
@@ -708,13 +710,13 @@
 		ctlr->speeds[0], ctlr->speeds[1], ctlr->speeds[2], ctlr->speeds[3]);
 	p = seprint(p, e, "type: %s\n", cname(ctlr));
 
-//	p = seprint(p, e, "eeprom:");
-//	for(i = 0; i < 0x40; i++){
-//		if(i && ((i & 7) == 0))
-//			p = seprint(p, e, "\n       ");
-//		p = seprint(p, e, " %4.4ux", ctlr->eeprom[i]);
-//	}
-//	p = seprint(p, e, "\n");
+	p = seprint(p, e, "eeprom:");
+	for(i = 0; i < 0x40; i++){
+		if(i && ((i & 7) == 0))
+			p = seprint(p, e, "\n       ");
+		p = seprint(p, e, " %4.4ux", ctlr->eeprom[i]);
+	}
+	p = seprint(p, e, "\n");
 
 	USED(p);
 	n = readstr(offset, a, n, s);
@@ -763,6 +765,7 @@
 	case i210:
 	case i217:
 	case i218:
+	case i219:
 		bit = (addr[5]<<2)|(addr[4]>>6);
 		x = (bit>>5) & 31;
 		break;
@@ -1558,52 +1561,108 @@
 }
 
 static int
-fcycle(Ctlr *, Flash *f)
+fread16(Ctlr *c, Flash *f, int ladr)
 {
 	u16int s;
-	int i;
+	int timeout;
 
+	delay(1);
 	s = f->reg[Fsts];
 	if((s&Fvalid) == 0)
 		return -1;
 	f->reg[Fsts] |= Fcerr | Ael;
-	for(i = 0; i < 10; i++){
+	for(timeout = 0; timeout < 10; timeout++){
 		if((s&Scip) == 0)
-			return 0;
+			goto done;
 		delay(1);
 		s = f->reg[Fsts];
 	}
 	return -1;
+done:
+	f->reg[Fsts] |= Fdone;
+	f->reg32[Faddr] = ladr;
+
+	/* setup flash control register */
+	s = f->reg[Fctl] & ~0x3ff;
+	f->reg[Fctl] = s | 1<<8 | Fgo;	/* 2 byte read */
+	timeout = 1000;
+	while((f->reg[Fsts] & Fdone) == 0 && timeout--)
+		microdelay(5);
+	if(timeout < 0){
+		print("%s: fread timeout\n", cname(c));
+		return -1;
+	}
+	if(f->reg[Fsts] & (Fcerr|Ael))
+		return -1;
+	return f->reg32[Fdata] & 0xffff;
 }
 
 static int
-fread(Ctlr *c, Flash *f, int ladr)
+fread32(Ctlr *c, Flash *f, int ladr, u32int *data)
 {
-	u16int s;
+	u32int s;
 	int timeout;
 
 	delay(1);
-	if(fcycle(c, f) == -1)
+	s = f->reg32[Fsts/2];
+	if((s&Fvalid) == 0)
 		return -1;
-	f->reg[Fsts] |= Fdone;
+	f->reg32[Fsts/2] |= Fcerr | Ael;
+	for(timeout = 0; timeout < 10; timeout++){
+		if((s&Scip) == 0)
+			goto done;
+		delay(1);
+		s = f->reg32[Fsts/2];
+	}
+	return -1;
+done:
+	f->reg32[Fsts/2] |= Fdone;
 	f->reg32[Faddr] = ladr;
 
 	/* setup flash control register */
-	s = f->reg[Fctl] & ~0x3ff;
-	f->reg[Fctl] = s | 1<<8 | Fgo;	/* 2 byte read */
+	s = (f->reg32[Fctl/2] >> 16) & ~0x3ff;
+	f->reg32[Fctl/2] = (s | 3<<8 | Fgo) << 16;	/* 4 byte read */
 	timeout = 1000;
-	while((f->reg[Fsts] & Fdone) == 0 && timeout--)
+	while((f->reg32[Fsts/2] & Fdone) == 0 && timeout--)
 		microdelay(5);
 	if(timeout < 0){
 		print("%s: fread timeout\n", cname(c));
 		return -1;
 	}
-	if(f->reg[Fsts] & (Fcerr|Ael))
+	if(f->reg32[Fsts/2] & (Fcerr|Ael))
 		return -1;
-	return f->reg32[Fdata] & 0xffff;
+	*data = f->reg32[Fdata];
+	return 0;
 }
 
 static int
+fload32(Ctlr *c)
+{
+	int r, adr;
+	u16int sum;
+	u32int w;
+	Flash f;
+
+	f.reg32 = &c->nic[0xe000/4];
+	f.reg = nil;
+	f.base = 0;
+	f.lim = (((csr32r(c, 0xC) >> 1) & 0x1F) + 1) << 12;
+	r = f.lim >> 1;
+	if(fread32(c, &f, r + 0x24, &w) == -1  || (w & 0xC000) != 0x8000)
+		r = 0;
+	sum = 0;
+	for(adr = 0; adr < 0x20; adr++) {
+		if(fread32(c, &f, r + adr*4, &w) == -1)
+			return -1;
+		c->eeprom[adr*2+0] = w;
+		c->eeprom[adr*2+1] = w>>16;
+		sum += w & 0xFFFF;
+		sum += w >> 16;
+	}
+	return sum;
+}
+
+static int
 fload(Ctlr *c)
 {
 	int data, r, adr;
@@ -1611,6 +1670,10 @@
 	void *va;
 	Flash f;
 
+	memset(c->eeprom, 0xFF, sizeof(c->eeprom));
+	if(c->pcidev->mem[1].bar == 0)
+		return fload32(c);	/* i219 */
+
 	va = vmap(c->pcidev->mem[1].bar & ~0x0f, c->pcidev->mem[1].size);
 	if(va == nil)
 		return -1;
@@ -1623,12 +1686,13 @@
 	r = f.base << 12;
 	sum = 0;
 	for(adr = 0; adr < 0x40; adr++) {
-		data = fread(c, &f, r + adr*2);
+		data = fread16(c, &f, r + adr*2);
 		if(data == -1)
-			return -1;
+			goto out;
 		c->eeprom[adr] = data;
 		sum += data;
 	}
+out:
 	vunmap(va, c->pcidev->mem[1].size);
 	return sum;
 }
@@ -1869,7 +1933,6 @@
 	case 0x153a:		/* i217-lm */
 	case 0x153b:		/* i217-v */
 		return i217;
-		break;
 	case 0x1559:		/* i218-v */
 	case 0x155a:		/* i218-lm */
 	case 0x15a0:		/* i218-lm */
@@ -1877,6 +1940,16 @@
 	case 0x15a2:		/* i218-lm */
 	case 0x15a3:		/* i218-v */
 		return i218;
+	case 0x156f:		/* i219-lm */
+	case 0x15b7:		/* i219-lm */
+	case 0x1570:		/* i219-v */
+	case 0x15b8:		/* i219-v */
+	case 0x15b9:		/* i219-lm */
+	case 0x15d6:		/* i219-v */
+	case 0x15d7:		/* i219-lm */
+	case 0x15d8:		/* i219-v */
+	case 0x15e3:		/* i219-lm */
+		return i219;
 	case 0x151f:		/* “powerville” eeprom-less */
 	case 0x1521:		/* copper */
 	case 0x1522:		/* fiber */
@@ -2109,6 +2182,12 @@
 }
 
 static int
+i219pnp(Ether *e)
+{
+	return pnp(e, i219);
+}
+
+static int
 i350pnp(Ether *e)
 {
 	return pnp(e, i350);
@@ -2140,6 +2219,7 @@
 	addethercard("i210", i210pnp);
 	addethercard("i217", i217pnp);
 	addethercard("i218", i218pnp);
+	addethercard("i219", i219pnp);
 	addethercard("i350", i350pnp);
 	addethercard("igbepcie", anypnp);
 }