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:
parent
2a063d30f6
commit
470de03fd0
@ -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 @@ startagain:
|
||||
/*
|
||||
* 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 @@ startagain:
|
||||
|
||||
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 @@ startagain:
|
||||
* 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 @@ startagain:
|
||||
/*
|
||||
* 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 @@ startagain:
|
||||
/*
|
||||
* 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 @@ startagain:
|
||||
/*
|
||||
* 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 @@ readcheck:
|
||||
* 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 @@ out:
|
||||
* 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 @@ out:
|
||||
* 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 @@ read_another:
|
||||
* 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 @@ read_another:
|
||||
*/
|
||||
|
||||
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 @@ out:
|
||||
* 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
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
*/
|
||||
|
@ -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 */
|
||||
|
Loading…
x
Reference in New Issue
Block a user