162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 or BSD-3-Clause */
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * Copyright(c) 2016 - 2018 Intel Corporation.
462306a36Sopenharmony_ci */
562306a36Sopenharmony_ci
662306a36Sopenharmony_ci#ifndef HFI1_VERBS_TXREQ_H
762306a36Sopenharmony_ci#define HFI1_VERBS_TXREQ_H
862306a36Sopenharmony_ci
962306a36Sopenharmony_ci#include <linux/types.h>
1062306a36Sopenharmony_ci#include <linux/slab.h>
1162306a36Sopenharmony_ci
1262306a36Sopenharmony_ci#include "verbs.h"
1362306a36Sopenharmony_ci#include "sdma_txreq.h"
1462306a36Sopenharmony_ci#include "iowait.h"
1562306a36Sopenharmony_ci
1662306a36Sopenharmony_cistruct verbs_txreq {
1762306a36Sopenharmony_ci	struct hfi1_sdma_header	phdr;
1862306a36Sopenharmony_ci	struct sdma_txreq       txreq;
1962306a36Sopenharmony_ci	struct rvt_qp           *qp;
2062306a36Sopenharmony_ci	struct rvt_swqe         *wqe;
2162306a36Sopenharmony_ci	struct rvt_mregion	*mr;
2262306a36Sopenharmony_ci	struct rvt_sge_state    *ss;
2362306a36Sopenharmony_ci	struct sdma_engine     *sde;
2462306a36Sopenharmony_ci	struct send_context     *psc;
2562306a36Sopenharmony_ci	u16                     hdr_dwords;
2662306a36Sopenharmony_ci	u16			s_cur_size;
2762306a36Sopenharmony_ci};
2862306a36Sopenharmony_ci
2962306a36Sopenharmony_cistruct hfi1_ibdev;
3062306a36Sopenharmony_cistruct verbs_txreq *__get_txreq(struct hfi1_ibdev *dev,
3162306a36Sopenharmony_ci				struct rvt_qp *qp);
3262306a36Sopenharmony_ci
3362306a36Sopenharmony_ci#define VERBS_TXREQ_GFP (GFP_ATOMIC | __GFP_NOWARN)
3462306a36Sopenharmony_cistatic inline struct verbs_txreq *get_txreq(struct hfi1_ibdev *dev,
3562306a36Sopenharmony_ci					    struct rvt_qp *qp)
3662306a36Sopenharmony_ci	__must_hold(&qp->slock)
3762306a36Sopenharmony_ci{
3862306a36Sopenharmony_ci	struct verbs_txreq *tx;
3962306a36Sopenharmony_ci	struct hfi1_qp_priv *priv = qp->priv;
4062306a36Sopenharmony_ci
4162306a36Sopenharmony_ci	tx = kmem_cache_alloc(dev->verbs_txreq_cache, VERBS_TXREQ_GFP);
4262306a36Sopenharmony_ci	if (unlikely(!tx)) {
4362306a36Sopenharmony_ci		/* call slow path to get the lock */
4462306a36Sopenharmony_ci		tx = __get_txreq(dev, qp);
4562306a36Sopenharmony_ci		if (!tx)
4662306a36Sopenharmony_ci			return tx;
4762306a36Sopenharmony_ci	}
4862306a36Sopenharmony_ci	tx->qp = qp;
4962306a36Sopenharmony_ci	tx->mr = NULL;
5062306a36Sopenharmony_ci	tx->sde = priv->s_sde;
5162306a36Sopenharmony_ci	tx->psc = priv->s_sendcontext;
5262306a36Sopenharmony_ci	/* so that we can test if the sdma descriptors are there */
5362306a36Sopenharmony_ci	tx->txreq.num_desc = 0;
5462306a36Sopenharmony_ci	/* Set the header type */
5562306a36Sopenharmony_ci	tx->phdr.hdr.hdr_type = priv->hdr_type;
5662306a36Sopenharmony_ci	tx->txreq.flags = 0;
5762306a36Sopenharmony_ci	return tx;
5862306a36Sopenharmony_ci}
5962306a36Sopenharmony_ci
6062306a36Sopenharmony_cistatic inline struct verbs_txreq *get_waiting_verbs_txreq(struct iowait_work *w)
6162306a36Sopenharmony_ci{
6262306a36Sopenharmony_ci	struct sdma_txreq *stx;
6362306a36Sopenharmony_ci
6462306a36Sopenharmony_ci	stx = iowait_get_txhead(w);
6562306a36Sopenharmony_ci	if (stx)
6662306a36Sopenharmony_ci		return container_of(stx, struct verbs_txreq, txreq);
6762306a36Sopenharmony_ci	return NULL;
6862306a36Sopenharmony_ci}
6962306a36Sopenharmony_ci
7062306a36Sopenharmony_cistatic inline bool verbs_txreq_queued(struct iowait_work *w)
7162306a36Sopenharmony_ci{
7262306a36Sopenharmony_ci	return iowait_packet_queued(w);
7362306a36Sopenharmony_ci}
7462306a36Sopenharmony_ci
7562306a36Sopenharmony_civoid hfi1_put_txreq(struct verbs_txreq *tx);
7662306a36Sopenharmony_ciint verbs_txreq_init(struct hfi1_ibdev *dev);
7762306a36Sopenharmony_civoid verbs_txreq_exit(struct hfi1_ibdev *dev);
7862306a36Sopenharmony_ci
7962306a36Sopenharmony_ci#endif                         /* HFI1_VERBS_TXREQ_H */
80