/*
 * Discovery service for the NVMe over Fabrics target.
 * Copyright (C) 2016 Intel Corporation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License version
 * 2 as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/slab.h>
#include <generated/utsrelease.h>
#include "nvmet.h"

struct nvmet_subsys *nvmet_disc_subsys;

static u64 nvmet_genctr;

static void __nvmet_disc_changed(struct nvmet_port *port,
				 struct nvmet_ctrl *ctrl)
{
	if (ctrl->port != port)
		return;

	if (nvmet_aen_bit_disabled(ctrl, NVME_AEN_BIT_DISC_CHANGE))
		return;

	nvmet_add_async_event(ctrl, NVME_AER_TYPE_NOTICE,
			      NVME_AER_NOTICE_DISC_CHANGED, NVME_LOG_DISC);
}

void nvmet_port_disc_changed(struct nvmet_port *port,
			     struct nvmet_subsys *subsys)
{
	struct nvmet_ctrl *ctrl;

	nvmet_genctr++;

	list_for_each_entry(ctrl, &nvmet_disc_subsys->ctrls, subsys_entry) {
		if (subsys && !nvmet_host_allowed(subsys, ctrl->hostnqn))
			continue;

		__nvmet_disc_changed(port, ctrl);
	}
}

static void __nvmet_subsys_disc_changed(struct nvmet_port *port,
					struct nvmet_subsys *subsys,
					struct nvmet_host *host)
{
	struct nvmet_ctrl *ctrl;

	list_for_each_entry(ctrl, &nvmet_disc_subsys->ctrls, subsys_entry) {
		if (host && strcmp(nvmet_host_name(host), ctrl->hostnqn))
			continue;

		__nvmet_disc_changed(port, ctrl);
	}
}

void nvmet_subsys_disc_changed(struct nvmet_subsys *subsys,
			       struct nvmet_host *host)
{
	struct nvmet_port *port;
	struct nvmet_subsys_link *s;

	nvmet_genctr++;

	list_for_each_entry(port, nvmet_ports, global_entry)
		list_for_each_entry(s, &port->subsystems, entry) {
			if (s->subsys != subsys)
				continue;
			__nvmet_subsys_disc_changed(port, subsys, host);
		}
}

void nvmet_referral_enable(struct nvmet_port *parent, struct nvmet_port *port)
{
	down_write(&nvmet_config_sem);
	if (list_empty(&port->entry)) {
		list_add_tail(&port->entry, &parent->referrals);
		port->enabled = true;
		nvmet_port_disc_changed(parent, NULL);
	}
	up_write(&nvmet_config_sem);
}

void nvmet_referral_disable(struct nvmet_port *parent, struct nvmet_port *port)
{
	down_write(&nvmet_config_sem);
	if (!list_empty(&port->entry)) {
		port->enabled = false;
		list_del_init(&port->entry);
		nvmet_port_disc_changed(parent, NULL);
	}
	up_write(&nvmet_config_sem);
}

static void nvmet_format_discovery_entry(struct nvmf_disc_rsp_page_hdr *hdr,
		struct nvmet_port *port, char *subsys_nqn, char *traddr,
		u8 type, u32 numrec)
{
	struct nvmf_disc_rsp_page_entry *e = &hdr->entries[numrec];

	e->trtype = port->disc_addr.trtype;
	e->adrfam = port->disc_addr.adrfam;
	e->treq = port->disc_addr.treq;
	e->portid = port->disc_addr.portid;
	/* we support only dynamic controllers */
	e->cntlid = cpu_to_le16(NVME_CNTLID_DYNAMIC);
	e->asqsz = cpu_to_le16(NVME_AQ_DEPTH);
	e->subtype = type;
	memcpy(e->trsvcid, port->disc_addr.trsvcid, NVMF_TRSVCID_SIZE);
	memcpy(e->traddr, traddr, NVMF_TRADDR_SIZE);
	memcpy(e->tsas.common, port->disc_addr.tsas.common, NVMF_TSAS_SIZE);
	strncpy(e->subnqn, subsys_nqn, NVMF_NQN_SIZE);
}

/*
 * nvmet_set_disc_traddr - set a correct discovery log entry traddr
 *
 * IP based transports (e.g RDMA) can listen on "any" ipv4/ipv6 addresses
 * (INADDR_ANY or IN6ADDR_ANY_INIT). The discovery log page traddr reply
 * must not contain that "any" IP address. If the transport implements
 * .disc_traddr, use it. this callback will set the discovery traddr
 * from the req->port address in case the port in question listens
 * "any" IP address.
 */
static void nvmet_set_disc_traddr(struct nvmet_req *req, struct nvmet_port *port,
		char *traddr)
{
	if (req->ops->disc_traddr)
		req->ops->disc_traddr(req, port, traddr);
	else
		memcpy(traddr, port->disc_addr.traddr, NVMF_TRADDR_SIZE);
}

static void nvmet_execute_get_disc_log_page(struct nvmet_req *req)
{
	const int entry_size = sizeof(struct nvmf_disc_rsp_page_entry);
	struct nvmet_ctrl *ctrl = req->sq->ctrl;
	struct nvmf_disc_rsp_page_hdr *hdr;
	size_t data_len = nvmet_get_log_page_len(req->cmd);
	size_t alloc_len = max(data_len, sizeof(*hdr));
	int residual_len = data_len - sizeof(*hdr);
	struct nvmet_subsys_link *p;
	struct nvmet_port *r;
	u32 numrec = 0;
	u16 status = 0;

	/*
	 * Make sure we're passing at least a buffer of response header size.
	 * If host provided data len is less than the header size, only the
	 * number of bytes requested by host will be sent to host.
	 */
	hdr = kzalloc(alloc_len, GFP_KERNEL);
	if (!hdr) {
		status = NVME_SC_INTERNAL;
		goto out;
	}

	down_read(&nvmet_config_sem);
	list_for_each_entry(p, &req->port->subsystems, entry) {
		if (!nvmet_host_allowed(p->subsys, ctrl->hostnqn))
			continue;
		if (residual_len >= entry_size) {
			char traddr[NVMF_TRADDR_SIZE];

			nvmet_set_disc_traddr(req, req->port, traddr);
			nvmet_format_discovery_entry(hdr, req->port,
					p->subsys->subsysnqn, traddr,
					NVME_NQN_NVME, numrec);
			residual_len -= entry_size;
		}
		numrec++;
	}

	list_for_each_entry(r, &req->port->referrals, entry) {
		if (residual_len >= entry_size) {
			nvmet_format_discovery_entry(hdr, r,
					NVME_DISC_SUBSYS_NAME,
					r->disc_addr.traddr,
					NVME_NQN_DISC, numrec);
			residual_len -= entry_size;
		}
		numrec++;
	}

	hdr->genctr = cpu_to_le64(nvmet_genctr);
	hdr->numrec = cpu_to_le64(numrec);
	hdr->recfmt = cpu_to_le16(0);

	nvmet_clear_aen_bit(req, NVME_AEN_BIT_DISC_CHANGE);

	up_read(&nvmet_config_sem);

	status = nvmet_copy_to_sgl(req, 0, hdr, data_len);
	kfree(hdr);
out:
	nvmet_req_complete(req, status);
}

static void nvmet_execute_identify_disc_ctrl(struct nvmet_req *req)
{
	struct nvmet_ctrl *ctrl = req->sq->ctrl;
	struct nvme_id_ctrl *id;
	u16 status = 0;

	id = kzalloc(sizeof(*id), GFP_KERNEL);
	if (!id) {
		status = NVME_SC_INTERNAL;
		goto out;
	}

	memset(id->fr, ' ', sizeof(id->fr));
	strncpy((char *)id->fr, UTS_RELEASE, sizeof(id->fr));

	/* no limit on data transfer sizes for now */
	id->mdts = 0;
	id->cntlid = cpu_to_le16(ctrl->cntlid);
	id->ver = cpu_to_le32(ctrl->subsys->ver);
	id->lpa = (1 << 2);

	/* no enforcement soft-limit for maxcmd - pick arbitrary high value */
	id->maxcmd = cpu_to_le16(NVMET_MAX_CMD);

	id->sgls = cpu_to_le32(1 << 0);	/* we always support SGLs */
	if (ctrl->ops->has_keyed_sgls)
		id->sgls |= cpu_to_le32(1 << 2);
	if (req->port->inline_data_size)
		id->sgls |= cpu_to_le32(1 << 20);

	id->oaes = cpu_to_le32(NVMET_DISC_AEN_CFG_OPTIONAL);

	strlcpy(id->subnqn, ctrl->subsys->subsysnqn, sizeof(id->subnqn));

	status = nvmet_copy_to_sgl(req, 0, id, sizeof(*id));

	kfree(id);
out:
	nvmet_req_complete(req, status);
}

static void nvmet_execute_disc_set_features(struct nvmet_req *req)
{
	u32 cdw10 = le32_to_cpu(req->cmd->common.cdw10);
	u16 stat;

	switch (cdw10 & 0xff) {
	case NVME_FEAT_KATO:
		stat = nvmet_set_feat_kato(req);
		break;
	case NVME_FEAT_ASYNC_EVENT:
		stat = nvmet_set_feat_async_event(req,
						  NVMET_DISC_AEN_CFG_OPTIONAL);
		break;
	default:
		req->error_loc =
			offsetof(struct nvme_common_command, cdw10);
		stat = NVME_SC_INVALID_FIELD | NVME_SC_DNR;
		break;
	}

	nvmet_req_complete(req, stat);
}

static void nvmet_execute_disc_get_features(struct nvmet_req *req)
{
	u32 cdw10 = le32_to_cpu(req->cmd->common.cdw10);
	u16 stat = 0;

	switch (cdw10 & 0xff) {
	case NVME_FEAT_KATO:
		nvmet_get_feat_kato(req);
		break;
	case NVME_FEAT_ASYNC_EVENT:
		nvmet_get_feat_async_event(req);
		break;
	default:
		req->error_loc =
			offsetof(struct nvme_common_command, cdw10);
		stat = NVME_SC_INVALID_FIELD | NVME_SC_DNR;
		break;
	}

	nvmet_req_complete(req, stat);
}

u16 nvmet_parse_discovery_cmd(struct nvmet_req *req)
{
	struct nvme_command *cmd = req->cmd;

	if (unlikely(!(req->sq->ctrl->csts & NVME_CSTS_RDY))) {
		pr_err("got cmd %d while not ready\n",
		       cmd->common.opcode);
		req->error_loc =
			offsetof(struct nvme_common_command, opcode);
		return NVME_SC_INVALID_OPCODE | NVME_SC_DNR;
	}

	switch (cmd->common.opcode) {
	case nvme_admin_set_features:
		req->execute = nvmet_execute_disc_set_features;
		req->data_len = 0;
		return 0;
	case nvme_admin_get_features:
		req->execute = nvmet_execute_disc_get_features;
		req->data_len = 0;
		return 0;
	case nvme_admin_async_event:
		req->execute = nvmet_execute_async_event;
		req->data_len = 0;
		return 0;
	case nvme_admin_keep_alive:
		req->execute = nvmet_execute_keep_alive;
		req->data_len = 0;
		return 0;
	case nvme_admin_get_log_page:
		req->data_len = nvmet_get_log_page_len(cmd);

		switch (cmd->get_log_page.lid) {
		case NVME_LOG_DISC:
			req->execute = nvmet_execute_get_disc_log_page;
			return 0;
		default:
			pr_err("unsupported get_log_page lid %d\n",
			       cmd->get_log_page.lid);
			req->error_loc =
				offsetof(struct nvme_get_log_page_command, lid);
		return NVME_SC_INVALID_OPCODE | NVME_SC_DNR;
		}
	case nvme_admin_identify:
		req->data_len = NVME_IDENTIFY_DATA_SIZE;
		switch (cmd->identify.cns) {
		case NVME_ID_CNS_CTRL:
			req->execute =
				nvmet_execute_identify_disc_ctrl;
			return 0;
		default:
			pr_err("unsupported identify cns %d\n",
			       cmd->identify.cns);
			req->error_loc = offsetof(struct nvme_identify, cns);
			return NVME_SC_INVALID_OPCODE | NVME_SC_DNR;
		}
	default:
		pr_err("unhandled cmd %d\n", cmd->common.opcode);
		req->error_loc = offsetof(struct nvme_common_command, opcode);
		return NVME_SC_INVALID_OPCODE | NVME_SC_DNR;
	}

}

int __init nvmet_init_discovery(void)
{
	nvmet_disc_subsys =
		nvmet_subsys_alloc(NVME_DISC_SUBSYS_NAME, NVME_NQN_DISC);
	if (!nvmet_disc_subsys)
		return -ENOMEM;
	return 0;
}

void nvmet_exit_discovery(void)
{
	nvmet_subsys_put(nvmet_disc_subsys);
}
