[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
please review the diff against SMC 91Cxx driver
こんばんは。
smc91c92を使っているmac68k用のNuBus NICのドライバーを書いた
のですが、fragmented packetをうまく組み立てることができない
ため、NFSが使えない状態です(netbsd,04650)。rloginなどは動き
ます。
私は上のカード以外にSMC 91Cxxのカードを持っていないため、原
因を切り分けることができません。どなたかMegahertzなどのカー
ドをお持ちの方、-currentに以下のパッチを当てて動くかどうか試
していただけないでしょうか。もちろん「ここが変だ」というので
も結構です。
やっていることは以下の通りです。
○NuBus NICではSMC91C92のレジスターが不連続なアドレスに割り
当てられているため、dp8390.cを参考にreg_map[]を通してアクセ
スするようにした
○mac68kはbig endianなので、レジスターのアクセスにle16toh()、
htole16()を使うようにした
○起動時にNICのROMからMAC addressを読み込んでレジスターに書
き込む機能を追加した
よろしくお願いします。
--
SUNAGAWA Keiki <kei_sun@ba2.so-net.ne.jp>
Hack on NetBSD, and your code runs on over 20 architectures!
Index: dev/ic/smc91cxx.c
===================================================================
RCS file: /a/rsync/netbsd.org/syssrc/sys/dev/ic/smc91cxx.c,v
retrieving revision 1.24
diff -u -r1.24 smc91cxx.c
--- smc91cxx.c 2000/02/04 04:05:50 1.24
+++ smc91cxx.c 2000/02/04 16:10:57
@@ -84,6 +84,7 @@
#include "bpfilter.h"
#include "rnd.h"
+#include <sys/endian.h>
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/mbuf.h>
@@ -190,23 +191,22 @@
}
void
-smc91cxx_attach(sc, myea)
+smc91cxx_attach(sc)
struct smc91cxx_softc *sc;
- u_int8_t *myea;
{
struct ifnet *ifp = &sc->sc_ec.ec_if;
bus_space_tag_t bst = sc->sc_bst;
bus_space_handle_t bsh = sc->sc_bsh;
const char *idstr;
u_int16_t tmp;
- u_int8_t enaddr[ETHER_ADDR_LEN];
int i, aui;
/* Make sure the chip is stopped. */
smc91cxx_stop(sc);
SMC_SELECT_BANK(sc, 3);
- tmp = bus_space_read_2(bst, bsh, REVISION_REG_W);
+ tmp = le16toh(bus_space_read_2(bst, bsh,
+ sc->sc_reg_map[REVISION_REG_W]));
/* check magic number */
if ((tmp & BSR_DETECT_MASK) != BSR_DETECT_VALUE) {
idstr = NULL;
@@ -220,21 +220,32 @@
printf("unknown chip id %d, ", RR_ID(tmp));
printf("revision %d\n", RR_REV(tmp));
- /* Read the station address from the chip. */
+ /* setup MAC address */
SMC_SELECT_BANK(sc, 1);
- if (myea == NULL) {
- myea = enaddr;
+ if (sc->sc_enaddr_from_rom) {
+ /* Write the MAC address got from ROM to chip. */
+ for (i = 0; i < ETHER_ADDR_LEN; i+= 2) {
+ /* Might this be little endian? */
+ tmp = sc->sc_enaddr[i] << 8 | sc->sc_enaddr[i + 1];
+ bus_space_write_2(bst, bsh,
+ sc->sc_reg_map[IAR_ADDR0_REG_W + i], tmp);
+ }
+ } else {
+ /* Read the MAC address from the chip. */
for (i = 0; i < ETHER_ADDR_LEN; i += 2) {
- tmp = bus_space_read_2(bst, bsh, IAR_ADDR0_REG_W + i);
- myea[i + 1] = (tmp >> 8) & 0xff;
- myea[i] = tmp & 0xff;
+ tmp = le16toh(bus_space_read_2(bst, bsh,
+ sc->sc_reg_map[IAR_ADDR0_REG_W + i]));
+ sc->sc_enaddr[i] = (htons(tmp) >> 8) & 0xff;
+ sc->sc_enaddr[i + 1] = htons(tmp) & 0xff;
}
}
+
printf("%s: MAC address %s, ", sc->sc_dev.dv_xname,
- ether_sprintf(myea));
+ ether_sprintf(sc->sc_enaddr));
/* ..and default media. */
- tmp = bus_space_read_2(bst, bsh, CONFIG_REG_W);
+ tmp = le16toh(bus_space_read_2(bst, bsh,
+ sc->sc_reg_map[CONFIG_REG_W]));
printf("default media %s\n", (aui = (tmp & CR_AUI_SELECT)) ?
"AUI" : "UTP");
@@ -249,7 +260,7 @@
/* Attach the interface. */
if_attach(ifp);
- ether_ifattach(ifp, myea);
+ ether_ifattach(ifp, sc->sc_enaddr);
/* Initialize the media structures. */
ifmedia_init(&sc->sc_media, 0, smc91cxx_mediachange,
@@ -304,12 +315,14 @@
case IFM_10_T:
case IFM_10_5:
SMC_SELECT_BANK(sc, 1);
- tmp = bus_space_read_2(bst, bsh, CONFIG_REG_W);
+ tmp = le16toh(bus_space_read_2(bst, bsh,
+ sc->sc_reg_map[CONFIG_REG_W]));
if (IFM_SUBTYPE(media) == IFM_10_5)
tmp |= CR_AUI_SELECT;
else
tmp &= ~CR_AUI_SELECT;
- bus_space_write_2(bst, bsh, CONFIG_REG_W, tmp);
+ bus_space_write_2(bst, bsh, sc->sc_reg_map[CONFIG_REG_W],
+ htole16(tmp));
delay(20000); /* XXX is this needed? */
break;
@@ -340,7 +353,8 @@
}
SMC_SELECT_BANK(sc, 1);
- tmp = bus_space_read_2(bst, bsh, CONFIG_REG_W);
+ tmp = le16toh(bus_space_read_2(bst, bsh,
+ sc->sc_reg_map[CONFIG_REG_W]));
ifmr->ifm_active =
IFM_ETHER | ((tmp & CR_AUI_SELECT) ? IFM_10_5 : IFM_10_T);
}
@@ -356,7 +370,6 @@
bus_space_tag_t bst = sc->sc_bst;
bus_space_handle_t bsh = sc->sc_bsh;
u_int16_t tmp;
- u_int8_t *enaddr;
int s, i;
s = splnet();
@@ -369,19 +382,21 @@
* XXX how long are we really supposed to delay? --thorpej
*/
SMC_SELECT_BANK(sc, 0);
- bus_space_write_2(bst, bsh, RECV_CONTROL_REG_W, RCR_SOFTRESET);
+ bus_space_write_2(bst, bsh, sc->sc_reg_map[RECV_CONTROL_REG_W],
+ htole16(RCR_SOFTRESET));
delay(100);
- bus_space_write_2(bst, bsh, RECV_CONTROL_REG_W, 0);
+ bus_space_write_2(bst, bsh, sc->sc_reg_map[RECV_CONTROL_REG_W], 0);
delay(200);
- bus_space_write_2(bst, bsh, TXMIT_CONTROL_REG_W, 0);
+ bus_space_write_2(bst, bsh, sc->sc_reg_map[TXMIT_CONTROL_REG_W], 0);
/* Set the Ethernet address. */
SMC_SELECT_BANK(sc, 1);
- enaddr = (u_int8_t *)LLADDR(ifp->if_sadl);
for (i = 0; i < ETHER_ADDR_LEN; i += 2) {
- tmp = enaddr[i + 1] << 8 | enaddr[i];
- bus_space_write_2(bst, bsh, IAR_ADDR0_REG_W + i, tmp);
+ /* Might it be little endian? */
+ tmp = sc->sc_enaddr[i] << 8 | sc->sc_enaddr[i + 1];
+ bus_space_write_2(bst, bsh,
+ sc->sc_reg_map[IAR_ADDR0_REG_W + i], tmp);
}
/*
@@ -389,21 +404,24 @@
* transmitted packets (making the best use of our limited memory)
* and enable the EPH interrupt on certain TX errors.
*/
- bus_space_write_2(bst, bsh, CONTROL_REG_W, (CTR_AUTO_RELEASE |
- CTR_TE_ENABLE | CTR_CR_ENABLE | CTR_LE_ENABLE));
+ bus_space_write_2(bst, bsh, sc->sc_reg_map[CONTROL_REG_W],
+ htole16(CTR_AUTO_RELEASE | CTR_TE_ENABLE | CTR_CR_ENABLE
+ | CTR_LE_ENABLE));
/*
* Reset the MMU and wait for it to be un-busy.
*/
SMC_SELECT_BANK(sc, 2);
- bus_space_write_2(bst, bsh, MMU_CMD_REG_W, MMUCR_RESET);
- while (bus_space_read_2(bst, bsh, MMU_CMD_REG_W) & MMUCR_BUSY)
+ bus_space_write_2(bst, bsh, sc->sc_reg_map[MMU_CMD_REG_W],
+ htole16(MMUCR_RESET));
+ while (le16toh(bus_space_read_2(bst, bsh,
+ sc->sc_reg_map[MMU_CMD_REG_W])) & MMUCR_BUSY)
/* XXX bound this loop! */ ;
/*
* Disable all interrupts.
*/
- bus_space_write_1(bst, bsh, INTR_MASK_REG_B, 0);
+ bus_space_write_1(bst, bsh, sc->sc_reg_map[INTR_MASK_REG_B], 0);
/*
* Set current media.
@@ -424,7 +442,8 @@
if (ifp->if_flags & IFF_PROMISC)
tmp |= RCR_PROMISC;
- bus_space_write_2(bst, bsh, RECV_CONTROL_REG_W, tmp);
+ bus_space_write_2(bst, bsh, sc->sc_reg_map[RECV_CONTROL_REG_W],
+ htole16(tmp));
/*
* Set transmitter control to "enabled".
@@ -439,14 +458,15 @@
tmp |= TCR_PAD_ENABLE;
#endif
- bus_space_write_2(bst, bsh, TXMIT_CONTROL_REG_W, tmp);
+ bus_space_write_2(bst, bsh, sc->sc_reg_map[TXMIT_CONTROL_REG_W],
+ htole16(tmp));
/*
* Now, enable interrupts.
*/
SMC_SELECT_BANK(sc, 2);
- bus_space_write_1(bst, bsh, INTR_MASK_REG_B,
+ bus_space_write_1(bst, bsh, sc->sc_reg_map[INTR_MASK_REG_B],
IM_EPH_INT | IM_RX_OVRN_INT | IM_RCV_INT | IM_TX_INT);
/* Interface is now running, with no output active. */
@@ -530,16 +550,19 @@
* Now allocate the memory.
*/
SMC_SELECT_BANK(sc, 2);
- bus_space_write_2(bst, bsh, MMU_CMD_REG_W, MMUCR_ALLOC | npages);
+ bus_space_write_2(bst, bsh, sc->sc_reg_map[MMU_CMD_REG_W],
+ htole16(MMUCR_ALLOC | npages));
timo = MEMORY_WAIT_TIME;
do {
- if (bus_space_read_1(bst, bsh, INTR_STAT_REG_B) & IM_ALLOC_INT)
+ if (bus_space_read_1(bst, bsh, sc->sc_reg_map[INTR_STAT_REG_B])
+ & IM_ALLOC_INT)
break;
delay(1);
} while (--timo);
- packetno = bus_space_read_1(bst, bsh, ALLOC_RESULT_REG_B);
+ packetno = bus_space_read_1(bst, bsh,
+ sc->sc_reg_map[ALLOC_RESULT_REG_B]);
if (packetno & ARR_FAILED || timo == 0) {
/*
@@ -550,8 +573,9 @@
* no one else attempts to transmit while we're allocating
* memory.
*/
- bus_space_write_1(bst, bsh, INTR_MASK_REG_B,
- bus_space_read_1(bst, bsh, INTR_MASK_REG_B) | IM_ALLOC_INT);
+ bus_space_write_1(bst, bsh, sc->sc_reg_map[INTR_MASK_REG_B],
+ bus_space_read_1(bst, bsh, sc->sc_reg_map[INTR_MASK_REG_B])
+ | IM_ALLOC_INT);
ifp->if_timer = 5;
ifp->if_flags |= IFF_OACTIVE;
@@ -562,20 +586,24 @@
/*
* We have a packet number - set the data window.
*/
- bus_space_write_1(bst, bsh, PACKET_NUM_REG_B, packetno);
+ bus_space_write_1(bst, bsh, sc->sc_reg_map[PACKET_NUM_REG_B],
+ packetno);
/*
* Point to the beginning of the packet.
*/
- bus_space_write_2(bst, bsh, POINTER_REG_W, PTR_AUTOINC /* | 0x0000 */);
+ bus_space_write_2(bst, bsh, sc->sc_reg_map[POINTER_REG_W],
+ htole16(PTR_AUTOINC /* | 0x0000 */));
/*
* Send the packet length (+6 for stats, length, and control bytes)
* and the status word (set to zeros).
*/
- bus_space_write_2(bst, bsh, DATA_REG_W, 0);
- bus_space_write_1(bst, bsh, DATA_REG_B, (length + 6) & 0xff);
- bus_space_write_1(bst, bsh, DATA_REG_B, ((length + 6) >> 8) & 0xff);
+ bus_space_write_2(bst, bsh, sc->sc_reg_map[DATA_REG_W], 0);
+ bus_space_write_1(bst, bsh, sc->sc_reg_map[DATA_REG_B],
+ (length + 6) & 0xff);
+ bus_space_write_1(bst, bsh, sc->sc_reg_map[DATA_REG_B],
+ ((length + 6) >> 8) & 0xff);
/*
* Get the packet from the kernel. This will include the Ethernet
@@ -587,14 +615,19 @@
* Push the packet out to the card.
*/
for (top = m; m != NULL; m = m->m_next) {
+#if !defined(mac68k)
/* Words... */
- bus_space_write_multi_2(bst, bsh, DATA_REG_W,
+ bus_space_write_multi_2(bst, bsh, sc->sc_reg_map[DATA_REG_W],
mtod(m, u_int16_t *), m->m_len >> 1);
/* ...and the remaining byte, if any. */
if (m->m_len & 1)
- bus_space_write_1(bst, bsh, DATA_REG_B,
+ bus_space_write_1(bst, bsh, sc->sc_reg_map[DATA_REG_B],
*(u_int8_t *)(mtod(m, u_int8_t *) + (m->m_len - 1)));
+#else /* XXX */
+ bus_space_write_multi_1(bst, bsh, sc->sc_reg_map[DATA_REG_B],
+ mtod(m, u_int8_t *), m->m_len);
+#endif
}
#ifdef SMC91CXX_SW_PAD
@@ -602,11 +635,11 @@
* Push out padding.
*/
while (pad > 1) {
- bus_space_write_2(bst, bsh, DATA_REG_W, 0);
+ bus_space_write_2(bst, bsh, sc->sc_reg_map[DATA_REG_W], 0);
pad -= 2;
}
if (pad)
- bus_space_write_1(bst, bsh, DATA_REG_B, 0);
+ bus_space_write_1(bst, bsh, sc->sc_reg_map[DATA_REG_B], 0);
#endif
/*
@@ -614,17 +647,18 @@
* is 0, meaning the packet is even lengthed and no special
* CRC handling is necessary.
*/
- bus_space_write_2(bst, bsh, DATA_REG_W, 0);
+ bus_space_write_2(bst, bsh, sc->sc_reg_map[DATA_REG_W], 0);
/*
* Enable transmit interrupts and let the chip go. Set a watchdog
* in case we miss the interrupt.
*/
- bus_space_write_1(bst, bsh, INTR_MASK_REG_B,
- bus_space_read_1(bst, bsh, INTR_MASK_REG_B) |
- IM_TX_INT | IM_TX_EMPTY_INT);
+ bus_space_write_1(bst, bsh, sc->sc_reg_map[INTR_MASK_REG_B],
+ bus_space_read_1(bst, bsh, sc->sc_reg_map[INTR_MASK_REG_B])
+ | IM_TX_INT | IM_TX_EMPTY_INT);
- bus_space_write_2(bst, bsh, MMU_CMD_REG_W, MMUCR_ENQUEUE);
+ bus_space_write_2(bst, bsh, sc->sc_reg_map[MMU_CMD_REG_W],
+ htole16(MMUCR_ENQUEUE));
ifp->if_timer = 5;
@@ -643,7 +677,8 @@
* RX FIFO. If nothing has arrived, attempt to queue another
* transmit packet.
*/
- if (bus_space_read_2(bst, bsh, FIFO_PORTS_REG_W) & FIFO_REMPTY)
+ if (bus_space_read_2(bst, bsh,
+ sc->sc_reg_map[FIFO_PORTS_REG_W]) & le16toh(FIFO_REMPTY))
goto again;
}
@@ -670,13 +705,14 @@
/*
* Obtain the current interrupt mask.
*/
- mask = bus_space_read_1(bst, bsh, INTR_MASK_REG_B);
+ mask = bus_space_read_1(bst, bsh, sc->sc_reg_map[INTR_MASK_REG_B]);
/*
* Get the set of interrupt which occurred and eliminate any
* which are not enabled.
*/
- interrupts = bus_space_read_1(bst, bsh, INTR_STAT_REG_B);
+ interrupts = bus_space_read_1(bst, bsh,
+ sc->sc_reg_map[INTR_STAT_REG_B]);
status = interrupts & mask;
/* Ours? */
@@ -686,13 +722,14 @@
/*
* It's ours; disable all interrupts while we process them.
*/
- bus_space_write_1(bst, bsh, INTR_MASK_REG_B, 0);
+ bus_space_write_1(bst, bsh, sc->sc_reg_map[INTR_MASK_REG_B], 0);
/*
* Receive overrun interrupts.
*/
if (status & IM_RX_OVRN_INT) {
- bus_space_write_1(bst, bsh, INTR_ACK_REG_B, IM_RX_OVRN_INT);
+ bus_space_write_1(bst, bsh, sc->sc_reg_map[INTR_ACK_REG_B],
+ IM_RX_OVRN_INT);
ifp->if_ierrors++;
}
@@ -701,7 +738,8 @@
*/
if (status & IM_RCV_INT) {
#if 1 /* DIAGNOSTIC */
- packetno = bus_space_read_2(bst, bsh, FIFO_PORTS_REG_W);
+ packetno = le16toh(bus_space_read_2(bst, bsh,
+ sc->sc_reg_map[FIFO_PORTS_REG_W]));
if (packetno & FIFO_REMPTY)
printf("%s: receive interrupt on empty fifo\n",
sc->sc_dev.dv_xname);
@@ -721,9 +759,11 @@
* Release the just-allocated memory. We will reallocate
* it through the normal start logic.
*/
- while (bus_space_read_2(bst, bsh, MMU_CMD_REG_W) & MMUCR_BUSY)
+ while (bus_space_read_2(bst, bsh,
+ sc->sc_reg_map[MMU_CMD_REG_W]) & le16toh(MMUCR_BUSY))
/* XXX bound this loop! */ ;
- bus_space_write_2(bst, bsh, MMU_CMD_REG_W, MMUCR_FREEPKT);
+ bus_space_write_2(bst, bsh, sc->sc_reg_map[MMU_CMD_REG_W],
+ htole16(MMUCR_FREEPKT));
ifp->if_flags &= ~IFF_OACTIVE;
ifp->if_timer = 0;
@@ -735,28 +775,31 @@
* mode.
*/
if (status & IM_TX_INT) {
- bus_space_write_1(bst, bsh, INTR_ACK_REG_B, IM_TX_INT);
+ bus_space_write_1(bst, bsh, sc->sc_reg_map[INTR_ACK_REG_B],
+ IM_TX_INT);
- packetno = bus_space_read_2(bst, bsh, FIFO_PORTS_REG_W) &
- FIFO_TX_MASK;
+ packetno = le16toh(bus_space_read_2(bst, bsh,
+ sc->sc_reg_map[FIFO_PORTS_REG_W])) & FIFO_TX_MASK;
/*
* Select this as the packet to read from.
*/
- bus_space_write_1(bst, bsh, PACKET_NUM_REG_B, packetno);
+ bus_space_write_1(bst, bsh, sc->sc_reg_map[PACKET_NUM_REG_B],
+ packetno);
/*
* Position the pointer to the beginning of the packet.
*/
- bus_space_write_2(bst, bsh, POINTER_REG_W,
- PTR_AUTOINC | PTR_READ /* | 0x0000 */);
+ bus_space_write_2(bst, bsh, sc->sc_reg_map[POINTER_REG_W],
+ htole16(PTR_AUTOINC | PTR_READ /* | 0x0000 */));
/*
* Fetch the TX status word. This will be a copy of
* the EPH_STATUS_REG_W at the time of the transmission
* failure.
*/
- tx_status = bus_space_read_2(bst, bsh, DATA_REG_W);
+ tx_status = le16toh(bus_space_read_2(bst, bsh,
+ sc->sc_reg_map[DATA_REG_W]));
if (tx_status & EPHSR_TX_SUC)
printf("%s: successful packet caused TX interrupt?!\n",
@@ -772,19 +815,23 @@
*/
SMC_SELECT_BANK(sc, 0);
#ifdef SMC91CXX_SW_PAD
- bus_space_write_2(bst, bsh, TXMIT_CONTROL_REG_W, TCR_ENABLE);
+ bus_space_write_2(bst, bsh,
+ sc->sc_reg_map[TXMIT_CONTROL_REG_W], htole16(TCR_ENABLE));
#else
- bus_space_write_2(bst, bsh, TXMIT_CONTROL_REG_W,
- TCR_ENABLE | TCR_PAD_ENABLE);
+ bus_space_write_2(bst, bsh,
+ sc->sc_reg_map[TXMIT_CONTROL_REG_W],
+ htole16(TCR_ENABLE | TCR_PAD_ENABLE));
#endif
/*
* Kill the failed packet and wait for the MMU to unbusy.
*/
SMC_SELECT_BANK(sc, 2);
- while (bus_space_read_2(bst, bsh, MMU_CMD_REG_W) & MMUCR_BUSY)
+ while (bus_space_read_2(bst, bsh,
+ sc->sc_reg_map[MMU_CMD_REG_W]) & le16toh(MMUCR_BUSY))
/* XXX bound this loop! */ ;
- bus_space_write_2(bst, bsh, MMU_CMD_REG_W, MMUCR_FREEPKT);
+ bus_space_write_2(bst, bsh, sc->sc_reg_map[MMU_CMD_REG_W],
+ htole16(MMUCR_FREEPKT));
ifp->if_timer = 0;
}
@@ -794,13 +841,15 @@
* update transmit statistics from the card.
*/
if (status & IM_TX_EMPTY_INT) {
- bus_space_write_1(bst, bsh, INTR_ACK_REG_B, IM_TX_EMPTY_INT);
+ bus_space_write_1(bst, bsh, sc->sc_reg_map[INTR_ACK_REG_B],
+ IM_TX_EMPTY_INT);
/* Disable this interrupt. */
mask &= ~IM_TX_EMPTY_INT;
SMC_SELECT_BANK(sc, 0);
- card_stats = bus_space_read_2(bst, bsh, COUNTER_REG_W);
+ card_stats = le16toh(bus_space_read_2(bst, bsh,
+ sc->sc_reg_map[COUNTER_REG_W]));
/* Single collisions. */
ifp->if_collisions += card_stats & ECR_COLN_MASK;
@@ -830,8 +879,8 @@
* Reenable the interrupts we wish to receive now that processing
* is complete.
*/
- mask |= bus_space_read_1(bst, bsh, INTR_MASK_REG_B);
- bus_space_write_1(bst, bsh, INTR_MASK_REG_B, mask);
+ mask |= bus_space_read_1(bst, bsh, sc->sc_reg_map[INTR_MASK_REG_B]);
+ bus_space_write_1(bst, bsh, sc->sc_reg_map[INTR_MASK_REG_B], mask);
#if NRND > 0
if (status)
@@ -863,14 +912,16 @@
* PTR_RCV is set, the packet number will be found automatically
* in FIFO_PORTS_REG_W, FIFO_RX_MASK.
*/
- bus_space_write_2(bst, bsh, POINTER_REG_W,
- PTR_READ | PTR_RCV | PTR_AUTOINC /* | 0x0000 */);
+ bus_space_write_2(bst, bsh, sc->sc_reg_map[POINTER_REG_W],
+ htole16(PTR_READ | PTR_RCV | PTR_AUTOINC /* | 0x0000 */));
/*
* First two words are status and packet length.
*/
- status = bus_space_read_2(bst, bsh, DATA_REG_W);
- packetlen = bus_space_read_2(bst, bsh, DATA_REG_W);
+ status = le16toh(bus_space_read_2(bst, bsh,
+ sc->sc_reg_map[DATA_REG_W]));
+ packetlen = le16toh(bus_space_read_2(bst, bsh,
+ sc->sc_reg_map[DATA_REG_W]));
/*
* The packet length includes 3 extra words: status, length,
@@ -896,8 +947,9 @@
* Allocate a header mbuf.
*/
MGETHDR(m, M_DONTWAIT, MT_DATA);
- if (m == NULL)
+ if (m == NULL) {
goto out;
+ }
m->m_pkthdr.rcvif = ifp;
m->m_pkthdr.len = m->m_len = packetlen;
@@ -920,12 +972,17 @@
*/
eh = mtod(m, struct ether_header *);
data = mtod(m, u_int8_t *);
- bus_space_read_multi_2(bst, bsh, DATA_REG_W, (u_int16_t *)data,
- packetlen >> 1);
+#if !defined(mac68k)
+ bus_space_read_multi_2(bst, bsh, sc->sc_reg_map[DATA_REG_W],
+ (u_int16_t *)data, packetlen >> 1);
if (packetlen & 1) {
data += packetlen & ~1;
- *data = bus_space_read_1(bst, bsh, DATA_REG_B);
+ *data = bus_space_read_1(bst, bsh, sc->sc_reg_map[DATA_REG_B]);
}
+#else /* XXX */
+ bus_space_read_multi_1(bst, bsh, sc->sc_reg_map[DATA_REG_B], data,
+ packetlen);
+#endif
ifp->if_ipackets++;
@@ -969,14 +1026,17 @@
/*
* Tell the card to free the memory occupied by this packet.
*/
- while (bus_space_read_2(bst, bsh, MMU_CMD_REG_W) & MMUCR_BUSY)
+ while (bus_space_read_2(bst, bsh,
+ sc->sc_reg_map[MMU_CMD_REG_W]) & le16toh(MMUCR_BUSY))
/* XXX bound this loop! */ ;
- bus_space_write_2(bst, bsh, MMU_CMD_REG_W, MMUCR_RELEASE);
+ bus_space_write_2(bst, bsh, sc->sc_reg_map[MMU_CMD_REG_W],
+ htole16(MMUCR_RELEASE));
/*
* Check for another packet.
*/
- packetno = bus_space_read_2(bst, bsh, FIFO_PORTS_REG_W);
+ packetno = le16toh(bus_space_read_2(bst, bsh,
+ sc->sc_reg_map[FIFO_PORTS_REG_W]));
if (packetno & FIFO_REMPTY)
return;
goto again;
@@ -1155,14 +1215,14 @@
* Clear interrupt mask; disable all interrupts.
*/
SMC_SELECT_BANK(sc, 2);
- bus_space_write_1(bst, bsh, INTR_MASK_REG_B, 0);
+ bus_space_write_1(bst, bsh, sc->sc_reg_map[INTR_MASK_REG_B], 0);
/*
* Disable transmitter and receiver.
*/
SMC_SELECT_BANK(sc, 0);
- bus_space_write_2(bst, bsh, RECV_CONTROL_REG_W, 0);
- bus_space_write_2(bst, bsh, TXMIT_CONTROL_REG_W, 0);
+ bus_space_write_2(bst, bsh, sc->sc_reg_map[RECV_CONTROL_REG_W], 0);
+ bus_space_write_2(bst, bsh, sc->sc_reg_map[TXMIT_CONTROL_REG_W], 0);
/*
* Cancel watchdog timer.
Index: dev/ic/smc91cxxvar.h
===================================================================
RCS file: /a/rsync/netbsd.org/syssrc/sys/dev/ic/smc91cxxvar.h,v
retrieving revision 1.7
diff -u -r1.7 smc91cxxvar.h
--- smc91cxxvar.h 2000/02/02 16:04:42 1.7
+++ smc91cxxvar.h 2000/02/03 18:18:07
@@ -37,6 +37,7 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
+#include <sys/endian.h>
#include "rnd.h"
#if NRND > 0
@@ -52,6 +53,11 @@
struct ifmedia sc_media; /* our media info */
+ u_int8_t sc_reg_map[SMC_IOSIZE]; /* register map (offsets) */
+
+ u_int8_t sc_enaddr[ETHER_ADDR_LEN]; /* MAC address */
+ int sc_enaddr_from_rom; /* MAC address can be taken from ROM */
+
/* Power management hooks and state. */
int (*sc_enable) __P((struct smc91cxx_softc *));
void (*sc_disable) __P((struct smc91cxx_softc *));
@@ -62,11 +68,16 @@
#endif
};
-#define SMC_SELECT_BANK(sc, x) \
+#define SMC_SELECT_BANK(sc, x) \
bus_space_write_2((sc)->sc_bst, (sc)->sc_bsh, \
- BANK_SELECT_REG_W, (x))
+ (sc)->sc_reg_map[BANK_SELECT_REG_W], htole16(x))
+/*
+ * Vendor types
+ */
+#define SMC91CXX_VENDOR_UNKNOWN 0xff /* unknown */
+#define SMC91CXX_VENDOR_API 0x00 /* API Engineering, Newer Technology */
-void smc91cxx_attach __P((struct smc91cxx_softc *, u_int8_t *));
+void smc91cxx_attach __P((struct smc91cxx_softc *));
int smc91cxx_intr __P((void *));
int smc91cxx_enable __P((struct smc91cxx_softc *));
void smc91cxx_disable __P((struct smc91cxx_softc *));
Index: dev/isa/if_sm_isa.c
===================================================================
RCS file: /a/rsync/netbsd.org/syssrc/sys/dev/isa/if_sm_isa.c,v
retrieving revision 1.4
diff -u -r1.4 if_sm_isa.c
--- if_sm_isa.c 1998/07/05 06:49:14 1.4
+++ if_sm_isa.c 1999/11/06 09:11:17
@@ -1,4 +1,4 @@
-/* $NetBSD: if_sm_isa.c,v 1.3 1998/07/05 00:51:22 jonathan Exp $ */
+/* $NetBSD: if_sm_isa.c,v 1.4 1998/07/05 06:49:14 jonathan Exp $ */
/*-
* Copyright (c) 1997 The NetBSD Foundation, Inc.
@@ -182,13 +182,19 @@
sc->sc_bst = iot;
sc->sc_bsh = ioh;
+ /* registers are linear. */
+ for (i = 0; i < SMC_IOSIZE; i++) {
+ sc->sc_reg_map[i] = i;
+ }
+
/* should always be enabled */
sc->sc_enabled = 1;
/* XXX Should get Ethernet address from EEPROM!! */
+ sc->sc_enaddr_from_rom = 0;
/* Perform generic intialization. */
- smc91cxx_attach(sc, NULL);
+ smc91cxx_attach(sc);
/* Establish the interrupt handler. */
isc->sc_ih = isa_intr_establish(ia->ia_ic, ia->ia_irq, IST_EDGE,
Index: dev/pcmcia/if_sm_pcmcia.c
===================================================================
RCS file: /a/rsync/netbsd.org/syssrc/sys/dev/pcmcia/if_sm_pcmcia.c,v
retrieving revision 1.21
diff -u -r1.21 if_sm_pcmcia.c
--- if_sm_pcmcia.c 2000/02/09 13:40:42 1.21
+++ if_sm_pcmcia.c 2000/02/12 01:43:19
@@ -155,6 +155,11 @@
psc->sc_pf = pa->pf;
cfe = pa->pf->cfe_head.sqh_first;
+ /* registers are linear. */
+ for (i = 0; i < SMC_IOSIZE; i++) {
+ sc->sc_reg_map[i] = i;
+ }
+
/* Enable the card. */
pcmcia_function_init(pa->pf, cfe);
if (pcmcia_function_enable(pa->pf)) {
@@ -190,6 +195,7 @@
panic("sm_pcmcia_attach: impossible");
printf(": %s\n", pp->pp_name);
+ sc->sc_enaddr_from_rom = 0;
/*
* First try to get the Ethernet address from FUNCE/LANNID tuple.
@@ -218,12 +224,18 @@
enaddr = myla;
}
- if (enaddr == NULL)
+ if (enaddr) {
+ for (i = 0; i < ETHER_ADDL_LEN; i++) {
+ sc->sc_enaddr[i] = *(enaddr + i);
+ }
+ sc->sc_enaddr_from_rom = 1;
+ } else {
printf("%s: unable to get Ethernet address\n",
sc->sc_dev.dv_xname);
+ }
/* Perform generic intialization. */
- smc91cxx_attach(sc, enaddr);
+ smc91cxx_attach(sc);
pcmcia_function_disable(pa->pf);
return;
Index: dev/pcmcia/mhzc.c
===================================================================
RCS file: /a/rsync/netbsd.org/syssrc/sys/dev/pcmcia/mhzc.c,v
retrieving revision 1.5
diff -u -r1.5 mhzc.c
--- mhzc.c 2000/02/05 04:44:00 1.5
+++ mhzc.c 2000/02/16 10:39:26
@@ -202,6 +202,10 @@
sc->sc_pf = pa->pf;
+ /* registers are linear. */
+ for (i = 0; i < SMC_IOSIZE; i++) {
+ sc->sc_reg_map[i] = i;
+ }
sc->sc_product = (const struct mhzc_product *)pcmcia_product_lookup(pa,
(const struct pcmcia_product *)mhzc_products,
sizeof mhzc_products[0], NULL);
@@ -515,17 +519,16 @@
*****************************************************************************/
int mhzc_em3336_lannid_ciscallback __P((struct pcmcia_tuple *, void *));
-int mhzc_em3336_ascii_enaddr __P((const char *cisstr, u_int8_t *));
+int mhzc_em3336_ascii_enaddr __P((const char *cisstr));
int
-mhzc_em3336_enaddr(sc, myla)
+mhzc_em3336_enaddr(sc)
struct mhzc_softc *sc;
- u_int8_t *myla;
{
/* Get the station address from CIS tuple 0x81. */
if (pcmcia_scan_cis(sc->sc_dev.dv_parent,
- mhzc_em3336_lannid_ciscallback, myla) != 1) {
+ mhzc_em3336_lannid_ciscallback, sc->sc_enaddr) != 1) {
printf("%s: unable to get Ethernet address from CIS\n",
sc->sc_dev.dv_xname);
return (0);
@@ -591,11 +594,10 @@
}
int
-mhzc_em3336_lannid_ciscallback(tuple, arg)
+mhzc_em3336_lannid_ciscallback(tuple)
struct pcmcia_tuple *tuple;
- void *arg;
{
- u_int8_t *myla = arg, addr_str[ETHER_ADDR_LEN * 2];
+ u_int8_t *addr_str[ETHER_ADDR_LEN * 2];
int i;
if (tuple->code == 0x81) {
@@ -610,9 +612,9 @@
addr_str[i] = pcmcia_tuple_read_1(tuple, i);
/*
- * Decode the string into `myla'.
+ * Decode the string into sc->sc_enaddr.
*/
- return (mhzc_em3336_ascii_enaddr(addr_str, myla));
+ return (mhzc_em3336_ascii_enaddr(addr_str, sc->sc_enaddr));
}
return (0);
}
@@ -775,7 +777,6 @@
{
struct smc91cxx_softc *sc = (void *)self;
struct mhzc_softc *msc = (void *)parent;
- u_int8_t myla[ETHER_ADDR_LEN];
printf(":");
if (pcmcia_io_map(msc->sc_pf, PCMCIA_WIDTH_IO16, 0,
@@ -794,11 +795,13 @@
sc->sc_enable = sm_mhzc_enable;
sc->sc_disable = sm_mhzc_disable;
- if ((*msc->sc_product->mp_enaddr)(msc, myla) != 1)
+ if ((*msc->sc_product->mp_enaddr)(msc, sc->sc_enaddr) != 1)
return;
+ sc->sc_enaddr_from_rom = 1;
+
/* Perform generic initialization. */
- smc91cxx_attach(sc, myla);
+ smc91cxx_attach(sc);
}
int