/* * 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 #include #include "fcs_vport.h" #include "fcs_lport.h" #include "fcs_rport.h" #include "fcs_trcmod.h" BFA_TRC_FILE(FCS, RPORT_API); /** * rport_api.c Remote port implementation. */ /** * fcs_rport_api FCS rport API. */ /** * Direct API to add a target by port wwn. This interface is used, for * example, by bios when target pwwn is known from boot lun configuration. */ bfa_status_t bfa_fcs_rport_add(struct bfa_fcs_port_s *port, wwn_t *pwwn, struct bfa_fcs_rport_s *rport, struct bfad_rport_s *rport_drv) { bfa_trc(port->fcs, *pwwn); return BFA_STATUS_OK; } /** * Direct API to remove a target and its associated resources. This * interface is used, for example, by vmware driver to remove target * ports from the target list for a VM. */ bfa_status_t bfa_fcs_rport_remove(struct bfa_fcs_rport_s *rport_in) { struct bfa_fcs_rport_s *rport; bfa_trc(rport_in->fcs, rport_in->pwwn); rport = bfa_fcs_port_get_rport_by_pwwn(rport_in->port, rport_in->pwwn); if (rport == NULL) { /* * TBD Error handling */ bfa_trc(rport_in->fcs, rport_in->pid); return BFA_STATUS_UNKNOWN_RWWN; } /* * TBD if this remote port is online, send a logo */ return BFA_STATUS_OK; } /** * Remote device status for display/debug. */ void bfa_fcs_rport_get_attr(struct bfa_fcs_rport_s *rport, struct bfa_rport_attr_s *rport_attr) { struct bfa_rport_qos_attr_s qos_attr; struct bfa_fcs_port_s *port = rport->port; bfa_os_memset(rport_attr, 0, sizeof(struct bfa_rport_attr_s)); rport_attr->pid = rport->pid; rport_attr->pwwn = rport->pwwn; rport_attr->nwwn = rport->nwwn; rport_attr->cos_supported = rport->fc_cos; rport_attr->df_sz = rport->maxfrsize; rport_attr->state = bfa_fcs_rport_get_state(rport); rport_attr->fc_cos = rport->fc_cos; rport_attr->cisc = rport->cisc; rport_attr->scsi_function = rport->scsi_function; rport_attr->curr_speed = rport->rpf.rpsc_speed; rport_attr->assigned_speed = rport->rpf.assigned_speed; bfa_rport_get_qos_attr(rport->bfa_rport, &qos_attr); rport_attr->qos_attr = qos_attr; rport_attr->trl_enforced = BFA_FALSE; if (bfa_fcport_is_ratelim(port->fcs->bfa)) { if ((rport->rpf.rpsc_speed == BFA_PPORT_SPEED_UNKNOWN) || (rport->rpf.rpsc_speed < bfa_fcs_port_get_rport_max_speed(port))) rport_attr->trl_enforced = BFA_TRUE; } /* * TODO * rport->symname */ } /** * Per remote device statistics. */ void bfa_fcs_rport_get_stats(struct bfa_fcs_rport_s *rport, struct bfa_rport_stats_s *stats) { *stats = rport->stats; } void bfa_fcs_rport_clear_stats(struct bfa_fcs_rport_s *rport) { bfa_os_memset((char *)&rport->stats, 0, sizeof(struct bfa_rport_stats_s)); } struct bfa_fcs_rport_s * bfa_fcs_rport_lookup(struct bfa_fcs_port_s *port, wwn_t rpwwn) { struct bfa_fcs_rport_s *rport; rport = bfa_fcs_port_get_rport_by_pwwn(port, rpwwn); if (rport == NULL) { /* * TBD Error handling */ } return rport; } struct bfa_fcs_rport_s * bfa_fcs_rport_lookup_by_nwwn(struct bfa_fcs_port_s *port, wwn_t rnwwn) { struct bfa_fcs_rport_s *rport; rport = bfa_fcs_port_get_rport_by_nwwn(port, rnwwn); if (rport == NULL) { /* * TBD Error handling */ } return rport; } /* * This API is to set the Rport's speed. Should be used when RPSC is not * supported by the rport. */ void bfa_fcs_rport_set_speed(struct bfa_fcs_rport_s *rport, enum bfa_pport_speed speed) { rport->rpf.assigned_speed = speed; /* Set this speed in f/w only if the RPSC speed is not available */ if (rport->rpf.rpsc_speed == BFA_PPORT_SPEED_UNKNOWN) bfa_rport_speed(rport->bfa_rport, speed); }