Add bus_dma(9) support for the DEFxA FDDI driver

This commit is contained in:
matt 1998-05-21 20:44:02 +00:00
parent aa04459121
commit cfbb5f3f21
7 changed files with 442 additions and 92 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: if_fea.c,v 1.16 1998/01/12 08:57:24 thorpej Exp $ */
/* $NetBSD: if_fea.c,v 1.17 1998/05/21 20:44:03 matt Exp $ */
/*-
* Copyright (c) 1995, 1996 Matt Thomas <matt@3am-software.com>
@ -474,6 +474,7 @@ pdq_eisa_attach(
const char *intrstr;
sc->sc_iotag = ea->ea_iot;
sc->sc_dmatag = ea->ea_dmat;
bcopy(sc->sc_dev.dv_xname, sc->sc_if.if_xname, IFNAMSIZ);
sc->sc_if.if_flags = 0;
sc->sc_if.if_softc = sc;

View File

@ -1,4 +1,4 @@
/* $NetBSD: pdq.c,v 1.12 1998/04/07 13:32:07 matt Exp $ */
/* $NetBSD: pdq.c,v 1.13 1998/05/21 20:44:02 matt Exp $ */
/*-
* Copyright (c) 1995,1996 Matt Thomas <matt@3am-software.com>
@ -268,6 +268,7 @@ pdq_init_pci_csrs(
static void
pdq_flush_databuf_queue(
pdq_t *pdq,
pdq_databuf_queue_t *q)
{
PDQ_OS_DATABUF_T *pdu;
@ -275,7 +276,7 @@ pdq_flush_databuf_queue(
PDQ_OS_DATABUF_DEQUEUE(q, pdu);
if (pdu == NULL)
return;
PDQ_OS_DATABUF_FREE(pdu);
PDQ_OS_DATABUF_FREE(pdq, pdu);
}
}
@ -563,16 +564,15 @@ pdq_queue_commands(
* Sync the command request buffer and descriptor, then advance
* the request producer index.
*/
PDQ_OS_BUS_DMA_SYNC(pdq, txd->txd_pa_lo, 0, txd->txd_seg_len, PDQ_OS_BUS_DMA_FROMHOST);
PDQ_OS_BUS_DMA_SYNC(pdq, ci->ci_pa_request_descriptors, ci->ci_request_producer * sizeof(pdq_txdesc_t), sizeof(pdq_txdesc_t), PDQ_OS_BUS_DMA_FROMHOST);
PDQ_OS_CMDRQST_PRESYNC(pdq, txd->txd_seg_len);
PDQ_OS_DESC_PRESYNC(pdq, txd, sizeof(pdq_txdesc_t));
PDQ_ADVANCE(ci->ci_request_producer, 1, PDQ_RING_MASK(dbp->pdqdb_command_requests));
/*
* Sync the command response buffer and advance the response
* producer index (descriptor is already pre-initialized)
*/
PDQ_OS_BUS_DMA_SYNC(pdq, dbp->pdqdb_command_responses[ci->ci_response_producer].rxd_pa_lo, 0,
PDQ_SIZE_COMMAND_RESPONSE, PDQ_OS_BUS_DMA_TOHOST);
PDQ_OS_CMDRSP_PRESYNC(pdq, PDQ_SIZE_COMMAND_RESPONSE);
PDQ_ADVANCE(ci->ci_response_producer, 1, PDQ_RING_MASK(dbp->pdqdb_command_responses));
/*
* At this point the command is done. All that needs to be done is to
@ -660,6 +660,7 @@ pdq_process_unsolicited_events(
while (cbp->pdqcb_unsolicited_event != ui->ui_completion) {
rxd = &dbp->pdqdb_unsolicited_events[ui->ui_completion];
event = &ui->ui_events[ui->ui_completion & (PDQ_NUM_UNSOLICITED_EVENTS-1)];
PDQ_OS_UNSOL_EVENT_POSTSYNC(pdq, event);
switch (event->event_type) {
case PDQ_UNSOLICITED_EVENT: {
@ -676,7 +677,7 @@ pdq_process_unsolicited_events(
break;
}
}
PDQ_OS_BUS_DMA_SYNC(pdq, rxd->rxd_pa_lo, 0, sizeof(pdq_unsolicited_event_t), PDQ_OS_BUS_DMA_TOHOST);
PDQ_OS_UNSOL_EVENT_PRESYNC(pdq, event);
PDQ_ADVANCE(ui->ui_completion, 1, PDQ_RING_MASK(dbp->pdqdb_unsolicited_events));
ui->ui_free++;
}
@ -713,11 +714,13 @@ pdq_process_received_data(
fpdu = lpdu = buffers[completion];
PDQ_ASSERT(fpdu != NULL);
PDQ_OS_RXPDU_POSTSYNC(pdq, fpdu, 0, sizeof(u_int32_t));
dataptr = PDQ_OS_DATABUF_PTR(fpdu);
status = *(pdq_rxstatus_t *) dataptr;
if (status.rxs_rcc_badpdu == 0) {
datalen = status.rxs_len;
PDQ_OS_RXPDU_POSTSYNC(pdq, fpdu, sizeof(u_int32_t),
PDQ_RX_FC_OFFSET + 1 - sizeof(u_int32_t));
fc = dataptr[PDQ_RX_FC_OFFSET];
switch (fc & (PDQ_FDDIFC_C|PDQ_FDDIFC_L|PDQ_FDDIFC_F)) {
case PDQ_FDDI_LLC_ASYNC:
@ -746,17 +749,17 @@ pdq_process_received_data(
*/
pdulen = datalen - 4 /* CRC */;
segcnt = (pdulen + PDQ_RX_FC_OFFSET + PDQ_OS_DATABUF_SIZE - 1) / PDQ_OS_DATABUF_SIZE;
PDQ_OS_DATABUF_ALLOC(npdu);
PDQ_OS_DATABUF_ALLOC(pdq, npdu);
if (npdu == NULL) {
PDQ_PRINTF(("discard: no databuf #0\n"));
goto discard_frame;
}
buffers[completion] = npdu;
for (idx = 1; idx < segcnt; idx++) {
PDQ_OS_DATABUF_ALLOC(npdu);
PDQ_OS_DATABUF_ALLOC(pdq, npdu);
if (npdu == NULL) {
PDQ_OS_DATABUF_NEXT_SET(lpdu, NULL);
PDQ_OS_DATABUF_FREE(fpdu);
PDQ_OS_DATABUF_FREE(pdq, fpdu);
goto discard_frame;
}
PDQ_OS_DATABUF_NEXT_SET(lpdu, buffers[(completion + idx) & ring_mask]);
@ -824,9 +827,9 @@ pdq_process_received_data(
}
rxd->rxd_pa_hi = 0;
rxd->rxd_seg_len_hi = PDQ_OS_DATABUF_SIZE / 16;
rxd->rxd_pa_lo = PDQ_OS_VA_TO_BUSPA(pdq, PDQ_OS_DATABUF_PTR(buffers[rx->rx_producer]));
PDQ_OS_BUS_DMA_SYNC(pdq, rxd->rxd_pa_lo, 0, PDQ_OS_DATABUF_SIZE, PDQ_OS_BUS_DMA_TOHOST);
PDQ_OS_BUS_DMA_SYNC(pdq, rx->rx_pa_descriptors, rx->rx_producer * sizeof(*rxd), sizeof(*rxd), PDQ_OS_BUS_DMA_FROMHOST);
rxd->rxd_pa_lo = PDQ_OS_DATABUF_BUSPA(pdq, buffers[rx->rx_producer]);
PDQ_OS_RXPDU_PRESYNC(pdq, buffers[rx->rx_producer], 0, PDQ_OS_DATABUF_SIZE);
PDQ_OS_DESC_PRESYNC(pdq, rxd, sizeof(*rxd));
PDQ_ADVANCE(rx->rx_producer, 1, ring_mask);
PDQ_ADVANCE(producer, 1, ring_mask);
PDQ_ADVANCE(completion, 1, ring_mask);
@ -843,7 +846,7 @@ pdq_process_received_data(
*/
for (idx = 0; idx < PDQ_RX_SEGCNT; idx++) {
if ((pdu = buffers[(rx->rx_producer + idx) & ring_mask]) == NULL) {
PDQ_OS_DATABUF_ALLOC(pdu);
PDQ_OS_DATABUF_ALLOC(pdq, pdu);
if (pdu == NULL)
break;
buffers[(rx->rx_producer + idx) & ring_mask] = pdu;
@ -856,9 +859,9 @@ pdq_process_received_data(
}
rxd->rxd_pa_hi = 0;
rxd->rxd_seg_len_hi = PDQ_OS_DATABUF_SIZE / 16;
rxd->rxd_pa_lo = PDQ_OS_VA_TO_BUSPA(pdq, PDQ_OS_DATABUF_PTR(pdu));
PDQ_OS_BUS_DMA_SYNC(pdq, rxd->rxd_pa_lo, 0, PDQ_OS_DATABUF_SIZE, PDQ_OS_BUS_DMA_TOHOST);
PDQ_OS_BUS_DMA_SYNC(pdq, rx->rx_pa_descriptors, rx->rx_producer * sizeof(*rxd), sizeof(*rxd), PDQ_OS_BUS_DMA_FROMHOST);
rxd->rxd_pa_lo = PDQ_OS_DATABUF_BUSPA(pdq, pdu);
PDQ_OS_RXPDU_PRESYNC(pdq, pdu, 0, PDQ_OS_DATABUF_SIZE);
PDQ_OS_DESC_PRESYNC(pdq, rxd, sizeof(*rxd));
}
if (idx < PDQ_RX_SEGCNT) {
/*
@ -884,6 +887,9 @@ pdq_queue_transmit_data(
pdq_txdesc_t *eop = NULL;
PDQ_OS_DATABUF_T *pdu0;
pdq_uint32_t freecnt;
#if defined(PDQ_BUS_DMA)
bus_dmamap_t map;
#endif
/*
* Need 2 or more descriptors to be able to send.
@ -892,9 +898,30 @@ pdq_queue_transmit_data(
return PDQ_FALSE;
dbp->pdqdb_transmits[producer] = tx->tx_hdrdesc;
PDQ_OS_BUS_DMA_SYNC(pdq, tx->tx_pa_descriptors, producer * sizeof(pdq_txdesc_t), sizeof(pdq_txdesc_t), PDQ_OS_BUS_DMA_FROMHOST);
PDQ_OS_DESC_PRESYNC(pdq, &dbp->pdqdb_transmits[producer], sizeof(pdq_txdesc_t));
PDQ_ADVANCE(producer, 1, PDQ_RING_MASK(dbp->pdqdb_transmits));
#if defined(PDQ_BUS_DMA)
map = M_GETCTX(pdu, bus_dmamap_t);
if ((freecnt = tx->tx_free - 1) > map->dm_nsegs) {
int idx;
for (idx = 0; idx < map->dm_nsegs; idx++) {
/*
* Initialize the transmit descriptor
*/
eop = &dbp->pdqdb_transmits[producer];
eop->txd_seg_len = map->dm_segs[idx].ds_len;
eop->txd_pa_lo = map->dm_segs[idx].ds_addr;
eop->txd_sop = eop->txd_eop = eop->txd_pa_hi = 0;
PDQ_OS_DESC_PRESYNC(pdq, eop, sizeof(pdq_txdesc_t));
freecnt--;
PDQ_ADVANCE(producer, 1, PDQ_RING_MASK(dbp->pdqdb_transmits));
}
pdu0 = NULL;
} else {
pdu0 = pdu;
}
#else
for (freecnt = tx->tx_free - 1, pdu0 = pdu; pdu0 != NULL && freecnt > 0;) {
pdq_uint32_t fraglen, datalen = PDQ_OS_DATABUF_LEN(pdu0);
const pdq_uint8_t *dataptr = PDQ_OS_DATABUF_PTR(pdu0);
@ -915,10 +942,7 @@ pdq_queue_transmit_data(
eop->txd_seg_len = seglen;
eop->txd_pa_lo = PDQ_OS_VA_TO_BUSPA(pdq, dataptr);
eop->txd_sop = eop->txd_eop = eop->txd_pa_hi = 0;
PDQ_OS_BUS_DMA_SYNC(pdq, eop->txd_pa_lo, 0, seglen, PDQ_OS_BUS_DMA_FROMHOST);
PDQ_OS_BUS_DMA_SYNC(pdq, tx->tx_pa_descriptors,
producer * sizeof(pdq_txdesc_t),
sizeof(pdq_txdesc_t), PDQ_OS_BUS_DMA_FROMHOST);
PDQ_OS_DESC_PRESYNC(pdq, eop, sizeof(pdq_txdesc_t));
datalen -= seglen;
dataptr += seglen;
fraglen = PDQ_OS_PAGESIZE;
@ -927,6 +951,7 @@ pdq_queue_transmit_data(
}
pdu0 = PDQ_OS_DATABUF_NEXT(pdu0);
}
#endif /* defined(PDQ_BUS_DMA) */
if (pdu0 != NULL) {
PDQ_ASSERT(freecnt == 0);
/*
@ -991,7 +1016,7 @@ pdq_flush_transmitter(
* Don't call transmit done since the packet never made it
* out on the wire.
*/
PDQ_OS_DATABUF_FREE(pdu);
PDQ_OS_DATABUF_FREE(pdq, pdu);
}
tx->tx_free = PDQ_RING_MASK(pdq->pdq_dbp->pdqdb_transmits);
@ -1098,12 +1123,12 @@ pdq_stop(
/*
* Flush all the databuf queues.
*/
pdq_flush_databuf_queue(&pdq->pdq_tx_info.tx_txq);
pdq_flush_databuf_queue(pdq, &pdq->pdq_tx_info.tx_txq);
pdq->pdq_flags &= ~(PDQ_TXOK|PDQ_IS_ONRING|PDQ_IS_FDX);
buffers = (PDQ_OS_DATABUF_T **) pdq->pdq_rx_info.rx_buffers;
for (idx = 0; idx < PDQ_RING_SIZE(pdq->pdq_dbp->pdqdb_receives); idx++) {
if (buffers[idx] != NULL) {
PDQ_OS_DATABUF_FREE(buffers[idx]);
PDQ_OS_DATABUF_FREE(pdq, buffers[idx]);
buffers[idx] = NULL;
}
}
@ -1111,7 +1136,7 @@ pdq_stop(
buffers = (PDQ_OS_DATABUF_T **) pdq->pdq_host_smt_info.rx_buffers;
for (idx = 0; idx < PDQ_RING_SIZE(pdq->pdq_dbp->pdqdb_host_smt); idx++) {
if (buffers[idx] != NULL) {
PDQ_OS_DATABUF_FREE(buffers[idx]);
PDQ_OS_DATABUF_FREE(pdq, buffers[idx]);
buffers[idx] = NULL;
}
}
@ -1179,16 +1204,14 @@ pdq_stop(
* Make sure there isn't stale information in the caches before
* tell the adapter about the blocks it's going to use.
*/
PDQ_OS_BUS_DMA_SYNC(pdq, PDQ_OS_VA_TO_BUSPA(pdq, pdq->pdq_cbp), 0,
sizeof(pdq->pdq_cbp), PDQ_OS_BUS_DMA_FROMHOST);
PDQ_OS_CONSUMER_PRESYNC(pdq);
PDQ_CSR_WRITE(csrs, csr_port_data_b, 0);
PDQ_CSR_WRITE(csrs, csr_port_data_a, PDQ_OS_VA_TO_BUSPA(pdq, pdq->pdq_cbp));
PDQ_CSR_WRITE(csrs, csr_port_data_a, pdq->pdq_pa_consumer_block);
pdq_do_port_control(csrs, PDQ_PCTL_CONSUMER_BLOCK);
PDQ_CSR_WRITE(csrs, csr_port_data_b, 0);
PDQ_CSR_WRITE(csrs, csr_port_data_a,
PDQ_OS_VA_TO_BUSPA(pdq, pdq->pdq_dbp) | PDQ_DMA_INIT_LW_BSWAP_DATA);
PDQ_CSR_WRITE(csrs, csr_port_data_a, pdq->pdq_pa_descriptor_block | PDQ_DMA_INIT_LW_BSWAP_DATA);
pdq_do_port_control(csrs, PDQ_PCTL_DMA_INIT);
for (cnt = 0; cnt < 1000; cnt++) {
@ -1329,6 +1352,7 @@ pdq_interrupt(
while ((data = PDQ_CSR_READ(csrs, csr_port_status)) & PDQ_PSTS_INTR_PENDING) {
progress = 1;
PDQ_PRINTF(("PDQ Interrupt: Status = 0x%08x\n", data));
PDQ_OS_CONSUMER_POSTSYNC(pdq);
if (data & PDQ_PSTS_RCV_DATA_PENDING) {
pdq_process_received_data(pdq, &pdq->pdq_rx_info,
pdq->pdq_dbp->pdqdb_receives,
@ -1434,8 +1458,10 @@ pdq_initialize(
{
pdq_t *pdq;
pdq_state_t state;
#if !defined(PDQ_BUS_DMA)
const pdq_uint32_t contig_bytes = (sizeof(pdq_descriptor_block_t) * 2) - PDQ_OS_PAGESIZE;
pdq_uint8_t *p;
#endif
int idx;
PDQ_ASSERT(sizeof(pdq_descriptor_block_t) == 8192);
@ -1471,6 +1497,7 @@ pdq_initialize(
* buffers (though on machines with 8KB pages we will to allocate
* them separately since there will be nothing left overs.)
*/
#if defined(PDQ_OS_MEMALLOC_CONTIG)
p = (pdq_uint8_t *) PDQ_OS_MEMALLOC_CONTIG(contig_bytes);
if (p != NULL) {
pdq_physaddr_t physaddr = PDQ_OS_VA_TO_BUSPA(pdq, p);
@ -1483,13 +1510,16 @@ pdq_initialize(
if (PDQ_OS_VA_TO_BUSPA(pdq, p + idx) - physaddr != idx)
goto cleanup_and_return;
}
physaddr &= 0x1FFF;
if (physaddr) {
if (physaddr & 0x1FFF) {
pdq->pdq_unsolicited_info.ui_events = (pdq_unsolicited_event_t *) p;
pdq->pdq_dbp = (pdq_descriptor_block_t *) &p[0x2000 - physaddr];
pdq->pdq_unsolicited_info.ui_pa_bufstart = physaddr;
pdq->pdq_dbp = (pdq_descriptor_block_t *) &p[0x2000 - (physaddr & 0x1FFF)];
pdq->pdq_pa_descriptor_block = physaddr & ~0x1FFFUL;
} else {
pdq->pdq_dbp = (pdq_descriptor_block_t *) p;
pdq->pdq_pa_descriptor_block = physaddr;
pdq->pdq_unsolicited_info.ui_events = (pdq_unsolicited_event_t *) &p[0x2000];
pdq->pdq_unsolicited_info.ui_pa_bufstart = physaddr + 0x2000;
}
}
if (contig_bytes == sizeof(pdq_descriptor_block_t)) {
@ -1497,6 +1527,10 @@ pdq_initialize(
(pdq_unsolicited_event_t *) PDQ_OS_MEMALLOC(
PDQ_NUM_UNSOLICITED_EVENTS * sizeof(pdq_unsolicited_event_t));
}
#else
if (pdq_os_memalloc_contig(pdq))
goto cleanup_and_return;
#endif
/*
* Make sure everything got allocated. If not, free what did
@ -1504,23 +1538,26 @@ pdq_initialize(
*/
if (pdq->pdq_dbp == NULL || pdq->pdq_unsolicited_info.ui_events == NULL) {
cleanup_and_return:
#ifdef PDQ_OS_MEMFREE_CONTIG
if (p /* pdq->pdq_dbp */ != NULL)
PDQ_OS_MEMFREE_CONTIG(p /* pdq->pdq_dbp */, contig_bytes);
if (contig_bytes == sizeof(pdq_descriptor_block_t) && pdq->pdq_unsolicited_info.ui_events != NULL)
PDQ_OS_MEMFREE(pdq->pdq_unsolicited_info.ui_events,
PDQ_NUM_UNSOLICITED_EVENTS * sizeof(pdq_unsolicited_event_t));
#endif
PDQ_OS_MEMFREE(pdq, sizeof(pdq_t));
return NULL;
}
pdq->pdq_cbp = (volatile pdq_consumer_block_t *) &pdq->pdq_dbp->pdqdb_consumer;
pdq->pdq_pa_consumer_block = PDQ_DB_BUSPA(pdq, pdq->pdq_cbp);
pdq->pdq_command_info.ci_request_bufstart = (pdq_uint8_t *) pdq->pdq_dbp->pdqdb_command_pool;
pdq->pdq_command_info.ci_response_bufstart = (pdq_uint8_t *) pdq->pdq_dbp->pdqdb_command_pool + sizeof(pdq->pdq_dbp->pdqdb_command_pool) - PDQ_SIZE_COMMAND_RESPONSE;
pdq->pdq_rx_info.rx_buffers = (void *) pdq->pdq_dbp->pdqdb_receive_buffers;
pdq->pdq_host_smt_info.rx_buffers = (void *) pdq->pdq_dbp->pdqdb_host_smt_buffers;
PDQ_PRINTF(("\nPDQ Descriptor Block = " PDQ_OS_PTR_FMT " (PA = 0x%x)\n", pdq->pdq_dbp, PDQ_OS_VA_TO_BUSPA(pdq, pdq->pdq_dbp)));
PDQ_PRINTF(("\nPDQ Descriptor Block = " PDQ_OS_PTR_FMT " (PA = 0x%x)\n", pdq->pdq_dbp, pdq->pdq_pa_descriptor_block));
PDQ_PRINTF((" Recieve Queue = " PDQ_OS_PTR_FMT "\n", pdq->pdq_dbp->pdqdb_receives));
PDQ_PRINTF((" Transmit Queue = " PDQ_OS_PTR_FMT "\n", pdq->pdq_dbp->pdqdb_transmits));
PDQ_PRINTF((" Host SMT Queue = " PDQ_OS_PTR_FMT "\n", pdq->pdq_dbp->pdqdb_host_smt));
@ -1575,8 +1612,8 @@ pdq_initialize(
/*
* Initialize the command information block
*/
pdq->pdq_command_info.ci_pa_request_bufstart = PDQ_OS_VA_TO_BUSPA(pdq, pdq->pdq_command_info.ci_request_bufstart);
pdq->pdq_command_info.ci_pa_request_descriptors = PDQ_OS_VA_TO_BUSPA(pdq, pdq->pdq_dbp->pdqdb_command_requests);
pdq->pdq_command_info.ci_pa_request_bufstart = PDQ_DB_BUSPA(pdq, pdq->pdq_command_info.ci_request_bufstart);
pdq->pdq_command_info.ci_pa_request_descriptors = PDQ_DB_BUSPA(pdq, pdq->pdq_dbp->pdqdb_command_requests);
PDQ_PRINTF(("PDQ Command Buffer = " PDQ_OS_PTR_FMT " (PA=0x%x)\n",
pdq->pdq_command_info.ci_request_bufstart,
pdq->pdq_command_info.ci_pa_request_bufstart));
@ -1588,8 +1625,8 @@ pdq_initialize(
txd->txd_pa_hi = 0;
}
pdq->pdq_command_info.ci_pa_response_bufstart = PDQ_OS_VA_TO_BUSPA(pdq, pdq->pdq_command_info.ci_response_bufstart);
pdq->pdq_command_info.ci_pa_response_descriptors = PDQ_OS_VA_TO_BUSPA(pdq, pdq->pdq_dbp->pdqdb_command_responses);
pdq->pdq_command_info.ci_pa_response_bufstart = PDQ_DB_BUSPA(pdq, pdq->pdq_command_info.ci_response_bufstart);
pdq->pdq_command_info.ci_pa_response_descriptors = PDQ_DB_BUSPA(pdq, pdq->pdq_dbp->pdqdb_command_responses);
for (idx = 0; idx < sizeof(pdq->pdq_dbp->pdqdb_command_responses)/sizeof(pdq->pdq_dbp->pdqdb_command_responses[0]); idx++) {
pdq_rxdesc_t *rxd = &pdq->pdq_dbp->pdqdb_command_responses[idx];
@ -1599,16 +1636,14 @@ pdq_initialize(
rxd->rxd_seg_len_lo = 0;
rxd->rxd_seg_len_hi = PDQ_SIZE_COMMAND_RESPONSE / 16;
}
PDQ_OS_BUS_DMA_SYNC(pdq, pdq->pdq_command_info.ci_pa_response_descriptors,
0, sizeof(pdq->pdq_dbp->pdqdb_command_responses),
PDQ_OS_BUS_DMA_FROMHOST);
PDQ_OS_DESC_PRESYNC(pdq, pdq->pdq_dbp->pdqdb_command_responses,
sizeof(pdq->pdq_dbp->pdqdb_command_responses));
/*
* Initialize the unsolicited event information block
*/
pdq->pdq_unsolicited_info.ui_free = PDQ_NUM_UNSOLICITED_EVENTS;
pdq->pdq_unsolicited_info.ui_pa_bufstart = PDQ_OS_VA_TO_BUSPA(pdq, pdq->pdq_unsolicited_info.ui_events);
pdq->pdq_unsolicited_info.ui_pa_descriptors = PDQ_OS_VA_TO_BUSPA(pdq, pdq->pdq_dbp->pdqdb_unsolicited_events);
pdq->pdq_unsolicited_info.ui_pa_descriptors = PDQ_DB_BUSPA(pdq, pdq->pdq_dbp->pdqdb_unsolicited_events);
PDQ_PRINTF(("PDQ Unsolicit Event Buffer = " PDQ_OS_PTR_FMT " (PA=0x%x)\n",
pdq->pdq_unsolicited_info.ui_events,
pdq->pdq_unsolicited_info.ui_pa_bufstart));
@ -1622,36 +1657,33 @@ pdq_initialize(
rxd->rxd_pa_lo = pdq->pdq_unsolicited_info.ui_pa_bufstart + (const pdq_uint8_t *) event
- (const pdq_uint8_t *) pdq->pdq_unsolicited_info.ui_events;
rxd->rxd_pa_hi = 0;
PDQ_OS_UNSOL_EVENT_PRESYNC(pdq, event);
}
PDQ_OS_BUS_DMA_SYNC(pdq, pdq->pdq_unsolicited_info.ui_pa_descriptors,
0, sizeof(pdq->pdq_dbp->pdqdb_unsolicited_events),
PDQ_OS_BUS_DMA_FROMHOST);
PDQ_OS_BUS_DMA_SYNC(pdq, pdq->pdq_unsolicited_info.ui_pa_bufstart,
0, sizeof(pdq->pdq_unsolicited_info.ui_events),
PDQ_OS_BUS_DMA_TOHOST);
PDQ_OS_DESC_PRESYNC(pdq, pdq->pdq_dbp->pdqdb_unsolicited_events,
sizeof(pdq->pdq_dbp->pdqdb_unsolicited_events));
/*
* Initialize the receive information blocks (normal and SMT).
*/
pdq->pdq_rx_info.rx_free = PDQ_RING_MASK(pdq->pdq_dbp->pdqdb_receives);
pdq->pdq_rx_info.rx_target = pdq->pdq_rx_info.rx_free - PDQ_RX_SEGCNT * 8;
pdq->pdq_rx_info.rx_pa_descriptors = PDQ_OS_VA_TO_BUSPA(pdq, pdq->pdq_dbp->pdqdb_receives);
pdq->pdq_rx_info.rx_pa_descriptors = PDQ_DB_BUSPA(pdq, pdq->pdq_dbp->pdqdb_receives);
pdq->pdq_host_smt_info.rx_free = PDQ_RING_MASK(pdq->pdq_dbp->pdqdb_host_smt);
pdq->pdq_host_smt_info.rx_target = pdq->pdq_host_smt_info.rx_free - PDQ_RX_SEGCNT * 3;
pdq->pdq_host_smt_info.rx_pa_descriptors = PDQ_OS_VA_TO_BUSPA(pdq, pdq->pdq_dbp->pdqdb_host_smt);
pdq->pdq_host_smt_info.rx_pa_descriptors = PDQ_DB_BUSPA(pdq, pdq->pdq_dbp->pdqdb_host_smt);
/*
* Initialize the transmit information block.
*/
pdq->pdq_tx_hdr[0] = PDQ_FDDI_PH0;
pdq->pdq_tx_hdr[1] = PDQ_FDDI_PH1;
pdq->pdq_tx_hdr[2] = PDQ_FDDI_PH2;
pdq->pdq_dbp->pdqdb_tx_hdr[0] = PDQ_FDDI_PH0;
pdq->pdq_dbp->pdqdb_tx_hdr[1] = PDQ_FDDI_PH1;
pdq->pdq_dbp->pdqdb_tx_hdr[2] = PDQ_FDDI_PH2;
pdq->pdq_tx_info.tx_free = PDQ_RING_MASK(pdq->pdq_dbp->pdqdb_transmits);
pdq->pdq_tx_info.tx_hdrdesc.txd_seg_len = sizeof(pdq->pdq_tx_hdr);
pdq->pdq_tx_info.tx_hdrdesc.txd_seg_len = sizeof(pdq->pdq_dbp->pdqdb_tx_hdr);
pdq->pdq_tx_info.tx_hdrdesc.txd_sop = 1;
pdq->pdq_tx_info.tx_hdrdesc.txd_pa_lo = PDQ_OS_VA_TO_BUSPA(pdq, pdq->pdq_tx_hdr);
pdq->pdq_tx_info.tx_pa_descriptors = PDQ_OS_VA_TO_BUSPA(pdq, pdq->pdq_dbp->pdqdb_transmits);
pdq->pdq_tx_info.tx_hdrdesc.txd_pa_lo = PDQ_DB_BUSPA(pdq, pdq->pdq_dbp->pdqdb_tx_hdr);
pdq->pdq_tx_info.tx_pa_descriptors = PDQ_DB_BUSPA(pdq, pdq->pdq_dbp->pdqdb_transmits);
state = PDQ_PSTS_ADAPTER_STATE(PDQ_CSR_READ(&pdq->pdq_csrs, csr_port_status));
PDQ_PRINTF(("PDQ Adapter State = %s\n", pdq_adapter_states[state]));

View File

@ -1,4 +1,4 @@
/* $NetBSD: pdq_ifsubr.c,v 1.12 1998/04/07 13:32:07 matt Exp $ */
/* $NetBSD: pdq_ifsubr.c,v 1.13 1998/05/21 20:44:02 matt Exp $ */
/*-
* Copyright (c) 1995, 1996 Matt Thomas <matt@3am-software.com>
@ -161,7 +161,7 @@ pdq_ifwatchdog(
IF_DEQUEUE(&ifp->if_snd, m);
if (m == NULL)
return;
m_freem(m);
PDQ_OS_DATABUF_FREE(PDQ_OS_IFP_TO_SOFTC(ifp)->sc_pdq, m);
}
}
@ -169,7 +169,7 @@ ifnet_ret_t
pdq_ifstart(
struct ifnet *ifp)
{
pdq_softc_t *sc = PDQ_OS_IFP_TO_SOFTC(ifp);
pdq_softc_t * const sc = PDQ_OS_IFP_TO_SOFTC(ifp);
struct ifqueue *ifq = &ifp->if_snd;
struct mbuf *m;
int tx = 0;
@ -185,9 +185,31 @@ pdq_ifstart(
return;
}
for (;; tx = 1) {
#if defined(PDQ_BUS_DMA) && !defined(PDQ_BUS_DMA_NOTX)
bus_dmamap_t map;
#endif
IF_DEQUEUE(ifq, m);
if (m == NULL)
break;
#if defined(PDQ_BUS_DMA) && !defined(PDQ_BUS_DMA_NOTX)
if (m->m_flags & M_HASDMAMAP) {
map = M_GETCTX(m, bus_dmamap_t);
} else {
map = NULL;
if (!bus_dmamap_create(sc->sc_dmatag, 0x1FFF, 255, 0x1FFF, 0, BUS_DMA_NOWAIT, &map)) {
if (!bus_dmamap_load_mbuf(sc->sc_dmatag, map, m, BUS_DMA_NOWAIT)) {
bus_dmamap_sync(sc->sc_dmatag, map, 0, m->m_pkthdr.len, BUS_DMASYNC_PREWRITE);
M_SETCTX(m, map);
m->m_flags |= M_HASDMAMAP;
}
}
if ((m->m_flags & M_HASDMAMAP) == 0) {
ifp->if_flags |= IFF_OACTIVE;
IF_PREPEND(ifq, m);
break;
}
}
#endif
if (pdq_queue_transmit_data(sc->sc_pdq, m) == PDQ_FALSE) {
ifp->if_flags |= IFF_OACTIVE;
@ -206,18 +228,30 @@ pdq_os_receive_pdu(
size_t pktlen,
int drop)
{
pdq_softc_t *sc = (pdq_softc_t *) pdq->pdq_os_ctx;
pdq_softc_t *sc = pdq->pdq_os_ctx;
struct fddi_header *fh = mtod(m, struct fddi_header *);
sc->sc_if.if_ipackets++;
#if NBPFILTER > 0
#if defined(PDQ_BUS_MAP)
pdq_os_databuf_sync(sc, m, 0, pktlen, BUS_DMASYNC_POSTREAD);
bus_dmamap_unload(sc->sc_dmatag, M_GETCTX(m, bus_dmamap_t));
bus_dmamap_destroy(sc->sc_dmatag, M_GETCTX(m, bus_dmamap_t));
m->m_flags &= ~M_HASDMAMAP;
#endif
if (sc->sc_bpf != NULL)
PDQ_BPF_MTAP(sc, m);
#endif
if (drop || (fh->fddi_fc & (FDDIFC_L|FDDIFC_F)) != FDDIFC_LLC_ASYNC) {
m_freem(m);
PDQ_OS_DATABUF_FREE(pdq, m);
return;
}
#if NBPFILTER == 0 && defined(PDQ_BUS_MAP)
pdq_os_databuf_sync(sc, m, 0, pktlen, BUS_DMASYNC_POSTREAD);
bus_dmamap_unload(sc->sc_dmatag, M_GETCTX(m, bus_dmamap_t));
bus_dmamap_destroy(sc->sc_dmatag, M_GETCTX(m, bus_dmamap_t));
m->m_flags &= ~M_HASDMAMAP;
#endif
m->m_data += sizeof(struct fddi_header);
m->m_len -= sizeof(struct fddi_header);
@ -230,7 +264,7 @@ void
pdq_os_restart_transmitter(
pdq_t *pdq)
{
pdq_softc_t *sc = (pdq_softc_t *) pdq->pdq_os_ctx;
pdq_softc_t *sc = pdq->pdq_os_ctx;
sc->sc_if.if_flags &= ~IFF_OACTIVE;
if (sc->sc_if.if_snd.ifq_head != NULL) {
sc->sc_if.if_timer = PDQ_OS_TX_TIMEOUT;
@ -245,12 +279,12 @@ pdq_os_transmit_done(
pdq_t *pdq,
struct mbuf *m)
{
pdq_softc_t *sc = (pdq_softc_t *) pdq->pdq_os_ctx;
pdq_softc_t *sc = pdq->pdq_os_ctx;
#if NBPFILTER > 0
if (sc->sc_bpf != NULL)
PDQ_BPF_MTAP(sc, m);
#endif
m_freem(m);
PDQ_OS_DATABUF_FREE(pdq, m);
sc->sc_if.if_opackets++;
}
@ -260,7 +294,7 @@ pdq_os_addr_fill(
pdq_lanaddr_t *addr,
size_t num_addrs)
{
pdq_softc_t *sc = (pdq_softc_t *) pdq->pdq_os_ctx;
pdq_softc_t *sc = pdq->pdq_os_ctx;
struct ether_multistep step;
struct ether_multi *enm;
@ -345,7 +379,7 @@ pdq_os_update_status(
pdq_t *pdq,
const void *arg)
{
pdq_softc_t * const sc = (pdq_softc_t *) pdq->pdq_os_ctx;
pdq_softc_t * const sc = pdq->pdq_os_ctx;
const pdq_response_status_chars_get_t *rsp = arg;
int media = 0;
@ -528,3 +562,186 @@ pdq_ifattach(
PDQ_BPFATTACH(sc, DLT_FDDI, sizeof(struct fddi_header));
#endif
}
#if defined(PDQ_BUS_DMA)
int
pdq_os_memalloc_contig(
pdq_t *pdq)
{
pdq_softc_t * const sc = pdq->pdq_os_ctx;
bus_dma_segment_t db_segs[1], ui_segs[1];
int db_nsegs = 0, ui_nsegs = 0;
int steps = 0;
int not_ok;
not_ok = bus_dmamem_alloc(sc->sc_dmatag,
sizeof(*pdq->pdq_dbp), sizeof(*pdq->pdq_dbp),
sizeof(*pdq->pdq_dbp), db_segs, 1, &db_nsegs,
BUS_DMA_NOWAIT);
if (!not_ok) {
steps++;
not_ok = bus_dmamem_map(sc->sc_dmatag, db_segs, db_nsegs,
sizeof(*pdq->pdq_dbp), (caddr_t *) &pdq->pdq_dbp,
BUS_DMA_NOWAIT);
}
if (!not_ok) {
steps++;
not_ok = bus_dmamap_create(sc->sc_dmatag, db_segs[0].ds_len, 1,
0x2000, 0, BUS_DMA_NOWAIT, &sc->sc_dbmap);
}
if (!not_ok) {
steps++;
not_ok = bus_dmamap_load(sc->sc_dmatag, sc->sc_dbmap,
pdq->pdq_dbp, sizeof(*pdq->pdq_dbp),
NULL, BUS_DMA_NOWAIT);
}
if (!not_ok) {
steps++;
pdq->pdq_pa_descriptor_block = sc->sc_dbmap->dm_segs[0].ds_addr;
not_ok = bus_dmamem_alloc(sc->sc_dmatag,
PDQ_OS_PAGESIZE, PDQ_OS_PAGESIZE, PDQ_OS_PAGESIZE,
ui_segs, 1, &ui_nsegs, BUS_DMA_NOWAIT);
}
if (!not_ok) {
steps++;
not_ok = bus_dmamem_map(sc->sc_dmatag, ui_segs, ui_nsegs,
PDQ_OS_PAGESIZE,
(caddr_t *) &pdq->pdq_unsolicited_info.ui_events,
BUS_DMA_NOWAIT);
}
if (!not_ok) {
steps++;
not_ok = bus_dmamap_create(sc->sc_dmatag, ui_segs[0].ds_len, 1,
PDQ_OS_PAGESIZE, 0, BUS_DMA_NOWAIT,
&sc->sc_uimap);
}
if (!not_ok) {
steps++;
not_ok = bus_dmamap_load(sc->sc_dmatag, sc->sc_uimap,
pdq->pdq_unsolicited_info.ui_events,
PDQ_OS_PAGESIZE, NULL, BUS_DMA_NOWAIT);
}
if (!not_ok) {
pdq->pdq_unsolicited_info.ui_pa_bufstart = sc->sc_uimap->dm_segs[0].ds_addr;
return not_ok;
}
switch (steps) {
case 8: {
bus_dmamap_unload(sc->sc_dmatag, sc->sc_uimap);
/* FALL THROUGH */
}
case 7: {
bus_dmamap_destroy(sc->sc_dmatag, sc->sc_uimap);
/* FALL THROUGH */
}
case 6: {
bus_dmamem_unmap(sc->sc_dmatag,
(caddr_t) pdq->pdq_unsolicited_info.ui_events,
PDQ_OS_PAGESIZE);
/* FALL THROUGH */
}
case 5: {
bus_dmamem_free(sc->sc_dmatag, ui_segs, ui_nsegs);
/* FALL THROUGH */
}
case 4: {
bus_dmamap_unload(sc->sc_dmatag, sc->sc_dbmap);
/* FALL THROUGH */
}
case 3: {
bus_dmamap_destroy(sc->sc_dmatag, sc->sc_dbmap);
/* FALL THROUGH */
}
case 2: {
bus_dmamem_unmap(sc->sc_dmatag,
(caddr_t) pdq->pdq_dbp,
sizeof(*pdq->pdq_dbp));
/* FALL THROUGH */
}
case 1: {
bus_dmamem_free(sc->sc_dmatag, db_segs, db_nsegs);
/* FALL THROUGH */
}
}
return not_ok;
}
extern void
pdq_os_descriptor_block_sync(
pdq_os_ctx_t *sc,
size_t offset,
size_t length,
int ops)
{
bus_dmamap_sync(sc->sc_dmatag, sc->sc_dbmap, offset, length, ops);
}
extern void
pdq_os_unsolicited_event_sync(
pdq_os_ctx_t *sc,
size_t offset,
size_t length,
int ops)
{
bus_dmamap_sync(sc->sc_dmatag, sc->sc_uimap, offset, length, ops);
}
extern void
pdq_os_databuf_sync(
pdq_os_ctx_t *sc,
struct mbuf *m,
size_t offset,
size_t length,
int ops)
{
bus_dmamap_sync(sc->sc_dmatag, M_GETCTX(m, bus_dmamap_t), offset, length, ops);
}
extern void
pdq_os_databuf_free(
pdq_os_ctx_t *sc,
struct mbuf *m)
{
if (m->m_flags & M_HASDMAMAP) {
bus_dmamap_t map = M_GETCTX(m, bus_dmamap_t);
bus_dmamap_unload(sc->sc_dmatag, map);
bus_dmamap_destroy(sc->sc_dmatag, map);
m->m_flags ^= M_HASDMAMAP;
}
m_freem(m);
}
extern struct mbuf *
pdq_os_databuf_alloc(
pdq_os_ctx_t *sc)
{
struct mbuf *m;
bus_dmamap_t map;
MGETHDR(m, M_DONTWAIT, MT_DATA);
if (m == NULL)
return NULL;
MCLGET(m, M_DONTWAIT);
if ((m->m_flags & M_EXT) == 0) {
m_free(m);
return NULL;
}
m->m_len = PDQ_OS_DATABUF_SIZE;
if (!bus_dmamap_create(sc->sc_dmatag, PDQ_OS_DATABUF_SIZE,
1, PDQ_OS_DATABUF_SIZE, 0, BUS_DMA_NOWAIT, &map)) {
m_free(m);
return NULL;
}
if (!bus_dmamap_load_mbuf(sc->sc_dmatag, map, m, BUS_DMA_NOWAIT)) {
bus_dmamap_destroy(sc->sc_dmatag, map);
m_free(m);
return NULL;
}
m->m_flags |= M_HASDMAMAP;
M_SETCTX(m, map);
return m;
}
#endif

View File

@ -1,4 +1,4 @@
/* $NetBSD: pdqreg.h,v 1.8 1998/04/07 13:32:06 matt Exp $ */
/* $NetBSD: pdqreg.h,v 1.9 1998/05/21 20:44:03 matt Exp $ */
/*-
* Copyright (c) 1995, 1996 Matt Thomas <matt@3am-software.com>
@ -369,10 +369,11 @@ typedef struct {
* command is at least that long all will be fine.
*/
#if defined(__alpha) || defined(__alpha__)
pdq_uint32_t pdqdb_command_pool[144];
pdq_uint32_t pdqdb_command_pool[143];
#else
pdq_uint32_t pdqdb_command_pool[464];
pdq_uint32_t pdqdb_command_pool[463];
#endif
pdq_uint8_t pdqdb_tx_hdr[4];
} pdq_descriptor_block_t;
#define PDQ_SIZE_COMMAND_RESPONSE 512
@ -462,6 +463,7 @@ typedef struct {
pdq_uint32_t tx_completion;
} pdq_tx_info_t;
typedef struct _pdq_os_ctx_t pdq_os_ctx_t;
struct _pdq_t {
pdq_csrs_t pdq_csrs;
pdq_pci_csrs_t pdq_pci_csrs;
@ -482,16 +484,21 @@ struct _pdq_t {
#define PDQ_IS_FDX 0x0080
#define PDQ_IS_ONRING 0x0100
const char *pdq_os_name;
void *pdq_os_ctx;
pdq_os_ctx_t *pdq_os_ctx;
pdq_uint32_t pdq_unit;
pdq_command_info_t pdq_command_info;
pdq_unsolicited_info_t pdq_unsolicited_info;
pdq_tx_info_t pdq_tx_info;
pdq_rx_info_t pdq_rx_info;
pdq_rx_info_t pdq_host_smt_info;
pdq_uint8_t pdq_tx_hdr[3];
pdq_physaddr_t pdq_pa_consumer_block;
pdq_physaddr_t pdq_pa_descriptor_block;
};
#define PDQ_DB_BUSPA(pdq, m) \
((pdq)->pdq_pa_descriptor_block + \
((u_int8_t *) (m) - (u_int8_t *) (pdq)->pdq_dbp))
typedef enum {
PDQC_START=0,
PDQC_FILTER_SET=1,

View File

@ -1,4 +1,4 @@
/* $NetBSD: pdqvar.h,v 1.16 1998/04/07 13:32:07 matt Exp $ */
/* $NetBSD: pdqvar.h,v 1.17 1998/05/21 20:44:02 matt Exp $ */
/*-
* Copyright (c) 1995, 1996 Matt Thomas <matt@3am-software.com>
@ -90,17 +90,23 @@ enum _pdq_type_t {
#endif
#define PDQ_OS_USEC_DELAY(n) DELAY(n)
#define PDQ_OS_MEMZERO(p, n) bzero((caddr_t)(p), (n))
#if defined(__NetBSD__) && !defined(PDQ_NO_BUS_DMA)
#define PDQ_BUS_DMA
#endif
#if !defined(PDQ_BUS_DMA)
#if defined(__NetBSD__) && defined(__alpha__)
#define PDQ_OS_VA_TO_BUSPA(pdq, p) (alpha_XXX_dmamap((vm_offset_t)p))
#else
#define PDQ_OS_VA_TO_BUSPA(pdq, p) vtophys(p)
#endif
#endif
#define PDQ_OS_MEMALLOC(n) malloc(n, M_DEVBUF, M_NOWAIT)
#define PDQ_OS_MEMFREE(p, n) free((void *) p, M_DEVBUF)
#ifdef __FreeBSD__
#define PDQ_OS_MEMALLOC_CONTIG(n) vm_page_alloc_contig(n, 0, 0xffffffff, PAGE_SIZE)
#define PDQ_OS_MEMFREE_CONTIG(p, n) kmem_free(kernel_map, (vm_offset_t) p, n)
#else
#if !defined(PDQ_BUS_DMA)
#if defined(UVM)
#define PDQ_OS_MEMALLOC_CONTIG(n) uvm_km_alloc(kernel_map, round_page(n))
#define PDQ_OS_MEMFREE_CONTIG(p, n) uvm_km_free(kernel_map, (vm_offset_t) p, n)
@ -108,6 +114,7 @@ enum _pdq_type_t {
#define PDQ_OS_MEMALLOC_CONTIG(n) kmem_alloc(kernel_map, round_page(n))
#define PDQ_OS_MEMFREE_CONTIG(p, n) kmem_free(kernel_map, (vm_offset_t) p, n)
#endif
#endif
#endif /* __FreeBSD__ */
#if defined(__FreeBSD__)
@ -162,9 +169,67 @@ typedef bus_addr_t pdq_bus_memoffset_t;
#define PDQ_OS_IOWR_8(t, base, offset, data) bus_space_write_1 (t, base, offset, data)
#define PDQ_CSR_OFFSET(base, offset) (0 + (offset)*sizeof(pdq_uint32_t))
#define PDQ_OS_BUS_DMA_TOHOST BUS_BARRIER_READ
#define PDQ_OS_BUS_DMA_FROMHOST BUS_BARRIER_WRITE
#define PDQ_OS_BUS_DMA_SYNC(pdq, base, offset, length, why) bus_space_barrier((pdq)->pdq_csrs.csr_bus, base, offset, length, why)
#ifdef PDQ_BUS_DMA
#define PDQ_OS_UNSOL_EVENT_PRESYNC(pdq, event) \
pdq_os_unsolicited_event_sync((pdq)->pdq_os_ctx, \
(u_int8_t *) (event) - \
(u_int8_t *) (pdq)->pdq_unsolicited_info.ui_events, \
sizeof(*event), BUS_DMASYNC_PREREAD)
#define PDQ_OS_UNSOL_EVENT_POSTSYNC(pdq, event) \
pdq_os_unsolicited_event_sync((pdq)->pdq_os_ctx, \
(u_int8_t *) (event) - \
(u_int8_t *) (pdq)->pdq_unsolicited_info.ui_events, \
sizeof(*event), BUS_DMASYNC_POSTREAD)
#define PDQ_OS_DESCBLOCK_SYNC(pdq, what, length, why) \
pdq_os_descriptor_block_sync((pdq)->pdq_os_ctx, \
(u_int8_t *) (what) - (u_int8_t *) (pdq)->pdq_dbp, \
(length), (why))
#define PDQ_OS_CONSUMER_PRESYNC(pdq) \
PDQ_OS_DESCBLOCK_SYNC((pdq), (pdq)->pdq_cbp, sizeof((pdq)->pdq_cbp), \
BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE)
#define PDQ_OS_CONSUMER_POSTSYNC(pdq) \
PDQ_OS_DESCBLOCK_SYNC((pdq), (pdq)->pdq_cbp, sizeof((pdq)->pdq_cbp), \
BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE)
#define PDQ_OS_DESC_PRESYNC(pdq, d, s) \
PDQ_OS_DESCBLOCK_SYNC((pdq), (d), (s), BUS_DMASYNC_PREWRITE)
#define PDQ_OS_DESC_POSTSYNC(pdq, d, s) \
PDQ_OS_DESCBLOCK_SYNC((pdq), (d), (s), BUS_DMASYNC_POSTWRITE)
#define PDQ_OS_CMDRQST_PRESYNC(pdq, s) \
PDQ_OS_DESCBLOCK_SYNC((pdq), \
(pdq)->pdq_dbp->pdqdb_command_pool, \
(s), BUS_DMASYNC_PREWRITE)
#define PDQ_OS_CMDRSP_PRESYNC(pdq, s) \
PDQ_OS_DESCBLOCK_SYNC((pdq), \
(pdq)->pdq_dbp->pdqdb_command_pool, \
(s), BUS_DMASYNC_PREREAD)
#define PDQ_OS_CMDRQST_POSTSYNC(pdq, s) \
PDQ_OS_DESCBLOCK_SYNC((pdq), \
(pdq)->pdq_dbp->pdqdb_command_pool, \
(s), BUS_DMASYNC_POSTWRITE)
#define PDQ_OS_CMDRSP_POSTSYNC(pdq, s) \
PDQ_OS_DESCBLOCK_SYNC((pdq), \
(pdq)->pdq_dbp->pdqdb_command_pool, \
(s), BUS_DMASYNC_POSTREAD)
#define PDQ_OS_RXPDU_PRESYNC(pdq, b, o, l) \
pdq_os_databuf_sync((pdq)->pdq_os_ctx, (b), (o), (l), \
BUS_DMASYNC_PREREAD)
#define PDQ_OS_RXPDU_POSTSYNC(pdq, b, o, l) \
pdq_os_databuf_sync((pdq)->pdq_os_ctx, (b), (o), (l), \
BUS_DMASYNC_POSTREAD)
#define PDQ_OS_DATABUF_ALLOC(pdq, b) ((void)((b) = pdq_os_databuf_alloc((pdq)->pdq_os_ctx)))
#define PDQ_OS_DATABUF_FREE(pdq, b) pdq_os_databuf_free((pdq)->pdq_os_ctx, b)
#define PDQ_OS_DATABUF_BUSPA(pdq, b) (M_GETCTX((b), bus_dmamap_t)->dm_segs[0].ds_addr + 0)
struct _pdq_os_ctx_t;
extern void pdq_os_descriptor_block_sync(struct _pdq_os_ctx_t *osctx, size_t offset,
size_t length, int ops);
extern void pdq_os_unsolicited_event_sync(struct _pdq_os_ctx_t *osctx, size_t offset,
size_t length, int ops);
extern struct mbuf *pdq_os_databuf_alloc(struct _pdq_os_ctx_t *osctx);
extern void pdq_os_databuf_sync(struct _pdq_os_ctx_t *osctx, struct mbuf *b,
size_t offset, size_t length, int ops);
extern void pdq_os_databuf_free(struct _pdq_os_ctx_t *osctx, struct mbuf *m);
#define M_HASDMAMAP M_LINK2
#endif
#define PDQ_CSR_WRITE(csr, name, data) PDQ_OS_IOWR_32((csr)->csr_bus, (csr)->csr_base, (csr)->name, data)
#define PDQ_CSR_READ(csr, name) PDQ_OS_IORD_32((csr)->csr_bus, (csr)->csr_base, (csr)->name)
@ -229,7 +294,7 @@ typedef bus_addr_t pdq_bus_memoffset_t;
#if !defined(PDQ_HWSUPPORT)
typedef struct {
typedef struct _pdq_os_ctx_t {
#if defined(__bsdi__)
struct device sc_dev; /* base device */
struct isadev sc_id; /* ISA device */
@ -242,6 +307,7 @@ typedef struct {
void *sc_ih; /* interrupt vectoring */
void *sc_ats; /* shutdown hook */
struct ethercom sc_ec;
bus_dma_tag_t sc_dmatag;
#define sc_if sc_ec.ec_if
#elif defined(__FreeBSD__)
struct kern_devconf *sc_kdc; /* freebsd cruft */
@ -267,6 +333,13 @@ typedef struct {
#else
caddr_t sc_bpf;
#endif
#if defined(PDQ_BUS_DMA)
#if !defined(__NetBSD__)
bus_dma_tag_t sc_dmatag;
#endif
bus_dmamap_t sc_dbmap; /* DMA map for descriptor block */
bus_dmamap_t sc_uimap; /* DMA map for unsolicited events */
#endif
} pdq_softc_t;
@ -301,7 +374,7 @@ extern void pdq_ifattach(pdq_softc_t *sc, ifnet_ret_t (*ifwatchdog)(int unit));
extern physreq_t *decfddiphysreq_db;
extern physreq_t *decfddiphysreq_mblk;
#define PDQ_OS_DATABUF_ALLOC(b) ((void) (((b) = allocb_physreq(PDQ_OS_DATABUF_SIZE, BPRI_MED, decfddiphysreq_mblk)) && ((b)->b_wptr = (b)->b_rptr + PDQ_OS_DATABUF_SIZE)))
#define PDQ_OS_DATABUF_ALLOC(pdq, b) ((void) (((b) = allocb_physreq(PDQ_OS_DATABUF_SIZE, BPRI_MED, decfddiphysreq_mblk)) && ((b)->b_wptr = (b)->b_rptr + PDQ_OS_DATABUF_SIZE)))
#define PDQ_OS_IORD_8(port) inb(port)
#define PDQ_OS_IOWR_8(port, data) outb(port, data)
@ -310,7 +383,9 @@ extern physreq_t *decfddiphysreq_mblk;
#ifdef PDQ_USE_MBUFS
#define PDQ_OS_DATABUF_SIZE (MCLBYTES)
#define PDQ_OS_DATABUF_FREE(b) (m_freem(b))
#ifndef PDQ_OS_DATABUF_FREE
#define PDQ_OS_DATABUF_FREE(pdq, b) (m_freem(b))
#endif
#define PDQ_OS_DATABUF_NEXT(b) ((b)->m_next)
#define PDQ_OS_DATABUF_NEXT_SET(b, b1) ((b)->m_next = (b1))
#define PDQ_OS_DATABUF_NEXTPKT(b) ((b)->m_nextpkt)
@ -322,7 +397,8 @@ extern physreq_t *decfddiphysreq_mblk;
#define PDQ_OS_DATABUF_ADJ(b, n) ((b)->m_data += (n), (b)->m_len -= (n))
typedef struct mbuf PDQ_OS_DATABUF_T;
#define PDQ_OS_DATABUF_ALLOC(b) do { \
#ifndef PDQ_OS_DATABUF_ALLOC
#define PDQ_OS_DATABUF_ALLOC(pdq, b) do { \
PDQ_OS_DATABUF_T *x_m0; \
MGETHDR(x_m0, M_DONTWAIT, MT_DATA); \
if (x_m0 != NULL) { \
@ -338,12 +414,13 @@ typedef struct mbuf PDQ_OS_DATABUF_T;
(b) = NULL; \
} \
} while (0)
#endif
#define PDQ_OS_DATABUF_RESET(b) ((b)->m_data = (b)->m_ext.ext_buf, (b)->m_len = MCLBYTES)
#endif /* PDQ_USE_MBUFS */
#ifdef PDQ_USE_STREAMS
#define PDQ_OS_DATABUF_SIZE (2048)
#define PDQ_OS_DATABUF_FREE(b) (freemsg(b))
#define PDQ_OS_DATABUF_FREE(pdq, b) (freemsg(b))
#define PDQ_OS_DATABUF_NEXT(b) ((b)->b_cont)
#define PDQ_OS_DATABUF_NEXT_SET(b, b1) ((b)->b_cont = (b1))
#define PDQ_OS_DATABUF_NEXTPKT(b) ((b)->b_next)
@ -356,7 +433,7 @@ typedef struct mbuf PDQ_OS_DATABUF_T;
typedef mblk_t PDQ_OS_DATABUF_T;
#ifndef PDQ_OS_DATABUF_ALLOC
#define PDQ_OS_DATABUF_ALLOC(b) ((void) (((b) = allocb(PDQ_OS_DATABUF_SIZE, BPRI_MED)) && ((b)->b_wptr = (b)->b_rptr + PDQ_OS_DATABUF_SIZE)))
#define PDQ_OS_DATABUF_ALLOC(pdq, b) ((void) (((b) = allocb(PDQ_OS_DATABUF_SIZE, BPRI_MED)) && ((b)->b_wptr = (b)->b_rptr + PDQ_OS_DATABUF_SIZE)))
#endif /* PDQ_OS_DATABUF_ALLOC */
#endif /* PDQ_USE_STREAMS */
@ -379,10 +456,21 @@ typedef mblk_t PDQ_OS_DATABUF_T;
} \
} while (0)
#if !defined(PDQ_OS_BUS_DMA_SYNC)
#define PDQ_OS_BUS_DMA_TOHOST 0x01
#define PDQ_OS_BUS_DMA_FROMHOST 0x02
#define PDQ_OS_BUS_DMA_SYNC(t, base, offset, length, why) do { } while(0)
#if !defined(PDQ_OS_CONSUMER_PRESYNC)
#define PDQ_OS_CONSUMER_PRESYNC(pdq) do { } while(0)
#define PDQ_OS_CONSUMER_POSTSYNC(pdq) do { } while(0)
#define PDQ_OS_DESC_PRESYNC(pdq, d, s) do { } while(0)
#define PDQ_OS_DESC_POSTSYNC(pdq, d, s) do { } while(0)
#define PDQ_OS_CMDRQST_PRESYNC(pdq, s) do { } while(0)
#define PDQ_OS_CMDRSP_PRESYNC(pdq, s) do { } while(0)
#define PDQ_OS_RXPDU_PRESYNC(pdq, b, o, l) do { } while(0)
#define PDQ_OS_RXPDU_POSTSYNC(pdq, b, o, l) do { } while(0)
#define PDQ_OS_UNSOL_EVENT_PRESYNC(pdq, e) do { } while(0)
#define PDQ_OS_UNSOL_EVENT_POSTSYNC(pdq, e) do { } while(0)
#endif
#ifndef PDQ_OS_DATABUF_BUSPA
#define PDQ_OS_DATABUF_BUSPA(pdq, b) PDQ_OS_VA_TO_BUSPA(pdq, PDQ_OS_DATABUF_PTR(b))
#endif
extern void pdq_os_addr_fill(pdq_t *pdq, pdq_lanaddr_t *addrs, size_t numaddrs);
@ -392,6 +480,9 @@ extern void pdq_os_transmit_done(pdq_t *pdq, PDQ_OS_DATABUF_T *pdu);
#if !defined(pdq_os_update_status)
extern void pdq_os_update_status(pdq_t *pdq, const void *rsp);
#endif
#if !defined(PDQ_OS_MEMALLOC_CONTIG)
extern int pdq_os_memalloc_contig(pdq_t *pdq);
#endif
extern pdq_boolean_t pdq_queue_transmit_data(pdq_t *pdq, PDQ_OS_DATABUF_T *pdu);
extern void pdq_flush_transmitter(pdq_t *pdq);

View File

@ -1,4 +1,4 @@
/* $NetBSD: if_fpa.c,v 1.24 1998/01/12 09:40:01 thorpej Exp $ */
/* $NetBSD: if_fpa.c,v 1.25 1998/05/21 20:44:03 matt Exp $ */
/*-
* Copyright (c) 1995, 1996 Matt Thomas <matt@3am-software.com>
@ -466,6 +466,7 @@ pdq_pci_attach(
return;
}
sc->sc_dmatag = pa->pa_dmat;
sc->sc_pdq = pdq_initialize(sc->sc_csrtag, sc->sc_membase,
sc->sc_if.if_xname, 0,
(void *) sc, PDQ_DEFPA);

View File

@ -1,4 +1,4 @@
/* $NetBSD: if_fta.c,v 1.13 1998/01/12 09:51:31 thorpej Exp $ */
/* $NetBSD: if_fta.c,v 1.14 1998/05/21 20:44:03 matt Exp $ */
/*-
* Copyright (c) 1996 Matt Thomas <matt@3am-software.com>
@ -90,6 +90,7 @@ pdq_tc_attach(
* NOTE: sc_bc is an alias for sc_csrtag and sc_membase is an
* alias for sc_csrhandle. sc_iobase is not used in this front-end.
*/
sc->sc_dmatag = ta->ta_dmat;
sc->sc_csrtag = ta->ta_memt;
bcopy(sc->sc_dev.dv_xname, sc->sc_if.if_xname, IFNAMSIZ);
sc->sc_if.if_flags = 0;