Convert to bus_space.

Make the pccard attachment work with NEWCARD
Start locking of the driver, but only the macros are defined right now

Tested on: Megahertz CC10BT/2
# (These cards are very popular on ebay these days, and run < $10 including
#  shipping from some sellers).
This commit is contained in:
Warner Losh 2003-10-25 19:56:19 +00:00
parent 2a063d30f6
commit 470de03fd0
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=121514
4 changed files with 205 additions and 143 deletions

View File

@ -172,15 +172,15 @@ sn_attach(device_t dev)
sc->dev = dev;
sc->pages_wanted = -1;
device_printf(dev, " ");
SMC_SELECT_BANK(sc, 3);
rev = (CSR_READ_2(sc, REVISION_REG_W) >> 4) & 0xf;
if (chip_ids[rev])
device_printf(dev, " %s ", chip_ids[rev]);
else
device_printf(dev, "support for this chip hasn't been integrated\n");
SMC_SELECT_BANK(3);
rev = inw(BASE + REVISION_REG_W);
if (chip_ids[(rev >> 4) & 0xF])
printf("%s ", chip_ids[(rev >> 4) & 0xF]);
SMC_SELECT_BANK(1);
i = inw(BASE + CONFIG_REG_W);
SMC_SELECT_BANK(sc, 1);
i = CSR_READ_2(sc, CONFIG_REG_W);
printf(i & CR_AUI_SELECT ? "AUI" : "UTP");
if (sc->pccard_enaddr)
@ -189,17 +189,17 @@ sn_attach(device_t dev)
w = (u_short)sc->arpcom.ac_enaddr[j * 2] |
(((u_short)sc->arpcom.ac_enaddr[j * 2 + 1]) << 8);
outw(BASE + IAR_ADDR0_REG_W + j * 2, w);
CSR_WRITE_2(sc, IAR_ADDR0_REG_W + j * 2, w);
}
/*
* Read the station address from the chip. The MAC address is bank 1,
* regs 4 - 9
*/
SMC_SELECT_BANK(1);
SMC_SELECT_BANK(sc, 1);
p = (u_char *) & sc->arpcom.ac_enaddr;
for (i = 0; i < 6; i += 2) {
address = inw(BASE + IAR_ADDR0_REG_W + i);
address = CSR_READ_2(sc, IAR_ADDR0_REG_W + i);
p[i + 1] = address >> 8;
p[i] = address & 0xFF;
}
@ -271,41 +271,41 @@ sninit(void *xsc)
* EEPROM. After the reset cycle, we pause briefly for the chip to
* be happy.
*/
SMC_SELECT_BANK(0);
outw(BASE + RECV_CONTROL_REG_W, RCR_SOFTRESET);
SMC_DELAY();
outw(BASE + RECV_CONTROL_REG_W, 0x0000);
SMC_DELAY();
SMC_DELAY();
SMC_SELECT_BANK(sc, 0);
CSR_WRITE_2(sc, RECV_CONTROL_REG_W, RCR_SOFTRESET);
SMC_DELAY(sc);
CSR_WRITE_2(sc, RECV_CONTROL_REG_W, 0x0000);
SMC_DELAY(sc);
SMC_DELAY(sc);
outw(BASE + TXMIT_CONTROL_REG_W, 0x0000);
CSR_WRITE_2(sc, TXMIT_CONTROL_REG_W, 0x0000);
/*
* Set the control register to automatically release succesfully
* transmitted packets (making the best use out of our limited
* memory) and to enable the EPH interrupt on certain TX errors.
*/
SMC_SELECT_BANK(1);
outw(BASE + CONTROL_REG_W, (CTR_AUTO_RELEASE | CTR_TE_ENABLE |
SMC_SELECT_BANK(sc, 1);
CSR_WRITE_2(sc, CONTROL_REG_W, (CTR_AUTO_RELEASE | CTR_TE_ENABLE |
CTR_CR_ENABLE | CTR_LE_ENABLE));
/* Set squelch level to 240mV (default 480mV) */
flags = inw(BASE + CONFIG_REG_W);
flags = CSR_READ_2(sc, CONFIG_REG_W);
flags |= CR_SET_SQLCH;
outw(BASE + CONFIG_REG_W, flags);
CSR_WRITE_2(sc, CONFIG_REG_W, flags);
/*
* Reset the MMU and wait for it to be un-busy.
*/
SMC_SELECT_BANK(2);
outw(BASE + MMU_CMD_REG_W, MMUCR_RESET);
while (inw(BASE + MMU_CMD_REG_W) & MMUCR_BUSY) /* NOTHING */
SMC_SELECT_BANK(sc, 2);
CSR_WRITE_2(sc, MMU_CMD_REG_W, MMUCR_RESET);
while (CSR_READ_2(sc, MMU_CMD_REG_W) & MMUCR_BUSY) /* NOTHING */
;
/*
* Disable all interrupts
*/
outb(BASE + INTR_MASK_REG_B, 0x00);
CSR_WRITE_1(sc, INTR_MASK_REG_B, 0x00);
sn_setmcast(sc);
@ -321,20 +321,20 @@ sninit(void *xsc)
flags |= TCR_PAD_ENABLE;
#endif /* SW_PAD */
outw(BASE + TXMIT_CONTROL_REG_W, flags);
CSR_WRITE_2(sc, TXMIT_CONTROL_REG_W, flags);
/*
* Now, enable interrupts
*/
SMC_SELECT_BANK(2);
SMC_SELECT_BANK(sc, 2);
mask = IM_EPH_INT |
IM_RX_OVRN_INT |
IM_RCV_INT |
IM_TX_INT;
outb(BASE + INTR_MASK_REG_B, mask);
CSR_WRITE_1(sc, INTR_MASK_REG_B, mask);
sc->intr_mask = mask;
sc->pages_wanted = -1;
@ -434,8 +434,8 @@ snstart(struct ifnet *ifp)
/*
* Now, try to allocate the memory
*/
SMC_SELECT_BANK(2);
outw(BASE + MMU_CMD_REG_W, MMUCR_ALLOC | numPages);
SMC_SELECT_BANK(sc, 2);
CSR_WRITE_2(sc, MMU_CMD_REG_W, MMUCR_ALLOC | numPages);
/*
* Wait a short amount of time to see if the allocation request
@ -445,7 +445,7 @@ snstart(struct ifnet *ifp)
time_out = MEMORY_WAIT_TIME;
do {
if (inb(BASE + INTR_STAT_REG_B) & IM_ALLOC_INT)
if (CSR_READ_1(sc, INTR_STAT_REG_B) & IM_ALLOC_INT)
break;
} while (--time_out);
@ -459,8 +459,8 @@ snstart(struct ifnet *ifp)
* interface active since there is no point in attempting an
* snstart() until after the memory is available.
*/
mask = inb(BASE + INTR_MASK_REG_B) | IM_ALLOC_INT;
outb(BASE + INTR_MASK_REG_B, mask);
mask = CSR_READ_1(sc, INTR_MASK_REG_B) | IM_ALLOC_INT;
CSR_WRITE_1(sc, INTR_MASK_REG_B, mask);
sc->intr_mask = mask;
sc->arpcom.ac_if.if_timer = 1;
@ -473,7 +473,7 @@ snstart(struct ifnet *ifp)
/*
* The memory allocation completed. Check the results.
*/
packet_no = inb(BASE + ALLOC_RESULT_REG_B);
packet_no = CSR_READ_1(sc, ALLOC_RESULT_REG_B);
if (packet_no & ARR_FAILED) {
if (junk++ > 10)
if_printf(ifp, "Memory allocation failed\n");
@ -482,20 +482,20 @@ snstart(struct ifnet *ifp)
/*
* We have a packet number, so tell the card to use it.
*/
outb(BASE + PACKET_NUM_REG_B, packet_no);
CSR_WRITE_1(sc, PACKET_NUM_REG_B, packet_no);
/*
* Point to the beginning of the packet
*/
outw(BASE + POINTER_REG_W, PTR_AUTOINC | 0x0000);
CSR_WRITE_2(sc, POINTER_REG_W, PTR_AUTOINC | 0x0000);
/*
* Send the packet length (+6 for status, length and control byte)
* and the status word (set to zeros)
*/
outw(BASE + DATA_REG_W, 0);
outb(BASE + DATA_REG_B, (length + 6) & 0xFF);
outb(BASE + DATA_REG_B, (length + 6) >> 8);
CSR_WRITE_2(sc, DATA_REG_W, 0);
CSR_WRITE_1(sc, DATA_REG_B, (length + 6) & 0xFF);
CSR_WRITE_1(sc, DATA_REG_B, (length + 6) >> 8);
/*
* Get the packet from the kernel. This will include the Ethernet
@ -511,41 +511,43 @@ snstart(struct ifnet *ifp)
/*
* Push out words.
*/
outsw(BASE + DATA_REG_W, mtod(m, caddr_t), m->m_len / 2);
CSR_WRITE_MULTI_2(sc, DATA_REG_W, mtod(m, uint16_t *),
m->m_len / 2);
/*
* Push out remaining byte.
*/
if (m->m_len & 1)
outb(BASE + DATA_REG_B, *(mtod(m, caddr_t) + m->m_len - 1));
CSR_WRITE_1(sc, DATA_REG_B,
*(mtod(m, caddr_t) + m->m_len - 1));
}
/*
* Push out padding.
*/
while (pad > 1) {
outw(BASE + DATA_REG_W, 0);
CSR_WRITE_2(sc, DATA_REG_W, 0);
pad -= 2;
}
if (pad)
outb(BASE + DATA_REG_B, 0);
CSR_WRITE_1(sc, DATA_REG_B, 0);
/*
* Push out control byte and unused packet byte The control byte is 0
* meaning the packet is even lengthed and no special CRC handling is
* desired.
*/
outw(BASE + DATA_REG_W, 0);
CSR_WRITE_2(sc, DATA_REG_W, 0);
/*
* Enable the interrupts and let the chipset deal with it Also set a
* watchdog in case we miss the interrupt.
*/
mask = inb(BASE + INTR_MASK_REG_B) | (IM_TX_INT | IM_TX_EMPTY_INT);
outb(BASE + INTR_MASK_REG_B, mask);
mask = CSR_READ_1(sc, INTR_MASK_REG_B) | (IM_TX_INT | IM_TX_EMPTY_INT);
CSR_WRITE_1(sc, INTR_MASK_REG_B, mask);
sc->intr_mask = mask;
outw(BASE + MMU_CMD_REG_W, MMUCR_ENQUEUE);
CSR_WRITE_2(sc, MMU_CMD_REG_W, MMUCR_ENQUEUE);
sc->arpcom.ac_if.if_flags |= IFF_OACTIVE;
sc->arpcom.ac_if.if_timer = 1;
@ -563,7 +565,7 @@ snstart(struct ifnet *ifp)
* RX FIFO. If nothing has arrived then attempt to queue another
* transmit packet.
*/
if (inw(BASE + FIFO_PORTS_REG_W) & FIFO_REMPTY)
if (CSR_READ_2(sc, FIFO_PORTS_REG_W) & FIFO_REMPTY)
goto startagain;
splx(s);
@ -650,13 +652,13 @@ snresume(struct ifnet *ifp)
numPages = (length + 6) >> 8;
SMC_SELECT_BANK(2);
SMC_SELECT_BANK(sc, 2);
/*
* The memory allocation completed. Check the results. If it failed,
* we simply set a watchdog timer and hope for the best.
*/
packet_no = inb(BASE + ALLOC_RESULT_REG_B);
packet_no = CSR_READ_1(sc, ALLOC_RESULT_REG_B);
if (packet_no & ARR_FAILED) {
if_printf(ifp, "Memory allocation failed. Weird.\n");
sc->arpcom.ac_if.if_timer = 1;
@ -665,7 +667,7 @@ snresume(struct ifnet *ifp)
/*
* We have a packet number, so tell the card to use it.
*/
outb(BASE + PACKET_NUM_REG_B, packet_no);
CSR_WRITE_1(sc, PACKET_NUM_REG_B, packet_no);
/*
* Now, numPages should match the pages_wanted recorded when the
@ -677,24 +679,24 @@ snresume(struct ifnet *ifp)
* If the allocation was the wrong size we simply release the
* memory once it is granted. Wait for the MMU to be un-busy.
*/
while (inw(BASE + MMU_CMD_REG_W) & MMUCR_BUSY) /* NOTHING */
while (CSR_READ_2(sc, MMU_CMD_REG_W) & MMUCR_BUSY) /* NOTHING */
;
outw(BASE + MMU_CMD_REG_W, MMUCR_FREEPKT);
CSR_WRITE_2(sc, MMU_CMD_REG_W, MMUCR_FREEPKT);
return;
}
/*
* Point to the beginning of the packet
*/
outw(BASE + POINTER_REG_W, PTR_AUTOINC | 0x0000);
CSR_WRITE_2(sc, POINTER_REG_W, PTR_AUTOINC | 0x0000);
/*
* Send the packet length (+6 for status, length and control byte)
* and the status word (set to zeros)
*/
outw(BASE + DATA_REG_W, 0);
outb(BASE + DATA_REG_B, (length + 6) & 0xFF);
outb(BASE + DATA_REG_B, (length + 6) >> 8);
CSR_WRITE_2(sc, DATA_REG_W, 0);
CSR_WRITE_1(sc, DATA_REG_B, (length + 6) & 0xFF);
CSR_WRITE_1(sc, DATA_REG_B, (length + 6) >> 8);
/*
* Get the packet from the kernel. This will include the Ethernet
@ -710,40 +712,41 @@ snresume(struct ifnet *ifp)
/*
* Push out words.
*/
outsw(BASE + DATA_REG_W, mtod(m, caddr_t), m->m_len / 2);
CSR_WRITE_MULTI_2(sc, DATA_REG_W, mtod(m, uint16_t *),
m->m_len / 2);
/*
* Push out remaining byte.
*/
if (m->m_len & 1)
outb(BASE + DATA_REG_B, *(mtod(m, caddr_t) + m->m_len - 1));
CSR_WRITE_1(sc, DATA_REG_B,
*(mtod(m, caddr_t) + m->m_len - 1));
}
/*
* Push out padding.
*/
while (pad > 1) {
outw(BASE + DATA_REG_W, 0);
CSR_WRITE_2(sc, DATA_REG_W, 0);
pad -= 2;
}
if (pad)
outb(BASE + DATA_REG_B, 0);
CSR_WRITE_1(sc, DATA_REG_B, 0);
/*
* Push out control byte and unused packet byte The control byte is 0
* meaning the packet is even lengthed and no special CRC handling is
* desired.
*/
outw(BASE + DATA_REG_W, 0);
CSR_WRITE_2(sc, DATA_REG_W, 0);
/*
* Enable the interrupts and let the chipset deal with it Also set a
* watchdog in case we miss the interrupt.
*/
mask = inb(BASE + INTR_MASK_REG_B) | (IM_TX_INT | IM_TX_EMPTY_INT);
outb(BASE + INTR_MASK_REG_B, mask);
mask = CSR_READ_1(sc, INTR_MASK_REG_B) | (IM_TX_INT | IM_TX_EMPTY_INT);
CSR_WRITE_1(sc, INTR_MASK_REG_B, mask);
sc->intr_mask = mask;
outw(BASE + MMU_CMD_REG_W, MMUCR_ENQUEUE);
CSR_WRITE_2(sc, MMU_CMD_REG_W, MMUCR_ENQUEUE);
BPF_MTAP(ifp, top);
@ -795,20 +798,20 @@ sn_intr(void *arg)
*/
ifp->if_timer = 0;
SMC_SELECT_BANK(2);
SMC_SELECT_BANK(sc, 2);
/*
* Obtain the current interrupt mask and clear the hardware mask
* while servicing interrupts.
*/
mask = inb(BASE + INTR_MASK_REG_B);
outb(BASE + INTR_MASK_REG_B, 0x00);
mask = CSR_READ_1(sc, INTR_MASK_REG_B);
CSR_WRITE_1(sc, INTR_MASK_REG_B, 0x00);
/*
* Get the set of interrupts which occurred and eliminate any which
* are masked.
*/
interrupts = inb(BASE + INTR_STAT_REG_B);
interrupts = CSR_READ_1(sc, INTR_STAT_REG_B);
status = interrupts & mask;
/*
@ -822,8 +825,8 @@ sn_intr(void *arg)
/*
* Acknowlege Interrupt
*/
SMC_SELECT_BANK(2);
outb(BASE + INTR_ACK_REG_B, IM_RX_OVRN_INT);
SMC_SELECT_BANK(sc, 2);
CSR_WRITE_1(sc, INTR_ACK_REG_B, IM_RX_OVRN_INT);
++sc->arpcom.ac_if.if_ierrors;
}
@ -833,8 +836,8 @@ sn_intr(void *arg)
if (status & IM_RCV_INT) {
int packet_number;
SMC_SELECT_BANK(2);
packet_number = inw(BASE + FIFO_PORTS_REG_W);
SMC_SELECT_BANK(sc, 2);
packet_number = CSR_READ_2(sc, FIFO_PORTS_REG_W);
if (packet_number & FIFO_REMPTY) {
/*
@ -864,28 +867,28 @@ sn_intr(void *arg)
/*
* Acknowlege Interrupt
*/
SMC_SELECT_BANK(2);
outb(BASE + INTR_ACK_REG_B, IM_TX_INT);
SMC_SELECT_BANK(sc, 2);
CSR_WRITE_1(sc, INTR_ACK_REG_B, IM_TX_INT);
packet_no = inw(BASE + FIFO_PORTS_REG_W);
packet_no = CSR_READ_2(sc, FIFO_PORTS_REG_W);
packet_no &= FIFO_TX_MASK;
/*
* select this as the packet to read from
*/
outb(BASE + PACKET_NUM_REG_B, packet_no);
CSR_WRITE_1(sc, PACKET_NUM_REG_B, packet_no);
/*
* Position the pointer to the first word from this packet
*/
outw(BASE + POINTER_REG_W, PTR_AUTOINC | PTR_READ | 0x0000);
CSR_WRITE_2(sc, POINTER_REG_W, PTR_AUTOINC | PTR_READ | 0x0000);
/*
* Fetch the TX status word. The value found here will be a
* copy of the EPH_STATUS_REG_W at the time the transmit
* failed.
*/
tx_status = inw(BASE + DATA_REG_W);
tx_status = CSR_READ_2(sc, DATA_REG_W);
if (tx_status & EPHSR_TX_SUC) {
device_printf(sc->dev,
@ -901,21 +904,21 @@ sn_intr(void *arg)
* Some of these errors will have disabled transmit.
* Re-enable transmit now.
*/
SMC_SELECT_BANK(0);
SMC_SELECT_BANK(sc, 0);
#ifdef SW_PAD
outw(BASE + TXMIT_CONTROL_REG_W, TCR_ENABLE);
CSR_WRITE_2(sc, TXMIT_CONTROL_REG_W, TCR_ENABLE);
#else
outw(BASE + TXMIT_CONTROL_REG_W, TCR_ENABLE | TCR_PAD_ENABLE);
CSR_WRITE_2(sc, TXMIT_CONTROL_REG_W, TCR_ENABLE | TCR_PAD_ENABLE);
#endif /* SW_PAD */
/*
* kill the failed packet. Wait for the MMU to be un-busy.
*/
SMC_SELECT_BANK(2);
while (inw(BASE + MMU_CMD_REG_W) & MMUCR_BUSY) /* NOTHING */
SMC_SELECT_BANK(sc, 2);
while (CSR_READ_2(sc, MMU_CMD_REG_W) & MMUCR_BUSY) /* NOTHING */
;
outw(BASE + MMU_CMD_REG_W, MMUCR_FREEPKT);
CSR_WRITE_2(sc, MMU_CMD_REG_W, MMUCR_FREEPKT);
/*
* Attempt to queue more transmits.
@ -932,16 +935,16 @@ sn_intr(void *arg)
/*
* Acknowlege Interrupt
*/
SMC_SELECT_BANK(2);
outb(BASE + INTR_ACK_REG_B, IM_TX_EMPTY_INT);
SMC_SELECT_BANK(sc, 2);
CSR_WRITE_1(sc, INTR_ACK_REG_B, IM_TX_EMPTY_INT);
/*
* Disable this interrupt.
*/
mask &= ~IM_TX_EMPTY_INT;
SMC_SELECT_BANK(0);
card_stats = inw(BASE + COUNTER_REG_W);
SMC_SELECT_BANK(sc, 0);
card_stats = CSR_READ_2(sc, COUNTER_REG_W);
/*
* Single collisions
@ -953,7 +956,7 @@ sn_intr(void *arg)
*/
sc->arpcom.ac_if.if_collisions += (card_stats & ECR_MCOLN_MASK) >> 4;
SMC_SELECT_BANK(2);
SMC_SELECT_BANK(sc, 2);
/*
* Attempt to enqueue some more stuff.
@ -974,7 +977,7 @@ sn_intr(void *arg)
* Handled all interrupt sources.
*/
SMC_SELECT_BANK(2);
SMC_SELECT_BANK(sc, 2);
/*
* Reestablish interrupts from mask which have not been deselected
@ -983,8 +986,8 @@ sn_intr(void *arg)
* updated by one or more of the interrupt handers and we must let
* those new interrupts stay enabled here.
*/
mask |= inb(BASE + INTR_MASK_REG_B);
outb(BASE + INTR_MASK_REG_B, mask);
mask |= CSR_READ_1(sc, INTR_MASK_REG_B);
CSR_WRITE_1(sc, INTR_MASK_REG_B, mask);
sc->intr_mask = mask;
splx(x);
@ -1001,9 +1004,9 @@ snread(register struct ifnet *ifp)
u_short packet_length;
u_char *data;
SMC_SELECT_BANK(2);
SMC_SELECT_BANK(sc, 2);
#if 0
packet_number = inw(BASE + FIFO_PORTS_REG_W);
packet_number = CSR_READ_2(sc, FIFO_PORTS_REG_W);
if (packet_number & FIFO_REMPTY) {
@ -1020,13 +1023,13 @@ snread(register struct ifnet *ifp)
* Start reading from the start of the packet. Since PTR_RCV is set,
* packet number is found in FIFO_PORTS_REG_W, FIFO_RX_MASK.
*/
outw(BASE + POINTER_REG_W, PTR_READ | PTR_RCV | PTR_AUTOINC | 0x0000);
CSR_WRITE_2(sc, POINTER_REG_W, PTR_READ | PTR_RCV | PTR_AUTOINC | 0x0000);
/*
* First two words are status and packet_length
*/
status = inw(BASE + DATA_REG_W);
packet_length = inw(BASE + DATA_REG_W) & RLEN_MASK;
status = CSR_READ_2(sc, DATA_REG_W);
packet_length = CSR_READ_2(sc, DATA_REG_W) & RLEN_MASK;
/*
* The packet length contains 3 extra words: status, length, and a
@ -1082,10 +1085,10 @@ snread(register struct ifnet *ifp)
*/
data = (u_char *) eh;
insw(BASE + DATA_REG_W, data, packet_length >> 1);
CSR_READ_MULTI_2(sc, DATA_REG_W, (uint16_t *) data, packet_length >> 1);
if (packet_length & 1) {
data += packet_length & ~1;
*data = inb(BASE + DATA_REG_B);
*data = CSR_READ_1(sc, DATA_REG_B);
}
++sc->arpcom.ac_if.if_ipackets;
@ -1102,15 +1105,15 @@ snread(register struct ifnet *ifp)
* Error or good, tell the card to get rid of this packet Wait for
* the MMU to be un-busy.
*/
SMC_SELECT_BANK(2);
while (inw(BASE + MMU_CMD_REG_W) & MMUCR_BUSY) /* NOTHING */
SMC_SELECT_BANK(sc, 2);
while (CSR_READ_2(sc, MMU_CMD_REG_W) & MMUCR_BUSY) /* NOTHING */
;
outw(BASE + MMU_CMD_REG_W, MMUCR_RELEASE);
CSR_WRITE_2(sc, MMU_CMD_REG_W, MMUCR_RELEASE);
/*
* Check whether another packet is ready
*/
packet_number = inw(BASE + FIFO_PORTS_REG_W);
packet_number = CSR_READ_2(sc, FIFO_PORTS_REG_W);
if (packet_number & FIFO_REMPTY) {
return;
}
@ -1207,15 +1210,15 @@ snstop(struct sn_softc *sc)
/*
* Clear interrupt mask; disable all interrupts.
*/
SMC_SELECT_BANK(2);
outb(BASE + INTR_MASK_REG_B, 0x00);
SMC_SELECT_BANK(sc, 2);
CSR_WRITE_1(sc, INTR_MASK_REG_B, 0x00);
/*
* Disable transmitter and Receiver
*/
SMC_SELECT_BANK(0);
outw(BASE + RECV_CONTROL_REG_W, 0x0000);
outw(BASE + TXMIT_CONTROL_REG_W, 0x0000);
SMC_SELECT_BANK(sc, 0);
CSR_WRITE_2(sc, RECV_CONTROL_REG_W, 0x0000);
CSR_WRITE_2(sc, TXMIT_CONTROL_REG_W, 0x0000);
/*
* Cancel watchdog.
@ -1254,7 +1257,8 @@ sn_activate(device_t dev)
return err;
}
sc->sn_io_addr = rman_get_start(sc->port_res);
sc->bst = rman_get_bustag(sc->port_res);
sc->bsh = rman_get_bushandle(sc->port_res);
return (0);
}
@ -1299,20 +1303,15 @@ sn_probe(device_t dev, int pccard)
u_int bank;
u_short revision_register;
u_short base_address_register;
u_short ioaddr;
int err;
if ((err = sn_activate(dev)) != 0)
return err;
ioaddr = sc->sn_io_addr;
#ifdef SN_DEBUG
device_printf(dev, "ioaddr is 0x%x\n", ioaddr);
#endif
/*
* First, see if the high byte is 0x33
*/
bank = inw(ioaddr + BANK_SELECT_REG_W);
bank = CSR_READ_2(sc, BANK_SELECT_REG_W);
if ((bank & BSR_DETECT_MASK) != BSR_DETECT_VALUE) {
#ifdef SN_DEBUG
device_printf(dev, "test1 failed\n");
@ -1324,8 +1323,8 @@ sn_probe(device_t dev, int pccard)
* test this. Go to bank 0, then test that the register still
* reports the high byte is 0x33.
*/
outw(ioaddr + BANK_SELECT_REG_W, 0x0000);
bank = inw(ioaddr + BANK_SELECT_REG_W);
CSR_WRITE_2(sc, BANK_SELECT_REG_W, 0x0000);
bank = CSR_READ_2(sc, BANK_SELECT_REG_W);
if ((bank & BSR_DETECT_MASK) != BSR_DETECT_VALUE) {
#ifdef SN_DEBUG
device_printf(dev, "test2 failed\n");
@ -1339,14 +1338,14 @@ sn_probe(device_t dev, int pccard)
* BASE_ADDR_REG_W register, after some jiggery pokery, is expected
* to match the I/O port address where the adapter is being probed.
*/
outw(ioaddr + BANK_SELECT_REG_W, 0x0001);
base_address_register = inw(ioaddr + BASE_ADDR_REG_W);
CSR_WRITE_2(sc, BANK_SELECT_REG_W, 0x0001);
base_address_register = (CSR_READ_2(sc, BASE_ADDR_REG_W) >> 3) & 0x3e0;
/*
* This test is nonsence on PC-card architecture, so if
* pccard == 1, skip this test. (hosokawa)
*/
if (!pccard && (ioaddr != (base_address_register >> 3 & 0x3E0))) {
if (!pccard && rman_get_start(sc->port_res) != base_address_register) {
/*
* Well, the base address register didn't match. Must not
@ -1354,8 +1353,8 @@ sn_probe(device_t dev, int pccard)
*/
#ifdef SN_DEBUG
device_printf(dev, "test3 failed ioaddr = 0x%x, "
"base_address_register = 0x%x\n", ioaddr,
base_address_register >> 3 & 0x3E0);
"base_address_register = 0x%x\n",
rman_get_start(sc->port_res), base_address_register);
#endif
goto error;
}
@ -1365,8 +1364,8 @@ sn_probe(device_t dev, int pccard)
* These might need to be added to later, as future revisions could
* be added.
*/
outw(ioaddr + BANK_SELECT_REG_W, 0x3);
revision_register = inw(ioaddr + REVISION_REG_W);
CSR_WRITE_2(sc, BANK_SELECT_REG_W, 0x3);
revision_register = CSR_READ_2(sc, REVISION_REG_W);
if (!chip_ids[(revision_register >> 4) & 0xF]) {
/*
@ -1413,21 +1412,21 @@ sn_setmcast(struct sn_softc *sc)
u_char mcf[MCFSZ];
if (sn_getmcf(&sc->arpcom, mcf)) {
/* set filter */
SMC_SELECT_BANK(3);
outw(BASE + MULTICAST1_REG_W,
SMC_SELECT_BANK(sc, 3);
CSR_WRITE_2(sc, MULTICAST1_REG_W,
((u_short)mcf[1] << 8) | mcf[0]);
outw(BASE + MULTICAST2_REG_W,
CSR_WRITE_2(sc, MULTICAST2_REG_W,
((u_short)mcf[3] << 8) | mcf[2]);
outw(BASE + MULTICAST3_REG_W,
CSR_WRITE_2(sc, MULTICAST3_REG_W,
((u_short)mcf[5] << 8) | mcf[4]);
outw(BASE + MULTICAST4_REG_W,
CSR_WRITE_2(sc, MULTICAST4_REG_W,
((u_short)mcf[7] << 8) | mcf[6]);
} else {
flags |= RCR_ALMUL;
}
}
SMC_SELECT_BANK(0);
outw(BASE + RECV_CONTROL_REG_W, flags);
SMC_SELECT_BANK(sc, 0);
CSR_WRITE_2(sc, RECV_CONTROL_REG_W, flags);
}
static int

View File

@ -85,6 +85,37 @@ sn_pccard_probe(device_t dev)
return (err);
}
static int
sn_pccard_ascii_enaddr(const char *str, u_char *enet)
{
uint8_t digit;
int i;
memset(enet, 0, ETHER_ADDR_LEN);
for (i = 0, digit = 0; i < (ETHER_ADDR_LEN * 2); i++) {
if (str[i] >= '0' && str[i] <= '9')
digit |= str[i] - '0';
else if (str[i] >= 'a' && str[i] <= 'f')
digit |= (str[i] - 'a') + 10;
else if (str[i] >= 'A' && str[i] <= 'F')
digit |= (str[i] - 'A') + 10;
else {
/* Bogus digit!! */
return (0);
}
/* Compensate for ordering of digits. */
if (i & 1) {
enet[i >> 1] = digit;
digit = 0;
} else
digit <<= 4;
}
return (1);
}
static int
sn_pccard_attach(device_t dev)
{
@ -92,11 +123,22 @@ sn_pccard_attach(device_t dev)
int i;
u_char sum;
u_char ether_addr[ETHER_ADDR_LEN];
const char *cisstr;
sc->pccard_enaddr = 0;
pccard_get_ether(dev, ether_addr);
for (i = 0, sum = 0; i < ETHER_ADDR_LEN; i++)
sum |= ether_addr[i];
if (sum == 0) {
pccard_get_cis3_str(dev, &cisstr);
if (strlen(cisstr) == ETHER_ADDR_LEN * 2)
sum = sn_pccard_ascii_enaddr(cisstr, ether_addr);
}
if (sum == 0) {
pccard_get_cis4_str(dev, &cisstr);
if (strlen(cisstr) == ETHER_ADDR_LEN * 2)
sum = sn_pccard_ascii_enaddr(cisstr, ether_addr);
}
if (sum) {
sc->pccard_enaddr = 1;
bcopy(ether_addr, sc->arpcom.ac_enaddr, ETHER_ADDR_LEN);

View File

@ -394,19 +394,15 @@
* or slightly complicated, repeated tasks.
*/
/* The base I/O address.
*/
#define BASE (sc->sn_io_addr)
/* Select a register bank, 0 to 3
*/
#define SMC_SELECT_BANK(x) { outw( BASE + BANK_SELECT_REG_W, (x) ); }
#define SMC_SELECT_BANK(sc, x) { CSR_WRITE_2(sc, BANK_SELECT_REG_W, (x)); }
/* Define a small delay for the reset
*/
#define SMC_DELAY() { inw( BASE + RECV_CONTROL_REG_W );\
inw( BASE + RECV_CONTROL_REG_W );\
inw( BASE + RECV_CONTROL_REG_W ); }
#define SMC_DELAY(sc) { CSR_READ_2(sc, RECV_CONTROL_REG_W); \
CSR_READ_2(sc, RECV_CONTROL_REG_W); \
CSR_READ_2(sc, RECV_CONTROL_REG_W); }
/* Define flags
*/

View File

@ -38,7 +38,8 @@
*/
struct sn_softc {
struct arpcom arpcom; /* Ethernet common part */
short sn_io_addr; /* i/o bus address (BASE) */
bus_space_tag_t bst;
bus_space_handle_t bsh;
int pages_wanted; /* Size of outstanding MMU ALLOC */
int intr_mask; /* Most recently set interrupt mask */
device_t dev;
@ -58,4 +59,28 @@ void sn_intr(void *);
int sn_activate(device_t);
void sn_deactivate(device_t);
#define CSR_READ_1(sc, off) (bus_space_read_1((sc)->bst, (sc)->bsh, off))
#define CSR_READ_2(sc, off) (bus_space_read_2((sc)->bst, (sc)->bsh, off))
#define CSR_WRITE_1(sc, off, val) \
bus_space_write_1(sc->bst, sc->bsh, off, val)
#define CSR_WRITE_2(sc, off, val) \
bus_space_write_2(sc->bst, sc->bsh, off, val)
#define CSR_WRITE_MULTI_1(sc, off, addr, count) \
bus_space_write_multi_1(sc->bst, sc->bsh, off, addr, count)
#define CSR_WRITE_MULTI_2(sc, off, addr, count) \
bus_space_write_multi_2(sc->bst, sc->bsh, off, addr, count)
#define CSR_READ_MULTI_1(sc, off, addr, count) \
bus_space_read_multi_1(sc->bst, sc->bsh, off, addr, count)
#define CSR_READ_MULTI_2(sc, off, addr, count) \
bus_space_read_multi_2(sc->bst, sc->bsh, off, addr, count)
#define SN_LOCK(_sc) mtx_lock(&(_sc)->sc_mtx)
#define SN_UNLOCK(_sc) mtx_unlock(&(_sc)->sc_mtx)
#define SN_LOCK_INIT(_sc) \
mtx_init(&_sc->sc_mtx, device_get_nameunit(_sc->dev), \
MTX_NETWORK_LOCK, MTX_DEF)
#define SN_LOCK_DESTORY(_sc) mtx_destroy(&_sc->sc_mtx);
#define SN_ASSERT_LOCKED(_sc) mtx_assert(&_sc->sc_mtx, MA_OWNED);
#define SN_ASSERT_UNLOCKED(_sc) mtx_assert(&_sc->sc_mtx, MA_NOTOWNED);
#endif /* _IF_SNVAR_H */