// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (C) 2021 Broadcom. All Rights Reserved. The term
 * “Broadcom” refers to Broadcom Inc. and/or its subsidiaries.
 */

/*
 * NPORT
 *
 * Port object for physical port and NPIV ports.
 */

/*
 * NPORT REFERENCE COUNTING
 *
 * A nport reference should be taken when:
 * - an nport is allocated
 * - a vport populates associated nport
 * - a remote node is allocated
 * - a unsolicited frame is processed
 * The reference should be dropped when:
 * - the unsolicited frame processesing is done
 * - the remote node is removed
 * - the vport is removed
 * - the nport is removed
 */

#include "efc.h"

void
efc_nport_cb(void *arg, int event, void *data)
{
	struct efc *efc = arg;
	struct efc_nport *nport = data;
	unsigned long flags = 0;

	efc_log_debug(efc, "nport event: %s\n", efc_sm_event_name(event));

	spin_lock_irqsave(&efc->lock, flags);
	efc_sm_post_event(&nport->sm, event, NULL);
	spin_unlock_irqrestore(&efc->lock, flags);
}

static struct efc_nport *
efc_nport_find_wwn(struct efc_domain *domain, uint64_t wwnn, uint64_t wwpn)
{
	struct efc_nport *nport = NULL;

	/* Find a nport, given the WWNN and WWPN */
	list_for_each_entry(nport, &domain->nport_list, list_entry) {
		if (nport->wwnn == wwnn && nport->wwpn == wwpn)
			return nport;
	}
	return NULL;
}

static void
_efc_nport_free(struct kref *arg)
{
	struct efc_nport *nport = container_of(arg, struct efc_nport, ref);

	kfree(nport);
}

struct efc_nport *
efc_nport_alloc(struct efc_domain *domain, uint64_t wwpn, uint64_t wwnn,
		u32 fc_id, bool enable_ini, bool enable_tgt)
{
	struct efc_nport *nport;

	if (domain->efc->enable_ini)
		enable_ini = 0;

	/* Return a failure if this nport has already been allocated */
	if ((wwpn != 0) || (wwnn != 0)) {
		nport = efc_nport_find_wwn(domain, wwnn, wwpn);
		if (nport) {
			efc_log_err(domain->efc,
				    "NPORT %016llX %016llX already allocated\n",
				    wwnn, wwpn);
			return NULL;
		}
	}

	nport = kzalloc(sizeof(*nport), GFP_ATOMIC);
	if (!nport)
		return nport;

	/* initialize refcount */
	kref_init(&nport->ref);
	nport->release = _efc_nport_free;

	nport->efc = domain->efc;
	snprintf(nport->display_name, sizeof(nport->display_name), "------");
	nport->domain = domain;
	xa_init(&nport->lookup);
	nport->instance_index = domain->nport_count++;
	nport->sm.app = nport;
	nport->enable_ini = enable_ini;
	nport->enable_tgt = enable_tgt;
	nport->enable_rscn = (nport->enable_ini ||
			(nport->enable_tgt && enable_target_rscn(nport->efc)));

	/* Copy service parameters from domain */
	memcpy(nport->service_params, domain->service_params,
	       sizeof(struct fc_els_flogi));

	/* Update requested fc_id */
	nport->fc_id = fc_id;

	/* Update the nport's service parameters for the new wwn's */
	nport->wwpn = wwpn;
	nport->wwnn = wwnn;
	snprintf(nport->wwnn_str, sizeof(nport->wwnn_str), "%016llX",
		 (unsigned long long)wwnn);

	/*
	 * if this is the "first" nport of the domain,
	 * then make it the "phys" nport
	 */
	if (list_empty(&domain->nport_list))
		domain->nport = nport;

	INIT_LIST_HEAD(&nport->list_entry);
	list_add_tail(&nport->list_entry, &domain->nport_list);

	kref_get(&domain->ref);

	efc_log_debug(domain->efc, "New Nport [%s]\n", nport->display_name);

	return nport;
}

void
efc_nport_free(struct efc_nport *nport)
{
	struct efc_domain *domain;

	if (!nport)
		return;

	domain = nport->domain;
	efc_log_debug(domain->efc, "[%s] free nport\n", nport->display_name);
	list_del(&nport->list_entry);
	/*
	 * if this is the physical nport,
	 * then clear it out of the domain
	 */
	if (nport == domain->nport)
		domain->nport = NULL;

	xa_destroy(&nport->lookup);
	xa_erase(&domain->lookup, nport->fc_id);

	if (list_empty(&domain->nport_list))
		efc_domain_post_event(domain, EFC_EVT_ALL_CHILD_NODES_FREE,
				      NULL);

	kref_put(&domain->ref, domain->release);
	kref_put(&nport->ref, nport->release);
}

struct efc_nport *
efc_nport_find(struct efc_domain *domain, u32 d_id)
{
	struct efc_nport *nport;

	/* Find a nport object, given an FC_ID */
	nport = xa_load(&domain->lookup, d_id);
	if (!nport || !kref_get_unless_zero(&nport->ref))
		return NULL;

	return nport;
}

int
efc_nport_attach(struct efc_nport *nport, u32 fc_id)
{
	int rc;
	struct efc_node *node;
	struct efc *efc = nport->efc;
	unsigned long index;

	/* Set our lookup */
	rc = xa_err(xa_store(&nport->domain->lookup, fc_id, nport, GFP_ATOMIC));
	if (rc) {
		efc_log_err(efc, "Sport lookup store failed: %d\n", rc);
		return rc;
	}

	/* Update our display_name */
	efc_node_fcid_display(fc_id, nport->display_name,
			      sizeof(nport->display_name));

	xa_for_each(&nport->lookup, index, node) {
		efc_node_update_display_name(node);
	}

	efc_log_debug(nport->efc, "[%s] attach nport: fc_id x%06x\n",
		      nport->display_name, fc_id);

	/* Register a nport, given an FC_ID */
	rc = efc_cmd_nport_attach(efc, nport, fc_id);
	if (rc < 0) {
		efc_log_err(nport->efc,
			    "efc_hw_port_attach failed: %d\n", rc);
		return -EIO;
	}
	return 0;
}

static void
efc_nport_shutdown(struct efc_nport *nport)
{
	struct efc *efc = nport->efc;
	struct efc_node *node;
	unsigned long index;

	xa_for_each(&nport->lookup, index, node) {
		if (!(node->rnode.fc_id == FC_FID_FLOGI && nport->is_vport)) {
			efc_node_post_event(node, EFC_EVT_SHUTDOWN, NULL);
			continue;
		}

		/*
		 * If this is a vport, logout of the fabric
		 * controller so that it deletes the vport
		 * on the switch.
		 */
		/* if link is down, don't send logo */
		if (efc->link_status == EFC_LINK_STATUS_DOWN) {
			efc_node_post_event(node, EFC_EVT_SHUTDOWN, NULL);
			continue;
		}

		efc_log_debug(efc, "[%s] nport shutdown vport, send logo\n",
			      node->display_name);

		if (!efc_send_logo(node)) {
			/* sent LOGO, wait for response */
			efc_node_transition(node, __efc_d_wait_logo_rsp, NULL);
			continue;
		}

		/*
		 * failed to send LOGO,
		 * go ahead and cleanup node anyways
		 */
		node_printf(node, "Failed to send LOGO\n");
		efc_node_post_event(node, EFC_EVT_SHUTDOWN_EXPLICIT_LOGO, NULL);
	}
}

static void
efc_vport_link_down(struct efc_nport *nport)
{
	struct efc *efc = nport->efc;
	struct efc_vport *vport;

	/* Clear the nport reference in the vport specification */
	list_for_each_entry(vport, &efc->vport_list, list_entry) {
		if (vport->nport == nport) {
			kref_put(&nport->ref, nport->release);
			vport->nport = NULL;
			break;
		}
	}
}

static void
__efc_nport_common(const char *funcname, struct efc_sm_ctx *ctx,
		   enum efc_sm_event evt, void *arg)
{
	struct efc_nport *nport = ctx->app;
	struct efc_domain *domain = nport->domain;
	struct efc *efc = nport->efc;

	switch (evt) {
	case EFC_EVT_ENTER:
	case EFC_EVT_REENTER:
	case EFC_EVT_EXIT:
	case EFC_EVT_ALL_CHILD_NODES_FREE:
		break;
	case EFC_EVT_NPORT_ATTACH_OK:
			efc_sm_transition(ctx, __efc_nport_attached, NULL);
		break;
	case EFC_EVT_SHUTDOWN:
		/* Flag this nport as shutting down */
		nport->shutting_down = true;

		if (nport->is_vport)
			efc_vport_link_down(nport);

		if (xa_empty(&nport->lookup)) {
			/* Remove the nport from the domain's lookup table */
			xa_erase(&domain->lookup, nport->fc_id);
			efc_sm_transition(ctx, __efc_nport_wait_port_free,
					  NULL);
			if (efc_cmd_nport_free(efc, nport)) {
				efc_log_debug(nport->efc,
					      "efc_hw_port_free failed\n");
				/* Not much we can do, free the nport anyways */
				efc_nport_free(nport);
			}
		} else {
			/* sm: node list is not empty / shutdown nodes */
			efc_sm_transition(ctx,
					  __efc_nport_wait_shutdown, NULL);
			efc_nport_shutdown(nport);
		}
		break;
	default:
		efc_log_debug(nport->efc, "[%s] %-20s %-20s not handled\n",
			      nport->display_name, funcname,
			      efc_sm_event_name(evt));
	}
}

void
__efc_nport_allocated(struct efc_sm_ctx *ctx,
		      enum efc_sm_event evt, void *arg)
{
	struct efc_nport *nport = ctx->app;
	struct efc_domain *domain = nport->domain;

	nport_sm_trace(nport);

	switch (evt) {
	/* the physical nport is attached */
	case EFC_EVT_NPORT_ATTACH_OK:
		WARN_ON(nport != domain->nport);
		efc_sm_transition(ctx, __efc_nport_attached, NULL);
		break;

	case EFC_EVT_NPORT_ALLOC_OK:
		/* ignore */
		break;
	default:
		__efc_nport_common(__func__, ctx, evt, arg);
	}
}

void
__efc_nport_vport_init(struct efc_sm_ctx *ctx,
		       enum efc_sm_event evt, void *arg)
{
	struct efc_nport *nport = ctx->app;
	struct efc *efc = nport->efc;

	nport_sm_trace(nport);

	switch (evt) {
	case EFC_EVT_ENTER: {
		__be64 be_wwpn = cpu_to_be64(nport->wwpn);

		if (nport->wwpn == 0)
			efc_log_debug(efc, "vport: letting f/w select WWN\n");

		if (nport->fc_id != U32_MAX) {
			efc_log_debug(efc, "vport: hard coding port id: %x\n",
				      nport->fc_id);
		}

		efc_sm_transition(ctx, __efc_nport_vport_wait_alloc, NULL);
		/* If wwpn is zero, then we'll let the f/w assign wwpn*/
		if (efc_cmd_nport_alloc(efc, nport, nport->domain,
					nport->wwpn == 0 ? NULL :
					(uint8_t *)&be_wwpn)) {
			efc_log_err(efc, "Can't allocate port\n");
			break;
		}

		break;
	}
	default:
		__efc_nport_common(__func__, ctx, evt, arg);
	}
}

void
__efc_nport_vport_wait_alloc(struct efc_sm_ctx *ctx,
			     enum efc_sm_event evt, void *arg)
{
	struct efc_nport *nport = ctx->app;
	struct efc *efc = nport->efc;

	nport_sm_trace(nport);

	switch (evt) {
	case EFC_EVT_NPORT_ALLOC_OK: {
		struct fc_els_flogi *sp;

		sp = (struct fc_els_flogi *)nport->service_params;

		if (nport->wwnn == 0) {
			nport->wwnn = be64_to_cpu(nport->sli_wwnn);
			nport->wwpn = be64_to_cpu(nport->sli_wwpn);
			snprintf(nport->wwnn_str, sizeof(nport->wwnn_str),
				 "%016llX", nport->wwpn);
		}

		/* Update the nport's service parameters */
		sp->fl_wwpn = cpu_to_be64(nport->wwpn);
		sp->fl_wwnn = cpu_to_be64(nport->wwnn);

		/*
		 * if nport->fc_id is uninitialized,
		 * then request that the fabric node use FDISC
		 * to find an fc_id.
		 * Otherwise we're restoring vports, or we're in
		 * fabric emulation mode, so attach the fc_id
		 */
		if (nport->fc_id == U32_MAX) {
			struct efc_node *fabric;

			fabric = efc_node_alloc(nport, FC_FID_FLOGI, false,
						false);
			if (!fabric) {
				efc_log_err(efc, "efc_node_alloc() failed\n");
				return;
			}
			efc_node_transition(fabric, __efc_vport_fabric_init,
					    NULL);
		} else {
			snprintf(nport->wwnn_str, sizeof(nport->wwnn_str),
				 "%016llX", nport->wwpn);
			efc_nport_attach(nport, nport->fc_id);
		}
		efc_sm_transition(ctx, __efc_nport_vport_allocated, NULL);
		break;
	}
	default:
		__efc_nport_common(__func__, ctx, evt, arg);
	}
}

void
__efc_nport_vport_allocated(struct efc_sm_ctx *ctx,
			    enum efc_sm_event evt, void *arg)
{
	struct efc_nport *nport = ctx->app;
	struct efc *efc = nport->efc;

	nport_sm_trace(nport);

	/*
	 * This state is entered after the nport is allocated;
	 * it then waits for a fabric node
	 * FDISC to complete, which requests a nport attach.
	 * The nport attach complete is handled in this state.
	 */
	switch (evt) {
	case EFC_EVT_NPORT_ATTACH_OK: {
		struct efc_node *node;

		/* Find our fabric node, and forward this event */
		node = efc_node_find(nport, FC_FID_FLOGI);
		if (!node) {
			efc_log_debug(efc, "can't find node %06x\n", FC_FID_FLOGI);
			break;
		}
		/* sm: / forward nport attach to fabric node */
		efc_node_post_event(node, evt, NULL);
		efc_sm_transition(ctx, __efc_nport_attached, NULL);
		break;
	}
	default:
		__efc_nport_common(__func__, ctx, evt, arg);
	}
}

static void
efc_vport_update_spec(struct efc_nport *nport)
{
	struct efc *efc = nport->efc;
	struct efc_vport *vport;
	unsigned long flags = 0;

	spin_lock_irqsave(&efc->vport_lock, flags);
	list_for_each_entry(vport, &efc->vport_list, list_entry) {
		if (vport->nport == nport) {
			vport->wwnn = nport->wwnn;
			vport->wwpn = nport->wwpn;
			vport->tgt_data = nport->tgt_data;
			vport->ini_data = nport->ini_data;
			break;
		}
	}
	spin_unlock_irqrestore(&efc->vport_lock, flags);
}

void
__efc_nport_attached(struct efc_sm_ctx *ctx,
		     enum efc_sm_event evt, void *arg)
{
	struct efc_nport *nport = ctx->app;
	struct efc *efc = nport->efc;

	nport_sm_trace(nport);

	switch (evt) {
	case EFC_EVT_ENTER: {
		struct efc_node *node;
		unsigned long index;

		efc_log_debug(efc,
			      "[%s] NPORT attached WWPN %016llX WWNN %016llX\n",
			      nport->display_name,
			      nport->wwpn, nport->wwnn);

		xa_for_each(&nport->lookup, index, node)
			efc_node_update_display_name(node);

		efc->tt.new_nport(efc, nport);

		/*
		 * Update the vport (if its not the physical nport)
		 * parameters
		 */
		if (nport->is_vport)
			efc_vport_update_spec(nport);
		break;
	}

	case EFC_EVT_EXIT:
		efc_log_debug(efc,
			      "[%s] NPORT deattached WWPN %016llX WWNN %016llX\n",
			      nport->display_name,
			      nport->wwpn, nport->wwnn);

		efc->tt.del_nport(efc, nport);
		break;
	default:
		__efc_nport_common(__func__, ctx, evt, arg);
	}
}

void
__efc_nport_wait_shutdown(struct efc_sm_ctx *ctx,
			  enum efc_sm_event evt, void *arg)
{
	struct efc_nport *nport = ctx->app;
	struct efc_domain *domain = nport->domain;
	struct efc *efc = nport->efc;

	nport_sm_trace(nport);

	switch (evt) {
	case EFC_EVT_NPORT_ALLOC_OK:
	case EFC_EVT_NPORT_ALLOC_FAIL:
	case EFC_EVT_NPORT_ATTACH_OK:
	case EFC_EVT_NPORT_ATTACH_FAIL:
		/* ignore these events - just wait for the all free event */
		break;

	case EFC_EVT_ALL_CHILD_NODES_FREE: {
		/*
		 * Remove the nport from the domain's
		 * sparse vector lookup table
		 */
		xa_erase(&domain->lookup, nport->fc_id);
		efc_sm_transition(ctx, __efc_nport_wait_port_free, NULL);
		if (efc_cmd_nport_free(efc, nport)) {
			efc_log_err(nport->efc, "efc_hw_port_free failed\n");
			/* Not much we can do, free the nport anyways */
			efc_nport_free(nport);
		}
		break;
	}
	default:
		__efc_nport_common(__func__, ctx, evt, arg);
	}
}

void
__efc_nport_wait_port_free(struct efc_sm_ctx *ctx,
			   enum efc_sm_event evt, void *arg)
{
	struct efc_nport *nport = ctx->app;

	nport_sm_trace(nport);

	switch (evt) {
	case EFC_EVT_NPORT_ATTACH_OK:
		/* Ignore as we are waiting for the free CB */
		break;
	case EFC_EVT_NPORT_FREE_OK: {
		/* All done, free myself */
		efc_nport_free(nport);
		break;
	}
	default:
		__efc_nport_common(__func__, ctx, evt, arg);
	}
}

static int
efc_vport_nport_alloc(struct efc_domain *domain, struct efc_vport *vport)
{
	struct efc_nport *nport;

	lockdep_assert_held(&domain->efc->lock);

	nport = efc_nport_alloc(domain, vport->wwpn, vport->wwnn, vport->fc_id,
				vport->enable_ini, vport->enable_tgt);
	vport->nport = nport;
	if (!nport)
		return -EIO;

	kref_get(&nport->ref);
	nport->is_vport = true;
	nport->tgt_data = vport->tgt_data;
	nport->ini_data = vport->ini_data;

	efc_sm_transition(&nport->sm, __efc_nport_vport_init, NULL);

	return 0;
}

int
efc_vport_start(struct efc_domain *domain)
{
	struct efc *efc = domain->efc;
	struct efc_vport *vport;
	struct efc_vport *next;
	int rc = 0;
	unsigned long flags = 0;

	/* Use the vport spec to find the associated vports and start them */
	spin_lock_irqsave(&efc->vport_lock, flags);
	list_for_each_entry_safe(vport, next, &efc->vport_list, list_entry) {
		if (!vport->nport) {
			if (efc_vport_nport_alloc(domain, vport))
				rc = -EIO;
		}
	}
	spin_unlock_irqrestore(&efc->vport_lock, flags);

	return rc;
}

int
efc_nport_vport_new(struct efc_domain *domain, uint64_t wwpn, uint64_t wwnn,
		    u32 fc_id, bool ini, bool tgt, void *tgt_data,
		    void *ini_data)
{
	struct efc *efc = domain->efc;
	struct efc_vport *vport;
	int rc = 0;
	unsigned long flags = 0;

	if (ini && domain->efc->enable_ini == 0) {
		efc_log_debug(efc, "driver initiator mode not enabled\n");
		return -EIO;
	}

	if (tgt && domain->efc->enable_tgt == 0) {
		efc_log_debug(efc, "driver target mode not enabled\n");
		return -EIO;
	}

	/*
	 * Create a vport spec if we need to recreate
	 * this vport after a link up event
	 */
	vport = efc_vport_create_spec(domain->efc, wwnn, wwpn, fc_id, ini, tgt,
				      tgt_data, ini_data);
	if (!vport) {
		efc_log_err(efc, "failed to create vport object entry\n");
		return -EIO;
	}

	spin_lock_irqsave(&efc->lock, flags);
	rc = efc_vport_nport_alloc(domain, vport);
	spin_unlock_irqrestore(&efc->lock, flags);

	return rc;
}

int
efc_nport_vport_del(struct efc *efc, struct efc_domain *domain,
		    u64 wwpn, uint64_t wwnn)
{
	struct efc_nport *nport;
	struct efc_vport *vport;
	struct efc_vport *next;
	unsigned long flags = 0;

	spin_lock_irqsave(&efc->vport_lock, flags);
	/* walk the efc_vport_list and remove from there */
	list_for_each_entry_safe(vport, next, &efc->vport_list, list_entry) {
		if (vport->wwpn == wwpn && vport->wwnn == wwnn) {
			list_del(&vport->list_entry);
			kfree(vport);
			break;
		}
	}
	spin_unlock_irqrestore(&efc->vport_lock, flags);

	if (!domain) {
		/* No domain means no nport to look for */
		return 0;
	}

	spin_lock_irqsave(&efc->lock, flags);
	list_for_each_entry(nport, &domain->nport_list, list_entry) {
		if (nport->wwpn == wwpn && nport->wwnn == wwnn) {
			kref_put(&nport->ref, nport->release);
			/* Shutdown this NPORT */
			efc_sm_post_event(&nport->sm, EFC_EVT_SHUTDOWN, NULL);
			break;
		}
	}

	spin_unlock_irqrestore(&efc->lock, flags);
	return 0;
}

void
efc_vport_del_all(struct efc *efc)
{
	struct efc_vport *vport;
	struct efc_vport *next;
	unsigned long flags = 0;

	spin_lock_irqsave(&efc->vport_lock, flags);
	list_for_each_entry_safe(vport, next, &efc->vport_list, list_entry) {
		list_del(&vport->list_entry);
		kfree(vport);
	}
	spin_unlock_irqrestore(&efc->vport_lock, flags);
}

struct efc_vport *
efc_vport_create_spec(struct efc *efc, uint64_t wwnn, uint64_t wwpn,
		      u32 fc_id, bool enable_ini,
		      bool enable_tgt, void *tgt_data, void *ini_data)
{
	struct efc_vport *vport;
	unsigned long flags = 0;

	/*
	 * walk the efc_vport_list and return failure
	 * if a valid(vport with non zero WWPN and WWNN) vport entry
	 * is already created
	 */
	spin_lock_irqsave(&efc->vport_lock, flags);
	list_for_each_entry(vport, &efc->vport_list, list_entry) {
		if ((wwpn && vport->wwpn == wwpn) &&
		    (wwnn && vport->wwnn == wwnn)) {
			efc_log_err(efc,
				    "VPORT %016llX %016llX already allocated\n",
				    wwnn, wwpn);
			spin_unlock_irqrestore(&efc->vport_lock, flags);
			return NULL;
		}
	}

	vport = kzalloc(sizeof(*vport), GFP_ATOMIC);
	if (!vport) {
		spin_unlock_irqrestore(&efc->vport_lock, flags);
		return NULL;
	}

	vport->wwnn = wwnn;
	vport->wwpn = wwpn;
	vport->fc_id = fc_id;
	vport->enable_tgt = enable_tgt;
	vport->enable_ini = enable_ini;
	vport->tgt_data = tgt_data;
	vport->ini_data = ini_data;

	INIT_LIST_HEAD(&vport->list_entry);
	list_add_tail(&vport->list_entry, &efc->vport_list);
	spin_unlock_irqrestore(&efc->vport_lock, flags);
	return vport;
}
