// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * RDMA Transport Layer
 *
 * Copyright (c) 2014 - 2018 ProfitBricks GmbH. All rights reserved.
 * Copyright (c) 2018 - 2019 1&1 IONOS Cloud GmbH. All rights reserved.
 * Copyright (c) 2019 - 2020 1&1 IONOS SE. All rights reserved.
 */
#undef pr_fmt
#define pr_fmt(fmt) KBUILD_MODNAME " L" __stringify(__LINE__) ": " fmt

#include <linux/module.h>
#include <linux/inet.h>

#include "rtrs-pri.h"
#include "rtrs-log.h"

MODULE_DESCRIPTION("RDMA Transport Core");
MODULE_LICENSE("GPL");

struct rtrs_iu *rtrs_iu_alloc(u32 queue_size, size_t size, gfp_t gfp_mask,
			      struct ib_device *dma_dev,
			      enum dma_data_direction dir,
			      void (*done)(struct ib_cq *cq, struct ib_wc *wc))
{
	struct rtrs_iu *ius, *iu;
	int i;

	ius = kcalloc(queue_size, sizeof(*ius), gfp_mask);
	if (!ius)
		return NULL;
	for (i = 0; i < queue_size; i++) {
		iu = &ius[i];
		iu->buf = kzalloc(size, gfp_mask);
		if (!iu->buf)
			goto err;

		iu->dma_addr = ib_dma_map_single(dma_dev, iu->buf, size, dir);
		if (ib_dma_mapping_error(dma_dev, iu->dma_addr))
			goto err;

		iu->cqe.done  = done;
		iu->size      = size;
		iu->direction = dir;
	}
	return ius;
err:
	rtrs_iu_free(ius, dir, dma_dev, i);
	return NULL;
}
EXPORT_SYMBOL_GPL(rtrs_iu_alloc);

void rtrs_iu_free(struct rtrs_iu *ius, enum dma_data_direction dir,
		   struct ib_device *ibdev, u32 queue_size)
{
	struct rtrs_iu *iu;
	int i;

	if (!ius)
		return;

	for (i = 0; i < queue_size; i++) {
		iu = &ius[i];
		ib_dma_unmap_single(ibdev, iu->dma_addr, iu->size, dir);
		kfree(iu->buf);
	}
	kfree(ius);
}
EXPORT_SYMBOL_GPL(rtrs_iu_free);

int rtrs_iu_post_recv(struct rtrs_con *con, struct rtrs_iu *iu)
{
	struct rtrs_sess *sess = con->sess;
	struct ib_recv_wr wr;
	struct ib_sge list;

	list.addr   = iu->dma_addr;
	list.length = iu->size;
	list.lkey   = sess->dev->ib_pd->local_dma_lkey;

	if (list.length == 0) {
		rtrs_wrn(con->sess,
			  "Posting receive work request failed, sg list is empty\n");
		return -EINVAL;
	}
	wr = (struct ib_recv_wr) {
		.wr_cqe  = &iu->cqe,
		.sg_list = &list,
		.num_sge = 1,
	};

	return ib_post_recv(con->qp, &wr, NULL);
}
EXPORT_SYMBOL_GPL(rtrs_iu_post_recv);

int rtrs_post_recv_empty(struct rtrs_con *con, struct ib_cqe *cqe)
{
	struct ib_recv_wr wr;

	wr = (struct ib_recv_wr) {
		.wr_cqe  = cqe,
	};

	return ib_post_recv(con->qp, &wr, NULL);
}
EXPORT_SYMBOL_GPL(rtrs_post_recv_empty);

int rtrs_iu_post_send(struct rtrs_con *con, struct rtrs_iu *iu, size_t size,
		       struct ib_send_wr *head)
{
	struct rtrs_sess *sess = con->sess;
	struct ib_send_wr wr;
	struct ib_sge list;

	if (WARN_ON(size == 0))
		return -EINVAL;

	list.addr   = iu->dma_addr;
	list.length = size;
	list.lkey   = sess->dev->ib_pd->local_dma_lkey;

	wr = (struct ib_send_wr) {
		.wr_cqe     = &iu->cqe,
		.sg_list    = &list,
		.num_sge    = 1,
		.opcode     = IB_WR_SEND,
		.send_flags = IB_SEND_SIGNALED,
	};

	if (head) {
		struct ib_send_wr *tail = head;

		while (tail->next)
			tail = tail->next;
		tail->next = &wr;
	} else {
		head = &wr;
	}

	return ib_post_send(con->qp, head, NULL);
}
EXPORT_SYMBOL_GPL(rtrs_iu_post_send);

int rtrs_iu_post_rdma_write_imm(struct rtrs_con *con, struct rtrs_iu *iu,
				 struct ib_sge *sge, unsigned int num_sge,
				 u32 rkey, u64 rdma_addr, u32 imm_data,
				 enum ib_send_flags flags,
				 struct ib_send_wr *head)
{
	struct ib_rdma_wr wr;
	int i;

	wr = (struct ib_rdma_wr) {
		.wr.wr_cqe	  = &iu->cqe,
		.wr.sg_list	  = sge,
		.wr.num_sge	  = num_sge,
		.rkey		  = rkey,
		.remote_addr	  = rdma_addr,
		.wr.opcode	  = IB_WR_RDMA_WRITE_WITH_IMM,
		.wr.ex.imm_data = cpu_to_be32(imm_data),
		.wr.send_flags  = flags,
	};

	/*
	 * If one of the sges has 0 size, the operation will fail with a
	 * length error
	 */
	for (i = 0; i < num_sge; i++)
		if (WARN_ON(sge[i].length == 0))
			return -EINVAL;

	if (head) {
		struct ib_send_wr *tail = head;

		while (tail->next)
			tail = tail->next;
		tail->next = &wr.wr;
	} else {
		head = &wr.wr;
	}

	return ib_post_send(con->qp, head, NULL);
}
EXPORT_SYMBOL_GPL(rtrs_iu_post_rdma_write_imm);

int rtrs_post_rdma_write_imm_empty(struct rtrs_con *con, struct ib_cqe *cqe,
				    u32 imm_data, enum ib_send_flags flags,
				    struct ib_send_wr *head)
{
	struct ib_send_wr wr;

	wr = (struct ib_send_wr) {
		.wr_cqe	= cqe,
		.send_flags	= flags,
		.opcode	= IB_WR_RDMA_WRITE_WITH_IMM,
		.ex.imm_data	= cpu_to_be32(imm_data),
	};

	if (head) {
		struct ib_send_wr *tail = head;

		while (tail->next)
			tail = tail->next;
		tail->next = &wr;
	} else {
		head = &wr;
	}

	return ib_post_send(con->qp, head, NULL);
}
EXPORT_SYMBOL_GPL(rtrs_post_rdma_write_imm_empty);

static void qp_event_handler(struct ib_event *ev, void *ctx)
{
	struct rtrs_con *con = ctx;

	switch (ev->event) {
	case IB_EVENT_COMM_EST:
		rtrs_info(con->sess, "QP event %s (%d) received\n",
			   ib_event_msg(ev->event), ev->event);
		rdma_notify(con->cm_id, IB_EVENT_COMM_EST);
		break;
	default:
		rtrs_info(con->sess, "Unhandled QP event %s (%d) received\n",
			   ib_event_msg(ev->event), ev->event);
		break;
	}
}

static int create_cq(struct rtrs_con *con, int cq_vector, u16 cq_size,
		     enum ib_poll_context poll_ctx)
{
	struct rdma_cm_id *cm_id = con->cm_id;
	struct ib_cq *cq;

	cq = ib_alloc_cq(cm_id->device, con, cq_size,
			 cq_vector, poll_ctx);
	if (IS_ERR(cq)) {
		rtrs_err(con->sess, "Creating completion queue failed, errno: %ld\n",
			  PTR_ERR(cq));
		return PTR_ERR(cq);
	}
	con->cq = cq;

	return 0;
}

static int create_qp(struct rtrs_con *con, struct ib_pd *pd,
		     u16 wr_queue_size, u32 max_sge)
{
	struct ib_qp_init_attr init_attr = {NULL};
	struct rdma_cm_id *cm_id = con->cm_id;
	int ret;

	init_attr.cap.max_send_wr = wr_queue_size;
	init_attr.cap.max_recv_wr = wr_queue_size;
	init_attr.cap.max_recv_sge = 1;
	init_attr.event_handler = qp_event_handler;
	init_attr.qp_context = con;
	init_attr.cap.max_send_sge = max_sge;

	init_attr.qp_type = IB_QPT_RC;
	init_attr.send_cq = con->cq;
	init_attr.recv_cq = con->cq;
	init_attr.sq_sig_type = IB_SIGNAL_REQ_WR;

	ret = rdma_create_qp(cm_id, pd, &init_attr);
	if (ret) {
		rtrs_err(con->sess, "Creating QP failed, err: %d\n", ret);
		return ret;
	}
	con->qp = cm_id->qp;

	return ret;
}

int rtrs_cq_qp_create(struct rtrs_sess *sess, struct rtrs_con *con,
		       u32 max_send_sge, int cq_vector, u16 cq_size,
		       u16 wr_queue_size, enum ib_poll_context poll_ctx)
{
	int err;

	err = create_cq(con, cq_vector, cq_size, poll_ctx);
	if (err)
		return err;

	err = create_qp(con, sess->dev->ib_pd, wr_queue_size, max_send_sge);
	if (err) {
		ib_free_cq(con->cq);
		con->cq = NULL;
		return err;
	}
	con->sess = sess;

	return 0;
}
EXPORT_SYMBOL_GPL(rtrs_cq_qp_create);

void rtrs_cq_qp_destroy(struct rtrs_con *con)
{
	if (con->qp) {
		rdma_destroy_qp(con->cm_id);
		con->qp = NULL;
	}
	if (con->cq) {
		ib_free_cq(con->cq);
		con->cq = NULL;
	}
}
EXPORT_SYMBOL_GPL(rtrs_cq_qp_destroy);

static void schedule_hb(struct rtrs_sess *sess)
{
	queue_delayed_work(sess->hb_wq, &sess->hb_dwork,
			   msecs_to_jiffies(sess->hb_interval_ms));
}

void rtrs_send_hb_ack(struct rtrs_sess *sess)
{
	struct rtrs_con *usr_con = sess->con[0];
	u32 imm;
	int err;

	imm = rtrs_to_imm(RTRS_HB_ACK_IMM, 0);
	err = rtrs_post_rdma_write_imm_empty(usr_con, sess->hb_cqe, imm,
					      IB_SEND_SIGNALED, NULL);
	if (err) {
		sess->hb_err_handler(usr_con);
		return;
	}
}
EXPORT_SYMBOL_GPL(rtrs_send_hb_ack);

static void hb_work(struct work_struct *work)
{
	struct rtrs_con *usr_con;
	struct rtrs_sess *sess;
	u32 imm;
	int err;

	sess = container_of(to_delayed_work(work), typeof(*sess), hb_dwork);
	usr_con = sess->con[0];

	if (sess->hb_missed_cnt > sess->hb_missed_max) {
		sess->hb_err_handler(usr_con);
		return;
	}
	if (sess->hb_missed_cnt++) {
		/* Reschedule work without sending hb */
		schedule_hb(sess);
		return;
	}
	imm = rtrs_to_imm(RTRS_HB_MSG_IMM, 0);
	err = rtrs_post_rdma_write_imm_empty(usr_con, sess->hb_cqe, imm,
					      IB_SEND_SIGNALED, NULL);
	if (err) {
		sess->hb_err_handler(usr_con);
		return;
	}

	schedule_hb(sess);
}

void rtrs_init_hb(struct rtrs_sess *sess, struct ib_cqe *cqe,
		  unsigned int interval_ms, unsigned int missed_max,
		  void (*err_handler)(struct rtrs_con *con),
		  struct workqueue_struct *wq)
{
	sess->hb_cqe = cqe;
	sess->hb_interval_ms = interval_ms;
	sess->hb_err_handler = err_handler;
	sess->hb_wq = wq;
	sess->hb_missed_max = missed_max;
	sess->hb_missed_cnt = 0;
	INIT_DELAYED_WORK(&sess->hb_dwork, hb_work);
}
EXPORT_SYMBOL_GPL(rtrs_init_hb);

void rtrs_start_hb(struct rtrs_sess *sess)
{
	schedule_hb(sess);
}
EXPORT_SYMBOL_GPL(rtrs_start_hb);

void rtrs_stop_hb(struct rtrs_sess *sess)
{
	cancel_delayed_work_sync(&sess->hb_dwork);
	sess->hb_missed_cnt = 0;
	sess->hb_missed_max = 0;
}
EXPORT_SYMBOL_GPL(rtrs_stop_hb);

static int rtrs_str_gid_to_sockaddr(const char *addr, size_t len,
				     short port, struct sockaddr_storage *dst)
{
	struct sockaddr_ib *dst_ib = (struct sockaddr_ib *)dst;
	int ret;

	/*
	 * We can use some of the IPv6 functions since GID is a valid
	 * IPv6 address format
	 */
	ret = in6_pton(addr, len, dst_ib->sib_addr.sib_raw, '\0', NULL);
	if (ret == 0)
		return -EINVAL;

	dst_ib->sib_family = AF_IB;
	/*
	 * Use the same TCP server port number as the IB service ID
	 * on the IB port space range
	 */
	dst_ib->sib_sid = cpu_to_be64(RDMA_IB_IP_PS_IB | port);
	dst_ib->sib_sid_mask = cpu_to_be64(0xffffffffffffffffULL);
	dst_ib->sib_pkey = cpu_to_be16(0xffff);

	return 0;
}

/**
 * rtrs_str_to_sockaddr() - Convert rtrs address string to sockaddr
 * @addr:	String representation of an addr (IPv4, IPv6 or IB GID):
 *              - "ip:192.168.1.1"
 *              - "ip:fe80::200:5aee:feaa:20a2"
 *              - "gid:fe80::200:5aee:feaa:20a2"
 * @len:        String address length
 * @port:	Destination port
 * @dst:	Destination sockaddr structure
 *
 * Returns 0 if conversion successful. Non-zero on error.
 */
static int rtrs_str_to_sockaddr(const char *addr, size_t len,
				u16 port, struct sockaddr_storage *dst)
{
	if (strncmp(addr, "gid:", 4) == 0) {
		return rtrs_str_gid_to_sockaddr(addr + 4, len - 4, port, dst);
	} else if (strncmp(addr, "ip:", 3) == 0) {
		char port_str[8];
		char *cpy;
		int err;

		snprintf(port_str, sizeof(port_str), "%u", port);
		cpy = kstrndup(addr + 3, len - 3, GFP_KERNEL);
		err = cpy ? inet_pton_with_scope(&init_net, AF_UNSPEC,
						 cpy, port_str, dst) : -ENOMEM;
		kfree(cpy);

		return err;
	}
	return -EPROTONOSUPPORT;
}

/**
 * sockaddr_to_str() - convert sockaddr to a string.
 * @addr:	the sockadddr structure to be converted.
 * @buf:	string containing socket addr.
 * @len:	string length.
 *
 * The return value is the number of characters written into buf not
 * including the trailing '\0'. If len is == 0 the function returns 0..
 */
int sockaddr_to_str(const struct sockaddr *addr, char *buf, size_t len)
{

	switch (addr->sa_family) {
	case AF_IB:
		return scnprintf(buf, len, "gid:%pI6",
			&((struct sockaddr_ib *)addr)->sib_addr.sib_raw);
	case AF_INET:
		return scnprintf(buf, len, "ip:%pI4",
			&((struct sockaddr_in *)addr)->sin_addr);
	case AF_INET6:
		return scnprintf(buf, len, "ip:%pI6c",
			  &((struct sockaddr_in6 *)addr)->sin6_addr);
	}
	return scnprintf(buf, len, "<invalid address family>");
}
EXPORT_SYMBOL(sockaddr_to_str);

/**
 * rtrs_addr_to_sockaddr() - convert path string "src,dst" or "src@dst"
 * to sockaddreses
 * @str:	string containing source and destination addr of a path
 *		separated by ',' or '@' I.e. "ip:1.1.1.1,ip:1.1.1.2" or
 *		"ip:1.1.1.1@ip:1.1.1.2". If str contains only one address it's
 *		considered to be destination.
 * @len:	string length
 * @port:	Destination port number.
 * @addr:	will be set to the source/destination address or to NULL
 *		if str doesn't contain any source address.
 *
 * Returns zero if conversion successful. Non-zero otherwise.
 */
int rtrs_addr_to_sockaddr(const char *str, size_t len, u16 port,
			  struct rtrs_addr *addr)
{
	const char *d;

	d = strchr(str, ',');
	if (!d)
		d = strchr(str, '@');
	if (d) {
		if (rtrs_str_to_sockaddr(str, d - str, 0, addr->src))
			return -EINVAL;
		d += 1;
		len -= d - str;
		str  = d;

	} else {
		addr->src = NULL;
	}
	return rtrs_str_to_sockaddr(str, len, port, addr->dst);
}
EXPORT_SYMBOL(rtrs_addr_to_sockaddr);

void rtrs_rdma_dev_pd_init(enum ib_pd_flags pd_flags,
			    struct rtrs_rdma_dev_pd *pool)
{
	WARN_ON(pool->ops && (!pool->ops->alloc ^ !pool->ops->free));
	INIT_LIST_HEAD(&pool->list);
	mutex_init(&pool->mutex);
	pool->pd_flags = pd_flags;
}
EXPORT_SYMBOL(rtrs_rdma_dev_pd_init);

void rtrs_rdma_dev_pd_deinit(struct rtrs_rdma_dev_pd *pool)
{
	mutex_destroy(&pool->mutex);
	WARN_ON(!list_empty(&pool->list));
}
EXPORT_SYMBOL(rtrs_rdma_dev_pd_deinit);

static void dev_free(struct kref *ref)
{
	struct rtrs_rdma_dev_pd *pool;
	struct rtrs_ib_dev *dev;

	dev = container_of(ref, typeof(*dev), ref);
	pool = dev->pool;

	mutex_lock(&pool->mutex);
	list_del(&dev->entry);
	mutex_unlock(&pool->mutex);

	if (pool->ops && pool->ops->deinit)
		pool->ops->deinit(dev);

	ib_dealloc_pd(dev->ib_pd);

	if (pool->ops && pool->ops->free)
		pool->ops->free(dev);
	else
		kfree(dev);
}

int rtrs_ib_dev_put(struct rtrs_ib_dev *dev)
{
	return kref_put(&dev->ref, dev_free);
}
EXPORT_SYMBOL(rtrs_ib_dev_put);

static int rtrs_ib_dev_get(struct rtrs_ib_dev *dev)
{
	return kref_get_unless_zero(&dev->ref);
}

struct rtrs_ib_dev *
rtrs_ib_dev_find_or_add(struct ib_device *ib_dev,
			 struct rtrs_rdma_dev_pd *pool)
{
	struct rtrs_ib_dev *dev;

	mutex_lock(&pool->mutex);
	list_for_each_entry(dev, &pool->list, entry) {
		if (dev->ib_dev->node_guid == ib_dev->node_guid &&
		    rtrs_ib_dev_get(dev))
			goto out_unlock;
	}
	mutex_unlock(&pool->mutex);
	if (pool->ops && pool->ops->alloc)
		dev = pool->ops->alloc();
	else
		dev = kzalloc(sizeof(*dev), GFP_KERNEL);
	if (IS_ERR_OR_NULL(dev))
		goto out_err;

	kref_init(&dev->ref);
	dev->pool = pool;
	dev->ib_dev = ib_dev;
	dev->ib_pd = ib_alloc_pd(ib_dev, pool->pd_flags);
	if (IS_ERR(dev->ib_pd))
		goto out_free_dev;

	if (pool->ops && pool->ops->init && pool->ops->init(dev))
		goto out_free_pd;

	mutex_lock(&pool->mutex);
	list_add(&dev->entry, &pool->list);
out_unlock:
	mutex_unlock(&pool->mutex);
	return dev;

out_free_pd:
	ib_dealloc_pd(dev->ib_pd);
out_free_dev:
	if (pool->ops && pool->ops->free)
		pool->ops->free(dev);
	else
		kfree(dev);
out_err:
	return NULL;
}
EXPORT_SYMBOL(rtrs_ib_dev_find_or_add);
