Modify EEPROM read functions and handle also 9356 EEPROM.
Fixes kern/9861.
This commit is contained in:
parent
e623cd6f8f
commit
439b360ab9
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: if_rl_cardbus.c,v 1.6 2000/04/28 03:48:56 tsutsui Exp $ */
|
||||
/* $NetBSD: if_rl_cardbus.c,v 1.7 2000/04/30 12:00:41 tsutsui Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2000 Masanori Kanaoka
|
||||
* All rights reserved.
|
||||
|
@ -164,9 +164,10 @@ rl_cardbus_attach(parent, self, aux)
|
|||
struct device *parent, *self;
|
||||
void *aux;
|
||||
{
|
||||
int s, pmreg;
|
||||
u_char eaddr[ETHER_ADDR_LEN];
|
||||
pcireg_t command;
|
||||
int addr_len, s, pmreg;
|
||||
u_int16_t val;
|
||||
u_char eaddr[ETHER_ADDR_LEN];
|
||||
pcireg_t command;
|
||||
struct rl_cardbus_softc *csc = (struct rl_cardbus_softc *)self;
|
||||
struct rl_softc *sc = &csc->sc_rl;
|
||||
struct cardbus_attach_args *ca = aux;
|
||||
|
@ -286,27 +287,22 @@ rl_cardbus_attach(parent, self, aux)
|
|||
sc->rl_type = RL_8139;
|
||||
|
||||
/*
|
||||
* LD-10/100CBA (ACCTON_MPX5030):
|
||||
* LPC3-TX-CB (REALTEK_RT8138):
|
||||
* rl_read_eeprom() can't get MAC address
|
||||
* from EEPROM(serial access). Lift MAC address
|
||||
* from RL-IDR0 -Rl_IDR5 register.
|
||||
*
|
||||
* RTL8139B(L) datasheet rev 2.4.
|
||||
*
|
||||
* o REGSTER RL_IDR0 - RL_IDR5 address
|
||||
*
|
||||
* o "After the vaild duration of the RSTB pin or
|
||||
* autoload command in 9346CR,RTL8139B(L) performs
|
||||
* a series of EEPROM read operation from 93C46(93C56)
|
||||
* address 00H to 31H." from 6. EEPROM Contents
|
||||
* Check EEPROM type 9346 or 9356
|
||||
*/
|
||||
eaddr[0] = CSR_READ_1(sc, RL_IDR0);
|
||||
eaddr[1] = CSR_READ_1(sc, RL_IDR1);
|
||||
eaddr[2] = CSR_READ_1(sc, RL_IDR2);
|
||||
eaddr[3] = CSR_READ_1(sc, RL_IDR3);
|
||||
eaddr[4] = CSR_READ_1(sc, RL_IDR4);
|
||||
eaddr[5] = CSR_READ_1(sc, RL_IDR5);
|
||||
if (rl_read_eeprom(sc, RL_EE_ID, RL_EEADDR_LEN1) == 0x8129)
|
||||
addr_len = RL_EEADDR_LEN1;
|
||||
else
|
||||
addr_len = RL_EEADDR_LEN0;
|
||||
|
||||
val = rl_read_eeprom(sc, RL_EE_EADDR0, addr_len);
|
||||
eaddr[0] = val & 0xff;
|
||||
eaddr[1] = val >> 8;
|
||||
val = rl_read_eeprom(sc, RL_EE_EADDR1, addr_len);
|
||||
eaddr[2] = val & 0xff;
|
||||
eaddr[3] = val >> 8;
|
||||
val = rl_read_eeprom(sc, RL_EE_EADDR2, addr_len);
|
||||
eaddr[4] = val & 0xff;
|
||||
eaddr[5] = val >> 8;
|
||||
} else {
|
||||
printf(": unknown device ID: 0x%x\n", t->rl_did);
|
||||
goto fail;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: rtl81x9.c,v 1.4 2000/04/26 14:02:34 tsutsui Exp $ */
|
||||
/* $NetBSD: rtl81x9.c,v 1.5 2000/04/30 12:00:40 tsutsui Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1997, 1998
|
||||
|
@ -156,8 +156,7 @@ STATIC void rl_shutdown __P((void *));
|
|||
STATIC int rl_ifmedia_upd __P((struct ifnet *));
|
||||
STATIC void rl_ifmedia_sts __P((struct ifnet *, struct ifmediareq *));
|
||||
|
||||
STATIC void rl_eeprom_putbyte __P((struct rl_softc *, int));
|
||||
STATIC void rl_eeprom_getword __P((struct rl_softc *, int, u_int16_t *));
|
||||
STATIC void rl_eeprom_putbyte __P((struct rl_softc *, int, int));
|
||||
STATIC void rl_mii_sync __P((struct rl_softc *));
|
||||
STATIC void rl_mii_send __P((struct rl_softc *, u_int32_t, int));
|
||||
STATIC int rl_mii_readreg __P((struct rl_softc *, struct rl_mii_frame *));
|
||||
|
@ -177,28 +176,28 @@ STATIC int rl_ether_ioctl __P((struct ifnet *, u_long, caddr_t));
|
|||
|
||||
#define EE_SET(x) \
|
||||
CSR_WRITE_1(sc, RL_EECMD, \
|
||||
CSR_READ_1(sc, RL_EECMD) | x)
|
||||
CSR_READ_1(sc, RL_EECMD) | (x))
|
||||
|
||||
#define EE_CLR(x) \
|
||||
CSR_WRITE_1(sc, RL_EECMD, \
|
||||
CSR_READ_1(sc, RL_EECMD) & ~x)
|
||||
CSR_READ_1(sc, RL_EECMD) & ~(x))
|
||||
|
||||
/*
|
||||
* Send a read command and address to the EEPROM, check for ACK.
|
||||
*/
|
||||
STATIC void rl_eeprom_putbyte(sc, addr)
|
||||
STATIC void rl_eeprom_putbyte(sc, addr, addr_len)
|
||||
struct rl_softc *sc;
|
||||
int addr;
|
||||
int addr, addr_len;
|
||||
{
|
||||
int d, i;
|
||||
|
||||
d = addr | RL_EECMD_READ;
|
||||
d = (RL_EECMD_READ << addr_len) | addr;
|
||||
|
||||
/*
|
||||
* Feed in each bit and stobe the clock.
|
||||
*/
|
||||
for (i = 0x400; i; i >>= 1) {
|
||||
if (d & i) {
|
||||
for (i = RL_EECMD_LEN + addr_len - 1; i >= 0; i--) {
|
||||
if (d & (1 << i)) {
|
||||
EE_SET(RL_EE_DATAIN);
|
||||
} else {
|
||||
EE_CLR(RL_EE_DATAIN);
|
||||
|
@ -209,20 +208,17 @@ STATIC void rl_eeprom_putbyte(sc, addr)
|
|||
EE_CLR(RL_EE_CLK);
|
||||
DELAY(100);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Read a word of data stored in the EEPROM at address 'addr.'
|
||||
*/
|
||||
STATIC void rl_eeprom_getword(sc, addr, dest)
|
||||
u_int16_t rl_read_eeprom(sc, addr, addr_len)
|
||||
struct rl_softc *sc;
|
||||
int addr;
|
||||
u_int16_t *dest;
|
||||
int addr, addr_len;
|
||||
{
|
||||
int i;
|
||||
u_int16_t word = 0;
|
||||
int i;
|
||||
|
||||
/* Enter EEPROM access mode. */
|
||||
CSR_WRITE_1(sc, RL_EECMD, RL_EEMODE_PROGRAM|RL_EE_SEL);
|
||||
|
@ -230,18 +226,18 @@ STATIC void rl_eeprom_getword(sc, addr, dest)
|
|||
/*
|
||||
* Send address of word we want to read.
|
||||
*/
|
||||
rl_eeprom_putbyte(sc, addr);
|
||||
rl_eeprom_putbyte(sc, addr, addr_len);
|
||||
|
||||
CSR_WRITE_1(sc, RL_EECMD, RL_EEMODE_PROGRAM|RL_EE_SEL);
|
||||
|
||||
/*
|
||||
* Start reading bits from EEPROM.
|
||||
*/
|
||||
for (i = 0x8000; i; i >>= 1) {
|
||||
for (i = 15; i >= 0; i--) {
|
||||
EE_SET(RL_EE_CLK);
|
||||
DELAY(100);
|
||||
if (CSR_READ_1(sc, RL_EECMD) & RL_EE_DATAOUT)
|
||||
word |= i;
|
||||
word |= (1 << i);
|
||||
EE_CLR(RL_EE_CLK);
|
||||
DELAY(100);
|
||||
}
|
||||
|
@ -249,43 +245,9 @@ STATIC void rl_eeprom_getword(sc, addr, dest)
|
|||
/* Turn off EEPROM access mode. */
|
||||
CSR_WRITE_1(sc, RL_EECMD, RL_EEMODE_OFF);
|
||||
|
||||
*dest = word;
|
||||
|
||||
return;
|
||||
return (word);
|
||||
}
|
||||
|
||||
/*
|
||||
* Read a sequence of words from the EEPROM.
|
||||
*/
|
||||
void rl_read_eeprom(sc, dest, off, cnt, swap)
|
||||
struct rl_softc *sc;
|
||||
caddr_t dest;
|
||||
int off;
|
||||
int cnt;
|
||||
int swap;
|
||||
{
|
||||
int i;
|
||||
u_int16_t word = 0, *ptr;
|
||||
|
||||
for (i = 0; i < cnt; i++) {
|
||||
rl_eeprom_getword(sc, off + i, &word);
|
||||
ptr = (u_int16_t *)(dest + (i * 2));
|
||||
if (swap)
|
||||
/*
|
||||
* EEPROM stores data in little endian and
|
||||
* rl_eeprom_getword() returns them in host's endian.
|
||||
* If caller requires byte-stream data, we should
|
||||
* revert them little endian.
|
||||
*/
|
||||
*ptr = htole16(word);
|
||||
else
|
||||
*ptr = word;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* MII access routines are provided for the 8129, which
|
||||
* doesn't have a built-in PHY. For the 8139, we fake things
|
||||
|
@ -753,7 +715,7 @@ rl_attach(sc, eaddr)
|
|||
printf("%s: can't create snd buffer DMA map,"
|
||||
" error = %d\n", sc->sc_dev.dv_xname, error);
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
ifp = &sc->ethercom.ec_if;
|
||||
ifp->if_softc = sc;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: rtl81x9reg.h,v 1.3 2000/04/26 14:02:35 tsutsui Exp $ */
|
||||
/* $NetBSD: rtl81x9reg.h,v 1.4 2000/04/30 12:00:40 tsutsui Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1997, 1998
|
||||
|
@ -238,16 +238,22 @@
|
|||
#define RL_EEMODE_PROGRAM 0x80
|
||||
#define RL_EEMODE_WRITECFG (0x80|0x40)
|
||||
|
||||
/* 9346 EEPROM commands */
|
||||
#define RL_EECMD_WRITE 0x140
|
||||
#define RL_EECMD_READ 0x180
|
||||
#define RL_EECMD_ERASE 0x1c0
|
||||
/* 9346/9356 EEPROM commands */
|
||||
#define RL_EEADDR_LEN0 6 /* 9346 */
|
||||
#define RL_EEADDR_LEN1 8 /* 9356 */
|
||||
#define RL_EECMD_LEN 4
|
||||
|
||||
#define RL_EECMD_WRITE 0x5 /* 0101b */
|
||||
#define RL_EECMD_READ 0x6 /* 0110b */
|
||||
#define RL_EECMD_ERASE 0x7 /* 0111b */
|
||||
|
||||
#define RL_EE_ID 0x00
|
||||
#define RL_EE_PCI_VID 0x01
|
||||
#define RL_EE_PCI_DID 0x02
|
||||
/* Location of station address inside EEPROM */
|
||||
#define RL_EE_EADDR 0x07
|
||||
#define RL_EE_EADDR0 0x07
|
||||
#define RL_EE_EADDR1 0x08
|
||||
#define RL_EE_EADDR2 0x09
|
||||
|
||||
/*
|
||||
* MII register (8129 only)
|
||||
|
@ -300,7 +306,7 @@
|
|||
#define RL_RX_BUF_SZ RL_RXBUF_64
|
||||
#define RL_RXBUFLEN (1 << ((RL_RX_BUF_SZ >> 11) + 13))
|
||||
#define RL_TX_LIST_CNT 4
|
||||
#define RL_TX_EARLYTHRESH (256 << 11)
|
||||
#define RL_TX_EARLYTHRESH ((256 / 32) << 16)
|
||||
#define RL_RX_FIFOTHRESH RL_RXFIFO_256BYTES
|
||||
#define RL_RX_MAXDMA RL_RXDMA_256BYTES
|
||||
#define RL_TX_MAXDMA RL_TXDMA_256BYTES
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: rtl81x9var.h,v 1.1 2000/04/26 14:02:35 tsutsui Exp $ */
|
||||
/* $NetBSD: rtl81x9var.h,v 1.2 2000/04/30 12:00:40 tsutsui Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1997, 1998
|
||||
|
@ -130,8 +130,8 @@ struct rl_softc {
|
|||
#define RL_PME_STATUS 0x8000
|
||||
|
||||
#ifdef _KERNEL
|
||||
void rl_attach __P((struct rl_softc *, const u_int8_t *));
|
||||
int rl_intr __P((void *));
|
||||
void rl_read_eeprom __P((struct rl_softc *, caddr_t, int, int, int));
|
||||
void rl_reset __P((struct rl_softc *));
|
||||
void rl_attach __P((struct rl_softc *, const u_int8_t *));
|
||||
int rl_intr __P((void *));
|
||||
u_int16_t rl_read_eeprom __P((struct rl_softc *, int, int));
|
||||
void rl_reset __P((struct rl_softc *));
|
||||
#endif /* _KERNEL */
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: if_rl_pci.c,v 1.5 2000/04/26 14:02:36 tsutsui Exp $ */
|
||||
/* $NetBSD: if_rl_pci.c,v 1.6 2000/04/30 12:00:41 tsutsui Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1997, 1998
|
||||
|
@ -221,7 +221,7 @@ rl_pci_attach(parent, self, aux)
|
|||
pcireg_t command;
|
||||
struct rl_pci_softc *psc = (struct rl_pci_softc *)self;
|
||||
struct rl_softc *sc = &psc->sc_rl;
|
||||
u_int16_t rl_did = 0;
|
||||
u_int16_t rl_did, val;
|
||||
struct pci_attach_args *pa = aux;
|
||||
pci_chipset_tag_t pc = pa->pa_pc;
|
||||
pci_intr_handle_t ih;
|
||||
|
@ -301,7 +301,7 @@ rl_pci_attach(parent, self, aux)
|
|||
* Now read the exact device type from the EEPROM to find
|
||||
* out if it's an 8129 or 8139.
|
||||
*/
|
||||
rl_read_eeprom(sc, (caddr_t)&rl_did, RL_EE_PCI_DID, 1, 0);
|
||||
rl_did = rl_read_eeprom(sc, RL_EE_PCI_DID, RL_EEADDR_LEN0);
|
||||
|
||||
if (rl_did == PCI_PRODUCT_REALTEK_RT8139 ||
|
||||
rl_did == PCI_PRODUCT_ACCTON_MPX5030 ||
|
||||
|
@ -326,7 +326,15 @@ rl_pci_attach(parent, self, aux)
|
|||
/*
|
||||
* Get station address from the EEPROM.
|
||||
*/
|
||||
rl_read_eeprom(sc, (caddr_t)&eaddr, RL_EE_EADDR, 3, 1);
|
||||
val = rl_read_eeprom(sc, RL_EE_EADDR0, RL_EEADDR_LEN0);
|
||||
eaddr[0] = val & 0xff;
|
||||
eaddr[1] = val >> 8;
|
||||
val = rl_read_eeprom(sc, RL_EE_EADDR1, RL_EEADDR_LEN0);
|
||||
eaddr[2] = val & 0xff;
|
||||
eaddr[3] = val >> 8;
|
||||
val = rl_read_eeprom(sc, RL_EE_EADDR2, RL_EEADDR_LEN0);
|
||||
eaddr[4] = val & 0xff;
|
||||
eaddr[5] = val >> 8;
|
||||
|
||||
/*
|
||||
* A RealTek chip was detected. Inform the world.
|
||||
|
|
Loading…
Reference in New Issue