/*
* 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.
*/
/**
* vfapi.c Fabric module implementation.
*/
#include "fcs_fabric.h"
#include "fcs_trcmod.h"
BFA_TRC_FILE(FCS, VFAPI);
/**
* fcs_vf_api virtual fabrics API
*/
/**
* Enable VF mode.
*
* @param[in] fcs fcs module instance
* @param[in] vf_id default vf_id of port, FC_VF_ID_NULL
* to use standard default vf_id of 1.
*
* @retval BFA_STATUS_OK vf mode is enabled
* @retval BFA_STATUS_BUSY Port is active. Port must be disabled
* before VF mode can be enabled.
*/
bfa_status_t
bfa_fcs_vf_mode_enable(struct bfa_fcs_s *fcs, u16 vf_id)
{
return BFA_STATUS_OK;
}
/**
* Disable VF mode.
*
* @param[in] fcs fcs module instance
*
* @retval BFA_STATUS_OK vf mode is disabled
* @retval BFA_STATUS_BUSY VFs are present and being used. All
* VFs must be deleted before disabling
* VF mode.
*/
bfa_status_t
bfa_fcs_vf_mode_disable(struct bfa_fcs_s *fcs)
{
return BFA_STATUS_OK;
}
/**
* Create a new VF instance.
*
* A new VF is created using the given VF configuration. A VF is identified
* by VF id. No duplicate VF creation is allowed with the same VF id. Once
* a VF is created, VF is automatically started after link initialization
* and EVFP exchange is completed.
*
* param[in] vf - FCS vf data structure. Memory is
* allocated by caller (driver)
* param[in] fcs - FCS module
* param[in] vf_cfg - VF configuration
* param[in] vf_drv - Opaque handle back to the driver's
* virtual vf structure
*
* retval BFA_STATUS_OK VF creation is successful
* retval BFA_STATUS_FAILED VF creation failed
* retval BFA_STATUS_EEXIST A VF exists with the given vf_id
*/
bfa_status_t
bfa_fcs_vf_create(bfa_fcs_vf_t *vf, struct bfa_fcs_s *fcs, u16 vf_id,
struct bfa_port_cfg_s *port_cfg, struct bfad_vf_s *vf_drv)
{
bfa_trc(fcs, vf_id);
return BFA_STATUS_OK;
}
/**
* Use this function to delete a BFA VF object. VF object should
* be stopped before this function call.
*
* param[in] vf - pointer to bfa_vf_t.
*
* retval BFA_STATUS_OK On vf deletion success
* retval BFA_STATUS_BUSY VF is not in a stopped state
* retval BFA_STATUS_INPROGRESS VF deletion in in progress
*/
bfa_status_t
bfa_fcs_vf_delete(bfa_fcs_vf_t *vf)
{
bfa_trc(vf->fcs, vf->vf_id);
return BFA_STATUS_OK;
}
/**
* Start participation in VF. This triggers login to the virtual fabric.
*
* param[in] vf - pointer to bfa_vf_t.
*
* return None
*/
void
bfa_fcs_vf_start(bfa_fcs_vf_t *vf)
{
bfa_trc(vf->fcs, vf->vf_id);
}
/**
* Logout with the virtual fabric.
*
* param[in] vf - pointer to bfa_vf_t.
*
* retval BFA_STATUS_OK On success.
* retval BFA_STATUS_INPROGRESS VF is being stopped.
*/
bfa_status_t
bfa_fcs_vf_stop(bfa_fcs_vf_t *vf)
{
bfa_trc(vf->fcs, vf->vf_id);
return BFA_STATUS_OK;
}
/**
* Returns attributes of the given VF.
*
* param[in] vf pointer to bfa_vf_t.
* param[out] vf_attr vf attributes returned
*
* return None
*/
void
bfa_fcs_vf_get_attr(bfa_fcs_vf_t *vf, struct bfa_vf_attr_s *vf_attr)
{
bfa_trc(vf->fcs, vf->vf_id);
}
/**
* Return statistics associated with the given vf.
*
* param[in] vf pointer to bfa_vf_t.
* param[out] vf_stats vf statistics returned
*
* @return None
*/
void
bfa_fcs_vf_get_stats(bfa_fcs_vf_t *vf, struct bfa_vf_stats_s *vf_stats)
{
bfa_os_memcpy(vf_stats, &vf->stats, sizeof(struct bfa_vf_stats_s));
return;
}
void
/**
* clear statistics associated with the given vf.
*
* param[in] vf pointer to bfa_vf_t.
*
* @return None
*/
bfa_fcs_vf_clear_stats(bfa_fcs_vf_t *vf)
{
bfa_os_memset(&vf->stats, 0, sizeof(struct bfa_vf_stats_s));
return;
}
/**
* Returns FCS vf structure for a given vf_id.
*
* param[in] vf_id - VF_ID
*
* return
* If lookup succeeds, retuns fcs vf object, otherwise returns NULL
*/
bfa_fcs_vf_t *
bfa_fcs_vf_lookup(struct bfa_fcs_s *fcs, u16 vf_id)
{
bfa_trc(fcs, vf_id);
if (vf_id == FC_VF_ID_NULL)
return &fcs->fabric;
/**
* @todo vf support
*/
return NULL;
}
/**
* Returns driver VF structure for a given FCS vf.
*
* param[in] vf - pointer to bfa_vf_t
*
* return Driver VF structure
*/
struct bfad_vf_s *
bfa_fcs_vf_get_drv_vf(bfa_fcs_vf_t *vf)
{
bfa_assert(vf);
bfa_trc(vf->fcs, vf->vf_id);
return vf->vf_drv;
}
/**
* Return the list of VFs configured.
*
* param[in] fcs fcs module instance
* param[out] vf_ids returned list of vf_ids
* param[in,out] nvfs in:size of vf_ids array,
* out:total elements present,
* actual elements returned is limited by the size
*
* return Driver VF structure
*/
void
bfa_fcs_vf_list(struct bfa_fcs_s *fcs, u16 *vf_ids, int *nvfs)
{
bfa_trc(fcs, *nvfs);
}
/**
* Return the list of all VFs visible from fabric.
*
* param[in] fcs fcs module instance
* param[out] vf_ids returned list of vf_ids
* param[in,out] nvfs in:size of vf_ids array,
* out:total elements present,
* actual elements returned is limited by the size
*
* return Driver VF structure
*/
void
bfa_fcs_vf_list_all(struct bfa_fcs_s *fcs, u16 *vf_ids, int *nvfs)
{
bfa_trc(fcs, *nvfs);
}
/**
* Return the list of local logical ports present in the given VF.
*
* param[in] vf vf for which logical ports are returned
* param[out] lpwwn returned logical port wwn list
* param[in,out] nlports in:size of lpwwn list;
* out:total elements present,
* actual elements returned is limited by the size
*
*/
void
bfa_fcs_vf_get_ports(bfa_fcs_vf_t *vf, wwn_t lpwwn[], int *nlports)
{
struct list_head *qe;
struct bfa_fcs_vport_s *vport;
int i;
struct bfa_fcs_s *fcs;
if (vf == NULL || lpwwn == NULL || *nlports == 0)
return;
fcs = vf->fcs;
bfa_trc(fcs, vf->vf_id);
bfa_trc(fcs, (u32) *nlports);
i = 0;
lpwwn[i++] = vf->bport.port_cfg.pwwn;
list_for_each(qe, &vf->vport_q) {
if (i >= *nlports)
break;
vport = (struct bfa_fcs_vport_s *) qe;
lpwwn[i++] = vport->lport.port_cfg.pwwn;
}
bfa_trc(fcs, i);
*nlports = i;
return;
}