Modify EEPROM read functions and handle also 9356 EEPROM.

Fixes kern/9861.
This commit is contained in:
tsutsui 2000-04-30 12:00:40 +00:00
parent e623cd6f8f
commit 439b360ab9
5 changed files with 67 additions and 95 deletions

View File

@ -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;

View File

@ -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;

View File

@ -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

View File

@ -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 */

View File

@ -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.