/*
 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
 * All rights reserved
 * www.brocade.com
 *
 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License (GPL) 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.
 */

#include <bfa.h>
#include <bfi/bfi_lps.h>
#include <cs/bfa_debug.h>

BFA_TRC_FILE(HAL, LPS);
BFA_MODULE(lps);

#define BFA_LPS_MIN_LPORTS	(1)
#define BFA_LPS_MAX_LPORTS	(256)

/**
 * forward declarations
 */
static void bfa_lps_meminfo(struct bfa_iocfc_cfg_s *cfg, u32 *ndm_len,
			    u32 *dm_len);
static void bfa_lps_attach(struct bfa_s *bfa, void *bfad,
			   struct bfa_iocfc_cfg_s *cfg,
			   struct bfa_meminfo_s *meminfo,
			   struct bfa_pcidev_s *pcidev);
static void bfa_lps_initdone(struct bfa_s *bfa);
static void bfa_lps_detach(struct bfa_s *bfa);
static void bfa_lps_start(struct bfa_s *bfa);
static void bfa_lps_stop(struct bfa_s *bfa);
static void bfa_lps_iocdisable(struct bfa_s *bfa);
static void bfa_lps_login_rsp(struct bfa_s *bfa,
			      struct bfi_lps_login_rsp_s *rsp);
static void bfa_lps_logout_rsp(struct bfa_s *bfa,
			       struct bfi_lps_logout_rsp_s *rsp);
static void bfa_lps_reqq_resume(void *lps_arg);
static void bfa_lps_free(struct bfa_lps_s *lps);
static void bfa_lps_send_login(struct bfa_lps_s *lps);
static void bfa_lps_send_logout(struct bfa_lps_s *lps);
static void bfa_lps_login_comp(struct bfa_lps_s *lps);
static void bfa_lps_logout_comp(struct bfa_lps_s *lps);


/**
 *  lps_pvt BFA LPS private functions
 */

enum bfa_lps_event {
	BFA_LPS_SM_LOGIN	= 1,	/* login request from user	*/
	BFA_LPS_SM_LOGOUT	= 2,	/* logout request from user	*/
	BFA_LPS_SM_FWRSP	= 3,	/* f/w response to login/logout	*/
	BFA_LPS_SM_RESUME	= 4,	/* space present in reqq queue	*/
	BFA_LPS_SM_DELETE	= 5,	/* lps delete from user		*/
	BFA_LPS_SM_OFFLINE	= 6,	/* Link is offline		*/
};

static void bfa_lps_sm_init(struct bfa_lps_s *lps, enum bfa_lps_event event);
static void bfa_lps_sm_login(struct bfa_lps_s *lps, enum bfa_lps_event event);
static void bfa_lps_sm_loginwait(struct bfa_lps_s *lps,
			enum bfa_lps_event event);
static void bfa_lps_sm_online(struct bfa_lps_s *lps, enum bfa_lps_event event);
static void bfa_lps_sm_logout(struct bfa_lps_s *lps, enum bfa_lps_event event);
static void bfa_lps_sm_logowait(struct bfa_lps_s *lps,
			enum bfa_lps_event event);

/**
 * Init state -- no login
 */
static void
bfa_lps_sm_init(struct bfa_lps_s *lps, enum bfa_lps_event event)
{
	bfa_trc(lps->bfa, lps->lp_tag);
	bfa_trc(lps->bfa, event);

	switch (event) {
	case BFA_LPS_SM_LOGIN:
		if (bfa_reqq_full(lps->bfa, lps->reqq)) {
			bfa_sm_set_state(lps, bfa_lps_sm_loginwait);
			bfa_reqq_wait(lps->bfa, lps->reqq, &lps->wqe);
		} else {
			bfa_sm_set_state(lps, bfa_lps_sm_login);
			bfa_lps_send_login(lps);
		}
		break;

	case BFA_LPS_SM_LOGOUT:
		bfa_lps_logout_comp(lps);
		break;

	case BFA_LPS_SM_DELETE:
		bfa_lps_free(lps);
		break;

	case BFA_LPS_SM_OFFLINE:
		break;

	case BFA_LPS_SM_FWRSP:
		/* Could happen when fabric detects loopback and discards
		 * the lps request. Fw will eventually sent out the timeout
		 * Just ignore
		 */
		break;

	default:
		bfa_assert(0);
	}
}

/**
 * login is in progress -- awaiting response from firmware
 */
static void
bfa_lps_sm_login(struct bfa_lps_s *lps, enum bfa_lps_event event)
{
	bfa_trc(lps->bfa, lps->lp_tag);
	bfa_trc(lps->bfa, event);

	switch (event) {
	case BFA_LPS_SM_FWRSP:
		if (lps->status == BFA_STATUS_OK)
			bfa_sm_set_state(lps, bfa_lps_sm_online);
		else
			bfa_sm_set_state(lps, bfa_lps_sm_init);
		bfa_lps_login_comp(lps);
		break;

	case BFA_LPS_SM_OFFLINE:
		bfa_sm_set_state(lps, bfa_lps_sm_init);
		break;

	default:
		bfa_assert(0);
	}
}

/**
 * login pending - awaiting space in request queue
 */
static void
bfa_lps_sm_loginwait(struct bfa_lps_s *lps, enum bfa_lps_event event)
{
	bfa_trc(lps->bfa, lps->lp_tag);
	bfa_trc(lps->bfa, event);

	switch (event) {
	case BFA_LPS_SM_RESUME:
		bfa_sm_set_state(lps, bfa_lps_sm_login);
		break;

	case BFA_LPS_SM_OFFLINE:
		bfa_sm_set_state(lps, bfa_lps_sm_init);
		bfa_reqq_wcancel(&lps->wqe);
		break;

	default:
		bfa_assert(0);
	}
}

/**
 * login complete
 */
static void
bfa_lps_sm_online(struct bfa_lps_s *lps, enum bfa_lps_event event)
{
	bfa_trc(lps->bfa, lps->lp_tag);
	bfa_trc(lps->bfa, event);

	switch (event) {
	case BFA_LPS_SM_LOGOUT:
		if (bfa_reqq_full(lps->bfa, lps->reqq)) {
			bfa_sm_set_state(lps, bfa_lps_sm_logowait);
			bfa_reqq_wait(lps->bfa, lps->reqq, &lps->wqe);
		} else {
			bfa_sm_set_state(lps, bfa_lps_sm_logout);
			bfa_lps_send_logout(lps);
		}
		break;

	case BFA_LPS_SM_OFFLINE:
	case BFA_LPS_SM_DELETE:
		bfa_sm_set_state(lps, bfa_lps_sm_init);
		break;

	default:
		bfa_assert(0);
	}
}

/**
 * logout in progress - awaiting firmware response
 */
static void
bfa_lps_sm_logout(struct bfa_lps_s *lps, enum bfa_lps_event event)
{
	bfa_trc(lps->bfa, lps->lp_tag);
	bfa_trc(lps->bfa, event);

	switch (event) {
	case BFA_LPS_SM_FWRSP:
		bfa_sm_set_state(lps, bfa_lps_sm_init);
		bfa_lps_logout_comp(lps);
		break;

	case BFA_LPS_SM_OFFLINE:
		bfa_sm_set_state(lps, bfa_lps_sm_init);
		break;

	default:
		bfa_assert(0);
	}
}

/**
 * logout pending -- awaiting space in request queue
 */
static void
bfa_lps_sm_logowait(struct bfa_lps_s *lps, enum bfa_lps_event event)
{
	bfa_trc(lps->bfa, lps->lp_tag);
	bfa_trc(lps->bfa, event);

	switch (event) {
	case BFA_LPS_SM_RESUME:
		bfa_sm_set_state(lps, bfa_lps_sm_logout);
		bfa_lps_send_logout(lps);
		break;

	case BFA_LPS_SM_OFFLINE:
		bfa_sm_set_state(lps, bfa_lps_sm_init);
		bfa_reqq_wcancel(&lps->wqe);
		break;

	default:
		bfa_assert(0);
	}
}



/**
 *  lps_pvt BFA LPS private functions
 */

/**
 * return memory requirement
 */
static void
bfa_lps_meminfo(struct bfa_iocfc_cfg_s *cfg, u32 *ndm_len, u32 *dm_len)
{
	if (cfg->drvcfg.min_cfg)
		*ndm_len += sizeof(struct bfa_lps_s) * BFA_LPS_MIN_LPORTS;
	else
		*ndm_len += sizeof(struct bfa_lps_s) * BFA_LPS_MAX_LPORTS;
}

/**
 * bfa module attach at initialization time
 */
static void
bfa_lps_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
		struct bfa_meminfo_s *meminfo, struct bfa_pcidev_s *pcidev)
{
	struct bfa_lps_mod_s	*mod = BFA_LPS_MOD(bfa);
	struct bfa_lps_s	*lps;
	int			i;

	bfa_os_memset(mod, 0, sizeof(struct bfa_lps_mod_s));
	mod->num_lps = BFA_LPS_MAX_LPORTS;
	if (cfg->drvcfg.min_cfg)
		mod->num_lps = BFA_LPS_MIN_LPORTS;
	else
		mod->num_lps = BFA_LPS_MAX_LPORTS;
	mod->lps_arr = lps = (struct bfa_lps_s *) bfa_meminfo_kva(meminfo);

	bfa_meminfo_kva(meminfo) += mod->num_lps * sizeof(struct bfa_lps_s);

	INIT_LIST_HEAD(&mod->lps_free_q);
	INIT_LIST_HEAD(&mod->lps_active_q);

	for (i = 0; i < mod->num_lps; i++, lps++) {
		lps->bfa	= bfa;
		lps->lp_tag	= (u8) i;
		lps->reqq	= BFA_REQQ_LPS;
		bfa_reqq_winit(&lps->wqe, bfa_lps_reqq_resume, lps);
		list_add_tail(&lps->qe, &mod->lps_free_q);
	}
}

static void
bfa_lps_initdone(struct bfa_s *bfa)
{
}

static void
bfa_lps_detach(struct bfa_s *bfa)
{
}

static void
bfa_lps_start(struct bfa_s *bfa)
{
}

static void
bfa_lps_stop(struct bfa_s *bfa)
{
}

/**
 * IOC in disabled state -- consider all lps offline
 */
static void
bfa_lps_iocdisable(struct bfa_s *bfa)
{
	struct bfa_lps_mod_s	*mod = BFA_LPS_MOD(bfa);
	struct bfa_lps_s	*lps;
	struct list_head		*qe, *qen;

	list_for_each_safe(qe, qen, &mod->lps_active_q) {
		lps = (struct bfa_lps_s *) qe;
		bfa_sm_send_event(lps, BFA_LPS_SM_OFFLINE);
	}
}

/**
 * Firmware login response
 */
static void
bfa_lps_login_rsp(struct bfa_s *bfa, struct bfi_lps_login_rsp_s *rsp)
{
	struct bfa_lps_mod_s	*mod = BFA_LPS_MOD(bfa);
	struct bfa_lps_s	*lps;

	bfa_assert(rsp->lp_tag < mod->num_lps);
	lps = BFA_LPS_FROM_TAG(mod, rsp->lp_tag);

	lps->status = rsp->status;
	switch (rsp->status) {
	case BFA_STATUS_OK:
		lps->fport	= rsp->f_port;
		lps->npiv_en	= rsp->npiv_en;
		lps->lp_pid	= rsp->lp_pid;
		lps->pr_bbcred	= bfa_os_ntohs(rsp->bb_credit);
		lps->pr_pwwn	= rsp->port_name;
		lps->pr_nwwn	= rsp->node_name;
		lps->auth_req	= rsp->auth_req;
		lps->lp_mac	= rsp->lp_mac;
		lps->brcd_switch = rsp->brcd_switch;
		lps->fcf_mac	= rsp->fcf_mac;

		break;

	case BFA_STATUS_FABRIC_RJT:
		lps->lsrjt_rsn = rsp->lsrjt_rsn;
		lps->lsrjt_expl = rsp->lsrjt_expl;

		break;

	case BFA_STATUS_EPROTOCOL:
		lps->ext_status = rsp->ext_status;

		break;

	default:
		/* Nothing to do with other status */
		break;
	}

	bfa_sm_send_event(lps, BFA_LPS_SM_FWRSP);
}

/**
 * Firmware logout response
 */
static void
bfa_lps_logout_rsp(struct bfa_s *bfa, struct bfi_lps_logout_rsp_s *rsp)
{
	struct bfa_lps_mod_s	*mod = BFA_LPS_MOD(bfa);
	struct bfa_lps_s	*lps;

	bfa_assert(rsp->lp_tag < mod->num_lps);
	lps = BFA_LPS_FROM_TAG(mod, rsp->lp_tag);

	bfa_sm_send_event(lps, BFA_LPS_SM_FWRSP);
}

/**
 * Space is available in request queue, resume queueing request to firmware.
 */
static void
bfa_lps_reqq_resume(void *lps_arg)
{
	struct bfa_lps_s	*lps = lps_arg;

	bfa_sm_send_event(lps, BFA_LPS_SM_RESUME);
}

/**
 * lps is freed -- triggered by vport delete
 */
static void
bfa_lps_free(struct bfa_lps_s *lps)
{
	struct bfa_lps_mod_s	*mod = BFA_LPS_MOD(lps->bfa);

	list_del(&lps->qe);
	list_add_tail(&lps->qe, &mod->lps_free_q);
}

/**
 * send login request to firmware
 */
static void
bfa_lps_send_login(struct bfa_lps_s *lps)
{
	struct bfi_lps_login_req_s	*m;

	m = bfa_reqq_next(lps->bfa, lps->reqq);
	bfa_assert(m);

	bfi_h2i_set(m->mh, BFI_MC_LPS, BFI_LPS_H2I_LOGIN_REQ,
			bfa_lpuid(lps->bfa));

	m->lp_tag	= lps->lp_tag;
	m->alpa		= lps->alpa;
	m->pdu_size	= bfa_os_htons(lps->pdusz);
	m->pwwn		= lps->pwwn;
	m->nwwn		= lps->nwwn;
	m->fdisc	= lps->fdisc;
	m->auth_en	= lps->auth_en;

	bfa_reqq_produce(lps->bfa, lps->reqq);
}

/**
 * send logout request to firmware
 */
static void
bfa_lps_send_logout(struct bfa_lps_s *lps)
{
	struct bfi_lps_logout_req_s *m;

	m = bfa_reqq_next(lps->bfa, lps->reqq);
	bfa_assert(m);

	bfi_h2i_set(m->mh, BFI_MC_LPS, BFI_LPS_H2I_LOGOUT_REQ,
			bfa_lpuid(lps->bfa));

	m->lp_tag    = lps->lp_tag;
	m->port_name = lps->pwwn;
	bfa_reqq_produce(lps->bfa, lps->reqq);
}

/**
 * Indirect login completion handler for non-fcs
 */
static void
bfa_lps_login_comp_cb(void *arg, bfa_boolean_t complete)
{
	struct bfa_lps_s *lps	= arg;

	if (!complete)
		return;

	if (lps->fdisc)
		bfa_cb_lps_fdisc_comp(lps->bfa->bfad, lps->uarg, lps->status);
	else
		bfa_cb_lps_flogi_comp(lps->bfa->bfad, lps->uarg, lps->status);
}

/**
 * Login completion handler -- direct call for fcs, queue for others
 */
static void
bfa_lps_login_comp(struct bfa_lps_s *lps)
{
	if (!lps->bfa->fcs) {
		bfa_cb_queue(lps->bfa, &lps->hcb_qe,
				bfa_lps_login_comp_cb, lps);
		return;
	}

	if (lps->fdisc)
		bfa_cb_lps_fdisc_comp(lps->bfa->bfad, lps->uarg, lps->status);
	else
		bfa_cb_lps_flogi_comp(lps->bfa->bfad, lps->uarg, lps->status);
}

/**
 * Indirect logout completion handler for non-fcs
 */
static void
bfa_lps_logout_comp_cb(void *arg, bfa_boolean_t complete)
{
	struct bfa_lps_s *lps	= arg;

	if (!complete)
		return;

	if (lps->fdisc)
		bfa_cb_lps_fdisclogo_comp(lps->bfa->bfad, lps->uarg);
	else
		bfa_cb_lps_flogo_comp(lps->bfa->bfad, lps->uarg);
}

/**
 * Logout completion handler -- direct call for fcs, queue for others
 */
static void
bfa_lps_logout_comp(struct bfa_lps_s *lps)
{
	if (!lps->bfa->fcs) {
		bfa_cb_queue(lps->bfa, &lps->hcb_qe,
				bfa_lps_logout_comp_cb, lps);
		return;
	}
	if (lps->fdisc)
		bfa_cb_lps_fdisclogo_comp(lps->bfa->bfad, lps->uarg);
	else
		bfa_cb_lps_flogo_comp(lps->bfa->bfad, lps->uarg);
}



/**
 *  lps_public BFA LPS public functions
 */

/**
 * Allocate a lport srvice tag.
 */
struct bfa_lps_s  *
bfa_lps_alloc(struct bfa_s *bfa)
{
	struct bfa_lps_mod_s	*mod = BFA_LPS_MOD(bfa);
	struct bfa_lps_s	*lps = NULL;

	bfa_q_deq(&mod->lps_free_q, &lps);

	if (lps == NULL)
		return NULL;

	list_add_tail(&lps->qe, &mod->lps_active_q);

	bfa_sm_set_state(lps, bfa_lps_sm_init);
	return lps;
}

/**
 * Free lport service tag. This can be called anytime after an alloc.
 * No need to wait for any pending login/logout completions.
 */
void
bfa_lps_delete(struct bfa_lps_s *lps)
{
	bfa_sm_send_event(lps, BFA_LPS_SM_DELETE);
}

/**
 * Initiate a lport login.
 */
void
bfa_lps_flogi(struct bfa_lps_s *lps, void *uarg, u8 alpa, u16 pdusz,
	wwn_t pwwn, wwn_t nwwn, bfa_boolean_t auth_en)
{
	lps->uarg	= uarg;
	lps->alpa	= alpa;
	lps->pdusz	= pdusz;
	lps->pwwn	= pwwn;
	lps->nwwn	= nwwn;
	lps->fdisc	= BFA_FALSE;
	lps->auth_en	= auth_en;
	bfa_sm_send_event(lps, BFA_LPS_SM_LOGIN);
}

/**
 * Initiate a lport fdisc login.
 */
void
bfa_lps_fdisc(struct bfa_lps_s *lps, void *uarg, u16 pdusz, wwn_t pwwn,
	wwn_t nwwn)
{
	lps->uarg	= uarg;
	lps->alpa	= 0;
	lps->pdusz	= pdusz;
	lps->pwwn	= pwwn;
	lps->nwwn	= nwwn;
	lps->fdisc	= BFA_TRUE;
	lps->auth_en	= BFA_FALSE;
	bfa_sm_send_event(lps, BFA_LPS_SM_LOGIN);
}

/**
 * Initiate a lport logout (flogi).
 */
void
bfa_lps_flogo(struct bfa_lps_s *lps)
{
	bfa_sm_send_event(lps, BFA_LPS_SM_LOGOUT);
}

/**
 * Initiate a lport FDSIC logout.
 */
void
bfa_lps_fdisclogo(struct bfa_lps_s *lps)
{
	bfa_sm_send_event(lps, BFA_LPS_SM_LOGOUT);
}

/**
 * Discard a pending login request -- should be called only for
 * link down handling.
 */
void
bfa_lps_discard(struct bfa_lps_s *lps)
{
	bfa_sm_send_event(lps, BFA_LPS_SM_OFFLINE);
}

/**
 * Return lport services tag
 */
u8
bfa_lps_get_tag(struct bfa_lps_s *lps)
{
	return lps->lp_tag;
}

/**
 * Return lport services tag given the pid
 */
u8
bfa_lps_get_tag_from_pid(struct bfa_s *bfa, u32 pid)
{
	struct bfa_lps_mod_s	*mod = BFA_LPS_MOD(bfa);
	struct bfa_lps_s	*lps;
	int			i;

	for (i = 0, lps = mod->lps_arr; i < mod->num_lps; i++, lps++) {
		if (lps->lp_pid == pid)
			return lps->lp_tag;
	}

	/* Return base port tag anyway */
	return 0;
}

/**
 * return if fabric login indicates support for NPIV
 */
bfa_boolean_t
bfa_lps_is_npiv_en(struct bfa_lps_s *lps)
{
	return lps->npiv_en;
}

/**
 * Return TRUE if attached to F-Port, else return FALSE
 */
bfa_boolean_t
bfa_lps_is_fport(struct bfa_lps_s *lps)
{
	return lps->fport;
}

/**
 * Return TRUE if attached to a Brocade Fabric
 */
bfa_boolean_t
bfa_lps_is_brcd_fabric(struct bfa_lps_s *lps)
{
	return lps->brcd_switch;
}
/**
 * return TRUE if authentication is required
 */
bfa_boolean_t
bfa_lps_is_authreq(struct bfa_lps_s *lps)
{
	return lps->auth_req;
}

bfa_eproto_status_t
bfa_lps_get_extstatus(struct bfa_lps_s *lps)
{
	return lps->ext_status;
}

/**
 * return port id assigned to the lport
 */
u32
bfa_lps_get_pid(struct bfa_lps_s *lps)
{
	return lps->lp_pid;
}

/**
 * Return bb_credit assigned in FLOGI response
 */
u16
bfa_lps_get_peer_bbcredit(struct bfa_lps_s *lps)
{
	return lps->pr_bbcred;
}

/**
 * Return peer port name
 */
wwn_t
bfa_lps_get_peer_pwwn(struct bfa_lps_s *lps)
{
	return lps->pr_pwwn;
}

/**
 * Return peer node name
 */
wwn_t
bfa_lps_get_peer_nwwn(struct bfa_lps_s *lps)
{
	return lps->pr_nwwn;
}

/**
 * return reason code if login request is rejected
 */
u8
bfa_lps_get_lsrjt_rsn(struct bfa_lps_s *lps)
{
	return lps->lsrjt_rsn;
}

/**
 * return explanation code if login request is rejected
 */
u8
bfa_lps_get_lsrjt_expl(struct bfa_lps_s *lps)
{
	return lps->lsrjt_expl;
}


/**
 * LPS firmware message class handler.
 */
void
bfa_lps_isr(struct bfa_s *bfa, struct bfi_msg_s *m)
{
	union bfi_lps_i2h_msg_u	msg;

	bfa_trc(bfa, m->mhdr.msg_id);
	msg.msg = m;

	switch (m->mhdr.msg_id) {
	case BFI_LPS_H2I_LOGIN_RSP:
		bfa_lps_login_rsp(bfa, msg.login_rsp);
		break;

	case BFI_LPS_H2I_LOGOUT_RSP:
		bfa_lps_logout_rsp(bfa, msg.logout_rsp);
		break;

	default:
		bfa_trc(bfa, m->mhdr.msg_id);
		bfa_assert(0);
	}
}


