diff options
Diffstat (limited to 'drivers/scsi/bfa/rport_ftrs.c')
-rw-r--r-- | drivers/scsi/bfa/rport_ftrs.c | 379 |
1 files changed, 0 insertions, 379 deletions
diff --git a/drivers/scsi/bfa/rport_ftrs.c b/drivers/scsi/bfa/rport_ftrs.c deleted file mode 100644 index f2a9361ce9a..00000000000 --- a/drivers/scsi/bfa/rport_ftrs.c +++ /dev/null @@ -1,379 +0,0 @@ -/* - * 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. - */ - -/** - * rport_ftrs.c Remote port features (RPF) implementation. - */ - -#include <bfa.h> -#include <bfa_svc.h> -#include "fcbuild.h" -#include "fcs_rport.h" -#include "fcs_lport.h" -#include "fcs_trcmod.h" -#include "fcs_fcxp.h" -#include "fcs.h" - -BFA_TRC_FILE(FCS, RPORT_FTRS); - -#define BFA_FCS_RPF_RETRIES (3) -#define BFA_FCS_RPF_RETRY_TIMEOUT (1000) /* 1 sec (In millisecs) */ - -static void bfa_fcs_rpf_send_rpsc2(void *rport_cbarg, - struct bfa_fcxp_s *fcxp_alloced); -static void bfa_fcs_rpf_rpsc2_response(void *fcsarg, - struct bfa_fcxp_s *fcxp, void *cbarg, - bfa_status_t req_status, u32 rsp_len, - u32 resid_len, - struct fchs_s *rsp_fchs); -static void bfa_fcs_rpf_timeout(void *arg); - -/** - * fcs_rport_ftrs_sm FCS rport state machine events - */ - -enum rpf_event { - RPFSM_EVENT_RPORT_OFFLINE = 1, /* Rport offline */ - RPFSM_EVENT_RPORT_ONLINE = 2, /* Rport online */ - RPFSM_EVENT_FCXP_SENT = 3, /* Frame from has been sent */ - RPFSM_EVENT_TIMEOUT = 4, /* Rport SM timeout event */ - RPFSM_EVENT_RPSC_COMP = 5, - RPFSM_EVENT_RPSC_FAIL = 6, - RPFSM_EVENT_RPSC_ERROR = 7, -}; - -static void bfa_fcs_rpf_sm_uninit(struct bfa_fcs_rpf_s *rpf, - enum rpf_event event); -static void bfa_fcs_rpf_sm_rpsc_sending(struct bfa_fcs_rpf_s *rpf, - enum rpf_event event); -static void bfa_fcs_rpf_sm_rpsc(struct bfa_fcs_rpf_s *rpf, - enum rpf_event event); -static void bfa_fcs_rpf_sm_rpsc_retry(struct bfa_fcs_rpf_s *rpf, - enum rpf_event event); -static void bfa_fcs_rpf_sm_offline(struct bfa_fcs_rpf_s *rpf, - enum rpf_event event); -static void bfa_fcs_rpf_sm_online(struct bfa_fcs_rpf_s *rpf, - enum rpf_event event); - -static void -bfa_fcs_rpf_sm_uninit(struct bfa_fcs_rpf_s *rpf, enum rpf_event event) -{ - struct bfa_fcs_rport_s *rport = rpf->rport; - struct bfa_fcs_fabric_s *fabric = &rport->fcs->fabric; - - bfa_trc(rport->fcs, rport->pwwn); - bfa_trc(rport->fcs, rport->pid); - bfa_trc(rport->fcs, event); - - switch (event) { - case RPFSM_EVENT_RPORT_ONLINE: - /* Send RPSC2 to a Brocade fabric only. */ - if ((!BFA_FCS_PID_IS_WKA(rport->pid)) && - ((bfa_lps_is_brcd_fabric(rport->port->fabric->lps)) || - (bfa_fcs_fabric_get_switch_oui(fabric) == - BFA_FCS_BRCD_SWITCH_OUI))) { - bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_rpsc_sending); - rpf->rpsc_retries = 0; - bfa_fcs_rpf_send_rpsc2(rpf, NULL); - } - break; - - case RPFSM_EVENT_RPORT_OFFLINE: - break; - - default: - bfa_sm_fault(rport->fcs, event); - } -} - -static void -bfa_fcs_rpf_sm_rpsc_sending(struct bfa_fcs_rpf_s *rpf, enum rpf_event event) -{ - struct bfa_fcs_rport_s *rport = rpf->rport; - - bfa_trc(rport->fcs, event); - - switch (event) { - case RPFSM_EVENT_FCXP_SENT: - bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_rpsc); - break; - - case RPFSM_EVENT_RPORT_OFFLINE: - bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_offline); - bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rpf->fcxp_wqe); - rpf->rpsc_retries = 0; - break; - - default: - bfa_sm_fault(rport->fcs, event); - } -} - -static void -bfa_fcs_rpf_sm_rpsc(struct bfa_fcs_rpf_s *rpf, enum rpf_event event) -{ - struct bfa_fcs_rport_s *rport = rpf->rport; - - bfa_trc(rport->fcs, rport->pid); - bfa_trc(rport->fcs, event); - - switch (event) { - case RPFSM_EVENT_RPSC_COMP: - bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_online); - /* Update speed info in f/w via BFA */ - if (rpf->rpsc_speed != BFA_PPORT_SPEED_UNKNOWN) - bfa_rport_speed(rport->bfa_rport, rpf->rpsc_speed); - else if (rpf->assigned_speed != BFA_PPORT_SPEED_UNKNOWN) - bfa_rport_speed(rport->bfa_rport, rpf->assigned_speed); - break; - - case RPFSM_EVENT_RPSC_FAIL: - /* RPSC not supported by rport */ - bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_online); - break; - - case RPFSM_EVENT_RPSC_ERROR: - /* need to retry...delayed a bit. */ - if (rpf->rpsc_retries++ < BFA_FCS_RPF_RETRIES) { - bfa_timer_start(rport->fcs->bfa, &rpf->timer, - bfa_fcs_rpf_timeout, rpf, - BFA_FCS_RPF_RETRY_TIMEOUT); - bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_rpsc_retry); - } else { - bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_online); - } - break; - - case RPFSM_EVENT_RPORT_OFFLINE: - bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_offline); - bfa_fcxp_discard(rpf->fcxp); - rpf->rpsc_retries = 0; - break; - - default: - bfa_sm_fault(rport->fcs, event); - } -} - -static void -bfa_fcs_rpf_sm_rpsc_retry(struct bfa_fcs_rpf_s *rpf, enum rpf_event event) -{ - struct bfa_fcs_rport_s *rport = rpf->rport; - - bfa_trc(rport->fcs, rport->pid); - bfa_trc(rport->fcs, event); - - switch (event) { - case RPFSM_EVENT_TIMEOUT: - /* re-send the RPSC */ - bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_rpsc_sending); - bfa_fcs_rpf_send_rpsc2(rpf, NULL); - break; - - case RPFSM_EVENT_RPORT_OFFLINE: - bfa_timer_stop(&rpf->timer); - bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_offline); - rpf->rpsc_retries = 0; - break; - - default: - bfa_sm_fault(rport->fcs, event); - } -} - -static void -bfa_fcs_rpf_sm_online(struct bfa_fcs_rpf_s *rpf, enum rpf_event event) -{ - struct bfa_fcs_rport_s *rport = rpf->rport; - - bfa_trc(rport->fcs, rport->pwwn); - bfa_trc(rport->fcs, rport->pid); - bfa_trc(rport->fcs, event); - - switch (event) { - case RPFSM_EVENT_RPORT_OFFLINE: - bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_offline); - rpf->rpsc_retries = 0; - break; - - default: - bfa_sm_fault(rport->fcs, event); - } -} - -static void -bfa_fcs_rpf_sm_offline(struct bfa_fcs_rpf_s *rpf, enum rpf_event event) -{ - struct bfa_fcs_rport_s *rport = rpf->rport; - - bfa_trc(rport->fcs, rport->pwwn); - bfa_trc(rport->fcs, rport->pid); - bfa_trc(rport->fcs, event); - - switch (event) { - case RPFSM_EVENT_RPORT_ONLINE: - bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_rpsc_sending); - bfa_fcs_rpf_send_rpsc2(rpf, NULL); - break; - - case RPFSM_EVENT_RPORT_OFFLINE: - break; - - default: - bfa_sm_fault(rport->fcs, event); - } -} -/** - * Called when Rport is created. - */ -void bfa_fcs_rpf_init(struct bfa_fcs_rport_s *rport) -{ - struct bfa_fcs_rpf_s *rpf = &rport->rpf; - - bfa_trc(rport->fcs, rport->pid); - rpf->rport = rport; - - bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_uninit); -} - -/** - * Called when Rport becomes online - */ -void bfa_fcs_rpf_rport_online(struct bfa_fcs_rport_s *rport) -{ - bfa_trc(rport->fcs, rport->pid); - - if (__fcs_min_cfg(rport->port->fcs)) - return; - - if (bfa_fcs_fabric_is_switched(rport->port->fabric)) - bfa_sm_send_event(&rport->rpf, RPFSM_EVENT_RPORT_ONLINE); -} - -/** - * Called when Rport becomes offline - */ -void bfa_fcs_rpf_rport_offline(struct bfa_fcs_rport_s *rport) -{ - bfa_trc(rport->fcs, rport->pid); - - if (__fcs_min_cfg(rport->port->fcs)) - return; - - rport->rpf.rpsc_speed = 0; - bfa_sm_send_event(&rport->rpf, RPFSM_EVENT_RPORT_OFFLINE); -} - -static void -bfa_fcs_rpf_timeout(void *arg) -{ - struct bfa_fcs_rpf_s *rpf = (struct bfa_fcs_rpf_s *) arg; - struct bfa_fcs_rport_s *rport = rpf->rport; - - bfa_trc(rport->fcs, rport->pid); - bfa_sm_send_event(rpf, RPFSM_EVENT_TIMEOUT); -} - -static void -bfa_fcs_rpf_send_rpsc2(void *rpf_cbarg, struct bfa_fcxp_s *fcxp_alloced) -{ - struct bfa_fcs_rpf_s *rpf = (struct bfa_fcs_rpf_s *)rpf_cbarg; - struct bfa_fcs_rport_s *rport = rpf->rport; - struct bfa_fcs_port_s *port = rport->port; - struct fchs_s fchs; - int len; - struct bfa_fcxp_s *fcxp; - - bfa_trc(rport->fcs, rport->pwwn); - - fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs); - if (!fcxp) { - bfa_fcxp_alloc_wait(port->fcs->bfa, &rpf->fcxp_wqe, - bfa_fcs_rpf_send_rpsc2, rpf); - return; - } - rpf->fcxp = fcxp; - - len = fc_rpsc2_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), rport->pid, - bfa_fcs_port_get_fcid(port), &rport->pid, 1); - - bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, - FC_CLASS_3, len, &fchs, bfa_fcs_rpf_rpsc2_response, - rpf, FC_MAX_PDUSZ, FC_ELS_TOV); - rport->stats.rpsc_sent++; - bfa_sm_send_event(rpf, RPFSM_EVENT_FCXP_SENT); - -} - -static void -bfa_fcs_rpf_rpsc2_response(void *fcsarg, struct bfa_fcxp_s *fcxp, void *cbarg, - bfa_status_t req_status, u32 rsp_len, - u32 resid_len, struct fchs_s *rsp_fchs) -{ - struct bfa_fcs_rpf_s *rpf = (struct bfa_fcs_rpf_s *) cbarg; - struct bfa_fcs_rport_s *rport = rpf->rport; - struct fc_ls_rjt_s *ls_rjt; - struct fc_rpsc2_acc_s *rpsc2_acc; - u16 num_ents; - - bfa_trc(rport->fcs, req_status); - - if (req_status != BFA_STATUS_OK) { - bfa_trc(rport->fcs, req_status); - if (req_status == BFA_STATUS_ETIMER) - rport->stats.rpsc_failed++; - bfa_sm_send_event(rpf, RPFSM_EVENT_RPSC_ERROR); - return; - } - - rpsc2_acc = (struct fc_rpsc2_acc_s *) BFA_FCXP_RSP_PLD(fcxp); - if (rpsc2_acc->els_cmd == FC_ELS_ACC) { - rport->stats.rpsc_accs++; - num_ents = bfa_os_ntohs(rpsc2_acc->num_pids); - bfa_trc(rport->fcs, num_ents); - if (num_ents > 0) { - bfa_assert(rpsc2_acc->port_info[0].pid != rport->pid); - bfa_trc(rport->fcs, - bfa_os_ntohs(rpsc2_acc->port_info[0].pid)); - bfa_trc(rport->fcs, - bfa_os_ntohs(rpsc2_acc->port_info[0].speed)); - bfa_trc(rport->fcs, - bfa_os_ntohs(rpsc2_acc->port_info[0].index)); - bfa_trc(rport->fcs, - rpsc2_acc->port_info[0].type); - - if (rpsc2_acc->port_info[0].speed == 0) { - bfa_sm_send_event(rpf, RPFSM_EVENT_RPSC_ERROR); - return; - } - - rpf->rpsc_speed = fc_rpsc_operspeed_to_bfa_speed( - bfa_os_ntohs(rpsc2_acc->port_info[0].speed)); - - bfa_sm_send_event(rpf, RPFSM_EVENT_RPSC_COMP); - } - } else { - ls_rjt = (struct fc_ls_rjt_s *) BFA_FCXP_RSP_PLD(fcxp); - bfa_trc(rport->fcs, ls_rjt->reason_code); - bfa_trc(rport->fcs, ls_rjt->reason_code_expl); - rport->stats.rpsc_rejects++; - if (ls_rjt->reason_code == FC_LS_RJT_RSN_CMD_NOT_SUPP) - bfa_sm_send_event(rpf, RPFSM_EVENT_RPSC_FAIL); - else - bfa_sm_send_event(rpf, RPFSM_EVENT_RPSC_ERROR); - } -} |