static void ntb_memcpy_tx(struct ntb_transport_qp *qp, 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); /* * Ensure that the data is fully copied before setting the * flags */ wmb(); } /* The rest is ntb_tx_copy_callback() */ iowrite32(entry->flags | IF_NTB_DESC_DONE_FLAG, &hdr->flags); CTR1(KTR_NTB, "TX: hdr %p set DESC_DONE", hdr); 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, entry->len); else m_freem(entry->buf); entry->buf = NULL; } 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 pp_ping(struct pp_ctx *pp) { u32 count; count = atomic_read(&pp->count); spin_lock(&pp->lock); ntb_peer_spad_write(pp->ntb, pp->out_pidx, 0, count); ntb_peer_msg_write(pp->ntb, pp->out_pidx, 0, count); dev_dbg(&pp->ntb->dev, "Ping port %d spad %#x, msg %#x\n", ntb_peer_port_number(pp->ntb, pp->out_pidx), count, count); ntb_peer_db_set(pp->ntb, pp->out_db); ntb_db_clear_mask(pp->ntb, pp->in_db); spin_unlock(&pp->lock); }