17725ccfdSJing Huang /* 2a36c61f9SKrishna Gudipati * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. 37725ccfdSJing Huang * All rights reserved 47725ccfdSJing Huang * www.brocade.com 57725ccfdSJing Huang * 67725ccfdSJing Huang * Linux driver for Brocade Fibre Channel Host Bus Adapter. 77725ccfdSJing Huang * 87725ccfdSJing Huang * This program is free software; you can redistribute it and/or modify it 97725ccfdSJing Huang * under the terms of the GNU General Public License (GPL) Version 2 as 107725ccfdSJing Huang * published by the Free Software Foundation 117725ccfdSJing Huang * 127725ccfdSJing Huang * This program is distributed in the hope that it will be useful, but 137725ccfdSJing Huang * WITHOUT ANY WARRANTY; without even the implied warranty of 147725ccfdSJing Huang * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 157725ccfdSJing Huang * General Public License for more details. 167725ccfdSJing Huang */ 177725ccfdSJing Huang 187725ccfdSJing Huang /** 19a36c61f9SKrishna Gudipati * bfa_fcs_lport.c BFA FCS port 207725ccfdSJing Huang */ 217725ccfdSJing Huang 22a36c61f9SKrishna Gudipati #include "bfa_fcs.h" 23a36c61f9SKrishna Gudipati #include "bfa_fcbuild.h" 24a36c61f9SKrishna Gudipati #include "bfa_fc.h" 25a36c61f9SKrishna Gudipati #include "bfad_drv.h" 267725ccfdSJing Huang 277725ccfdSJing Huang BFA_TRC_FILE(FCS, PORT); 287725ccfdSJing Huang 297725ccfdSJing Huang /** 307725ccfdSJing Huang * Forward declarations 317725ccfdSJing Huang */ 327725ccfdSJing Huang 33a36c61f9SKrishna Gudipati static void bfa_fcs_lport_send_ls_rjt(struct bfa_fcs_lport_s *port, 347725ccfdSJing Huang struct fchs_s *rx_fchs, u8 reason_code, 357725ccfdSJing Huang u8 reason_code_expl); 36a36c61f9SKrishna Gudipati static void bfa_fcs_lport_plogi(struct bfa_fcs_lport_s *port, 37a36c61f9SKrishna Gudipati struct fchs_s *rx_fchs, struct fc_logi_s *plogi); 38a36c61f9SKrishna Gudipati static void bfa_fcs_lport_online_actions(struct bfa_fcs_lport_s *port); 39a36c61f9SKrishna Gudipati static void bfa_fcs_lport_offline_actions(struct bfa_fcs_lport_s *port); 40a36c61f9SKrishna Gudipati static void bfa_fcs_lport_unknown_init(struct bfa_fcs_lport_s *port); 41a36c61f9SKrishna Gudipati static void bfa_fcs_lport_unknown_online(struct bfa_fcs_lport_s *port); 42a36c61f9SKrishna Gudipati static void bfa_fcs_lport_unknown_offline(struct bfa_fcs_lport_s *port); 43a36c61f9SKrishna Gudipati static void bfa_fcs_lport_deleted(struct bfa_fcs_lport_s *port); 44a36c61f9SKrishna Gudipati static void bfa_fcs_lport_echo(struct bfa_fcs_lport_s *port, 457725ccfdSJing Huang struct fchs_s *rx_fchs, 467725ccfdSJing Huang struct fc_echo_s *echo, u16 len); 47a36c61f9SKrishna Gudipati static void bfa_fcs_lport_rnid(struct bfa_fcs_lport_s *port, 487725ccfdSJing Huang struct fchs_s *rx_fchs, 497725ccfdSJing Huang struct fc_rnid_cmd_s *rnid, u16 len); 50a36c61f9SKrishna Gudipati static void bfa_fs_port_get_gen_topo_data(struct bfa_fcs_lport_s *port, 517725ccfdSJing Huang struct fc_rnid_general_topology_data_s *gen_topo_data); 527725ccfdSJing Huang 53a36c61f9SKrishna Gudipati static void bfa_fcs_lport_fab_init(struct bfa_fcs_lport_s *port); 54a36c61f9SKrishna Gudipati static void bfa_fcs_lport_fab_online(struct bfa_fcs_lport_s *port); 55a36c61f9SKrishna Gudipati static void bfa_fcs_lport_fab_offline(struct bfa_fcs_lport_s *port); 56a36c61f9SKrishna Gudipati 57a36c61f9SKrishna Gudipati static void bfa_fcs_lport_n2n_init(struct bfa_fcs_lport_s *port); 58a36c61f9SKrishna Gudipati static void bfa_fcs_lport_n2n_online(struct bfa_fcs_lport_s *port); 59a36c61f9SKrishna Gudipati static void bfa_fcs_lport_n2n_offline(struct bfa_fcs_lport_s *port); 60a36c61f9SKrishna Gudipati 617725ccfdSJing Huang static struct { 62a36c61f9SKrishna Gudipati void (*init) (struct bfa_fcs_lport_s *port); 63a36c61f9SKrishna Gudipati void (*online) (struct bfa_fcs_lport_s *port); 64a36c61f9SKrishna Gudipati void (*offline) (struct bfa_fcs_lport_s *port); 657725ccfdSJing Huang } __port_action[] = { 667725ccfdSJing Huang { 67a36c61f9SKrishna Gudipati bfa_fcs_lport_unknown_init, bfa_fcs_lport_unknown_online, 68a36c61f9SKrishna Gudipati bfa_fcs_lport_unknown_offline}, { 69a36c61f9SKrishna Gudipati bfa_fcs_lport_fab_init, bfa_fcs_lport_fab_online, 70a36c61f9SKrishna Gudipati bfa_fcs_lport_fab_offline}, { 71a36c61f9SKrishna Gudipati bfa_fcs_lport_n2n_init, bfa_fcs_lport_n2n_online, 72a36c61f9SKrishna Gudipati bfa_fcs_lport_n2n_offline}, 73a36c61f9SKrishna Gudipati }; 747725ccfdSJing Huang 757725ccfdSJing Huang /** 767725ccfdSJing Huang * fcs_port_sm FCS logical port state machine 777725ccfdSJing Huang */ 787725ccfdSJing Huang 79a36c61f9SKrishna Gudipati enum bfa_fcs_lport_event { 807725ccfdSJing Huang BFA_FCS_PORT_SM_CREATE = 1, 817725ccfdSJing Huang BFA_FCS_PORT_SM_ONLINE = 2, 827725ccfdSJing Huang BFA_FCS_PORT_SM_OFFLINE = 3, 837725ccfdSJing Huang BFA_FCS_PORT_SM_DELETE = 4, 847725ccfdSJing Huang BFA_FCS_PORT_SM_DELRPORT = 5, 857725ccfdSJing Huang }; 867725ccfdSJing Huang 87a36c61f9SKrishna Gudipati static void bfa_fcs_lport_sm_uninit(struct bfa_fcs_lport_s *port, 88a36c61f9SKrishna Gudipati enum bfa_fcs_lport_event event); 89a36c61f9SKrishna Gudipati static void bfa_fcs_lport_sm_init(struct bfa_fcs_lport_s *port, 90a36c61f9SKrishna Gudipati enum bfa_fcs_lport_event event); 91a36c61f9SKrishna Gudipati static void bfa_fcs_lport_sm_online(struct bfa_fcs_lport_s *port, 92a36c61f9SKrishna Gudipati enum bfa_fcs_lport_event event); 93a36c61f9SKrishna Gudipati static void bfa_fcs_lport_sm_offline(struct bfa_fcs_lport_s *port, 94a36c61f9SKrishna Gudipati enum bfa_fcs_lport_event event); 95a36c61f9SKrishna Gudipati static void bfa_fcs_lport_sm_deleting(struct bfa_fcs_lport_s *port, 96a36c61f9SKrishna Gudipati enum bfa_fcs_lport_event event); 977725ccfdSJing Huang 987725ccfdSJing Huang static void 99a36c61f9SKrishna Gudipati bfa_fcs_lport_sm_uninit( 100a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port, 101a36c61f9SKrishna Gudipati enum bfa_fcs_lport_event event) 1027725ccfdSJing Huang { 1037725ccfdSJing Huang bfa_trc(port->fcs, port->port_cfg.pwwn); 1047725ccfdSJing Huang bfa_trc(port->fcs, event); 1057725ccfdSJing Huang 1067725ccfdSJing Huang switch (event) { 1077725ccfdSJing Huang case BFA_FCS_PORT_SM_CREATE: 108a36c61f9SKrishna Gudipati bfa_sm_set_state(port, bfa_fcs_lport_sm_init); 1097725ccfdSJing Huang break; 1107725ccfdSJing Huang 1117725ccfdSJing Huang default: 112e641de37SKrishna Gudipati bfa_sm_fault(port->fcs, event); 1137725ccfdSJing Huang } 1147725ccfdSJing Huang } 1157725ccfdSJing Huang 1167725ccfdSJing Huang static void 117a36c61f9SKrishna Gudipati bfa_fcs_lport_sm_init(struct bfa_fcs_lport_s *port, 118a36c61f9SKrishna Gudipati enum bfa_fcs_lport_event event) 1197725ccfdSJing Huang { 1207725ccfdSJing Huang bfa_trc(port->fcs, port->port_cfg.pwwn); 1217725ccfdSJing Huang bfa_trc(port->fcs, event); 1227725ccfdSJing Huang 1237725ccfdSJing Huang switch (event) { 1247725ccfdSJing Huang case BFA_FCS_PORT_SM_ONLINE: 125a36c61f9SKrishna Gudipati bfa_sm_set_state(port, bfa_fcs_lport_sm_online); 126a36c61f9SKrishna Gudipati bfa_fcs_lport_online_actions(port); 1277725ccfdSJing Huang break; 1287725ccfdSJing Huang 1297725ccfdSJing Huang case BFA_FCS_PORT_SM_DELETE: 130a36c61f9SKrishna Gudipati bfa_sm_set_state(port, bfa_fcs_lport_sm_uninit); 131a36c61f9SKrishna Gudipati bfa_fcs_lport_deleted(port); 1327725ccfdSJing Huang break; 1337725ccfdSJing Huang 1343e98cc01SJing Huang case BFA_FCS_PORT_SM_OFFLINE: 1353e98cc01SJing Huang break; 1363e98cc01SJing Huang 1377725ccfdSJing Huang default: 138e641de37SKrishna Gudipati bfa_sm_fault(port->fcs, event); 1397725ccfdSJing Huang } 1407725ccfdSJing Huang } 1417725ccfdSJing Huang 1427725ccfdSJing Huang static void 143a36c61f9SKrishna Gudipati bfa_fcs_lport_sm_online( 144a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port, 145a36c61f9SKrishna Gudipati enum bfa_fcs_lport_event event) 1467725ccfdSJing Huang { 1477725ccfdSJing Huang struct bfa_fcs_rport_s *rport; 1487725ccfdSJing Huang struct list_head *qe, *qen; 1497725ccfdSJing Huang 1507725ccfdSJing Huang bfa_trc(port->fcs, port->port_cfg.pwwn); 1517725ccfdSJing Huang bfa_trc(port->fcs, event); 1527725ccfdSJing Huang 1537725ccfdSJing Huang switch (event) { 1547725ccfdSJing Huang case BFA_FCS_PORT_SM_OFFLINE: 155a36c61f9SKrishna Gudipati bfa_sm_set_state(port, bfa_fcs_lport_sm_offline); 156a36c61f9SKrishna Gudipati bfa_fcs_lport_offline_actions(port); 1577725ccfdSJing Huang break; 1587725ccfdSJing Huang 1597725ccfdSJing Huang case BFA_FCS_PORT_SM_DELETE: 1607725ccfdSJing Huang 1617725ccfdSJing Huang __port_action[port->fabric->fab_type].offline(port); 1627725ccfdSJing Huang 1637725ccfdSJing Huang if (port->num_rports == 0) { 164a36c61f9SKrishna Gudipati bfa_sm_set_state(port, bfa_fcs_lport_sm_uninit); 165a36c61f9SKrishna Gudipati bfa_fcs_lport_deleted(port); 1667725ccfdSJing Huang } else { 167a36c61f9SKrishna Gudipati bfa_sm_set_state(port, bfa_fcs_lport_sm_deleting); 1687725ccfdSJing Huang list_for_each_safe(qe, qen, &port->rport_q) { 1697725ccfdSJing Huang rport = (struct bfa_fcs_rport_s *) qe; 1707725ccfdSJing Huang bfa_fcs_rport_delete(rport); 1717725ccfdSJing Huang } 1727725ccfdSJing Huang } 1737725ccfdSJing Huang break; 1747725ccfdSJing Huang 1757725ccfdSJing Huang case BFA_FCS_PORT_SM_DELRPORT: 1767725ccfdSJing Huang break; 1777725ccfdSJing Huang 1787725ccfdSJing Huang default: 179e641de37SKrishna Gudipati bfa_sm_fault(port->fcs, event); 1807725ccfdSJing Huang } 1817725ccfdSJing Huang } 1827725ccfdSJing Huang 1837725ccfdSJing Huang static void 184a36c61f9SKrishna Gudipati bfa_fcs_lport_sm_offline( 185a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port, 186a36c61f9SKrishna Gudipati enum bfa_fcs_lport_event event) 1877725ccfdSJing Huang { 1887725ccfdSJing Huang struct bfa_fcs_rport_s *rport; 1897725ccfdSJing Huang struct list_head *qe, *qen; 1907725ccfdSJing Huang 1917725ccfdSJing Huang bfa_trc(port->fcs, port->port_cfg.pwwn); 1927725ccfdSJing Huang bfa_trc(port->fcs, event); 1937725ccfdSJing Huang 1947725ccfdSJing Huang switch (event) { 1957725ccfdSJing Huang case BFA_FCS_PORT_SM_ONLINE: 196a36c61f9SKrishna Gudipati bfa_sm_set_state(port, bfa_fcs_lport_sm_online); 197a36c61f9SKrishna Gudipati bfa_fcs_lport_online_actions(port); 1987725ccfdSJing Huang break; 1997725ccfdSJing Huang 2007725ccfdSJing Huang case BFA_FCS_PORT_SM_DELETE: 2017725ccfdSJing Huang if (port->num_rports == 0) { 202a36c61f9SKrishna Gudipati bfa_sm_set_state(port, bfa_fcs_lport_sm_uninit); 203a36c61f9SKrishna Gudipati bfa_fcs_lport_deleted(port); 2047725ccfdSJing Huang } else { 205a36c61f9SKrishna Gudipati bfa_sm_set_state(port, bfa_fcs_lport_sm_deleting); 2067725ccfdSJing Huang list_for_each_safe(qe, qen, &port->rport_q) { 2077725ccfdSJing Huang rport = (struct bfa_fcs_rport_s *) qe; 2087725ccfdSJing Huang bfa_fcs_rport_delete(rport); 2097725ccfdSJing Huang } 2107725ccfdSJing Huang } 2117725ccfdSJing Huang break; 2127725ccfdSJing Huang 2137725ccfdSJing Huang case BFA_FCS_PORT_SM_DELRPORT: 2147725ccfdSJing Huang case BFA_FCS_PORT_SM_OFFLINE: 2157725ccfdSJing Huang break; 2167725ccfdSJing Huang 2177725ccfdSJing Huang default: 218e641de37SKrishna Gudipati bfa_sm_fault(port->fcs, event); 2197725ccfdSJing Huang } 2207725ccfdSJing Huang } 2217725ccfdSJing Huang 2227725ccfdSJing Huang static void 223a36c61f9SKrishna Gudipati bfa_fcs_lport_sm_deleting( 224a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port, 225a36c61f9SKrishna Gudipati enum bfa_fcs_lport_event event) 2267725ccfdSJing Huang { 2277725ccfdSJing Huang bfa_trc(port->fcs, port->port_cfg.pwwn); 2287725ccfdSJing Huang bfa_trc(port->fcs, event); 2297725ccfdSJing Huang 2307725ccfdSJing Huang switch (event) { 2317725ccfdSJing Huang case BFA_FCS_PORT_SM_DELRPORT: 2327725ccfdSJing Huang if (port->num_rports == 0) { 233a36c61f9SKrishna Gudipati bfa_sm_set_state(port, bfa_fcs_lport_sm_uninit); 234a36c61f9SKrishna Gudipati bfa_fcs_lport_deleted(port); 2357725ccfdSJing Huang } 2367725ccfdSJing Huang break; 2377725ccfdSJing Huang 2387725ccfdSJing Huang default: 239e641de37SKrishna Gudipati bfa_sm_fault(port->fcs, event); 2407725ccfdSJing Huang } 2417725ccfdSJing Huang } 2427725ccfdSJing Huang 2437725ccfdSJing Huang /** 2447725ccfdSJing Huang * fcs_port_pvt 2457725ccfdSJing Huang */ 2467725ccfdSJing Huang 2477725ccfdSJing Huang /* 2487725ccfdSJing Huang * Send a LS reject 2497725ccfdSJing Huang */ 2507725ccfdSJing Huang static void 251a36c61f9SKrishna Gudipati bfa_fcs_lport_send_ls_rjt(struct bfa_fcs_lport_s *port, struct fchs_s *rx_fchs, 2527725ccfdSJing Huang u8 reason_code, u8 reason_code_expl) 2537725ccfdSJing Huang { 2547725ccfdSJing Huang struct fchs_s fchs; 2557725ccfdSJing Huang struct bfa_fcxp_s *fcxp; 2567725ccfdSJing Huang struct bfa_rport_s *bfa_rport = NULL; 2577725ccfdSJing Huang int len; 2587725ccfdSJing Huang 259a36c61f9SKrishna Gudipati bfa_trc(port->fcs, rx_fchs->d_id); 2607725ccfdSJing Huang bfa_trc(port->fcs, rx_fchs->s_id); 2617725ccfdSJing Huang 2627725ccfdSJing Huang fcxp = bfa_fcs_fcxp_alloc(port->fcs); 2637725ccfdSJing Huang if (!fcxp) 2647725ccfdSJing Huang return; 2657725ccfdSJing Huang 266a36c61f9SKrishna Gudipati len = fc_ls_rjt_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), 267a36c61f9SKrishna Gudipati rx_fchs->s_id, bfa_fcs_lport_get_fcid(port), 268a36c61f9SKrishna Gudipati rx_fchs->ox_id, reason_code, reason_code_expl); 2697725ccfdSJing Huang 2707725ccfdSJing Huang bfa_fcxp_send(fcxp, bfa_rport, port->fabric->vf_id, port->lp_tag, 2717725ccfdSJing Huang BFA_FALSE, FC_CLASS_3, len, &fchs, NULL, NULL, 2727725ccfdSJing Huang FC_MAX_PDUSZ, 0); 2737725ccfdSJing Huang } 2747725ccfdSJing Huang 2757725ccfdSJing Huang /** 2767725ccfdSJing Huang * Process incoming plogi from a remote port. 2777725ccfdSJing Huang */ 2787725ccfdSJing Huang static void 279a36c61f9SKrishna Gudipati bfa_fcs_lport_plogi(struct bfa_fcs_lport_s *port, 280a36c61f9SKrishna Gudipati struct fchs_s *rx_fchs, struct fc_logi_s *plogi) 2817725ccfdSJing Huang { 2827725ccfdSJing Huang struct bfa_fcs_rport_s *rport; 2837725ccfdSJing Huang 2847725ccfdSJing Huang bfa_trc(port->fcs, rx_fchs->d_id); 2857725ccfdSJing Huang bfa_trc(port->fcs, rx_fchs->s_id); 2867725ccfdSJing Huang 2877725ccfdSJing Huang /* 2887725ccfdSJing Huang * If min cfg mode is enabled, drop any incoming PLOGIs 2897725ccfdSJing Huang */ 2907725ccfdSJing Huang if (__fcs_min_cfg(port->fcs)) { 2917725ccfdSJing Huang bfa_trc(port->fcs, rx_fchs->s_id); 2927725ccfdSJing Huang return; 2937725ccfdSJing Huang } 2947725ccfdSJing Huang 2957725ccfdSJing Huang if (fc_plogi_parse(rx_fchs) != FC_PARSE_OK) { 2967725ccfdSJing Huang bfa_trc(port->fcs, rx_fchs->s_id); 2977725ccfdSJing Huang /* 2987725ccfdSJing Huang * send a LS reject 2997725ccfdSJing Huang */ 300a36c61f9SKrishna Gudipati bfa_fcs_lport_send_ls_rjt(port, rx_fchs, 3017725ccfdSJing Huang FC_LS_RJT_RSN_PROTOCOL_ERROR, 3027725ccfdSJing Huang FC_LS_RJT_EXP_SPARMS_ERR_OPTIONS); 3037725ccfdSJing Huang return; 3047725ccfdSJing Huang } 3057725ccfdSJing Huang 3067725ccfdSJing Huang /** 3077725ccfdSJing Huang * Direct Attach P2P mode : verify address assigned by the r-port. 3087725ccfdSJing Huang */ 309a36c61f9SKrishna Gudipati if ((!bfa_fcs_fabric_is_switched(port->fabric)) && 310a36c61f9SKrishna Gudipati (memcmp((void *)&bfa_fcs_lport_get_pwwn(port), 311a36c61f9SKrishna Gudipati (void *)&plogi->port_name, sizeof(wwn_t)) < 0)) { 3127725ccfdSJing Huang if (BFA_FCS_PID_IS_WKA(rx_fchs->d_id)) { 313a36c61f9SKrishna Gudipati /* Address assigned to us cannot be a WKA */ 314a36c61f9SKrishna Gudipati bfa_fcs_lport_send_ls_rjt(port, rx_fchs, 3157725ccfdSJing Huang FC_LS_RJT_RSN_PROTOCOL_ERROR, 3167725ccfdSJing Huang FC_LS_RJT_EXP_INVALID_NPORT_ID); 3177725ccfdSJing Huang return; 3187725ccfdSJing Huang } 3197725ccfdSJing Huang port->pid = rx_fchs->d_id; 3207725ccfdSJing Huang } 3217725ccfdSJing Huang 3227725ccfdSJing Huang /** 3237725ccfdSJing Huang * First, check if we know the device by pwwn. 3247725ccfdSJing Huang */ 325a36c61f9SKrishna Gudipati rport = bfa_fcs_lport_get_rport_by_pwwn(port, plogi->port_name); 3267725ccfdSJing Huang if (rport) { 3277725ccfdSJing Huang /** 328a36c61f9SKrishna Gudipati * Direct Attach P2P mode : handle address assigned by r-port. 3297725ccfdSJing Huang */ 330a36c61f9SKrishna Gudipati if ((!bfa_fcs_fabric_is_switched(port->fabric)) && 331a36c61f9SKrishna Gudipati (memcmp((void *)&bfa_fcs_lport_get_pwwn(port), 3327725ccfdSJing Huang (void *)&plogi->port_name, sizeof(wwn_t)) < 0)) { 3337725ccfdSJing Huang port->pid = rx_fchs->d_id; 3347725ccfdSJing Huang rport->pid = rx_fchs->s_id; 3357725ccfdSJing Huang } 3367725ccfdSJing Huang bfa_fcs_rport_plogi(rport, rx_fchs, plogi); 3377725ccfdSJing Huang return; 3387725ccfdSJing Huang } 3397725ccfdSJing Huang 3407725ccfdSJing Huang /** 3417725ccfdSJing Huang * Next, lookup rport by PID. 3427725ccfdSJing Huang */ 343a36c61f9SKrishna Gudipati rport = bfa_fcs_lport_get_rport_by_pid(port, rx_fchs->s_id); 3447725ccfdSJing Huang if (!rport) { 3457725ccfdSJing Huang /** 3467725ccfdSJing Huang * Inbound PLOGI from a new device. 3477725ccfdSJing Huang */ 3487725ccfdSJing Huang bfa_fcs_rport_plogi_create(port, rx_fchs, plogi); 3497725ccfdSJing Huang return; 3507725ccfdSJing Huang } 3517725ccfdSJing Huang 3527725ccfdSJing Huang /** 3537725ccfdSJing Huang * Rport is known only by PID. 3547725ccfdSJing Huang */ 3557725ccfdSJing Huang if (rport->pwwn) { 3567725ccfdSJing Huang /** 3577725ccfdSJing Huang * This is a different device with the same pid. Old device 3587725ccfdSJing Huang * disappeared. Send implicit LOGO to old device. 3597725ccfdSJing Huang */ 3607725ccfdSJing Huang bfa_assert(rport->pwwn != plogi->port_name); 3617725ccfdSJing Huang bfa_fcs_rport_logo_imp(rport); 3627725ccfdSJing Huang 3637725ccfdSJing Huang /** 3647725ccfdSJing Huang * Inbound PLOGI from a new device (with old PID). 3657725ccfdSJing Huang */ 3667725ccfdSJing Huang bfa_fcs_rport_plogi_create(port, rx_fchs, plogi); 3677725ccfdSJing Huang return; 3687725ccfdSJing Huang } 3697725ccfdSJing Huang 3707725ccfdSJing Huang /** 3717725ccfdSJing Huang * PLOGI crossing each other. 3727725ccfdSJing Huang */ 3737725ccfdSJing Huang bfa_assert(rport->pwwn == WWN_NULL); 3747725ccfdSJing Huang bfa_fcs_rport_plogi(rport, rx_fchs, plogi); 3757725ccfdSJing Huang } 3767725ccfdSJing Huang 3777725ccfdSJing Huang /* 3787725ccfdSJing Huang * Process incoming ECHO. 3797725ccfdSJing Huang * Since it does not require a login, it is processed here. 3807725ccfdSJing Huang */ 3817725ccfdSJing Huang static void 382a36c61f9SKrishna Gudipati bfa_fcs_lport_echo(struct bfa_fcs_lport_s *port, struct fchs_s *rx_fchs, 3837725ccfdSJing Huang struct fc_echo_s *echo, u16 rx_len) 3847725ccfdSJing Huang { 3857725ccfdSJing Huang struct fchs_s fchs; 3867725ccfdSJing Huang struct bfa_fcxp_s *fcxp; 3877725ccfdSJing Huang struct bfa_rport_s *bfa_rport = NULL; 3887725ccfdSJing Huang int len, pyld_len; 3897725ccfdSJing Huang 3907725ccfdSJing Huang bfa_trc(port->fcs, rx_fchs->s_id); 3917725ccfdSJing Huang bfa_trc(port->fcs, rx_fchs->d_id); 3927725ccfdSJing Huang 3937725ccfdSJing Huang fcxp = bfa_fcs_fcxp_alloc(port->fcs); 3947725ccfdSJing Huang if (!fcxp) 3957725ccfdSJing Huang return; 3967725ccfdSJing Huang 397a36c61f9SKrishna Gudipati len = fc_ls_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), 398a36c61f9SKrishna Gudipati rx_fchs->s_id, bfa_fcs_lport_get_fcid(port), 399a36c61f9SKrishna Gudipati rx_fchs->ox_id); 4007725ccfdSJing Huang 4017725ccfdSJing Huang /* 4027725ccfdSJing Huang * Copy the payload (if any) from the echo frame 4037725ccfdSJing Huang */ 4047725ccfdSJing Huang pyld_len = rx_len - sizeof(struct fchs_s); 405a36c61f9SKrishna Gudipati bfa_trc(port->fcs, rx_len); 4067725ccfdSJing Huang bfa_trc(port->fcs, pyld_len); 4077725ccfdSJing Huang 4087725ccfdSJing Huang if (pyld_len > len) 4097725ccfdSJing Huang memcpy(((u8 *) bfa_fcxp_get_reqbuf(fcxp)) + 4107725ccfdSJing Huang sizeof(struct fc_echo_s), (echo + 1), 4117725ccfdSJing Huang (pyld_len - sizeof(struct fc_echo_s))); 4127725ccfdSJing Huang 4137725ccfdSJing Huang bfa_fcxp_send(fcxp, bfa_rport, port->fabric->vf_id, port->lp_tag, 4147725ccfdSJing Huang BFA_FALSE, FC_CLASS_3, pyld_len, &fchs, NULL, NULL, 4157725ccfdSJing Huang FC_MAX_PDUSZ, 0); 4167725ccfdSJing Huang } 4177725ccfdSJing Huang 4187725ccfdSJing Huang /* 4197725ccfdSJing Huang * Process incoming RNID. 4207725ccfdSJing Huang * Since it does not require a login, it is processed here. 4217725ccfdSJing Huang */ 4227725ccfdSJing Huang static void 423a36c61f9SKrishna Gudipati bfa_fcs_lport_rnid(struct bfa_fcs_lport_s *port, struct fchs_s *rx_fchs, 4247725ccfdSJing Huang struct fc_rnid_cmd_s *rnid, u16 rx_len) 4257725ccfdSJing Huang { 4267725ccfdSJing Huang struct fc_rnid_common_id_data_s common_id_data; 4277725ccfdSJing Huang struct fc_rnid_general_topology_data_s gen_topo_data; 4287725ccfdSJing Huang struct fchs_s fchs; 4297725ccfdSJing Huang struct bfa_fcxp_s *fcxp; 4307725ccfdSJing Huang struct bfa_rport_s *bfa_rport = NULL; 4317725ccfdSJing Huang u16 len; 4327725ccfdSJing Huang u32 data_format; 4337725ccfdSJing Huang 4347725ccfdSJing Huang bfa_trc(port->fcs, rx_fchs->s_id); 4357725ccfdSJing Huang bfa_trc(port->fcs, rx_fchs->d_id); 4367725ccfdSJing Huang bfa_trc(port->fcs, rx_len); 4377725ccfdSJing Huang 4387725ccfdSJing Huang fcxp = bfa_fcs_fcxp_alloc(port->fcs); 4397725ccfdSJing Huang if (!fcxp) 4407725ccfdSJing Huang return; 4417725ccfdSJing Huang 4427725ccfdSJing Huang /* 4437725ccfdSJing Huang * Check Node Indentification Data Format 4447725ccfdSJing Huang * We only support General Topology Discovery Format. 4457725ccfdSJing Huang * For any other requested Data Formats, we return Common Node Id Data 4467725ccfdSJing Huang * only, as per FC-LS. 4477725ccfdSJing Huang */ 4487725ccfdSJing Huang bfa_trc(port->fcs, rnid->node_id_data_format); 4497725ccfdSJing Huang if (rnid->node_id_data_format == RNID_NODEID_DATA_FORMAT_DISCOVERY) { 4507725ccfdSJing Huang data_format = RNID_NODEID_DATA_FORMAT_DISCOVERY; 4517725ccfdSJing Huang /* 4527725ccfdSJing Huang * Get General topology data for this port 4537725ccfdSJing Huang */ 4547725ccfdSJing Huang bfa_fs_port_get_gen_topo_data(port, &gen_topo_data); 4557725ccfdSJing Huang } else { 4567725ccfdSJing Huang data_format = RNID_NODEID_DATA_FORMAT_COMMON; 4577725ccfdSJing Huang } 4587725ccfdSJing Huang 4597725ccfdSJing Huang /* 4607725ccfdSJing Huang * Copy the Node Id Info 4617725ccfdSJing Huang */ 462a36c61f9SKrishna Gudipati common_id_data.port_name = bfa_fcs_lport_get_pwwn(port); 463a36c61f9SKrishna Gudipati common_id_data.node_name = bfa_fcs_lport_get_nwwn(port); 4647725ccfdSJing Huang 465a36c61f9SKrishna Gudipati len = fc_rnid_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), 466a36c61f9SKrishna Gudipati rx_fchs->s_id, bfa_fcs_lport_get_fcid(port), 467a36c61f9SKrishna Gudipati rx_fchs->ox_id, data_format, &common_id_data, 468a36c61f9SKrishna Gudipati &gen_topo_data); 4697725ccfdSJing Huang 4707725ccfdSJing Huang bfa_fcxp_send(fcxp, bfa_rport, port->fabric->vf_id, port->lp_tag, 4717725ccfdSJing Huang BFA_FALSE, FC_CLASS_3, len, &fchs, NULL, NULL, 4727725ccfdSJing Huang FC_MAX_PDUSZ, 0); 4737725ccfdSJing Huang } 4747725ccfdSJing Huang 4757725ccfdSJing Huang /* 4767725ccfdSJing Huang * Fill out General Topolpgy Discovery Data for RNID ELS. 4777725ccfdSJing Huang */ 4787725ccfdSJing Huang static void 479a36c61f9SKrishna Gudipati bfa_fs_port_get_gen_topo_data(struct bfa_fcs_lport_s *port, 4807725ccfdSJing Huang struct fc_rnid_general_topology_data_s *gen_topo_data) 4817725ccfdSJing Huang { 4826a18b167SJing Huang memset(gen_topo_data, 0, 4837725ccfdSJing Huang sizeof(struct fc_rnid_general_topology_data_s)); 4847725ccfdSJing Huang 485ba816ea8SJing Huang gen_topo_data->asso_type = cpu_to_be32(RNID_ASSOCIATED_TYPE_HOST); 4867725ccfdSJing Huang gen_topo_data->phy_port_num = 0; /* @todo */ 487ba816ea8SJing Huang gen_topo_data->num_attached_nodes = cpu_to_be32(1); 4887725ccfdSJing Huang } 4897725ccfdSJing Huang 4907725ccfdSJing Huang static void 491a36c61f9SKrishna Gudipati bfa_fcs_lport_online_actions(struct bfa_fcs_lport_s *port) 4927725ccfdSJing Huang { 493a36c61f9SKrishna Gudipati struct bfad_s *bfad = (struct bfad_s *)port->fcs->bfad; 494a36c61f9SKrishna Gudipati char lpwwn_buf[BFA_STRING_32]; 495a36c61f9SKrishna Gudipati 4967725ccfdSJing Huang bfa_trc(port->fcs, port->fabric->oper_type); 4977725ccfdSJing Huang 4987725ccfdSJing Huang __port_action[port->fabric->fab_type].init(port); 4997725ccfdSJing Huang __port_action[port->fabric->fab_type].online(port); 5007725ccfdSJing Huang 501a36c61f9SKrishna Gudipati wwn2str(lpwwn_buf, bfa_fcs_lport_get_pwwn(port)); 502a36c61f9SKrishna Gudipati BFA_LOG(KERN_INFO, bfad, log_level, 503a36c61f9SKrishna Gudipati "Logical port online: WWN = %s Role = %s\n", 504a36c61f9SKrishna Gudipati lpwwn_buf, "Initiator"); 505a36c61f9SKrishna Gudipati 506a36c61f9SKrishna Gudipati bfad->bfad_flags |= BFAD_PORT_ONLINE; 5077725ccfdSJing Huang } 5087725ccfdSJing Huang 5097725ccfdSJing Huang static void 510a36c61f9SKrishna Gudipati bfa_fcs_lport_offline_actions(struct bfa_fcs_lport_s *port) 5117725ccfdSJing Huang { 5127725ccfdSJing Huang struct list_head *qe, *qen; 5137725ccfdSJing Huang struct bfa_fcs_rport_s *rport; 514a36c61f9SKrishna Gudipati struct bfad_s *bfad = (struct bfad_s *)port->fcs->bfad; 515a36c61f9SKrishna Gudipati char lpwwn_buf[BFA_STRING_32]; 5167725ccfdSJing Huang 5177725ccfdSJing Huang bfa_trc(port->fcs, port->fabric->oper_type); 5187725ccfdSJing Huang 5197725ccfdSJing Huang __port_action[port->fabric->fab_type].offline(port); 5207725ccfdSJing Huang 521a36c61f9SKrishna Gudipati wwn2str(lpwwn_buf, bfa_fcs_lport_get_pwwn(port)); 522f8ceafdeSJing Huang if (bfa_fcs_fabric_is_online(port->fabric) == BFA_TRUE) 523a36c61f9SKrishna Gudipati BFA_LOG(KERN_ERR, bfad, log_level, 524a36c61f9SKrishna Gudipati "Logical port lost fabric connectivity: WWN = %s Role = %s\n", 525a36c61f9SKrishna Gudipati lpwwn_buf, "Initiator"); 526f8ceafdeSJing Huang else 527a36c61f9SKrishna Gudipati BFA_LOG(KERN_INFO, bfad, log_level, 528a36c61f9SKrishna Gudipati "Logical port taken offline: WWN = %s Role = %s\n", 529a36c61f9SKrishna Gudipati lpwwn_buf, "Initiator"); 5307725ccfdSJing Huang 5317725ccfdSJing Huang list_for_each_safe(qe, qen, &port->rport_q) { 5327725ccfdSJing Huang rport = (struct bfa_fcs_rport_s *) qe; 5337725ccfdSJing Huang bfa_fcs_rport_offline(rport); 5347725ccfdSJing Huang } 5357725ccfdSJing Huang } 5367725ccfdSJing Huang 5377725ccfdSJing Huang static void 538a36c61f9SKrishna Gudipati bfa_fcs_lport_unknown_init(struct bfa_fcs_lport_s *port) 5397725ccfdSJing Huang { 5407725ccfdSJing Huang bfa_assert(0); 5417725ccfdSJing Huang } 5427725ccfdSJing Huang 5437725ccfdSJing Huang static void 544a36c61f9SKrishna Gudipati bfa_fcs_lport_unknown_online(struct bfa_fcs_lport_s *port) 5457725ccfdSJing Huang { 5467725ccfdSJing Huang bfa_assert(0); 5477725ccfdSJing Huang } 5487725ccfdSJing Huang 5497725ccfdSJing Huang static void 550a36c61f9SKrishna Gudipati bfa_fcs_lport_unknown_offline(struct bfa_fcs_lport_s *port) 5517725ccfdSJing Huang { 5527725ccfdSJing Huang bfa_assert(0); 5537725ccfdSJing Huang } 5547725ccfdSJing Huang 5557725ccfdSJing Huang static void 556a36c61f9SKrishna Gudipati bfa_fcs_lport_abts_acc(struct bfa_fcs_lport_s *port, struct fchs_s *rx_fchs) 5577725ccfdSJing Huang { 558a36c61f9SKrishna Gudipati struct fchs_s fchs; 559a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp; 560a36c61f9SKrishna Gudipati int len; 5617725ccfdSJing Huang 562a36c61f9SKrishna Gudipati bfa_trc(port->fcs, rx_fchs->d_id); 563a36c61f9SKrishna Gudipati bfa_trc(port->fcs, rx_fchs->s_id); 564a36c61f9SKrishna Gudipati 565a36c61f9SKrishna Gudipati fcxp = bfa_fcs_fcxp_alloc(port->fcs); 566a36c61f9SKrishna Gudipati if (!fcxp) 567a36c61f9SKrishna Gudipati return; 568a36c61f9SKrishna Gudipati 569a36c61f9SKrishna Gudipati len = fc_ba_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), 570a36c61f9SKrishna Gudipati rx_fchs->s_id, bfa_fcs_lport_get_fcid(port), 571a36c61f9SKrishna Gudipati rx_fchs->ox_id, 0); 572a36c61f9SKrishna Gudipati 573a36c61f9SKrishna Gudipati bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, 574a36c61f9SKrishna Gudipati BFA_FALSE, FC_CLASS_3, len, &fchs, NULL, NULL, 575a36c61f9SKrishna Gudipati FC_MAX_PDUSZ, 0); 576a36c61f9SKrishna Gudipati } 577a36c61f9SKrishna Gudipati static void 578a36c61f9SKrishna Gudipati bfa_fcs_lport_deleted(struct bfa_fcs_lport_s *port) 579a36c61f9SKrishna Gudipati { 580a36c61f9SKrishna Gudipati struct bfad_s *bfad = (struct bfad_s *)port->fcs->bfad; 581a36c61f9SKrishna Gudipati char lpwwn_buf[BFA_STRING_32]; 582a36c61f9SKrishna Gudipati 583a36c61f9SKrishna Gudipati wwn2str(lpwwn_buf, bfa_fcs_lport_get_pwwn(port)); 584a36c61f9SKrishna Gudipati BFA_LOG(KERN_INFO, bfad, log_level, 585a36c61f9SKrishna Gudipati "Logical port deleted: WWN = %s Role = %s\n", 586a36c61f9SKrishna Gudipati lpwwn_buf, "Initiator"); 587a36c61f9SKrishna Gudipati 588a36c61f9SKrishna Gudipati /* Base port will be deleted by the OS driver */ 5897725ccfdSJing Huang if (port->vport) { 590a36c61f9SKrishna Gudipati bfa_fcb_lport_delete(port->fcs->bfad, port->port_cfg.roles, 5917725ccfdSJing Huang port->fabric->vf_drv, 5927725ccfdSJing Huang port->vport ? port->vport->vport_drv : NULL); 5937725ccfdSJing Huang bfa_fcs_vport_delete_comp(port->vport); 5947725ccfdSJing Huang } else { 5957725ccfdSJing Huang bfa_fcs_fabric_port_delete_comp(port->fabric); 5967725ccfdSJing Huang } 5977725ccfdSJing Huang } 5987725ccfdSJing Huang 5997725ccfdSJing Huang 6007725ccfdSJing Huang 6017725ccfdSJing Huang /** 6027725ccfdSJing Huang * fcs_lport_api BFA FCS port API 6037725ccfdSJing Huang */ 6047725ccfdSJing Huang /** 6057725ccfdSJing Huang * Module initialization 6067725ccfdSJing Huang */ 6077725ccfdSJing Huang void 608a36c61f9SKrishna Gudipati bfa_fcs_lport_modinit(struct bfa_fcs_s *fcs) 6097725ccfdSJing Huang { 6107725ccfdSJing Huang 6117725ccfdSJing Huang } 6127725ccfdSJing Huang 6137725ccfdSJing Huang /** 6147725ccfdSJing Huang * Module cleanup 6157725ccfdSJing Huang */ 6167725ccfdSJing Huang void 617a36c61f9SKrishna Gudipati bfa_fcs_lport_modexit(struct bfa_fcs_s *fcs) 6187725ccfdSJing Huang { 6197725ccfdSJing Huang bfa_fcs_modexit_comp(fcs); 6207725ccfdSJing Huang } 6217725ccfdSJing Huang 6227725ccfdSJing Huang /** 6237725ccfdSJing Huang * Unsolicited frame receive handling. 6247725ccfdSJing Huang */ 6257725ccfdSJing Huang void 626a36c61f9SKrishna Gudipati bfa_fcs_lport_uf_recv(struct bfa_fcs_lport_s *lport, 627a36c61f9SKrishna Gudipati struct fchs_s *fchs, u16 len) 6287725ccfdSJing Huang { 6297725ccfdSJing Huang u32 pid = fchs->s_id; 6307725ccfdSJing Huang struct bfa_fcs_rport_s *rport = NULL; 6317725ccfdSJing Huang struct fc_els_cmd_s *els_cmd = (struct fc_els_cmd_s *) (fchs + 1); 6327725ccfdSJing Huang 6337725ccfdSJing Huang bfa_stats(lport, uf_recvs); 6347725ccfdSJing Huang 635a36c61f9SKrishna Gudipati if (!bfa_fcs_lport_is_online(lport)) { 6367725ccfdSJing Huang bfa_stats(lport, uf_recv_drops); 6377725ccfdSJing Huang return; 6387725ccfdSJing Huang } 6397725ccfdSJing Huang 6407725ccfdSJing Huang /** 6417725ccfdSJing Huang * First, handle ELSs that donot require a login. 6427725ccfdSJing Huang */ 6437725ccfdSJing Huang /* 6447725ccfdSJing Huang * Handle PLOGI first 6457725ccfdSJing Huang */ 6467725ccfdSJing Huang if ((fchs->type == FC_TYPE_ELS) && 6477725ccfdSJing Huang (els_cmd->els_code == FC_ELS_PLOGI)) { 648a36c61f9SKrishna Gudipati bfa_fcs_lport_plogi(lport, fchs, (struct fc_logi_s *) els_cmd); 6497725ccfdSJing Huang return; 6507725ccfdSJing Huang } 6517725ccfdSJing Huang 6527725ccfdSJing Huang /* 6537725ccfdSJing Huang * Handle ECHO separately. 6547725ccfdSJing Huang */ 6557725ccfdSJing Huang if ((fchs->type == FC_TYPE_ELS) && (els_cmd->els_code == FC_ELS_ECHO)) { 656a36c61f9SKrishna Gudipati bfa_fcs_lport_echo(lport, fchs, 6577725ccfdSJing Huang (struct fc_echo_s *)els_cmd, len); 6587725ccfdSJing Huang return; 6597725ccfdSJing Huang } 6607725ccfdSJing Huang 6617725ccfdSJing Huang /* 6627725ccfdSJing Huang * Handle RNID separately. 6637725ccfdSJing Huang */ 6647725ccfdSJing Huang if ((fchs->type == FC_TYPE_ELS) && (els_cmd->els_code == FC_ELS_RNID)) { 665a36c61f9SKrishna Gudipati bfa_fcs_lport_rnid(lport, fchs, 6667725ccfdSJing Huang (struct fc_rnid_cmd_s *) els_cmd, len); 6677725ccfdSJing Huang return; 6687725ccfdSJing Huang } 6697725ccfdSJing Huang 670a36c61f9SKrishna Gudipati if (fchs->type == FC_TYPE_BLS) { 671a36c61f9SKrishna Gudipati if ((fchs->routing == FC_RTG_BASIC_LINK) && 672a36c61f9SKrishna Gudipati (fchs->cat_info == FC_CAT_ABTS)) 673a36c61f9SKrishna Gudipati bfa_fcs_lport_abts_acc(lport, fchs); 674a36c61f9SKrishna Gudipati return; 675a36c61f9SKrishna Gudipati } 6767725ccfdSJing Huang /** 6777725ccfdSJing Huang * look for a matching remote port ID 6787725ccfdSJing Huang */ 679a36c61f9SKrishna Gudipati rport = bfa_fcs_lport_get_rport_by_pid(lport, pid); 6807725ccfdSJing Huang if (rport) { 6817725ccfdSJing Huang bfa_trc(rport->fcs, fchs->s_id); 6827725ccfdSJing Huang bfa_trc(rport->fcs, fchs->d_id); 6837725ccfdSJing Huang bfa_trc(rport->fcs, fchs->type); 6847725ccfdSJing Huang 6857725ccfdSJing Huang bfa_fcs_rport_uf_recv(rport, fchs, len); 6867725ccfdSJing Huang return; 6877725ccfdSJing Huang } 6887725ccfdSJing Huang 6897725ccfdSJing Huang /** 6907725ccfdSJing Huang * Only handles ELS frames for now. 6917725ccfdSJing Huang */ 6927725ccfdSJing Huang if (fchs->type != FC_TYPE_ELS) { 6937725ccfdSJing Huang bfa_trc(lport->fcs, fchs->type); 6947725ccfdSJing Huang bfa_assert(0); 6957725ccfdSJing Huang return; 6967725ccfdSJing Huang } 6977725ccfdSJing Huang 6987725ccfdSJing Huang bfa_trc(lport->fcs, els_cmd->els_code); 6997725ccfdSJing Huang if (els_cmd->els_code == FC_ELS_RSCN) { 700a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_process_rscn(lport, fchs, len); 7017725ccfdSJing Huang return; 7027725ccfdSJing Huang } 7037725ccfdSJing Huang 7047725ccfdSJing Huang if (els_cmd->els_code == FC_ELS_LOGO) { 7057725ccfdSJing Huang /** 7067725ccfdSJing Huang * @todo Handle LOGO frames received. 7077725ccfdSJing Huang */ 7087725ccfdSJing Huang return; 7097725ccfdSJing Huang } 7107725ccfdSJing Huang 7117725ccfdSJing Huang if (els_cmd->els_code == FC_ELS_PRLI) { 7127725ccfdSJing Huang /** 7137725ccfdSJing Huang * @todo Handle PRLI frames received. 7147725ccfdSJing Huang */ 7157725ccfdSJing Huang return; 7167725ccfdSJing Huang } 7177725ccfdSJing Huang 7187725ccfdSJing Huang /** 7197725ccfdSJing Huang * Unhandled ELS frames. Send a LS_RJT. 7207725ccfdSJing Huang */ 721a36c61f9SKrishna Gudipati bfa_fcs_lport_send_ls_rjt(lport, fchs, FC_LS_RJT_RSN_CMD_NOT_SUPP, 7227725ccfdSJing Huang FC_LS_RJT_EXP_NO_ADDL_INFO); 7237725ccfdSJing Huang 7247725ccfdSJing Huang } 7257725ccfdSJing Huang 7267725ccfdSJing Huang /** 7277725ccfdSJing Huang * PID based Lookup for a R-Port in the Port R-Port Queue 7287725ccfdSJing Huang */ 7297725ccfdSJing Huang struct bfa_fcs_rport_s * 730a36c61f9SKrishna Gudipati bfa_fcs_lport_get_rport_by_pid(struct bfa_fcs_lport_s *port, u32 pid) 7317725ccfdSJing Huang { 7327725ccfdSJing Huang struct bfa_fcs_rport_s *rport; 7337725ccfdSJing Huang struct list_head *qe; 7347725ccfdSJing Huang 7357725ccfdSJing Huang list_for_each(qe, &port->rport_q) { 7367725ccfdSJing Huang rport = (struct bfa_fcs_rport_s *) qe; 7377725ccfdSJing Huang if (rport->pid == pid) 7387725ccfdSJing Huang return rport; 7397725ccfdSJing Huang } 7407725ccfdSJing Huang 7417725ccfdSJing Huang bfa_trc(port->fcs, pid); 7427725ccfdSJing Huang return NULL; 7437725ccfdSJing Huang } 7447725ccfdSJing Huang 7457725ccfdSJing Huang /** 7467725ccfdSJing Huang * PWWN based Lookup for a R-Port in the Port R-Port Queue 7477725ccfdSJing Huang */ 7487725ccfdSJing Huang struct bfa_fcs_rport_s * 749a36c61f9SKrishna Gudipati bfa_fcs_lport_get_rport_by_pwwn(struct bfa_fcs_lport_s *port, wwn_t pwwn) 7507725ccfdSJing Huang { 7517725ccfdSJing Huang struct bfa_fcs_rport_s *rport; 7527725ccfdSJing Huang struct list_head *qe; 7537725ccfdSJing Huang 7547725ccfdSJing Huang list_for_each(qe, &port->rport_q) { 7557725ccfdSJing Huang rport = (struct bfa_fcs_rport_s *) qe; 7567725ccfdSJing Huang if (wwn_is_equal(rport->pwwn, pwwn)) 7577725ccfdSJing Huang return rport; 7587725ccfdSJing Huang } 7597725ccfdSJing Huang 7607725ccfdSJing Huang bfa_trc(port->fcs, pwwn); 761f8ceafdeSJing Huang return NULL; 7627725ccfdSJing Huang } 7637725ccfdSJing Huang 7647725ccfdSJing Huang /** 7657725ccfdSJing Huang * NWWN based Lookup for a R-Port in the Port R-Port Queue 7667725ccfdSJing Huang */ 7677725ccfdSJing Huang struct bfa_fcs_rport_s * 768a36c61f9SKrishna Gudipati bfa_fcs_lport_get_rport_by_nwwn(struct bfa_fcs_lport_s *port, wwn_t nwwn) 7697725ccfdSJing Huang { 7707725ccfdSJing Huang struct bfa_fcs_rport_s *rport; 7717725ccfdSJing Huang struct list_head *qe; 7727725ccfdSJing Huang 7737725ccfdSJing Huang list_for_each(qe, &port->rport_q) { 7747725ccfdSJing Huang rport = (struct bfa_fcs_rport_s *) qe; 7757725ccfdSJing Huang if (wwn_is_equal(rport->nwwn, nwwn)) 7767725ccfdSJing Huang return rport; 7777725ccfdSJing Huang } 7787725ccfdSJing Huang 7797725ccfdSJing Huang bfa_trc(port->fcs, nwwn); 780f8ceafdeSJing Huang return NULL; 7817725ccfdSJing Huang } 7827725ccfdSJing Huang 7837725ccfdSJing Huang /** 7847725ccfdSJing Huang * Called by rport module when new rports are discovered. 7857725ccfdSJing Huang */ 7867725ccfdSJing Huang void 787a36c61f9SKrishna Gudipati bfa_fcs_lport_add_rport( 788a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port, 7897725ccfdSJing Huang struct bfa_fcs_rport_s *rport) 7907725ccfdSJing Huang { 7917725ccfdSJing Huang list_add_tail(&rport->qe, &port->rport_q); 7927725ccfdSJing Huang port->num_rports++; 7937725ccfdSJing Huang } 7947725ccfdSJing Huang 7957725ccfdSJing Huang /** 7967725ccfdSJing Huang * Called by rport module to when rports are deleted. 7977725ccfdSJing Huang */ 7987725ccfdSJing Huang void 799a36c61f9SKrishna Gudipati bfa_fcs_lport_del_rport( 800a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port, 8017725ccfdSJing Huang struct bfa_fcs_rport_s *rport) 8027725ccfdSJing Huang { 8037725ccfdSJing Huang bfa_assert(bfa_q_is_on_q(&port->rport_q, rport)); 8047725ccfdSJing Huang list_del(&rport->qe); 8057725ccfdSJing Huang port->num_rports--; 8067725ccfdSJing Huang 8077725ccfdSJing Huang bfa_sm_send_event(port, BFA_FCS_PORT_SM_DELRPORT); 8087725ccfdSJing Huang } 8097725ccfdSJing Huang 8107725ccfdSJing Huang /** 8117725ccfdSJing Huang * Called by fabric for base port when fabric login is complete. 8127725ccfdSJing Huang * Called by vport for virtual ports when FDISC is complete. 8137725ccfdSJing Huang */ 8147725ccfdSJing Huang void 815a36c61f9SKrishna Gudipati bfa_fcs_lport_online(struct bfa_fcs_lport_s *port) 8167725ccfdSJing Huang { 8177725ccfdSJing Huang bfa_sm_send_event(port, BFA_FCS_PORT_SM_ONLINE); 8187725ccfdSJing Huang } 8197725ccfdSJing Huang 8207725ccfdSJing Huang /** 8217725ccfdSJing Huang * Called by fabric for base port when fabric goes offline. 8227725ccfdSJing Huang * Called by vport for virtual ports when virtual port becomes offline. 8237725ccfdSJing Huang */ 8247725ccfdSJing Huang void 825a36c61f9SKrishna Gudipati bfa_fcs_lport_offline(struct bfa_fcs_lport_s *port) 8267725ccfdSJing Huang { 8277725ccfdSJing Huang bfa_sm_send_event(port, BFA_FCS_PORT_SM_OFFLINE); 8287725ccfdSJing Huang } 8297725ccfdSJing Huang 8307725ccfdSJing Huang /** 8317725ccfdSJing Huang * Called by fabric to delete base lport and associated resources. 8327725ccfdSJing Huang * 8337725ccfdSJing Huang * Called by vport to delete lport and associated resources. Should call 8347725ccfdSJing Huang * bfa_fcs_vport_delete_comp() for vports on completion. 8357725ccfdSJing Huang */ 8367725ccfdSJing Huang void 837a36c61f9SKrishna Gudipati bfa_fcs_lport_delete(struct bfa_fcs_lport_s *port) 8387725ccfdSJing Huang { 8397725ccfdSJing Huang bfa_sm_send_event(port, BFA_FCS_PORT_SM_DELETE); 8407725ccfdSJing Huang } 8417725ccfdSJing Huang 8427725ccfdSJing Huang /** 8437725ccfdSJing Huang * Return TRUE if port is online, else return FALSE 8447725ccfdSJing Huang */ 8457725ccfdSJing Huang bfa_boolean_t 846a36c61f9SKrishna Gudipati bfa_fcs_lport_is_online(struct bfa_fcs_lport_s *port) 8477725ccfdSJing Huang { 848a36c61f9SKrishna Gudipati return bfa_sm_cmp_state(port, bfa_fcs_lport_sm_online); 8497725ccfdSJing Huang } 8507725ccfdSJing Huang 8517725ccfdSJing Huang /** 852e6714324SKrishna Gudipati * Attach time initialization of logical ports. 8537725ccfdSJing Huang */ 8547725ccfdSJing Huang void 855a36c61f9SKrishna Gudipati bfa_fcs_lport_attach(struct bfa_fcs_lport_s *lport, struct bfa_fcs_s *fcs, 856a36c61f9SKrishna Gudipati u16 vf_id, struct bfa_fcs_vport_s *vport) 8577725ccfdSJing Huang { 8587725ccfdSJing Huang lport->fcs = fcs; 8597725ccfdSJing Huang lport->fabric = bfa_fcs_vf_lookup(fcs, vf_id); 8607725ccfdSJing Huang lport->vport = vport; 8617725ccfdSJing Huang lport->lp_tag = (vport) ? bfa_lps_get_tag(vport->lps) : 8627725ccfdSJing Huang bfa_lps_get_tag(lport->fabric->lps); 8637725ccfdSJing Huang 8647725ccfdSJing Huang INIT_LIST_HEAD(&lport->rport_q); 8657725ccfdSJing Huang lport->num_rports = 0; 866e6714324SKrishna Gudipati } 8677725ccfdSJing Huang 868e6714324SKrishna Gudipati /** 869e6714324SKrishna Gudipati * Logical port initialization of base or virtual port. 870e6714324SKrishna Gudipati * Called by fabric for base port or by vport for virtual ports. 871e6714324SKrishna Gudipati */ 872e6714324SKrishna Gudipati 873e6714324SKrishna Gudipati void 874a36c61f9SKrishna Gudipati bfa_fcs_lport_init(struct bfa_fcs_lport_s *lport, 875a36c61f9SKrishna Gudipati struct bfa_lport_cfg_s *port_cfg) 876e6714324SKrishna Gudipati { 877e6714324SKrishna Gudipati struct bfa_fcs_vport_s *vport = lport->vport; 878a36c61f9SKrishna Gudipati struct bfad_s *bfad = (struct bfad_s *)lport->fcs->bfad; 879a36c61f9SKrishna Gudipati char lpwwn_buf[BFA_STRING_32]; 880e6714324SKrishna Gudipati 8816a18b167SJing Huang lport->port_cfg = *port_cfg; 882e6714324SKrishna Gudipati 883a36c61f9SKrishna Gudipati lport->bfad_port = bfa_fcb_lport_new(lport->fcs->bfad, lport, 884e6714324SKrishna Gudipati lport->port_cfg.roles, 8857725ccfdSJing Huang lport->fabric->vf_drv, 8867725ccfdSJing Huang vport ? vport->vport_drv : NULL); 887e6714324SKrishna Gudipati 888a36c61f9SKrishna Gudipati wwn2str(lpwwn_buf, bfa_fcs_lport_get_pwwn(lport)); 889a36c61f9SKrishna Gudipati BFA_LOG(KERN_INFO, bfad, log_level, 890a36c61f9SKrishna Gudipati "New logical port created: WWN = %s Role = %s\n", 891a36c61f9SKrishna Gudipati lpwwn_buf, "Initiator"); 8927725ccfdSJing Huang 893a36c61f9SKrishna Gudipati bfa_sm_set_state(lport, bfa_fcs_lport_sm_uninit); 8947725ccfdSJing Huang bfa_sm_send_event(lport, BFA_FCS_PORT_SM_CREATE); 8957725ccfdSJing Huang } 8967725ccfdSJing Huang 8977725ccfdSJing Huang /** 8987725ccfdSJing Huang * fcs_lport_api 8997725ccfdSJing Huang */ 9007725ccfdSJing Huang 9017725ccfdSJing Huang void 902a36c61f9SKrishna Gudipati bfa_fcs_lport_get_attr( 903a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port, 904a36c61f9SKrishna Gudipati struct bfa_lport_attr_s *port_attr) 9057725ccfdSJing Huang { 906a36c61f9SKrishna Gudipati if (bfa_sm_cmp_state(port, bfa_fcs_lport_sm_online)) 9077725ccfdSJing Huang port_attr->pid = port->pid; 9087725ccfdSJing Huang else 9097725ccfdSJing Huang port_attr->pid = 0; 9107725ccfdSJing Huang 9117725ccfdSJing Huang port_attr->port_cfg = port->port_cfg; 9127725ccfdSJing Huang 9137725ccfdSJing Huang if (port->fabric) { 9147725ccfdSJing Huang port_attr->port_type = bfa_fcs_fabric_port_type(port->fabric); 9157725ccfdSJing Huang port_attr->loopback = bfa_fcs_fabric_is_loopback(port->fabric); 916f926a05fSKrishna Gudipati port_attr->authfail = 917f926a05fSKrishna Gudipati bfa_fcs_fabric_is_auth_failed(port->fabric); 918a36c61f9SKrishna Gudipati port_attr->fabric_name = bfa_fcs_lport_get_fabric_name(port); 9197725ccfdSJing Huang memcpy(port_attr->fabric_ip_addr, 920a36c61f9SKrishna Gudipati bfa_fcs_lport_get_fabric_ipaddr(port), 9217725ccfdSJing Huang BFA_FCS_FABRIC_IPADDR_SZ); 9227725ccfdSJing Huang 92386e32dabSKrishna Gudipati if (port->vport != NULL) { 924a36c61f9SKrishna Gudipati port_attr->port_type = BFA_PORT_TYPE_VPORT; 92586e32dabSKrishna Gudipati port_attr->fpma_mac = 92686e32dabSKrishna Gudipati bfa_lps_get_lp_mac(port->vport->lps); 927a36c61f9SKrishna Gudipati } else { 92886e32dabSKrishna Gudipati port_attr->fpma_mac = 92986e32dabSKrishna Gudipati bfa_lps_get_lp_mac(port->fabric->lps); 930a36c61f9SKrishna Gudipati } 931a36c61f9SKrishna Gudipati } else { 932a36c61f9SKrishna Gudipati port_attr->port_type = BFA_PORT_TYPE_UNKNOWN; 933a36c61f9SKrishna Gudipati port_attr->state = BFA_LPORT_UNINIT; 934a36c61f9SKrishna Gudipati } 935a36c61f9SKrishna Gudipati } 936a36c61f9SKrishna Gudipati 937a36c61f9SKrishna Gudipati /** 938a36c61f9SKrishna Gudipati * bfa_fcs_lport_fab port fab functions 939a36c61f9SKrishna Gudipati */ 940a36c61f9SKrishna Gudipati 941a36c61f9SKrishna Gudipati /** 942a36c61f9SKrishna Gudipati * Called by port to initialize fabric services of the base port. 943a36c61f9SKrishna Gudipati */ 944a36c61f9SKrishna Gudipati static void 945a36c61f9SKrishna Gudipati bfa_fcs_lport_fab_init(struct bfa_fcs_lport_s *port) 946a36c61f9SKrishna Gudipati { 947a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_init(port); 948a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_init(port); 949a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_init(port); 950a36c61f9SKrishna Gudipati } 951a36c61f9SKrishna Gudipati 952a36c61f9SKrishna Gudipati /** 953a36c61f9SKrishna Gudipati * Called by port to notify transition to online state. 954a36c61f9SKrishna Gudipati */ 955a36c61f9SKrishna Gudipati static void 956a36c61f9SKrishna Gudipati bfa_fcs_lport_fab_online(struct bfa_fcs_lport_s *port) 957a36c61f9SKrishna Gudipati { 958a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_online(port); 959a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_online(port); 960a36c61f9SKrishna Gudipati } 961a36c61f9SKrishna Gudipati 962a36c61f9SKrishna Gudipati /** 963a36c61f9SKrishna Gudipati * Called by port to notify transition to offline state. 964a36c61f9SKrishna Gudipati */ 965a36c61f9SKrishna Gudipati static void 966a36c61f9SKrishna Gudipati bfa_fcs_lport_fab_offline(struct bfa_fcs_lport_s *port) 967a36c61f9SKrishna Gudipati { 968a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_offline(port); 969a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_offline(port); 970a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_offline(port); 971a36c61f9SKrishna Gudipati } 972a36c61f9SKrishna Gudipati 973a36c61f9SKrishna Gudipati /** 974a36c61f9SKrishna Gudipati * bfa_fcs_lport_n2n functions 975a36c61f9SKrishna Gudipati */ 976a36c61f9SKrishna Gudipati 977a36c61f9SKrishna Gudipati /** 978a36c61f9SKrishna Gudipati * Called by fcs/port to initialize N2N topology. 979a36c61f9SKrishna Gudipati */ 980a36c61f9SKrishna Gudipati static void 981a36c61f9SKrishna Gudipati bfa_fcs_lport_n2n_init(struct bfa_fcs_lport_s *port) 982a36c61f9SKrishna Gudipati { 983a36c61f9SKrishna Gudipati } 984a36c61f9SKrishna Gudipati 985a36c61f9SKrishna Gudipati /** 986a36c61f9SKrishna Gudipati * Called by fcs/port to notify transition to online state. 987a36c61f9SKrishna Gudipati */ 988a36c61f9SKrishna Gudipati static void 989a36c61f9SKrishna Gudipati bfa_fcs_lport_n2n_online(struct bfa_fcs_lport_s *port) 990a36c61f9SKrishna Gudipati { 991a36c61f9SKrishna Gudipati struct bfa_fcs_lport_n2n_s *n2n_port = &port->port_topo.pn2n; 992a36c61f9SKrishna Gudipati struct bfa_lport_cfg_s *pcfg = &port->port_cfg; 993a36c61f9SKrishna Gudipati struct bfa_fcs_rport_s *rport; 994a36c61f9SKrishna Gudipati 995a36c61f9SKrishna Gudipati bfa_trc(port->fcs, pcfg->pwwn); 996a36c61f9SKrishna Gudipati 997a36c61f9SKrishna Gudipati /* 998a36c61f9SKrishna Gudipati * If our PWWN is > than that of the r-port, we have to initiate PLOGI 999a36c61f9SKrishna Gudipati * and assign an Address. if not, we need to wait for its PLOGI. 1000a36c61f9SKrishna Gudipati * 1001a36c61f9SKrishna Gudipati * If our PWWN is < than that of the remote port, it will send a PLOGI 1002a36c61f9SKrishna Gudipati * with the PIDs assigned. The rport state machine take care of this 1003a36c61f9SKrishna Gudipati * incoming PLOGI. 1004a36c61f9SKrishna Gudipati */ 1005a36c61f9SKrishna Gudipati if (memcmp 1006a36c61f9SKrishna Gudipati ((void *)&pcfg->pwwn, (void *)&n2n_port->rem_port_wwn, 1007a36c61f9SKrishna Gudipati sizeof(wwn_t)) > 0) { 1008a36c61f9SKrishna Gudipati port->pid = N2N_LOCAL_PID; 1009a36c61f9SKrishna Gudipati /** 1010a36c61f9SKrishna Gudipati * First, check if we know the device by pwwn. 1011a36c61f9SKrishna Gudipati */ 1012a36c61f9SKrishna Gudipati rport = bfa_fcs_lport_get_rport_by_pwwn(port, 1013a36c61f9SKrishna Gudipati n2n_port->rem_port_wwn); 1014a36c61f9SKrishna Gudipati if (rport) { 1015a36c61f9SKrishna Gudipati bfa_trc(port->fcs, rport->pid); 1016a36c61f9SKrishna Gudipati bfa_trc(port->fcs, rport->pwwn); 1017a36c61f9SKrishna Gudipati rport->pid = N2N_REMOTE_PID; 1018a36c61f9SKrishna Gudipati bfa_fcs_rport_online(rport); 1019a36c61f9SKrishna Gudipati return; 1020a36c61f9SKrishna Gudipati } 1021a36c61f9SKrishna Gudipati 1022a36c61f9SKrishna Gudipati /* 1023a36c61f9SKrishna Gudipati * In n2n there can be only one rport. Delete the old one 1024a36c61f9SKrishna Gudipati * whose pid should be zero, because it is offline. 1025a36c61f9SKrishna Gudipati */ 1026a36c61f9SKrishna Gudipati if (port->num_rports > 0) { 1027a36c61f9SKrishna Gudipati rport = bfa_fcs_lport_get_rport_by_pid(port, 0); 1028a36c61f9SKrishna Gudipati bfa_assert(rport != NULL); 1029a36c61f9SKrishna Gudipati if (rport) { 1030a36c61f9SKrishna Gudipati bfa_trc(port->fcs, rport->pwwn); 1031a36c61f9SKrishna Gudipati bfa_fcs_rport_delete(rport); 1032a36c61f9SKrishna Gudipati } 1033a36c61f9SKrishna Gudipati } 1034a36c61f9SKrishna Gudipati bfa_fcs_rport_create(port, N2N_REMOTE_PID); 1035a36c61f9SKrishna Gudipati } 1036a36c61f9SKrishna Gudipati } 1037a36c61f9SKrishna Gudipati 1038a36c61f9SKrishna Gudipati /** 1039a36c61f9SKrishna Gudipati * Called by fcs/port to notify transition to offline state. 1040a36c61f9SKrishna Gudipati */ 1041a36c61f9SKrishna Gudipati static void 1042a36c61f9SKrishna Gudipati bfa_fcs_lport_n2n_offline(struct bfa_fcs_lport_s *port) 1043a36c61f9SKrishna Gudipati { 1044a36c61f9SKrishna Gudipati struct bfa_fcs_lport_n2n_s *n2n_port = &port->port_topo.pn2n; 1045a36c61f9SKrishna Gudipati 1046a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->pid); 1047a36c61f9SKrishna Gudipati port->pid = 0; 1048a36c61f9SKrishna Gudipati n2n_port->rem_port_wwn = 0; 1049a36c61f9SKrishna Gudipati n2n_port->reply_oxid = 0; 1050a36c61f9SKrishna Gudipati } 1051a36c61f9SKrishna Gudipati 1052a36c61f9SKrishna Gudipati #define BFA_FCS_FDMI_CMD_MAX_RETRIES 2 1053a36c61f9SKrishna Gudipati 1054a36c61f9SKrishna Gudipati /* 1055a36c61f9SKrishna Gudipati * forward declarations 1056a36c61f9SKrishna Gudipati */ 1057a36c61f9SKrishna Gudipati static void bfa_fcs_lport_fdmi_send_rhba(void *fdmi_cbarg, 1058a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp_alloced); 1059a36c61f9SKrishna Gudipati static void bfa_fcs_lport_fdmi_send_rprt(void *fdmi_cbarg, 1060a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp_alloced); 1061a36c61f9SKrishna Gudipati static void bfa_fcs_lport_fdmi_send_rpa(void *fdmi_cbarg, 1062a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp_alloced); 1063a36c61f9SKrishna Gudipati static void bfa_fcs_lport_fdmi_rhba_response(void *fcsarg, 1064a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp, 1065a36c61f9SKrishna Gudipati void *cbarg, 1066a36c61f9SKrishna Gudipati bfa_status_t req_status, 1067a36c61f9SKrishna Gudipati u32 rsp_len, 1068a36c61f9SKrishna Gudipati u32 resid_len, 1069a36c61f9SKrishna Gudipati struct fchs_s *rsp_fchs); 1070a36c61f9SKrishna Gudipati static void bfa_fcs_lport_fdmi_rprt_response(void *fcsarg, 1071a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp, 1072a36c61f9SKrishna Gudipati void *cbarg, 1073a36c61f9SKrishna Gudipati bfa_status_t req_status, 1074a36c61f9SKrishna Gudipati u32 rsp_len, 1075a36c61f9SKrishna Gudipati u32 resid_len, 1076a36c61f9SKrishna Gudipati struct fchs_s *rsp_fchs); 1077a36c61f9SKrishna Gudipati static void bfa_fcs_lport_fdmi_rpa_response(void *fcsarg, 1078a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp, 1079a36c61f9SKrishna Gudipati void *cbarg, 1080a36c61f9SKrishna Gudipati bfa_status_t req_status, 1081a36c61f9SKrishna Gudipati u32 rsp_len, 1082a36c61f9SKrishna Gudipati u32 resid_len, 1083a36c61f9SKrishna Gudipati struct fchs_s *rsp_fchs); 1084a36c61f9SKrishna Gudipati static void bfa_fcs_lport_fdmi_timeout(void *arg); 1085a36c61f9SKrishna Gudipati static u16 bfa_fcs_lport_fdmi_build_rhba_pyld(struct bfa_fcs_lport_fdmi_s *fdmi, 1086a36c61f9SKrishna Gudipati u8 *pyld); 1087a36c61f9SKrishna Gudipati static u16 bfa_fcs_lport_fdmi_build_rprt_pyld(struct bfa_fcs_lport_fdmi_s *fdmi, 1088a36c61f9SKrishna Gudipati u8 *pyld); 1089a36c61f9SKrishna Gudipati static u16 bfa_fcs_lport_fdmi_build_rpa_pyld(struct bfa_fcs_lport_fdmi_s *fdmi, 1090a36c61f9SKrishna Gudipati u8 *pyld); 1091a36c61f9SKrishna Gudipati static u16 bfa_fcs_lport_fdmi_build_portattr_block(struct bfa_fcs_lport_fdmi_s * 1092a36c61f9SKrishna Gudipati fdmi, u8 *pyld); 1093a36c61f9SKrishna Gudipati static void bfa_fcs_fdmi_get_hbaattr(struct bfa_fcs_lport_fdmi_s *fdmi, 1094a36c61f9SKrishna Gudipati struct bfa_fcs_fdmi_hba_attr_s *hba_attr); 1095a36c61f9SKrishna Gudipati static void bfa_fcs_fdmi_get_portattr(struct bfa_fcs_lport_fdmi_s *fdmi, 1096a36c61f9SKrishna Gudipati struct bfa_fcs_fdmi_port_attr_s *port_attr); 1097a36c61f9SKrishna Gudipati /** 1098a36c61f9SKrishna Gudipati * fcs_fdmi_sm FCS FDMI state machine 1099a36c61f9SKrishna Gudipati */ 1100a36c61f9SKrishna Gudipati 1101a36c61f9SKrishna Gudipati /** 1102a36c61f9SKrishna Gudipati * FDMI State Machine events 1103a36c61f9SKrishna Gudipati */ 1104a36c61f9SKrishna Gudipati enum port_fdmi_event { 1105a36c61f9SKrishna Gudipati FDMISM_EVENT_PORT_ONLINE = 1, 1106a36c61f9SKrishna Gudipati FDMISM_EVENT_PORT_OFFLINE = 2, 1107a36c61f9SKrishna Gudipati FDMISM_EVENT_RSP_OK = 4, 1108a36c61f9SKrishna Gudipati FDMISM_EVENT_RSP_ERROR = 5, 1109a36c61f9SKrishna Gudipati FDMISM_EVENT_TIMEOUT = 6, 1110a36c61f9SKrishna Gudipati FDMISM_EVENT_RHBA_SENT = 7, 1111a36c61f9SKrishna Gudipati FDMISM_EVENT_RPRT_SENT = 8, 1112a36c61f9SKrishna Gudipati FDMISM_EVENT_RPA_SENT = 9, 1113a36c61f9SKrishna Gudipati }; 1114a36c61f9SKrishna Gudipati 1115a36c61f9SKrishna Gudipati static void bfa_fcs_lport_fdmi_sm_offline(struct bfa_fcs_lport_fdmi_s *fdmi, 1116a36c61f9SKrishna Gudipati enum port_fdmi_event event); 1117a36c61f9SKrishna Gudipati static void bfa_fcs_lport_fdmi_sm_sending_rhba( 1118a36c61f9SKrishna Gudipati struct bfa_fcs_lport_fdmi_s *fdmi, 1119a36c61f9SKrishna Gudipati enum port_fdmi_event event); 1120a36c61f9SKrishna Gudipati static void bfa_fcs_lport_fdmi_sm_rhba(struct bfa_fcs_lport_fdmi_s *fdmi, 1121a36c61f9SKrishna Gudipati enum port_fdmi_event event); 1122a36c61f9SKrishna Gudipati static void bfa_fcs_lport_fdmi_sm_rhba_retry( 1123a36c61f9SKrishna Gudipati struct bfa_fcs_lport_fdmi_s *fdmi, 1124a36c61f9SKrishna Gudipati enum port_fdmi_event event); 1125a36c61f9SKrishna Gudipati static void bfa_fcs_lport_fdmi_sm_sending_rprt( 1126a36c61f9SKrishna Gudipati struct bfa_fcs_lport_fdmi_s *fdmi, 1127a36c61f9SKrishna Gudipati enum port_fdmi_event event); 1128a36c61f9SKrishna Gudipati static void bfa_fcs_lport_fdmi_sm_rprt(struct bfa_fcs_lport_fdmi_s *fdmi, 1129a36c61f9SKrishna Gudipati enum port_fdmi_event event); 1130a36c61f9SKrishna Gudipati static void bfa_fcs_lport_fdmi_sm_rprt_retry( 1131a36c61f9SKrishna Gudipati struct bfa_fcs_lport_fdmi_s *fdmi, 1132a36c61f9SKrishna Gudipati enum port_fdmi_event event); 1133a36c61f9SKrishna Gudipati static void bfa_fcs_lport_fdmi_sm_sending_rpa( 1134a36c61f9SKrishna Gudipati struct bfa_fcs_lport_fdmi_s *fdmi, 1135a36c61f9SKrishna Gudipati enum port_fdmi_event event); 1136a36c61f9SKrishna Gudipati static void bfa_fcs_lport_fdmi_sm_rpa(struct bfa_fcs_lport_fdmi_s *fdmi, 1137a36c61f9SKrishna Gudipati enum port_fdmi_event event); 1138a36c61f9SKrishna Gudipati static void bfa_fcs_lport_fdmi_sm_rpa_retry( 1139a36c61f9SKrishna Gudipati struct bfa_fcs_lport_fdmi_s *fdmi, 1140a36c61f9SKrishna Gudipati enum port_fdmi_event event); 1141a36c61f9SKrishna Gudipati static void bfa_fcs_lport_fdmi_sm_online(struct bfa_fcs_lport_fdmi_s *fdmi, 1142a36c61f9SKrishna Gudipati enum port_fdmi_event event); 1143a36c61f9SKrishna Gudipati static void bfa_fcs_lport_fdmi_sm_disabled( 1144a36c61f9SKrishna Gudipati struct bfa_fcs_lport_fdmi_s *fdmi, 1145a36c61f9SKrishna Gudipati enum port_fdmi_event event); 1146a36c61f9SKrishna Gudipati /** 1147a36c61f9SKrishna Gudipati * Start in offline state - awaiting MS to send start. 1148a36c61f9SKrishna Gudipati */ 1149a36c61f9SKrishna Gudipati static void 1150a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_sm_offline(struct bfa_fcs_lport_fdmi_s *fdmi, 1151a36c61f9SKrishna Gudipati enum port_fdmi_event event) 1152a36c61f9SKrishna Gudipati { 1153a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = fdmi->ms->port; 1154a36c61f9SKrishna Gudipati 1155a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 1156a36c61f9SKrishna Gudipati bfa_trc(port->fcs, event); 1157a36c61f9SKrishna Gudipati 1158a36c61f9SKrishna Gudipati fdmi->retry_cnt = 0; 1159a36c61f9SKrishna Gudipati 1160a36c61f9SKrishna Gudipati switch (event) { 1161a36c61f9SKrishna Gudipati case FDMISM_EVENT_PORT_ONLINE: 1162a36c61f9SKrishna Gudipati if (port->vport) { 1163a36c61f9SKrishna Gudipati /* 1164a36c61f9SKrishna Gudipati * For Vports, register a new port. 1165a36c61f9SKrishna Gudipati */ 1166a36c61f9SKrishna Gudipati bfa_sm_set_state(fdmi, 1167a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_sm_sending_rprt); 1168a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_send_rprt(fdmi, NULL); 1169a36c61f9SKrishna Gudipati } else { 1170a36c61f9SKrishna Gudipati /* 1171a36c61f9SKrishna Gudipati * For a base port, we should first register the HBA 1172a36c61f9SKrishna Gudipati * atribute. The HBA attribute also contains the base 1173a36c61f9SKrishna Gudipati * port registration. 1174a36c61f9SKrishna Gudipati */ 1175a36c61f9SKrishna Gudipati bfa_sm_set_state(fdmi, 1176a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_sm_sending_rhba); 1177a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_send_rhba(fdmi, NULL); 1178a36c61f9SKrishna Gudipati } 1179a36c61f9SKrishna Gudipati break; 1180a36c61f9SKrishna Gudipati 1181a36c61f9SKrishna Gudipati case FDMISM_EVENT_PORT_OFFLINE: 1182a36c61f9SKrishna Gudipati break; 1183a36c61f9SKrishna Gudipati 1184a36c61f9SKrishna Gudipati default: 1185a36c61f9SKrishna Gudipati bfa_sm_fault(port->fcs, event); 1186a36c61f9SKrishna Gudipati } 1187a36c61f9SKrishna Gudipati } 1188a36c61f9SKrishna Gudipati 1189a36c61f9SKrishna Gudipati static void 1190a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_sm_sending_rhba(struct bfa_fcs_lport_fdmi_s *fdmi, 1191a36c61f9SKrishna Gudipati enum port_fdmi_event event) 1192a36c61f9SKrishna Gudipati { 1193a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = fdmi->ms->port; 1194a36c61f9SKrishna Gudipati 1195a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 1196a36c61f9SKrishna Gudipati bfa_trc(port->fcs, event); 1197a36c61f9SKrishna Gudipati 1198a36c61f9SKrishna Gudipati switch (event) { 1199a36c61f9SKrishna Gudipati case FDMISM_EVENT_RHBA_SENT: 1200a36c61f9SKrishna Gudipati bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_rhba); 1201a36c61f9SKrishna Gudipati break; 1202a36c61f9SKrishna Gudipati 1203a36c61f9SKrishna Gudipati case FDMISM_EVENT_PORT_OFFLINE: 1204a36c61f9SKrishna Gudipati bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline); 1205a36c61f9SKrishna Gudipati bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(port), 1206a36c61f9SKrishna Gudipati &fdmi->fcxp_wqe); 1207a36c61f9SKrishna Gudipati break; 1208a36c61f9SKrishna Gudipati 1209a36c61f9SKrishna Gudipati default: 1210a36c61f9SKrishna Gudipati bfa_sm_fault(port->fcs, event); 1211a36c61f9SKrishna Gudipati } 1212a36c61f9SKrishna Gudipati } 1213a36c61f9SKrishna Gudipati 1214a36c61f9SKrishna Gudipati static void 1215a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_sm_rhba(struct bfa_fcs_lport_fdmi_s *fdmi, 1216a36c61f9SKrishna Gudipati enum port_fdmi_event event) 1217a36c61f9SKrishna Gudipati { 1218a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = fdmi->ms->port; 1219a36c61f9SKrishna Gudipati 1220a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 1221a36c61f9SKrishna Gudipati bfa_trc(port->fcs, event); 1222a36c61f9SKrishna Gudipati 1223a36c61f9SKrishna Gudipati switch (event) { 1224a36c61f9SKrishna Gudipati case FDMISM_EVENT_RSP_ERROR: 1225a36c61f9SKrishna Gudipati /* 1226a36c61f9SKrishna Gudipati * if max retries have not been reached, start timer for a 1227a36c61f9SKrishna Gudipati * delayed retry 1228a36c61f9SKrishna Gudipati */ 1229a36c61f9SKrishna Gudipati if (fdmi->retry_cnt++ < BFA_FCS_FDMI_CMD_MAX_RETRIES) { 1230a36c61f9SKrishna Gudipati bfa_sm_set_state(fdmi, 1231a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_sm_rhba_retry); 1232a36c61f9SKrishna Gudipati bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(port), 1233a36c61f9SKrishna Gudipati &fdmi->timer, 1234a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_timeout, fdmi, 1235a36c61f9SKrishna Gudipati BFA_FCS_RETRY_TIMEOUT); 1236a36c61f9SKrishna Gudipati } else { 1237a36c61f9SKrishna Gudipati /* 1238a36c61f9SKrishna Gudipati * set state to offline 1239a36c61f9SKrishna Gudipati */ 1240a36c61f9SKrishna Gudipati bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline); 1241a36c61f9SKrishna Gudipati } 1242a36c61f9SKrishna Gudipati break; 1243a36c61f9SKrishna Gudipati 1244a36c61f9SKrishna Gudipati case FDMISM_EVENT_RSP_OK: 1245a36c61f9SKrishna Gudipati /* 1246a36c61f9SKrishna Gudipati * Initiate Register Port Attributes 1247a36c61f9SKrishna Gudipati */ 1248a36c61f9SKrishna Gudipati bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_sending_rpa); 1249a36c61f9SKrishna Gudipati fdmi->retry_cnt = 0; 1250a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_send_rpa(fdmi, NULL); 1251a36c61f9SKrishna Gudipati break; 1252a36c61f9SKrishna Gudipati 1253a36c61f9SKrishna Gudipati case FDMISM_EVENT_PORT_OFFLINE: 1254a36c61f9SKrishna Gudipati bfa_fcxp_discard(fdmi->fcxp); 1255a36c61f9SKrishna Gudipati bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline); 1256a36c61f9SKrishna Gudipati break; 1257a36c61f9SKrishna Gudipati 1258a36c61f9SKrishna Gudipati default: 1259a36c61f9SKrishna Gudipati bfa_sm_fault(port->fcs, event); 1260a36c61f9SKrishna Gudipati } 1261a36c61f9SKrishna Gudipati } 1262a36c61f9SKrishna Gudipati 1263a36c61f9SKrishna Gudipati static void 1264a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_sm_rhba_retry(struct bfa_fcs_lport_fdmi_s *fdmi, 1265a36c61f9SKrishna Gudipati enum port_fdmi_event event) 1266a36c61f9SKrishna Gudipati { 1267a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = fdmi->ms->port; 1268a36c61f9SKrishna Gudipati 1269a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 1270a36c61f9SKrishna Gudipati bfa_trc(port->fcs, event); 1271a36c61f9SKrishna Gudipati 1272a36c61f9SKrishna Gudipati switch (event) { 1273a36c61f9SKrishna Gudipati case FDMISM_EVENT_TIMEOUT: 1274a36c61f9SKrishna Gudipati /* 1275a36c61f9SKrishna Gudipati * Retry Timer Expired. Re-send 1276a36c61f9SKrishna Gudipati */ 1277a36c61f9SKrishna Gudipati bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_sending_rhba); 1278a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_send_rhba(fdmi, NULL); 1279a36c61f9SKrishna Gudipati break; 1280a36c61f9SKrishna Gudipati 1281a36c61f9SKrishna Gudipati case FDMISM_EVENT_PORT_OFFLINE: 1282a36c61f9SKrishna Gudipati bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline); 1283a36c61f9SKrishna Gudipati bfa_timer_stop(&fdmi->timer); 1284a36c61f9SKrishna Gudipati break; 1285a36c61f9SKrishna Gudipati 1286a36c61f9SKrishna Gudipati default: 1287a36c61f9SKrishna Gudipati bfa_sm_fault(port->fcs, event); 1288a36c61f9SKrishna Gudipati } 1289a36c61f9SKrishna Gudipati } 1290a36c61f9SKrishna Gudipati 1291a36c61f9SKrishna Gudipati /* 1292a36c61f9SKrishna Gudipati * RPRT : Register Port 1293a36c61f9SKrishna Gudipati */ 1294a36c61f9SKrishna Gudipati static void 1295a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_sm_sending_rprt(struct bfa_fcs_lport_fdmi_s *fdmi, 1296a36c61f9SKrishna Gudipati enum port_fdmi_event event) 1297a36c61f9SKrishna Gudipati { 1298a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = fdmi->ms->port; 1299a36c61f9SKrishna Gudipati 1300a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 1301a36c61f9SKrishna Gudipati bfa_trc(port->fcs, event); 1302a36c61f9SKrishna Gudipati 1303a36c61f9SKrishna Gudipati switch (event) { 1304a36c61f9SKrishna Gudipati case FDMISM_EVENT_RPRT_SENT: 1305a36c61f9SKrishna Gudipati bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_rprt); 1306a36c61f9SKrishna Gudipati break; 1307a36c61f9SKrishna Gudipati 1308a36c61f9SKrishna Gudipati case FDMISM_EVENT_PORT_OFFLINE: 1309a36c61f9SKrishna Gudipati bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline); 1310a36c61f9SKrishna Gudipati bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(port), 1311a36c61f9SKrishna Gudipati &fdmi->fcxp_wqe); 1312a36c61f9SKrishna Gudipati break; 1313a36c61f9SKrishna Gudipati 1314a36c61f9SKrishna Gudipati default: 1315a36c61f9SKrishna Gudipati bfa_sm_fault(port->fcs, event); 1316a36c61f9SKrishna Gudipati } 1317a36c61f9SKrishna Gudipati } 1318a36c61f9SKrishna Gudipati 1319a36c61f9SKrishna Gudipati static void 1320a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_sm_rprt(struct bfa_fcs_lport_fdmi_s *fdmi, 1321a36c61f9SKrishna Gudipati enum port_fdmi_event event) 1322a36c61f9SKrishna Gudipati { 1323a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = fdmi->ms->port; 1324a36c61f9SKrishna Gudipati 1325a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 1326a36c61f9SKrishna Gudipati bfa_trc(port->fcs, event); 1327a36c61f9SKrishna Gudipati 1328a36c61f9SKrishna Gudipati switch (event) { 1329a36c61f9SKrishna Gudipati case FDMISM_EVENT_RSP_ERROR: 1330a36c61f9SKrishna Gudipati /* 1331a36c61f9SKrishna Gudipati * if max retries have not been reached, start timer for a 1332a36c61f9SKrishna Gudipati * delayed retry 1333a36c61f9SKrishna Gudipati */ 1334a36c61f9SKrishna Gudipati if (fdmi->retry_cnt++ < BFA_FCS_FDMI_CMD_MAX_RETRIES) { 1335a36c61f9SKrishna Gudipati bfa_sm_set_state(fdmi, 1336a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_sm_rprt_retry); 1337a36c61f9SKrishna Gudipati bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(port), 1338a36c61f9SKrishna Gudipati &fdmi->timer, 1339a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_timeout, fdmi, 1340a36c61f9SKrishna Gudipati BFA_FCS_RETRY_TIMEOUT); 13417725ccfdSJing Huang 13427725ccfdSJing Huang } else { 1343a36c61f9SKrishna Gudipati /* 1344a36c61f9SKrishna Gudipati * set state to offline 1345a36c61f9SKrishna Gudipati */ 1346a36c61f9SKrishna Gudipati bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline); 1347a36c61f9SKrishna Gudipati fdmi->retry_cnt = 0; 13487725ccfdSJing Huang } 1349a36c61f9SKrishna Gudipati break; 1350a36c61f9SKrishna Gudipati 1351a36c61f9SKrishna Gudipati case FDMISM_EVENT_RSP_OK: 1352a36c61f9SKrishna Gudipati fdmi->retry_cnt = 0; 1353a36c61f9SKrishna Gudipati bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_online); 1354a36c61f9SKrishna Gudipati break; 1355a36c61f9SKrishna Gudipati 1356a36c61f9SKrishna Gudipati case FDMISM_EVENT_PORT_OFFLINE: 1357a36c61f9SKrishna Gudipati bfa_fcxp_discard(fdmi->fcxp); 1358a36c61f9SKrishna Gudipati bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline); 1359a36c61f9SKrishna Gudipati break; 1360a36c61f9SKrishna Gudipati 1361a36c61f9SKrishna Gudipati default: 1362a36c61f9SKrishna Gudipati bfa_sm_fault(port->fcs, event); 1363a36c61f9SKrishna Gudipati } 1364a36c61f9SKrishna Gudipati } 1365a36c61f9SKrishna Gudipati 1366a36c61f9SKrishna Gudipati static void 1367a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_sm_rprt_retry(struct bfa_fcs_lport_fdmi_s *fdmi, 1368a36c61f9SKrishna Gudipati enum port_fdmi_event event) 1369a36c61f9SKrishna Gudipati { 1370a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = fdmi->ms->port; 1371a36c61f9SKrishna Gudipati 1372a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 1373a36c61f9SKrishna Gudipati bfa_trc(port->fcs, event); 1374a36c61f9SKrishna Gudipati 1375a36c61f9SKrishna Gudipati switch (event) { 1376a36c61f9SKrishna Gudipati case FDMISM_EVENT_TIMEOUT: 1377a36c61f9SKrishna Gudipati /* 1378a36c61f9SKrishna Gudipati * Retry Timer Expired. Re-send 1379a36c61f9SKrishna Gudipati */ 1380a36c61f9SKrishna Gudipati bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_sending_rprt); 1381a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_send_rprt(fdmi, NULL); 1382a36c61f9SKrishna Gudipati break; 1383a36c61f9SKrishna Gudipati 1384a36c61f9SKrishna Gudipati case FDMISM_EVENT_PORT_OFFLINE: 1385a36c61f9SKrishna Gudipati bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline); 1386a36c61f9SKrishna Gudipati bfa_timer_stop(&fdmi->timer); 1387a36c61f9SKrishna Gudipati break; 1388a36c61f9SKrishna Gudipati 1389a36c61f9SKrishna Gudipati default: 1390a36c61f9SKrishna Gudipati bfa_sm_fault(port->fcs, event); 1391a36c61f9SKrishna Gudipati } 1392a36c61f9SKrishna Gudipati } 1393a36c61f9SKrishna Gudipati 1394a36c61f9SKrishna Gudipati /* 1395a36c61f9SKrishna Gudipati * Register Port Attributes 1396a36c61f9SKrishna Gudipati */ 1397a36c61f9SKrishna Gudipati static void 1398a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_sm_sending_rpa(struct bfa_fcs_lport_fdmi_s *fdmi, 1399a36c61f9SKrishna Gudipati enum port_fdmi_event event) 1400a36c61f9SKrishna Gudipati { 1401a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = fdmi->ms->port; 1402a36c61f9SKrishna Gudipati 1403a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 1404a36c61f9SKrishna Gudipati bfa_trc(port->fcs, event); 1405a36c61f9SKrishna Gudipati 1406a36c61f9SKrishna Gudipati switch (event) { 1407a36c61f9SKrishna Gudipati case FDMISM_EVENT_RPA_SENT: 1408a36c61f9SKrishna Gudipati bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_rpa); 1409a36c61f9SKrishna Gudipati break; 1410a36c61f9SKrishna Gudipati 1411a36c61f9SKrishna Gudipati case FDMISM_EVENT_PORT_OFFLINE: 1412a36c61f9SKrishna Gudipati bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline); 1413a36c61f9SKrishna Gudipati bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(port), 1414a36c61f9SKrishna Gudipati &fdmi->fcxp_wqe); 1415a36c61f9SKrishna Gudipati break; 1416a36c61f9SKrishna Gudipati 1417a36c61f9SKrishna Gudipati default: 1418a36c61f9SKrishna Gudipati bfa_sm_fault(port->fcs, event); 1419a36c61f9SKrishna Gudipati } 1420a36c61f9SKrishna Gudipati } 1421a36c61f9SKrishna Gudipati 1422a36c61f9SKrishna Gudipati static void 1423a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_sm_rpa(struct bfa_fcs_lport_fdmi_s *fdmi, 1424a36c61f9SKrishna Gudipati enum port_fdmi_event event) 1425a36c61f9SKrishna Gudipati { 1426a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = fdmi->ms->port; 1427a36c61f9SKrishna Gudipati 1428a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 1429a36c61f9SKrishna Gudipati bfa_trc(port->fcs, event); 1430a36c61f9SKrishna Gudipati 1431a36c61f9SKrishna Gudipati switch (event) { 1432a36c61f9SKrishna Gudipati case FDMISM_EVENT_RSP_ERROR: 1433a36c61f9SKrishna Gudipati /* 1434a36c61f9SKrishna Gudipati * if max retries have not been reached, start timer for a 1435a36c61f9SKrishna Gudipati * delayed retry 1436a36c61f9SKrishna Gudipati */ 1437a36c61f9SKrishna Gudipati if (fdmi->retry_cnt++ < BFA_FCS_FDMI_CMD_MAX_RETRIES) { 1438a36c61f9SKrishna Gudipati bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_rpa_retry); 1439a36c61f9SKrishna Gudipati bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(port), 1440a36c61f9SKrishna Gudipati &fdmi->timer, 1441a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_timeout, fdmi, 1442a36c61f9SKrishna Gudipati BFA_FCS_RETRY_TIMEOUT); 1443a36c61f9SKrishna Gudipati } else { 1444a36c61f9SKrishna Gudipati /* 1445a36c61f9SKrishna Gudipati * set state to offline 1446a36c61f9SKrishna Gudipati */ 1447a36c61f9SKrishna Gudipati bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline); 1448a36c61f9SKrishna Gudipati fdmi->retry_cnt = 0; 1449a36c61f9SKrishna Gudipati } 1450a36c61f9SKrishna Gudipati break; 1451a36c61f9SKrishna Gudipati 1452a36c61f9SKrishna Gudipati case FDMISM_EVENT_RSP_OK: 1453a36c61f9SKrishna Gudipati bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_online); 1454a36c61f9SKrishna Gudipati fdmi->retry_cnt = 0; 1455a36c61f9SKrishna Gudipati break; 1456a36c61f9SKrishna Gudipati 1457a36c61f9SKrishna Gudipati case FDMISM_EVENT_PORT_OFFLINE: 1458a36c61f9SKrishna Gudipati bfa_fcxp_discard(fdmi->fcxp); 1459a36c61f9SKrishna Gudipati bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline); 1460a36c61f9SKrishna Gudipati break; 1461a36c61f9SKrishna Gudipati 1462a36c61f9SKrishna Gudipati default: 1463a36c61f9SKrishna Gudipati bfa_sm_fault(port->fcs, event); 1464a36c61f9SKrishna Gudipati } 1465a36c61f9SKrishna Gudipati } 1466a36c61f9SKrishna Gudipati 1467a36c61f9SKrishna Gudipati static void 1468a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_sm_rpa_retry(struct bfa_fcs_lport_fdmi_s *fdmi, 1469a36c61f9SKrishna Gudipati enum port_fdmi_event event) 1470a36c61f9SKrishna Gudipati { 1471a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = fdmi->ms->port; 1472a36c61f9SKrishna Gudipati 1473a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 1474a36c61f9SKrishna Gudipati bfa_trc(port->fcs, event); 1475a36c61f9SKrishna Gudipati 1476a36c61f9SKrishna Gudipati switch (event) { 1477a36c61f9SKrishna Gudipati case FDMISM_EVENT_TIMEOUT: 1478a36c61f9SKrishna Gudipati /* 1479a36c61f9SKrishna Gudipati * Retry Timer Expired. Re-send 1480a36c61f9SKrishna Gudipati */ 1481a36c61f9SKrishna Gudipati bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_sending_rpa); 1482a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_send_rpa(fdmi, NULL); 1483a36c61f9SKrishna Gudipati break; 1484a36c61f9SKrishna Gudipati 1485a36c61f9SKrishna Gudipati case FDMISM_EVENT_PORT_OFFLINE: 1486a36c61f9SKrishna Gudipati bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline); 1487a36c61f9SKrishna Gudipati bfa_timer_stop(&fdmi->timer); 1488a36c61f9SKrishna Gudipati break; 1489a36c61f9SKrishna Gudipati 1490a36c61f9SKrishna Gudipati default: 1491a36c61f9SKrishna Gudipati bfa_sm_fault(port->fcs, event); 1492a36c61f9SKrishna Gudipati } 1493a36c61f9SKrishna Gudipati } 1494a36c61f9SKrishna Gudipati 1495a36c61f9SKrishna Gudipati static void 1496a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_sm_online(struct bfa_fcs_lport_fdmi_s *fdmi, 1497a36c61f9SKrishna Gudipati enum port_fdmi_event event) 1498a36c61f9SKrishna Gudipati { 1499a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = fdmi->ms->port; 1500a36c61f9SKrishna Gudipati 1501a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 1502a36c61f9SKrishna Gudipati bfa_trc(port->fcs, event); 1503a36c61f9SKrishna Gudipati 1504a36c61f9SKrishna Gudipati switch (event) { 1505a36c61f9SKrishna Gudipati case FDMISM_EVENT_PORT_OFFLINE: 1506a36c61f9SKrishna Gudipati bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline); 1507a36c61f9SKrishna Gudipati break; 1508a36c61f9SKrishna Gudipati 1509a36c61f9SKrishna Gudipati default: 1510a36c61f9SKrishna Gudipati bfa_sm_fault(port->fcs, event); 1511a36c61f9SKrishna Gudipati } 1512a36c61f9SKrishna Gudipati } 1513a36c61f9SKrishna Gudipati /** 1514a36c61f9SKrishna Gudipati * FDMI is disabled state. 1515a36c61f9SKrishna Gudipati */ 1516a36c61f9SKrishna Gudipati static void 1517a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_sm_disabled(struct bfa_fcs_lport_fdmi_s *fdmi, 1518a36c61f9SKrishna Gudipati enum port_fdmi_event event) 1519a36c61f9SKrishna Gudipati { 1520a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = fdmi->ms->port; 1521a36c61f9SKrishna Gudipati 1522a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 1523a36c61f9SKrishna Gudipati bfa_trc(port->fcs, event); 1524a36c61f9SKrishna Gudipati 1525a36c61f9SKrishna Gudipati /* No op State. It can only be enabled at Driver Init. */ 1526a36c61f9SKrishna Gudipati } 1527a36c61f9SKrishna Gudipati 1528a36c61f9SKrishna Gudipati /** 1529a36c61f9SKrishna Gudipati * RHBA : Register HBA Attributes. 1530a36c61f9SKrishna Gudipati */ 1531a36c61f9SKrishna Gudipati static void 1532a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_send_rhba(void *fdmi_cbarg, struct bfa_fcxp_s *fcxp_alloced) 1533a36c61f9SKrishna Gudipati { 1534a36c61f9SKrishna Gudipati struct bfa_fcs_lport_fdmi_s *fdmi = fdmi_cbarg; 1535a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = fdmi->ms->port; 1536a36c61f9SKrishna Gudipati struct fchs_s fchs; 1537a36c61f9SKrishna Gudipati int len, attr_len; 1538a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp; 1539a36c61f9SKrishna Gudipati u8 *pyld; 1540a36c61f9SKrishna Gudipati 1541a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 1542a36c61f9SKrishna Gudipati 1543a36c61f9SKrishna Gudipati fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs); 1544a36c61f9SKrishna Gudipati if (!fcxp) { 1545a36c61f9SKrishna Gudipati bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &fdmi->fcxp_wqe, 1546a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_send_rhba, fdmi); 1547a36c61f9SKrishna Gudipati return; 1548a36c61f9SKrishna Gudipati } 1549a36c61f9SKrishna Gudipati fdmi->fcxp = fcxp; 1550a36c61f9SKrishna Gudipati 1551a36c61f9SKrishna Gudipati pyld = bfa_fcxp_get_reqbuf(fcxp); 15526a18b167SJing Huang memset(pyld, 0, FC_MAX_PDUSZ); 1553a36c61f9SKrishna Gudipati 1554a36c61f9SKrishna Gudipati len = fc_fdmi_reqhdr_build(&fchs, pyld, bfa_fcs_lport_get_fcid(port), 1555a36c61f9SKrishna Gudipati FDMI_RHBA); 1556a36c61f9SKrishna Gudipati 1557a36c61f9SKrishna Gudipati attr_len = 1558a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_build_rhba_pyld(fdmi, 1559a36c61f9SKrishna Gudipati (u8 *) ((struct ct_hdr_s *) pyld 1560a36c61f9SKrishna Gudipati + 1)); 1561a36c61f9SKrishna Gudipati 1562a36c61f9SKrishna Gudipati bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, 1563a36c61f9SKrishna Gudipati FC_CLASS_3, (len + attr_len), &fchs, 1564a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_rhba_response, (void *)fdmi, 1565a36c61f9SKrishna Gudipati FC_MAX_PDUSZ, FC_FCCT_TOV); 1566a36c61f9SKrishna Gudipati 1567a36c61f9SKrishna Gudipati bfa_sm_send_event(fdmi, FDMISM_EVENT_RHBA_SENT); 1568a36c61f9SKrishna Gudipati } 1569a36c61f9SKrishna Gudipati 1570a36c61f9SKrishna Gudipati static u16 1571a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_build_rhba_pyld(struct bfa_fcs_lport_fdmi_s *fdmi, u8 *pyld) 1572a36c61f9SKrishna Gudipati { 1573a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = fdmi->ms->port; 1574a36c61f9SKrishna Gudipati struct bfa_fcs_fdmi_hba_attr_s hba_attr; 1575a36c61f9SKrishna Gudipati struct bfa_fcs_fdmi_hba_attr_s *fcs_hba_attr = &hba_attr; 1576a36c61f9SKrishna Gudipati struct fdmi_rhba_s *rhba = (struct fdmi_rhba_s *) pyld; 1577a36c61f9SKrishna Gudipati struct fdmi_attr_s *attr; 1578a36c61f9SKrishna Gudipati u8 *curr_ptr; 1579a36c61f9SKrishna Gudipati u16 len, count; 1580a36c61f9SKrishna Gudipati 1581a36c61f9SKrishna Gudipati /* 1582a36c61f9SKrishna Gudipati * get hba attributes 1583a36c61f9SKrishna Gudipati */ 1584a36c61f9SKrishna Gudipati bfa_fcs_fdmi_get_hbaattr(fdmi, fcs_hba_attr); 1585a36c61f9SKrishna Gudipati 1586a36c61f9SKrishna Gudipati rhba->hba_id = bfa_fcs_lport_get_pwwn(port); 1587ba816ea8SJing Huang rhba->port_list.num_ports = cpu_to_be32(1); 1588a36c61f9SKrishna Gudipati rhba->port_list.port_entry = bfa_fcs_lport_get_pwwn(port); 1589a36c61f9SKrishna Gudipati 1590a36c61f9SKrishna Gudipati len = sizeof(rhba->hba_id) + sizeof(rhba->port_list); 1591a36c61f9SKrishna Gudipati 1592a36c61f9SKrishna Gudipati count = 0; 1593a36c61f9SKrishna Gudipati len += sizeof(rhba->hba_attr_blk.attr_count); 1594a36c61f9SKrishna Gudipati 1595a36c61f9SKrishna Gudipati /* 1596a36c61f9SKrishna Gudipati * fill out the invididual entries of the HBA attrib Block 1597a36c61f9SKrishna Gudipati */ 1598a36c61f9SKrishna Gudipati curr_ptr = (u8 *) &rhba->hba_attr_blk.hba_attr; 1599a36c61f9SKrishna Gudipati 1600a36c61f9SKrishna Gudipati /* 1601a36c61f9SKrishna Gudipati * Node Name 1602a36c61f9SKrishna Gudipati */ 1603a36c61f9SKrishna Gudipati attr = (struct fdmi_attr_s *) curr_ptr; 1604ba816ea8SJing Huang attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_NODENAME); 1605a36c61f9SKrishna Gudipati attr->len = sizeof(wwn_t); 1606a36c61f9SKrishna Gudipati memcpy(attr->value, &bfa_fcs_lport_get_nwwn(port), attr->len); 1607a36c61f9SKrishna Gudipati curr_ptr += sizeof(attr->type) + sizeof(attr->len) + attr->len; 1608a36c61f9SKrishna Gudipati len += attr->len; 1609a36c61f9SKrishna Gudipati count++; 1610a36c61f9SKrishna Gudipati attr->len = 1611ba816ea8SJing Huang cpu_to_be16(attr->len + sizeof(attr->type) + 1612a36c61f9SKrishna Gudipati sizeof(attr->len)); 1613a36c61f9SKrishna Gudipati 1614a36c61f9SKrishna Gudipati /* 1615a36c61f9SKrishna Gudipati * Manufacturer 1616a36c61f9SKrishna Gudipati */ 1617a36c61f9SKrishna Gudipati attr = (struct fdmi_attr_s *) curr_ptr; 1618ba816ea8SJing Huang attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_MANUFACTURER); 1619a36c61f9SKrishna Gudipati attr->len = (u16) strlen(fcs_hba_attr->manufacturer); 1620a36c61f9SKrishna Gudipati memcpy(attr->value, fcs_hba_attr->manufacturer, attr->len); 1621a36c61f9SKrishna Gudipati attr->len = fc_roundup(attr->len, sizeof(u32)); /* variable 1622a36c61f9SKrishna Gudipati *fields need 1623a36c61f9SKrishna Gudipati *to be 4 byte 1624a36c61f9SKrishna Gudipati *aligned */ 1625a36c61f9SKrishna Gudipati curr_ptr += sizeof(attr->type) + sizeof(attr->len) + attr->len; 1626a36c61f9SKrishna Gudipati len += attr->len; 1627a36c61f9SKrishna Gudipati count++; 1628a36c61f9SKrishna Gudipati attr->len = 1629ba816ea8SJing Huang cpu_to_be16(attr->len + sizeof(attr->type) + 1630a36c61f9SKrishna Gudipati sizeof(attr->len)); 1631a36c61f9SKrishna Gudipati 1632a36c61f9SKrishna Gudipati /* 1633a36c61f9SKrishna Gudipati * Serial Number 1634a36c61f9SKrishna Gudipati */ 1635a36c61f9SKrishna Gudipati attr = (struct fdmi_attr_s *) curr_ptr; 1636ba816ea8SJing Huang attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_SERIALNUM); 1637a36c61f9SKrishna Gudipati attr->len = (u16) strlen(fcs_hba_attr->serial_num); 1638a36c61f9SKrishna Gudipati memcpy(attr->value, fcs_hba_attr->serial_num, attr->len); 1639a36c61f9SKrishna Gudipati attr->len = fc_roundup(attr->len, sizeof(u32)); /* variable 1640a36c61f9SKrishna Gudipati *fields need 1641a36c61f9SKrishna Gudipati *to be 4 byte 1642a36c61f9SKrishna Gudipati *aligned */ 1643a36c61f9SKrishna Gudipati curr_ptr += sizeof(attr->type) + sizeof(attr->len) + attr->len; 1644a36c61f9SKrishna Gudipati len += attr->len; 1645a36c61f9SKrishna Gudipati count++; 1646a36c61f9SKrishna Gudipati attr->len = 1647ba816ea8SJing Huang cpu_to_be16(attr->len + sizeof(attr->type) + 1648a36c61f9SKrishna Gudipati sizeof(attr->len)); 1649a36c61f9SKrishna Gudipati 1650a36c61f9SKrishna Gudipati /* 1651a36c61f9SKrishna Gudipati * Model 1652a36c61f9SKrishna Gudipati */ 1653a36c61f9SKrishna Gudipati attr = (struct fdmi_attr_s *) curr_ptr; 1654ba816ea8SJing Huang attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_MODEL); 1655a36c61f9SKrishna Gudipati attr->len = (u16) strlen(fcs_hba_attr->model); 1656a36c61f9SKrishna Gudipati memcpy(attr->value, fcs_hba_attr->model, attr->len); 1657a36c61f9SKrishna Gudipati attr->len = fc_roundup(attr->len, sizeof(u32)); /* variable 1658a36c61f9SKrishna Gudipati *fields need 1659a36c61f9SKrishna Gudipati *to be 4 byte 1660a36c61f9SKrishna Gudipati *aligned */ 1661a36c61f9SKrishna Gudipati curr_ptr += sizeof(attr->type) + sizeof(attr->len) + attr->len; 1662a36c61f9SKrishna Gudipati len += attr->len; 1663a36c61f9SKrishna Gudipati count++; 1664a36c61f9SKrishna Gudipati attr->len = 1665ba816ea8SJing Huang cpu_to_be16(attr->len + sizeof(attr->type) + 1666a36c61f9SKrishna Gudipati sizeof(attr->len)); 1667a36c61f9SKrishna Gudipati 1668a36c61f9SKrishna Gudipati /* 1669a36c61f9SKrishna Gudipati * Model Desc 1670a36c61f9SKrishna Gudipati */ 1671a36c61f9SKrishna Gudipati attr = (struct fdmi_attr_s *) curr_ptr; 1672ba816ea8SJing Huang attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_MODEL_DESC); 1673a36c61f9SKrishna Gudipati attr->len = (u16) strlen(fcs_hba_attr->model_desc); 1674a36c61f9SKrishna Gudipati memcpy(attr->value, fcs_hba_attr->model_desc, attr->len); 1675a36c61f9SKrishna Gudipati attr->len = fc_roundup(attr->len, sizeof(u32)); /* variable 1676a36c61f9SKrishna Gudipati *fields need 1677a36c61f9SKrishna Gudipati *to be 4 byte 1678a36c61f9SKrishna Gudipati *aligned */ 1679a36c61f9SKrishna Gudipati curr_ptr += sizeof(attr->type) + sizeof(attr->len) + attr->len; 1680a36c61f9SKrishna Gudipati len += attr->len; 1681a36c61f9SKrishna Gudipati count++; 1682a36c61f9SKrishna Gudipati attr->len = 1683ba816ea8SJing Huang cpu_to_be16(attr->len + sizeof(attr->type) + 1684a36c61f9SKrishna Gudipati sizeof(attr->len)); 1685a36c61f9SKrishna Gudipati 1686a36c61f9SKrishna Gudipati /* 1687a36c61f9SKrishna Gudipati * H/W Version 1688a36c61f9SKrishna Gudipati */ 1689a36c61f9SKrishna Gudipati if (fcs_hba_attr->hw_version[0] != '\0') { 1690a36c61f9SKrishna Gudipati attr = (struct fdmi_attr_s *) curr_ptr; 1691ba816ea8SJing Huang attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_HW_VERSION); 1692a36c61f9SKrishna Gudipati attr->len = (u16) strlen(fcs_hba_attr->hw_version); 1693a36c61f9SKrishna Gudipati memcpy(attr->value, fcs_hba_attr->hw_version, attr->len); 1694a36c61f9SKrishna Gudipati attr->len = fc_roundup(attr->len, sizeof(u32)); /* variable 1695a36c61f9SKrishna Gudipati *fields need 1696a36c61f9SKrishna Gudipati *to be 4 byte 1697a36c61f9SKrishna Gudipati *aligned */ 1698a36c61f9SKrishna Gudipati curr_ptr += sizeof(attr->type) + sizeof(attr->len) + attr->len; 1699a36c61f9SKrishna Gudipati len += attr->len; 1700a36c61f9SKrishna Gudipati count++; 1701a36c61f9SKrishna Gudipati attr->len = 1702ba816ea8SJing Huang cpu_to_be16(attr->len + sizeof(attr->type) + 1703a36c61f9SKrishna Gudipati sizeof(attr->len)); 1704a36c61f9SKrishna Gudipati } 1705a36c61f9SKrishna Gudipati 1706a36c61f9SKrishna Gudipati /* 1707a36c61f9SKrishna Gudipati * Driver Version 1708a36c61f9SKrishna Gudipati */ 1709a36c61f9SKrishna Gudipati attr = (struct fdmi_attr_s *) curr_ptr; 1710ba816ea8SJing Huang attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_DRIVER_VERSION); 1711a36c61f9SKrishna Gudipati attr->len = (u16) strlen(fcs_hba_attr->driver_version); 1712a36c61f9SKrishna Gudipati memcpy(attr->value, fcs_hba_attr->driver_version, attr->len); 1713a36c61f9SKrishna Gudipati attr->len = fc_roundup(attr->len, sizeof(u32)); /* variable 1714a36c61f9SKrishna Gudipati *fields need 1715a36c61f9SKrishna Gudipati *to be 4 byte 1716a36c61f9SKrishna Gudipati *aligned */ 1717a36c61f9SKrishna Gudipati curr_ptr += sizeof(attr->type) + sizeof(attr->len) + attr->len; 1718a36c61f9SKrishna Gudipati len += attr->len;; 1719a36c61f9SKrishna Gudipati count++; 1720a36c61f9SKrishna Gudipati attr->len = 1721ba816ea8SJing Huang cpu_to_be16(attr->len + sizeof(attr->type) + 1722a36c61f9SKrishna Gudipati sizeof(attr->len)); 1723a36c61f9SKrishna Gudipati 1724a36c61f9SKrishna Gudipati /* 1725a36c61f9SKrishna Gudipati * Option Rom Version 1726a36c61f9SKrishna Gudipati */ 1727a36c61f9SKrishna Gudipati if (fcs_hba_attr->option_rom_ver[0] != '\0') { 1728a36c61f9SKrishna Gudipati attr = (struct fdmi_attr_s *) curr_ptr; 1729ba816ea8SJing Huang attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_ROM_VERSION); 1730a36c61f9SKrishna Gudipati attr->len = (u16) strlen(fcs_hba_attr->option_rom_ver); 1731a36c61f9SKrishna Gudipati memcpy(attr->value, fcs_hba_attr->option_rom_ver, attr->len); 1732a36c61f9SKrishna Gudipati attr->len = fc_roundup(attr->len, sizeof(u32)); /* variable 1733a36c61f9SKrishna Gudipati *fields need 1734a36c61f9SKrishna Gudipati *to be 4 byte 1735a36c61f9SKrishna Gudipati *aligned */ 1736a36c61f9SKrishna Gudipati curr_ptr += sizeof(attr->type) + sizeof(attr->len) + attr->len; 1737a36c61f9SKrishna Gudipati len += attr->len; 1738a36c61f9SKrishna Gudipati count++; 1739a36c61f9SKrishna Gudipati attr->len = 1740ba816ea8SJing Huang cpu_to_be16(attr->len + sizeof(attr->type) + 1741a36c61f9SKrishna Gudipati sizeof(attr->len)); 1742a36c61f9SKrishna Gudipati } 1743a36c61f9SKrishna Gudipati 1744a36c61f9SKrishna Gudipati /* 1745a36c61f9SKrishna Gudipati * f/w Version = driver version 1746a36c61f9SKrishna Gudipati */ 1747a36c61f9SKrishna Gudipati attr = (struct fdmi_attr_s *) curr_ptr; 1748ba816ea8SJing Huang attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_FW_VERSION); 1749a36c61f9SKrishna Gudipati attr->len = (u16) strlen(fcs_hba_attr->driver_version); 1750a36c61f9SKrishna Gudipati memcpy(attr->value, fcs_hba_attr->driver_version, attr->len); 1751a36c61f9SKrishna Gudipati attr->len = fc_roundup(attr->len, sizeof(u32)); /* variable 1752a36c61f9SKrishna Gudipati *fields need 1753a36c61f9SKrishna Gudipati *to be 4 byte 1754a36c61f9SKrishna Gudipati *aligned */ 1755a36c61f9SKrishna Gudipati curr_ptr += sizeof(attr->type) + sizeof(attr->len) + attr->len; 1756a36c61f9SKrishna Gudipati len += attr->len; 1757a36c61f9SKrishna Gudipati count++; 1758a36c61f9SKrishna Gudipati attr->len = 1759ba816ea8SJing Huang cpu_to_be16(attr->len + sizeof(attr->type) + 1760a36c61f9SKrishna Gudipati sizeof(attr->len)); 1761a36c61f9SKrishna Gudipati 1762a36c61f9SKrishna Gudipati /* 1763a36c61f9SKrishna Gudipati * OS Name 1764a36c61f9SKrishna Gudipati */ 1765a36c61f9SKrishna Gudipati if (fcs_hba_attr->os_name[0] != '\0') { 1766a36c61f9SKrishna Gudipati attr = (struct fdmi_attr_s *) curr_ptr; 1767ba816ea8SJing Huang attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_OS_NAME); 1768a36c61f9SKrishna Gudipati attr->len = (u16) strlen(fcs_hba_attr->os_name); 1769a36c61f9SKrishna Gudipati memcpy(attr->value, fcs_hba_attr->os_name, attr->len); 1770a36c61f9SKrishna Gudipati attr->len = fc_roundup(attr->len, sizeof(u32)); /* variable 1771a36c61f9SKrishna Gudipati *fields need 1772a36c61f9SKrishna Gudipati *to be 4 byte 1773a36c61f9SKrishna Gudipati *aligned */ 1774a36c61f9SKrishna Gudipati curr_ptr += sizeof(attr->type) + sizeof(attr->len) + attr->len; 1775a36c61f9SKrishna Gudipati len += attr->len; 1776a36c61f9SKrishna Gudipati count++; 1777a36c61f9SKrishna Gudipati attr->len = 1778ba816ea8SJing Huang cpu_to_be16(attr->len + sizeof(attr->type) + 1779a36c61f9SKrishna Gudipati sizeof(attr->len)); 1780a36c61f9SKrishna Gudipati } 1781a36c61f9SKrishna Gudipati 1782a36c61f9SKrishna Gudipati /* 1783a36c61f9SKrishna Gudipati * MAX_CT_PAYLOAD 1784a36c61f9SKrishna Gudipati */ 1785a36c61f9SKrishna Gudipati attr = (struct fdmi_attr_s *) curr_ptr; 1786ba816ea8SJing Huang attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_MAX_CT); 1787a36c61f9SKrishna Gudipati attr->len = sizeof(fcs_hba_attr->max_ct_pyld); 1788a36c61f9SKrishna Gudipati memcpy(attr->value, &fcs_hba_attr->max_ct_pyld, attr->len); 1789a36c61f9SKrishna Gudipati len += attr->len; 1790a36c61f9SKrishna Gudipati count++; 1791a36c61f9SKrishna Gudipati attr->len = 1792ba816ea8SJing Huang cpu_to_be16(attr->len + sizeof(attr->type) + 1793a36c61f9SKrishna Gudipati sizeof(attr->len)); 1794a36c61f9SKrishna Gudipati 1795a36c61f9SKrishna Gudipati /* 1796a36c61f9SKrishna Gudipati * Update size of payload 1797a36c61f9SKrishna Gudipati */ 1798a36c61f9SKrishna Gudipati len += ((sizeof(attr->type) + 1799a36c61f9SKrishna Gudipati sizeof(attr->len)) * count); 1800a36c61f9SKrishna Gudipati 1801ba816ea8SJing Huang rhba->hba_attr_blk.attr_count = cpu_to_be32(count); 1802a36c61f9SKrishna Gudipati return len; 1803a36c61f9SKrishna Gudipati } 1804a36c61f9SKrishna Gudipati 1805a36c61f9SKrishna Gudipati static void 1806a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_rhba_response(void *fcsarg, struct bfa_fcxp_s *fcxp, 1807a36c61f9SKrishna Gudipati void *cbarg, bfa_status_t req_status, 1808a36c61f9SKrishna Gudipati u32 rsp_len, u32 resid_len, 1809a36c61f9SKrishna Gudipati struct fchs_s *rsp_fchs) 1810a36c61f9SKrishna Gudipati { 1811a36c61f9SKrishna Gudipati struct bfa_fcs_lport_fdmi_s *fdmi = 1812a36c61f9SKrishna Gudipati (struct bfa_fcs_lport_fdmi_s *) cbarg; 1813a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = fdmi->ms->port; 1814a36c61f9SKrishna Gudipati struct ct_hdr_s *cthdr = NULL; 1815a36c61f9SKrishna Gudipati 1816a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 1817a36c61f9SKrishna Gudipati 1818a36c61f9SKrishna Gudipati /* 1819a36c61f9SKrishna Gudipati * Sanity Checks 1820a36c61f9SKrishna Gudipati */ 1821a36c61f9SKrishna Gudipati if (req_status != BFA_STATUS_OK) { 1822a36c61f9SKrishna Gudipati bfa_trc(port->fcs, req_status); 1823a36c61f9SKrishna Gudipati bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_ERROR); 1824a36c61f9SKrishna Gudipati return; 1825a36c61f9SKrishna Gudipati } 1826a36c61f9SKrishna Gudipati 1827a36c61f9SKrishna Gudipati cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp); 1828ba816ea8SJing Huang cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code); 1829a36c61f9SKrishna Gudipati 1830a36c61f9SKrishna Gudipati if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) { 1831a36c61f9SKrishna Gudipati bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_OK); 1832a36c61f9SKrishna Gudipati return; 1833a36c61f9SKrishna Gudipati } 1834a36c61f9SKrishna Gudipati 1835a36c61f9SKrishna Gudipati bfa_trc(port->fcs, cthdr->reason_code); 1836a36c61f9SKrishna Gudipati bfa_trc(port->fcs, cthdr->exp_code); 1837a36c61f9SKrishna Gudipati bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_ERROR); 1838a36c61f9SKrishna Gudipati } 1839a36c61f9SKrishna Gudipati 1840a36c61f9SKrishna Gudipati /** 1841a36c61f9SKrishna Gudipati * RPRT : Register Port 1842a36c61f9SKrishna Gudipati */ 1843a36c61f9SKrishna Gudipati static void 1844a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_send_rprt(void *fdmi_cbarg, struct bfa_fcxp_s *fcxp_alloced) 1845a36c61f9SKrishna Gudipati { 1846a36c61f9SKrishna Gudipati struct bfa_fcs_lport_fdmi_s *fdmi = fdmi_cbarg; 1847a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = fdmi->ms->port; 1848a36c61f9SKrishna Gudipati struct fchs_s fchs; 1849a36c61f9SKrishna Gudipati u16 len, attr_len; 1850a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp; 1851a36c61f9SKrishna Gudipati u8 *pyld; 1852a36c61f9SKrishna Gudipati 1853a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 1854a36c61f9SKrishna Gudipati 1855a36c61f9SKrishna Gudipati fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs); 1856a36c61f9SKrishna Gudipati if (!fcxp) { 1857a36c61f9SKrishna Gudipati bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &fdmi->fcxp_wqe, 1858a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_send_rprt, fdmi); 1859a36c61f9SKrishna Gudipati return; 1860a36c61f9SKrishna Gudipati } 1861a36c61f9SKrishna Gudipati fdmi->fcxp = fcxp; 1862a36c61f9SKrishna Gudipati 1863a36c61f9SKrishna Gudipati pyld = bfa_fcxp_get_reqbuf(fcxp); 18646a18b167SJing Huang memset(pyld, 0, FC_MAX_PDUSZ); 1865a36c61f9SKrishna Gudipati 1866a36c61f9SKrishna Gudipati len = fc_fdmi_reqhdr_build(&fchs, pyld, bfa_fcs_lport_get_fcid(port), 1867a36c61f9SKrishna Gudipati FDMI_RPRT); 1868a36c61f9SKrishna Gudipati 1869a36c61f9SKrishna Gudipati attr_len = 1870a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_build_rprt_pyld(fdmi, 1871a36c61f9SKrishna Gudipati (u8 *) ((struct ct_hdr_s *) pyld 1872a36c61f9SKrishna Gudipati + 1)); 1873a36c61f9SKrishna Gudipati 1874a36c61f9SKrishna Gudipati bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, 1875a36c61f9SKrishna Gudipati FC_CLASS_3, len + attr_len, &fchs, 1876a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_rprt_response, (void *)fdmi, 1877a36c61f9SKrishna Gudipati FC_MAX_PDUSZ, FC_FCCT_TOV); 1878a36c61f9SKrishna Gudipati 1879a36c61f9SKrishna Gudipati bfa_sm_send_event(fdmi, FDMISM_EVENT_RPRT_SENT); 1880a36c61f9SKrishna Gudipati } 1881a36c61f9SKrishna Gudipati 1882a36c61f9SKrishna Gudipati /** 1883a36c61f9SKrishna Gudipati * This routine builds Port Attribute Block that used in RPA, RPRT commands. 1884a36c61f9SKrishna Gudipati */ 1885a36c61f9SKrishna Gudipati static u16 1886a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_build_portattr_block(struct bfa_fcs_lport_fdmi_s *fdmi, 1887a36c61f9SKrishna Gudipati u8 *pyld) 1888a36c61f9SKrishna Gudipati { 1889a36c61f9SKrishna Gudipati struct bfa_fcs_fdmi_port_attr_s fcs_port_attr; 1890a36c61f9SKrishna Gudipati struct fdmi_port_attr_s *port_attrib = (struct fdmi_port_attr_s *) pyld; 1891a36c61f9SKrishna Gudipati struct fdmi_attr_s *attr; 1892a36c61f9SKrishna Gudipati u8 *curr_ptr; 1893a36c61f9SKrishna Gudipati u16 len; 1894a36c61f9SKrishna Gudipati u8 count = 0; 1895a36c61f9SKrishna Gudipati 1896a36c61f9SKrishna Gudipati /* 1897a36c61f9SKrishna Gudipati * get port attributes 1898a36c61f9SKrishna Gudipati */ 1899a36c61f9SKrishna Gudipati bfa_fcs_fdmi_get_portattr(fdmi, &fcs_port_attr); 1900a36c61f9SKrishna Gudipati 1901a36c61f9SKrishna Gudipati len = sizeof(port_attrib->attr_count); 1902a36c61f9SKrishna Gudipati 1903a36c61f9SKrishna Gudipati /* 1904a36c61f9SKrishna Gudipati * fill out the invididual entries 1905a36c61f9SKrishna Gudipati */ 1906a36c61f9SKrishna Gudipati curr_ptr = (u8 *) &port_attrib->port_attr; 1907a36c61f9SKrishna Gudipati 1908a36c61f9SKrishna Gudipati /* 1909a36c61f9SKrishna Gudipati * FC4 Types 1910a36c61f9SKrishna Gudipati */ 1911a36c61f9SKrishna Gudipati attr = (struct fdmi_attr_s *) curr_ptr; 1912ba816ea8SJing Huang attr->type = cpu_to_be16(FDMI_PORT_ATTRIB_FC4_TYPES); 1913a36c61f9SKrishna Gudipati attr->len = sizeof(fcs_port_attr.supp_fc4_types); 1914a36c61f9SKrishna Gudipati memcpy(attr->value, fcs_port_attr.supp_fc4_types, attr->len); 1915a36c61f9SKrishna Gudipati curr_ptr += sizeof(attr->type) + sizeof(attr->len) + attr->len; 1916a36c61f9SKrishna Gudipati len += attr->len; 1917a36c61f9SKrishna Gudipati ++count; 1918a36c61f9SKrishna Gudipati attr->len = 1919ba816ea8SJing Huang cpu_to_be16(attr->len + sizeof(attr->type) + 1920a36c61f9SKrishna Gudipati sizeof(attr->len)); 1921a36c61f9SKrishna Gudipati 1922a36c61f9SKrishna Gudipati /* 1923a36c61f9SKrishna Gudipati * Supported Speed 1924a36c61f9SKrishna Gudipati */ 1925a36c61f9SKrishna Gudipati attr = (struct fdmi_attr_s *) curr_ptr; 1926ba816ea8SJing Huang attr->type = cpu_to_be16(FDMI_PORT_ATTRIB_SUPP_SPEED); 1927a36c61f9SKrishna Gudipati attr->len = sizeof(fcs_port_attr.supp_speed); 1928a36c61f9SKrishna Gudipati memcpy(attr->value, &fcs_port_attr.supp_speed, attr->len); 1929a36c61f9SKrishna Gudipati curr_ptr += sizeof(attr->type) + sizeof(attr->len) + attr->len; 1930a36c61f9SKrishna Gudipati len += attr->len; 1931a36c61f9SKrishna Gudipati ++count; 1932a36c61f9SKrishna Gudipati attr->len = 1933ba816ea8SJing Huang cpu_to_be16(attr->len + sizeof(attr->type) + 1934a36c61f9SKrishna Gudipati sizeof(attr->len)); 1935a36c61f9SKrishna Gudipati 1936a36c61f9SKrishna Gudipati /* 1937a36c61f9SKrishna Gudipati * current Port Speed 1938a36c61f9SKrishna Gudipati */ 1939a36c61f9SKrishna Gudipati attr = (struct fdmi_attr_s *) curr_ptr; 1940ba816ea8SJing Huang attr->type = cpu_to_be16(FDMI_PORT_ATTRIB_PORT_SPEED); 1941a36c61f9SKrishna Gudipati attr->len = sizeof(fcs_port_attr.curr_speed); 1942a36c61f9SKrishna Gudipati memcpy(attr->value, &fcs_port_attr.curr_speed, attr->len); 1943a36c61f9SKrishna Gudipati curr_ptr += sizeof(attr->type) + sizeof(attr->len) + attr->len; 1944a36c61f9SKrishna Gudipati len += attr->len; 1945a36c61f9SKrishna Gudipati ++count; 1946a36c61f9SKrishna Gudipati attr->len = 1947ba816ea8SJing Huang cpu_to_be16(attr->len + sizeof(attr->type) + 1948a36c61f9SKrishna Gudipati sizeof(attr->len)); 1949a36c61f9SKrishna Gudipati 1950a36c61f9SKrishna Gudipati /* 1951a36c61f9SKrishna Gudipati * max frame size 1952a36c61f9SKrishna Gudipati */ 1953a36c61f9SKrishna Gudipati attr = (struct fdmi_attr_s *) curr_ptr; 1954ba816ea8SJing Huang attr->type = cpu_to_be16(FDMI_PORT_ATTRIB_FRAME_SIZE); 1955a36c61f9SKrishna Gudipati attr->len = sizeof(fcs_port_attr.max_frm_size); 1956a36c61f9SKrishna Gudipati memcpy(attr->value, &fcs_port_attr.max_frm_size, attr->len); 1957a36c61f9SKrishna Gudipati curr_ptr += sizeof(attr->type) + sizeof(attr->len) + attr->len; 1958a36c61f9SKrishna Gudipati len += attr->len; 1959a36c61f9SKrishna Gudipati ++count; 1960a36c61f9SKrishna Gudipati attr->len = 1961ba816ea8SJing Huang cpu_to_be16(attr->len + sizeof(attr->type) + 1962a36c61f9SKrishna Gudipati sizeof(attr->len)); 1963a36c61f9SKrishna Gudipati 1964a36c61f9SKrishna Gudipati /* 1965a36c61f9SKrishna Gudipati * OS Device Name 1966a36c61f9SKrishna Gudipati */ 1967a36c61f9SKrishna Gudipati if (fcs_port_attr.os_device_name[0] != '\0') { 1968a36c61f9SKrishna Gudipati attr = (struct fdmi_attr_s *) curr_ptr; 1969ba816ea8SJing Huang attr->type = cpu_to_be16(FDMI_PORT_ATTRIB_DEV_NAME); 1970a36c61f9SKrishna Gudipati attr->len = (u16) strlen(fcs_port_attr.os_device_name); 1971a36c61f9SKrishna Gudipati memcpy(attr->value, fcs_port_attr.os_device_name, attr->len); 1972a36c61f9SKrishna Gudipati attr->len = fc_roundup(attr->len, sizeof(u32)); /* variable 1973a36c61f9SKrishna Gudipati *fields need 1974a36c61f9SKrishna Gudipati *to be 4 byte 1975a36c61f9SKrishna Gudipati *aligned */ 1976a36c61f9SKrishna Gudipati curr_ptr += sizeof(attr->type) + sizeof(attr->len) + attr->len; 1977a36c61f9SKrishna Gudipati len += attr->len; 1978a36c61f9SKrishna Gudipati ++count; 1979a36c61f9SKrishna Gudipati attr->len = 1980ba816ea8SJing Huang cpu_to_be16(attr->len + sizeof(attr->type) + 1981a36c61f9SKrishna Gudipati sizeof(attr->len)); 1982a36c61f9SKrishna Gudipati } 1983a36c61f9SKrishna Gudipati /* 1984a36c61f9SKrishna Gudipati * Host Name 1985a36c61f9SKrishna Gudipati */ 1986a36c61f9SKrishna Gudipati if (fcs_port_attr.host_name[0] != '\0') { 1987a36c61f9SKrishna Gudipati attr = (struct fdmi_attr_s *) curr_ptr; 1988ba816ea8SJing Huang attr->type = cpu_to_be16(FDMI_PORT_ATTRIB_HOST_NAME); 1989a36c61f9SKrishna Gudipati attr->len = (u16) strlen(fcs_port_attr.host_name); 1990a36c61f9SKrishna Gudipati memcpy(attr->value, fcs_port_attr.host_name, attr->len); 1991a36c61f9SKrishna Gudipati attr->len = fc_roundup(attr->len, sizeof(u32)); /* variable 1992a36c61f9SKrishna Gudipati *fields need 1993a36c61f9SKrishna Gudipati *to be 4 byte 1994a36c61f9SKrishna Gudipati *aligned */ 1995a36c61f9SKrishna Gudipati curr_ptr += sizeof(attr->type) + sizeof(attr->len) + attr->len; 1996a36c61f9SKrishna Gudipati len += attr->len; 1997a36c61f9SKrishna Gudipati ++count; 1998a36c61f9SKrishna Gudipati attr->len = 1999ba816ea8SJing Huang cpu_to_be16(attr->len + sizeof(attr->type) + 2000a36c61f9SKrishna Gudipati sizeof(attr->len)); 2001a36c61f9SKrishna Gudipati } 2002a36c61f9SKrishna Gudipati 2003a36c61f9SKrishna Gudipati /* 2004a36c61f9SKrishna Gudipati * Update size of payload 2005a36c61f9SKrishna Gudipati */ 2006ba816ea8SJing Huang port_attrib->attr_count = cpu_to_be32(count); 2007a36c61f9SKrishna Gudipati len += ((sizeof(attr->type) + 2008a36c61f9SKrishna Gudipati sizeof(attr->len)) * count); 2009a36c61f9SKrishna Gudipati return len; 2010a36c61f9SKrishna Gudipati } 2011a36c61f9SKrishna Gudipati 2012a36c61f9SKrishna Gudipati static u16 2013a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_build_rprt_pyld(struct bfa_fcs_lport_fdmi_s *fdmi, u8 *pyld) 2014a36c61f9SKrishna Gudipati { 2015a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = fdmi->ms->port; 2016a36c61f9SKrishna Gudipati struct fdmi_rprt_s *rprt = (struct fdmi_rprt_s *) pyld; 2017a36c61f9SKrishna Gudipati u16 len; 2018a36c61f9SKrishna Gudipati 2019a36c61f9SKrishna Gudipati rprt->hba_id = bfa_fcs_lport_get_pwwn(bfa_fcs_get_base_port(port->fcs)); 2020a36c61f9SKrishna Gudipati rprt->port_name = bfa_fcs_lport_get_pwwn(port); 2021a36c61f9SKrishna Gudipati 2022a36c61f9SKrishna Gudipati len = bfa_fcs_lport_fdmi_build_portattr_block(fdmi, 2023a36c61f9SKrishna Gudipati (u8 *) &rprt->port_attr_blk); 2024a36c61f9SKrishna Gudipati 2025a36c61f9SKrishna Gudipati len += sizeof(rprt->hba_id) + sizeof(rprt->port_name); 2026a36c61f9SKrishna Gudipati 2027a36c61f9SKrishna Gudipati return len; 2028a36c61f9SKrishna Gudipati } 2029a36c61f9SKrishna Gudipati 2030a36c61f9SKrishna Gudipati static void 2031a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_rprt_response(void *fcsarg, struct bfa_fcxp_s *fcxp, 2032a36c61f9SKrishna Gudipati void *cbarg, bfa_status_t req_status, 2033a36c61f9SKrishna Gudipati u32 rsp_len, u32 resid_len, 2034a36c61f9SKrishna Gudipati struct fchs_s *rsp_fchs) 2035a36c61f9SKrishna Gudipati { 2036a36c61f9SKrishna Gudipati struct bfa_fcs_lport_fdmi_s *fdmi = 2037a36c61f9SKrishna Gudipati (struct bfa_fcs_lport_fdmi_s *) cbarg; 2038a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = fdmi->ms->port; 2039a36c61f9SKrishna Gudipati struct ct_hdr_s *cthdr = NULL; 2040a36c61f9SKrishna Gudipati 2041a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 2042a36c61f9SKrishna Gudipati 2043a36c61f9SKrishna Gudipati /* 2044a36c61f9SKrishna Gudipati * Sanity Checks 2045a36c61f9SKrishna Gudipati */ 2046a36c61f9SKrishna Gudipati if (req_status != BFA_STATUS_OK) { 2047a36c61f9SKrishna Gudipati bfa_trc(port->fcs, req_status); 2048a36c61f9SKrishna Gudipati bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_ERROR); 2049a36c61f9SKrishna Gudipati return; 2050a36c61f9SKrishna Gudipati } 2051a36c61f9SKrishna Gudipati 2052a36c61f9SKrishna Gudipati cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp); 2053ba816ea8SJing Huang cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code); 2054a36c61f9SKrishna Gudipati 2055a36c61f9SKrishna Gudipati if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) { 2056a36c61f9SKrishna Gudipati bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_OK); 2057a36c61f9SKrishna Gudipati return; 2058a36c61f9SKrishna Gudipati } 2059a36c61f9SKrishna Gudipati 2060a36c61f9SKrishna Gudipati bfa_trc(port->fcs, cthdr->reason_code); 2061a36c61f9SKrishna Gudipati bfa_trc(port->fcs, cthdr->exp_code); 2062a36c61f9SKrishna Gudipati bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_ERROR); 2063a36c61f9SKrishna Gudipati } 2064a36c61f9SKrishna Gudipati 2065a36c61f9SKrishna Gudipati /** 2066a36c61f9SKrishna Gudipati * RPA : Register Port Attributes. 2067a36c61f9SKrishna Gudipati */ 2068a36c61f9SKrishna Gudipati static void 2069a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_send_rpa(void *fdmi_cbarg, struct bfa_fcxp_s *fcxp_alloced) 2070a36c61f9SKrishna Gudipati { 2071a36c61f9SKrishna Gudipati struct bfa_fcs_lport_fdmi_s *fdmi = fdmi_cbarg; 2072a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = fdmi->ms->port; 2073a36c61f9SKrishna Gudipati struct fchs_s fchs; 2074a36c61f9SKrishna Gudipati u16 len, attr_len; 2075a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp; 2076a36c61f9SKrishna Gudipati u8 *pyld; 2077a36c61f9SKrishna Gudipati 2078a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 2079a36c61f9SKrishna Gudipati 2080a36c61f9SKrishna Gudipati fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs); 2081a36c61f9SKrishna Gudipati if (!fcxp) { 2082a36c61f9SKrishna Gudipati bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &fdmi->fcxp_wqe, 2083a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_send_rpa, fdmi); 2084a36c61f9SKrishna Gudipati return; 2085a36c61f9SKrishna Gudipati } 2086a36c61f9SKrishna Gudipati fdmi->fcxp = fcxp; 2087a36c61f9SKrishna Gudipati 2088a36c61f9SKrishna Gudipati pyld = bfa_fcxp_get_reqbuf(fcxp); 20896a18b167SJing Huang memset(pyld, 0, FC_MAX_PDUSZ); 2090a36c61f9SKrishna Gudipati 2091a36c61f9SKrishna Gudipati len = fc_fdmi_reqhdr_build(&fchs, pyld, bfa_fcs_lport_get_fcid(port), 2092a36c61f9SKrishna Gudipati FDMI_RPA); 2093a36c61f9SKrishna Gudipati 2094a36c61f9SKrishna Gudipati attr_len = 2095a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_build_rpa_pyld(fdmi, 2096a36c61f9SKrishna Gudipati (u8 *) ((struct ct_hdr_s *) pyld 2097a36c61f9SKrishna Gudipati + 1)); 2098a36c61f9SKrishna Gudipati 2099a36c61f9SKrishna Gudipati bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, 2100a36c61f9SKrishna Gudipati FC_CLASS_3, len + attr_len, &fchs, 2101a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_rpa_response, (void *)fdmi, 2102a36c61f9SKrishna Gudipati FC_MAX_PDUSZ, FC_FCCT_TOV); 2103a36c61f9SKrishna Gudipati 2104a36c61f9SKrishna Gudipati bfa_sm_send_event(fdmi, FDMISM_EVENT_RPA_SENT); 2105a36c61f9SKrishna Gudipati } 2106a36c61f9SKrishna Gudipati 2107a36c61f9SKrishna Gudipati static u16 2108a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_build_rpa_pyld(struct bfa_fcs_lport_fdmi_s *fdmi, u8 *pyld) 2109a36c61f9SKrishna Gudipati { 2110a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = fdmi->ms->port; 2111a36c61f9SKrishna Gudipati struct fdmi_rpa_s *rpa = (struct fdmi_rpa_s *) pyld; 2112a36c61f9SKrishna Gudipati u16 len; 2113a36c61f9SKrishna Gudipati 2114a36c61f9SKrishna Gudipati rpa->port_name = bfa_fcs_lport_get_pwwn(port); 2115a36c61f9SKrishna Gudipati 2116a36c61f9SKrishna Gudipati len = bfa_fcs_lport_fdmi_build_portattr_block(fdmi, 2117a36c61f9SKrishna Gudipati (u8 *) &rpa->port_attr_blk); 2118a36c61f9SKrishna Gudipati 2119a36c61f9SKrishna Gudipati len += sizeof(rpa->port_name); 2120a36c61f9SKrishna Gudipati 2121a36c61f9SKrishna Gudipati return len; 2122a36c61f9SKrishna Gudipati } 2123a36c61f9SKrishna Gudipati 2124a36c61f9SKrishna Gudipati static void 2125a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_rpa_response(void *fcsarg, struct bfa_fcxp_s *fcxp, 2126a36c61f9SKrishna Gudipati void *cbarg, bfa_status_t req_status, u32 rsp_len, 2127a36c61f9SKrishna Gudipati u32 resid_len, struct fchs_s *rsp_fchs) 2128a36c61f9SKrishna Gudipati { 2129a36c61f9SKrishna Gudipati struct bfa_fcs_lport_fdmi_s *fdmi = 2130a36c61f9SKrishna Gudipati (struct bfa_fcs_lport_fdmi_s *) cbarg; 2131a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = fdmi->ms->port; 2132a36c61f9SKrishna Gudipati struct ct_hdr_s *cthdr = NULL; 2133a36c61f9SKrishna Gudipati 2134a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 2135a36c61f9SKrishna Gudipati 2136a36c61f9SKrishna Gudipati /* 2137a36c61f9SKrishna Gudipati * Sanity Checks 2138a36c61f9SKrishna Gudipati */ 2139a36c61f9SKrishna Gudipati if (req_status != BFA_STATUS_OK) { 2140a36c61f9SKrishna Gudipati bfa_trc(port->fcs, req_status); 2141a36c61f9SKrishna Gudipati bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_ERROR); 2142a36c61f9SKrishna Gudipati return; 2143a36c61f9SKrishna Gudipati } 2144a36c61f9SKrishna Gudipati 2145a36c61f9SKrishna Gudipati cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp); 2146ba816ea8SJing Huang cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code); 2147a36c61f9SKrishna Gudipati 2148a36c61f9SKrishna Gudipati if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) { 2149a36c61f9SKrishna Gudipati bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_OK); 2150a36c61f9SKrishna Gudipati return; 2151a36c61f9SKrishna Gudipati } 2152a36c61f9SKrishna Gudipati 2153a36c61f9SKrishna Gudipati bfa_trc(port->fcs, cthdr->reason_code); 2154a36c61f9SKrishna Gudipati bfa_trc(port->fcs, cthdr->exp_code); 2155a36c61f9SKrishna Gudipati bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_ERROR); 2156a36c61f9SKrishna Gudipati } 2157a36c61f9SKrishna Gudipati 2158a36c61f9SKrishna Gudipati static void 2159a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_timeout(void *arg) 2160a36c61f9SKrishna Gudipati { 2161a36c61f9SKrishna Gudipati struct bfa_fcs_lport_fdmi_s *fdmi = (struct bfa_fcs_lport_fdmi_s *) arg; 2162a36c61f9SKrishna Gudipati 2163a36c61f9SKrishna Gudipati bfa_sm_send_event(fdmi, FDMISM_EVENT_TIMEOUT); 2164a36c61f9SKrishna Gudipati } 2165a36c61f9SKrishna Gudipati 2166a36c61f9SKrishna Gudipati void 2167a36c61f9SKrishna Gudipati bfa_fcs_fdmi_get_hbaattr(struct bfa_fcs_lport_fdmi_s *fdmi, 2168a36c61f9SKrishna Gudipati struct bfa_fcs_fdmi_hba_attr_s *hba_attr) 2169a36c61f9SKrishna Gudipati { 2170a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = fdmi->ms->port; 2171a36c61f9SKrishna Gudipati struct bfa_fcs_driver_info_s *driver_info = &port->fcs->driver_info; 2172a36c61f9SKrishna Gudipati 21736a18b167SJing Huang memset(hba_attr, 0, sizeof(struct bfa_fcs_fdmi_hba_attr_s)); 2174a36c61f9SKrishna Gudipati 2175a36c61f9SKrishna Gudipati bfa_ioc_get_adapter_manufacturer(&port->fcs->bfa->ioc, 2176a36c61f9SKrishna Gudipati hba_attr->manufacturer); 2177a36c61f9SKrishna Gudipati bfa_ioc_get_adapter_serial_num(&port->fcs->bfa->ioc, 2178a36c61f9SKrishna Gudipati hba_attr->serial_num); 2179a36c61f9SKrishna Gudipati bfa_ioc_get_adapter_model(&port->fcs->bfa->ioc, 2180a36c61f9SKrishna Gudipati hba_attr->model); 2181a36c61f9SKrishna Gudipati bfa_ioc_get_adapter_model(&port->fcs->bfa->ioc, 2182a36c61f9SKrishna Gudipati hba_attr->model_desc); 2183a36c61f9SKrishna Gudipati bfa_ioc_get_pci_chip_rev(&port->fcs->bfa->ioc, 2184a36c61f9SKrishna Gudipati hba_attr->hw_version); 2185a36c61f9SKrishna Gudipati bfa_ioc_get_adapter_optrom_ver(&port->fcs->bfa->ioc, 2186a36c61f9SKrishna Gudipati hba_attr->option_rom_ver); 2187a36c61f9SKrishna Gudipati bfa_ioc_get_adapter_fw_ver(&port->fcs->bfa->ioc, 2188a36c61f9SKrishna Gudipati hba_attr->fw_version); 2189a36c61f9SKrishna Gudipati 2190a36c61f9SKrishna Gudipati strncpy(hba_attr->driver_version, (char *)driver_info->version, 2191a36c61f9SKrishna Gudipati sizeof(hba_attr->driver_version)); 2192a36c61f9SKrishna Gudipati 2193a36c61f9SKrishna Gudipati strncpy(hba_attr->os_name, driver_info->host_os_name, 2194a36c61f9SKrishna Gudipati sizeof(hba_attr->os_name)); 2195a36c61f9SKrishna Gudipati 2196a36c61f9SKrishna Gudipati /* 2197a36c61f9SKrishna Gudipati * If there is a patch level, append it 2198a36c61f9SKrishna Gudipati * to the os name along with a separator 2199a36c61f9SKrishna Gudipati */ 2200a36c61f9SKrishna Gudipati if (driver_info->host_os_patch[0] != '\0') { 2201a36c61f9SKrishna Gudipati strncat(hba_attr->os_name, BFA_FCS_PORT_SYMBNAME_SEPARATOR, 2202a36c61f9SKrishna Gudipati sizeof(BFA_FCS_PORT_SYMBNAME_SEPARATOR)); 2203a36c61f9SKrishna Gudipati strncat(hba_attr->os_name, driver_info->host_os_patch, 2204a36c61f9SKrishna Gudipati sizeof(driver_info->host_os_patch)); 2205a36c61f9SKrishna Gudipati } 2206a36c61f9SKrishna Gudipati 2207ba816ea8SJing Huang hba_attr->max_ct_pyld = cpu_to_be32(FC_MAX_PDUSZ); 2208a36c61f9SKrishna Gudipati } 2209a36c61f9SKrishna Gudipati 2210a36c61f9SKrishna Gudipati void 2211a36c61f9SKrishna Gudipati bfa_fcs_fdmi_get_portattr(struct bfa_fcs_lport_fdmi_s *fdmi, 2212a36c61f9SKrishna Gudipati struct bfa_fcs_fdmi_port_attr_s *port_attr) 2213a36c61f9SKrishna Gudipati { 2214a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = fdmi->ms->port; 2215a36c61f9SKrishna Gudipati struct bfa_fcs_driver_info_s *driver_info = &port->fcs->driver_info; 2216a36c61f9SKrishna Gudipati struct bfa_port_attr_s pport_attr; 2217a36c61f9SKrishna Gudipati 22186a18b167SJing Huang memset(port_attr, 0, sizeof(struct bfa_fcs_fdmi_port_attr_s)); 2219a36c61f9SKrishna Gudipati 2220a36c61f9SKrishna Gudipati /* 2221a36c61f9SKrishna Gudipati * get pport attributes from hal 2222a36c61f9SKrishna Gudipati */ 2223a36c61f9SKrishna Gudipati bfa_fcport_get_attr(port->fcs->bfa, &pport_attr); 2224a36c61f9SKrishna Gudipati 2225a36c61f9SKrishna Gudipati /* 2226a36c61f9SKrishna Gudipati * get FC4 type Bitmask 2227a36c61f9SKrishna Gudipati */ 2228a36c61f9SKrishna Gudipati fc_get_fc4type_bitmask(FC_TYPE_FCP, port_attr->supp_fc4_types); 2229a36c61f9SKrishna Gudipati 2230a36c61f9SKrishna Gudipati /* 2231a36c61f9SKrishna Gudipati * Supported Speeds 2232a36c61f9SKrishna Gudipati */ 2233ba816ea8SJing Huang port_attr->supp_speed = cpu_to_be32(BFA_FCS_FDMI_SUPORTED_SPEEDS); 2234a36c61f9SKrishna Gudipati 2235a36c61f9SKrishna Gudipati /* 2236a36c61f9SKrishna Gudipati * Current Speed 2237a36c61f9SKrishna Gudipati */ 2238ba816ea8SJing Huang port_attr->curr_speed = cpu_to_be32(pport_attr.speed); 2239a36c61f9SKrishna Gudipati 2240a36c61f9SKrishna Gudipati /* 2241a36c61f9SKrishna Gudipati * Max PDU Size. 2242a36c61f9SKrishna Gudipati */ 2243ba816ea8SJing Huang port_attr->max_frm_size = cpu_to_be32(FC_MAX_PDUSZ); 2244a36c61f9SKrishna Gudipati 2245a36c61f9SKrishna Gudipati /* 2246a36c61f9SKrishna Gudipati * OS device Name 2247a36c61f9SKrishna Gudipati */ 2248a36c61f9SKrishna Gudipati strncpy(port_attr->os_device_name, (char *)driver_info->os_device_name, 2249a36c61f9SKrishna Gudipati sizeof(port_attr->os_device_name)); 2250a36c61f9SKrishna Gudipati 2251a36c61f9SKrishna Gudipati /* 2252a36c61f9SKrishna Gudipati * Host name 2253a36c61f9SKrishna Gudipati */ 2254a36c61f9SKrishna Gudipati strncpy(port_attr->host_name, (char *)driver_info->host_machine_name, 2255a36c61f9SKrishna Gudipati sizeof(port_attr->host_name)); 22567725ccfdSJing Huang 22577725ccfdSJing Huang } 22587725ccfdSJing Huang 22597725ccfdSJing Huang 2260a36c61f9SKrishna Gudipati void 2261a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_init(struct bfa_fcs_lport_ms_s *ms) 2262a36c61f9SKrishna Gudipati { 2263a36c61f9SKrishna Gudipati struct bfa_fcs_lport_fdmi_s *fdmi = &ms->fdmi; 2264a36c61f9SKrishna Gudipati 2265a36c61f9SKrishna Gudipati fdmi->ms = ms; 2266a36c61f9SKrishna Gudipati if (ms->port->fcs->fdmi_enabled) 2267a36c61f9SKrishna Gudipati bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline); 2268a36c61f9SKrishna Gudipati else 2269a36c61f9SKrishna Gudipati bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_disabled); 2270a36c61f9SKrishna Gudipati } 2271a36c61f9SKrishna Gudipati 2272a36c61f9SKrishna Gudipati void 2273a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_offline(struct bfa_fcs_lport_ms_s *ms) 2274a36c61f9SKrishna Gudipati { 2275a36c61f9SKrishna Gudipati struct bfa_fcs_lport_fdmi_s *fdmi = &ms->fdmi; 2276a36c61f9SKrishna Gudipati 2277a36c61f9SKrishna Gudipati fdmi->ms = ms; 2278a36c61f9SKrishna Gudipati bfa_sm_send_event(fdmi, FDMISM_EVENT_PORT_OFFLINE); 2279a36c61f9SKrishna Gudipati } 2280a36c61f9SKrishna Gudipati 2281a36c61f9SKrishna Gudipati void 2282a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_online(struct bfa_fcs_lport_ms_s *ms) 2283a36c61f9SKrishna Gudipati { 2284a36c61f9SKrishna Gudipati struct bfa_fcs_lport_fdmi_s *fdmi = &ms->fdmi; 2285a36c61f9SKrishna Gudipati 2286a36c61f9SKrishna Gudipati fdmi->ms = ms; 2287a36c61f9SKrishna Gudipati bfa_sm_send_event(fdmi, FDMISM_EVENT_PORT_ONLINE); 2288a36c61f9SKrishna Gudipati } 2289a36c61f9SKrishna Gudipati 2290a36c61f9SKrishna Gudipati #define BFA_FCS_MS_CMD_MAX_RETRIES 2 2291a36c61f9SKrishna Gudipati 2292a36c61f9SKrishna Gudipati /* 2293a36c61f9SKrishna Gudipati * forward declarations 2294a36c61f9SKrishna Gudipati */ 2295a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ms_send_plogi(void *ms_cbarg, 2296a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp_alloced); 2297a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ms_timeout(void *arg); 2298a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ms_plogi_response(void *fcsarg, 2299a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp, 2300a36c61f9SKrishna Gudipati void *cbarg, 2301a36c61f9SKrishna Gudipati bfa_status_t req_status, 2302a36c61f9SKrishna Gudipati u32 rsp_len, 2303a36c61f9SKrishna Gudipati u32 resid_len, 2304a36c61f9SKrishna Gudipati struct fchs_s *rsp_fchs); 2305a36c61f9SKrishna Gudipati 2306a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ms_send_gmal(void *ms_cbarg, 2307a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp_alloced); 2308a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ms_gmal_response(void *fcsarg, 2309a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp, 2310a36c61f9SKrishna Gudipati void *cbarg, 2311a36c61f9SKrishna Gudipati bfa_status_t req_status, 2312a36c61f9SKrishna Gudipati u32 rsp_len, 2313a36c61f9SKrishna Gudipati u32 resid_len, 2314a36c61f9SKrishna Gudipati struct fchs_s *rsp_fchs); 2315a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ms_send_gfn(void *ms_cbarg, 2316a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp_alloced); 2317a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ms_gfn_response(void *fcsarg, 2318a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp, 2319a36c61f9SKrishna Gudipati void *cbarg, 2320a36c61f9SKrishna Gudipati bfa_status_t req_status, 2321a36c61f9SKrishna Gudipati u32 rsp_len, 2322a36c61f9SKrishna Gudipati u32 resid_len, 2323a36c61f9SKrishna Gudipati struct fchs_s *rsp_fchs); 2324a36c61f9SKrishna Gudipati /** 2325a36c61f9SKrishna Gudipati * fcs_ms_sm FCS MS state machine 2326a36c61f9SKrishna Gudipati */ 2327a36c61f9SKrishna Gudipati 2328a36c61f9SKrishna Gudipati /** 2329a36c61f9SKrishna Gudipati * MS State Machine events 2330a36c61f9SKrishna Gudipati */ 2331a36c61f9SKrishna Gudipati enum port_ms_event { 2332a36c61f9SKrishna Gudipati MSSM_EVENT_PORT_ONLINE = 1, 2333a36c61f9SKrishna Gudipati MSSM_EVENT_PORT_OFFLINE = 2, 2334a36c61f9SKrishna Gudipati MSSM_EVENT_RSP_OK = 3, 2335a36c61f9SKrishna Gudipati MSSM_EVENT_RSP_ERROR = 4, 2336a36c61f9SKrishna Gudipati MSSM_EVENT_TIMEOUT = 5, 2337a36c61f9SKrishna Gudipati MSSM_EVENT_FCXP_SENT = 6, 2338a36c61f9SKrishna Gudipati MSSM_EVENT_PORT_FABRIC_RSCN = 7 2339a36c61f9SKrishna Gudipati }; 2340a36c61f9SKrishna Gudipati 2341a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ms_sm_offline(struct bfa_fcs_lport_ms_s *ms, 2342a36c61f9SKrishna Gudipati enum port_ms_event event); 2343a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ms_sm_plogi_sending(struct bfa_fcs_lport_ms_s *ms, 2344a36c61f9SKrishna Gudipati enum port_ms_event event); 2345a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ms_sm_plogi(struct bfa_fcs_lport_ms_s *ms, 2346a36c61f9SKrishna Gudipati enum port_ms_event event); 2347a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ms_sm_plogi_retry(struct bfa_fcs_lport_ms_s *ms, 2348a36c61f9SKrishna Gudipati enum port_ms_event event); 2349a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ms_sm_gmal_sending(struct bfa_fcs_lport_ms_s *ms, 2350a36c61f9SKrishna Gudipati enum port_ms_event event); 2351a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ms_sm_gmal(struct bfa_fcs_lport_ms_s *ms, 2352a36c61f9SKrishna Gudipati enum port_ms_event event); 2353a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ms_sm_gmal_retry(struct bfa_fcs_lport_ms_s *ms, 2354a36c61f9SKrishna Gudipati enum port_ms_event event); 2355a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ms_sm_gfn_sending(struct bfa_fcs_lport_ms_s *ms, 2356a36c61f9SKrishna Gudipati enum port_ms_event event); 2357a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ms_sm_gfn(struct bfa_fcs_lport_ms_s *ms, 2358a36c61f9SKrishna Gudipati enum port_ms_event event); 2359a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ms_sm_gfn_retry(struct bfa_fcs_lport_ms_s *ms, 2360a36c61f9SKrishna Gudipati enum port_ms_event event); 2361a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ms_sm_online(struct bfa_fcs_lport_ms_s *ms, 2362a36c61f9SKrishna Gudipati enum port_ms_event event); 2363a36c61f9SKrishna Gudipati /** 2364a36c61f9SKrishna Gudipati * Start in offline state - awaiting NS to send start. 2365a36c61f9SKrishna Gudipati */ 2366a36c61f9SKrishna Gudipati static void 2367a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_sm_offline(struct bfa_fcs_lport_ms_s *ms, 2368a36c61f9SKrishna Gudipati enum port_ms_event event) 2369a36c61f9SKrishna Gudipati { 2370a36c61f9SKrishna Gudipati bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn); 2371a36c61f9SKrishna Gudipati bfa_trc(ms->port->fcs, event); 2372a36c61f9SKrishna Gudipati 2373a36c61f9SKrishna Gudipati switch (event) { 2374a36c61f9SKrishna Gudipati case MSSM_EVENT_PORT_ONLINE: 2375a36c61f9SKrishna Gudipati bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_plogi_sending); 2376a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_send_plogi(ms, NULL); 2377a36c61f9SKrishna Gudipati break; 2378a36c61f9SKrishna Gudipati 2379a36c61f9SKrishna Gudipati case MSSM_EVENT_PORT_OFFLINE: 2380a36c61f9SKrishna Gudipati break; 2381a36c61f9SKrishna Gudipati 2382a36c61f9SKrishna Gudipati default: 2383a36c61f9SKrishna Gudipati bfa_sm_fault(ms->port->fcs, event); 2384a36c61f9SKrishna Gudipati } 2385a36c61f9SKrishna Gudipati } 2386a36c61f9SKrishna Gudipati 2387a36c61f9SKrishna Gudipati static void 2388a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_sm_plogi_sending(struct bfa_fcs_lport_ms_s *ms, 2389a36c61f9SKrishna Gudipati enum port_ms_event event) 2390a36c61f9SKrishna Gudipati { 2391a36c61f9SKrishna Gudipati bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn); 2392a36c61f9SKrishna Gudipati bfa_trc(ms->port->fcs, event); 2393a36c61f9SKrishna Gudipati 2394a36c61f9SKrishna Gudipati switch (event) { 2395a36c61f9SKrishna Gudipati case MSSM_EVENT_FCXP_SENT: 2396a36c61f9SKrishna Gudipati bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_plogi); 2397a36c61f9SKrishna Gudipati break; 2398a36c61f9SKrishna Gudipati 2399a36c61f9SKrishna Gudipati case MSSM_EVENT_PORT_OFFLINE: 2400a36c61f9SKrishna Gudipati bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_offline); 2401a36c61f9SKrishna Gudipati bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ms->port), 2402a36c61f9SKrishna Gudipati &ms->fcxp_wqe); 2403a36c61f9SKrishna Gudipati break; 2404a36c61f9SKrishna Gudipati 2405a36c61f9SKrishna Gudipati default: 2406a36c61f9SKrishna Gudipati bfa_sm_fault(ms->port->fcs, event); 2407a36c61f9SKrishna Gudipati } 2408a36c61f9SKrishna Gudipati } 2409a36c61f9SKrishna Gudipati 2410a36c61f9SKrishna Gudipati static void 2411a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_sm_plogi(struct bfa_fcs_lport_ms_s *ms, 2412a36c61f9SKrishna Gudipati enum port_ms_event event) 2413a36c61f9SKrishna Gudipati { 2414a36c61f9SKrishna Gudipati bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn); 2415a36c61f9SKrishna Gudipati bfa_trc(ms->port->fcs, event); 2416a36c61f9SKrishna Gudipati 2417a36c61f9SKrishna Gudipati switch (event) { 2418a36c61f9SKrishna Gudipati case MSSM_EVENT_RSP_ERROR: 2419a36c61f9SKrishna Gudipati /* 2420a36c61f9SKrishna Gudipati * Start timer for a delayed retry 2421a36c61f9SKrishna Gudipati */ 2422a36c61f9SKrishna Gudipati bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_plogi_retry); 2423a36c61f9SKrishna Gudipati ms->port->stats.ms_retries++; 2424a36c61f9SKrishna Gudipati bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ms->port), 2425a36c61f9SKrishna Gudipati &ms->timer, bfa_fcs_lport_ms_timeout, ms, 2426a36c61f9SKrishna Gudipati BFA_FCS_RETRY_TIMEOUT); 2427a36c61f9SKrishna Gudipati break; 2428a36c61f9SKrishna Gudipati 2429a36c61f9SKrishna Gudipati case MSSM_EVENT_RSP_OK: 2430a36c61f9SKrishna Gudipati /* 2431a36c61f9SKrishna Gudipati * since plogi is done, now invoke MS related sub-modules 2432a36c61f9SKrishna Gudipati */ 2433a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_online(ms); 2434a36c61f9SKrishna Gudipati 2435a36c61f9SKrishna Gudipati /** 2436a36c61f9SKrishna Gudipati * if this is a Vport, go to online state. 2437a36c61f9SKrishna Gudipati */ 2438a36c61f9SKrishna Gudipati if (ms->port->vport) { 2439a36c61f9SKrishna Gudipati bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_online); 2440a36c61f9SKrishna Gudipati break; 2441a36c61f9SKrishna Gudipati } 2442a36c61f9SKrishna Gudipati 2443a36c61f9SKrishna Gudipati /* 2444a36c61f9SKrishna Gudipati * For a base port we need to get the 2445a36c61f9SKrishna Gudipati * switch's IP address. 2446a36c61f9SKrishna Gudipati */ 2447a36c61f9SKrishna Gudipati bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_gmal_sending); 2448a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_send_gmal(ms, NULL); 2449a36c61f9SKrishna Gudipati break; 2450a36c61f9SKrishna Gudipati 2451a36c61f9SKrishna Gudipati case MSSM_EVENT_PORT_OFFLINE: 2452a36c61f9SKrishna Gudipati bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_offline); 2453a36c61f9SKrishna Gudipati bfa_fcxp_discard(ms->fcxp); 2454a36c61f9SKrishna Gudipati break; 2455a36c61f9SKrishna Gudipati 2456a36c61f9SKrishna Gudipati default: 2457a36c61f9SKrishna Gudipati bfa_sm_fault(ms->port->fcs, event); 2458a36c61f9SKrishna Gudipati } 2459a36c61f9SKrishna Gudipati } 2460a36c61f9SKrishna Gudipati 2461a36c61f9SKrishna Gudipati static void 2462a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_sm_plogi_retry(struct bfa_fcs_lport_ms_s *ms, 2463a36c61f9SKrishna Gudipati enum port_ms_event event) 2464a36c61f9SKrishna Gudipati { 2465a36c61f9SKrishna Gudipati bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn); 2466a36c61f9SKrishna Gudipati bfa_trc(ms->port->fcs, event); 2467a36c61f9SKrishna Gudipati 2468a36c61f9SKrishna Gudipati switch (event) { 2469a36c61f9SKrishna Gudipati case MSSM_EVENT_TIMEOUT: 2470a36c61f9SKrishna Gudipati /* 2471a36c61f9SKrishna Gudipati * Retry Timer Expired. Re-send 2472a36c61f9SKrishna Gudipati */ 2473a36c61f9SKrishna Gudipati bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_plogi_sending); 2474a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_send_plogi(ms, NULL); 2475a36c61f9SKrishna Gudipati break; 2476a36c61f9SKrishna Gudipati 2477a36c61f9SKrishna Gudipati case MSSM_EVENT_PORT_OFFLINE: 2478a36c61f9SKrishna Gudipati bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_offline); 2479a36c61f9SKrishna Gudipati bfa_timer_stop(&ms->timer); 2480a36c61f9SKrishna Gudipati break; 2481a36c61f9SKrishna Gudipati 2482a36c61f9SKrishna Gudipati default: 2483a36c61f9SKrishna Gudipati bfa_sm_fault(ms->port->fcs, event); 2484a36c61f9SKrishna Gudipati } 2485a36c61f9SKrishna Gudipati } 2486a36c61f9SKrishna Gudipati 2487a36c61f9SKrishna Gudipati static void 2488a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_sm_online(struct bfa_fcs_lport_ms_s *ms, 2489a36c61f9SKrishna Gudipati enum port_ms_event event) 2490a36c61f9SKrishna Gudipati { 2491a36c61f9SKrishna Gudipati bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn); 2492a36c61f9SKrishna Gudipati bfa_trc(ms->port->fcs, event); 2493a36c61f9SKrishna Gudipati 2494a36c61f9SKrishna Gudipati switch (event) { 2495a36c61f9SKrishna Gudipati case MSSM_EVENT_PORT_OFFLINE: 2496a36c61f9SKrishna Gudipati bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_offline); 2497a36c61f9SKrishna Gudipati break; 2498a36c61f9SKrishna Gudipati 2499a36c61f9SKrishna Gudipati case MSSM_EVENT_PORT_FABRIC_RSCN: 2500a36c61f9SKrishna Gudipati bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_gfn_sending); 2501a36c61f9SKrishna Gudipati ms->retry_cnt = 0; 2502a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_send_gfn(ms, NULL); 2503a36c61f9SKrishna Gudipati break; 2504a36c61f9SKrishna Gudipati 2505a36c61f9SKrishna Gudipati default: 2506a36c61f9SKrishna Gudipati bfa_sm_fault(ms->port->fcs, event); 2507a36c61f9SKrishna Gudipati } 2508a36c61f9SKrishna Gudipati } 2509a36c61f9SKrishna Gudipati 2510a36c61f9SKrishna Gudipati static void 2511a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_sm_gmal_sending(struct bfa_fcs_lport_ms_s *ms, 2512a36c61f9SKrishna Gudipati enum port_ms_event event) 2513a36c61f9SKrishna Gudipati { 2514a36c61f9SKrishna Gudipati bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn); 2515a36c61f9SKrishna Gudipati bfa_trc(ms->port->fcs, event); 2516a36c61f9SKrishna Gudipati 2517a36c61f9SKrishna Gudipati switch (event) { 2518a36c61f9SKrishna Gudipati case MSSM_EVENT_FCXP_SENT: 2519a36c61f9SKrishna Gudipati bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_gmal); 2520a36c61f9SKrishna Gudipati break; 2521a36c61f9SKrishna Gudipati 2522a36c61f9SKrishna Gudipati case MSSM_EVENT_PORT_OFFLINE: 2523a36c61f9SKrishna Gudipati bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_offline); 2524a36c61f9SKrishna Gudipati bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ms->port), 2525a36c61f9SKrishna Gudipati &ms->fcxp_wqe); 2526a36c61f9SKrishna Gudipati break; 2527a36c61f9SKrishna Gudipati 2528a36c61f9SKrishna Gudipati default: 2529a36c61f9SKrishna Gudipati bfa_sm_fault(ms->port->fcs, event); 2530a36c61f9SKrishna Gudipati } 2531a36c61f9SKrishna Gudipati } 2532a36c61f9SKrishna Gudipati 2533a36c61f9SKrishna Gudipati static void 2534a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_sm_gmal(struct bfa_fcs_lport_ms_s *ms, 2535a36c61f9SKrishna Gudipati enum port_ms_event event) 2536a36c61f9SKrishna Gudipati { 2537a36c61f9SKrishna Gudipati bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn); 2538a36c61f9SKrishna Gudipati bfa_trc(ms->port->fcs, event); 2539a36c61f9SKrishna Gudipati 2540a36c61f9SKrishna Gudipati switch (event) { 2541a36c61f9SKrishna Gudipati case MSSM_EVENT_RSP_ERROR: 2542a36c61f9SKrishna Gudipati /* 2543a36c61f9SKrishna Gudipati * Start timer for a delayed retry 2544a36c61f9SKrishna Gudipati */ 2545a36c61f9SKrishna Gudipati if (ms->retry_cnt++ < BFA_FCS_MS_CMD_MAX_RETRIES) { 2546a36c61f9SKrishna Gudipati bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_gmal_retry); 2547a36c61f9SKrishna Gudipati ms->port->stats.ms_retries++; 2548a36c61f9SKrishna Gudipati bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ms->port), 2549a36c61f9SKrishna Gudipati &ms->timer, bfa_fcs_lport_ms_timeout, ms, 2550a36c61f9SKrishna Gudipati BFA_FCS_RETRY_TIMEOUT); 2551a36c61f9SKrishna Gudipati } else { 2552a36c61f9SKrishna Gudipati bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_gfn_sending); 2553a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_send_gfn(ms, NULL); 2554a36c61f9SKrishna Gudipati ms->retry_cnt = 0; 2555a36c61f9SKrishna Gudipati } 2556a36c61f9SKrishna Gudipati break; 2557a36c61f9SKrishna Gudipati 2558a36c61f9SKrishna Gudipati case MSSM_EVENT_RSP_OK: 2559a36c61f9SKrishna Gudipati bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_gfn_sending); 2560a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_send_gfn(ms, NULL); 2561a36c61f9SKrishna Gudipati break; 2562a36c61f9SKrishna Gudipati 2563a36c61f9SKrishna Gudipati case MSSM_EVENT_PORT_OFFLINE: 2564a36c61f9SKrishna Gudipati bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_offline); 2565a36c61f9SKrishna Gudipati bfa_fcxp_discard(ms->fcxp); 2566a36c61f9SKrishna Gudipati break; 2567a36c61f9SKrishna Gudipati 2568a36c61f9SKrishna Gudipati default: 2569a36c61f9SKrishna Gudipati bfa_sm_fault(ms->port->fcs, event); 2570a36c61f9SKrishna Gudipati } 2571a36c61f9SKrishna Gudipati } 2572a36c61f9SKrishna Gudipati 2573a36c61f9SKrishna Gudipati static void 2574a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_sm_gmal_retry(struct bfa_fcs_lport_ms_s *ms, 2575a36c61f9SKrishna Gudipati enum port_ms_event event) 2576a36c61f9SKrishna Gudipati { 2577a36c61f9SKrishna Gudipati bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn); 2578a36c61f9SKrishna Gudipati bfa_trc(ms->port->fcs, event); 2579a36c61f9SKrishna Gudipati 2580a36c61f9SKrishna Gudipati switch (event) { 2581a36c61f9SKrishna Gudipati case MSSM_EVENT_TIMEOUT: 2582a36c61f9SKrishna Gudipati /* 2583a36c61f9SKrishna Gudipati * Retry Timer Expired. Re-send 2584a36c61f9SKrishna Gudipati */ 2585a36c61f9SKrishna Gudipati bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_gmal_sending); 2586a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_send_gmal(ms, NULL); 2587a36c61f9SKrishna Gudipati break; 2588a36c61f9SKrishna Gudipati 2589a36c61f9SKrishna Gudipati case MSSM_EVENT_PORT_OFFLINE: 2590a36c61f9SKrishna Gudipati bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_offline); 2591a36c61f9SKrishna Gudipati bfa_timer_stop(&ms->timer); 2592a36c61f9SKrishna Gudipati break; 2593a36c61f9SKrishna Gudipati 2594a36c61f9SKrishna Gudipati default: 2595a36c61f9SKrishna Gudipati bfa_sm_fault(ms->port->fcs, event); 2596a36c61f9SKrishna Gudipati } 2597a36c61f9SKrishna Gudipati } 2598a36c61f9SKrishna Gudipati /** 2599a36c61f9SKrishna Gudipati * ms_pvt MS local functions 2600a36c61f9SKrishna Gudipati */ 2601a36c61f9SKrishna Gudipati 2602a36c61f9SKrishna Gudipati static void 2603a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_send_gmal(void *ms_cbarg, struct bfa_fcxp_s *fcxp_alloced) 2604a36c61f9SKrishna Gudipati { 2605a36c61f9SKrishna Gudipati struct bfa_fcs_lport_ms_s *ms = ms_cbarg; 2606a36c61f9SKrishna Gudipati bfa_fcs_lport_t *port = ms->port; 2607a36c61f9SKrishna Gudipati struct fchs_s fchs; 2608a36c61f9SKrishna Gudipati int len; 2609a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp; 2610a36c61f9SKrishna Gudipati 2611a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->pid); 2612a36c61f9SKrishna Gudipati 2613a36c61f9SKrishna Gudipati fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs); 2614a36c61f9SKrishna Gudipati if (!fcxp) { 2615a36c61f9SKrishna Gudipati bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ms->fcxp_wqe, 2616a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_send_gmal, ms); 2617a36c61f9SKrishna Gudipati return; 2618a36c61f9SKrishna Gudipati } 2619a36c61f9SKrishna Gudipati ms->fcxp = fcxp; 2620a36c61f9SKrishna Gudipati 2621a36c61f9SKrishna Gudipati len = fc_gmal_req_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), 2622a36c61f9SKrishna Gudipati bfa_fcs_lport_get_fcid(port), 2623a36c61f9SKrishna Gudipati bfa_lps_get_peer_nwwn(port->fabric->lps)); 2624a36c61f9SKrishna Gudipati 2625a36c61f9SKrishna Gudipati bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, 2626a36c61f9SKrishna Gudipati FC_CLASS_3, len, &fchs, 2627a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_gmal_response, (void *)ms, 2628a36c61f9SKrishna Gudipati FC_MAX_PDUSZ, FC_FCCT_TOV); 2629a36c61f9SKrishna Gudipati 2630a36c61f9SKrishna Gudipati bfa_sm_send_event(ms, MSSM_EVENT_FCXP_SENT); 2631a36c61f9SKrishna Gudipati } 2632a36c61f9SKrishna Gudipati 2633a36c61f9SKrishna Gudipati static void 2634a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_gmal_response(void *fcsarg, struct bfa_fcxp_s *fcxp, 2635a36c61f9SKrishna Gudipati void *cbarg, bfa_status_t req_status, 2636a36c61f9SKrishna Gudipati u32 rsp_len, u32 resid_len, 2637a36c61f9SKrishna Gudipati struct fchs_s *rsp_fchs) 2638a36c61f9SKrishna Gudipati { 2639a36c61f9SKrishna Gudipati struct bfa_fcs_lport_ms_s *ms = (struct bfa_fcs_lport_ms_s *) cbarg; 2640a36c61f9SKrishna Gudipati bfa_fcs_lport_t *port = ms->port; 2641a36c61f9SKrishna Gudipati struct ct_hdr_s *cthdr = NULL; 2642a36c61f9SKrishna Gudipati struct fcgs_gmal_resp_s *gmal_resp; 2643a36c61f9SKrishna Gudipati struct fcgs_gmal_entry_s *gmal_entry; 2644a36c61f9SKrishna Gudipati u32 num_entries; 2645a36c61f9SKrishna Gudipati u8 *rsp_str; 2646a36c61f9SKrishna Gudipati 2647a36c61f9SKrishna Gudipati bfa_trc(port->fcs, req_status); 2648a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 2649a36c61f9SKrishna Gudipati 2650a36c61f9SKrishna Gudipati /* 2651a36c61f9SKrishna Gudipati * Sanity Checks 2652a36c61f9SKrishna Gudipati */ 2653a36c61f9SKrishna Gudipati if (req_status != BFA_STATUS_OK) { 2654a36c61f9SKrishna Gudipati bfa_trc(port->fcs, req_status); 2655a36c61f9SKrishna Gudipati bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR); 2656a36c61f9SKrishna Gudipati return; 2657a36c61f9SKrishna Gudipati } 2658a36c61f9SKrishna Gudipati 2659a36c61f9SKrishna Gudipati cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp); 2660ba816ea8SJing Huang cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code); 2661a36c61f9SKrishna Gudipati 2662a36c61f9SKrishna Gudipati if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) { 2663a36c61f9SKrishna Gudipati gmal_resp = (struct fcgs_gmal_resp_s *)(cthdr + 1); 2664a36c61f9SKrishna Gudipati 2665ba816ea8SJing Huang num_entries = be32_to_cpu(gmal_resp->ms_len); 2666a36c61f9SKrishna Gudipati if (num_entries == 0) { 2667a36c61f9SKrishna Gudipati bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR); 2668a36c61f9SKrishna Gudipati return; 2669a36c61f9SKrishna Gudipati } 2670a36c61f9SKrishna Gudipati /* 2671a36c61f9SKrishna Gudipati * The response could contain multiple Entries. 2672a36c61f9SKrishna Gudipati * Entries for SNMP interface, etc. 2673a36c61f9SKrishna Gudipati * We look for the entry with a telnet prefix. 2674a36c61f9SKrishna Gudipati * First "http://" entry refers to IP addr 2675a36c61f9SKrishna Gudipati */ 2676a36c61f9SKrishna Gudipati 2677a36c61f9SKrishna Gudipati gmal_entry = (struct fcgs_gmal_entry_s *)gmal_resp->ms_ma; 2678a36c61f9SKrishna Gudipati while (num_entries > 0) { 2679a36c61f9SKrishna Gudipati if (strncmp(gmal_entry->prefix, 2680a36c61f9SKrishna Gudipati CT_GMAL_RESP_PREFIX_HTTP, 2681a36c61f9SKrishna Gudipati sizeof(gmal_entry->prefix)) == 0) { 2682a36c61f9SKrishna Gudipati 2683a36c61f9SKrishna Gudipati /* 2684a36c61f9SKrishna Gudipati * if the IP address is terminating with a '/', 2685a36c61f9SKrishna Gudipati * remove it. 2686a36c61f9SKrishna Gudipati * Byte 0 consists of the length of the string. 2687a36c61f9SKrishna Gudipati */ 2688a36c61f9SKrishna Gudipati rsp_str = &(gmal_entry->prefix[0]); 2689a36c61f9SKrishna Gudipati if (rsp_str[gmal_entry->len-1] == '/') 2690a36c61f9SKrishna Gudipati rsp_str[gmal_entry->len-1] = 0; 2691a36c61f9SKrishna Gudipati 2692a36c61f9SKrishna Gudipati /* copy IP Address to fabric */ 2693a36c61f9SKrishna Gudipati strncpy(bfa_fcs_lport_get_fabric_ipaddr(port), 2694a36c61f9SKrishna Gudipati gmal_entry->ip_addr, 2695a36c61f9SKrishna Gudipati BFA_FCS_FABRIC_IPADDR_SZ); 2696a36c61f9SKrishna Gudipati break; 2697a36c61f9SKrishna Gudipati } else { 2698a36c61f9SKrishna Gudipati --num_entries; 2699a36c61f9SKrishna Gudipati ++gmal_entry; 2700a36c61f9SKrishna Gudipati } 2701a36c61f9SKrishna Gudipati } 2702a36c61f9SKrishna Gudipati 2703a36c61f9SKrishna Gudipati bfa_sm_send_event(ms, MSSM_EVENT_RSP_OK); 2704a36c61f9SKrishna Gudipati return; 2705a36c61f9SKrishna Gudipati } 2706a36c61f9SKrishna Gudipati 2707a36c61f9SKrishna Gudipati bfa_trc(port->fcs, cthdr->reason_code); 2708a36c61f9SKrishna Gudipati bfa_trc(port->fcs, cthdr->exp_code); 2709a36c61f9SKrishna Gudipati bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR); 2710a36c61f9SKrishna Gudipati } 2711a36c61f9SKrishna Gudipati 2712a36c61f9SKrishna Gudipati static void 2713a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_sm_gfn_sending(struct bfa_fcs_lport_ms_s *ms, 2714a36c61f9SKrishna Gudipati enum port_ms_event event) 2715a36c61f9SKrishna Gudipati { 2716a36c61f9SKrishna Gudipati bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn); 2717a36c61f9SKrishna Gudipati bfa_trc(ms->port->fcs, event); 2718a36c61f9SKrishna Gudipati 2719a36c61f9SKrishna Gudipati switch (event) { 2720a36c61f9SKrishna Gudipati case MSSM_EVENT_FCXP_SENT: 2721a36c61f9SKrishna Gudipati bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_gfn); 2722a36c61f9SKrishna Gudipati break; 2723a36c61f9SKrishna Gudipati 2724a36c61f9SKrishna Gudipati case MSSM_EVENT_PORT_OFFLINE: 2725a36c61f9SKrishna Gudipati bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_offline); 2726a36c61f9SKrishna Gudipati bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ms->port), 2727a36c61f9SKrishna Gudipati &ms->fcxp_wqe); 2728a36c61f9SKrishna Gudipati break; 2729a36c61f9SKrishna Gudipati 2730a36c61f9SKrishna Gudipati default: 2731a36c61f9SKrishna Gudipati bfa_sm_fault(ms->port->fcs, event); 2732a36c61f9SKrishna Gudipati } 2733a36c61f9SKrishna Gudipati } 2734a36c61f9SKrishna Gudipati 2735a36c61f9SKrishna Gudipati static void 2736a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_sm_gfn(struct bfa_fcs_lport_ms_s *ms, 2737a36c61f9SKrishna Gudipati enum port_ms_event event) 2738a36c61f9SKrishna Gudipati { 2739a36c61f9SKrishna Gudipati bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn); 2740a36c61f9SKrishna Gudipati bfa_trc(ms->port->fcs, event); 2741a36c61f9SKrishna Gudipati 2742a36c61f9SKrishna Gudipati switch (event) { 2743a36c61f9SKrishna Gudipati case MSSM_EVENT_RSP_ERROR: 2744a36c61f9SKrishna Gudipati /* 2745a36c61f9SKrishna Gudipati * Start timer for a delayed retry 2746a36c61f9SKrishna Gudipati */ 2747a36c61f9SKrishna Gudipati if (ms->retry_cnt++ < BFA_FCS_MS_CMD_MAX_RETRIES) { 2748a36c61f9SKrishna Gudipati bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_gfn_retry); 2749a36c61f9SKrishna Gudipati ms->port->stats.ms_retries++; 2750a36c61f9SKrishna Gudipati bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ms->port), 2751a36c61f9SKrishna Gudipati &ms->timer, bfa_fcs_lport_ms_timeout, ms, 2752a36c61f9SKrishna Gudipati BFA_FCS_RETRY_TIMEOUT); 2753a36c61f9SKrishna Gudipati } else { 2754a36c61f9SKrishna Gudipati bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_online); 2755a36c61f9SKrishna Gudipati ms->retry_cnt = 0; 2756a36c61f9SKrishna Gudipati } 2757a36c61f9SKrishna Gudipati break; 2758a36c61f9SKrishna Gudipati 2759a36c61f9SKrishna Gudipati case MSSM_EVENT_RSP_OK: 2760a36c61f9SKrishna Gudipati bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_online); 2761a36c61f9SKrishna Gudipati break; 2762a36c61f9SKrishna Gudipati 2763a36c61f9SKrishna Gudipati case MSSM_EVENT_PORT_OFFLINE: 2764a36c61f9SKrishna Gudipati bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_offline); 2765a36c61f9SKrishna Gudipati bfa_fcxp_discard(ms->fcxp); 2766a36c61f9SKrishna Gudipati break; 2767a36c61f9SKrishna Gudipati 2768a36c61f9SKrishna Gudipati default: 2769a36c61f9SKrishna Gudipati bfa_sm_fault(ms->port->fcs, event); 2770a36c61f9SKrishna Gudipati } 2771a36c61f9SKrishna Gudipati } 2772a36c61f9SKrishna Gudipati 2773a36c61f9SKrishna Gudipati static void 2774a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_sm_gfn_retry(struct bfa_fcs_lport_ms_s *ms, 2775a36c61f9SKrishna Gudipati enum port_ms_event event) 2776a36c61f9SKrishna Gudipati { 2777a36c61f9SKrishna Gudipati bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn); 2778a36c61f9SKrishna Gudipati bfa_trc(ms->port->fcs, event); 2779a36c61f9SKrishna Gudipati 2780a36c61f9SKrishna Gudipati switch (event) { 2781a36c61f9SKrishna Gudipati case MSSM_EVENT_TIMEOUT: 2782a36c61f9SKrishna Gudipati /* 2783a36c61f9SKrishna Gudipati * Retry Timer Expired. Re-send 2784a36c61f9SKrishna Gudipati */ 2785a36c61f9SKrishna Gudipati bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_gfn_sending); 2786a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_send_gfn(ms, NULL); 2787a36c61f9SKrishna Gudipati break; 2788a36c61f9SKrishna Gudipati 2789a36c61f9SKrishna Gudipati case MSSM_EVENT_PORT_OFFLINE: 2790a36c61f9SKrishna Gudipati bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_offline); 2791a36c61f9SKrishna Gudipati bfa_timer_stop(&ms->timer); 2792a36c61f9SKrishna Gudipati break; 2793a36c61f9SKrishna Gudipati 2794a36c61f9SKrishna Gudipati default: 2795a36c61f9SKrishna Gudipati bfa_sm_fault(ms->port->fcs, event); 2796a36c61f9SKrishna Gudipati } 2797a36c61f9SKrishna Gudipati } 2798a36c61f9SKrishna Gudipati /** 2799a36c61f9SKrishna Gudipati * ms_pvt MS local functions 2800a36c61f9SKrishna Gudipati */ 2801a36c61f9SKrishna Gudipati 2802a36c61f9SKrishna Gudipati static void 2803a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_send_gfn(void *ms_cbarg, struct bfa_fcxp_s *fcxp_alloced) 2804a36c61f9SKrishna Gudipati { 2805a36c61f9SKrishna Gudipati struct bfa_fcs_lport_ms_s *ms = ms_cbarg; 2806a36c61f9SKrishna Gudipati bfa_fcs_lport_t *port = ms->port; 2807a36c61f9SKrishna Gudipati struct fchs_s fchs; 2808a36c61f9SKrishna Gudipati int len; 2809a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp; 2810a36c61f9SKrishna Gudipati 2811a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->pid); 2812a36c61f9SKrishna Gudipati 2813a36c61f9SKrishna Gudipati fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs); 2814a36c61f9SKrishna Gudipati if (!fcxp) { 2815a36c61f9SKrishna Gudipati bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ms->fcxp_wqe, 2816a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_send_gfn, ms); 2817a36c61f9SKrishna Gudipati return; 2818a36c61f9SKrishna Gudipati } 2819a36c61f9SKrishna Gudipati ms->fcxp = fcxp; 2820a36c61f9SKrishna Gudipati 2821a36c61f9SKrishna Gudipati len = fc_gfn_req_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), 2822a36c61f9SKrishna Gudipati bfa_fcs_lport_get_fcid(port), 2823a36c61f9SKrishna Gudipati bfa_lps_get_peer_nwwn(port->fabric->lps)); 2824a36c61f9SKrishna Gudipati 2825a36c61f9SKrishna Gudipati bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, 2826a36c61f9SKrishna Gudipati FC_CLASS_3, len, &fchs, 2827a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_gfn_response, (void *)ms, 2828a36c61f9SKrishna Gudipati FC_MAX_PDUSZ, FC_FCCT_TOV); 2829a36c61f9SKrishna Gudipati 2830a36c61f9SKrishna Gudipati bfa_sm_send_event(ms, MSSM_EVENT_FCXP_SENT); 2831a36c61f9SKrishna Gudipati } 2832a36c61f9SKrishna Gudipati 2833a36c61f9SKrishna Gudipati static void 2834a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_gfn_response(void *fcsarg, struct bfa_fcxp_s *fcxp, 2835a36c61f9SKrishna Gudipati void *cbarg, bfa_status_t req_status, u32 rsp_len, 2836a36c61f9SKrishna Gudipati u32 resid_len, struct fchs_s *rsp_fchs) 2837a36c61f9SKrishna Gudipati { 2838a36c61f9SKrishna Gudipati struct bfa_fcs_lport_ms_s *ms = (struct bfa_fcs_lport_ms_s *) cbarg; 2839a36c61f9SKrishna Gudipati bfa_fcs_lport_t *port = ms->port; 2840a36c61f9SKrishna Gudipati struct ct_hdr_s *cthdr = NULL; 2841a36c61f9SKrishna Gudipati wwn_t *gfn_resp; 2842a36c61f9SKrishna Gudipati 2843a36c61f9SKrishna Gudipati bfa_trc(port->fcs, req_status); 2844a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 2845a36c61f9SKrishna Gudipati 2846a36c61f9SKrishna Gudipati /* 2847a36c61f9SKrishna Gudipati * Sanity Checks 2848a36c61f9SKrishna Gudipati */ 2849a36c61f9SKrishna Gudipati if (req_status != BFA_STATUS_OK) { 2850a36c61f9SKrishna Gudipati bfa_trc(port->fcs, req_status); 2851a36c61f9SKrishna Gudipati bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR); 2852a36c61f9SKrishna Gudipati return; 2853a36c61f9SKrishna Gudipati } 2854a36c61f9SKrishna Gudipati 2855a36c61f9SKrishna Gudipati cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp); 2856ba816ea8SJing Huang cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code); 2857a36c61f9SKrishna Gudipati 2858a36c61f9SKrishna Gudipati if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) { 2859a36c61f9SKrishna Gudipati gfn_resp = (wwn_t *)(cthdr + 1); 2860a36c61f9SKrishna Gudipati /* check if it has actually changed */ 2861a36c61f9SKrishna Gudipati if ((memcmp((void *)&bfa_fcs_lport_get_fabric_name(port), 2862a36c61f9SKrishna Gudipati gfn_resp, sizeof(wwn_t)) != 0)) { 2863a36c61f9SKrishna Gudipati bfa_fcs_fabric_set_fabric_name(port->fabric, *gfn_resp); 2864a36c61f9SKrishna Gudipati } 2865a36c61f9SKrishna Gudipati bfa_sm_send_event(ms, MSSM_EVENT_RSP_OK); 2866a36c61f9SKrishna Gudipati return; 2867a36c61f9SKrishna Gudipati } 2868a36c61f9SKrishna Gudipati 2869a36c61f9SKrishna Gudipati bfa_trc(port->fcs, cthdr->reason_code); 2870a36c61f9SKrishna Gudipati bfa_trc(port->fcs, cthdr->exp_code); 2871a36c61f9SKrishna Gudipati bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR); 2872a36c61f9SKrishna Gudipati } 2873a36c61f9SKrishna Gudipati 2874a36c61f9SKrishna Gudipati /** 2875a36c61f9SKrishna Gudipati * ms_pvt MS local functions 2876a36c61f9SKrishna Gudipati */ 2877a36c61f9SKrishna Gudipati 2878a36c61f9SKrishna Gudipati static void 2879a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_send_plogi(void *ms_cbarg, struct bfa_fcxp_s *fcxp_alloced) 2880a36c61f9SKrishna Gudipati { 2881a36c61f9SKrishna Gudipati struct bfa_fcs_lport_ms_s *ms = ms_cbarg; 2882a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = ms->port; 2883a36c61f9SKrishna Gudipati struct fchs_s fchs; 2884a36c61f9SKrishna Gudipati int len; 2885a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp; 2886a36c61f9SKrishna Gudipati 2887a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->pid); 2888a36c61f9SKrishna Gudipati 2889a36c61f9SKrishna Gudipati fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs); 2890a36c61f9SKrishna Gudipati if (!fcxp) { 2891a36c61f9SKrishna Gudipati port->stats.ms_plogi_alloc_wait++; 2892a36c61f9SKrishna Gudipati bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ms->fcxp_wqe, 2893a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_send_plogi, ms); 2894a36c61f9SKrishna Gudipati return; 2895a36c61f9SKrishna Gudipati } 2896a36c61f9SKrishna Gudipati ms->fcxp = fcxp; 2897a36c61f9SKrishna Gudipati 2898a36c61f9SKrishna Gudipati len = fc_plogi_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), 2899a36c61f9SKrishna Gudipati bfa_os_hton3b(FC_MGMT_SERVER), 2900a36c61f9SKrishna Gudipati bfa_fcs_lport_get_fcid(port), 0, 2901a36c61f9SKrishna Gudipati port->port_cfg.pwwn, port->port_cfg.nwwn, 2902a36c61f9SKrishna Gudipati bfa_fcport_get_maxfrsize(port->fcs->bfa)); 2903a36c61f9SKrishna Gudipati 2904a36c61f9SKrishna Gudipati bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, 2905a36c61f9SKrishna Gudipati FC_CLASS_3, len, &fchs, 2906a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_plogi_response, (void *)ms, 2907a36c61f9SKrishna Gudipati FC_MAX_PDUSZ, FC_ELS_TOV); 2908a36c61f9SKrishna Gudipati 2909a36c61f9SKrishna Gudipati port->stats.ms_plogi_sent++; 2910a36c61f9SKrishna Gudipati bfa_sm_send_event(ms, MSSM_EVENT_FCXP_SENT); 2911a36c61f9SKrishna Gudipati } 2912a36c61f9SKrishna Gudipati 2913a36c61f9SKrishna Gudipati static void 2914a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_plogi_response(void *fcsarg, struct bfa_fcxp_s *fcxp, 2915a36c61f9SKrishna Gudipati void *cbarg, bfa_status_t req_status, 2916a36c61f9SKrishna Gudipati u32 rsp_len, u32 resid_len, struct fchs_s *rsp_fchs) 2917a36c61f9SKrishna Gudipati { 2918a36c61f9SKrishna Gudipati struct bfa_fcs_lport_ms_s *ms = (struct bfa_fcs_lport_ms_s *) cbarg; 2919a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = ms->port; 2920a36c61f9SKrishna Gudipati struct fc_els_cmd_s *els_cmd; 2921a36c61f9SKrishna Gudipati struct fc_ls_rjt_s *ls_rjt; 2922a36c61f9SKrishna Gudipati 2923a36c61f9SKrishna Gudipati bfa_trc(port->fcs, req_status); 2924a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 2925a36c61f9SKrishna Gudipati 2926a36c61f9SKrishna Gudipati /* 2927a36c61f9SKrishna Gudipati * Sanity Checks 2928a36c61f9SKrishna Gudipati */ 2929a36c61f9SKrishna Gudipati if (req_status != BFA_STATUS_OK) { 2930a36c61f9SKrishna Gudipati port->stats.ms_plogi_rsp_err++; 2931a36c61f9SKrishna Gudipati bfa_trc(port->fcs, req_status); 2932a36c61f9SKrishna Gudipati bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR); 2933a36c61f9SKrishna Gudipati return; 2934a36c61f9SKrishna Gudipati } 2935a36c61f9SKrishna Gudipati 2936a36c61f9SKrishna Gudipati els_cmd = (struct fc_els_cmd_s *) BFA_FCXP_RSP_PLD(fcxp); 2937a36c61f9SKrishna Gudipati 2938a36c61f9SKrishna Gudipati switch (els_cmd->els_code) { 2939a36c61f9SKrishna Gudipati 2940a36c61f9SKrishna Gudipati case FC_ELS_ACC: 2941a36c61f9SKrishna Gudipati if (rsp_len < sizeof(struct fc_logi_s)) { 2942a36c61f9SKrishna Gudipati bfa_trc(port->fcs, rsp_len); 2943a36c61f9SKrishna Gudipati port->stats.ms_plogi_acc_err++; 2944a36c61f9SKrishna Gudipati bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR); 2945a36c61f9SKrishna Gudipati break; 2946a36c61f9SKrishna Gudipati } 2947a36c61f9SKrishna Gudipati port->stats.ms_plogi_accepts++; 2948a36c61f9SKrishna Gudipati bfa_sm_send_event(ms, MSSM_EVENT_RSP_OK); 2949a36c61f9SKrishna Gudipati break; 2950a36c61f9SKrishna Gudipati 2951a36c61f9SKrishna Gudipati case FC_ELS_LS_RJT: 2952a36c61f9SKrishna Gudipati ls_rjt = (struct fc_ls_rjt_s *) BFA_FCXP_RSP_PLD(fcxp); 2953a36c61f9SKrishna Gudipati 2954a36c61f9SKrishna Gudipati bfa_trc(port->fcs, ls_rjt->reason_code); 2955a36c61f9SKrishna Gudipati bfa_trc(port->fcs, ls_rjt->reason_code_expl); 2956a36c61f9SKrishna Gudipati 2957a36c61f9SKrishna Gudipati port->stats.ms_rejects++; 2958a36c61f9SKrishna Gudipati bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR); 2959a36c61f9SKrishna Gudipati break; 2960a36c61f9SKrishna Gudipati 2961a36c61f9SKrishna Gudipati default: 2962a36c61f9SKrishna Gudipati port->stats.ms_plogi_unknown_rsp++; 2963a36c61f9SKrishna Gudipati bfa_trc(port->fcs, els_cmd->els_code); 2964a36c61f9SKrishna Gudipati bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR); 2965a36c61f9SKrishna Gudipati } 2966a36c61f9SKrishna Gudipati } 2967a36c61f9SKrishna Gudipati 2968a36c61f9SKrishna Gudipati static void 2969a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_timeout(void *arg) 2970a36c61f9SKrishna Gudipati { 2971a36c61f9SKrishna Gudipati struct bfa_fcs_lport_ms_s *ms = (struct bfa_fcs_lport_ms_s *) arg; 2972a36c61f9SKrishna Gudipati 2973a36c61f9SKrishna Gudipati ms->port->stats.ms_timeouts++; 2974a36c61f9SKrishna Gudipati bfa_sm_send_event(ms, MSSM_EVENT_TIMEOUT); 2975a36c61f9SKrishna Gudipati } 2976a36c61f9SKrishna Gudipati 2977a36c61f9SKrishna Gudipati 2978a36c61f9SKrishna Gudipati void 2979a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_init(struct bfa_fcs_lport_s *port) 2980a36c61f9SKrishna Gudipati { 2981a36c61f9SKrishna Gudipati struct bfa_fcs_lport_ms_s *ms = BFA_FCS_GET_MS_FROM_PORT(port); 2982a36c61f9SKrishna Gudipati 2983a36c61f9SKrishna Gudipati ms->port = port; 2984a36c61f9SKrishna Gudipati bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_offline); 2985a36c61f9SKrishna Gudipati 2986a36c61f9SKrishna Gudipati /* 2987a36c61f9SKrishna Gudipati * Invoke init routines of sub modules. 2988a36c61f9SKrishna Gudipati */ 2989a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_init(ms); 2990a36c61f9SKrishna Gudipati } 2991a36c61f9SKrishna Gudipati 2992a36c61f9SKrishna Gudipati void 2993a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_offline(struct bfa_fcs_lport_s *port) 2994a36c61f9SKrishna Gudipati { 2995a36c61f9SKrishna Gudipati struct bfa_fcs_lport_ms_s *ms = BFA_FCS_GET_MS_FROM_PORT(port); 2996a36c61f9SKrishna Gudipati 2997a36c61f9SKrishna Gudipati ms->port = port; 2998a36c61f9SKrishna Gudipati bfa_sm_send_event(ms, MSSM_EVENT_PORT_OFFLINE); 2999a36c61f9SKrishna Gudipati bfa_fcs_lport_fdmi_offline(ms); 3000a36c61f9SKrishna Gudipati } 3001a36c61f9SKrishna Gudipati 3002a36c61f9SKrishna Gudipati void 3003a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_online(struct bfa_fcs_lport_s *port) 3004a36c61f9SKrishna Gudipati { 3005a36c61f9SKrishna Gudipati struct bfa_fcs_lport_ms_s *ms = BFA_FCS_GET_MS_FROM_PORT(port); 3006a36c61f9SKrishna Gudipati 3007a36c61f9SKrishna Gudipati ms->port = port; 3008a36c61f9SKrishna Gudipati bfa_sm_send_event(ms, MSSM_EVENT_PORT_ONLINE); 3009a36c61f9SKrishna Gudipati } 3010a36c61f9SKrishna Gudipati void 3011a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_fabric_rscn(struct bfa_fcs_lport_s *port) 3012a36c61f9SKrishna Gudipati { 3013a36c61f9SKrishna Gudipati struct bfa_fcs_lport_ms_s *ms = BFA_FCS_GET_MS_FROM_PORT(port); 3014a36c61f9SKrishna Gudipati 3015a36c61f9SKrishna Gudipati /* todo. Handle this only when in Online state */ 3016a36c61f9SKrishna Gudipati if (bfa_sm_cmp_state(ms, bfa_fcs_lport_ms_sm_online)) 3017a36c61f9SKrishna Gudipati bfa_sm_send_event(ms, MSSM_EVENT_PORT_FABRIC_RSCN); 3018a36c61f9SKrishna Gudipati } 3019a36c61f9SKrishna Gudipati 3020a36c61f9SKrishna Gudipati /** 3021a36c61f9SKrishna Gudipati * @page ns_sm_info VPORT NS State Machine 3022a36c61f9SKrishna Gudipati * 3023a36c61f9SKrishna Gudipati * @section ns_sm_interactions VPORT NS State Machine Interactions 3024a36c61f9SKrishna Gudipati * 3025a36c61f9SKrishna Gudipati * @section ns_sm VPORT NS State Machine 3026a36c61f9SKrishna Gudipati * img ns_sm.jpg 3027a36c61f9SKrishna Gudipati */ 3028a36c61f9SKrishna Gudipati 3029a36c61f9SKrishna Gudipati /* 3030a36c61f9SKrishna Gudipati * forward declarations 3031a36c61f9SKrishna Gudipati */ 3032a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_send_plogi(void *ns_cbarg, 3033a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp_alloced); 3034a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_send_rspn_id(void *ns_cbarg, 3035a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp_alloced); 3036a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_send_rft_id(void *ns_cbarg, 3037a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp_alloced); 3038a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_send_rff_id(void *ns_cbarg, 3039a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp_alloced); 3040a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_send_gid_ft(void *ns_cbarg, 3041a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp_alloced); 3042a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_timeout(void *arg); 3043a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_plogi_response(void *fcsarg, 3044a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp, 3045a36c61f9SKrishna Gudipati void *cbarg, 3046a36c61f9SKrishna Gudipati bfa_status_t req_status, 3047a36c61f9SKrishna Gudipati u32 rsp_len, 3048a36c61f9SKrishna Gudipati u32 resid_len, 3049a36c61f9SKrishna Gudipati struct fchs_s *rsp_fchs); 3050a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_rspn_id_response(void *fcsarg, 3051a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp, 3052a36c61f9SKrishna Gudipati void *cbarg, 3053a36c61f9SKrishna Gudipati bfa_status_t req_status, 3054a36c61f9SKrishna Gudipati u32 rsp_len, 3055a36c61f9SKrishna Gudipati u32 resid_len, 3056a36c61f9SKrishna Gudipati struct fchs_s *rsp_fchs); 3057a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_rft_id_response(void *fcsarg, 3058a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp, 3059a36c61f9SKrishna Gudipati void *cbarg, 3060a36c61f9SKrishna Gudipati bfa_status_t req_status, 3061a36c61f9SKrishna Gudipati u32 rsp_len, 3062a36c61f9SKrishna Gudipati u32 resid_len, 3063a36c61f9SKrishna Gudipati struct fchs_s *rsp_fchs); 3064a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_rff_id_response(void *fcsarg, 3065a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp, 3066a36c61f9SKrishna Gudipati void *cbarg, 3067a36c61f9SKrishna Gudipati bfa_status_t req_status, 3068a36c61f9SKrishna Gudipati u32 rsp_len, 3069a36c61f9SKrishna Gudipati u32 resid_len, 3070a36c61f9SKrishna Gudipati struct fchs_s *rsp_fchs); 3071a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_gid_ft_response(void *fcsarg, 3072a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp, 3073a36c61f9SKrishna Gudipati void *cbarg, 3074a36c61f9SKrishna Gudipati bfa_status_t req_status, 3075a36c61f9SKrishna Gudipati u32 rsp_len, 3076a36c61f9SKrishna Gudipati u32 resid_len, 3077a36c61f9SKrishna Gudipati struct fchs_s *rsp_fchs); 3078a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_process_gidft_pids( 3079a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port, 3080a36c61f9SKrishna Gudipati u32 *pid_buf, u32 n_pids); 3081a36c61f9SKrishna Gudipati 3082a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_boot_target_disc(bfa_fcs_lport_t *port); 3083a36c61f9SKrishna Gudipati /** 3084a36c61f9SKrishna Gudipati * fcs_ns_sm FCS nameserver interface state machine 3085a36c61f9SKrishna Gudipati */ 3086a36c61f9SKrishna Gudipati 3087a36c61f9SKrishna Gudipati /** 3088a36c61f9SKrishna Gudipati * VPort NS State Machine events 3089a36c61f9SKrishna Gudipati */ 3090a36c61f9SKrishna Gudipati enum vport_ns_event { 3091a36c61f9SKrishna Gudipati NSSM_EVENT_PORT_ONLINE = 1, 3092a36c61f9SKrishna Gudipati NSSM_EVENT_PORT_OFFLINE = 2, 3093a36c61f9SKrishna Gudipati NSSM_EVENT_PLOGI_SENT = 3, 3094a36c61f9SKrishna Gudipati NSSM_EVENT_RSP_OK = 4, 3095a36c61f9SKrishna Gudipati NSSM_EVENT_RSP_ERROR = 5, 3096a36c61f9SKrishna Gudipati NSSM_EVENT_TIMEOUT = 6, 3097a36c61f9SKrishna Gudipati NSSM_EVENT_NS_QUERY = 7, 3098a36c61f9SKrishna Gudipati NSSM_EVENT_RSPNID_SENT = 8, 3099a36c61f9SKrishna Gudipati NSSM_EVENT_RFTID_SENT = 9, 3100a36c61f9SKrishna Gudipati NSSM_EVENT_RFFID_SENT = 10, 3101a36c61f9SKrishna Gudipati NSSM_EVENT_GIDFT_SENT = 11, 3102a36c61f9SKrishna Gudipati }; 3103a36c61f9SKrishna Gudipati 3104a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_sm_offline(struct bfa_fcs_lport_ns_s *ns, 3105a36c61f9SKrishna Gudipati enum vport_ns_event event); 3106a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_sm_plogi_sending(struct bfa_fcs_lport_ns_s *ns, 3107a36c61f9SKrishna Gudipati enum vport_ns_event event); 3108a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_sm_plogi(struct bfa_fcs_lport_ns_s *ns, 3109a36c61f9SKrishna Gudipati enum vport_ns_event event); 3110a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_sm_plogi_retry(struct bfa_fcs_lport_ns_s *ns, 3111a36c61f9SKrishna Gudipati enum vport_ns_event event); 3112a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_sm_sending_rspn_id( 3113a36c61f9SKrishna Gudipati struct bfa_fcs_lport_ns_s *ns, 3114a36c61f9SKrishna Gudipati enum vport_ns_event event); 3115a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_sm_rspn_id(struct bfa_fcs_lport_ns_s *ns, 3116a36c61f9SKrishna Gudipati enum vport_ns_event event); 3117a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_sm_rspn_id_retry(struct bfa_fcs_lport_ns_s *ns, 3118a36c61f9SKrishna Gudipati enum vport_ns_event event); 3119a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_sm_sending_rft_id( 3120a36c61f9SKrishna Gudipati struct bfa_fcs_lport_ns_s *ns, 3121a36c61f9SKrishna Gudipati enum vport_ns_event event); 3122a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_sm_rft_id_retry(struct bfa_fcs_lport_ns_s *ns, 3123a36c61f9SKrishna Gudipati enum vport_ns_event event); 3124a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_sm_rft_id(struct bfa_fcs_lport_ns_s *ns, 3125a36c61f9SKrishna Gudipati enum vport_ns_event event); 3126a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_sm_sending_rff_id( 3127a36c61f9SKrishna Gudipati struct bfa_fcs_lport_ns_s *ns, 3128a36c61f9SKrishna Gudipati enum vport_ns_event event); 3129a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_sm_rff_id_retry(struct bfa_fcs_lport_ns_s *ns, 3130a36c61f9SKrishna Gudipati enum vport_ns_event event); 3131a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_sm_rff_id(struct bfa_fcs_lport_ns_s *ns, 3132a36c61f9SKrishna Gudipati enum vport_ns_event event); 3133a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_sm_sending_gid_ft( 3134a36c61f9SKrishna Gudipati struct bfa_fcs_lport_ns_s *ns, 3135a36c61f9SKrishna Gudipati enum vport_ns_event event); 3136a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_sm_gid_ft(struct bfa_fcs_lport_ns_s *ns, 3137a36c61f9SKrishna Gudipati enum vport_ns_event event); 3138a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_sm_gid_ft_retry(struct bfa_fcs_lport_ns_s *ns, 3139a36c61f9SKrishna Gudipati enum vport_ns_event event); 3140a36c61f9SKrishna Gudipati static void bfa_fcs_lport_ns_sm_online(struct bfa_fcs_lport_ns_s *ns, 3141a36c61f9SKrishna Gudipati enum vport_ns_event event); 3142a36c61f9SKrishna Gudipati /** 3143a36c61f9SKrishna Gudipati * Start in offline state - awaiting linkup 3144a36c61f9SKrishna Gudipati */ 3145a36c61f9SKrishna Gudipati static void 3146a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_sm_offline(struct bfa_fcs_lport_ns_s *ns, 3147a36c61f9SKrishna Gudipati enum vport_ns_event event) 3148a36c61f9SKrishna Gudipati { 3149a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn); 3150a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, event); 3151a36c61f9SKrishna Gudipati 3152a36c61f9SKrishna Gudipati switch (event) { 3153a36c61f9SKrishna Gudipati case NSSM_EVENT_PORT_ONLINE: 3154a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_plogi_sending); 3155a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_send_plogi(ns, NULL); 3156a36c61f9SKrishna Gudipati break; 3157a36c61f9SKrishna Gudipati 3158a36c61f9SKrishna Gudipati case NSSM_EVENT_PORT_OFFLINE: 3159a36c61f9SKrishna Gudipati break; 3160a36c61f9SKrishna Gudipati 3161a36c61f9SKrishna Gudipati default: 3162a36c61f9SKrishna Gudipati bfa_sm_fault(ns->port->fcs, event); 3163a36c61f9SKrishna Gudipati } 3164a36c61f9SKrishna Gudipati } 3165a36c61f9SKrishna Gudipati 3166a36c61f9SKrishna Gudipati static void 3167a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_sm_plogi_sending(struct bfa_fcs_lport_ns_s *ns, 3168a36c61f9SKrishna Gudipati enum vport_ns_event event) 3169a36c61f9SKrishna Gudipati { 3170a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn); 3171a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, event); 3172a36c61f9SKrishna Gudipati 3173a36c61f9SKrishna Gudipati switch (event) { 3174a36c61f9SKrishna Gudipati case NSSM_EVENT_PLOGI_SENT: 3175a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_plogi); 3176a36c61f9SKrishna Gudipati break; 3177a36c61f9SKrishna Gudipati 3178a36c61f9SKrishna Gudipati case NSSM_EVENT_PORT_OFFLINE: 3179a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline); 3180a36c61f9SKrishna Gudipati bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ns->port), 3181a36c61f9SKrishna Gudipati &ns->fcxp_wqe); 3182a36c61f9SKrishna Gudipati break; 3183a36c61f9SKrishna Gudipati 3184a36c61f9SKrishna Gudipati default: 3185a36c61f9SKrishna Gudipati bfa_sm_fault(ns->port->fcs, event); 3186a36c61f9SKrishna Gudipati } 3187a36c61f9SKrishna Gudipati } 3188a36c61f9SKrishna Gudipati 3189a36c61f9SKrishna Gudipati static void 3190a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_sm_plogi(struct bfa_fcs_lport_ns_s *ns, 3191a36c61f9SKrishna Gudipati enum vport_ns_event event) 3192a36c61f9SKrishna Gudipati { 3193a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn); 3194a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, event); 3195a36c61f9SKrishna Gudipati 3196a36c61f9SKrishna Gudipati switch (event) { 3197a36c61f9SKrishna Gudipati case NSSM_EVENT_RSP_ERROR: 3198a36c61f9SKrishna Gudipati /* 3199a36c61f9SKrishna Gudipati * Start timer for a delayed retry 3200a36c61f9SKrishna Gudipati */ 3201a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_plogi_retry); 3202a36c61f9SKrishna Gudipati ns->port->stats.ns_retries++; 3203a36c61f9SKrishna Gudipati bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ns->port), 3204a36c61f9SKrishna Gudipati &ns->timer, bfa_fcs_lport_ns_timeout, ns, 3205a36c61f9SKrishna Gudipati BFA_FCS_RETRY_TIMEOUT); 3206a36c61f9SKrishna Gudipati break; 3207a36c61f9SKrishna Gudipati 3208a36c61f9SKrishna Gudipati case NSSM_EVENT_RSP_OK: 3209a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_sending_rspn_id); 3210a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_send_rspn_id(ns, NULL); 3211a36c61f9SKrishna Gudipati break; 3212a36c61f9SKrishna Gudipati 3213a36c61f9SKrishna Gudipati case NSSM_EVENT_PORT_OFFLINE: 3214a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline); 3215a36c61f9SKrishna Gudipati bfa_fcxp_discard(ns->fcxp); 3216a36c61f9SKrishna Gudipati break; 3217a36c61f9SKrishna Gudipati 3218a36c61f9SKrishna Gudipati default: 3219a36c61f9SKrishna Gudipati bfa_sm_fault(ns->port->fcs, event); 3220a36c61f9SKrishna Gudipati } 3221a36c61f9SKrishna Gudipati } 3222a36c61f9SKrishna Gudipati 3223a36c61f9SKrishna Gudipati static void 3224a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_sm_plogi_retry(struct bfa_fcs_lport_ns_s *ns, 3225a36c61f9SKrishna Gudipati enum vport_ns_event event) 3226a36c61f9SKrishna Gudipati { 3227a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn); 3228a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, event); 3229a36c61f9SKrishna Gudipati 3230a36c61f9SKrishna Gudipati switch (event) { 3231a36c61f9SKrishna Gudipati case NSSM_EVENT_TIMEOUT: 3232a36c61f9SKrishna Gudipati /* 3233a36c61f9SKrishna Gudipati * Retry Timer Expired. Re-send 3234a36c61f9SKrishna Gudipati */ 3235a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_plogi_sending); 3236a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_send_plogi(ns, NULL); 3237a36c61f9SKrishna Gudipati break; 3238a36c61f9SKrishna Gudipati 3239a36c61f9SKrishna Gudipati case NSSM_EVENT_PORT_OFFLINE: 3240a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline); 3241a36c61f9SKrishna Gudipati bfa_timer_stop(&ns->timer); 3242a36c61f9SKrishna Gudipati break; 3243a36c61f9SKrishna Gudipati 3244a36c61f9SKrishna Gudipati default: 3245a36c61f9SKrishna Gudipati bfa_sm_fault(ns->port->fcs, event); 3246a36c61f9SKrishna Gudipati } 3247a36c61f9SKrishna Gudipati } 3248a36c61f9SKrishna Gudipati 3249a36c61f9SKrishna Gudipati static void 3250a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_sm_sending_rspn_id(struct bfa_fcs_lport_ns_s *ns, 3251a36c61f9SKrishna Gudipati enum vport_ns_event event) 3252a36c61f9SKrishna Gudipati { 3253a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn); 3254a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, event); 3255a36c61f9SKrishna Gudipati 3256a36c61f9SKrishna Gudipati switch (event) { 3257a36c61f9SKrishna Gudipati case NSSM_EVENT_RSPNID_SENT: 3258a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_rspn_id); 3259a36c61f9SKrishna Gudipati break; 3260a36c61f9SKrishna Gudipati 3261a36c61f9SKrishna Gudipati case NSSM_EVENT_PORT_OFFLINE: 3262a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline); 3263a36c61f9SKrishna Gudipati bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ns->port), 3264a36c61f9SKrishna Gudipati &ns->fcxp_wqe); 3265a36c61f9SKrishna Gudipati break; 3266a36c61f9SKrishna Gudipati 3267a36c61f9SKrishna Gudipati default: 3268a36c61f9SKrishna Gudipati bfa_sm_fault(ns->port->fcs, event); 3269a36c61f9SKrishna Gudipati } 3270a36c61f9SKrishna Gudipati } 3271a36c61f9SKrishna Gudipati 3272a36c61f9SKrishna Gudipati static void 3273a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_sm_rspn_id(struct bfa_fcs_lport_ns_s *ns, 3274a36c61f9SKrishna Gudipati enum vport_ns_event event) 3275a36c61f9SKrishna Gudipati { 3276a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn); 3277a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, event); 3278a36c61f9SKrishna Gudipati 3279a36c61f9SKrishna Gudipati switch (event) { 3280a36c61f9SKrishna Gudipati case NSSM_EVENT_RSP_ERROR: 3281a36c61f9SKrishna Gudipati /* 3282a36c61f9SKrishna Gudipati * Start timer for a delayed retry 3283a36c61f9SKrishna Gudipati */ 3284a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_rspn_id_retry); 3285a36c61f9SKrishna Gudipati ns->port->stats.ns_retries++; 3286a36c61f9SKrishna Gudipati bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ns->port), 3287a36c61f9SKrishna Gudipati &ns->timer, bfa_fcs_lport_ns_timeout, ns, 3288a36c61f9SKrishna Gudipati BFA_FCS_RETRY_TIMEOUT); 3289a36c61f9SKrishna Gudipati break; 3290a36c61f9SKrishna Gudipati 3291a36c61f9SKrishna Gudipati case NSSM_EVENT_RSP_OK: 3292a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_sending_rft_id); 3293a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_send_rft_id(ns, NULL); 3294a36c61f9SKrishna Gudipati break; 3295a36c61f9SKrishna Gudipati 3296a36c61f9SKrishna Gudipati case NSSM_EVENT_PORT_OFFLINE: 3297a36c61f9SKrishna Gudipati bfa_fcxp_discard(ns->fcxp); 3298a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline); 3299a36c61f9SKrishna Gudipati break; 3300a36c61f9SKrishna Gudipati 3301a36c61f9SKrishna Gudipati default: 3302a36c61f9SKrishna Gudipati bfa_sm_fault(ns->port->fcs, event); 3303a36c61f9SKrishna Gudipati } 3304a36c61f9SKrishna Gudipati } 3305a36c61f9SKrishna Gudipati 3306a36c61f9SKrishna Gudipati static void 3307a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_sm_rspn_id_retry(struct bfa_fcs_lport_ns_s *ns, 3308a36c61f9SKrishna Gudipati enum vport_ns_event event) 3309a36c61f9SKrishna Gudipati { 3310a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn); 3311a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, event); 3312a36c61f9SKrishna Gudipati 3313a36c61f9SKrishna Gudipati switch (event) { 3314a36c61f9SKrishna Gudipati case NSSM_EVENT_TIMEOUT: 3315a36c61f9SKrishna Gudipati /* 3316a36c61f9SKrishna Gudipati * Retry Timer Expired. Re-send 3317a36c61f9SKrishna Gudipati */ 3318a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_sending_rspn_id); 3319a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_send_rspn_id(ns, NULL); 3320a36c61f9SKrishna Gudipati break; 3321a36c61f9SKrishna Gudipati 3322a36c61f9SKrishna Gudipati case NSSM_EVENT_PORT_OFFLINE: 3323a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline); 3324a36c61f9SKrishna Gudipati bfa_timer_stop(&ns->timer); 3325a36c61f9SKrishna Gudipati break; 3326a36c61f9SKrishna Gudipati 3327a36c61f9SKrishna Gudipati default: 3328a36c61f9SKrishna Gudipati bfa_sm_fault(ns->port->fcs, event); 3329a36c61f9SKrishna Gudipati } 3330a36c61f9SKrishna Gudipati } 3331a36c61f9SKrishna Gudipati 3332a36c61f9SKrishna Gudipati static void 3333a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_sm_sending_rft_id(struct bfa_fcs_lport_ns_s *ns, 3334a36c61f9SKrishna Gudipati enum vport_ns_event event) 3335a36c61f9SKrishna Gudipati { 3336a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn); 3337a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, event); 3338a36c61f9SKrishna Gudipati 3339a36c61f9SKrishna Gudipati switch (event) { 3340a36c61f9SKrishna Gudipati case NSSM_EVENT_RFTID_SENT: 3341a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_rft_id); 3342a36c61f9SKrishna Gudipati break; 3343a36c61f9SKrishna Gudipati 3344a36c61f9SKrishna Gudipati case NSSM_EVENT_PORT_OFFLINE: 3345a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline); 3346a36c61f9SKrishna Gudipati bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ns->port), 3347a36c61f9SKrishna Gudipati &ns->fcxp_wqe); 3348a36c61f9SKrishna Gudipati break; 3349a36c61f9SKrishna Gudipati 3350a36c61f9SKrishna Gudipati default: 3351a36c61f9SKrishna Gudipati bfa_sm_fault(ns->port->fcs, event); 3352a36c61f9SKrishna Gudipati } 3353a36c61f9SKrishna Gudipati } 3354a36c61f9SKrishna Gudipati 3355a36c61f9SKrishna Gudipati static void 3356a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_sm_rft_id(struct bfa_fcs_lport_ns_s *ns, 3357a36c61f9SKrishna Gudipati enum vport_ns_event event) 3358a36c61f9SKrishna Gudipati { 3359a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn); 3360a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, event); 3361a36c61f9SKrishna Gudipati 3362a36c61f9SKrishna Gudipati switch (event) { 3363a36c61f9SKrishna Gudipati case NSSM_EVENT_RSP_OK: 3364a36c61f9SKrishna Gudipati /* Now move to register FC4 Features */ 3365a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_sending_rff_id); 3366a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_send_rff_id(ns, NULL); 3367a36c61f9SKrishna Gudipati break; 3368a36c61f9SKrishna Gudipati 3369a36c61f9SKrishna Gudipati case NSSM_EVENT_RSP_ERROR: 3370a36c61f9SKrishna Gudipati /* 3371a36c61f9SKrishna Gudipati * Start timer for a delayed retry 3372a36c61f9SKrishna Gudipati */ 3373a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_rft_id_retry); 3374a36c61f9SKrishna Gudipati ns->port->stats.ns_retries++; 3375a36c61f9SKrishna Gudipati bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ns->port), 3376a36c61f9SKrishna Gudipati &ns->timer, bfa_fcs_lport_ns_timeout, ns, 3377a36c61f9SKrishna Gudipati BFA_FCS_RETRY_TIMEOUT); 3378a36c61f9SKrishna Gudipati break; 3379a36c61f9SKrishna Gudipati 3380a36c61f9SKrishna Gudipati case NSSM_EVENT_PORT_OFFLINE: 3381a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline); 3382a36c61f9SKrishna Gudipati bfa_fcxp_discard(ns->fcxp); 3383a36c61f9SKrishna Gudipati break; 3384a36c61f9SKrishna Gudipati 3385a36c61f9SKrishna Gudipati default: 3386a36c61f9SKrishna Gudipati bfa_sm_fault(ns->port->fcs, event); 3387a36c61f9SKrishna Gudipati } 3388a36c61f9SKrishna Gudipati } 3389a36c61f9SKrishna Gudipati 3390a36c61f9SKrishna Gudipati static void 3391a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_sm_rft_id_retry(struct bfa_fcs_lport_ns_s *ns, 3392a36c61f9SKrishna Gudipati enum vport_ns_event event) 3393a36c61f9SKrishna Gudipati { 3394a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn); 3395a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, event); 3396a36c61f9SKrishna Gudipati 3397a36c61f9SKrishna Gudipati switch (event) { 3398a36c61f9SKrishna Gudipati case NSSM_EVENT_TIMEOUT: 3399a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_sending_rft_id); 3400a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_send_rft_id(ns, NULL); 3401a36c61f9SKrishna Gudipati break; 3402a36c61f9SKrishna Gudipati 3403a36c61f9SKrishna Gudipati case NSSM_EVENT_PORT_OFFLINE: 3404a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline); 3405a36c61f9SKrishna Gudipati bfa_timer_stop(&ns->timer); 3406a36c61f9SKrishna Gudipati break; 3407a36c61f9SKrishna Gudipati 3408a36c61f9SKrishna Gudipati default: 3409a36c61f9SKrishna Gudipati bfa_sm_fault(ns->port->fcs, event); 3410a36c61f9SKrishna Gudipati } 3411a36c61f9SKrishna Gudipati } 3412a36c61f9SKrishna Gudipati 3413a36c61f9SKrishna Gudipati static void 3414a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_sm_sending_rff_id(struct bfa_fcs_lport_ns_s *ns, 3415a36c61f9SKrishna Gudipati enum vport_ns_event event) 3416a36c61f9SKrishna Gudipati { 3417a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn); 3418a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, event); 3419a36c61f9SKrishna Gudipati 3420a36c61f9SKrishna Gudipati switch (event) { 3421a36c61f9SKrishna Gudipati case NSSM_EVENT_RFFID_SENT: 3422a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_rff_id); 3423a36c61f9SKrishna Gudipati break; 3424a36c61f9SKrishna Gudipati 3425a36c61f9SKrishna Gudipati case NSSM_EVENT_PORT_OFFLINE: 3426a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline); 3427a36c61f9SKrishna Gudipati bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ns->port), 3428a36c61f9SKrishna Gudipati &ns->fcxp_wqe); 3429a36c61f9SKrishna Gudipati break; 3430a36c61f9SKrishna Gudipati 3431a36c61f9SKrishna Gudipati default: 3432a36c61f9SKrishna Gudipati bfa_sm_fault(ns->port->fcs, event); 3433a36c61f9SKrishna Gudipati } 3434a36c61f9SKrishna Gudipati } 3435a36c61f9SKrishna Gudipati 3436a36c61f9SKrishna Gudipati static void 3437a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_sm_rff_id(struct bfa_fcs_lport_ns_s *ns, 3438a36c61f9SKrishna Gudipati enum vport_ns_event event) 3439a36c61f9SKrishna Gudipati { 3440a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn); 3441a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, event); 3442a36c61f9SKrishna Gudipati 3443a36c61f9SKrishna Gudipati switch (event) { 3444a36c61f9SKrishna Gudipati case NSSM_EVENT_RSP_OK: 3445a36c61f9SKrishna Gudipati 3446a36c61f9SKrishna Gudipati /* 3447a36c61f9SKrishna Gudipati * If min cfg mode is enabled, we donot initiate rport 3448a36c61f9SKrishna Gudipati * discovery with the fabric. Instead, we will retrieve the 3449a36c61f9SKrishna Gudipati * boot targets from HAL/FW. 3450a36c61f9SKrishna Gudipati */ 3451a36c61f9SKrishna Gudipati if (__fcs_min_cfg(ns->port->fcs)) { 3452a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_boot_target_disc(ns->port); 3453a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_online); 3454a36c61f9SKrishna Gudipati return; 3455a36c61f9SKrishna Gudipati } 3456a36c61f9SKrishna Gudipati 3457a36c61f9SKrishna Gudipati /* 3458a36c61f9SKrishna Gudipati * If the port role is Initiator Mode issue NS query. 3459a36c61f9SKrishna Gudipati * If it is Target Mode, skip this and go to online. 3460a36c61f9SKrishna Gudipati */ 3461a36c61f9SKrishna Gudipati if (BFA_FCS_VPORT_IS_INITIATOR_MODE(ns->port)) { 3462a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, 3463a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_sm_sending_gid_ft); 3464a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_send_gid_ft(ns, NULL); 3465a36c61f9SKrishna Gudipati } 3466a36c61f9SKrishna Gudipati /* 3467a36c61f9SKrishna Gudipati * kick off mgmt srvr state machine 3468a36c61f9SKrishna Gudipati */ 3469a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_online(ns->port); 3470a36c61f9SKrishna Gudipati break; 3471a36c61f9SKrishna Gudipati 3472a36c61f9SKrishna Gudipati case NSSM_EVENT_RSP_ERROR: 3473a36c61f9SKrishna Gudipati /* 3474a36c61f9SKrishna Gudipati * Start timer for a delayed retry 3475a36c61f9SKrishna Gudipati */ 3476a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_rff_id_retry); 3477a36c61f9SKrishna Gudipati ns->port->stats.ns_retries++; 3478a36c61f9SKrishna Gudipati bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ns->port), 3479a36c61f9SKrishna Gudipati &ns->timer, bfa_fcs_lport_ns_timeout, ns, 3480a36c61f9SKrishna Gudipati BFA_FCS_RETRY_TIMEOUT); 3481a36c61f9SKrishna Gudipati break; 3482a36c61f9SKrishna Gudipati 3483a36c61f9SKrishna Gudipati case NSSM_EVENT_PORT_OFFLINE: 3484a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline); 3485a36c61f9SKrishna Gudipati bfa_fcxp_discard(ns->fcxp); 3486a36c61f9SKrishna Gudipati break; 3487a36c61f9SKrishna Gudipati 3488a36c61f9SKrishna Gudipati default: 3489a36c61f9SKrishna Gudipati bfa_sm_fault(ns->port->fcs, event); 3490a36c61f9SKrishna Gudipati } 3491a36c61f9SKrishna Gudipati } 3492a36c61f9SKrishna Gudipati 3493a36c61f9SKrishna Gudipati static void 3494a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_sm_rff_id_retry(struct bfa_fcs_lport_ns_s *ns, 3495a36c61f9SKrishna Gudipati enum vport_ns_event event) 3496a36c61f9SKrishna Gudipati { 3497a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn); 3498a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, event); 3499a36c61f9SKrishna Gudipati 3500a36c61f9SKrishna Gudipati switch (event) { 3501a36c61f9SKrishna Gudipati case NSSM_EVENT_TIMEOUT: 3502a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_sending_rff_id); 3503a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_send_rff_id(ns, NULL); 3504a36c61f9SKrishna Gudipati break; 3505a36c61f9SKrishna Gudipati 3506a36c61f9SKrishna Gudipati case NSSM_EVENT_PORT_OFFLINE: 3507a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline); 3508a36c61f9SKrishna Gudipati bfa_timer_stop(&ns->timer); 3509a36c61f9SKrishna Gudipati break; 3510a36c61f9SKrishna Gudipati 3511a36c61f9SKrishna Gudipati default: 3512a36c61f9SKrishna Gudipati bfa_sm_fault(ns->port->fcs, event); 3513a36c61f9SKrishna Gudipati } 3514a36c61f9SKrishna Gudipati } 3515a36c61f9SKrishna Gudipati static void 3516a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_sm_sending_gid_ft(struct bfa_fcs_lport_ns_s *ns, 3517a36c61f9SKrishna Gudipati enum vport_ns_event event) 3518a36c61f9SKrishna Gudipati { 3519a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn); 3520a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, event); 3521a36c61f9SKrishna Gudipati 3522a36c61f9SKrishna Gudipati switch (event) { 3523a36c61f9SKrishna Gudipati case NSSM_EVENT_GIDFT_SENT: 3524a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_gid_ft); 3525a36c61f9SKrishna Gudipati break; 3526a36c61f9SKrishna Gudipati 3527a36c61f9SKrishna Gudipati case NSSM_EVENT_PORT_OFFLINE: 3528a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline); 3529a36c61f9SKrishna Gudipati bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ns->port), 3530a36c61f9SKrishna Gudipati &ns->fcxp_wqe); 3531a36c61f9SKrishna Gudipati break; 3532a36c61f9SKrishna Gudipati 3533a36c61f9SKrishna Gudipati default: 3534a36c61f9SKrishna Gudipati bfa_sm_fault(ns->port->fcs, event); 3535a36c61f9SKrishna Gudipati } 3536a36c61f9SKrishna Gudipati } 3537a36c61f9SKrishna Gudipati 3538a36c61f9SKrishna Gudipati static void 3539a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_sm_gid_ft(struct bfa_fcs_lport_ns_s *ns, 3540a36c61f9SKrishna Gudipati enum vport_ns_event event) 3541a36c61f9SKrishna Gudipati { 3542a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn); 3543a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, event); 3544a36c61f9SKrishna Gudipati 3545a36c61f9SKrishna Gudipati switch (event) { 3546a36c61f9SKrishna Gudipati case NSSM_EVENT_RSP_OK: 3547a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_online); 3548a36c61f9SKrishna Gudipati break; 3549a36c61f9SKrishna Gudipati 3550a36c61f9SKrishna Gudipati case NSSM_EVENT_RSP_ERROR: 3551a36c61f9SKrishna Gudipati /* 3552a36c61f9SKrishna Gudipati * TBD: for certain reject codes, we don't need to retry 3553a36c61f9SKrishna Gudipati */ 3554a36c61f9SKrishna Gudipati /* 3555a36c61f9SKrishna Gudipati * Start timer for a delayed retry 3556a36c61f9SKrishna Gudipati */ 3557a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_gid_ft_retry); 3558a36c61f9SKrishna Gudipati ns->port->stats.ns_retries++; 3559a36c61f9SKrishna Gudipati bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ns->port), 3560a36c61f9SKrishna Gudipati &ns->timer, bfa_fcs_lport_ns_timeout, ns, 3561a36c61f9SKrishna Gudipati BFA_FCS_RETRY_TIMEOUT); 3562a36c61f9SKrishna Gudipati break; 3563a36c61f9SKrishna Gudipati 3564a36c61f9SKrishna Gudipati case NSSM_EVENT_PORT_OFFLINE: 3565a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline); 3566a36c61f9SKrishna Gudipati bfa_fcxp_discard(ns->fcxp); 3567a36c61f9SKrishna Gudipati break; 3568a36c61f9SKrishna Gudipati 3569a36c61f9SKrishna Gudipati case NSSM_EVENT_NS_QUERY: 3570a36c61f9SKrishna Gudipati break; 3571a36c61f9SKrishna Gudipati 3572a36c61f9SKrishna Gudipati default: 3573a36c61f9SKrishna Gudipati bfa_sm_fault(ns->port->fcs, event); 3574a36c61f9SKrishna Gudipati } 3575a36c61f9SKrishna Gudipati } 3576a36c61f9SKrishna Gudipati 3577a36c61f9SKrishna Gudipati static void 3578a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_sm_gid_ft_retry(struct bfa_fcs_lport_ns_s *ns, 3579a36c61f9SKrishna Gudipati enum vport_ns_event event) 3580a36c61f9SKrishna Gudipati { 3581a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn); 3582a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, event); 3583a36c61f9SKrishna Gudipati 3584a36c61f9SKrishna Gudipati switch (event) { 3585a36c61f9SKrishna Gudipati case NSSM_EVENT_TIMEOUT: 3586a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_sending_gid_ft); 3587a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_send_gid_ft(ns, NULL); 3588a36c61f9SKrishna Gudipati break; 3589a36c61f9SKrishna Gudipati 3590a36c61f9SKrishna Gudipati case NSSM_EVENT_PORT_OFFLINE: 3591a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline); 3592a36c61f9SKrishna Gudipati bfa_timer_stop(&ns->timer); 3593a36c61f9SKrishna Gudipati break; 3594a36c61f9SKrishna Gudipati 3595a36c61f9SKrishna Gudipati default: 3596a36c61f9SKrishna Gudipati bfa_sm_fault(ns->port->fcs, event); 3597a36c61f9SKrishna Gudipati } 3598a36c61f9SKrishna Gudipati } 3599a36c61f9SKrishna Gudipati 3600a36c61f9SKrishna Gudipati static void 3601a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_sm_online(struct bfa_fcs_lport_ns_s *ns, 3602a36c61f9SKrishna Gudipati enum vport_ns_event event) 3603a36c61f9SKrishna Gudipati { 3604a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn); 3605a36c61f9SKrishna Gudipati bfa_trc(ns->port->fcs, event); 3606a36c61f9SKrishna Gudipati 3607a36c61f9SKrishna Gudipati switch (event) { 3608a36c61f9SKrishna Gudipati case NSSM_EVENT_PORT_OFFLINE: 3609a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline); 3610a36c61f9SKrishna Gudipati break; 3611a36c61f9SKrishna Gudipati 3612a36c61f9SKrishna Gudipati case NSSM_EVENT_NS_QUERY: 3613a36c61f9SKrishna Gudipati /* 3614a36c61f9SKrishna Gudipati * If the port role is Initiator Mode issue NS query. 3615a36c61f9SKrishna Gudipati * If it is Target Mode, skip this and go to online. 3616a36c61f9SKrishna Gudipati */ 3617a36c61f9SKrishna Gudipati if (BFA_FCS_VPORT_IS_INITIATOR_MODE(ns->port)) { 3618a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, 3619a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_sm_sending_gid_ft); 3620a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_send_gid_ft(ns, NULL); 3621a36c61f9SKrishna Gudipati }; 3622a36c61f9SKrishna Gudipati break; 3623a36c61f9SKrishna Gudipati 3624a36c61f9SKrishna Gudipati default: 3625a36c61f9SKrishna Gudipati bfa_sm_fault(ns->port->fcs, event); 3626a36c61f9SKrishna Gudipati } 3627a36c61f9SKrishna Gudipati } 3628a36c61f9SKrishna Gudipati 3629a36c61f9SKrishna Gudipati 3630a36c61f9SKrishna Gudipati 3631a36c61f9SKrishna Gudipati /** 3632a36c61f9SKrishna Gudipati * ns_pvt Nameserver local functions 3633a36c61f9SKrishna Gudipati */ 3634a36c61f9SKrishna Gudipati 3635a36c61f9SKrishna Gudipati static void 3636a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_send_plogi(void *ns_cbarg, struct bfa_fcxp_s *fcxp_alloced) 3637a36c61f9SKrishna Gudipati { 3638a36c61f9SKrishna Gudipati struct bfa_fcs_lport_ns_s *ns = ns_cbarg; 3639a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = ns->port; 3640a36c61f9SKrishna Gudipati struct fchs_s fchs; 3641a36c61f9SKrishna Gudipati int len; 3642a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp; 3643a36c61f9SKrishna Gudipati 3644a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->pid); 3645a36c61f9SKrishna Gudipati 3646a36c61f9SKrishna Gudipati fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs); 3647a36c61f9SKrishna Gudipati if (!fcxp) { 3648a36c61f9SKrishna Gudipati port->stats.ns_plogi_alloc_wait++; 3649a36c61f9SKrishna Gudipati bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ns->fcxp_wqe, 3650a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_send_plogi, ns); 3651a36c61f9SKrishna Gudipati return; 3652a36c61f9SKrishna Gudipati } 3653a36c61f9SKrishna Gudipati ns->fcxp = fcxp; 3654a36c61f9SKrishna Gudipati 3655a36c61f9SKrishna Gudipati len = fc_plogi_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), 3656a36c61f9SKrishna Gudipati bfa_os_hton3b(FC_NAME_SERVER), 3657a36c61f9SKrishna Gudipati bfa_fcs_lport_get_fcid(port), 0, 3658a36c61f9SKrishna Gudipati port->port_cfg.pwwn, port->port_cfg.nwwn, 3659a36c61f9SKrishna Gudipati bfa_fcport_get_maxfrsize(port->fcs->bfa)); 3660a36c61f9SKrishna Gudipati 3661a36c61f9SKrishna Gudipati bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, 3662a36c61f9SKrishna Gudipati FC_CLASS_3, len, &fchs, 3663a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_plogi_response, (void *)ns, 3664a36c61f9SKrishna Gudipati FC_MAX_PDUSZ, FC_ELS_TOV); 3665a36c61f9SKrishna Gudipati port->stats.ns_plogi_sent++; 3666a36c61f9SKrishna Gudipati 3667a36c61f9SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_PLOGI_SENT); 3668a36c61f9SKrishna Gudipati } 3669a36c61f9SKrishna Gudipati 3670a36c61f9SKrishna Gudipati static void 3671a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_plogi_response(void *fcsarg, struct bfa_fcxp_s *fcxp, 3672a36c61f9SKrishna Gudipati void *cbarg, bfa_status_t req_status, u32 rsp_len, 3673a36c61f9SKrishna Gudipati u32 resid_len, struct fchs_s *rsp_fchs) 3674a36c61f9SKrishna Gudipati { 3675a36c61f9SKrishna Gudipati struct bfa_fcs_lport_ns_s *ns = (struct bfa_fcs_lport_ns_s *) cbarg; 3676a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = ns->port; 3677a36c61f9SKrishna Gudipati /* struct fc_logi_s *plogi_resp; */ 3678a36c61f9SKrishna Gudipati struct fc_els_cmd_s *els_cmd; 3679a36c61f9SKrishna Gudipati struct fc_ls_rjt_s *ls_rjt; 3680a36c61f9SKrishna Gudipati 3681a36c61f9SKrishna Gudipati bfa_trc(port->fcs, req_status); 3682a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 3683a36c61f9SKrishna Gudipati 3684a36c61f9SKrishna Gudipati /* 3685a36c61f9SKrishna Gudipati * Sanity Checks 3686a36c61f9SKrishna Gudipati */ 3687a36c61f9SKrishna Gudipati if (req_status != BFA_STATUS_OK) { 3688a36c61f9SKrishna Gudipati bfa_trc(port->fcs, req_status); 3689a36c61f9SKrishna Gudipati port->stats.ns_plogi_rsp_err++; 3690a36c61f9SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR); 3691a36c61f9SKrishna Gudipati return; 3692a36c61f9SKrishna Gudipati } 3693a36c61f9SKrishna Gudipati 3694a36c61f9SKrishna Gudipati els_cmd = (struct fc_els_cmd_s *) BFA_FCXP_RSP_PLD(fcxp); 3695a36c61f9SKrishna Gudipati 3696a36c61f9SKrishna Gudipati switch (els_cmd->els_code) { 3697a36c61f9SKrishna Gudipati 3698a36c61f9SKrishna Gudipati case FC_ELS_ACC: 3699a36c61f9SKrishna Gudipati if (rsp_len < sizeof(struct fc_logi_s)) { 3700a36c61f9SKrishna Gudipati bfa_trc(port->fcs, rsp_len); 3701a36c61f9SKrishna Gudipati port->stats.ns_plogi_acc_err++; 3702a36c61f9SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR); 3703a36c61f9SKrishna Gudipati break; 3704a36c61f9SKrishna Gudipati } 3705a36c61f9SKrishna Gudipati port->stats.ns_plogi_accepts++; 3706a36c61f9SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_RSP_OK); 3707a36c61f9SKrishna Gudipati break; 3708a36c61f9SKrishna Gudipati 3709a36c61f9SKrishna Gudipati case FC_ELS_LS_RJT: 3710a36c61f9SKrishna Gudipati ls_rjt = (struct fc_ls_rjt_s *) BFA_FCXP_RSP_PLD(fcxp); 3711a36c61f9SKrishna Gudipati 3712a36c61f9SKrishna Gudipati bfa_trc(port->fcs, ls_rjt->reason_code); 3713a36c61f9SKrishna Gudipati bfa_trc(port->fcs, ls_rjt->reason_code_expl); 3714a36c61f9SKrishna Gudipati 3715a36c61f9SKrishna Gudipati port->stats.ns_rejects++; 3716a36c61f9SKrishna Gudipati 3717a36c61f9SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR); 3718a36c61f9SKrishna Gudipati break; 3719a36c61f9SKrishna Gudipati 3720a36c61f9SKrishna Gudipati default: 3721a36c61f9SKrishna Gudipati port->stats.ns_plogi_unknown_rsp++; 3722a36c61f9SKrishna Gudipati bfa_trc(port->fcs, els_cmd->els_code); 3723a36c61f9SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR); 3724a36c61f9SKrishna Gudipati } 3725a36c61f9SKrishna Gudipati } 3726a36c61f9SKrishna Gudipati 3727a36c61f9SKrishna Gudipati /** 3728a36c61f9SKrishna Gudipati * Register the symbolic port name. 3729a36c61f9SKrishna Gudipati */ 3730a36c61f9SKrishna Gudipati static void 3731a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_send_rspn_id(void *ns_cbarg, struct bfa_fcxp_s *fcxp_alloced) 3732a36c61f9SKrishna Gudipati { 3733a36c61f9SKrishna Gudipati struct bfa_fcs_lport_ns_s *ns = ns_cbarg; 3734a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = ns->port; 3735a36c61f9SKrishna Gudipati struct fchs_s fchs; 3736a36c61f9SKrishna Gudipati int len; 3737a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp; 3738a36c61f9SKrishna Gudipati u8 symbl[256]; 3739a36c61f9SKrishna Gudipati u8 *psymbl = &symbl[0]; 3740a36c61f9SKrishna Gudipati 37416a18b167SJing Huang memset(symbl, 0, sizeof(symbl)); 3742a36c61f9SKrishna Gudipati 3743a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 3744a36c61f9SKrishna Gudipati 3745a36c61f9SKrishna Gudipati fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs); 3746a36c61f9SKrishna Gudipati if (!fcxp) { 3747a36c61f9SKrishna Gudipati port->stats.ns_rspnid_alloc_wait++; 3748a36c61f9SKrishna Gudipati bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ns->fcxp_wqe, 3749a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_send_rspn_id, ns); 3750a36c61f9SKrishna Gudipati return; 3751a36c61f9SKrishna Gudipati } 3752a36c61f9SKrishna Gudipati ns->fcxp = fcxp; 3753a36c61f9SKrishna Gudipati 3754a36c61f9SKrishna Gudipati /* 3755a36c61f9SKrishna Gudipati * for V-Port, form a Port Symbolic Name 3756a36c61f9SKrishna Gudipati */ 3757a36c61f9SKrishna Gudipati if (port->vport) { 3758a36c61f9SKrishna Gudipati /** 3759a36c61f9SKrishna Gudipati * For Vports, we append the vport's port symbolic name 3760a36c61f9SKrishna Gudipati * to that of the base port. 3761a36c61f9SKrishna Gudipati */ 3762a36c61f9SKrishna Gudipati 3763a36c61f9SKrishna Gudipati strncpy((char *)psymbl, 3764a36c61f9SKrishna Gudipati (char *) & 3765a36c61f9SKrishna Gudipati (bfa_fcs_lport_get_psym_name 3766a36c61f9SKrishna Gudipati (bfa_fcs_get_base_port(port->fcs))), 3767a36c61f9SKrishna Gudipati strlen((char *) & 3768a36c61f9SKrishna Gudipati bfa_fcs_lport_get_psym_name(bfa_fcs_get_base_port 3769a36c61f9SKrishna Gudipati (port->fcs)))); 3770a36c61f9SKrishna Gudipati 3771a36c61f9SKrishna Gudipati /* Ensure we have a null terminating string. */ 3772a36c61f9SKrishna Gudipati ((char *)psymbl)[strlen((char *) & 3773a36c61f9SKrishna Gudipati bfa_fcs_lport_get_psym_name(bfa_fcs_get_base_port 3774a36c61f9SKrishna Gudipati (port->fcs)))] = 0; 3775a36c61f9SKrishna Gudipati strncat((char *)psymbl, 3776a36c61f9SKrishna Gudipati (char *) &(bfa_fcs_lport_get_psym_name(port)), 3777a36c61f9SKrishna Gudipati strlen((char *) &bfa_fcs_lport_get_psym_name(port))); 3778a36c61f9SKrishna Gudipati } else { 3779a36c61f9SKrishna Gudipati psymbl = (u8 *) &(bfa_fcs_lport_get_psym_name(port)); 3780a36c61f9SKrishna Gudipati } 3781a36c61f9SKrishna Gudipati 3782a36c61f9SKrishna Gudipati len = fc_rspnid_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), 3783a36c61f9SKrishna Gudipati bfa_fcs_lport_get_fcid(port), 0, psymbl); 3784a36c61f9SKrishna Gudipati 3785a36c61f9SKrishna Gudipati bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, 3786a36c61f9SKrishna Gudipati FC_CLASS_3, len, &fchs, 3787a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_rspn_id_response, (void *)ns, 3788a36c61f9SKrishna Gudipati FC_MAX_PDUSZ, FC_FCCT_TOV); 3789a36c61f9SKrishna Gudipati 3790a36c61f9SKrishna Gudipati port->stats.ns_rspnid_sent++; 3791a36c61f9SKrishna Gudipati 3792a36c61f9SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_RSPNID_SENT); 3793a36c61f9SKrishna Gudipati } 3794a36c61f9SKrishna Gudipati 3795a36c61f9SKrishna Gudipati static void 3796a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_rspn_id_response(void *fcsarg, struct bfa_fcxp_s *fcxp, 3797a36c61f9SKrishna Gudipati void *cbarg, bfa_status_t req_status, 3798a36c61f9SKrishna Gudipati u32 rsp_len, u32 resid_len, 3799a36c61f9SKrishna Gudipati struct fchs_s *rsp_fchs) 3800a36c61f9SKrishna Gudipati { 3801a36c61f9SKrishna Gudipati struct bfa_fcs_lport_ns_s *ns = (struct bfa_fcs_lport_ns_s *) cbarg; 3802a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = ns->port; 3803a36c61f9SKrishna Gudipati struct ct_hdr_s *cthdr = NULL; 3804a36c61f9SKrishna Gudipati 3805a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 3806a36c61f9SKrishna Gudipati 3807a36c61f9SKrishna Gudipati /* 3808a36c61f9SKrishna Gudipati * Sanity Checks 3809a36c61f9SKrishna Gudipati */ 3810a36c61f9SKrishna Gudipati if (req_status != BFA_STATUS_OK) { 3811a36c61f9SKrishna Gudipati bfa_trc(port->fcs, req_status); 3812a36c61f9SKrishna Gudipati port->stats.ns_rspnid_rsp_err++; 3813a36c61f9SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR); 3814a36c61f9SKrishna Gudipati return; 3815a36c61f9SKrishna Gudipati } 3816a36c61f9SKrishna Gudipati 3817a36c61f9SKrishna Gudipati cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp); 3818ba816ea8SJing Huang cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code); 3819a36c61f9SKrishna Gudipati 3820a36c61f9SKrishna Gudipati if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) { 3821a36c61f9SKrishna Gudipati port->stats.ns_rspnid_accepts++; 3822a36c61f9SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_RSP_OK); 3823a36c61f9SKrishna Gudipati return; 3824a36c61f9SKrishna Gudipati } 3825a36c61f9SKrishna Gudipati 3826a36c61f9SKrishna Gudipati port->stats.ns_rspnid_rejects++; 3827a36c61f9SKrishna Gudipati bfa_trc(port->fcs, cthdr->reason_code); 3828a36c61f9SKrishna Gudipati bfa_trc(port->fcs, cthdr->exp_code); 3829a36c61f9SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR); 3830a36c61f9SKrishna Gudipati } 3831a36c61f9SKrishna Gudipati 3832a36c61f9SKrishna Gudipati /** 3833a36c61f9SKrishna Gudipati * Register FC4-Types 3834a36c61f9SKrishna Gudipati */ 3835a36c61f9SKrishna Gudipati static void 3836a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_send_rft_id(void *ns_cbarg, struct bfa_fcxp_s *fcxp_alloced) 3837a36c61f9SKrishna Gudipati { 3838a36c61f9SKrishna Gudipati struct bfa_fcs_lport_ns_s *ns = ns_cbarg; 3839a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = ns->port; 3840a36c61f9SKrishna Gudipati struct fchs_s fchs; 3841a36c61f9SKrishna Gudipati int len; 3842a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp; 3843a36c61f9SKrishna Gudipati 3844a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 3845a36c61f9SKrishna Gudipati 3846a36c61f9SKrishna Gudipati fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs); 3847a36c61f9SKrishna Gudipati if (!fcxp) { 3848a36c61f9SKrishna Gudipati port->stats.ns_rftid_alloc_wait++; 3849a36c61f9SKrishna Gudipati bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ns->fcxp_wqe, 3850a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_send_rft_id, ns); 3851a36c61f9SKrishna Gudipati return; 3852a36c61f9SKrishna Gudipati } 3853a36c61f9SKrishna Gudipati ns->fcxp = fcxp; 3854a36c61f9SKrishna Gudipati 3855a36c61f9SKrishna Gudipati len = fc_rftid_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), 3856a36c61f9SKrishna Gudipati bfa_fcs_lport_get_fcid(port), 0, port->port_cfg.roles); 3857a36c61f9SKrishna Gudipati 3858a36c61f9SKrishna Gudipati bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, 3859a36c61f9SKrishna Gudipati FC_CLASS_3, len, &fchs, 3860a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_rft_id_response, (void *)ns, 3861a36c61f9SKrishna Gudipati FC_MAX_PDUSZ, FC_FCCT_TOV); 3862a36c61f9SKrishna Gudipati 3863a36c61f9SKrishna Gudipati port->stats.ns_rftid_sent++; 3864a36c61f9SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_RFTID_SENT); 3865a36c61f9SKrishna Gudipati } 3866a36c61f9SKrishna Gudipati 3867a36c61f9SKrishna Gudipati static void 3868a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_rft_id_response(void *fcsarg, struct bfa_fcxp_s *fcxp, 3869a36c61f9SKrishna Gudipati void *cbarg, bfa_status_t req_status, 3870a36c61f9SKrishna Gudipati u32 rsp_len, u32 resid_len, 3871a36c61f9SKrishna Gudipati struct fchs_s *rsp_fchs) 3872a36c61f9SKrishna Gudipati { 3873a36c61f9SKrishna Gudipati struct bfa_fcs_lport_ns_s *ns = (struct bfa_fcs_lport_ns_s *) cbarg; 3874a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = ns->port; 3875a36c61f9SKrishna Gudipati struct ct_hdr_s *cthdr = NULL; 3876a36c61f9SKrishna Gudipati 3877a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 3878a36c61f9SKrishna Gudipati 3879a36c61f9SKrishna Gudipati /* 3880a36c61f9SKrishna Gudipati * Sanity Checks 3881a36c61f9SKrishna Gudipati */ 3882a36c61f9SKrishna Gudipati if (req_status != BFA_STATUS_OK) { 3883a36c61f9SKrishna Gudipati bfa_trc(port->fcs, req_status); 3884a36c61f9SKrishna Gudipati port->stats.ns_rftid_rsp_err++; 3885a36c61f9SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR); 3886a36c61f9SKrishna Gudipati return; 3887a36c61f9SKrishna Gudipati } 3888a36c61f9SKrishna Gudipati 3889a36c61f9SKrishna Gudipati cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp); 3890ba816ea8SJing Huang cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code); 3891a36c61f9SKrishna Gudipati 3892a36c61f9SKrishna Gudipati if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) { 3893a36c61f9SKrishna Gudipati port->stats.ns_rftid_accepts++; 3894a36c61f9SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_RSP_OK); 3895a36c61f9SKrishna Gudipati return; 3896a36c61f9SKrishna Gudipati } 3897a36c61f9SKrishna Gudipati 3898a36c61f9SKrishna Gudipati port->stats.ns_rftid_rejects++; 3899a36c61f9SKrishna Gudipati bfa_trc(port->fcs, cthdr->reason_code); 3900a36c61f9SKrishna Gudipati bfa_trc(port->fcs, cthdr->exp_code); 3901a36c61f9SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR); 3902a36c61f9SKrishna Gudipati } 3903a36c61f9SKrishna Gudipati 3904a36c61f9SKrishna Gudipati /** 3905a36c61f9SKrishna Gudipati * Register FC4-Features : Should be done after RFT_ID 3906a36c61f9SKrishna Gudipati */ 3907a36c61f9SKrishna Gudipati static void 3908a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_send_rff_id(void *ns_cbarg, struct bfa_fcxp_s *fcxp_alloced) 3909a36c61f9SKrishna Gudipati { 3910a36c61f9SKrishna Gudipati struct bfa_fcs_lport_ns_s *ns = ns_cbarg; 3911a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = ns->port; 3912a36c61f9SKrishna Gudipati struct fchs_s fchs; 3913a36c61f9SKrishna Gudipati int len; 3914a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp; 3915a36c61f9SKrishna Gudipati u8 fc4_ftrs = 0; 3916a36c61f9SKrishna Gudipati 3917a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 3918a36c61f9SKrishna Gudipati 3919a36c61f9SKrishna Gudipati fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs); 3920a36c61f9SKrishna Gudipati if (!fcxp) { 3921a36c61f9SKrishna Gudipati port->stats.ns_rffid_alloc_wait++; 3922a36c61f9SKrishna Gudipati bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ns->fcxp_wqe, 3923a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_send_rff_id, ns); 3924a36c61f9SKrishna Gudipati return; 3925a36c61f9SKrishna Gudipati } 3926a36c61f9SKrishna Gudipati ns->fcxp = fcxp; 3927a36c61f9SKrishna Gudipati 3928a36c61f9SKrishna Gudipati if (BFA_FCS_VPORT_IS_INITIATOR_MODE(ns->port)) 3929a36c61f9SKrishna Gudipati fc4_ftrs = FC_GS_FCP_FC4_FEATURE_INITIATOR; 3930a36c61f9SKrishna Gudipati 3931a36c61f9SKrishna Gudipati len = fc_rffid_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), 3932a36c61f9SKrishna Gudipati bfa_fcs_lport_get_fcid(port), 0, 3933a36c61f9SKrishna Gudipati FC_TYPE_FCP, fc4_ftrs); 3934a36c61f9SKrishna Gudipati 3935a36c61f9SKrishna Gudipati bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, 3936a36c61f9SKrishna Gudipati FC_CLASS_3, len, &fchs, 3937a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_rff_id_response, (void *)ns, 3938a36c61f9SKrishna Gudipati FC_MAX_PDUSZ, FC_FCCT_TOV); 3939a36c61f9SKrishna Gudipati 3940a36c61f9SKrishna Gudipati port->stats.ns_rffid_sent++; 3941a36c61f9SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_RFFID_SENT); 3942a36c61f9SKrishna Gudipati } 3943a36c61f9SKrishna Gudipati 3944a36c61f9SKrishna Gudipati static void 3945a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_rff_id_response(void *fcsarg, struct bfa_fcxp_s *fcxp, 3946a36c61f9SKrishna Gudipati void *cbarg, bfa_status_t req_status, 3947a36c61f9SKrishna Gudipati u32 rsp_len, u32 resid_len, 3948a36c61f9SKrishna Gudipati struct fchs_s *rsp_fchs) 3949a36c61f9SKrishna Gudipati { 3950a36c61f9SKrishna Gudipati struct bfa_fcs_lport_ns_s *ns = (struct bfa_fcs_lport_ns_s *) cbarg; 3951a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = ns->port; 3952a36c61f9SKrishna Gudipati struct ct_hdr_s *cthdr = NULL; 3953a36c61f9SKrishna Gudipati 3954a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 3955a36c61f9SKrishna Gudipati 3956a36c61f9SKrishna Gudipati /* 3957a36c61f9SKrishna Gudipati * Sanity Checks 3958a36c61f9SKrishna Gudipati */ 3959a36c61f9SKrishna Gudipati if (req_status != BFA_STATUS_OK) { 3960a36c61f9SKrishna Gudipati bfa_trc(port->fcs, req_status); 3961a36c61f9SKrishna Gudipati port->stats.ns_rffid_rsp_err++; 3962a36c61f9SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR); 3963a36c61f9SKrishna Gudipati return; 3964a36c61f9SKrishna Gudipati } 3965a36c61f9SKrishna Gudipati 3966a36c61f9SKrishna Gudipati cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp); 3967ba816ea8SJing Huang cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code); 3968a36c61f9SKrishna Gudipati 3969a36c61f9SKrishna Gudipati if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) { 3970a36c61f9SKrishna Gudipati port->stats.ns_rffid_accepts++; 3971a36c61f9SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_RSP_OK); 3972a36c61f9SKrishna Gudipati return; 3973a36c61f9SKrishna Gudipati } 3974a36c61f9SKrishna Gudipati 3975a36c61f9SKrishna Gudipati port->stats.ns_rffid_rejects++; 3976a36c61f9SKrishna Gudipati bfa_trc(port->fcs, cthdr->reason_code); 3977a36c61f9SKrishna Gudipati bfa_trc(port->fcs, cthdr->exp_code); 3978a36c61f9SKrishna Gudipati 3979a36c61f9SKrishna Gudipati if (cthdr->reason_code == CT_RSN_NOT_SUPP) { 3980a36c61f9SKrishna Gudipati /* if this command is not supported, we don't retry */ 3981a36c61f9SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_RSP_OK); 3982a36c61f9SKrishna Gudipati } else 3983a36c61f9SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR); 3984a36c61f9SKrishna Gudipati } 3985a36c61f9SKrishna Gudipati /** 3986a36c61f9SKrishna Gudipati * Query Fabric for FC4-Types Devices. 3987a36c61f9SKrishna Gudipati * 3988a36c61f9SKrishna Gudipati * TBD : Need to use a local (FCS private) response buffer, since the response 3989a36c61f9SKrishna Gudipati * can be larger than 2K. 3990a36c61f9SKrishna Gudipati */ 3991a36c61f9SKrishna Gudipati static void 3992a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_send_gid_ft(void *ns_cbarg, struct bfa_fcxp_s *fcxp_alloced) 3993a36c61f9SKrishna Gudipati { 3994a36c61f9SKrishna Gudipati struct bfa_fcs_lport_ns_s *ns = ns_cbarg; 3995a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = ns->port; 3996a36c61f9SKrishna Gudipati struct fchs_s fchs; 3997a36c61f9SKrishna Gudipati int len; 3998a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp; 3999a36c61f9SKrishna Gudipati 4000a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->pid); 4001a36c61f9SKrishna Gudipati 4002a36c61f9SKrishna Gudipati fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs); 4003a36c61f9SKrishna Gudipati if (!fcxp) { 4004a36c61f9SKrishna Gudipati port->stats.ns_gidft_alloc_wait++; 4005a36c61f9SKrishna Gudipati bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ns->fcxp_wqe, 4006a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_send_gid_ft, ns); 4007a36c61f9SKrishna Gudipati return; 4008a36c61f9SKrishna Gudipati } 4009a36c61f9SKrishna Gudipati ns->fcxp = fcxp; 4010a36c61f9SKrishna Gudipati 4011a36c61f9SKrishna Gudipati /* 4012a36c61f9SKrishna Gudipati * This query is only initiated for FCP initiator mode. 4013a36c61f9SKrishna Gudipati */ 4014a36c61f9SKrishna Gudipati len = fc_gid_ft_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), 4015a36c61f9SKrishna Gudipati ns->port->pid, FC_TYPE_FCP); 4016a36c61f9SKrishna Gudipati 4017a36c61f9SKrishna Gudipati bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, 4018a36c61f9SKrishna Gudipati FC_CLASS_3, len, &fchs, 4019a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_gid_ft_response, (void *)ns, 4020a36c61f9SKrishna Gudipati bfa_fcxp_get_maxrsp(port->fcs->bfa), FC_FCCT_TOV); 4021a36c61f9SKrishna Gudipati 4022a36c61f9SKrishna Gudipati port->stats.ns_gidft_sent++; 4023a36c61f9SKrishna Gudipati 4024a36c61f9SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_GIDFT_SENT); 4025a36c61f9SKrishna Gudipati } 4026a36c61f9SKrishna Gudipati 4027a36c61f9SKrishna Gudipati static void 4028a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_gid_ft_response(void *fcsarg, struct bfa_fcxp_s *fcxp, 4029a36c61f9SKrishna Gudipati void *cbarg, bfa_status_t req_status, 4030a36c61f9SKrishna Gudipati u32 rsp_len, u32 resid_len, 4031a36c61f9SKrishna Gudipati struct fchs_s *rsp_fchs) 4032a36c61f9SKrishna Gudipati { 4033a36c61f9SKrishna Gudipati struct bfa_fcs_lport_ns_s *ns = (struct bfa_fcs_lport_ns_s *) cbarg; 4034a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = ns->port; 4035a36c61f9SKrishna Gudipati struct ct_hdr_s *cthdr = NULL; 4036a36c61f9SKrishna Gudipati u32 n_pids; 4037a36c61f9SKrishna Gudipati 4038a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 4039a36c61f9SKrishna Gudipati 4040a36c61f9SKrishna Gudipati /* 4041a36c61f9SKrishna Gudipati * Sanity Checks 4042a36c61f9SKrishna Gudipati */ 4043a36c61f9SKrishna Gudipati if (req_status != BFA_STATUS_OK) { 4044a36c61f9SKrishna Gudipati bfa_trc(port->fcs, req_status); 4045a36c61f9SKrishna Gudipati port->stats.ns_gidft_rsp_err++; 4046a36c61f9SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR); 4047a36c61f9SKrishna Gudipati return; 4048a36c61f9SKrishna Gudipati } 4049a36c61f9SKrishna Gudipati 4050a36c61f9SKrishna Gudipati if (resid_len != 0) { 4051a36c61f9SKrishna Gudipati /* 4052a36c61f9SKrishna Gudipati * TBD : we will need to allocate a larger buffer & retry the 4053a36c61f9SKrishna Gudipati * command 4054a36c61f9SKrishna Gudipati */ 4055a36c61f9SKrishna Gudipati bfa_trc(port->fcs, rsp_len); 4056a36c61f9SKrishna Gudipati bfa_trc(port->fcs, resid_len); 4057a36c61f9SKrishna Gudipati return; 4058a36c61f9SKrishna Gudipati } 4059a36c61f9SKrishna Gudipati 4060a36c61f9SKrishna Gudipati cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp); 4061ba816ea8SJing Huang cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code); 4062a36c61f9SKrishna Gudipati 4063a36c61f9SKrishna Gudipati switch (cthdr->cmd_rsp_code) { 4064a36c61f9SKrishna Gudipati 4065a36c61f9SKrishna Gudipati case CT_RSP_ACCEPT: 4066a36c61f9SKrishna Gudipati 4067a36c61f9SKrishna Gudipati port->stats.ns_gidft_accepts++; 4068a36c61f9SKrishna Gudipati n_pids = (fc_get_ctresp_pyld_len(rsp_len) / sizeof(u32)); 4069a36c61f9SKrishna Gudipati bfa_trc(port->fcs, n_pids); 4070a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_process_gidft_pids(port, 4071a36c61f9SKrishna Gudipati (u32 *) (cthdr + 1), 4072a36c61f9SKrishna Gudipati n_pids); 4073a36c61f9SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_RSP_OK); 4074a36c61f9SKrishna Gudipati break; 4075a36c61f9SKrishna Gudipati 4076a36c61f9SKrishna Gudipati case CT_RSP_REJECT: 4077a36c61f9SKrishna Gudipati 4078a36c61f9SKrishna Gudipati /* 4079a36c61f9SKrishna Gudipati * Check the reason code & explanation. 4080a36c61f9SKrishna Gudipati * There may not have been any FC4 devices in the fabric 4081a36c61f9SKrishna Gudipati */ 4082a36c61f9SKrishna Gudipati port->stats.ns_gidft_rejects++; 4083a36c61f9SKrishna Gudipati bfa_trc(port->fcs, cthdr->reason_code); 4084a36c61f9SKrishna Gudipati bfa_trc(port->fcs, cthdr->exp_code); 4085a36c61f9SKrishna Gudipati 4086a36c61f9SKrishna Gudipati if ((cthdr->reason_code == CT_RSN_UNABLE_TO_PERF) 4087a36c61f9SKrishna Gudipati && (cthdr->exp_code == CT_NS_EXP_FT_NOT_REG)) { 4088a36c61f9SKrishna Gudipati 4089a36c61f9SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_RSP_OK); 4090a36c61f9SKrishna Gudipati } else { 4091a36c61f9SKrishna Gudipati /* 4092a36c61f9SKrishna Gudipati * for all other errors, retry 4093a36c61f9SKrishna Gudipati */ 4094a36c61f9SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR); 4095a36c61f9SKrishna Gudipati } 4096a36c61f9SKrishna Gudipati break; 4097a36c61f9SKrishna Gudipati 4098a36c61f9SKrishna Gudipati default: 4099a36c61f9SKrishna Gudipati port->stats.ns_gidft_unknown_rsp++; 4100a36c61f9SKrishna Gudipati bfa_trc(port->fcs, cthdr->cmd_rsp_code); 4101a36c61f9SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR); 4102a36c61f9SKrishna Gudipati } 4103a36c61f9SKrishna Gudipati } 4104a36c61f9SKrishna Gudipati 4105a36c61f9SKrishna Gudipati /** 4106a36c61f9SKrishna Gudipati * This routine will be called by bfa_timer on timer timeouts. 4107a36c61f9SKrishna Gudipati * 4108a36c61f9SKrishna Gudipati * param[in] port - pointer to bfa_fcs_lport_t. 4109a36c61f9SKrishna Gudipati * 4110a36c61f9SKrishna Gudipati * return 4111a36c61f9SKrishna Gudipati * void 4112a36c61f9SKrishna Gudipati * 4113a36c61f9SKrishna Gudipati * Special Considerations: 4114a36c61f9SKrishna Gudipati * 4115a36c61f9SKrishna Gudipati * note 4116a36c61f9SKrishna Gudipati */ 4117a36c61f9SKrishna Gudipati static void 4118a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_timeout(void *arg) 4119a36c61f9SKrishna Gudipati { 4120a36c61f9SKrishna Gudipati struct bfa_fcs_lport_ns_s *ns = (struct bfa_fcs_lport_ns_s *) arg; 4121a36c61f9SKrishna Gudipati 4122a36c61f9SKrishna Gudipati ns->port->stats.ns_timeouts++; 4123a36c61f9SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_TIMEOUT); 4124a36c61f9SKrishna Gudipati } 4125a36c61f9SKrishna Gudipati 4126a36c61f9SKrishna Gudipati /* 4127a36c61f9SKrishna Gudipati * Process the PID list in GID_FT response 4128a36c61f9SKrishna Gudipati */ 4129a36c61f9SKrishna Gudipati static void 4130a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_process_gidft_pids(struct bfa_fcs_lport_s *port, u32 *pid_buf, 4131a36c61f9SKrishna Gudipati u32 n_pids) 4132a36c61f9SKrishna Gudipati { 4133a36c61f9SKrishna Gudipati struct fcgs_gidft_resp_s *gidft_entry; 4134a36c61f9SKrishna Gudipati struct bfa_fcs_rport_s *rport; 4135a36c61f9SKrishna Gudipati u32 ii; 4136a36c61f9SKrishna Gudipati 4137a36c61f9SKrishna Gudipati for (ii = 0; ii < n_pids; ii++) { 4138a36c61f9SKrishna Gudipati gidft_entry = (struct fcgs_gidft_resp_s *) &pid_buf[ii]; 4139a36c61f9SKrishna Gudipati 4140a36c61f9SKrishna Gudipati if (gidft_entry->pid == port->pid) 4141a36c61f9SKrishna Gudipati continue; 4142a36c61f9SKrishna Gudipati 4143a36c61f9SKrishna Gudipati /* 4144a36c61f9SKrishna Gudipati * Check if this rport already exists 4145a36c61f9SKrishna Gudipati */ 4146a36c61f9SKrishna Gudipati rport = bfa_fcs_lport_get_rport_by_pid(port, gidft_entry->pid); 4147a36c61f9SKrishna Gudipati if (rport == NULL) { 4148a36c61f9SKrishna Gudipati /* 4149a36c61f9SKrishna Gudipati * this is a new device. create rport 4150a36c61f9SKrishna Gudipati */ 4151a36c61f9SKrishna Gudipati rport = bfa_fcs_rport_create(port, gidft_entry->pid); 4152a36c61f9SKrishna Gudipati } else { 4153a36c61f9SKrishna Gudipati /* 4154a36c61f9SKrishna Gudipati * this rport already exists 4155a36c61f9SKrishna Gudipati */ 4156a36c61f9SKrishna Gudipati bfa_fcs_rport_scn(rport); 4157a36c61f9SKrishna Gudipati } 4158a36c61f9SKrishna Gudipati 4159a36c61f9SKrishna Gudipati bfa_trc(port->fcs, gidft_entry->pid); 4160a36c61f9SKrishna Gudipati 4161a36c61f9SKrishna Gudipati /* 4162a36c61f9SKrishna Gudipati * if the last entry bit is set, bail out. 4163a36c61f9SKrishna Gudipati */ 4164a36c61f9SKrishna Gudipati if (gidft_entry->last) 4165a36c61f9SKrishna Gudipati return; 4166a36c61f9SKrishna Gudipati } 4167a36c61f9SKrishna Gudipati } 4168a36c61f9SKrishna Gudipati 4169a36c61f9SKrishna Gudipati /** 4170a36c61f9SKrishna Gudipati * fcs_ns_public FCS nameserver public interfaces 4171a36c61f9SKrishna Gudipati */ 4172a36c61f9SKrishna Gudipati 4173a36c61f9SKrishna Gudipati /* 4174a36c61f9SKrishna Gudipati * Functions called by port/fab. 4175a36c61f9SKrishna Gudipati * These will send relevant Events to the ns state machine. 4176a36c61f9SKrishna Gudipati */ 4177a36c61f9SKrishna Gudipati void 4178a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_init(struct bfa_fcs_lport_s *port) 4179a36c61f9SKrishna Gudipati { 4180a36c61f9SKrishna Gudipati struct bfa_fcs_lport_ns_s *ns = BFA_FCS_GET_NS_FROM_PORT(port); 4181a36c61f9SKrishna Gudipati 4182a36c61f9SKrishna Gudipati ns->port = port; 4183a36c61f9SKrishna Gudipati bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline); 4184a36c61f9SKrishna Gudipati } 4185a36c61f9SKrishna Gudipati 4186a36c61f9SKrishna Gudipati void 4187a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_offline(struct bfa_fcs_lport_s *port) 4188a36c61f9SKrishna Gudipati { 4189a36c61f9SKrishna Gudipati struct bfa_fcs_lport_ns_s *ns = BFA_FCS_GET_NS_FROM_PORT(port); 4190a36c61f9SKrishna Gudipati 4191a36c61f9SKrishna Gudipati ns->port = port; 4192a36c61f9SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_PORT_OFFLINE); 4193a36c61f9SKrishna Gudipati } 4194a36c61f9SKrishna Gudipati 4195a36c61f9SKrishna Gudipati void 4196a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_online(struct bfa_fcs_lport_s *port) 4197a36c61f9SKrishna Gudipati { 4198a36c61f9SKrishna Gudipati struct bfa_fcs_lport_ns_s *ns = BFA_FCS_GET_NS_FROM_PORT(port); 4199a36c61f9SKrishna Gudipati 4200a36c61f9SKrishna Gudipati ns->port = port; 4201a36c61f9SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_PORT_ONLINE); 4202a36c61f9SKrishna Gudipati } 4203a36c61f9SKrishna Gudipati 4204a36c61f9SKrishna Gudipati void 4205a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_query(struct bfa_fcs_lport_s *port) 4206a36c61f9SKrishna Gudipati { 4207a36c61f9SKrishna Gudipati struct bfa_fcs_lport_ns_s *ns = BFA_FCS_GET_NS_FROM_PORT(port); 4208a36c61f9SKrishna Gudipati 4209a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->pid); 4210a36c61f9SKrishna Gudipati bfa_sm_send_event(ns, NSSM_EVENT_NS_QUERY); 4211a36c61f9SKrishna Gudipati } 4212a36c61f9SKrishna Gudipati 4213a36c61f9SKrishna Gudipati void 4214a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_boot_target_disc(bfa_fcs_lport_t *port) 4215a36c61f9SKrishna Gudipati { 4216a36c61f9SKrishna Gudipati 4217a36c61f9SKrishna Gudipati struct bfa_fcs_rport_s *rport; 4218a36c61f9SKrishna Gudipati u8 nwwns; 4219a36c61f9SKrishna Gudipati wwn_t wwns[BFA_PREBOOT_BOOTLUN_MAX]; 4220a36c61f9SKrishna Gudipati int ii; 4221a36c61f9SKrishna Gudipati 4222a36c61f9SKrishna Gudipati bfa_iocfc_get_bootwwns(port->fcs->bfa, &nwwns, wwns); 4223a36c61f9SKrishna Gudipati 4224a36c61f9SKrishna Gudipati for (ii = 0 ; ii < nwwns; ++ii) { 4225a36c61f9SKrishna Gudipati rport = bfa_fcs_rport_create_by_wwn(port, wwns[ii]); 4226a36c61f9SKrishna Gudipati bfa_assert(rport); 4227a36c61f9SKrishna Gudipati } 4228a36c61f9SKrishna Gudipati } 4229a36c61f9SKrishna Gudipati 4230a36c61f9SKrishna Gudipati /** 4231a36c61f9SKrishna Gudipati * FCS SCN 4232a36c61f9SKrishna Gudipati */ 4233a36c61f9SKrishna Gudipati 4234a36c61f9SKrishna Gudipati #define FC_QOS_RSCN_EVENT 0x0c 4235a36c61f9SKrishna Gudipati #define FC_FABRIC_NAME_RSCN_EVENT 0x0d 4236a36c61f9SKrishna Gudipati 4237a36c61f9SKrishna Gudipati /* 4238a36c61f9SKrishna Gudipati * forward declarations 4239a36c61f9SKrishna Gudipati */ 4240a36c61f9SKrishna Gudipati static void bfa_fcs_lport_scn_send_scr(void *scn_cbarg, 4241a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp_alloced); 4242a36c61f9SKrishna Gudipati static void bfa_fcs_lport_scn_scr_response(void *fcsarg, 4243a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp, 4244a36c61f9SKrishna Gudipati void *cbarg, 4245a36c61f9SKrishna Gudipati bfa_status_t req_status, 4246a36c61f9SKrishna Gudipati u32 rsp_len, 4247a36c61f9SKrishna Gudipati u32 resid_len, 4248a36c61f9SKrishna Gudipati struct fchs_s *rsp_fchs); 4249a36c61f9SKrishna Gudipati static void bfa_fcs_lport_scn_send_ls_acc(struct bfa_fcs_lport_s *port, 4250a36c61f9SKrishna Gudipati struct fchs_s *rx_fchs); 4251a36c61f9SKrishna Gudipati static void bfa_fcs_lport_scn_timeout(void *arg); 4252a36c61f9SKrishna Gudipati 4253a36c61f9SKrishna Gudipati /** 4254a36c61f9SKrishna Gudipati * fcs_scm_sm FCS SCN state machine 4255a36c61f9SKrishna Gudipati */ 4256a36c61f9SKrishna Gudipati 4257a36c61f9SKrishna Gudipati /** 4258a36c61f9SKrishna Gudipati * VPort SCN State Machine events 4259a36c61f9SKrishna Gudipati */ 4260a36c61f9SKrishna Gudipati enum port_scn_event { 4261a36c61f9SKrishna Gudipati SCNSM_EVENT_PORT_ONLINE = 1, 4262a36c61f9SKrishna Gudipati SCNSM_EVENT_PORT_OFFLINE = 2, 4263a36c61f9SKrishna Gudipati SCNSM_EVENT_RSP_OK = 3, 4264a36c61f9SKrishna Gudipati SCNSM_EVENT_RSP_ERROR = 4, 4265a36c61f9SKrishna Gudipati SCNSM_EVENT_TIMEOUT = 5, 4266a36c61f9SKrishna Gudipati SCNSM_EVENT_SCR_SENT = 6, 4267a36c61f9SKrishna Gudipati }; 4268a36c61f9SKrishna Gudipati 4269a36c61f9SKrishna Gudipati static void bfa_fcs_lport_scn_sm_offline(struct bfa_fcs_lport_scn_s *scn, 4270a36c61f9SKrishna Gudipati enum port_scn_event event); 4271a36c61f9SKrishna Gudipati static void bfa_fcs_lport_scn_sm_sending_scr( 4272a36c61f9SKrishna Gudipati struct bfa_fcs_lport_scn_s *scn, 4273a36c61f9SKrishna Gudipati enum port_scn_event event); 4274a36c61f9SKrishna Gudipati static void bfa_fcs_lport_scn_sm_scr(struct bfa_fcs_lport_scn_s *scn, 4275a36c61f9SKrishna Gudipati enum port_scn_event event); 4276a36c61f9SKrishna Gudipati static void bfa_fcs_lport_scn_sm_scr_retry(struct bfa_fcs_lport_scn_s *scn, 4277a36c61f9SKrishna Gudipati enum port_scn_event event); 4278a36c61f9SKrishna Gudipati static void bfa_fcs_lport_scn_sm_online(struct bfa_fcs_lport_scn_s *scn, 4279a36c61f9SKrishna Gudipati enum port_scn_event event); 4280a36c61f9SKrishna Gudipati 4281a36c61f9SKrishna Gudipati /** 4282a36c61f9SKrishna Gudipati * Starting state - awaiting link up. 4283a36c61f9SKrishna Gudipati */ 4284a36c61f9SKrishna Gudipati static void 4285a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_sm_offline(struct bfa_fcs_lport_scn_s *scn, 4286a36c61f9SKrishna Gudipati enum port_scn_event event) 4287a36c61f9SKrishna Gudipati { 4288a36c61f9SKrishna Gudipati switch (event) { 4289a36c61f9SKrishna Gudipati case SCNSM_EVENT_PORT_ONLINE: 4290a36c61f9SKrishna Gudipati bfa_sm_set_state(scn, bfa_fcs_lport_scn_sm_sending_scr); 4291a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_send_scr(scn, NULL); 4292a36c61f9SKrishna Gudipati break; 4293a36c61f9SKrishna Gudipati 4294a36c61f9SKrishna Gudipati case SCNSM_EVENT_PORT_OFFLINE: 4295a36c61f9SKrishna Gudipati break; 4296a36c61f9SKrishna Gudipati 4297a36c61f9SKrishna Gudipati default: 4298a36c61f9SKrishna Gudipati bfa_sm_fault(scn->port->fcs, event); 4299a36c61f9SKrishna Gudipati } 4300a36c61f9SKrishna Gudipati } 4301a36c61f9SKrishna Gudipati 4302a36c61f9SKrishna Gudipati static void 4303a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_sm_sending_scr(struct bfa_fcs_lport_scn_s *scn, 4304a36c61f9SKrishna Gudipati enum port_scn_event event) 4305a36c61f9SKrishna Gudipati { 4306a36c61f9SKrishna Gudipati switch (event) { 4307a36c61f9SKrishna Gudipati case SCNSM_EVENT_SCR_SENT: 4308a36c61f9SKrishna Gudipati bfa_sm_set_state(scn, bfa_fcs_lport_scn_sm_scr); 4309a36c61f9SKrishna Gudipati break; 4310a36c61f9SKrishna Gudipati 4311a36c61f9SKrishna Gudipati case SCNSM_EVENT_PORT_OFFLINE: 4312a36c61f9SKrishna Gudipati bfa_sm_set_state(scn, bfa_fcs_lport_scn_sm_offline); 4313a36c61f9SKrishna Gudipati bfa_fcxp_walloc_cancel(scn->port->fcs->bfa, &scn->fcxp_wqe); 4314a36c61f9SKrishna Gudipati break; 4315a36c61f9SKrishna Gudipati 4316a36c61f9SKrishna Gudipati default: 4317a36c61f9SKrishna Gudipati bfa_sm_fault(scn->port->fcs, event); 4318a36c61f9SKrishna Gudipati } 4319a36c61f9SKrishna Gudipati } 4320a36c61f9SKrishna Gudipati 4321a36c61f9SKrishna Gudipati static void 4322a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_sm_scr(struct bfa_fcs_lport_scn_s *scn, 4323a36c61f9SKrishna Gudipati enum port_scn_event event) 4324a36c61f9SKrishna Gudipati { 4325a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = scn->port; 4326a36c61f9SKrishna Gudipati 4327a36c61f9SKrishna Gudipati switch (event) { 4328a36c61f9SKrishna Gudipati case SCNSM_EVENT_RSP_OK: 4329a36c61f9SKrishna Gudipati bfa_sm_set_state(scn, bfa_fcs_lport_scn_sm_online); 4330a36c61f9SKrishna Gudipati break; 4331a36c61f9SKrishna Gudipati 4332a36c61f9SKrishna Gudipati case SCNSM_EVENT_RSP_ERROR: 4333a36c61f9SKrishna Gudipati bfa_sm_set_state(scn, bfa_fcs_lport_scn_sm_scr_retry); 4334a36c61f9SKrishna Gudipati bfa_timer_start(port->fcs->bfa, &scn->timer, 4335a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_timeout, scn, 4336a36c61f9SKrishna Gudipati BFA_FCS_RETRY_TIMEOUT); 4337a36c61f9SKrishna Gudipati break; 4338a36c61f9SKrishna Gudipati 4339a36c61f9SKrishna Gudipati case SCNSM_EVENT_PORT_OFFLINE: 4340a36c61f9SKrishna Gudipati bfa_sm_set_state(scn, bfa_fcs_lport_scn_sm_offline); 4341a36c61f9SKrishna Gudipati bfa_fcxp_discard(scn->fcxp); 4342a36c61f9SKrishna Gudipati break; 4343a36c61f9SKrishna Gudipati 4344a36c61f9SKrishna Gudipati default: 4345a36c61f9SKrishna Gudipati bfa_sm_fault(port->fcs, event); 4346a36c61f9SKrishna Gudipati } 4347a36c61f9SKrishna Gudipati } 4348a36c61f9SKrishna Gudipati 4349a36c61f9SKrishna Gudipati static void 4350a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_sm_scr_retry(struct bfa_fcs_lport_scn_s *scn, 4351a36c61f9SKrishna Gudipati enum port_scn_event event) 4352a36c61f9SKrishna Gudipati { 4353a36c61f9SKrishna Gudipati switch (event) { 4354a36c61f9SKrishna Gudipati case SCNSM_EVENT_TIMEOUT: 4355a36c61f9SKrishna Gudipati bfa_sm_set_state(scn, bfa_fcs_lport_scn_sm_sending_scr); 4356a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_send_scr(scn, NULL); 4357a36c61f9SKrishna Gudipati break; 4358a36c61f9SKrishna Gudipati 4359a36c61f9SKrishna Gudipati case SCNSM_EVENT_PORT_OFFLINE: 4360a36c61f9SKrishna Gudipati bfa_sm_set_state(scn, bfa_fcs_lport_scn_sm_offline); 4361a36c61f9SKrishna Gudipati bfa_timer_stop(&scn->timer); 4362a36c61f9SKrishna Gudipati break; 4363a36c61f9SKrishna Gudipati 4364a36c61f9SKrishna Gudipati default: 4365a36c61f9SKrishna Gudipati bfa_sm_fault(scn->port->fcs, event); 4366a36c61f9SKrishna Gudipati } 4367a36c61f9SKrishna Gudipati } 4368a36c61f9SKrishna Gudipati 4369a36c61f9SKrishna Gudipati static void 4370a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_sm_online(struct bfa_fcs_lport_scn_s *scn, 4371a36c61f9SKrishna Gudipati enum port_scn_event event) 4372a36c61f9SKrishna Gudipati { 4373a36c61f9SKrishna Gudipati switch (event) { 4374a36c61f9SKrishna Gudipati case SCNSM_EVENT_PORT_OFFLINE: 4375a36c61f9SKrishna Gudipati bfa_sm_set_state(scn, bfa_fcs_lport_scn_sm_offline); 4376a36c61f9SKrishna Gudipati break; 4377a36c61f9SKrishna Gudipati 4378a36c61f9SKrishna Gudipati default: 4379a36c61f9SKrishna Gudipati bfa_sm_fault(scn->port->fcs, event); 4380a36c61f9SKrishna Gudipati } 4381a36c61f9SKrishna Gudipati } 4382a36c61f9SKrishna Gudipati 4383a36c61f9SKrishna Gudipati 4384a36c61f9SKrishna Gudipati 4385a36c61f9SKrishna Gudipati /** 4386a36c61f9SKrishna Gudipati * fcs_scn_private FCS SCN private functions 4387a36c61f9SKrishna Gudipati */ 4388a36c61f9SKrishna Gudipati 4389a36c61f9SKrishna Gudipati /** 4390a36c61f9SKrishna Gudipati * This routine will be called to send a SCR command. 4391a36c61f9SKrishna Gudipati */ 4392a36c61f9SKrishna Gudipati static void 4393a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_send_scr(void *scn_cbarg, struct bfa_fcxp_s *fcxp_alloced) 4394a36c61f9SKrishna Gudipati { 4395a36c61f9SKrishna Gudipati struct bfa_fcs_lport_scn_s *scn = scn_cbarg; 4396a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = scn->port; 4397a36c61f9SKrishna Gudipati struct fchs_s fchs; 4398a36c61f9SKrishna Gudipati int len; 4399a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp; 4400a36c61f9SKrishna Gudipati 4401a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->pid); 4402a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 4403a36c61f9SKrishna Gudipati 4404a36c61f9SKrishna Gudipati fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs); 4405a36c61f9SKrishna Gudipati if (!fcxp) { 4406a36c61f9SKrishna Gudipati bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &scn->fcxp_wqe, 4407a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_send_scr, scn); 4408a36c61f9SKrishna Gudipati return; 4409a36c61f9SKrishna Gudipati } 4410a36c61f9SKrishna Gudipati scn->fcxp = fcxp; 4411a36c61f9SKrishna Gudipati 4412a36c61f9SKrishna Gudipati /* Handle VU registrations for Base port only */ 4413a36c61f9SKrishna Gudipati if ((!port->vport) && bfa_ioc_get_fcmode(&port->fcs->bfa->ioc)) { 4414a36c61f9SKrishna Gudipati len = fc_scr_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), 4415a36c61f9SKrishna Gudipati bfa_lps_is_brcd_fabric(port->fabric->lps), 4416a36c61f9SKrishna Gudipati port->pid, 0); 4417a36c61f9SKrishna Gudipati } else { 4418a36c61f9SKrishna Gudipati len = fc_scr_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), 4419a36c61f9SKrishna Gudipati BFA_FALSE, 4420a36c61f9SKrishna Gudipati port->pid, 0); 4421a36c61f9SKrishna Gudipati } 4422a36c61f9SKrishna Gudipati 4423a36c61f9SKrishna Gudipati bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, 4424a36c61f9SKrishna Gudipati FC_CLASS_3, len, &fchs, 4425a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_scr_response, 4426a36c61f9SKrishna Gudipati (void *)scn, FC_MAX_PDUSZ, FC_ELS_TOV); 4427a36c61f9SKrishna Gudipati 4428a36c61f9SKrishna Gudipati bfa_sm_send_event(scn, SCNSM_EVENT_SCR_SENT); 4429a36c61f9SKrishna Gudipati } 4430a36c61f9SKrishna Gudipati 4431a36c61f9SKrishna Gudipati static void 4432a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_scr_response(void *fcsarg, struct bfa_fcxp_s *fcxp, 4433a36c61f9SKrishna Gudipati void *cbarg, bfa_status_t req_status, u32 rsp_len, 4434a36c61f9SKrishna Gudipati u32 resid_len, struct fchs_s *rsp_fchs) 4435a36c61f9SKrishna Gudipati { 4436a36c61f9SKrishna Gudipati struct bfa_fcs_lport_scn_s *scn = (struct bfa_fcs_lport_scn_s *) cbarg; 4437a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = scn->port; 4438a36c61f9SKrishna Gudipati struct fc_els_cmd_s *els_cmd; 4439a36c61f9SKrishna Gudipati struct fc_ls_rjt_s *ls_rjt; 4440a36c61f9SKrishna Gudipati 4441a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->port_cfg.pwwn); 4442a36c61f9SKrishna Gudipati 4443a36c61f9SKrishna Gudipati /* 4444a36c61f9SKrishna Gudipati * Sanity Checks 4445a36c61f9SKrishna Gudipati */ 4446a36c61f9SKrishna Gudipati if (req_status != BFA_STATUS_OK) { 4447a36c61f9SKrishna Gudipati bfa_trc(port->fcs, req_status); 4448a36c61f9SKrishna Gudipati bfa_sm_send_event(scn, SCNSM_EVENT_RSP_ERROR); 4449a36c61f9SKrishna Gudipati return; 4450a36c61f9SKrishna Gudipati } 4451a36c61f9SKrishna Gudipati 4452a36c61f9SKrishna Gudipati els_cmd = (struct fc_els_cmd_s *) BFA_FCXP_RSP_PLD(fcxp); 4453a36c61f9SKrishna Gudipati 4454a36c61f9SKrishna Gudipati switch (els_cmd->els_code) { 4455a36c61f9SKrishna Gudipati 4456a36c61f9SKrishna Gudipati case FC_ELS_ACC: 4457a36c61f9SKrishna Gudipati bfa_sm_send_event(scn, SCNSM_EVENT_RSP_OK); 4458a36c61f9SKrishna Gudipati break; 4459a36c61f9SKrishna Gudipati 4460a36c61f9SKrishna Gudipati case FC_ELS_LS_RJT: 4461a36c61f9SKrishna Gudipati 4462a36c61f9SKrishna Gudipati ls_rjt = (struct fc_ls_rjt_s *) BFA_FCXP_RSP_PLD(fcxp); 4463a36c61f9SKrishna Gudipati 4464a36c61f9SKrishna Gudipati bfa_trc(port->fcs, ls_rjt->reason_code); 4465a36c61f9SKrishna Gudipati bfa_trc(port->fcs, ls_rjt->reason_code_expl); 4466a36c61f9SKrishna Gudipati 4467a36c61f9SKrishna Gudipati bfa_sm_send_event(scn, SCNSM_EVENT_RSP_ERROR); 4468a36c61f9SKrishna Gudipati break; 4469a36c61f9SKrishna Gudipati 4470a36c61f9SKrishna Gudipati default: 4471a36c61f9SKrishna Gudipati bfa_sm_send_event(scn, SCNSM_EVENT_RSP_ERROR); 4472a36c61f9SKrishna Gudipati } 4473a36c61f9SKrishna Gudipati } 4474a36c61f9SKrishna Gudipati 4475a36c61f9SKrishna Gudipati /* 4476a36c61f9SKrishna Gudipati * Send a LS Accept 4477a36c61f9SKrishna Gudipati */ 4478a36c61f9SKrishna Gudipati static void 4479a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_send_ls_acc(struct bfa_fcs_lport_s *port, 4480a36c61f9SKrishna Gudipati struct fchs_s *rx_fchs) 4481a36c61f9SKrishna Gudipati { 4482a36c61f9SKrishna Gudipati struct fchs_s fchs; 4483a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp; 4484a36c61f9SKrishna Gudipati struct bfa_rport_s *bfa_rport = NULL; 4485a36c61f9SKrishna Gudipati int len; 4486a36c61f9SKrishna Gudipati 4487a36c61f9SKrishna Gudipati bfa_trc(port->fcs, rx_fchs->s_id); 4488a36c61f9SKrishna Gudipati 4489a36c61f9SKrishna Gudipati fcxp = bfa_fcs_fcxp_alloc(port->fcs); 4490a36c61f9SKrishna Gudipati if (!fcxp) 4491a36c61f9SKrishna Gudipati return; 4492a36c61f9SKrishna Gudipati 4493a36c61f9SKrishna Gudipati len = fc_ls_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), 4494a36c61f9SKrishna Gudipati rx_fchs->s_id, bfa_fcs_lport_get_fcid(port), 4495a36c61f9SKrishna Gudipati rx_fchs->ox_id); 4496a36c61f9SKrishna Gudipati 4497a36c61f9SKrishna Gudipati bfa_fcxp_send(fcxp, bfa_rport, port->fabric->vf_id, port->lp_tag, 4498a36c61f9SKrishna Gudipati BFA_FALSE, FC_CLASS_3, len, &fchs, NULL, NULL, 4499a36c61f9SKrishna Gudipati FC_MAX_PDUSZ, 0); 4500a36c61f9SKrishna Gudipati } 4501a36c61f9SKrishna Gudipati 4502a36c61f9SKrishna Gudipati /** 4503a36c61f9SKrishna Gudipati * This routine will be called by bfa_timer on timer timeouts. 4504a36c61f9SKrishna Gudipati * 4505a36c61f9SKrishna Gudipati * param[in] vport - pointer to bfa_fcs_lport_t. 4506a36c61f9SKrishna Gudipati * param[out] vport_status - pointer to return vport status in 4507a36c61f9SKrishna Gudipati * 4508a36c61f9SKrishna Gudipati * return 4509a36c61f9SKrishna Gudipati * void 4510a36c61f9SKrishna Gudipati * 4511a36c61f9SKrishna Gudipati * Special Considerations: 4512a36c61f9SKrishna Gudipati * 4513a36c61f9SKrishna Gudipati * note 4514a36c61f9SKrishna Gudipati */ 4515a36c61f9SKrishna Gudipati static void 4516a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_timeout(void *arg) 4517a36c61f9SKrishna Gudipati { 4518a36c61f9SKrishna Gudipati struct bfa_fcs_lport_scn_s *scn = (struct bfa_fcs_lport_scn_s *) arg; 4519a36c61f9SKrishna Gudipati 4520a36c61f9SKrishna Gudipati bfa_sm_send_event(scn, SCNSM_EVENT_TIMEOUT); 4521a36c61f9SKrishna Gudipati } 4522a36c61f9SKrishna Gudipati 4523a36c61f9SKrishna Gudipati 4524a36c61f9SKrishna Gudipati 4525a36c61f9SKrishna Gudipati /** 4526a36c61f9SKrishna Gudipati * fcs_scn_public FCS state change notification public interfaces 4527a36c61f9SKrishna Gudipati */ 4528a36c61f9SKrishna Gudipati 4529a36c61f9SKrishna Gudipati /* 4530a36c61f9SKrishna Gudipati * Functions called by port/fab 4531a36c61f9SKrishna Gudipati */ 4532a36c61f9SKrishna Gudipati void 4533a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_init(struct bfa_fcs_lport_s *port) 4534a36c61f9SKrishna Gudipati { 4535a36c61f9SKrishna Gudipati struct bfa_fcs_lport_scn_s *scn = BFA_FCS_GET_SCN_FROM_PORT(port); 4536a36c61f9SKrishna Gudipati 4537a36c61f9SKrishna Gudipati scn->port = port; 4538a36c61f9SKrishna Gudipati bfa_sm_set_state(scn, bfa_fcs_lport_scn_sm_offline); 4539a36c61f9SKrishna Gudipati } 4540a36c61f9SKrishna Gudipati 4541a36c61f9SKrishna Gudipati void 4542a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_offline(struct bfa_fcs_lport_s *port) 4543a36c61f9SKrishna Gudipati { 4544a36c61f9SKrishna Gudipati struct bfa_fcs_lport_scn_s *scn = BFA_FCS_GET_SCN_FROM_PORT(port); 4545a36c61f9SKrishna Gudipati 4546a36c61f9SKrishna Gudipati scn->port = port; 4547a36c61f9SKrishna Gudipati bfa_sm_send_event(scn, SCNSM_EVENT_PORT_OFFLINE); 4548a36c61f9SKrishna Gudipati } 4549a36c61f9SKrishna Gudipati 4550a36c61f9SKrishna Gudipati void 4551a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_online(struct bfa_fcs_lport_s *port) 4552a36c61f9SKrishna Gudipati { 4553a36c61f9SKrishna Gudipati struct bfa_fcs_lport_scn_s *scn = BFA_FCS_GET_SCN_FROM_PORT(port); 4554a36c61f9SKrishna Gudipati 4555a36c61f9SKrishna Gudipati scn->port = port; 4556a36c61f9SKrishna Gudipati bfa_sm_send_event(scn, SCNSM_EVENT_PORT_ONLINE); 4557a36c61f9SKrishna Gudipati } 4558a36c61f9SKrishna Gudipati 4559a36c61f9SKrishna Gudipati static void 4560a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_portid_rscn(struct bfa_fcs_lport_s *port, u32 rpid) 4561a36c61f9SKrishna Gudipati { 4562a36c61f9SKrishna Gudipati struct bfa_fcs_rport_s *rport; 4563a36c61f9SKrishna Gudipati 4564a36c61f9SKrishna Gudipati bfa_trc(port->fcs, rpid); 4565a36c61f9SKrishna Gudipati 4566a36c61f9SKrishna Gudipati /** 4567a36c61f9SKrishna Gudipati * If this is an unknown device, then it just came online. 4568a36c61f9SKrishna Gudipati * Otherwise let rport handle the RSCN event. 4569a36c61f9SKrishna Gudipati */ 4570a36c61f9SKrishna Gudipati rport = bfa_fcs_lport_get_rport_by_pid(port, rpid); 4571a36c61f9SKrishna Gudipati if (rport == NULL) { 4572a36c61f9SKrishna Gudipati /* 4573a36c61f9SKrishna Gudipati * If min cfg mode is enabled, we donot need to 4574a36c61f9SKrishna Gudipati * discover any new rports. 4575a36c61f9SKrishna Gudipati */ 4576a36c61f9SKrishna Gudipati if (!__fcs_min_cfg(port->fcs)) 4577a36c61f9SKrishna Gudipati rport = bfa_fcs_rport_create(port, rpid); 4578a36c61f9SKrishna Gudipati } else 4579a36c61f9SKrishna Gudipati bfa_fcs_rport_scn(rport); 4580a36c61f9SKrishna Gudipati } 4581a36c61f9SKrishna Gudipati 4582a36c61f9SKrishna Gudipati /** 4583a36c61f9SKrishna Gudipati * rscn format based PID comparison 4584a36c61f9SKrishna Gudipati */ 4585a36c61f9SKrishna Gudipati #define __fc_pid_match(__c0, __c1, __fmt) \ 4586a36c61f9SKrishna Gudipati (((__fmt) == FC_RSCN_FORMAT_FABRIC) || \ 4587a36c61f9SKrishna Gudipati (((__fmt) == FC_RSCN_FORMAT_DOMAIN) && \ 4588a36c61f9SKrishna Gudipati ((__c0)[0] == (__c1)[0])) || \ 4589a36c61f9SKrishna Gudipati (((__fmt) == FC_RSCN_FORMAT_AREA) && \ 4590a36c61f9SKrishna Gudipati ((__c0)[0] == (__c1)[0]) && \ 4591a36c61f9SKrishna Gudipati ((__c0)[1] == (__c1)[1]))) 4592a36c61f9SKrishna Gudipati 4593a36c61f9SKrishna Gudipati static void 4594a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_multiport_rscn(struct bfa_fcs_lport_s *port, 4595a36c61f9SKrishna Gudipati enum fc_rscn_format format, 4596a36c61f9SKrishna Gudipati u32 rscn_pid) 4597a36c61f9SKrishna Gudipati { 4598a36c61f9SKrishna Gudipati struct bfa_fcs_rport_s *rport; 4599a36c61f9SKrishna Gudipati struct list_head *qe, *qe_next; 4600a36c61f9SKrishna Gudipati u8 *c0, *c1; 4601a36c61f9SKrishna Gudipati 4602a36c61f9SKrishna Gudipati bfa_trc(port->fcs, format); 4603a36c61f9SKrishna Gudipati bfa_trc(port->fcs, rscn_pid); 4604a36c61f9SKrishna Gudipati 4605a36c61f9SKrishna Gudipati c0 = (u8 *) &rscn_pid; 4606a36c61f9SKrishna Gudipati 4607a36c61f9SKrishna Gudipati list_for_each_safe(qe, qe_next, &port->rport_q) { 4608a36c61f9SKrishna Gudipati rport = (struct bfa_fcs_rport_s *) qe; 4609a36c61f9SKrishna Gudipati c1 = (u8 *) &rport->pid; 4610a36c61f9SKrishna Gudipati if (__fc_pid_match(c0, c1, format)) 4611a36c61f9SKrishna Gudipati bfa_fcs_rport_scn(rport); 4612a36c61f9SKrishna Gudipati } 4613a36c61f9SKrishna Gudipati } 4614a36c61f9SKrishna Gudipati 4615a36c61f9SKrishna Gudipati 4616a36c61f9SKrishna Gudipati void 4617a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_process_rscn(struct bfa_fcs_lport_s *port, 4618a36c61f9SKrishna Gudipati struct fchs_s *fchs, u32 len) 4619a36c61f9SKrishna Gudipati { 4620a36c61f9SKrishna Gudipati struct fc_rscn_pl_s *rscn = (struct fc_rscn_pl_s *) (fchs + 1); 4621a36c61f9SKrishna Gudipati int num_entries; 4622a36c61f9SKrishna Gudipati u32 rscn_pid; 4623a36c61f9SKrishna Gudipati bfa_boolean_t nsquery = BFA_FALSE, found; 4624a36c61f9SKrishna Gudipati int i = 0, j; 4625a36c61f9SKrishna Gudipati 4626a36c61f9SKrishna Gudipati num_entries = 4627ba816ea8SJing Huang (be16_to_cpu(rscn->payldlen) - 4628a36c61f9SKrishna Gudipati sizeof(u32)) / sizeof(rscn->event[0]); 4629a36c61f9SKrishna Gudipati 4630a36c61f9SKrishna Gudipati bfa_trc(port->fcs, num_entries); 4631a36c61f9SKrishna Gudipati 4632a36c61f9SKrishna Gudipati port->stats.num_rscn++; 4633a36c61f9SKrishna Gudipati 4634a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_send_ls_acc(port, fchs); 4635a36c61f9SKrishna Gudipati 4636a36c61f9SKrishna Gudipati for (i = 0; i < num_entries; i++) { 4637a36c61f9SKrishna Gudipati rscn_pid = rscn->event[i].portid; 4638a36c61f9SKrishna Gudipati 4639a36c61f9SKrishna Gudipati bfa_trc(port->fcs, rscn->event[i].format); 4640a36c61f9SKrishna Gudipati bfa_trc(port->fcs, rscn_pid); 4641a36c61f9SKrishna Gudipati 4642a36c61f9SKrishna Gudipati /* check for duplicate entries in the list */ 4643a36c61f9SKrishna Gudipati found = BFA_FALSE; 4644a36c61f9SKrishna Gudipati for (j = 0; j < i; j++) { 4645a36c61f9SKrishna Gudipati if (rscn->event[j].portid == rscn_pid) { 4646a36c61f9SKrishna Gudipati found = BFA_TRUE; 4647a36c61f9SKrishna Gudipati break; 4648a36c61f9SKrishna Gudipati } 4649a36c61f9SKrishna Gudipati } 4650a36c61f9SKrishna Gudipati 4651a36c61f9SKrishna Gudipati /* if found in down the list, pid has been already processed */ 4652a36c61f9SKrishna Gudipati if (found) { 4653a36c61f9SKrishna Gudipati bfa_trc(port->fcs, rscn_pid); 4654a36c61f9SKrishna Gudipati continue; 4655a36c61f9SKrishna Gudipati } 4656a36c61f9SKrishna Gudipati 4657a36c61f9SKrishna Gudipati switch (rscn->event[i].format) { 4658a36c61f9SKrishna Gudipati case FC_RSCN_FORMAT_PORTID: 4659a36c61f9SKrishna Gudipati if (rscn->event[i].qualifier == FC_QOS_RSCN_EVENT) { 4660a36c61f9SKrishna Gudipati /* 4661a36c61f9SKrishna Gudipati * Ignore this event. 4662a36c61f9SKrishna Gudipati * f/w would have processed it 4663a36c61f9SKrishna Gudipati */ 4664a36c61f9SKrishna Gudipati bfa_trc(port->fcs, rscn_pid); 4665a36c61f9SKrishna Gudipati } else { 4666a36c61f9SKrishna Gudipati port->stats.num_portid_rscn++; 4667a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_portid_rscn(port, rscn_pid); 4668a36c61f9SKrishna Gudipati } 4669a36c61f9SKrishna Gudipati break; 4670a36c61f9SKrishna Gudipati 4671a36c61f9SKrishna Gudipati case FC_RSCN_FORMAT_FABRIC: 4672a36c61f9SKrishna Gudipati if (rscn->event[i].qualifier == 4673a36c61f9SKrishna Gudipati FC_FABRIC_NAME_RSCN_EVENT) { 4674a36c61f9SKrishna Gudipati bfa_fcs_lport_ms_fabric_rscn(port); 4675a36c61f9SKrishna Gudipati break; 4676a36c61f9SKrishna Gudipati } 4677a36c61f9SKrishna Gudipati /* !!!!!!!!! Fall Through !!!!!!!!!!!!! */ 4678a36c61f9SKrishna Gudipati 4679a36c61f9SKrishna Gudipati case FC_RSCN_FORMAT_AREA: 4680a36c61f9SKrishna Gudipati case FC_RSCN_FORMAT_DOMAIN: 4681a36c61f9SKrishna Gudipati nsquery = BFA_TRUE; 4682a36c61f9SKrishna Gudipati bfa_fcs_lport_scn_multiport_rscn(port, 4683a36c61f9SKrishna Gudipati rscn->event[i].format, 4684a36c61f9SKrishna Gudipati rscn_pid); 4685a36c61f9SKrishna Gudipati break; 4686a36c61f9SKrishna Gudipati 4687a36c61f9SKrishna Gudipati 4688a36c61f9SKrishna Gudipati default: 4689a36c61f9SKrishna Gudipati bfa_assert(0); 4690a36c61f9SKrishna Gudipati nsquery = BFA_TRUE; 4691a36c61f9SKrishna Gudipati } 4692a36c61f9SKrishna Gudipati } 4693a36c61f9SKrishna Gudipati 4694a36c61f9SKrishna Gudipati /** 4695a36c61f9SKrishna Gudipati * If any of area, domain or fabric RSCN is received, do a fresh discovery 4696a36c61f9SKrishna Gudipati * to find new devices. 4697a36c61f9SKrishna Gudipati */ 4698a36c61f9SKrishna Gudipati if (nsquery) 4699a36c61f9SKrishna Gudipati bfa_fcs_lport_ns_query(port); 4700a36c61f9SKrishna Gudipati } 4701a36c61f9SKrishna Gudipati 4702a36c61f9SKrishna Gudipati /** 4703a36c61f9SKrishna Gudipati * BFA FCS port 4704a36c61f9SKrishna Gudipati */ 4705a36c61f9SKrishna Gudipati /** 4706a36c61f9SKrishna Gudipati * fcs_port_api BFA FCS port API 4707a36c61f9SKrishna Gudipati */ 4708a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s * 4709a36c61f9SKrishna Gudipati bfa_fcs_get_base_port(struct bfa_fcs_s *fcs) 4710a36c61f9SKrishna Gudipati { 4711a36c61f9SKrishna Gudipati return &fcs->fabric.bport; 4712a36c61f9SKrishna Gudipati } 4713a36c61f9SKrishna Gudipati 4714a36c61f9SKrishna Gudipati wwn_t 4715a36c61f9SKrishna Gudipati bfa_fcs_lport_get_rport(struct bfa_fcs_lport_s *port, wwn_t wwn, int index, 4716a36c61f9SKrishna Gudipati int nrports, bfa_boolean_t bwwn) 4717a36c61f9SKrishna Gudipati { 4718a36c61f9SKrishna Gudipati struct list_head *qh, *qe; 4719a36c61f9SKrishna Gudipati struct bfa_fcs_rport_s *rport = NULL; 4720a36c61f9SKrishna Gudipati int i; 4721a36c61f9SKrishna Gudipati struct bfa_fcs_s *fcs; 4722a36c61f9SKrishna Gudipati 4723a36c61f9SKrishna Gudipati if (port == NULL || nrports == 0) 4724a36c61f9SKrishna Gudipati return (wwn_t) 0; 4725a36c61f9SKrishna Gudipati 4726a36c61f9SKrishna Gudipati fcs = port->fcs; 4727a36c61f9SKrishna Gudipati bfa_trc(fcs, (u32) nrports); 4728a36c61f9SKrishna Gudipati 4729a36c61f9SKrishna Gudipati i = 0; 4730a36c61f9SKrishna Gudipati qh = &port->rport_q; 4731a36c61f9SKrishna Gudipati qe = bfa_q_first(qh); 4732a36c61f9SKrishna Gudipati 4733a36c61f9SKrishna Gudipati while ((qe != qh) && (i < nrports)) { 4734a36c61f9SKrishna Gudipati rport = (struct bfa_fcs_rport_s *) qe; 4735a36c61f9SKrishna Gudipati if (bfa_os_ntoh3b(rport->pid) > 0xFFF000) { 4736a36c61f9SKrishna Gudipati qe = bfa_q_next(qe); 4737a36c61f9SKrishna Gudipati bfa_trc(fcs, (u32) rport->pwwn); 4738a36c61f9SKrishna Gudipati bfa_trc(fcs, rport->pid); 4739a36c61f9SKrishna Gudipati bfa_trc(fcs, i); 4740a36c61f9SKrishna Gudipati continue; 4741a36c61f9SKrishna Gudipati } 4742a36c61f9SKrishna Gudipati 4743a36c61f9SKrishna Gudipati if (bwwn) { 4744a36c61f9SKrishna Gudipati if (!memcmp(&wwn, &rport->pwwn, 8)) 4745a36c61f9SKrishna Gudipati break; 4746a36c61f9SKrishna Gudipati } else { 4747a36c61f9SKrishna Gudipati if (i == index) 4748a36c61f9SKrishna Gudipati break; 4749a36c61f9SKrishna Gudipati } 4750a36c61f9SKrishna Gudipati 4751a36c61f9SKrishna Gudipati i++; 4752a36c61f9SKrishna Gudipati qe = bfa_q_next(qe); 4753a36c61f9SKrishna Gudipati } 4754a36c61f9SKrishna Gudipati 4755a36c61f9SKrishna Gudipati bfa_trc(fcs, i); 4756a36c61f9SKrishna Gudipati if (rport) 4757a36c61f9SKrishna Gudipati return rport->pwwn; 4758a36c61f9SKrishna Gudipati else 4759a36c61f9SKrishna Gudipati return (wwn_t) 0; 4760a36c61f9SKrishna Gudipati } 4761a36c61f9SKrishna Gudipati 4762a36c61f9SKrishna Gudipati void 4763a36c61f9SKrishna Gudipati bfa_fcs_lport_get_rports(struct bfa_fcs_lport_s *port, 4764a36c61f9SKrishna Gudipati wwn_t rport_wwns[], int *nrports) 4765a36c61f9SKrishna Gudipati { 4766a36c61f9SKrishna Gudipati struct list_head *qh, *qe; 4767a36c61f9SKrishna Gudipati struct bfa_fcs_rport_s *rport = NULL; 4768a36c61f9SKrishna Gudipati int i; 4769a36c61f9SKrishna Gudipati struct bfa_fcs_s *fcs; 4770a36c61f9SKrishna Gudipati 4771a36c61f9SKrishna Gudipati if (port == NULL || rport_wwns == NULL || *nrports == 0) 4772a36c61f9SKrishna Gudipati return; 4773a36c61f9SKrishna Gudipati 4774a36c61f9SKrishna Gudipati fcs = port->fcs; 4775a36c61f9SKrishna Gudipati bfa_trc(fcs, (u32) *nrports); 4776a36c61f9SKrishna Gudipati 4777a36c61f9SKrishna Gudipati i = 0; 4778a36c61f9SKrishna Gudipati qh = &port->rport_q; 4779a36c61f9SKrishna Gudipati qe = bfa_q_first(qh); 4780a36c61f9SKrishna Gudipati 4781a36c61f9SKrishna Gudipati while ((qe != qh) && (i < *nrports)) { 4782a36c61f9SKrishna Gudipati rport = (struct bfa_fcs_rport_s *) qe; 4783a36c61f9SKrishna Gudipati if (bfa_os_ntoh3b(rport->pid) > 0xFFF000) { 4784a36c61f9SKrishna Gudipati qe = bfa_q_next(qe); 4785a36c61f9SKrishna Gudipati bfa_trc(fcs, (u32) rport->pwwn); 4786a36c61f9SKrishna Gudipati bfa_trc(fcs, rport->pid); 4787a36c61f9SKrishna Gudipati bfa_trc(fcs, i); 4788a36c61f9SKrishna Gudipati continue; 4789a36c61f9SKrishna Gudipati } 4790a36c61f9SKrishna Gudipati 4791a36c61f9SKrishna Gudipati rport_wwns[i] = rport->pwwn; 4792a36c61f9SKrishna Gudipati 4793a36c61f9SKrishna Gudipati i++; 4794a36c61f9SKrishna Gudipati qe = bfa_q_next(qe); 4795a36c61f9SKrishna Gudipati } 4796a36c61f9SKrishna Gudipati 4797a36c61f9SKrishna Gudipati bfa_trc(fcs, i); 4798a36c61f9SKrishna Gudipati *nrports = i; 4799a36c61f9SKrishna Gudipati } 4800a36c61f9SKrishna Gudipati 4801a36c61f9SKrishna Gudipati /* 4802a36c61f9SKrishna Gudipati * Iterate's through all the rport's in the given port to 4803a36c61f9SKrishna Gudipati * determine the maximum operating speed. 4804a36c61f9SKrishna Gudipati * 4805a36c61f9SKrishna Gudipati * !!!! To be used in TRL Functionality only !!!! 4806a36c61f9SKrishna Gudipati */ 4807a36c61f9SKrishna Gudipati bfa_port_speed_t 4808a36c61f9SKrishna Gudipati bfa_fcs_lport_get_rport_max_speed(bfa_fcs_lport_t *port) 4809a36c61f9SKrishna Gudipati { 4810a36c61f9SKrishna Gudipati struct list_head *qh, *qe; 4811a36c61f9SKrishna Gudipati struct bfa_fcs_rport_s *rport = NULL; 4812a36c61f9SKrishna Gudipati struct bfa_fcs_s *fcs; 4813a36c61f9SKrishna Gudipati bfa_port_speed_t max_speed = 0; 4814a36c61f9SKrishna Gudipati struct bfa_port_attr_s port_attr; 4815a36c61f9SKrishna Gudipati bfa_port_speed_t port_speed, rport_speed; 4816a36c61f9SKrishna Gudipati bfa_boolean_t trl_enabled = bfa_fcport_is_ratelim(port->fcs->bfa); 4817a36c61f9SKrishna Gudipati 4818a36c61f9SKrishna Gudipati 4819a36c61f9SKrishna Gudipati if (port == NULL) 4820a36c61f9SKrishna Gudipati return 0; 4821a36c61f9SKrishna Gudipati 4822a36c61f9SKrishna Gudipati fcs = port->fcs; 4823a36c61f9SKrishna Gudipati 4824a36c61f9SKrishna Gudipati /* Get Physical port's current speed */ 4825a36c61f9SKrishna Gudipati bfa_fcport_get_attr(port->fcs->bfa, &port_attr); 4826a36c61f9SKrishna Gudipati port_speed = port_attr.speed; 4827a36c61f9SKrishna Gudipati bfa_trc(fcs, port_speed); 4828a36c61f9SKrishna Gudipati 4829a36c61f9SKrishna Gudipati qh = &port->rport_q; 4830a36c61f9SKrishna Gudipati qe = bfa_q_first(qh); 4831a36c61f9SKrishna Gudipati 4832a36c61f9SKrishna Gudipati while (qe != qh) { 4833a36c61f9SKrishna Gudipati rport = (struct bfa_fcs_rport_s *) qe; 4834a36c61f9SKrishna Gudipati if ((bfa_os_ntoh3b(rport->pid) > 0xFFF000) || 4835a36c61f9SKrishna Gudipati (bfa_fcs_rport_get_state(rport) == 4836a36c61f9SKrishna Gudipati BFA_RPORT_OFFLINE)) { 4837a36c61f9SKrishna Gudipati qe = bfa_q_next(qe); 4838a36c61f9SKrishna Gudipati continue; 4839a36c61f9SKrishna Gudipati } 4840a36c61f9SKrishna Gudipati 4841a36c61f9SKrishna Gudipati rport_speed = rport->rpf.rpsc_speed; 4842a36c61f9SKrishna Gudipati if ((trl_enabled) && (rport_speed == 4843a36c61f9SKrishna Gudipati BFA_PORT_SPEED_UNKNOWN)) { 4844a36c61f9SKrishna Gudipati /* Use default ratelim speed setting */ 4845a36c61f9SKrishna Gudipati rport_speed = 4846a36c61f9SKrishna Gudipati bfa_fcport_get_ratelim_speed(port->fcs->bfa); 4847a36c61f9SKrishna Gudipati } 4848a36c61f9SKrishna Gudipati 4849a36c61f9SKrishna Gudipati if ((rport_speed == BFA_PORT_SPEED_8GBPS) || 4850a36c61f9SKrishna Gudipati (rport_speed > port_speed)) { 4851a36c61f9SKrishna Gudipati max_speed = rport_speed; 4852a36c61f9SKrishna Gudipati break; 4853a36c61f9SKrishna Gudipati } else if (rport_speed > max_speed) { 4854a36c61f9SKrishna Gudipati max_speed = rport_speed; 4855a36c61f9SKrishna Gudipati } 4856a36c61f9SKrishna Gudipati 4857a36c61f9SKrishna Gudipati qe = bfa_q_next(qe); 4858a36c61f9SKrishna Gudipati } 4859a36c61f9SKrishna Gudipati 4860a36c61f9SKrishna Gudipati bfa_trc(fcs, max_speed); 4861a36c61f9SKrishna Gudipati return max_speed; 4862a36c61f9SKrishna Gudipati } 4863a36c61f9SKrishna Gudipati 4864a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s * 4865a36c61f9SKrishna Gudipati bfa_fcs_lookup_port(struct bfa_fcs_s *fcs, u16 vf_id, wwn_t lpwwn) 4866a36c61f9SKrishna Gudipati { 4867a36c61f9SKrishna Gudipati struct bfa_fcs_vport_s *vport; 4868a36c61f9SKrishna Gudipati bfa_fcs_vf_t *vf; 4869a36c61f9SKrishna Gudipati 4870a36c61f9SKrishna Gudipati bfa_assert(fcs != NULL); 4871a36c61f9SKrishna Gudipati 4872a36c61f9SKrishna Gudipati vf = bfa_fcs_vf_lookup(fcs, vf_id); 4873a36c61f9SKrishna Gudipati if (vf == NULL) { 4874a36c61f9SKrishna Gudipati bfa_trc(fcs, vf_id); 4875a36c61f9SKrishna Gudipati return NULL; 4876a36c61f9SKrishna Gudipati } 4877a36c61f9SKrishna Gudipati 4878a36c61f9SKrishna Gudipati if (!lpwwn || (vf->bport.port_cfg.pwwn == lpwwn)) 4879a36c61f9SKrishna Gudipati return &vf->bport; 4880a36c61f9SKrishna Gudipati 4881a36c61f9SKrishna Gudipati vport = bfa_fcs_fabric_vport_lookup(vf, lpwwn); 4882a36c61f9SKrishna Gudipati if (vport) 4883a36c61f9SKrishna Gudipati return &vport->lport; 4884a36c61f9SKrishna Gudipati 4885a36c61f9SKrishna Gudipati return NULL; 4886a36c61f9SKrishna Gudipati } 4887a36c61f9SKrishna Gudipati 4888a36c61f9SKrishna Gudipati /* 4889a36c61f9SKrishna Gudipati * API corresponding to NPIV_VPORT_GETINFO. 4890a36c61f9SKrishna Gudipati */ 4891a36c61f9SKrishna Gudipati void 4892a36c61f9SKrishna Gudipati bfa_fcs_lport_get_info(struct bfa_fcs_lport_s *port, 4893a36c61f9SKrishna Gudipati struct bfa_lport_info_s *port_info) 4894a36c61f9SKrishna Gudipati { 4895a36c61f9SKrishna Gudipati 4896a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->fabric->fabric_name); 4897a36c61f9SKrishna Gudipati 4898a36c61f9SKrishna Gudipati if (port->vport == NULL) { 4899a36c61f9SKrishna Gudipati /* 4900a36c61f9SKrishna Gudipati * This is a Physical port 4901a36c61f9SKrishna Gudipati */ 4902a36c61f9SKrishna Gudipati port_info->port_type = BFA_LPORT_TYPE_PHYSICAL; 4903a36c61f9SKrishna Gudipati 4904a36c61f9SKrishna Gudipati /* 4905a36c61f9SKrishna Gudipati * @todo : need to fix the state & reason 4906a36c61f9SKrishna Gudipati */ 4907a36c61f9SKrishna Gudipati port_info->port_state = 0; 4908a36c61f9SKrishna Gudipati port_info->offline_reason = 0; 4909a36c61f9SKrishna Gudipati 4910a36c61f9SKrishna Gudipati port_info->port_wwn = bfa_fcs_lport_get_pwwn(port); 4911a36c61f9SKrishna Gudipati port_info->node_wwn = bfa_fcs_lport_get_nwwn(port); 4912a36c61f9SKrishna Gudipati 4913a36c61f9SKrishna Gudipati port_info->max_vports_supp = 4914a36c61f9SKrishna Gudipati bfa_lps_get_max_vport(port->fcs->bfa); 4915a36c61f9SKrishna Gudipati port_info->num_vports_inuse = 4916a36c61f9SKrishna Gudipati bfa_fcs_fabric_vport_count(port->fabric); 4917a36c61f9SKrishna Gudipati port_info->max_rports_supp = BFA_FCS_MAX_RPORTS_SUPP; 4918a36c61f9SKrishna Gudipati port_info->num_rports_inuse = port->num_rports; 4919a36c61f9SKrishna Gudipati } else { 4920a36c61f9SKrishna Gudipati /* 4921a36c61f9SKrishna Gudipati * This is a virtual port 4922a36c61f9SKrishna Gudipati */ 4923a36c61f9SKrishna Gudipati port_info->port_type = BFA_LPORT_TYPE_VIRTUAL; 4924a36c61f9SKrishna Gudipati 4925a36c61f9SKrishna Gudipati /* 4926a36c61f9SKrishna Gudipati * @todo : need to fix the state & reason 4927a36c61f9SKrishna Gudipati */ 4928a36c61f9SKrishna Gudipati port_info->port_state = 0; 4929a36c61f9SKrishna Gudipati port_info->offline_reason = 0; 4930a36c61f9SKrishna Gudipati 4931a36c61f9SKrishna Gudipati port_info->port_wwn = bfa_fcs_lport_get_pwwn(port); 4932a36c61f9SKrishna Gudipati port_info->node_wwn = bfa_fcs_lport_get_nwwn(port); 4933a36c61f9SKrishna Gudipati } 4934a36c61f9SKrishna Gudipati } 4935a36c61f9SKrishna Gudipati 4936a36c61f9SKrishna Gudipati void 4937a36c61f9SKrishna Gudipati bfa_fcs_lport_get_stats(struct bfa_fcs_lport_s *fcs_port, 4938a36c61f9SKrishna Gudipati struct bfa_lport_stats_s *port_stats) 4939a36c61f9SKrishna Gudipati { 4940a36c61f9SKrishna Gudipati *port_stats = fcs_port->stats; 4941a36c61f9SKrishna Gudipati } 4942a36c61f9SKrishna Gudipati 4943a36c61f9SKrishna Gudipati void 4944a36c61f9SKrishna Gudipati bfa_fcs_lport_clear_stats(struct bfa_fcs_lport_s *fcs_port) 4945a36c61f9SKrishna Gudipati { 49466a18b167SJing Huang memset(&fcs_port->stats, 0, sizeof(struct bfa_lport_stats_s)); 4947a36c61f9SKrishna Gudipati } 4948a36c61f9SKrishna Gudipati 4949a36c61f9SKrishna Gudipati /** 4950a36c61f9SKrishna Gudipati * FCS virtual port state machine 4951a36c61f9SKrishna Gudipati */ 4952a36c61f9SKrishna Gudipati 4953a36c61f9SKrishna Gudipati #define __vport_fcs(__vp) ((__vp)->lport.fcs) 4954a36c61f9SKrishna Gudipati #define __vport_pwwn(__vp) ((__vp)->lport.port_cfg.pwwn) 4955a36c61f9SKrishna Gudipati #define __vport_nwwn(__vp) ((__vp)->lport.port_cfg.nwwn) 4956a36c61f9SKrishna Gudipati #define __vport_bfa(__vp) ((__vp)->lport.fcs->bfa) 4957a36c61f9SKrishna Gudipati #define __vport_fcid(__vp) ((__vp)->lport.pid) 4958a36c61f9SKrishna Gudipati #define __vport_fabric(__vp) ((__vp)->lport.fabric) 4959a36c61f9SKrishna Gudipati #define __vport_vfid(__vp) ((__vp)->lport.fabric->vf_id) 4960a36c61f9SKrishna Gudipati 4961a36c61f9SKrishna Gudipati #define BFA_FCS_VPORT_MAX_RETRIES 5 4962a36c61f9SKrishna Gudipati /* 4963a36c61f9SKrishna Gudipati * Forward declarations 4964a36c61f9SKrishna Gudipati */ 4965a36c61f9SKrishna Gudipati static void bfa_fcs_vport_do_fdisc(struct bfa_fcs_vport_s *vport); 4966a36c61f9SKrishna Gudipati static void bfa_fcs_vport_timeout(void *vport_arg); 4967a36c61f9SKrishna Gudipati static void bfa_fcs_vport_do_logo(struct bfa_fcs_vport_s *vport); 4968a36c61f9SKrishna Gudipati static void bfa_fcs_vport_free(struct bfa_fcs_vport_s *vport); 4969a36c61f9SKrishna Gudipati 4970a36c61f9SKrishna Gudipati /** 4971a36c61f9SKrishna Gudipati * fcs_vport_sm FCS virtual port state machine 4972a36c61f9SKrishna Gudipati */ 4973a36c61f9SKrishna Gudipati 4974a36c61f9SKrishna Gudipati /** 4975a36c61f9SKrishna Gudipati * VPort State Machine events 4976a36c61f9SKrishna Gudipati */ 4977a36c61f9SKrishna Gudipati enum bfa_fcs_vport_event { 4978a36c61f9SKrishna Gudipati BFA_FCS_VPORT_SM_CREATE = 1, /* vport create event */ 4979a36c61f9SKrishna Gudipati BFA_FCS_VPORT_SM_DELETE = 2, /* vport delete event */ 4980a36c61f9SKrishna Gudipati BFA_FCS_VPORT_SM_START = 3, /* vport start request */ 4981a36c61f9SKrishna Gudipati BFA_FCS_VPORT_SM_STOP = 4, /* stop: unsupported */ 4982a36c61f9SKrishna Gudipati BFA_FCS_VPORT_SM_ONLINE = 5, /* fabric online */ 4983a36c61f9SKrishna Gudipati BFA_FCS_VPORT_SM_OFFLINE = 6, /* fabric offline event */ 4984a36c61f9SKrishna Gudipati BFA_FCS_VPORT_SM_FRMSENT = 7, /* fdisc/logo sent events */ 4985a36c61f9SKrishna Gudipati BFA_FCS_VPORT_SM_RSP_OK = 8, /* good response */ 4986a36c61f9SKrishna Gudipati BFA_FCS_VPORT_SM_RSP_ERROR = 9, /* error/bad response */ 4987a36c61f9SKrishna Gudipati BFA_FCS_VPORT_SM_TIMEOUT = 10, /* delay timer event */ 4988a36c61f9SKrishna Gudipati BFA_FCS_VPORT_SM_DELCOMP = 11, /* lport delete completion */ 4989a36c61f9SKrishna Gudipati BFA_FCS_VPORT_SM_RSP_DUP_WWN = 12, /* Dup wnn error*/ 4990a36c61f9SKrishna Gudipati BFA_FCS_VPORT_SM_RSP_FAILED = 13, /* non-retryable failure */ 4991a36c61f9SKrishna Gudipati }; 4992a36c61f9SKrishna Gudipati 4993a36c61f9SKrishna Gudipati static void bfa_fcs_vport_sm_uninit(struct bfa_fcs_vport_s *vport, 4994a36c61f9SKrishna Gudipati enum bfa_fcs_vport_event event); 4995a36c61f9SKrishna Gudipati static void bfa_fcs_vport_sm_created(struct bfa_fcs_vport_s *vport, 4996a36c61f9SKrishna Gudipati enum bfa_fcs_vport_event event); 4997a36c61f9SKrishna Gudipati static void bfa_fcs_vport_sm_offline(struct bfa_fcs_vport_s *vport, 4998a36c61f9SKrishna Gudipati enum bfa_fcs_vport_event event); 4999a36c61f9SKrishna Gudipati static void bfa_fcs_vport_sm_fdisc(struct bfa_fcs_vport_s *vport, 5000a36c61f9SKrishna Gudipati enum bfa_fcs_vport_event event); 5001a36c61f9SKrishna Gudipati static void bfa_fcs_vport_sm_fdisc_retry(struct bfa_fcs_vport_s *vport, 5002a36c61f9SKrishna Gudipati enum bfa_fcs_vport_event event); 5003a36c61f9SKrishna Gudipati static void bfa_fcs_vport_sm_online(struct bfa_fcs_vport_s *vport, 5004a36c61f9SKrishna Gudipati enum bfa_fcs_vport_event event); 5005a36c61f9SKrishna Gudipati static void bfa_fcs_vport_sm_deleting(struct bfa_fcs_vport_s *vport, 5006a36c61f9SKrishna Gudipati enum bfa_fcs_vport_event event); 5007a36c61f9SKrishna Gudipati static void bfa_fcs_vport_sm_cleanup(struct bfa_fcs_vport_s *vport, 5008a36c61f9SKrishna Gudipati enum bfa_fcs_vport_event event); 5009a36c61f9SKrishna Gudipati static void bfa_fcs_vport_sm_logo(struct bfa_fcs_vport_s *vport, 5010a36c61f9SKrishna Gudipati enum bfa_fcs_vport_event event); 5011a36c61f9SKrishna Gudipati static void bfa_fcs_vport_sm_error(struct bfa_fcs_vport_s *vport, 5012a36c61f9SKrishna Gudipati enum bfa_fcs_vport_event event); 5013a36c61f9SKrishna Gudipati 5014a36c61f9SKrishna Gudipati static struct bfa_sm_table_s vport_sm_table[] = { 5015a36c61f9SKrishna Gudipati {BFA_SM(bfa_fcs_vport_sm_uninit), BFA_FCS_VPORT_UNINIT}, 5016a36c61f9SKrishna Gudipati {BFA_SM(bfa_fcs_vport_sm_created), BFA_FCS_VPORT_CREATED}, 5017a36c61f9SKrishna Gudipati {BFA_SM(bfa_fcs_vport_sm_offline), BFA_FCS_VPORT_OFFLINE}, 5018a36c61f9SKrishna Gudipati {BFA_SM(bfa_fcs_vport_sm_fdisc), BFA_FCS_VPORT_FDISC}, 5019a36c61f9SKrishna Gudipati {BFA_SM(bfa_fcs_vport_sm_fdisc_retry), BFA_FCS_VPORT_FDISC_RETRY}, 5020a36c61f9SKrishna Gudipati {BFA_SM(bfa_fcs_vport_sm_online), BFA_FCS_VPORT_ONLINE}, 5021a36c61f9SKrishna Gudipati {BFA_SM(bfa_fcs_vport_sm_deleting), BFA_FCS_VPORT_DELETING}, 5022a36c61f9SKrishna Gudipati {BFA_SM(bfa_fcs_vport_sm_cleanup), BFA_FCS_VPORT_CLEANUP}, 5023a36c61f9SKrishna Gudipati {BFA_SM(bfa_fcs_vport_sm_logo), BFA_FCS_VPORT_LOGO}, 5024a36c61f9SKrishna Gudipati {BFA_SM(bfa_fcs_vport_sm_error), BFA_FCS_VPORT_ERROR} 5025a36c61f9SKrishna Gudipati }; 5026a36c61f9SKrishna Gudipati 5027a36c61f9SKrishna Gudipati /** 5028a36c61f9SKrishna Gudipati * Beginning state. 5029a36c61f9SKrishna Gudipati */ 5030a36c61f9SKrishna Gudipati static void 5031a36c61f9SKrishna Gudipati bfa_fcs_vport_sm_uninit(struct bfa_fcs_vport_s *vport, 5032a36c61f9SKrishna Gudipati enum bfa_fcs_vport_event event) 5033a36c61f9SKrishna Gudipati { 5034a36c61f9SKrishna Gudipati bfa_trc(__vport_fcs(vport), __vport_pwwn(vport)); 5035a36c61f9SKrishna Gudipati bfa_trc(__vport_fcs(vport), event); 5036a36c61f9SKrishna Gudipati 5037a36c61f9SKrishna Gudipati switch (event) { 5038a36c61f9SKrishna Gudipati case BFA_FCS_VPORT_SM_CREATE: 5039a36c61f9SKrishna Gudipati bfa_sm_set_state(vport, bfa_fcs_vport_sm_created); 5040a36c61f9SKrishna Gudipati bfa_fcs_fabric_addvport(__vport_fabric(vport), vport); 5041a36c61f9SKrishna Gudipati break; 5042a36c61f9SKrishna Gudipati 5043a36c61f9SKrishna Gudipati default: 5044a36c61f9SKrishna Gudipati bfa_sm_fault(__vport_fcs(vport), event); 5045a36c61f9SKrishna Gudipati } 5046a36c61f9SKrishna Gudipati } 5047a36c61f9SKrishna Gudipati 5048a36c61f9SKrishna Gudipati /** 5049a36c61f9SKrishna Gudipati * Created state - a start event is required to start up the state machine. 5050a36c61f9SKrishna Gudipati */ 5051a36c61f9SKrishna Gudipati static void 5052a36c61f9SKrishna Gudipati bfa_fcs_vport_sm_created(struct bfa_fcs_vport_s *vport, 5053a36c61f9SKrishna Gudipati enum bfa_fcs_vport_event event) 5054a36c61f9SKrishna Gudipati { 5055a36c61f9SKrishna Gudipati bfa_trc(__vport_fcs(vport), __vport_pwwn(vport)); 5056a36c61f9SKrishna Gudipati bfa_trc(__vport_fcs(vport), event); 5057a36c61f9SKrishna Gudipati 5058a36c61f9SKrishna Gudipati switch (event) { 5059a36c61f9SKrishna Gudipati case BFA_FCS_VPORT_SM_START: 5060a36c61f9SKrishna Gudipati if (bfa_fcs_fabric_is_online(__vport_fabric(vport)) 5061a36c61f9SKrishna Gudipati && bfa_fcs_fabric_npiv_capable(__vport_fabric(vport))) { 5062a36c61f9SKrishna Gudipati bfa_sm_set_state(vport, bfa_fcs_vport_sm_fdisc); 5063a36c61f9SKrishna Gudipati bfa_fcs_vport_do_fdisc(vport); 5064a36c61f9SKrishna Gudipati } else { 5065a36c61f9SKrishna Gudipati /** 5066a36c61f9SKrishna Gudipati * Fabric is offline or not NPIV capable, stay in 5067a36c61f9SKrishna Gudipati * offline state. 5068a36c61f9SKrishna Gudipati */ 5069a36c61f9SKrishna Gudipati vport->vport_stats.fab_no_npiv++; 5070a36c61f9SKrishna Gudipati bfa_sm_set_state(vport, bfa_fcs_vport_sm_offline); 5071a36c61f9SKrishna Gudipati } 5072a36c61f9SKrishna Gudipati break; 5073a36c61f9SKrishna Gudipati 5074a36c61f9SKrishna Gudipati case BFA_FCS_VPORT_SM_DELETE: 5075a36c61f9SKrishna Gudipati bfa_sm_set_state(vport, bfa_fcs_vport_sm_cleanup); 5076a36c61f9SKrishna Gudipati bfa_fcs_lport_delete(&vport->lport); 5077a36c61f9SKrishna Gudipati break; 5078a36c61f9SKrishna Gudipati 5079a36c61f9SKrishna Gudipati case BFA_FCS_VPORT_SM_ONLINE: 5080a36c61f9SKrishna Gudipati case BFA_FCS_VPORT_SM_OFFLINE: 5081a36c61f9SKrishna Gudipati /** 5082a36c61f9SKrishna Gudipati * Ignore ONLINE/OFFLINE events from fabric 5083a36c61f9SKrishna Gudipati * till vport is started. 5084a36c61f9SKrishna Gudipati */ 5085a36c61f9SKrishna Gudipati break; 5086a36c61f9SKrishna Gudipati 5087a36c61f9SKrishna Gudipati default: 5088a36c61f9SKrishna Gudipati bfa_sm_fault(__vport_fcs(vport), event); 5089a36c61f9SKrishna Gudipati } 5090a36c61f9SKrishna Gudipati } 5091a36c61f9SKrishna Gudipati 5092a36c61f9SKrishna Gudipati /** 5093a36c61f9SKrishna Gudipati * Offline state - awaiting ONLINE event from fabric SM. 5094a36c61f9SKrishna Gudipati */ 5095a36c61f9SKrishna Gudipati static void 5096a36c61f9SKrishna Gudipati bfa_fcs_vport_sm_offline(struct bfa_fcs_vport_s *vport, 5097a36c61f9SKrishna Gudipati enum bfa_fcs_vport_event event) 5098a36c61f9SKrishna Gudipati { 5099a36c61f9SKrishna Gudipati bfa_trc(__vport_fcs(vport), __vport_pwwn(vport)); 5100a36c61f9SKrishna Gudipati bfa_trc(__vport_fcs(vport), event); 5101a36c61f9SKrishna Gudipati 5102a36c61f9SKrishna Gudipati switch (event) { 5103a36c61f9SKrishna Gudipati case BFA_FCS_VPORT_SM_DELETE: 5104a36c61f9SKrishna Gudipati bfa_sm_set_state(vport, bfa_fcs_vport_sm_cleanup); 5105a36c61f9SKrishna Gudipati bfa_fcs_lport_delete(&vport->lport); 5106a36c61f9SKrishna Gudipati break; 5107a36c61f9SKrishna Gudipati 5108a36c61f9SKrishna Gudipati case BFA_FCS_VPORT_SM_ONLINE: 5109a36c61f9SKrishna Gudipati bfa_sm_set_state(vport, bfa_fcs_vport_sm_fdisc); 5110a36c61f9SKrishna Gudipati vport->fdisc_retries = 0; 5111a36c61f9SKrishna Gudipati bfa_fcs_vport_do_fdisc(vport); 5112a36c61f9SKrishna Gudipati break; 5113a36c61f9SKrishna Gudipati 5114a36c61f9SKrishna Gudipati case BFA_FCS_VPORT_SM_OFFLINE: 5115a36c61f9SKrishna Gudipati /* 5116a36c61f9SKrishna Gudipati * This can happen if the vport couldn't be initialzied 5117a36c61f9SKrishna Gudipati * due the fact that the npiv was not enabled on the switch. 5118a36c61f9SKrishna Gudipati * In that case we will put the vport in offline state. 5119a36c61f9SKrishna Gudipati * However, the link can go down and cause the this event to 5120a36c61f9SKrishna Gudipati * be sent when we are already offline. Ignore it. 5121a36c61f9SKrishna Gudipati */ 5122a36c61f9SKrishna Gudipati break; 5123a36c61f9SKrishna Gudipati 5124a36c61f9SKrishna Gudipati default: 5125a36c61f9SKrishna Gudipati bfa_sm_fault(__vport_fcs(vport), event); 5126a36c61f9SKrishna Gudipati } 5127a36c61f9SKrishna Gudipati } 5128a36c61f9SKrishna Gudipati 5129a36c61f9SKrishna Gudipati 5130a36c61f9SKrishna Gudipati /** 5131a36c61f9SKrishna Gudipati * FDISC is sent and awaiting reply from fabric. 5132a36c61f9SKrishna Gudipati */ 5133a36c61f9SKrishna Gudipati static void 5134a36c61f9SKrishna Gudipati bfa_fcs_vport_sm_fdisc(struct bfa_fcs_vport_s *vport, 5135a36c61f9SKrishna Gudipati enum bfa_fcs_vport_event event) 5136a36c61f9SKrishna Gudipati { 5137a36c61f9SKrishna Gudipati bfa_trc(__vport_fcs(vport), __vport_pwwn(vport)); 5138a36c61f9SKrishna Gudipati bfa_trc(__vport_fcs(vport), event); 5139a36c61f9SKrishna Gudipati 5140a36c61f9SKrishna Gudipati switch (event) { 5141a36c61f9SKrishna Gudipati case BFA_FCS_VPORT_SM_DELETE: 5142a36c61f9SKrishna Gudipati bfa_sm_set_state(vport, bfa_fcs_vport_sm_cleanup); 5143a36c61f9SKrishna Gudipati bfa_lps_discard(vport->lps); 5144a36c61f9SKrishna Gudipati bfa_fcs_lport_delete(&vport->lport); 5145a36c61f9SKrishna Gudipati break; 5146a36c61f9SKrishna Gudipati 5147a36c61f9SKrishna Gudipati case BFA_FCS_VPORT_SM_OFFLINE: 5148a36c61f9SKrishna Gudipati bfa_sm_set_state(vport, bfa_fcs_vport_sm_offline); 5149a36c61f9SKrishna Gudipati bfa_lps_discard(vport->lps); 5150a36c61f9SKrishna Gudipati break; 5151a36c61f9SKrishna Gudipati 5152a36c61f9SKrishna Gudipati case BFA_FCS_VPORT_SM_RSP_OK: 5153a36c61f9SKrishna Gudipati bfa_sm_set_state(vport, bfa_fcs_vport_sm_online); 5154a36c61f9SKrishna Gudipati bfa_fcs_lport_online(&vport->lport); 5155a36c61f9SKrishna Gudipati break; 5156a36c61f9SKrishna Gudipati 5157a36c61f9SKrishna Gudipati case BFA_FCS_VPORT_SM_RSP_ERROR: 5158a36c61f9SKrishna Gudipati bfa_sm_set_state(vport, bfa_fcs_vport_sm_fdisc_retry); 5159a36c61f9SKrishna Gudipati bfa_timer_start(__vport_bfa(vport), &vport->timer, 5160a36c61f9SKrishna Gudipati bfa_fcs_vport_timeout, vport, 5161a36c61f9SKrishna Gudipati BFA_FCS_RETRY_TIMEOUT); 5162a36c61f9SKrishna Gudipati break; 5163a36c61f9SKrishna Gudipati 5164a36c61f9SKrishna Gudipati case BFA_FCS_VPORT_SM_RSP_FAILED: 5165a36c61f9SKrishna Gudipati bfa_sm_set_state(vport, bfa_fcs_vport_sm_offline); 5166a36c61f9SKrishna Gudipati break; 5167a36c61f9SKrishna Gudipati 5168a36c61f9SKrishna Gudipati case BFA_FCS_VPORT_SM_RSP_DUP_WWN: 5169a36c61f9SKrishna Gudipati bfa_sm_set_state(vport, bfa_fcs_vport_sm_error); 5170a36c61f9SKrishna Gudipati break; 5171a36c61f9SKrishna Gudipati 5172a36c61f9SKrishna Gudipati default: 5173a36c61f9SKrishna Gudipati bfa_sm_fault(__vport_fcs(vport), event); 5174a36c61f9SKrishna Gudipati } 5175a36c61f9SKrishna Gudipati } 5176a36c61f9SKrishna Gudipati 5177a36c61f9SKrishna Gudipati /** 5178a36c61f9SKrishna Gudipati * FDISC attempt failed - a timer is active to retry FDISC. 5179a36c61f9SKrishna Gudipati */ 5180a36c61f9SKrishna Gudipati static void 5181a36c61f9SKrishna Gudipati bfa_fcs_vport_sm_fdisc_retry(struct bfa_fcs_vport_s *vport, 5182a36c61f9SKrishna Gudipati enum bfa_fcs_vport_event event) 5183a36c61f9SKrishna Gudipati { 5184a36c61f9SKrishna Gudipati bfa_trc(__vport_fcs(vport), __vport_pwwn(vport)); 5185a36c61f9SKrishna Gudipati bfa_trc(__vport_fcs(vport), event); 5186a36c61f9SKrishna Gudipati 5187a36c61f9SKrishna Gudipati switch (event) { 5188a36c61f9SKrishna Gudipati case BFA_FCS_VPORT_SM_DELETE: 5189a36c61f9SKrishna Gudipati bfa_sm_set_state(vport, bfa_fcs_vport_sm_cleanup); 5190a36c61f9SKrishna Gudipati bfa_timer_stop(&vport->timer); 5191a36c61f9SKrishna Gudipati bfa_fcs_lport_delete(&vport->lport); 5192a36c61f9SKrishna Gudipati break; 5193a36c61f9SKrishna Gudipati 5194a36c61f9SKrishna Gudipati case BFA_FCS_VPORT_SM_OFFLINE: 5195a36c61f9SKrishna Gudipati bfa_sm_set_state(vport, bfa_fcs_vport_sm_offline); 5196a36c61f9SKrishna Gudipati bfa_timer_stop(&vport->timer); 5197a36c61f9SKrishna Gudipati break; 5198a36c61f9SKrishna Gudipati 5199a36c61f9SKrishna Gudipati case BFA_FCS_VPORT_SM_TIMEOUT: 5200a36c61f9SKrishna Gudipati bfa_sm_set_state(vport, bfa_fcs_vport_sm_fdisc); 5201a36c61f9SKrishna Gudipati vport->vport_stats.fdisc_retries++; 5202a36c61f9SKrishna Gudipati vport->fdisc_retries++; 5203a36c61f9SKrishna Gudipati bfa_fcs_vport_do_fdisc(vport); 5204a36c61f9SKrishna Gudipati break; 5205a36c61f9SKrishna Gudipati 5206a36c61f9SKrishna Gudipati default: 5207a36c61f9SKrishna Gudipati bfa_sm_fault(__vport_fcs(vport), event); 5208a36c61f9SKrishna Gudipati } 5209a36c61f9SKrishna Gudipati } 5210a36c61f9SKrishna Gudipati 5211a36c61f9SKrishna Gudipati /** 5212a36c61f9SKrishna Gudipati * Vport is online (FDISC is complete). 5213a36c61f9SKrishna Gudipati */ 5214a36c61f9SKrishna Gudipati static void 5215a36c61f9SKrishna Gudipati bfa_fcs_vport_sm_online(struct bfa_fcs_vport_s *vport, 5216a36c61f9SKrishna Gudipati enum bfa_fcs_vport_event event) 5217a36c61f9SKrishna Gudipati { 5218a36c61f9SKrishna Gudipati bfa_trc(__vport_fcs(vport), __vport_pwwn(vport)); 5219a36c61f9SKrishna Gudipati bfa_trc(__vport_fcs(vport), event); 5220a36c61f9SKrishna Gudipati 5221a36c61f9SKrishna Gudipati switch (event) { 5222a36c61f9SKrishna Gudipati case BFA_FCS_VPORT_SM_DELETE: 5223a36c61f9SKrishna Gudipati bfa_sm_set_state(vport, bfa_fcs_vport_sm_deleting); 5224a36c61f9SKrishna Gudipati bfa_fcs_lport_delete(&vport->lport); 5225a36c61f9SKrishna Gudipati break; 5226a36c61f9SKrishna Gudipati 5227a36c61f9SKrishna Gudipati case BFA_FCS_VPORT_SM_OFFLINE: 5228a36c61f9SKrishna Gudipati bfa_sm_set_state(vport, bfa_fcs_vport_sm_offline); 5229a36c61f9SKrishna Gudipati bfa_lps_discard(vport->lps); 5230a36c61f9SKrishna Gudipati bfa_fcs_lport_offline(&vport->lport); 5231a36c61f9SKrishna Gudipati break; 5232a36c61f9SKrishna Gudipati 5233a36c61f9SKrishna Gudipati default: 5234a36c61f9SKrishna Gudipati bfa_sm_fault(__vport_fcs(vport), event); 5235a36c61f9SKrishna Gudipati } 5236a36c61f9SKrishna Gudipati } 5237a36c61f9SKrishna Gudipati 5238a36c61f9SKrishna Gudipati /** 5239a36c61f9SKrishna Gudipati * Vport is being deleted - awaiting lport delete completion to send 5240a36c61f9SKrishna Gudipati * LOGO to fabric. 5241a36c61f9SKrishna Gudipati */ 5242a36c61f9SKrishna Gudipati static void 5243a36c61f9SKrishna Gudipati bfa_fcs_vport_sm_deleting(struct bfa_fcs_vport_s *vport, 5244a36c61f9SKrishna Gudipati enum bfa_fcs_vport_event event) 5245a36c61f9SKrishna Gudipati { 5246a36c61f9SKrishna Gudipati bfa_trc(__vport_fcs(vport), __vport_pwwn(vport)); 5247a36c61f9SKrishna Gudipati bfa_trc(__vport_fcs(vport), event); 5248a36c61f9SKrishna Gudipati 5249a36c61f9SKrishna Gudipati switch (event) { 5250a36c61f9SKrishna Gudipati case BFA_FCS_VPORT_SM_DELETE: 5251a36c61f9SKrishna Gudipati break; 5252a36c61f9SKrishna Gudipati 5253a36c61f9SKrishna Gudipati case BFA_FCS_VPORT_SM_DELCOMP: 5254a36c61f9SKrishna Gudipati bfa_sm_set_state(vport, bfa_fcs_vport_sm_logo); 5255a36c61f9SKrishna Gudipati bfa_fcs_vport_do_logo(vport); 5256a36c61f9SKrishna Gudipati break; 5257a36c61f9SKrishna Gudipati 5258a36c61f9SKrishna Gudipati case BFA_FCS_VPORT_SM_OFFLINE: 5259a36c61f9SKrishna Gudipati bfa_sm_set_state(vport, bfa_fcs_vport_sm_cleanup); 5260a36c61f9SKrishna Gudipati break; 5261a36c61f9SKrishna Gudipati 5262a36c61f9SKrishna Gudipati default: 5263a36c61f9SKrishna Gudipati bfa_sm_fault(__vport_fcs(vport), event); 5264a36c61f9SKrishna Gudipati } 5265a36c61f9SKrishna Gudipati } 5266a36c61f9SKrishna Gudipati 5267a36c61f9SKrishna Gudipati /** 5268a36c61f9SKrishna Gudipati * Error State. 5269a36c61f9SKrishna Gudipati * This state will be set when the Vport Creation fails due 5270a36c61f9SKrishna Gudipati * to errors like Dup WWN. In this state only operation allowed 5271a36c61f9SKrishna Gudipati * is a Vport Delete. 5272a36c61f9SKrishna Gudipati */ 5273a36c61f9SKrishna Gudipati static void 5274a36c61f9SKrishna Gudipati bfa_fcs_vport_sm_error(struct bfa_fcs_vport_s *vport, 5275a36c61f9SKrishna Gudipati enum bfa_fcs_vport_event event) 5276a36c61f9SKrishna Gudipati { 5277a36c61f9SKrishna Gudipati bfa_trc(__vport_fcs(vport), __vport_pwwn(vport)); 5278a36c61f9SKrishna Gudipati bfa_trc(__vport_fcs(vport), event); 5279a36c61f9SKrishna Gudipati 5280a36c61f9SKrishna Gudipati switch (event) { 5281a36c61f9SKrishna Gudipati case BFA_FCS_VPORT_SM_DELETE: 5282a36c61f9SKrishna Gudipati bfa_sm_set_state(vport, bfa_fcs_vport_sm_cleanup); 5283a36c61f9SKrishna Gudipati bfa_fcs_lport_delete(&vport->lport); 5284a36c61f9SKrishna Gudipati break; 5285a36c61f9SKrishna Gudipati 5286a36c61f9SKrishna Gudipati default: 5287a36c61f9SKrishna Gudipati bfa_trc(__vport_fcs(vport), event); 5288a36c61f9SKrishna Gudipati } 5289a36c61f9SKrishna Gudipati } 5290a36c61f9SKrishna Gudipati 5291a36c61f9SKrishna Gudipati /** 5292a36c61f9SKrishna Gudipati * Lport cleanup is in progress since vport is being deleted. Fabric is 5293a36c61f9SKrishna Gudipati * offline, so no LOGO is needed to complete vport deletion. 5294a36c61f9SKrishna Gudipati */ 5295a36c61f9SKrishna Gudipati static void 5296a36c61f9SKrishna Gudipati bfa_fcs_vport_sm_cleanup(struct bfa_fcs_vport_s *vport, 5297a36c61f9SKrishna Gudipati enum bfa_fcs_vport_event event) 5298a36c61f9SKrishna Gudipati { 5299a36c61f9SKrishna Gudipati bfa_trc(__vport_fcs(vport), __vport_pwwn(vport)); 5300a36c61f9SKrishna Gudipati bfa_trc(__vport_fcs(vport), event); 5301a36c61f9SKrishna Gudipati 5302a36c61f9SKrishna Gudipati switch (event) { 5303a36c61f9SKrishna Gudipati case BFA_FCS_VPORT_SM_DELCOMP: 5304a36c61f9SKrishna Gudipati bfa_sm_set_state(vport, bfa_fcs_vport_sm_uninit); 5305a36c61f9SKrishna Gudipati bfa_fcs_vport_free(vport); 5306a36c61f9SKrishna Gudipati break; 5307a36c61f9SKrishna Gudipati 5308a36c61f9SKrishna Gudipati case BFA_FCS_VPORT_SM_DELETE: 5309a36c61f9SKrishna Gudipati break; 5310a36c61f9SKrishna Gudipati 5311a36c61f9SKrishna Gudipati default: 5312a36c61f9SKrishna Gudipati bfa_sm_fault(__vport_fcs(vport), event); 5313a36c61f9SKrishna Gudipati } 5314a36c61f9SKrishna Gudipati } 5315a36c61f9SKrishna Gudipati 5316a36c61f9SKrishna Gudipati /** 5317a36c61f9SKrishna Gudipati * LOGO is sent to fabric. Vport delete is in progress. Lport delete cleanup 5318a36c61f9SKrishna Gudipati * is done. 5319a36c61f9SKrishna Gudipati */ 5320a36c61f9SKrishna Gudipati static void 5321a36c61f9SKrishna Gudipati bfa_fcs_vport_sm_logo(struct bfa_fcs_vport_s *vport, 5322a36c61f9SKrishna Gudipati enum bfa_fcs_vport_event event) 5323a36c61f9SKrishna Gudipati { 5324a36c61f9SKrishna Gudipati bfa_trc(__vport_fcs(vport), __vport_pwwn(vport)); 5325a36c61f9SKrishna Gudipati bfa_trc(__vport_fcs(vport), event); 5326a36c61f9SKrishna Gudipati 5327a36c61f9SKrishna Gudipati switch (event) { 5328a36c61f9SKrishna Gudipati case BFA_FCS_VPORT_SM_OFFLINE: 5329a36c61f9SKrishna Gudipati bfa_lps_discard(vport->lps); 5330a36c61f9SKrishna Gudipati /* 5331a36c61f9SKrishna Gudipati * !!! fall through !!! 5332a36c61f9SKrishna Gudipati */ 5333a36c61f9SKrishna Gudipati 5334a36c61f9SKrishna Gudipati case BFA_FCS_VPORT_SM_RSP_OK: 5335a36c61f9SKrishna Gudipati case BFA_FCS_VPORT_SM_RSP_ERROR: 5336a36c61f9SKrishna Gudipati bfa_sm_set_state(vport, bfa_fcs_vport_sm_uninit); 5337a36c61f9SKrishna Gudipati bfa_fcs_vport_free(vport); 5338a36c61f9SKrishna Gudipati break; 5339a36c61f9SKrishna Gudipati 5340a36c61f9SKrishna Gudipati case BFA_FCS_VPORT_SM_DELETE: 5341a36c61f9SKrishna Gudipati break; 5342a36c61f9SKrishna Gudipati 5343a36c61f9SKrishna Gudipati default: 5344a36c61f9SKrishna Gudipati bfa_sm_fault(__vport_fcs(vport), event); 5345a36c61f9SKrishna Gudipati } 5346a36c61f9SKrishna Gudipati } 5347a36c61f9SKrishna Gudipati 5348a36c61f9SKrishna Gudipati 5349a36c61f9SKrishna Gudipati 5350a36c61f9SKrishna Gudipati /** 5351a36c61f9SKrishna Gudipati * fcs_vport_private FCS virtual port private functions 5352a36c61f9SKrishna Gudipati */ 5353a36c61f9SKrishna Gudipati /** 5354a36c61f9SKrishna Gudipati * This routine will be called to send a FDISC command. 5355a36c61f9SKrishna Gudipati */ 5356a36c61f9SKrishna Gudipati static void 5357a36c61f9SKrishna Gudipati bfa_fcs_vport_do_fdisc(struct bfa_fcs_vport_s *vport) 5358a36c61f9SKrishna Gudipati { 5359a36c61f9SKrishna Gudipati bfa_lps_fdisc(vport->lps, vport, 5360a36c61f9SKrishna Gudipati bfa_fcport_get_maxfrsize(__vport_bfa(vport)), 5361a36c61f9SKrishna Gudipati __vport_pwwn(vport), __vport_nwwn(vport)); 5362a36c61f9SKrishna Gudipati vport->vport_stats.fdisc_sent++; 5363a36c61f9SKrishna Gudipati } 5364a36c61f9SKrishna Gudipati 5365a36c61f9SKrishna Gudipati static void 5366a36c61f9SKrishna Gudipati bfa_fcs_vport_fdisc_rejected(struct bfa_fcs_vport_s *vport) 5367a36c61f9SKrishna Gudipati { 5368a36c61f9SKrishna Gudipati u8 lsrjt_rsn = bfa_lps_get_lsrjt_rsn(vport->lps); 5369a36c61f9SKrishna Gudipati u8 lsrjt_expl = bfa_lps_get_lsrjt_expl(vport->lps); 5370a36c61f9SKrishna Gudipati 5371a36c61f9SKrishna Gudipati bfa_trc(__vport_fcs(vport), lsrjt_rsn); 5372a36c61f9SKrishna Gudipati bfa_trc(__vport_fcs(vport), lsrjt_expl); 5373a36c61f9SKrishna Gudipati 5374a36c61f9SKrishna Gudipati /* For certain reason codes, we don't want to retry. */ 5375a36c61f9SKrishna Gudipati switch (bfa_lps_get_lsrjt_expl(vport->lps)) { 5376a36c61f9SKrishna Gudipati case FC_LS_RJT_EXP_INV_PORT_NAME: /* by brocade */ 5377a36c61f9SKrishna Gudipati case FC_LS_RJT_EXP_INVALID_NPORT_ID: /* by Cisco */ 5378a36c61f9SKrishna Gudipati if (vport->fdisc_retries < BFA_FCS_VPORT_MAX_RETRIES) 5379a36c61f9SKrishna Gudipati bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_ERROR); 5380a36c61f9SKrishna Gudipati else 5381a36c61f9SKrishna Gudipati bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_DUP_WWN); 5382a36c61f9SKrishna Gudipati break; 5383a36c61f9SKrishna Gudipati 5384a36c61f9SKrishna Gudipati case FC_LS_RJT_EXP_INSUFF_RES: 5385a36c61f9SKrishna Gudipati /* 5386a36c61f9SKrishna Gudipati * This means max logins per port/switch setting on the 5387a36c61f9SKrishna Gudipati * switch was exceeded. 5388a36c61f9SKrishna Gudipati */ 5389a36c61f9SKrishna Gudipati if (vport->fdisc_retries < BFA_FCS_VPORT_MAX_RETRIES) 5390a36c61f9SKrishna Gudipati bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_ERROR); 5391a36c61f9SKrishna Gudipati else 5392a36c61f9SKrishna Gudipati bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_FAILED); 5393a36c61f9SKrishna Gudipati break; 5394a36c61f9SKrishna Gudipati 5395a36c61f9SKrishna Gudipati default: 5396a36c61f9SKrishna Gudipati bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_ERROR); 5397a36c61f9SKrishna Gudipati } 5398a36c61f9SKrishna Gudipati } 5399a36c61f9SKrishna Gudipati 5400a36c61f9SKrishna Gudipati /** 5401a36c61f9SKrishna Gudipati * Called to send a logout to the fabric. Used when a V-Port is 5402a36c61f9SKrishna Gudipati * deleted/stopped. 5403a36c61f9SKrishna Gudipati */ 5404a36c61f9SKrishna Gudipati static void 5405a36c61f9SKrishna Gudipati bfa_fcs_vport_do_logo(struct bfa_fcs_vport_s *vport) 5406a36c61f9SKrishna Gudipati { 5407a36c61f9SKrishna Gudipati bfa_trc(__vport_fcs(vport), __vport_pwwn(vport)); 5408a36c61f9SKrishna Gudipati 5409a36c61f9SKrishna Gudipati vport->vport_stats.logo_sent++; 5410a36c61f9SKrishna Gudipati bfa_lps_fdisclogo(vport->lps); 5411a36c61f9SKrishna Gudipati } 5412a36c61f9SKrishna Gudipati 5413a36c61f9SKrishna Gudipati 5414a36c61f9SKrishna Gudipati /** 5415a36c61f9SKrishna Gudipati * This routine will be called by bfa_timer on timer timeouts. 5416a36c61f9SKrishna Gudipati * 5417a36c61f9SKrishna Gudipati * param[in] vport - pointer to bfa_fcs_vport_t. 5418a36c61f9SKrishna Gudipati * param[out] vport_status - pointer to return vport status in 5419a36c61f9SKrishna Gudipati * 5420a36c61f9SKrishna Gudipati * return 5421a36c61f9SKrishna Gudipati * void 5422a36c61f9SKrishna Gudipati * 5423a36c61f9SKrishna Gudipati * Special Considerations: 5424a36c61f9SKrishna Gudipati * 5425a36c61f9SKrishna Gudipati * note 5426a36c61f9SKrishna Gudipati */ 5427a36c61f9SKrishna Gudipati static void 5428a36c61f9SKrishna Gudipati bfa_fcs_vport_timeout(void *vport_arg) 5429a36c61f9SKrishna Gudipati { 5430a36c61f9SKrishna Gudipati struct bfa_fcs_vport_s *vport = (struct bfa_fcs_vport_s *) vport_arg; 5431a36c61f9SKrishna Gudipati 5432a36c61f9SKrishna Gudipati vport->vport_stats.fdisc_timeouts++; 5433a36c61f9SKrishna Gudipati bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_TIMEOUT); 5434a36c61f9SKrishna Gudipati } 5435a36c61f9SKrishna Gudipati 5436a36c61f9SKrishna Gudipati static void 5437a36c61f9SKrishna Gudipati bfa_fcs_vport_free(struct bfa_fcs_vport_s *vport) 5438a36c61f9SKrishna Gudipati { 5439a36c61f9SKrishna Gudipati struct bfad_vport_s *vport_drv = 5440a36c61f9SKrishna Gudipati (struct bfad_vport_s *)vport->vport_drv; 5441a36c61f9SKrishna Gudipati 5442a36c61f9SKrishna Gudipati bfa_fcs_fabric_delvport(__vport_fabric(vport), vport); 5443a36c61f9SKrishna Gudipati 5444a36c61f9SKrishna Gudipati if (vport_drv->comp_del) 5445a36c61f9SKrishna Gudipati complete(vport_drv->comp_del); 5446a36c61f9SKrishna Gudipati 5447a36c61f9SKrishna Gudipati bfa_lps_delete(vport->lps); 5448a36c61f9SKrishna Gudipati } 5449a36c61f9SKrishna Gudipati 5450a36c61f9SKrishna Gudipati 5451a36c61f9SKrishna Gudipati 5452a36c61f9SKrishna Gudipati /** 5453a36c61f9SKrishna Gudipati * fcs_vport_public FCS virtual port public interfaces 5454a36c61f9SKrishna Gudipati */ 5455a36c61f9SKrishna Gudipati 5456a36c61f9SKrishna Gudipati /** 5457a36c61f9SKrishna Gudipati * Online notification from fabric SM. 5458a36c61f9SKrishna Gudipati */ 5459a36c61f9SKrishna Gudipati void 5460a36c61f9SKrishna Gudipati bfa_fcs_vport_online(struct bfa_fcs_vport_s *vport) 5461a36c61f9SKrishna Gudipati { 5462a36c61f9SKrishna Gudipati vport->vport_stats.fab_online++; 5463a36c61f9SKrishna Gudipati bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_ONLINE); 5464a36c61f9SKrishna Gudipati } 5465a36c61f9SKrishna Gudipati 5466a36c61f9SKrishna Gudipati /** 5467a36c61f9SKrishna Gudipati * Offline notification from fabric SM. 5468a36c61f9SKrishna Gudipati */ 5469a36c61f9SKrishna Gudipati void 5470a36c61f9SKrishna Gudipati bfa_fcs_vport_offline(struct bfa_fcs_vport_s *vport) 5471a36c61f9SKrishna Gudipati { 5472a36c61f9SKrishna Gudipati vport->vport_stats.fab_offline++; 5473a36c61f9SKrishna Gudipati bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_OFFLINE); 5474a36c61f9SKrishna Gudipati } 5475a36c61f9SKrishna Gudipati 5476a36c61f9SKrishna Gudipati /** 5477a36c61f9SKrishna Gudipati * Cleanup notification from fabric SM on link timer expiry. 5478a36c61f9SKrishna Gudipati */ 5479a36c61f9SKrishna Gudipati void 5480a36c61f9SKrishna Gudipati bfa_fcs_vport_cleanup(struct bfa_fcs_vport_s *vport) 5481a36c61f9SKrishna Gudipati { 5482a36c61f9SKrishna Gudipati vport->vport_stats.fab_cleanup++; 5483a36c61f9SKrishna Gudipati } 5484a36c61f9SKrishna Gudipati /** 5485a36c61f9SKrishna Gudipati * delete notification from fabric SM. To be invoked from within FCS. 5486a36c61f9SKrishna Gudipati */ 5487a36c61f9SKrishna Gudipati void 5488a36c61f9SKrishna Gudipati bfa_fcs_vport_fcs_delete(struct bfa_fcs_vport_s *vport) 5489a36c61f9SKrishna Gudipati { 5490a36c61f9SKrishna Gudipati bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_DELETE); 5491a36c61f9SKrishna Gudipati } 5492a36c61f9SKrishna Gudipati 5493a36c61f9SKrishna Gudipati /** 5494a36c61f9SKrishna Gudipati * Delete completion callback from associated lport 5495a36c61f9SKrishna Gudipati */ 5496a36c61f9SKrishna Gudipati void 5497a36c61f9SKrishna Gudipati bfa_fcs_vport_delete_comp(struct bfa_fcs_vport_s *vport) 5498a36c61f9SKrishna Gudipati { 5499a36c61f9SKrishna Gudipati bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_DELCOMP); 5500a36c61f9SKrishna Gudipati } 5501a36c61f9SKrishna Gudipati 5502a36c61f9SKrishna Gudipati 5503a36c61f9SKrishna Gudipati 5504a36c61f9SKrishna Gudipati /** 5505a36c61f9SKrishna Gudipati * fcs_vport_api Virtual port API 5506a36c61f9SKrishna Gudipati */ 5507a36c61f9SKrishna Gudipati 5508a36c61f9SKrishna Gudipati /** 5509a36c61f9SKrishna Gudipati * Use this function to instantiate a new FCS vport object. This 5510a36c61f9SKrishna Gudipati * function will not trigger any HW initialization process (which will be 5511a36c61f9SKrishna Gudipati * done in vport_start() call) 5512a36c61f9SKrishna Gudipati * 5513a36c61f9SKrishna Gudipati * param[in] vport - pointer to bfa_fcs_vport_t. This space 5514a36c61f9SKrishna Gudipati * needs to be allocated by the driver. 5515a36c61f9SKrishna Gudipati * param[in] fcs - FCS instance 5516a36c61f9SKrishna Gudipati * param[in] vport_cfg - vport configuration 5517a36c61f9SKrishna Gudipati * param[in] vf_id - VF_ID if vport is created within a VF. 5518a36c61f9SKrishna Gudipati * FC_VF_ID_NULL to specify base fabric. 5519a36c61f9SKrishna Gudipati * param[in] vport_drv - Opaque handle back to the driver's vport 5520a36c61f9SKrishna Gudipati * structure 5521a36c61f9SKrishna Gudipati * 5522a36c61f9SKrishna Gudipati * retval BFA_STATUS_OK - on success. 5523a36c61f9SKrishna Gudipati * retval BFA_STATUS_FAILED - on failure. 5524a36c61f9SKrishna Gudipati */ 5525a36c61f9SKrishna Gudipati bfa_status_t 5526a36c61f9SKrishna Gudipati bfa_fcs_vport_create(struct bfa_fcs_vport_s *vport, struct bfa_fcs_s *fcs, 5527a36c61f9SKrishna Gudipati u16 vf_id, struct bfa_lport_cfg_s *vport_cfg, 5528a36c61f9SKrishna Gudipati struct bfad_vport_s *vport_drv) 5529a36c61f9SKrishna Gudipati { 5530a36c61f9SKrishna Gudipati if (vport_cfg->pwwn == 0) 5531a36c61f9SKrishna Gudipati return BFA_STATUS_INVALID_WWN; 5532a36c61f9SKrishna Gudipati 5533a36c61f9SKrishna Gudipati if (bfa_fcs_lport_get_pwwn(&fcs->fabric.bport) == vport_cfg->pwwn) 5534a36c61f9SKrishna Gudipati return BFA_STATUS_VPORT_WWN_BP; 5535a36c61f9SKrishna Gudipati 5536a36c61f9SKrishna Gudipati if (bfa_fcs_vport_lookup(fcs, vf_id, vport_cfg->pwwn) != NULL) 5537a36c61f9SKrishna Gudipati return BFA_STATUS_VPORT_EXISTS; 5538a36c61f9SKrishna Gudipati 5539a36c61f9SKrishna Gudipati if (bfa_fcs_fabric_vport_count(&fcs->fabric) == 5540a36c61f9SKrishna Gudipati bfa_lps_get_max_vport(fcs->bfa)) 5541a36c61f9SKrishna Gudipati return BFA_STATUS_VPORT_MAX; 5542a36c61f9SKrishna Gudipati 5543a36c61f9SKrishna Gudipati vport->lps = bfa_lps_alloc(fcs->bfa); 5544a36c61f9SKrishna Gudipati if (!vport->lps) 5545a36c61f9SKrishna Gudipati return BFA_STATUS_VPORT_MAX; 5546a36c61f9SKrishna Gudipati 5547a36c61f9SKrishna Gudipati vport->vport_drv = vport_drv; 5548a36c61f9SKrishna Gudipati vport_cfg->preboot_vp = BFA_FALSE; 5549a36c61f9SKrishna Gudipati 5550a36c61f9SKrishna Gudipati bfa_sm_set_state(vport, bfa_fcs_vport_sm_uninit); 5551a36c61f9SKrishna Gudipati bfa_fcs_lport_attach(&vport->lport, fcs, vf_id, vport); 5552a36c61f9SKrishna Gudipati bfa_fcs_lport_init(&vport->lport, vport_cfg); 5553a36c61f9SKrishna Gudipati bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_CREATE); 5554a36c61f9SKrishna Gudipati 5555a36c61f9SKrishna Gudipati return BFA_STATUS_OK; 5556a36c61f9SKrishna Gudipati } 5557a36c61f9SKrishna Gudipati 5558a36c61f9SKrishna Gudipati /** 5559a36c61f9SKrishna Gudipati * Use this function to instantiate a new FCS PBC vport object. This 5560a36c61f9SKrishna Gudipati * function will not trigger any HW initialization process (which will be 5561a36c61f9SKrishna Gudipati * done in vport_start() call) 5562a36c61f9SKrishna Gudipati * 5563a36c61f9SKrishna Gudipati * param[in] vport - pointer to bfa_fcs_vport_t. This space 5564a36c61f9SKrishna Gudipati * needs to be allocated by the driver. 5565a36c61f9SKrishna Gudipati * param[in] fcs - FCS instance 5566a36c61f9SKrishna Gudipati * param[in] vport_cfg - vport configuration 5567a36c61f9SKrishna Gudipati * param[in] vf_id - VF_ID if vport is created within a VF. 5568a36c61f9SKrishna Gudipati * FC_VF_ID_NULL to specify base fabric. 5569a36c61f9SKrishna Gudipati * param[in] vport_drv - Opaque handle back to the driver's vport 5570a36c61f9SKrishna Gudipati * structure 5571a36c61f9SKrishna Gudipati * 5572a36c61f9SKrishna Gudipati * retval BFA_STATUS_OK - on success. 5573a36c61f9SKrishna Gudipati * retval BFA_STATUS_FAILED - on failure. 5574a36c61f9SKrishna Gudipati */ 5575a36c61f9SKrishna Gudipati bfa_status_t 5576a36c61f9SKrishna Gudipati bfa_fcs_pbc_vport_create(struct bfa_fcs_vport_s *vport, struct bfa_fcs_s *fcs, 5577a36c61f9SKrishna Gudipati u16 vf_id, struct bfa_lport_cfg_s *vport_cfg, 5578a36c61f9SKrishna Gudipati struct bfad_vport_s *vport_drv) 5579a36c61f9SKrishna Gudipati { 5580a36c61f9SKrishna Gudipati bfa_status_t rc; 5581a36c61f9SKrishna Gudipati 5582a36c61f9SKrishna Gudipati rc = bfa_fcs_vport_create(vport, fcs, vf_id, vport_cfg, vport_drv); 5583a36c61f9SKrishna Gudipati vport->lport.port_cfg.preboot_vp = BFA_TRUE; 5584a36c61f9SKrishna Gudipati 5585a36c61f9SKrishna Gudipati return rc; 5586a36c61f9SKrishna Gudipati } 5587a36c61f9SKrishna Gudipati 5588a36c61f9SKrishna Gudipati /** 5589a36c61f9SKrishna Gudipati * Use this function to findout if this is a pbc vport or not. 5590a36c61f9SKrishna Gudipati * 5591a36c61f9SKrishna Gudipati * @param[in] vport - pointer to bfa_fcs_vport_t. 5592a36c61f9SKrishna Gudipati * 5593a36c61f9SKrishna Gudipati * @returns None 5594a36c61f9SKrishna Gudipati */ 5595a36c61f9SKrishna Gudipati bfa_boolean_t 5596a36c61f9SKrishna Gudipati bfa_fcs_is_pbc_vport(struct bfa_fcs_vport_s *vport) 5597a36c61f9SKrishna Gudipati { 5598a36c61f9SKrishna Gudipati 5599a36c61f9SKrishna Gudipati if (vport && (vport->lport.port_cfg.preboot_vp == BFA_TRUE)) 5600a36c61f9SKrishna Gudipati return BFA_TRUE; 5601a36c61f9SKrishna Gudipati else 5602a36c61f9SKrishna Gudipati return BFA_FALSE; 5603a36c61f9SKrishna Gudipati 5604a36c61f9SKrishna Gudipati } 5605a36c61f9SKrishna Gudipati 5606a36c61f9SKrishna Gudipati /** 5607a36c61f9SKrishna Gudipati * Use this function initialize the vport. 5608a36c61f9SKrishna Gudipati * 5609a36c61f9SKrishna Gudipati * @param[in] vport - pointer to bfa_fcs_vport_t. 5610a36c61f9SKrishna Gudipati * 5611a36c61f9SKrishna Gudipati * @returns None 5612a36c61f9SKrishna Gudipati */ 5613a36c61f9SKrishna Gudipati bfa_status_t 5614a36c61f9SKrishna Gudipati bfa_fcs_vport_start(struct bfa_fcs_vport_s *vport) 5615a36c61f9SKrishna Gudipati { 5616a36c61f9SKrishna Gudipati bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_START); 5617a36c61f9SKrishna Gudipati 5618a36c61f9SKrishna Gudipati return BFA_STATUS_OK; 5619a36c61f9SKrishna Gudipati } 5620a36c61f9SKrishna Gudipati 5621a36c61f9SKrishna Gudipati /** 5622a36c61f9SKrishna Gudipati * Use this function quiese the vport object. This function will return 5623a36c61f9SKrishna Gudipati * immediately, when the vport is actually stopped, the 5624a36c61f9SKrishna Gudipati * bfa_drv_vport_stop_cb() will be called. 5625a36c61f9SKrishna Gudipati * 5626a36c61f9SKrishna Gudipati * param[in] vport - pointer to bfa_fcs_vport_t. 5627a36c61f9SKrishna Gudipati * 5628a36c61f9SKrishna Gudipati * return None 5629a36c61f9SKrishna Gudipati */ 5630a36c61f9SKrishna Gudipati bfa_status_t 5631a36c61f9SKrishna Gudipati bfa_fcs_vport_stop(struct bfa_fcs_vport_s *vport) 5632a36c61f9SKrishna Gudipati { 5633a36c61f9SKrishna Gudipati bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_STOP); 5634a36c61f9SKrishna Gudipati 5635a36c61f9SKrishna Gudipati return BFA_STATUS_OK; 5636a36c61f9SKrishna Gudipati } 5637a36c61f9SKrishna Gudipati 5638a36c61f9SKrishna Gudipati /** 5639a36c61f9SKrishna Gudipati * Use this function to delete a vport object. Fabric object should 5640a36c61f9SKrishna Gudipati * be stopped before this function call. 5641a36c61f9SKrishna Gudipati * 5642a36c61f9SKrishna Gudipati * !!!!!!! Donot invoke this from within FCS !!!!!!! 5643a36c61f9SKrishna Gudipati * 5644a36c61f9SKrishna Gudipati * param[in] vport - pointer to bfa_fcs_vport_t. 5645a36c61f9SKrishna Gudipati * 5646a36c61f9SKrishna Gudipati * return None 5647a36c61f9SKrishna Gudipati */ 5648a36c61f9SKrishna Gudipati bfa_status_t 5649a36c61f9SKrishna Gudipati bfa_fcs_vport_delete(struct bfa_fcs_vport_s *vport) 5650a36c61f9SKrishna Gudipati { 5651a36c61f9SKrishna Gudipati 5652a36c61f9SKrishna Gudipati if (vport->lport.port_cfg.preboot_vp) 5653a36c61f9SKrishna Gudipati return BFA_STATUS_PBC; 5654a36c61f9SKrishna Gudipati 5655a36c61f9SKrishna Gudipati bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_DELETE); 5656a36c61f9SKrishna Gudipati 5657a36c61f9SKrishna Gudipati return BFA_STATUS_OK; 5658a36c61f9SKrishna Gudipati } 5659a36c61f9SKrishna Gudipati 5660a36c61f9SKrishna Gudipati /** 5661a36c61f9SKrishna Gudipati * Use this function to get vport's current status info. 5662a36c61f9SKrishna Gudipati * 5663a36c61f9SKrishna Gudipati * param[in] vport pointer to bfa_fcs_vport_t. 5664a36c61f9SKrishna Gudipati * param[out] attr pointer to return vport attributes 5665a36c61f9SKrishna Gudipati * 5666a36c61f9SKrishna Gudipati * return None 5667a36c61f9SKrishna Gudipati */ 5668a36c61f9SKrishna Gudipati void 5669a36c61f9SKrishna Gudipati bfa_fcs_vport_get_attr(struct bfa_fcs_vport_s *vport, 5670a36c61f9SKrishna Gudipati struct bfa_vport_attr_s *attr) 5671a36c61f9SKrishna Gudipati { 5672a36c61f9SKrishna Gudipati if (vport == NULL || attr == NULL) 5673a36c61f9SKrishna Gudipati return; 5674a36c61f9SKrishna Gudipati 56756a18b167SJing Huang memset(attr, 0, sizeof(struct bfa_vport_attr_s)); 5676a36c61f9SKrishna Gudipati 5677a36c61f9SKrishna Gudipati bfa_fcs_lport_get_attr(&vport->lport, &attr->port_attr); 5678a36c61f9SKrishna Gudipati attr->vport_state = bfa_sm_to_state(vport_sm_table, vport->sm); 5679a36c61f9SKrishna Gudipati } 5680a36c61f9SKrishna Gudipati 5681a36c61f9SKrishna Gudipati /** 5682a36c61f9SKrishna Gudipati * Use this function to get vport's statistics. 5683a36c61f9SKrishna Gudipati * 5684a36c61f9SKrishna Gudipati * param[in] vport pointer to bfa_fcs_vport_t. 5685a36c61f9SKrishna Gudipati * param[out] stats pointer to return vport statistics in 5686a36c61f9SKrishna Gudipati * 5687a36c61f9SKrishna Gudipati * return None 5688a36c61f9SKrishna Gudipati */ 5689a36c61f9SKrishna Gudipati void 5690a36c61f9SKrishna Gudipati bfa_fcs_vport_get_stats(struct bfa_fcs_vport_s *vport, 5691a36c61f9SKrishna Gudipati struct bfa_vport_stats_s *stats) 5692a36c61f9SKrishna Gudipati { 5693a36c61f9SKrishna Gudipati *stats = vport->vport_stats; 5694a36c61f9SKrishna Gudipati } 5695a36c61f9SKrishna Gudipati 5696a36c61f9SKrishna Gudipati /** 5697a36c61f9SKrishna Gudipati * Use this function to clear vport's statistics. 5698a36c61f9SKrishna Gudipati * 5699a36c61f9SKrishna Gudipati * param[in] vport pointer to bfa_fcs_vport_t. 5700a36c61f9SKrishna Gudipati * 5701a36c61f9SKrishna Gudipati * return None 5702a36c61f9SKrishna Gudipati */ 5703a36c61f9SKrishna Gudipati void 5704a36c61f9SKrishna Gudipati bfa_fcs_vport_clr_stats(struct bfa_fcs_vport_s *vport) 5705a36c61f9SKrishna Gudipati { 57066a18b167SJing Huang memset(&vport->vport_stats, 0, sizeof(struct bfa_vport_stats_s)); 5707a36c61f9SKrishna Gudipati } 5708a36c61f9SKrishna Gudipati 5709a36c61f9SKrishna Gudipati /** 5710a36c61f9SKrishna Gudipati * Lookup a virtual port. Excludes base port from lookup. 5711a36c61f9SKrishna Gudipati */ 5712a36c61f9SKrishna Gudipati struct bfa_fcs_vport_s * 5713a36c61f9SKrishna Gudipati bfa_fcs_vport_lookup(struct bfa_fcs_s *fcs, u16 vf_id, wwn_t vpwwn) 5714a36c61f9SKrishna Gudipati { 5715a36c61f9SKrishna Gudipati struct bfa_fcs_vport_s *vport; 5716a36c61f9SKrishna Gudipati struct bfa_fcs_fabric_s *fabric; 5717a36c61f9SKrishna Gudipati 5718a36c61f9SKrishna Gudipati bfa_trc(fcs, vf_id); 5719a36c61f9SKrishna Gudipati bfa_trc(fcs, vpwwn); 5720a36c61f9SKrishna Gudipati 5721a36c61f9SKrishna Gudipati fabric = bfa_fcs_vf_lookup(fcs, vf_id); 5722a36c61f9SKrishna Gudipati if (!fabric) { 5723a36c61f9SKrishna Gudipati bfa_trc(fcs, vf_id); 5724a36c61f9SKrishna Gudipati return NULL; 5725a36c61f9SKrishna Gudipati } 5726a36c61f9SKrishna Gudipati 5727a36c61f9SKrishna Gudipati vport = bfa_fcs_fabric_vport_lookup(fabric, vpwwn); 5728a36c61f9SKrishna Gudipati return vport; 5729a36c61f9SKrishna Gudipati } 5730a36c61f9SKrishna Gudipati 5731a36c61f9SKrishna Gudipati /** 5732a36c61f9SKrishna Gudipati * FDISC Response 5733a36c61f9SKrishna Gudipati */ 5734a36c61f9SKrishna Gudipati void 5735a36c61f9SKrishna Gudipati bfa_cb_lps_fdisc_comp(void *bfad, void *uarg, bfa_status_t status) 5736a36c61f9SKrishna Gudipati { 5737a36c61f9SKrishna Gudipati struct bfa_fcs_vport_s *vport = uarg; 5738a36c61f9SKrishna Gudipati 5739a36c61f9SKrishna Gudipati bfa_trc(__vport_fcs(vport), __vport_pwwn(vport)); 5740a36c61f9SKrishna Gudipati bfa_trc(__vport_fcs(vport), status); 5741a36c61f9SKrishna Gudipati 5742a36c61f9SKrishna Gudipati switch (status) { 5743a36c61f9SKrishna Gudipati case BFA_STATUS_OK: 5744a36c61f9SKrishna Gudipati /* 5745a36c61f9SKrishna Gudipati * Initialiaze the V-Port fields 5746a36c61f9SKrishna Gudipati */ 5747a36c61f9SKrishna Gudipati __vport_fcid(vport) = bfa_lps_get_pid(vport->lps); 5748a36c61f9SKrishna Gudipati vport->vport_stats.fdisc_accepts++; 5749a36c61f9SKrishna Gudipati bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_OK); 5750a36c61f9SKrishna Gudipati break; 5751a36c61f9SKrishna Gudipati 5752a36c61f9SKrishna Gudipati case BFA_STATUS_INVALID_MAC: 5753a36c61f9SKrishna Gudipati /* Only for CNA */ 5754a36c61f9SKrishna Gudipati vport->vport_stats.fdisc_acc_bad++; 5755a36c61f9SKrishna Gudipati bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_ERROR); 5756a36c61f9SKrishna Gudipati 5757a36c61f9SKrishna Gudipati break; 5758a36c61f9SKrishna Gudipati 5759a36c61f9SKrishna Gudipati case BFA_STATUS_EPROTOCOL: 5760a36c61f9SKrishna Gudipati switch (bfa_lps_get_extstatus(vport->lps)) { 5761a36c61f9SKrishna Gudipati case BFA_EPROTO_BAD_ACCEPT: 5762a36c61f9SKrishna Gudipati vport->vport_stats.fdisc_acc_bad++; 5763a36c61f9SKrishna Gudipati break; 5764a36c61f9SKrishna Gudipati 5765a36c61f9SKrishna Gudipati case BFA_EPROTO_UNKNOWN_RSP: 5766a36c61f9SKrishna Gudipati vport->vport_stats.fdisc_unknown_rsp++; 5767a36c61f9SKrishna Gudipati break; 5768a36c61f9SKrishna Gudipati 5769a36c61f9SKrishna Gudipati default: 5770a36c61f9SKrishna Gudipati break; 5771a36c61f9SKrishna Gudipati } 5772a36c61f9SKrishna Gudipati 5773a36c61f9SKrishna Gudipati bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_ERROR); 5774a36c61f9SKrishna Gudipati break; 5775a36c61f9SKrishna Gudipati 5776a36c61f9SKrishna Gudipati case BFA_STATUS_FABRIC_RJT: 5777a36c61f9SKrishna Gudipati vport->vport_stats.fdisc_rejects++; 5778a36c61f9SKrishna Gudipati bfa_fcs_vport_fdisc_rejected(vport); 5779a36c61f9SKrishna Gudipati break; 5780a36c61f9SKrishna Gudipati 5781a36c61f9SKrishna Gudipati default: 5782a36c61f9SKrishna Gudipati vport->vport_stats.fdisc_rsp_err++; 5783a36c61f9SKrishna Gudipati bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_ERROR); 5784a36c61f9SKrishna Gudipati } 5785a36c61f9SKrishna Gudipati } 5786a36c61f9SKrishna Gudipati 5787a36c61f9SKrishna Gudipati /** 5788a36c61f9SKrishna Gudipati * LOGO response 5789a36c61f9SKrishna Gudipati */ 5790a36c61f9SKrishna Gudipati void 5791a36c61f9SKrishna Gudipati bfa_cb_lps_fdisclogo_comp(void *bfad, void *uarg) 5792a36c61f9SKrishna Gudipati { 5793a36c61f9SKrishna Gudipati struct bfa_fcs_vport_s *vport = uarg; 5794a36c61f9SKrishna Gudipati bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_OK); 5795a36c61f9SKrishna Gudipati } 5796a36c61f9SKrishna Gudipati 5797a36c61f9SKrishna Gudipati /** 5798a36c61f9SKrishna Gudipati * Received clear virtual link 5799a36c61f9SKrishna Gudipati */ 5800a36c61f9SKrishna Gudipati void 5801a36c61f9SKrishna Gudipati bfa_cb_lps_cvl_event(void *bfad, void *uarg) 5802a36c61f9SKrishna Gudipati { 5803a36c61f9SKrishna Gudipati struct bfa_fcs_vport_s *vport = uarg; 5804a36c61f9SKrishna Gudipati 5805a36c61f9SKrishna Gudipati /* Send an Offline followed by an ONLINE */ 5806a36c61f9SKrishna Gudipati bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_OFFLINE); 5807a36c61f9SKrishna Gudipati bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_ONLINE); 5808a36c61f9SKrishna Gudipati } 5809