/*
 * 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.
 */

/**
 *  bfa_fcs.c BFA FCS main
 */

#include <fcs/bfa_fcs.h>
#include "fcs_port.h"
#include "fcs_uf.h"
#include "fcs_vport.h"
#include "fcs_rport.h"
#include "fcs_fabric.h"
#include "fcs_fcpim.h"
#include "fcs_fcptm.h"
#include "fcbuild.h"
#include "fcs.h"
#include "bfad_drv.h"
#include <fcb/bfa_fcb.h>

/**
 * FCS sub-modules
 */
struct bfa_fcs_mod_s {
	void		(*attach) (struct bfa_fcs_s *fcs);
	void            (*modinit) (struct bfa_fcs_s *fcs);
	void            (*modexit) (struct bfa_fcs_s *fcs);
};

#define BFA_FCS_MODULE(_mod) { _mod ## _modinit, _mod ## _modexit }

static struct bfa_fcs_mod_s fcs_modules[] = {
	{ bfa_fcs_pport_attach, NULL, NULL },
	{ bfa_fcs_uf_attach, NULL, NULL },
	{ bfa_fcs_fabric_attach, bfa_fcs_fabric_modinit,
	 bfa_fcs_fabric_modexit },
};

/**
 *  fcs_api BFA FCS API
 */

static void
bfa_fcs_exit_comp(void *fcs_cbarg)
{
	struct bfa_fcs_s *fcs = fcs_cbarg;
	struct bfad_s *bfad = fcs->bfad;

	complete(&bfad->comp);
}



/**
 *  fcs_api BFA FCS API
 */

/**
 * fcs attach -- called once to initialize data structures at driver attach time
 */
void
bfa_fcs_attach(struct bfa_fcs_s *fcs, struct bfa_s *bfa, struct bfad_s *bfad,
			bfa_boolean_t min_cfg)
{
	int             i;
	struct bfa_fcs_mod_s  *mod;

	fcs->bfa = bfa;
	fcs->bfad = bfad;
	fcs->min_cfg = min_cfg;

	bfa_attach_fcs(bfa);
	fcbuild_init();

	for (i = 0; i < ARRAY_SIZE(fcs_modules); i++) {
		mod = &fcs_modules[i];
		if (mod->attach)
			mod->attach(fcs);
	}
}

/**
 * fcs initialization, called once after bfa initialization is complete
 */
void
bfa_fcs_init(struct bfa_fcs_s *fcs)
{
	int i, npbc_vports;
	struct bfa_fcs_mod_s  *mod;
	struct bfi_pbc_vport_s pbc_vports[BFI_PBC_MAX_VPORTS];

	for (i = 0; i < ARRAY_SIZE(fcs_modules); i++) {
		mod = &fcs_modules[i];
		if (mod->modinit)
			mod->modinit(fcs);
	}
	/* Initialize pbc vports */
	if (!fcs->min_cfg) {
		npbc_vports =
			bfa_iocfc_get_pbc_vports(fcs->bfa, pbc_vports);
		for (i = 0; i < npbc_vports; i++)
			bfa_fcb_pbc_vport_create(fcs->bfa->bfad, pbc_vports[i]);
	}
}

/**
 * Start FCS operations.
 */
void
bfa_fcs_start(struct bfa_fcs_s *fcs)
{
	bfa_fcs_fabric_modstart(fcs);
}

/**
 * 		FCS driver details initialization.
 *
 * 	param[in]		fcs		FCS instance
 * 	param[in]		driver_info	Driver Details
 *
 * 	return None
 */
void
bfa_fcs_driver_info_init(struct bfa_fcs_s *fcs,
			struct bfa_fcs_driver_info_s *driver_info)
{

	fcs->driver_info = *driver_info;

	bfa_fcs_fabric_psymb_init(&fcs->fabric);
}

/**
 *      @brief
 *              FCS FDMI Driver Parameter Initialization
 *
 *      @param[in]              fcs             FCS instance
 *      @param[in]              fdmi_enable     TRUE/FALSE
 *
 *      @return None
 */
void
bfa_fcs_set_fdmi_param(struct bfa_fcs_s *fcs, bfa_boolean_t fdmi_enable)
{

	fcs->fdmi_enabled = fdmi_enable;

}

/**
 * 		FCS instance cleanup and exit.
 *
 * 	param[in]		fcs			FCS instance
 * 	return None
 */
void
bfa_fcs_exit(struct bfa_fcs_s *fcs)
{
	struct bfa_fcs_mod_s  *mod;
	int i;

	bfa_wc_init(&fcs->wc, bfa_fcs_exit_comp, fcs);

	for (i = 0; i < ARRAY_SIZE(fcs_modules); i++) {

		mod = &fcs_modules[i];
		if (mod->modexit) {
			bfa_wc_up(&fcs->wc);
			mod->modexit(fcs);
		}
	}

	bfa_wc_wait(&fcs->wc);
}


void
bfa_fcs_trc_init(struct bfa_fcs_s *fcs, struct bfa_trc_mod_s *trcmod)
{
	fcs->trcmod = trcmod;
}


void
bfa_fcs_log_init(struct bfa_fcs_s *fcs, struct bfa_log_mod_s *logmod)
{
	fcs->logm = logmod;
}


void
bfa_fcs_aen_init(struct bfa_fcs_s *fcs, struct bfa_aen_s *aen)
{
	fcs->aen = aen;
}

void
bfa_fcs_modexit_comp(struct bfa_fcs_s *fcs)
{
	bfa_wc_down(&fcs->wc);
}


