e1000 tweaks for tom

上级 8c0dd51c
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
#include "amd64.h" #include "amd64.h"
#include "kernel.hh" #include "kernel.hh"
#include "pci.hh" #include "pci.hh"
#include "pcireg.hh"
#include "spinlock.h" #include "spinlock.h"
#include "e1000reg.hh" #include "e1000reg.hh"
...@@ -30,6 +31,27 @@ static struct { ...@@ -30,6 +31,27 @@ static struct {
struct spinlock lk; struct spinlock lk;
} e1000; } e1000;
struct eerd {
u32 data_shift;
u32 addr_shift;
u32 done_bit;
u32 start_bit;
};
static const struct eerd eerd_default = {
data_shift: 16,
addr_shift: 8,
done_bit: 0x00000010,
start_bit: 0x00000001,
};
static const struct eerd eerd_82541xx = {
data_shift: 16,
addr_shift: 2,
done_bit: 0x00000002,
start_bit: 0x00000001
};
static inline u32 static inline u32
erd(u32 reg) erd(u32 reg)
{ {
...@@ -47,27 +69,32 @@ ewr(u32 reg, u32 val) ...@@ -47,27 +69,32 @@ ewr(u32 reg, u32 val)
} }
static int static int
eeprom_eerd_read(u16 off) eeprom_eerd_read(const eerd* eerd, u16 off)
{ {
u32 reg; u32 reg;
int x; int x;
// [E1000 13.4.4] Ensure EEC control is released
reg = erd(WMREG_EECD);
reg &= ~(EECD_EE_REQ|EECD_EE_GNT);
ewr(WMREG_EECD, reg);
// [E1000 5.3.1] Software EEPROM access // [E1000 5.3.1] Software EEPROM access
ewr(WMREG_EERD, (off<<EERD_ADDR_SHIFT) | EERD_START); ewr(WMREG_EERD, (off<<eerd->addr_shift) | eerd->start_bit);
for (x = 0; x < 5; x++) { for (x = 0; x < 5; x++) {
reg = erd(WMREG_EERD); reg = erd(WMREG_EERD);
if (reg & EERD_DONE) if (reg & eerd->done_bit)
return (reg&EERD_DATA_MASK) >> EERD_DATA_SHIFT; return (reg&EERD_DATA_MASK) >> eerd->data_shift;
microdelay(50000); microdelay(50000);
} }
return -1; return -1;
} }
static int static int
eeprom_read(u16 *buf, int off, int count) eeprom_read(const eerd* eerd, u16 *buf, int off, int count)
{ {
for (int i = 0; i < count; i++) { for (int i = 0; i < count; i++) {
int r = eeprom_eerd_read(off+i); int r = eeprom_eerd_read(eerd, off+i);
if (r < 0) { if (r < 0) {
cprintf("eeprom_read: cannot read\n"); cprintf("eeprom_read: cannot read\n");
return -1; return -1;
...@@ -267,6 +294,7 @@ e1000eattach(struct pci_func *pcif) ...@@ -267,6 +294,7 @@ e1000eattach(struct pci_func *pcif)
int int
e1000attach(struct pci_func *pcif) e1000attach(struct pci_func *pcif)
{ {
const eerd* eerd;
int r; int r;
int i; int i;
...@@ -278,7 +306,7 @@ e1000attach(struct pci_func *pcif) ...@@ -278,7 +306,7 @@ e1000attach(struct pci_func *pcif)
initlock(&e1000.lk, "e1000", 1); initlock(&e1000.lk, "e1000", 1);
e1000.membase = pcif->reg_base[0]; e1000.membase = pcif->reg_base[0];
e1000.iobase = pcif->reg_base[2]; e1000.iobase = pcif->reg_base[2];
e1000.pcidevid = pcif->dev_id; e1000.pcidevid = PCI_PRODUCT(pcif->dev_id);
e1000irq = pcif->irq_line; e1000irq = pcif->irq_line;
picenable(e1000irq); picenable(e1000irq);
...@@ -286,8 +314,20 @@ e1000attach(struct pci_func *pcif) ...@@ -286,8 +314,20 @@ e1000attach(struct pci_func *pcif)
e1000reset(); e1000reset();
switch(e1000.pcidevid) {
case 0x100e:
case 0x1079:
eerd = &eerd_default;
break;
case 0x1076:
eerd = &eerd_82541xx;
break;
default:
panic("e1000attach: %x", e1000.pcidevid);
}
// Get the MAC address // Get the MAC address
r = eeprom_read((u16*)e1000.hwaddr, EEPROM_OFF_MACADDR, 3); r = eeprom_read(eerd, (u16*)e1000.hwaddr, EEPROM_OFF_MACADDR, 3);
if (r < 0) if (r < 0)
return 0; return 0;
......
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论