aboutsummaryrefslogtreecommitdiff
path: root/sys/dev/ntb/ntb_transport.c
diff options
context:
space:
mode:
authorAlexander Motin <mav@FreeBSD.org>2016-07-09 11:40:59 +0000
committerAlexander Motin <mav@FreeBSD.org>2016-07-09 11:40:59 +0000
commit0c84bc33cfdeb597ac65ce3b6880ae9c698f1a0b (patch)
tree51f651bc63dbf843ab13d5ef66984fd22d6e7a03 /sys/dev/ntb/ntb_transport.c
parentf7be35856a3353461246bb41810b45c095bcafb1 (diff)
downloadsrc-0c84bc33cfdeb597ac65ce3b6880ae9c698f1a0b.tar.gz
src-0c84bc33cfdeb597ac65ce3b6880ae9c698f1a0b.zip
Reduce code divergence from Linux, preparing for DMA support.
Notes
Notes: svn path=/head/; revision=302487
Diffstat (limited to 'sys/dev/ntb/ntb_transport.c')
-rw-r--r--sys/dev/ntb/ntb_transport.c132
1 files changed, 73 insertions, 59 deletions
diff --git a/sys/dev/ntb/ntb_transport.c b/sys/dev/ntb/ntb_transport.c
index e2c67772146b..38c7b333e2bb 100644
--- a/sys/dev/ntb/ntb_transport.c
+++ b/sys/dev/ntb/ntb_transport.c
@@ -264,8 +264,6 @@ static void ntb_transport_init_queue(struct ntb_transport_ctx *nt,
unsigned int qp_num);
static int ntb_process_tx(struct ntb_transport_qp *qp,
struct ntb_queue_entry *entry);
-static void ntb_memcpy_tx(struct ntb_transport_qp *qp,
- struct ntb_queue_entry *entry, void *offset);
static void ntb_transport_rxc_db(void *arg, int pending);
static int ntb_process_rxc(struct ntb_transport_qp *qp);
static void ntb_memcpy_rx(struct ntb_transport_qp *qp,
@@ -586,11 +584,13 @@ ntb_transport_create_queue(void *data, device_t dev,
entry->cb_data = data;
entry->buf = NULL;
entry->len = transport_mtu;
+ entry->qp = qp;
ntb_list_add(&qp->ntb_rx_q_lock, entry, &qp->rx_pend_q);
}
for (i = 0; i < NTB_QP_DEF_NUM_ENTRIES; i++) {
entry = malloc(sizeof(*entry), M_NTB_T, M_WAITOK | M_ZERO);
+ entry->qp = qp;
ntb_list_add(&qp->ntb_tx_free_q_lock, entry, &qp->tx_free_q);
}
@@ -672,60 +672,44 @@ ntb_transport_tx_enqueue(struct ntb_transport_qp *qp, void *cb, void *data,
return (rc);
}
-static int
-ntb_process_tx(struct ntb_transport_qp *qp, struct ntb_queue_entry *entry)
+static void
+ntb_tx_copy_callback(void *data)
{
- void *offset;
+ struct ntb_queue_entry *entry = data;
+ struct ntb_transport_qp *qp = entry->qp;
+ struct ntb_payload_header *hdr = entry->x_hdr;
- offset = qp->tx_mw + qp->tx_max_frame * qp->tx_index;
- CTR3(KTR_NTB,
- "TX: process_tx: tx_pkts=%lu, tx_index=%u, remote entry=%u",
- qp->tx_pkts, qp->tx_index, qp->remote_rx_info->entry);
- if (qp->tx_index == qp->remote_rx_info->entry) {
- CTR0(KTR_NTB, "TX: ring full");
- qp->tx_ring_full++;
- return (EAGAIN);
- }
+ iowrite32(entry->flags | NTBT_DESC_DONE_FLAG, &hdr->flags);
+ CTR1(KTR_NTB, "TX: hdr %p set DESC_DONE", hdr);
- if (entry->len > qp->tx_max_frame - sizeof(struct ntb_payload_header)) {
- if (qp->tx_handler != NULL)
+ NTB_PEER_DB_SET(qp->ntb, 1ull << qp->qp_num);
+
+ /*
+ * The entry length can only be zero if the packet is intended to be a
+ * "link down" or similar. Since no payload is being sent in these
+ * cases, there is nothing to add to the completion queue.
+ */
+ if (entry->len > 0) {
+ qp->tx_bytes += entry->len;
+
+ if (qp->tx_handler)
qp->tx_handler(qp, qp->cb_data, entry->buf,
- EIO);
+ entry->len);
else
m_freem(entry->buf);
-
entry->buf = NULL;
- ntb_list_add(&qp->ntb_tx_free_q_lock, entry, &qp->tx_free_q);
- CTR1(KTR_NTB,
- "TX: frame too big. returning entry %p to tx_free_q",
- entry);
- return (0);
}
- CTR2(KTR_NTB, "TX: copying entry %p to offset %p", entry, offset);
- ntb_memcpy_tx(qp, entry, offset);
-
- qp->tx_index++;
- qp->tx_index %= qp->tx_max_entry;
- qp->tx_pkts++;
-
- return (0);
+ CTR3(KTR_NTB,
+ "TX: entry %p sent. hdr->ver = %u, hdr->flags = 0x%x, Returning "
+ "to tx_free_q", entry, hdr->ver, hdr->flags);
+ ntb_list_add(&qp->ntb_tx_free_q_lock, entry, &qp->tx_free_q);
}
static void
-ntb_memcpy_tx(struct ntb_transport_qp *qp, struct ntb_queue_entry *entry,
- void *offset)
+ntb_memcpy_tx(struct ntb_queue_entry *entry, void *offset)
{
- struct ntb_payload_header *hdr;
-
- /* This piece is from Linux' ntb_async_tx() */
- hdr = (struct ntb_payload_header *)((char *)offset + qp->tx_max_frame -
- sizeof(struct ntb_payload_header));
- entry->x_hdr = hdr;
- iowrite32(entry->len, &hdr->len);
- iowrite32(qp->tx_pkts, &hdr->ver);
- /* This piece is ntb_memcpy_tx() */
CTR2(KTR_NTB, "TX: copying %d bytes to offset %p", entry->len, offset);
if (entry->buf != NULL) {
m_copydata((struct mbuf *)entry->buf, 0, entry->len, offset);
@@ -737,32 +721,62 @@ ntb_memcpy_tx(struct ntb_transport_qp *qp, struct ntb_queue_entry *entry,
wmb();
}
- /* The rest is ntb_tx_copy_callback() */
- iowrite32(entry->flags | NTBT_DESC_DONE_FLAG, &hdr->flags);
- CTR1(KTR_NTB, "TX: hdr %p set DESC_DONE", hdr);
+ ntb_tx_copy_callback(entry);
+}
- NTB_PEER_DB_SET(qp->ntb, 1ull << qp->qp_num);
+static void
+ntb_async_tx(struct ntb_transport_qp *qp, struct ntb_queue_entry *entry)
+{
+ struct ntb_payload_header *hdr;
+ void *offset;
- /*
- * The entry length can only be zero if the packet is intended to be a
- * "link down" or similar. Since no payload is being sent in these
- * cases, there is nothing to add to the completion queue.
- */
- if (entry->len > 0) {
- qp->tx_bytes += entry->len;
+ offset = qp->tx_mw + qp->tx_max_frame * qp->tx_index;
+ hdr = (struct ntb_payload_header *)((char *)offset + qp->tx_max_frame -
+ sizeof(struct ntb_payload_header));
+ entry->x_hdr = hdr;
- if (qp->tx_handler)
+ iowrite32(entry->len, &hdr->len);
+ iowrite32(qp->tx_pkts, &hdr->ver);
+
+ ntb_memcpy_tx(entry, offset);
+}
+
+static int
+ntb_process_tx(struct ntb_transport_qp *qp, struct ntb_queue_entry *entry)
+{
+
+ CTR3(KTR_NTB,
+ "TX: process_tx: tx_pkts=%lu, tx_index=%u, remote entry=%u",
+ qp->tx_pkts, qp->tx_index, qp->remote_rx_info->entry);
+ if (qp->tx_index == qp->remote_rx_info->entry) {
+ CTR0(KTR_NTB, "TX: ring full");
+ qp->tx_ring_full++;
+ return (EAGAIN);
+ }
+
+ if (entry->len > qp->tx_max_frame - sizeof(struct ntb_payload_header)) {
+ if (qp->tx_handler != NULL)
qp->tx_handler(qp, qp->cb_data, entry->buf,
- entry->len);
+ EIO);
else
m_freem(entry->buf);
+
entry->buf = NULL;
+ ntb_list_add(&qp->ntb_tx_free_q_lock, entry, &qp->tx_free_q);
+ CTR1(KTR_NTB,
+ "TX: frame too big. returning entry %p to tx_free_q",
+ entry);
+ return (0);
}
+ CTR2(KTR_NTB, "TX: copying entry %p to index %u", entry, qp->tx_index);
+ ntb_async_tx(qp, entry);
- CTR3(KTR_NTB,
- "TX: entry %p sent. hdr->ver = %u, hdr->flags = 0x%x, Returning "
- "to tx_free_q", entry, hdr->ver, hdr->flags);
- ntb_list_add(&qp->ntb_tx_free_q_lock, entry, &qp->tx_free_q);
+ qp->tx_index++;
+ qp->tx_index %= qp->tx_max_entry;
+
+ qp->tx_pkts++;
+
+ return (0);
}
/* Transport Rx */